Skip to content

Warn on type arguments in isinstance - #3040

Merged
ilevkivskyi merged 5 commits into
python:masterfrom
pkch:warn-type-args-isinstance
Apr 13, 2017
Merged

ilevkivskyi merged 5 commits into
python:masterfrom
pkch:warn-type-args-isinstance

Conversation

@pkch

@pkch pkch commented Mar 21, 2017

Copy link
Copy Markdown
Contributor

Fixes #3037

@ilevkivskyi ilevkivskyi left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Here are few comments.

Comment thread mypy/messages.py Outdated

def type_arguments_not_allowed(self,
context: Context,
) -> None:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can it be formatted in one line? (maximum allowed length in mypy is 99 chars)

Comment thread mypy/checkexpr.py Outdated
or isinstance(typ, NameExpr)
and self.chk.lookup_qualified(typ.name).kind == nodes.TYPE_ALIAS):
self.msg.type_arguments_not_allowed(e)
except KeyError:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a bit strange. Do you understand why it could fail?
If this happens only for actual undefined names, you could add a comment "This error is reported elsewhere" (if this is true of course).
In any case, I would put only self.chk.lookup_qualified(typ.name) inside try ... except ... block, to avoid masking possible bugs later.

@pkch pkch Mar 21, 2017 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure. Here's where it happens when running mypy mypy:

# stubgenc.py
all_bases = obj.mro()
# ...
for base in all_bases:
    if not any(issubclass(b, base) for b in bases): # builtins.KeyError: 'Failed lookup: bases'
        bases.append(base)

and here:

# testextensions.py    
def assertIsSubclass(self, cls, class_or_tuple, msg=None):
    if not issubclass(cls, class_or_tuple): # failed lookup

and here:

    Emp = TypedDict('Emp', {'name': str, 'id': int})
    with self.assertRaises(TypeError):
        isinstance({}, Emp) # failed lookup

In all cases, the names are typed as Any. Why weren't they added to the symbol table, and why then didn't mypy complain about using undefined names?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, this looks like something unrelated.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Regardless, I don't find "except KeyError" acceptable. Which subexpression are you expecting to raise KeyError? And why is it raised?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gvanrossum This is an outdated version of PR, in the new version try ... except surrounds only lookup_qualified.

Comment thread test-data/unit/check-isinstance.test Outdated
isinstance(x, Iterable[T]) # E: Type arguments not allowed in this context
It2 = Iterable[T]
isinstance(x, It2[int]) # E: Type arguments not allowed in this context
isinstance(x, It2) # E: Type arguments not allowed in this context

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would add few tests with issubclass just in case. Also maybe split the test into smaller tests (e.g. one without aliases, one with aliases, and one with issubclass).

Comment thread mypy/messages.py Outdated
def type_arguments_not_allowed(self,
context: Context,
) -> None:
self.fail('Type arguments not allowed in this context', context)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer a more detailed error message explaining that this is because of isinstance. For example: "Type arguments not allowed in instance and type checks"

@ilevkivskyi
ilevkivskyi merged commit 77e3237 into python:master Apr 13, 2017
@ilevkivskyi

Copy link
Copy Markdown
Member

@pkch Thanks! I just added two explanatory comments.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants