Skip to content

Commit b36d1c9

Browse files
authored
[mypyc] Get rid of of self.non_ext_class (#7648)
Pass around a NonExtClassData instead of stashing it in a member global. It would be nice to do this with more things also.
1 parent fb556ae commit b36d1c9

File tree

1 file changed

+32
-35
lines changed

1 file changed

+32
-35
lines changed

mypyc/genops.py

Lines changed: 32 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1009,11 +1009,6 @@ def __init__(self,
10091009
self.callable_class_names = set() # type: Set[str]
10101010
self.options = options
10111011

1012-
# This instance of NonExtClassInfo keeps track of information needed to construct
1013-
# a non-extension class. Its' value is None if the current class being visited
1014-
# is an extension class.
1015-
self.non_ext_info = None # type: Optional[NonExtClassInfo]
1016-
10171012
# These variables keep track of the number of lambdas, implicit indices, and implicit
10181013
# iterators instantiated so we avoid name conflicts. The indices and iterators are
10191014
# instantiated from for-loops.
@@ -1143,7 +1138,8 @@ def handle_ext_method(self, cdef: ClassDef, fdef: FuncDef) -> None:
11431138
class_ir.glue_methods[(cls, name)] = f
11441139
self.functions.append(f)
11451140

1146-
def handle_non_ext_method(self, cdef: ClassDef, fdef: FuncDef) -> None:
1141+
def handle_non_ext_method(
1142+
self, non_ext: NonExtClassInfo, cdef: ClassDef, fdef: FuncDef) -> None:
11471143
# Perform the function of visit_method for methods inside non-extension classes.
11481144
name = fdef.name()
11491145
func_ir, func_reg = self.gen_func_item(fdef, name, self.mapper.fdef_to_sig(fdef), cdef)
@@ -1168,14 +1164,14 @@ def handle_non_ext_method(self, cdef: ClassDef, fdef: FuncDef) -> None:
11681164
stat_meth = self.load_module_attr_by_fullname('builtins.staticmethod', fdef.line)
11691165
func_reg = self.py_call(stat_meth, [func_reg], fdef.line)
11701166

1171-
self.add_to_non_ext_dict(name, func_reg, fdef.line)
1167+
self.add_to_non_ext_dict(non_ext, name, func_reg, fdef.line)
11721168

1173-
def visit_method(self, cdef: ClassDef, fdef: FuncDef) -> None:
1174-
class_ir = self.mapper.type_to_ir[cdef.info]
1175-
if class_ir.is_ext_class:
1176-
self.handle_ext_method(cdef, fdef)
1169+
def visit_method(
1170+
self, cdef: ClassDef, non_ext: Optional[NonExtClassInfo], fdef: FuncDef) -> None:
1171+
if non_ext:
1172+
self.handle_non_ext_method(non_ext, cdef, fdef)
11771173
else:
1178-
self.handle_non_ext_method(cdef, fdef)
1174+
self.handle_ext_method(cdef, fdef)
11791175

11801176
def is_constant(self, e: Expression) -> bool:
11811177
"""Check whether we allow an expression to appear as a default value.
@@ -1253,27 +1249,27 @@ def generate_attr_defaults(self, cdef: ClassDef) -> None:
12531249
self.functions.append(ir)
12541250
cls.methods[ir.name] = ir
12551251

1256-
def load_non_ext_class(self, ir: ClassIR, line: int) -> Value:
1257-
assert self.non_ext_info is not None
1258-
1252+
def load_non_ext_class(self, ir: ClassIR, non_ext: NonExtClassInfo, line: int) -> Value:
12591253
cls_name = self.load_static_unicode(ir.name)
12601254

12611255
# Add __annotations__ to the class dict.
12621256
self.primitive_op(dict_set_item_op,
1263-
[self.non_ext_info.dict, self.load_static_unicode('__annotations__'),
1264-
self.non_ext_info.anns], -1)
1257+
[non_ext.dict, self.load_static_unicode('__annotations__'),
1258+
non_ext.anns], -1)
12651259

12661260
# We add a __doc__ attribute so if the non-extension class is decorated with the
12671261
# dataclass decorator, dataclass will not try to look for __text_signature__.
12681262
# https://github.com/python/cpython/blob/3.7/Lib/dataclasses.py#L957
12691263
filler_doc_str = 'filler docstring for classes decorated with dataclass'
1270-
self.add_to_non_ext_dict('__doc__', self.load_static_unicode(filler_doc_str), line)
1271-
self.add_to_non_ext_dict('__module__', self.load_static_unicode(self.module_name), line)
1264+
self.add_to_non_ext_dict(
1265+
non_ext, '__doc__', self.load_static_unicode(filler_doc_str), line)
1266+
self.add_to_non_ext_dict(
1267+
non_ext, '__module__', self.load_static_unicode(self.module_name), line)
12721268
metaclass = self.primitive_op(type_object_op, [], line)
1273-
metaclass = self.primitive_op(py_calc_meta_op, [metaclass, self.non_ext_info.bases], line)
1269+
metaclass = self.primitive_op(py_calc_meta_op, [metaclass, non_ext.bases], line)
12741270

12751271
class_type_obj = self.py_call(metaclass,
1276-
[cls_name, self.non_ext_info.bases, self.non_ext_info.dict],
1272+
[cls_name, non_ext.bases, non_ext.dict],
12771273
line)
12781274
return class_type_obj
12791275

@@ -1309,13 +1305,13 @@ def populate_non_ext_bases(self, cdef: ClassDef) -> Value:
13091305
bases.append(base)
13101306
return self.primitive_op(new_tuple_op, bases, cdef.line)
13111307

1312-
def add_to_non_ext_dict(self, key: str, val: Value, line: int) -> None:
1308+
def add_to_non_ext_dict(self, non_ext: NonExtClassInfo,
1309+
key: str, val: Value, line: int) -> None:
13131310
# Add an attribute entry into the class dict of a non-extension class.
1314-
assert self.non_ext_info is not None
13151311
key_unicode = self.load_static_unicode(key)
1316-
self.primitive_op(dict_set_item_op, [self.non_ext_info.dict, key_unicode, val], line)
1312+
self.primitive_op(dict_set_item_op, [non_ext.dict, key_unicode, val], line)
13171313

1318-
def add_non_ext_class_attr(self, lvalue: NameExpr,
1314+
def add_non_ext_class_attr(self, non_ext: NonExtClassInfo, lvalue: NameExpr,
13191315
stmt: AssignmentStmt, cdef: ClassDef,
13201316
attr_to_cache: List[Lvalue]) -> None:
13211317
"""
@@ -1326,16 +1322,15 @@ def add_non_ext_class_attr(self, lvalue: NameExpr,
13261322
# We populate __annotations__ because dataclasses uses it to determine
13271323
# which attributes to compute on.
13281324
# TODO: Maybe generate more precise types for annotations
1329-
assert self.non_ext_info is not None
13301325
key = self.load_static_unicode(lvalue.name)
13311326
typ = self.primitive_op(type_object_op, [], stmt.line)
1332-
self.primitive_op(dict_set_item_op, [self.non_ext_info.anns, key, typ], stmt.line)
1327+
self.primitive_op(dict_set_item_op, [non_ext.anns, key, typ], stmt.line)
13331328

13341329
# Only add the attribute to the __dict__ if the assignment is of the form:
13351330
# x: type = value (don't add attributes of the form 'x: type' to the __dict__).
13361331
if not isinstance(stmt.rvalue, TempNode):
13371332
rvalue = self.accept(stmt.rvalue)
1338-
self.add_to_non_ext_dict(lvalue.name, rvalue, stmt.line)
1333+
self.add_to_non_ext_dict(non_ext, lvalue.name, rvalue, stmt.line)
13391334
# We cache enum attributes to speed up enum attribute lookup since they
13401335
# are final.
13411336
if cdef.info.bases and cdef.info.bases[0].type.fullname() == 'enum.Enum':
@@ -1390,14 +1385,15 @@ def visit_class_def(self, cdef: ClassDef) -> None:
13901385
if ir.is_ext_class:
13911386
# If the class is not decorated, generate an extension class for it.
13921387
self.allocate_class(cdef)
1388+
non_ext = None # type: Optional[NonExtClassInfo]
13931389
else:
13941390
non_ext_bases = self.populate_non_ext_bases(cdef)
13951391
non_ext_dict = self.setup_non_ext_dict(cdef, non_ext_bases)
13961392
# We populate __annotations__ for non-extension classes
13971393
# because dataclasses uses it to determine which attributes to compute on.
13981394
# TODO: Maybe generate more precise types for annotations
13991395
non_ext_anns = self.primitive_op(new_dict_op, [], cdef.line)
1400-
self.non_ext_info = NonExtClassInfo(non_ext_dict, non_ext_bases, non_ext_anns)
1396+
non_ext = NonExtClassInfo(non_ext_dict, non_ext_bases, non_ext_anns)
14011397

14021398
attrs_to_cache = [] # type: List[Lvalue]
14031399

@@ -1410,13 +1406,13 @@ def visit_class_def(self, cdef: ClassDef) -> None:
14101406
stmt.line)
14111407
for item in stmt.items:
14121408
with self.catch_errors(stmt.line):
1413-
self.visit_method(cdef, get_func_def(item))
1409+
self.visit_method(cdef, non_ext, get_func_def(item))
14141410
elif isinstance(stmt, (FuncDef, Decorator, OverloadedFuncDef)):
14151411
if cdef.info.names[stmt.name()].plugin_generated and not ir.is_ext_class:
14161412
# Ignore plugin generated methods when creating non-extension classes
14171413
continue
14181414
with self.catch_errors(stmt.line):
1419-
self.visit_method(cdef, get_func_def(stmt))
1415+
self.visit_method(cdef, non_ext, get_func_def(stmt))
14201416
elif isinstance(stmt, PassStmt):
14211417
continue
14221418
elif isinstance(stmt, AssignmentStmt):
@@ -1430,8 +1426,9 @@ def visit_class_def(self, cdef: ClassDef) -> None:
14301426
self.error("Only assignment to variables is supported in class bodies",
14311427
stmt.line)
14321428
continue
1433-
if not ir.is_ext_class:
1434-
self.add_non_ext_class_attr(lvalue, stmt, cdef, attrs_to_cache)
1429+
if non_ext:
1430+
self.add_non_ext_class_attr(
1431+
non_ext, lvalue, stmt, cdef, attrs_to_cache)
14351432
continue
14361433
# Variable declaration with no body
14371434
if isinstance(stmt.rvalue, TempNode):
@@ -1451,12 +1448,12 @@ def visit_class_def(self, cdef: ClassDef) -> None:
14511448
else:
14521449
self.error("Unsupported statement in class body", stmt.line)
14531450

1454-
if ir.is_ext_class:
1451+
if not non_ext: # That is, an extension class
14551452
self.generate_attr_defaults(cdef)
14561453
self.create_ne_from_eq(cdef)
14571454
else:
14581455
# Dynamically create the class via the type constructor
1459-
non_ext_class = self.load_non_ext_class(ir, cdef.line)
1456+
non_ext_class = self.load_non_ext_class(ir, non_ext, cdef.line)
14601457
non_ext_class = self.load_decorated_class(cdef, non_ext_class)
14611458

14621459
# Save the decorated class

0 commit comments

Comments
 (0)