예제 #1
0
파일: function.py 프로젝트: wesleyks/mypy
def handle_non_ext_method(
        builder: IRBuilder, non_ext: NonExtClassInfo, cdef: ClassDef, fdef: FuncDef) -> None:
    # Perform the function of visit_method for methods inside non-extension classes.
    name = fdef.name
    func_ir, func_reg = gen_func_item(builder, fdef, name, builder.mapper.fdef_to_sig(fdef), cdef)
    assert func_reg is not None
    builder.functions.append(func_ir)

    if is_decorated(builder, fdef):
        # The undecorated method is a generated callable class
        orig_func = func_reg
        func_reg = load_decorated_func(builder, fdef, orig_func)

    # TODO: Support property setters in non-extension classes
    if fdef.is_property:
        prop = builder.load_module_attr_by_fullname('builtins.property', fdef.line)
        func_reg = builder.py_call(prop, [func_reg], fdef.line)

    elif builder.mapper.func_to_decl[fdef].kind == FUNC_CLASSMETHOD:
        cls_meth = builder.load_module_attr_by_fullname('builtins.classmethod', fdef.line)
        func_reg = builder.py_call(cls_meth, [func_reg], fdef.line)

    elif builder.mapper.func_to_decl[fdef].kind == FUNC_STATICMETHOD:
        stat_meth = builder.load_module_attr_by_fullname(
            'builtins.staticmethod', fdef.line
        )
        func_reg = builder.py_call(stat_meth, [func_reg], fdef.line)

    builder.add_to_non_ext_dict(non_ext, name, func_reg, fdef.line)
예제 #2
0
def add_non_ext_class_attr(builder: IRBuilder,
                           non_ext: NonExtClassInfo,
                           lvalue: NameExpr,
                           stmt: AssignmentStmt,
                           cdef: ClassDef,
                           attr_to_cache: List[Tuple[Lvalue, RType]]) -> None:
    """Add a class attribute to __annotations__ of a non-extension class.

    If the attribute is initialized with a value, also add it 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_str(lvalue.name)
    typ = builder.add(LoadAddress(type_object_op.type, type_object_op.src, stmt.line))
    builder.call_c(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__')
        ):
            # Enum values are always boxed, so use object_rprimitive.
            attr_to_cache.append((lvalue, object_rprimitive))
예제 #3
0
def finish_non_ext_dict(builder: IRBuilder, non_ext: NonExtClassInfo, line: int) -> None:
    # Add __annotations__ to the class dict.
    builder.call_c(dict_set_item_op,
                [non_ext.dict, builder.load_str('__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_str(filler_doc_str), line)
    builder.add_to_non_ext_dict(
        non_ext, '__module__', builder.load_str(builder.module_name), line)
예제 #4
0
def add_non_ext_class_attr(builder: IRBuilder, non_ext: NonExtClassInfo,
                           lvalue: NameExpr, stmt: AssignmentStmt,
                           cdef: ClassDef,
                           attr_to_cache: List[Tuple[Lvalue, RType]]) -> None:
    """Add a class attribute to __dict__ of a non-extension class."""
    # 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 these since Enum will remove it
                and lvalue.name not in ENUM_REMOVED_PROPS):
            # Enum values are always boxed, so use object_rprimitive.
            attr_to_cache.append((lvalue, object_rprimitive))
예제 #5
0
파일: classdef.py 프로젝트: srittau/mypy
def add_dunders_to_non_ext_dict(builder: IRBuilder, non_ext: NonExtClassInfo,
                                line: int, add_annotations: bool = True) -> None:
    if add_annotations:
        # Add __annotations__ to the class dict.
        builder.add_to_non_ext_dict(non_ext, '__annotations__', non_ext.anns, line)

    # 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_str(filler_doc_str), line)
    builder.add_to_non_ext_dict(
        non_ext, '__module__', builder.load_str(builder.module_name), line)