def add_non_ext_class_attr(builder: IRBuilder, non_ext: NonExtClassInfo, lvalue: NameExpr, stmt: AssignmentStmt, cdef: ClassDef, attr_to_cache: List[Lvalue]) -> None: """ Add a class attribute to __annotations__ of a non-extension class. If the attribute is assigned to a value, it is also added to __dict__. """ # We populate __annotations__ because dataclasses uses it to determine # which attributes to compute on. # TODO: Maybe generate more precise types for annotations key = builder.load_static_unicode(lvalue.name) typ = builder.primitive_op(type_object_op, [], stmt.line) builder.primitive_op(dict_set_item_op, [non_ext.anns, key, typ], stmt.line) # Only add the attribute to the __dict__ if the assignment is of the form: # x: type = value (don't add attributes of the form 'x: type' to the __dict__). if not isinstance(stmt.rvalue, TempNode): rvalue = builder.accept(stmt.rvalue) builder.add_to_non_ext_dict(non_ext, lvalue.name, rvalue, stmt.line) # We cache enum attributes to speed up enum attribute lookup since they # are final. if ( cdef.info.bases and cdef.info.bases[0].type.fullname == 'enum.Enum' # Skip "_order_" and "__order__", since Enum will remove it and lvalue.name not in ('_order_', '__order__') ): attr_to_cache.append(lvalue)
def finish_non_ext_dict(builder: IRBuilder, non_ext: NonExtClassInfo, line: int) -> None: # Add __annotations__ to the class dict. builder.primitive_op(dict_set_item_op, [non_ext.dict, builder.load_static_unicode('__annotations__'), non_ext.anns], -1) # We add a __doc__ attribute so if the non-extension class is decorated with the # dataclass decorator, dataclass will not try to look for __text_signature__. # https://github.com/python/cpython/blob/3.7/Lib/dataclasses.py#L957 filler_doc_str = 'mypyc filler docstring' builder.add_to_non_ext_dict( non_ext, '__doc__', builder.load_static_unicode(filler_doc_str), line) builder.add_to_non_ext_dict( non_ext, '__module__', builder.load_static_unicode(builder.module_name), line)