@@ -1986,89 +1986,7 @@ def analyze_lvalue(self, lval: Lvalue, nested: bool = False,
1986
1986
overrides an existing name.
1987
1987
"""
1988
1988
if isinstance (lval , NameExpr ):
1989
- # Top-level definitions within some statements (at least while) are
1990
- # not handled in the first pass, so they have to be added now.
1991
- nested_global = (not self .is_func_scope () and
1992
- self .block_depth [- 1 ] > 0 and
1993
- not self .type )
1994
- if (add_global or nested_global ) and lval .name not in self .globals :
1995
- # Define new global name.
1996
- v = Var (lval .name )
1997
- v .set_line (lval )
1998
- v ._fullname = self .qualified_name (lval .name )
1999
- v .is_ready = False # Type not inferred yet
2000
- lval .node = v
2001
- lval .is_new_def = True
2002
- lval .is_inferred_def = True
2003
- lval .kind = GDEF
2004
- lval .fullname = v ._fullname
2005
- self .globals [lval .name ] = SymbolTableNode (GDEF , v )
2006
- elif isinstance (lval .node , Var ) and lval .is_new_def :
2007
- if lval .kind == GDEF :
2008
- # Since the is_new_def flag is set, this must have been analyzed
2009
- # already in the first pass and added to the symbol table.
2010
- # An exception is typing module with incomplete test fixtures.
2011
- assert lval .node .name () in self .globals or self .cur_mod_id == 'typing'
2012
- elif (self .locals [- 1 ] is not None and lval .name not in self .locals [- 1 ] and
2013
- lval .name not in self .global_decls [- 1 ] and
2014
- lval .name not in self .nonlocal_decls [- 1 ]):
2015
- # Define new local name.
2016
- v = Var (lval .name )
2017
- v .set_line (lval )
2018
- lval .node = v
2019
- lval .is_new_def = True
2020
- lval .is_inferred_def = True
2021
- lval .kind = LDEF
2022
- lval .fullname = lval .name
2023
- self .add_local (v , lval )
2024
- if lval .name == '_' :
2025
- # Special case for assignment to local named '_': always infer 'Any'.
2026
- typ = AnyType (TypeOfAny .special_form )
2027
- self .store_declared_types (lval , typ )
2028
- elif not self .is_func_scope () and (self .type and
2029
- lval .name not in self .type .names ):
2030
- # Define a new attribute within class body.
2031
- v = Var (lval .name )
2032
- v .info = self .type
2033
- v .is_initialized_in_class = True
2034
- v .is_inferred = not explicit_type
2035
- v .set_line (lval )
2036
- v ._fullname = self .qualified_name (lval .name )
2037
- lval .node = v
2038
- lval .is_new_def = True
2039
- lval .is_inferred_def = True
2040
- lval .kind = MDEF
2041
- lval .fullname = lval .name
2042
- self .type .names [lval .name ] = SymbolTableNode (MDEF , v )
2043
- else :
2044
- # An existing name, try to find the original definition.
2045
- global_def = self .globals .get (lval .name )
2046
- if self .locals :
2047
- locals_last = self .locals [- 1 ]
2048
- if locals_last :
2049
- local_def = locals_last .get (lval .name )
2050
- else :
2051
- local_def = None
2052
- else :
2053
- local_def = None
2054
- type_def = self .type .names .get (lval .name ) if self .type else None
2055
-
2056
- original_def = global_def or local_def or type_def
2057
-
2058
- # Redefining an existing name with final is always an error.
2059
- if final_cb is not None :
2060
- # We avoid extra errors if the original definition is also final
2061
- # by keeping the final status of this assignment.
2062
- keep_final = bool (original_def and isinstance (original_def .node , Var ) and
2063
- original_def .node .is_final )
2064
- final_cb (keep_final )
2065
- if explicit_type :
2066
- # Don't re-bind types
2067
- self .name_already_defined (lval .name , lval , original_def )
2068
- else :
2069
- # Bind to an existing name.
2070
- lval .accept (self )
2071
- self .check_lvalue_validity (lval .node , lval )
1989
+ self .analyze_name_lvalue (lval , add_global , explicit_type , final_cb )
2072
1990
elif isinstance (lval , MemberExpr ):
2073
1991
if not add_global :
2074
1992
self .analyze_member_lvalue (lval , explicit_type , final_cb = final_cb )
@@ -2093,6 +2011,105 @@ def analyze_lvalue(self, lval: Lvalue, nested: bool = False,
2093
2011
else :
2094
2012
self .fail ('Invalid assignment target' , lval )
2095
2013
2014
+ def analyze_name_lvalue (self ,
2015
+ lval : NameExpr ,
2016
+ add_global : bool ,
2017
+ explicit_type : bool ,
2018
+ final_cb : Optional [Callable [[bool ], None ]]) -> None :
2019
+ """Analyze an lvalue that targets a name expression.
2020
+
2021
+ Arguments are similar to "analyze_lvalue".
2022
+ """
2023
+ # Top-level definitions within some statements (at least while) are
2024
+ # not handled in the first pass, so they have to be added now.
2025
+ nested_global = (not self .is_func_scope () and
2026
+ self .block_depth [- 1 ] > 0 and
2027
+ not self .type )
2028
+ if (add_global or nested_global ) and lval .name not in self .globals :
2029
+ # Define new global name.
2030
+ v = self .make_name_lvalue_var (lval , GDEF )
2031
+ self .globals [lval .name ] = SymbolTableNode (GDEF , v )
2032
+ elif isinstance (lval .node , Var ) and lval .is_new_def :
2033
+ if lval .kind == GDEF :
2034
+ # Since the is_new_def flag is set, this must have been analyzed
2035
+ # already in the first pass and added to the symbol table.
2036
+ # An exception is typing module with incomplete test fixtures.
2037
+ assert lval .node .name () in self .globals or self .cur_mod_id == 'typing'
2038
+ elif (self .locals [- 1 ] is not None and lval .name not in self .locals [- 1 ] and
2039
+ lval .name not in self .global_decls [- 1 ] and
2040
+ lval .name not in self .nonlocal_decls [- 1 ]):
2041
+ # Define new local name.
2042
+ v = self .make_name_lvalue_var (lval , LDEF )
2043
+ self .add_local (v , lval )
2044
+ if lval .name == '_' :
2045
+ # Special case for assignment to local named '_': always infer 'Any'.
2046
+ typ = AnyType (TypeOfAny .special_form )
2047
+ self .store_declared_types (lval , typ )
2048
+ elif not self .is_func_scope () and (self .type and
2049
+ lval .name not in self .type .names ):
2050
+ # Define a new attribute within class body.
2051
+ v = self .make_name_lvalue_var (lval , MDEF )
2052
+ v .is_inferred = not explicit_type
2053
+ self .type .names [lval .name ] = SymbolTableNode (MDEF , v )
2054
+ else :
2055
+ self .make_name_lvalue_point_to_existing_def (lval , explicit_type , final_cb )
2056
+
2057
+ def make_name_lvalue_var (self , lvalue : NameExpr , kind : int ) -> Var :
2058
+ """Return a Var node for an lvalue that is a name expression."""
2059
+ v = Var (lvalue .name )
2060
+ v .set_line (lvalue )
2061
+ if kind == MDEF :
2062
+ assert self .type is not None
2063
+ v .info = self .type
2064
+ v .is_initialized_in_class = True
2065
+ if kind != LDEF :
2066
+ v ._fullname = self .qualified_name (lvalue .name )
2067
+ if kind == GDEF :
2068
+ v .is_ready = False # Type not inferred yet
2069
+ lvalue .node = v
2070
+ lvalue .is_new_def = True
2071
+ lvalue .is_inferred_def = True
2072
+ lvalue .kind = kind
2073
+ if kind == GDEF :
2074
+ lvalue .fullname = v ._fullname
2075
+ else :
2076
+ lvalue .fullname = lvalue .name
2077
+ return v
2078
+
2079
+ def make_name_lvalue_point_to_existing_def (
2080
+ self ,
2081
+ lval : NameExpr ,
2082
+ explicit_type : bool ,
2083
+ final_cb : Optional [Callable [[bool ], None ]]) -> None :
2084
+ # Assume that an existing name exists. Try to find the original definition.
2085
+ global_def = self .globals .get (lval .name )
2086
+ if self .locals :
2087
+ locals_last = self .locals [- 1 ]
2088
+ if locals_last :
2089
+ local_def = locals_last .get (lval .name )
2090
+ else :
2091
+ local_def = None
2092
+ else :
2093
+ local_def = None
2094
+ type_def = self .type .names .get (lval .name ) if self .type else None
2095
+
2096
+ original_def = global_def or local_def or type_def
2097
+
2098
+ # Redefining an existing name with final is always an error.
2099
+ if final_cb is not None :
2100
+ # We avoid extra errors if the original definition is also final
2101
+ # by keeping the final status of this assignment.
2102
+ keep_final = bool (original_def and isinstance (original_def .node , Var ) and
2103
+ original_def .node .is_final )
2104
+ final_cb (keep_final )
2105
+ if explicit_type :
2106
+ # Don't re-bind types
2107
+ self .name_already_defined (lval .name , lval , original_def )
2108
+ else :
2109
+ # Bind to an existing name.
2110
+ lval .accept (self )
2111
+ self .check_lvalue_validity (lval .node , lval )
2112
+
2096
2113
def analyze_tuple_or_list_lvalue (self , lval : TupleExpr ,
2097
2114
add_global : bool = False ,
2098
2115
explicit_type : bool = False ) -> None :
0 commit comments