Skip to content

Commit b36d1c9

Browse files
authored
[mypyc] Get rid of of self.non_ext_class (python#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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy