Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Warn on type arguments in isinstance #3040

Merged
merged 5 commits into from
Apr 13, 2017

Conversation

pkch
Copy link
Contributor

@pkch pkch commented Mar 21, 2017

Fixes #3037

Copy link
Member

@ilevkivskyi ilevkivskyi left a comment

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.

mypy/messages.py Outdated
@@ -864,6 +864,11 @@ def typeddict_item_name_not_found(self,
self.fail('\'{}\' is not a valid item name; expected one of {}'.format(
item_name, format_item_name_list(typ.items.keys())), context)

def type_arguments_not_allowed(self,
context: Context,
) -> None:
Copy link
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)

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
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.

Copy link
Contributor Author

@pkch pkch Mar 21, 2017

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
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
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
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.

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
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).

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
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
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