Skip to content

Refactor plugin system and special case TypedDict get and int.__pow__ #3501

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

Merged
merged 11 commits into from
Jun 7, 2017
Merged
20 changes: 12 additions & 8 deletions mypy/checkexpr.py
Original file line number Diff line number Diff line change
Expand Up @@ -218,15 +218,19 @@ def visit_call_expr(self, e: CallExpr, allow_none_return: bool = False) -> Type:
and isinstance(e.callee, MemberExpr)
and isinstance(callee_type, FunctionLike)):
callee_expr_type = self.chk.type_map.get(e.callee.expr)
if isinstance(callee_expr_type, TypedDictType):
info = None
# TODO: Support fallbacks of other kinds of types as well?
if isinstance(callee_expr_type, Instance):
info = callee_expr_type.type
elif isinstance(callee_expr_type, TypedDictType):
info = callee_expr_type.fallback.type.get_containing_type_info(e.callee.name)
if info:
fullname = '{}.{}'.format(info.fullname(), e.callee.name)
object_type = callee_expr_type
signature_hook = self.plugin.get_method_signature_hook(fullname)
if signature_hook:
callee_type = self.apply_method_signature_hook(
e, callee_type, object_type, signature_hook)
if info:
fullname = '{}.{}'.format(info.fullname(), e.callee.name)
object_type = callee_expr_type
signature_hook = self.plugin.get_method_signature_hook(fullname)
if signature_hook:
callee_type = self.apply_method_signature_hook(
e, callee_type, object_type, signature_hook)
ret_type = self.check_call_expr_with_callee_type(callee_type, e, fullname, object_type)
if isinstance(ret_type, UninhabitedType):
self.chk.binder.unreachable()
Expand Down
1 change: 1 addition & 0 deletions test-data/unit/check-expressions.test
Original file line number Diff line number Diff line change
Expand Up @@ -1698,4 +1698,5 @@ reveal_type(a**(-0)) # E: Revealed type is 'builtins.int'
reveal_type(a**(-1)) # E: Revealed type is 'builtins.float'
reveal_type(a**(-2)) # E: Revealed type is 'builtins.float'
Copy link
Member

Choose a reason for hiding this comment

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

The parentheses around the negative number are redundant; you can write a**-2. (Though it's nice to know that you handle parenthesized exponent too, since I presume users might not know the parentheses are redundant.)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I'll remove most of the parentheses but keep one pair to ensure that they are accepted.

reveal_type(a**b) # E: Revealed type is 'Any'
Copy link
Member

Choose a reason for hiding this comment

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

At some point in the future I'd like mypy to do constant propagation too, so this would become int as well. :-)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yeah, constant propagation for at least simple things like ints, floats and strings shouldn't be hard. Then we'd have to update this test case.

reveal_type(a.__pow__(2)) # E: Revealed type is 'builtins.int'
Copy link
Member

Choose a reason for hiding this comment

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

Try a.__pow__(-2) too?

[builtins fixtures/ops.pyi]