8000 Turn `literal` and `literal_hash` into functions by elazarg · Pull Request #3071 · python/mypy · GitHub
[go: up one dir, main page]

Skip to content

Turn literal and literal_hash into functions #3071

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 17 commits into from
Aug 30, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 19 additions & 19 deletions mypy/binder.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@
from contextlib import contextmanager

from mypy.types import Type, AnyType, PartialType, UnionType, TypeOfAny
from mypy.nodes import (Key, Expression, Var, RefExpr)

from mypy.subtypes import is_subtype
from mypy.join import join_simple
from mypy.sametypes import is_same_type

from mypy.nodes import Expression, Var, RefExpr
from mypy.literals import Key, literal, literal_hash, subkeys
from mypy.nodes import IndexExpr, MemberExpr, NameExpr


Expand Down Expand Up @@ -61,7 +60,7 @@ class A:

def __init__(self) -> None:
# The stack of frames currently used. These map
# expr.literal_hash -- literals like 'foo.bar' --
# literal_hash(expr) -- literals like 'foo.bar' --
# to types. The last element of this list is the
# top-most, current frame. Each earlier element
# records the state as of when that frame was last
Expand All @@ -75,7 +74,7 @@ def __init__(self) -> None:
# has no corresponding element in this list.
self.options_on_return = [] # type: List[List[Frame]]

# Maps expr.literal_hash to get_declaration(expr)
# Maps literal_hash(expr) to get_declaration(expr)
# for every expr stored in the binder
self.declarations = DeclarationsFrame()
# Set of other keys to invalidate if a key is changed, e.g. x -> {x.a, x[0]}
Expand All @@ -94,9 +93,8 @@ def _add_dependencies(self, key: Key, value: Optional[Key] = None) -> None:
value = key
else:
self.dependencies.setdefault(key, set()).add(value)
for elt in key:
if isinstance(elt, Key):
self._add_dependencies(elt, value)
for elt in subkeys(key):
self._add_dependencies(elt, value)

def push_frame(self) -> Frame:
"""Push a new frame into the binder."""
Expand All @@ -119,12 +117,11 @@ def _get(self, key: Key, index: int=-1) -> Optional[Type]:
def put(self, expr: Expression, typ: Type) -> None:
if not isinstance(expr, BindableTypes):
return
if not expr.literal:
if not literal(expr):
return
key = expr.literal_hash
key = literal_hash(expr)
assert key is not None, 'Internal error: binder tried to put non-literal'
if key not in self.declarations:
assert isinstance(expr, BindableTypes)
self.declarations[key] = get_declaration(expr)
self._add_dependencies(key)
self._put(key, typ)
Expand All @@ -133,8 +130,9 @@ def unreachable(self) -> None:
self.frames[-1].unreachable = True

def get(self, expr: Expression) -> Optional[Type]:
assert expr.literal_hash is not None, 'Internal error: binder tried to get non-literal'
return self._get(expr.literal_hash)
key = literal_hash(expr)
assert key is not None, 'Internal error: binder tried to get non-literal'
return self._get(key)

def is_unreachable(self) -> bool:
# TODO: Copy the value of unreachable into new frames to avoid
Expand All @@ -143,8 +141,9 @@ def is_unreachable(self) -> bool:

def cleanse(self, expr: Expression) -> None:
"""Remove all references to a Node from the binder."""
assert expr.literal_hash is not None, 'Internal error: binder tried cleanse non-literal'
self._cleanse_key(expr.literal_hash)
key = literal_hash(expr)
assert key is not None, 'Internal error: binder tried cleanse non-literal'
self._cleanse_key(key)

def _cleanse_key(self, key: Key) -> None:
"""Remove all references to a key from the binder."""
Expand Down Expand Up @@ -217,7 +216,7 @@ def assign_type(self, expr: Expression,
restrict_any: bool = False) -> None:
if not isinstance(expr, BindableTypes):
return None
if not expr.literal:
if not literal(expr):
return
self.invalidate_dependencies(expr)

Expand Down Expand Up @@ -266,14 +265,15 @@ def invalidate_dependencies(self, expr: BindableExpression) -> None:
It is overly conservative: it invalidates globally, including
in code paths unreachable from here.
"""
assert expr.literal_hash is not None
for dep in self.dependencies.get(expr.literal_hash, set()):
key = literal_hash(expr)
assert key is not None
for dep in self.dependencies.get(key, set()):
self._cleanse_key(dep)

def most_recent_enclosing_type(self, expr: BindableExpression, type: Type) -> Optional[Type]:
if isinstance(type, AnyType):
return get_declaration(expr)
key = expr.literal_hash
key = literal_hash(expr)
assert key is not None
enclosers = ([get_declaration(expr)] +
[f[key] for f in self.frames
Expand Down
16 changes: 9 additions & 7 deletions mypy/checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
ARG_POS, MDEF,
CONTRAVARIANT, COVARIANT, INVARIANT)
from mypy import nodes
from mypy.literals import literal, literal_hash
from mypy.typeanal import has_any_from_unimported_type, check_for_explicit_any
from mypy.types import (
Type, AnyType, CallableType, FunctionLike, Overloaded, TupleType, TypedDictType,
Expand Down Expand Up @@ -2846,9 +2847,9 @@ def and_conditional_maps(m1: TypeMap, m2: TypeMap) -> TypeMap:
# arbitrarily give precedence to m2. (In the future, we could use
# an intersection type.)
result = m2.copy()
m2_keys = set(n2.literal_hash for n2 in m2)
m2_keys = set(literal_hash(n2) for n2 in m2)
for n1 in m1:
if n1.literal_hash not in m2_keys:
if literal_hash(n1) not in m2_keys:
result[n1] = m1[n1]
return result

Expand All @@ -2870,7 +2871,7 @@ def or_conditional_maps(m1: TypeMap, m2: TypeMap) -> TypeMap:
result = {}
for n1 in m1:
for n2 in m2:
if n1.literal_hash == n2.literal_hash:
if literal_hash(n1) == literal_hash(n2):
result[n1] = UnionType.make_simplified_union([m1[n1], m2[n2]])
return result

Expand Down Expand Up @@ -2910,13 +2911,13 @@ def find_isinstance_check(node: Expression,
if len(node.args) != 2: # the error will be reported later
return {}, {}
expr = node.args[0]
if expr.literal == LITERAL_TYPE:
if literal(expr) == LITERAL_TYPE:
vartype = type_map[expr]
type = get_isinstance_type(node.args[1], type_map)
return conditional_type_map(expr, vartype, type)
elif refers_to_fullname(node.callee, 'builtins.issubclass'):
expr = node.args[0]
if expr.literal == LITERAL_TYPE:
if literal(expr) == LITERAL_TYPE:
vartype = type_map[expr]
type = get_isinstance_type(node.args[1], type_map)
if isinstance(vartype, UnionType):
Expand All @@ -2940,7 +2941,7 @@ def find_isinstance_check(node: Expression,
return yes_map, no_map
elif refers_to_fullname(node.callee, 'builtins.callable'):
expr = node.args[0]
if expr.literal == LITERAL_TYPE:
if literal(expr) == LITERAL_TYPE:
vartype = type_map[expr]
return conditional_callable_type_map(expr, vartype)
elif isinstance(node, ComparisonExpr) and experiments.STRICT_OPTIONAL:
Expand All @@ -2950,7 +2951,8 @@ def find_isinstance_check(node: Expression,
if_vars = {} # type: TypeMap
else_vars = {} # type: TypeMap
for expr in node.operands:
if expr.literal == LITERAL_TYPE and not is_literal_none(expr) and expr in type_map:
if (literal(expr) == LITERAL_TYPE and not is_literal_none(expr)
and expr in type_map):
# This should only be true at most once: there should be
# two elements in node.operands, and at least one of them
# should represent a None.
Expand Down
3 changes: 2 additions & 1 deletion mypy/checkexpr.py
67F4
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
TypeAliasExpr, BackquoteExpr, EnumCallExpr,
ARG_POS, ARG_NAMED, ARG_STAR, ARG_STAR2, MODULE_REF, TVAR, LITERAL_TYPE,
)
from mypy.literals import literal
from mypy import nodes
import mypy.checker
from mypy import types
Expand Down Expand Up @@ -2497,7 +2498,7 @@ def bool_type(self) -> Instance:
return self.named_type('builtins.bool')

def narrow_type_from_binder(self, expr: Expression, known_type: Type) -> Type:
if expr.literal >= LITERAL_TYPE:
if literal(expr) >= LITERAL_TYPE:
restriction = self.chk.binder.get(expr)
if restriction:
ans = narrow_declared_type(known_type, restriction)
Expand Down
Loading
0