8000 [WIP] Tighten Lvalues and remove all references to Node by elazarg · Pull Request #2221 · python/mypy · GitHub
[go: up one dir, main page]

Skip to content

[WIP] Tighten Lvalues and remove all references to Node #2221

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

Closed
wants to merge 14 commits into from
Closed
Prev Previous commit
Next Next commit
tighten lvalues for binder
  • Loading branch information
elazarg committed Oct 5, 2016
commit f6bdc207c17bb6fd7e5e08dcf993f4df1400b2cc
34 changes: 25 additions & 9 deletions mypy/binder.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from builtins import type as realtype
from typing import (Any, Dict, List, Set, Iterator, Union)
from contextlib import contextmanager

Expand All @@ -8,15 +9,20 @@
from mypy.join import join_simple
from mypy.sametypes import is_same_type

from mypy.nodes import IndexExpr, MemberExpr, NameExpr, SuperExpr

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't understand why is it needed. This can be fixed regardless of this PR.

class Frame(Dict[Any, Type]):
pass

BLval = Union[IndexExpr, MemberExpr, NameExpr]


class Key(AnyType):
pass


class Frame(Dict[Key, Type]):
pass


class ConditionalTypeBinder:
"""Keep track of conditional types of variables.

Expand Down Expand Up @@ -97,6 +103,7 @@ def _get(self, key: Key, index: int=-1) -> Type:
return None

def push(self, expr: Expression, typ: Type) -> None:
assert isinstance(expr, (IndexExpr, MemberExpr, NameExpr))
if not expr.literal:
return
key = expr.literal_hash
Expand All @@ -105,11 +112,16 @@ def push(self, expr: Expression, typ: Type) -> None:
self._add_dependencies(key)
self._push(key, typ)

def get(self, expr: Union[Expression, Var]) -> Type:
def get(self, expr: Union[BLval, Var]) -> Type:
assert isinstance(expr, BLval.__union_params__ + (Var,))
if isinstance(expr, Var):
# where is this literal hash initialized?
return self._get(expr.literal_hash)
return self._get(expr.literal_hash)

def cleanse(self, expr: Expression) -> None:
def cleanse(self, expr: BLval) -> None:
"""Remove all references to an Expression from the binder."""
assert isinstance(expr, BLval.__union_params__)
self._cleanse_key(expr.literal_hash)

def _cleanse_key(self, key: Key) -> None:
Expand Down Expand Up @@ -165,7 +177,8 @@ def pop_frame(self, fall_through: int = 0) -> Frame:

return result

def get_declaration(self, expr: Expression) -> Type:
def get_declaration(self, expr: BLval) -> Type:
assert isinstance(expr, BLval.__union_params__)
if isinstance(expr, (RefExpr, SymbolTableNode)) and isinstance(expr.node, Var):
type = expr.node.type
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The test here is never true, and I think the original (changed in one of my previous PRs) was never true either. I wonder why.

if isinstance(type, PartialType):
Expand All @@ -174,11 +187,12 @@ def get_declaration(self, expr: Expression) -> Type:
else:
return None

def assign_type(self, expr: Expression,
def assign_type(self, expr: Union[BLval, SuperExpr],
type: Type,
declared_type: Type,
restrict_any: bool = False) -> None:
if not expr.literal:
assert isinstance(expr, BLval.__union_params__ + (SuperExpr,))
if isinstance(expr, SuperExpr) or not expr.literal:
return
self.invalidate_dependencies(expr)

Expand Down Expand Up @@ -211,7 +225,8 @@ def assign_type(self, expr: Expression,
# just copy this variable into a single stored frame.
self.allow_jump(i)

def invalidate_dependencies(self, expr: Expression) -> None:
def invalidate_dependencies(self, expr: BLval) -> None:
assert isinstance(expr, BLval.__union_params__)
"""Invalidate knowledge of types that include expr, but not expr itself.

For example, when expr is foo.bar, invalidate foo.bar.baz.
Expand All @@ -222,7 +237,8 @@ def invalidate_dependencies(self, expr: Expression) -> None:
for dep in self.dependencies.get(expr.literal_hash, set()):
self._cleanse_key(dep)

def most_recent_enclosing_type(self, expr: Expression, type: Type) -> Type:
def most_recent_enclosing_type(self, expr: BLval, type: Type) -> Type:
assert isinstance(expr, BLval.__union_params__)
if isinstance(type, AnyType):
return self.get_declaration(expr)
key = expr.literal_hash
Expand Down
4 changes: 3 additions & 1 deletion mypy/checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -1081,6 +1081,7 @@ def check_assignment(self, lvalue: Lvalue, rvalue: Expression, infer_lvalue_type
rvalue_type = self.check_simple_assignment(lvalue_type, rvalue, lvalue)

if rvalue_type and infer_lvalue_type:
assert isinstance(lvalue, (IndexExpr, MemberExpr, NameExpr, SuperExpr))
self.binder.assign_type(lvalue,
rvalue_type,
lvalue_type,
Expand Down Expand Up @@ -1378,7 +1379,8 @@ def set_inference_error_fallback_type(self, var: Var, lvalue: Lvalue, type: Type
if context.get_line() in self.errors.ignored_lines[self.errors.file]:
self.set_inferred_type(var, lvalue, AnyType())

def narrow_type_from_binder(self, expr: Expression, known_type: Type) -> Type:
def narrow_type_from_binder(self, expr: Union[IndexExpr, MemberExpr, NameExpr],
known_type: Type) -> Type:
if expr.literal >= LITERAL_TYPE:
restriction = self.binder.get(expr)
if restriction:
Expand Down
0