diff --git a/mypyc/irbuild/builder.py b/mypyc/irbuild/builder.py index 1411222010a1..075fd29e359c 100644 --- a/mypyc/irbuild/builder.py +++ b/mypyc/irbuild/builder.py @@ -288,20 +288,20 @@ def add_to_non_ext_dict(self, non_ext: NonExtClassInfo, key_unicode = self.load_str(key) self.call_c(dict_set_item_op, [non_ext.dict, key_unicode, val], line) - def gen_import_from(self, id: str, line: int, imported: List[str]) -> None: + def gen_import_from(self, id: str, globals_dict: Value, + imported: List[str], line: int) -> Value: self.imports[id] = None - globals_dict = self.load_globals_dict() - null = Integer(0, dict_rprimitive, line) + null_dict = Integer(0, dict_rprimitive, line) names_to_import = self.new_list_op([self.load_str(name) for name in imported], line) - - level = Integer(0, c_int_rprimitive, line) + zero_int = Integer(0, c_int_rprimitive, line) value = self.call_c( import_extra_args_op, - [self.load_str(id), globals_dict, null, names_to_import, level], + [self.load_str(id), globals_dict, null_dict, names_to_import, zero_int], line, ) self.add(InitStatic(value, id, namespace=NAMESPACE_MODULE)) + return value def gen_import(self, id: str, line: int) -> None: self.imports[id] = None diff --git a/mypyc/irbuild/statement.py b/mypyc/irbuild/statement.py index f37e2455f3e2..6a744781ee50 100644 --- a/mypyc/irbuild/statement.py +++ b/mypyc/irbuild/statement.py @@ -22,7 +22,7 @@ ) from mypyc.ir.rtypes import RInstance, exc_rtuple from mypyc.primitives.generic_ops import py_delattr_op -from mypyc.primitives.misc_ops import type_op +from mypyc.primitives.misc_ops import type_op, import_from_op from mypyc.primitives.exc_ops import ( raise_exception_op, reraise_exception_op, error_catch_op, exc_matches_op, restore_exc_info_op, get_exc_value_op, keep_propagating_op, get_exc_info_op @@ -172,18 +172,20 @@ def transform_import_from(builder: IRBuilder, node: ImportFrom) -> None: id = importlib.util.resolve_name('.' * node.relative + node.id, module_package) - imported = [name for name, _ in node.names] - builder.gen_import_from(id, node.line, imported) - module = builder.load_module(id) + globals = builder.load_globals_dict() + imported_names = [name for name, _ in node.names] + module = builder.gen_import_from(id, globals, imported_names, node.line) # Copy everything into our module's dict. # Note that we miscompile import from inside of functions here, # since that case *shouldn't* load it into the globals dict. # This probably doesn't matter much and the code runs basically right. - globals = builder.load_globals_dict() for name, maybe_as_name in node.names: as_name = maybe_as_name or name - obj = builder.py_get_attr(module, name, node.line) + obj = builder.call_c(import_from_op, + [module, builder.load_str(id), + builder.load_str(name), builder.load_str(as_name)], + node.line) builder.gen_method_call( globals, '__setitem__', [builder.load_str(as_name), obj], result_type=None, line=node.line) diff --git a/mypyc/lib-rt/CPy.h b/mypyc/lib-rt/CPy.h index d43c79590636..f1a342527b11 100644 --- a/mypyc/lib-rt/CPy.h +++ b/mypyc/lib-rt/CPy.h @@ -542,6 +542,9 @@ int CPyStatics_Initialize(PyObject **statics, const int *tuples); PyObject *CPy_Super(PyObject *builtins, PyObject *self); +PyObject *CPyImport_ImportFrom(PyObject *module, PyObject *package_name, + PyObject *import_name, PyObject *as_name); + #ifdef __cplusplus } #endif diff --git a/mypyc/lib-rt/misc_ops.c b/mypyc/lib-rt/misc_ops.c index 923ea22629a8..0eef96b854dc 100644 --- a/mypyc/lib-rt/misc_ops.c +++ b/mypyc/lib-rt/misc_ops.c @@ -643,3 +643,36 @@ CPy_Super(PyObject *builtins, PyObject *self) { Py_DECREF(super_type); return result; } + +// This helper function is a simplification of cpython/ceval.c/import_from() +PyObject *CPyImport_ImportFrom(PyObject *module, PyObject *package_name, + PyObject *import_name, PyObject *as_name) { + // check if the imported module has an attribute by that name + PyObject *x = PyObject_GetAttr(module, import_name); + if (x == NULL) { + // if not, attempt to import a submodule with that name + PyObject *fullmodname = PyUnicode_FromFormat("%U.%U", package_name, import_name); + if (fullmodname == NULL) { + goto fail; + } + + // The following code is a simplification of cpython/import.c/PyImport_GetModule() + x = PyObject_GetItem(module, fullmodname); + Py_DECREF(fullmodname); + if (x == NULL) { + goto fail; + } + } + return x; + +fail: + PyErr_Clear(); + PyObject *package_path = PyModule_GetFilenameObject(module); + PyObject *errmsg = PyUnicode_FromFormat("cannot import name %R from %R (%S)", + import_name, package_name, package_path); + // NULL checks for errmsg and package_name done by PyErr_SetImportError. + PyErr_SetImportError(errmsg, package_name, package_path); + Py_DECREF(package_path); + Py_DECREF(errmsg); + return NULL; +} diff --git a/mypyc/primitives/misc_ops.py b/mypyc/primitives/misc_ops.py index 8d18978622ec..ed1a04da59dd 100644 --- a/mypyc/primitives/misc_ops.py +++ b/mypyc/primitives/misc_ops.py @@ -123,6 +123,15 @@ error_kind=ERR_MAGIC ) +# Import-from helper op +import_from_op = custom_op( + arg_types=[object_rprimitive, str_rprimitive, + str_rprimitive, str_rprimitive], + return_type=object_rprimitive, + c_function_name='CPyImport_ImportFrom', + error_kind=ERR_MAGIC +) + # Get the sys.modules dictionary get_module_dict_op = custom_op( arg_types=[], diff --git a/mypyc/test-data/fixtures/ir.py b/mypyc/test-data/fixtures/ir.py index bd98a07949f2..9a64280c5372 100644 --- a/mypyc/test-data/fixtures/ir.py +++ b/mypyc/test-data/fixtures/ir.py @@ -229,6 +229,8 @@ class ValueError(Exception): pass class AttributeError(Exception): pass +class ImportError(Exception): pass + class NameError(Exception): pass class LookupError(Exception): pass diff --git a/mypyc/test-data/irbuild-basic.test b/mypyc/test-data/irbuild-basic.test index bd1df8276f59..0ec691a8fe36 100644 --- a/mypyc/test-data/irbuild-basic.test +++ b/mypyc/test-data/irbuild-basic.test @@ -2497,77 +2497,76 @@ def __top_level__(): r9 :: list r10, r11, r12, r13 :: ptr r14 :: str - r15, r16 :: object - r17 :: dict - r18 :: str + r15 :: object + r16, r17, r18 :: str r19 :: object r20 :: str r21 :: int32 r22 :: bit - r23 :: str - r24 :: object - r25 :: str - r26 :: int32 - r27 :: bit - r28 :: str - r29 :: object - r30 :: str - r31 :: int32 - r32 :: bit - r33, r34 :: str - r35 :: object - r36 :: tuple[str, object] - r37 :: object - r38 :: str + r23, r24, r25 :: str + r26 :: object + r27 :: str + r28 :: int32 + r29 :: bit + r30, r31, r32 :: str + r33 :: object + r34 :: str + r35 :: int32 + r36 :: bit + r37, r38 :: str r39 :: object r40 :: tuple[str, object] r41 :: object - r42 :: tuple[object, object] + r42 :: str r43 :: object - r44 :: dict - r45 :: str - r46, r47 :: object + r44 :: tuple[str, object] + r45 :: object + r46 :: tuple[object, object] + r47 :: object r48 :: dict r49 :: str - r50 :: int32 - r51 :: bit - r52 :: str - r53 :: dict - r54 :: str - r55, r56, r57 :: object - r58 :: tuple - r59 :: dict - r60 :: str - r61 :: int32 - r62 :: bit + r50, r51 :: object + r52 :: dict + r53 :: str + r54 :: int32 + r55 :: bit + r56 :: str + r57 :: dict + r58 :: str + r59, r60, r61 :: object + r62 :: tuple r63 :: dict r64 :: str - r65, r66, r67 :: object - r68 :: dict - r69 :: str - r70 :: int32 - r71 :: bit - r72 :: str - r73 :: dict - r74 :: str - r75 :: object - r76 :: dict - r77 :: str - r78, r79 :: object + r65 :: int32 + r66 :: bit + r67 :: dict + r68 :: str + r69, r70, r71 :: object + r72 :: dict + r73 :: str + r74 :: int32 + r75 :: bit + r76 :: str + r77 :: dict + r78 :: str + r79 :: object r80 :: dict r81 :: str - r82 :: int32 - r83 :: bit - r84 :: list - r85, r86, r87 :: object - r88, r89, r90, r91 :: ptr - r92 :: dict - r93 :: str - r94, r95 :: object + r82, r83 :: object + r84 :: dict + r85 :: str + r86 :: int32 + r87 :: bit + r88 :: list + r89, r90, r91 :: object + r92, r93, r94, r95 :: ptr r96 :: dict r97 :: str - r98 :: int32 - r99 :: bit + r98, r99 :: object + r100 :: dict + r101 :: str + r102 :: int32 + r103 :: bit L0: r0 = builtins :: module r1 = load_address _Py_NoneStruct @@ -2594,94 +2593,98 @@ L2: r14 = 'typing' r15 = PyImport_ImportModuleLevelObject(r14, r5, 0, r9, 0) typing = r15 :: module - r16 = typing :: module - r17 = __main__.globals :: static + r16 = 'typing' + r17 = 'List' r18 = 'List' - r19 = CPyObject_GetAttr(r16, r18) + r19 = CPyImport_ImportFrom(r15, r16, r17, r18) r20 = 'List' - r21 = CPyDict_SetItem(r17, r20, r19) + r21 = CPyDict_SetItem(r5, r20, r19) r22 = r21 >= 0 :: signed - r23 = 'NewType' - r24 = CPyObject_GetAttr(r16, r23) + r23 = 'typing' + r24 = 'NewType' r25 = 'NewType' - r26 = CPyDict_SetItem(r17, r25, r24) - r27 = r26 >= 0 :: signed - r28 = 'NamedTuple' - r29 = CPyObject_GetAttr(r16, r28) - r30 = 'NamedTuple' - r31 = CPyDict_SetItem(r17, r30, r29) - r32 = r31 >= 0 :: signed - r33 = 'Lol' - r34 = 'a' - r35 = load_address PyLong_Type - r36 = (r34, r35) - r37 = box(tuple[str, object], r36) - r38 = 'b' - r39 = load_address PyUnicode_Type + r26 = CPyImport_ImportFrom(r15, r23, r24, r25) + r27 = 'NewType' + r28 = CPyDict_SetItem(r5, r27, r26) + r29 = r28 >= 0 :: signed + r30 = 'typing' + r31 = 'NamedTuple' + r32 = 'NamedTuple' + r33 = CPyImport_ImportFrom(r15, r30, r31, r32) + r34 = 'NamedTuple' + r35 = CPyDict_SetItem(r5, r34, r33) + r36 = r35 >= 0 :: signed + r37 = 'Lol' + r38 = 'a' + r39 = load_address PyLong_Type r40 = (r38, r39) r41 = box(tuple[str, object], r40) - r42 = (r37, r41) - r43 = box(tuple[object, object], r42) - r44 = __main__.globals :: static - r45 = 'NamedTuple' - r46 = CPyDict_GetItem(r44, r45) - r47 = PyObject_CallFunctionObjArgs(r46, r33, r43, 0) + r42 = 'b' + r43 = load_address PyUnicode_Type + r44 = (r42, r43) + r45 = box(tuple[str, object], r44) + r46 = (r41, r45) + r47 = box(tuple[object, object], r46) r48 = __main__.globals :: static - r49 = 'Lol' - r50 = CPyDict_SetItem(r48, r49, r47) - r51 = r50 >= 0 :: signed - r52 = '' - r53 = __main__.globals :: static - r54 = 'Lol' - r55 = CPyDict_GetItem(r53, r54) - r56 = box(short_int, 2) - r57 = PyObject_CallFunctionObjArgs(r55, r56, r52, 0) - r58 = cast(tuple, r57) - r59 = __main__.globals :: static - r60 = 'x' - r61 = CPyDict_SetItem(r59, r60, r58) - r62 = r61 >= 0 :: signed + r49 = 'NamedTuple' + r50 = CPyDict_GetItem(r48, r49) + r51 = PyObject_CallFunctionObjArgs(r50, r37, r47, 0) + r52 = __main__.globals :: static + r53 = 'Lol' + r54 = CPyDict_SetItem(r52, r53, r51) + r55 = r54 >= 0 :: signed + r56 = '' + r57 = __main__.globals :: static + r58 = 'Lol' + r59 = CPyDict_GetItem(r57, r58) + r60 = box(short_int, 2) + r61 = PyObject_CallFunctionObjArgs(r59, r60, r56, 0) + r62 = cast(tuple, r61) r63 = __main__.globals :: static - r64 = 'List' - r65 = CPyDict_GetItem(r63, r64) - r66 = load_address PyLong_Type - r67 = PyObject_GetItem(r65, r66) - r68 = __main__.globals :: static - r69 = 'Foo' - r70 = CPyDict_SetItem(r68, r69, r67) - r71 = r70 >= 0 :: signed - r72 = 'Bar' - r73 = __main__.globals :: static - r74 = 'Foo' - r75 = CPyDict_GetItem(r73, r74) - r76 = __main__.globals :: static - r77 = 'NewType' - r78 = CPyDict_GetItem(r76, r77) - r79 = PyObject_CallFunctionObjArgs(r78, r72, r75, 0) + r64 = 'x' + r65 = CPyDict_SetItem(r63, r64, r62) + r66 = r65 >= 0 :: signed + r67 = __main__.globals :: static + r68 = 'List' + r69 = CPyDict_GetItem(r67, r68) + r70 = load_address PyLong_Type + r71 = PyObject_GetItem(r69, r70) + r72 = __main__.globals :: static + r73 = 'Foo' + r74 = CPyDict_SetItem(r72, r73, r71) + r75 = r74 >= 0 :: signed + r76 = 'Bar' + r77 = __main__.globals :: static + r78 = 'Foo' + r79 = CPyDict_GetItem(r77, r78) r80 = __main__.globals :: static - r81 = 'Bar' - r82 = CPyDict_SetItem(r80, r81, r79) - r83 = r82 >= 0 :: signed - r84 = PyList_New(3) - r85 = box(short_int, 2) - r86 = box(short_int, 4) - r87 = box(short_int, 6) - r88 = get_element_ptr r84 ob_item :: PyListObject - r89 = load_mem r88 :: ptr* - set_mem r89, r85 :: builtins.object* - r90 = r89 + WORD_SIZE*1 - set_mem r90, r86 :: builtins.object* - r91 = r89 + WORD_SIZE*2 - set_mem r91, r87 :: builtins.object* - keep_alive r84 - r92 = __main__.globals :: static - r93 = 'Bar' - r94 = CPyDict_GetItem(r92, r93) - r95 = PyObject_CallFunctionObjArgs(r94, r84, 0) + r81 = 'NewType' + r82 = CPyDict_GetItem(r80, r81) + r83 = PyObject_CallFunctionObjArgs(r82, r76, r79, 0) + r84 = __main__.globals :: static + r85 = 'Bar' + r86 = CPyDict_SetItem(r84, r85, r83) + r87 = r86 >= 0 :: signed + r88 = PyList_New(3) + r89 = box(short_int, 2) + r90 = box(short_int, 4) + r91 = box(short_int, 6) + r92 = get_element_ptr r88 ob_item :: PyListObject + r93 = load_mem r92 :: ptr* + set_mem r93, r89 :: builtins.object* + r94 = r93 + WORD_SIZE*1 + set_mem r94, r90 :: builtins.object* + r95 = r93 + WORD_SIZE*2 + set_mem r95, r91 :: builtins.object* + keep_alive r88 r96 = __main__.globals :: static - r97 = 'y' - r98 = CPyDict_SetItem(r96, r97, r95) - r99 = r98 >= 0 :: signed + r97 = 'Bar' + r98 = CPyDict_GetItem(r96, r97) + r99 = PyObject_CallFunctionObjArgs(r98, r88, 0) + r100 = __main__.globals :: static + r101 = 'y' + r102 = CPyDict_SetItem(r100, r101, r99) + r103 = r102 >= 0 :: signed return 1 [case testChainedConditional] @@ -3003,9 +3006,8 @@ def __top_level__(): r7 :: list r8, r9 :: ptr r10 :: str - r11, r12 :: object - r13 :: dict - r14 :: str + r11 :: object + r12, r13, r14 :: str r15 :: object r16 :: str r17 :: int32 @@ -3043,12 +3045,12 @@ L2: r10 = 'typing' r11 = PyImport_ImportModuleLevelObject(r10, r5, 0, r7, 0) typing = r11 :: module - r12 = typing :: module - r13 = __main__.globals :: static + r12 = 'typing' + r13 = 'Callable' r14 = 'Callable' - r15 = CPyObject_GetAttr(r12, r14) + r15 = CPyImport_ImportFrom(r11, r12, r13, r14) r16 = 'Callable' - r17 = CPyDict_SetItem(r13, r16, r15) + r17 = CPyDict_SetItem(r5, r16, r15) r18 = r17 >= 0 :: signed r19 = __main__.globals :: static r20 = '__mypyc_c_decorator_helper__' @@ -3145,9 +3147,8 @@ def __top_level__(): r7 :: list r8, r9 :: ptr r10 :: str - r11, r12 :: object - r13 :: dict - r14 :: str + r11 :: object + r12, r13, r14 :: str r15 :: object r16 :: str r17 :: int32 @@ -3172,12 +3173,12 @@ L2: r10 = 'typing' r11 = PyImport_ImportModuleLevelObject(r10, r5, 0, r7, 0) typing = r11 :: module - r12 = typing :: module - r13 = __main__.globals :: static + r12 = 'typing' + r13 = 'Callable' r14 = 'Callable' - r15 = CPyObject_GetAttr(r12, r14) + r15 = CPyImport_ImportFrom(r11, r12, r13, r14) r16 = 'Callable' - r17 = CPyDict_SetItem(r13, r16, r15) + r17 = CPyDict_SetItem(r5, r16, r15) r18 = r17 >= 0 :: signed return 1 diff --git a/mypyc/test-data/irbuild-classes.test b/mypyc/test-data/irbuild-classes.test index 5962c2498768..58dd99b180bc 100644 --- a/mypyc/test-data/irbuild-classes.test +++ b/mypyc/test-data/irbuild-classes.test @@ -296,80 +296,78 @@ def __top_level__(): r8 :: list r9, r10, r11 :: ptr r12 :: str - r13, r14 :: object - r15 :: dict - r16 :: str + r13 :: object + r14, r15, r16 :: str r17 :: object r18 :: str r19 :: int32 r20 :: bit - r21 :: str - r22 :: object - r23 :: str - r24 :: int32 - r25 :: bit - r26 :: dict - r27 :: str - r28 :: list - r29, r30 :: ptr - r31 :: str - r32, r33 :: object - r34 :: dict - r35 :: str - r36 :: object - r37 :: str - r38 :: int32 - r39 :: bit - r40 :: str - r41 :: dict + r21, r22, r23 :: str + r24 :: object + r25 :: str + r26 :: int32 + r27 :: bit + r28 :: dict + r29 :: str + r30 :: list + r31, r32 :: ptr + r33 :: str + r34 :: object + r35, r36, r37 :: str + r38 :: object + r39 :: str + r40 :: int32 + r41 :: bit r42 :: str - r43, r44 :: object - r45 :: dict - r46 :: str - r47 :: int32 - r48 :: bit - r49 :: object - r50 :: str - r51, r52 :: object - r53 :: bool - r54 :: str - r55 :: tuple - r56 :: int32 - r57 :: bit - r58 :: dict - r59 :: str - r60 :: int32 - r61 :: bit - r62 :: object - r63 :: str - r64, r65 :: object - r66 :: str - r67 :: tuple - r68 :: int32 - r69 :: bit - r70 :: dict - r71 :: str - r72 :: int32 - r73 :: bit - r74, r75 :: object - r76 :: dict - r77 :: str - r78 :: object - r79 :: dict - r80 :: str - r81, r82 :: object - r83 :: tuple - r84 :: str - r85, r86 :: object - r87 :: bool - r88, r89 :: str - r90 :: tuple - r91 :: int32 - r92 :: bit - r93 :: dict - r94 :: str - r95 :: int32 - r96 :: bit + r43 :: dict + r44 :: str + r45, r46 :: object + r47 :: dict + r48 :: str + r49 :: int32 + r50 :: bit + r51 :: object + r52 :: str + r53, r54 :: object + r55 :: bool + r56 :: str + r57 :: tuple + r58 :: int32 + r59 :: bit + r60 :: dict + r61 :: str + r62 :: int32 + r63 :: bit + r64 :: object + r65 :: str + r66, r67 :: object + r68 :: str + r69 :: tuple + r70 :: int32 + r71 :: bit + r72 :: dict + r73 :: str + r74 :: int32 + r75 :: bit + r76, r77 :: object + r78 :: dict + r79 :: str + r80 :: object + r81 :: dict + r82 :: str + r83, r84 :: object + r85 :: tuple + r86 :: str + r87, r88 :: object + r89 :: bool + r90, r91 :: str + r92 :: tuple + r93 :: int32 + r94 :: bit + r95 :: dict + r96 :: str + r97 :: int32 + r98 :: bit L0: r0 = builtins :: module r1 = load_address _Py_NoneStruct @@ -393,95 +391,97 @@ L2: r12 = 'typing' r13 = PyImport_ImportModuleLevelObject(r12, r5, 0, r8, 0) typing = r13 :: module - r14 = typing :: module - r15 = __main__.globals :: static + r14 = 'typing' + r15 = 'TypeVar' r16 = 'TypeVar' - r17 = CPyObject_GetAttr(r14, r16) + r17 = CPyImport_ImportFrom(r13, r14, r15, r16) r18 = 'TypeVar' - r19 = CPyDict_SetItem(r15, r18, r17) + r19 = CPyDict_SetItem(r5, r18, r17) r20 = r19 >= 0 :: signed - r21 = 'Generic' - r22 = CPyObject_GetAttr(r14, r21) + r21 = 'typing' + r22 = 'Generic' r23 = 'Generic' - r24 = CPyDict_SetItem(r15, r23, r22) - r25 = r24 >= 0 :: signed - r26 = __main__.globals :: static - r27 = 'trait' - r28 = PyList_New(1) - r29 = get_element_ptr r28 ob_item :: PyListObject - r30 = load_mem r29 :: ptr* - set_mem r30, r27 :: builtins.object* - keep_alive r28 - r31 = 'mypy_extensions' - r32 = PyImport_ImportModuleLevelObject(r31, r26, 0, r28, 0) - mypy_extensions = r32 :: module - r33 = mypy_extensions :: module - r34 = __main__.globals :: static - r35 = 'trait' - r36 = CPyObject_GetAttr(r33, r35) + r24 = CPyImport_ImportFrom(r13, r21, r22, r23) + r25 = 'Generic' + r26 = CPyDict_SetItem(r5, r25, r24) + r27 = r26 >= 0 :: signed + r28 = __main__.globals :: static + r29 = 'trait' + r30 = PyList_New(1) + r31 = get_element_ptr r30 ob_item :: PyListObject + r32 = load_mem r31 :: ptr* + set_mem r32, r29 :: builtins.object* + keep_alive r30 + r33 = 'mypy_extensions' + r34 = PyImport_ImportModuleLevelObject(r33, r28, 0, r30, 0) + mypy_extensions = r34 :: module + r35 = 'mypy_extensions' + r36 = 'trait' r37 = 'trait' - r38 = CPyDict_SetItem(r34, r37, r36) - r39 = r38 >= 0 :: signed - r40 = 'T' - r41 = __main__.globals :: static - r42 = 'TypeVar' - r43 = CPyDict_GetItem(r41, r42) - r44 = PyObject_CallFunctionObjArgs(r43, r40, 0) - r45 = __main__.globals :: static - r46 = 'T' - r47 = CPyDict_SetItem(r45, r46, r44) - r48 = r47 >= 0 :: signed - r49 = :: object - r50 = '__main__' - r51 = __main__.C_template :: type - r52 = CPyType_FromTemplate(r51, r49, r50) - r53 = C_trait_vtable_setup() - r54 = '__mypyc_attrs__' - r55 = PyTuple_Pack(0) - r56 = PyObject_SetAttr(r52, r54, r55) - r57 = r56 >= 0 :: signed - __main__.C = r52 :: type - r58 = __main__.globals :: static - r59 = 'C' - r60 = CPyDict_SetItem(r58, r59, r52) - r61 = r60 >= 0 :: signed - r62 = :: object - r63 = '__main__' - r64 = __main__.S_template :: type - r65 = CPyType_FromTemplate(r64, r62, r63) - r66 = '__mypyc_attrs__' - r67 = PyTuple_Pack(0) - r68 = PyObject_SetAttr(r65, r66, r67) - r69 = r68 >= 0 :: signed - __main__.S = r65 :: type - r70 = __main__.globals :: static - r71 = 'S' - r72 = CPyDict_SetItem(r70, r71, r65) - r73 = r72 >= 0 :: signed - r74 = __main__.C :: type - r75 = __main__.S :: type - r76 = __main__.globals :: static - r77 = 'Generic' - r78 = CPyDict_GetItem(r76, r77) - r79 = __main__.globals :: static - r80 = 'T' - r81 = CPyDict_GetItem(r79, r80) - r82 = PyObject_GetItem(r78, r81) - r83 = PyTuple_Pack(3, r74, r75, r82) - r84 = '__main__' - r85 = __main__.D_template :: type - r86 = CPyType_FromTemplate(r85, r83, r84) - r87 = D_trait_vtable_setup() - r88 = '__mypyc_attrs__' - r89 = '__dict__' - r90 = PyTuple_Pack(1, r89) - r91 = PyObject_SetAttr(r86, r88, r90) - r92 = r91 >= 0 :: signed - __main__.D = r86 :: type - r93 = __main__.globals :: static - r94 = 'D' - r95 = CPyDict_SetItem(r93, r94, r86) - r96 = r95 >= 0 :: signed + r38 = CPyImport_ImportFrom(r34, r35, r36, r37) + r39 = 'trait' + r40 = CPyDict_SetItem(r28, r39, r38) + r41 = r40 >= 0 :: signed + r42 = 'T' + r43 = __main__.globals :: static + r44 = 'TypeVar' + r45 = CPyDict_GetItem(r43, r44) + r46 = PyObject_CallFunctionObjArgs(r45, r42, 0) + r47 = __main__.globals :: static + r48 = 'T' + r49 = CPyDict_SetItem(r47, r48, r46) + r50 = r49 >= 0 :: signed + r51 = :: object + r52 = '__main__' + r53 = __main__.C_template :: type + r54 = CPyType_FromTemplate(r53, r51, r52) + r55 = C_trait_vtable_setup() + r56 = '__mypyc_attrs__' + r57 = PyTuple_Pack(0) + r58 = PyObject_SetAttr(r54, r56, r57) + r59 = r58 >= 0 :: signed + __main__.C = r54 :: type + r60 = __main__.globals :: static + r61 = 'C' + r62 = CPyDict_SetItem(r60, r61, r54) + r63 = r62 >= 0 :: signed + r64 = :: object + r65 = '__main__' + r66 = __main__.S_template :: type + r67 = CPyType_FromTemplate(r66, r64, r65) + r68 = '__mypyc_attrs__' + r69 = PyTuple_Pack(0) + r70 = PyObject_SetAttr(r67, r68, r69) + r71 = r70 >= 0 :: signed + __main__.S = r67 :: type + r72 = __main__.globals :: static + r73 = 'S' + r74 = CPyDict_SetItem(r72, r73, r67) + r75 = r74 >= 0 :: signed + r76 = __main__.C :: type + r77 = __main__.S :: type + r78 = __main__.globals :: static + r79 = 'Generic' + r80 = CPyDict_GetItem(r78, r79) + r81 = __main__.globals :: static + r82 = 'T' + r83 = CPyDict_GetItem(r81, r82) + r84 = PyObject_GetItem(r80, r83) + r85 = PyTuple_Pack(3, r76, r77, r84) + r86 = '__main__' + r87 = __main__.D_template :: type + r88 = CPyType_FromTemplate(r87, r85, r86) + r89 = D_trait_vtable_setup() + r90 = '__mypyc_attrs__' + r91 = '__dict__' + r92 = PyTuple_Pack(1, r91) + r93 = PyObject_SetAttr(r88, r90, r92) + r94 = r93 >= 0 :: signed + __main__.D = r88 :: type + r95 = __main__.globals :: static + r96 = 'D' + r97 = CPyDict_SetItem(r95, r96, r88) + r98 = r97 >= 0 :: signed return 1 [case testIsInstance] diff --git a/mypyc/test-data/run-imports.test b/mypyc/test-data/run-imports.test index cff07f158190..0957d1b2b87f 100644 --- a/mypyc/test-data/run-imports.test +++ b/mypyc/test-data/run-imports.test @@ -100,16 +100,43 @@ def h(x): return x * 3 [case testFromImportWithKnownModule] -from pkg import mod +from pkg import mod1 +from pkg import mod2 as modmod +from pkg.mod2 import g as gg +from pkg.mod3 import h as h2, g as g2 def test_import() -> None: - assert mod.h(8) == 24 + assert mod1.h(8) == 24 + assert modmod.g(1) == 1 + assert gg(2) == 2 + assert h2(10) == 12 + assert g2(10) == 13 [file pkg/__init__.py] -[file pkg/mod.py] +[file pkg/mod1.py] def h(x: int) -> int: return x * 3 +[file pkg/mod2.py] +def g(x: int) -> int: + return x + +[file pkg/mod3.py] +def h(x: int) -> int: + return x + 2 + +def g(x: int) -> int: + return x + 3 + +[case testFromImportWithUnKnownModule] +def test_import() -> None: + try: + from pkg import a # type: ignore + except ImportError: + pass + +[file pkg/__init__.py] + [case testMultipleFromImportsWithSamePackageButDifferentModules] from pkg import a from pkg import b