-
-
Notifications
You must be signed in to change notification settings - Fork 3k
Last strict optional fixes #4070
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
Changes from 1 commit
178ad41
9d77fbc
1f73106
218253a
233c298
cd6613d
583c00e
6ecd80b
b105456
363407c
eaa6edb
0302811
6387359
424334a
80c1b38
2a96e50
6f8cd68
46e8c2d
a877957
9969ecb
aabbefa
2549386
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -204,13 +204,13 @@ class SemanticAnalyzer(NodeVisitor[None]): | |
# Names declated using "nonlocal" (separate set for each scope) | ||
nonlocal_decls = None # type: List[Set[str]] | ||
# Local names of function scopes; None for non-function scopes. | ||
locals = None # type: List[SymbolTable] | ||
locals = None # type: List[Optional[SymbolTable]] | ||
# Nested block depths of scopes | ||
block_depth = None # type: List[int] | ||
# TypeInfo of directly enclosing class (or None) | ||
type = None # type: Optional[TypeInfo] | ||
# Stack of outer classes (the second tuple item contains tvars). | ||
type_stack = None # type: List[TypeInfo] | ||
type_stack = None # type: List[Optional[TypeInfo]] | ||
# Type variables that are bound by the directly enclosing class | ||
bound_tvars = None # type: List[SymbolTableNode] | ||
# Type variables bound by the current scope, be it class or function | ||
|
@@ -289,6 +289,7 @@ def visit_file(self, file_node: MypyFile, fnam: str, options: Options, | |
for name in implicit_module_attrs: | ||
v = self.globals[name].node | ||
if isinstance(v, Var): | ||
assert v.type is not None, "Type of implicit attribute not set" | ||
v.type = self.anal_type(v.type) | ||
v.is_ready = True | ||
|
||
|
@@ -381,6 +382,7 @@ def visit_func_def(self, defn: FuncDef) -> None: | |
# be a win. | ||
if self.is_class_scope(): | ||
# Method definition | ||
assert self.type is not None, "Type not set at class scope" | ||
defn.info = self.type | ||
if not defn.is_decorated and not defn.is_overload: | ||
if (defn.name() in self.type.names and | ||
|
@@ -433,6 +435,7 @@ def visit_func_def(self, defn: FuncDef) -> None: | |
def prepare_method_signature(self, func: FuncDef) -> None: | ||
"""Check basic signature validity and tweak annotation of self/cls argument.""" | ||
# Only non-static methods are special. | ||
assert self.type is not None, "This method should be only called inside a class" | ||
functype = func.type | ||
if not func.is_static: | ||
if not func.arguments: | ||
|
@@ -546,7 +549,7 @@ def visit_overloaded_func_def(self, defn: OverloadedFuncDef) -> None: | |
assert defn.impl is defn.items[-1] | ||
defn.items = defn.items[:-1] | ||
elif not self.is_stub_file and not non_overload_indexes: | ||
if not (self.is_class_scope() and self.type.is_protocol): | ||
if not (self.type and not self.is_func_scope() and self.type.is_protocol): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Random observation: Here it would be useful is There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, I also noticed it would be very useful to somehow "remember" the bindings. For simple cases I was thinking about something like inlining methods (very approximately): @inline
def meth(self) -> bool:
return self.x is not None and self.y is not None
if self.meth(): # use original expression returned by 'meth' here
... |
||
self.fail( | ||
"An overloaded function outside a stub file must have an implementation", | ||
defn) | ||
|
@@ -566,7 +569,7 @@ def visit_overloaded_func_def(self, defn: OverloadedFuncDef) -> None: | |
# redfinitions already. | ||
return | ||
|
||
if self.is_class_scope(): | ||
if self.type and not self.is_func_scope(): | ||
self.type.names[defn.name()] = SymbolTableNode(MDEF, defn, | ||
typ=defn.type) | ||
defn.info = self.type | ||
|
@@ -1778,9 +1781,10 @@ def check_and_set_up_type_alias(self, s: AssignmentStmt) -> None: | |
if not res: | ||
return | ||
node = self.lookup(lvalue.name, lvalue) | ||
assert node is not None | ||
if not lvalue.is_def: | ||
# Only a definition can create a type alias, not regular assignment. | ||
if node and node.kind == TYPE_ALIAS or isinstance(node.node, TypeInfo): | ||
if node.kind == TYPE_ALIAS or isinstance(node.node, TypeInfo): | ||
self.fail('Cannot assign multiple types to name "{}"' | ||
' without an explicit "Type[...]" annotation' | ||
8000 .format(lvalue.name), lvalue) | ||
|
@@ -1916,6 +1920,7 @@ def analyze_tuple_or_list_lvalue(self, lval: Union[ListExpr, TupleExpr], | |
def analyze_member_lvalue(self, lval: MemberExpr) -> None: | ||
lval.accept(self) | ||
if self.is_self_member_ref(lval): | ||
assert self.type, "Self member outside a class" | ||
node = self.type.get(lval.name) | ||
if node is None or isinstance(node.node, Var) and node.node.is_abstract_var: | ||
if self.type.is_protocol and node is None: | ||
|
@@ -2133,6 +2138,7 @@ def process_typevar_declaration(self, s: AssignmentStmt) -> None: | |
context=s) | ||
# Yes, it's a valid type variable definition! Add it to the symbol table. | ||
node = self.lookup(name, s) | ||
assert node is not None | ||
node.kind = TVAR | ||
TypeVar = TypeVarExpr(name, node.fullname, values, upper_bound, variance) | ||
TypeVar.line = call.line | ||
|
@@ -3549,7 +3555,7 @@ def lookup(self, name: str, ctx: Context, | |
self.name_not_defined(name, ctx) | ||
return None | ||
# 2. Class attributes (if within class definition) | ||
if self.is_class_scope() and name in self.type.names: | ||
if self.type and not self.is_func_scope() and name in self.type.names: | ||
node = self.type.names[name] | ||
if not node.implicit: | ||
return node | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could remove this assert by adding a
TypeInfo
argument and passing it from the caller.