Wang
Wang

Reputation: 8173

the importlib.import_module has strange behavior in python3.5

The importlib.import_module with relative module name can fail sometime.

For example, I have a package structure like this:

├── test0
│   ├── __init__.py
│   ├── test1.py
│   └── test2.py
├── test_impl.py

Test code like this:

import importlib
import sys
print(sys.version_info)
def test_imp_module(module_name, pkgname):
    try:
        _m = importlib.import_module(module_name, pkgname)
        print("import OK: module={}, pkg={}".format(module_name, pkgname))
    except Exception as e:
        print(e)

test_imp_module(".test1", "test0")
test_imp_module("test0.test1", "")
if __name__ == '__main__':
    test_imp_module(".test1", "test0")
    test_imp_module("test0.test1", "")

In Python3.5 it will fail the first test:

$ python3 test_impl.py 
sys.version_info(major=3, minor=5, micro=2, releaselevel='final', serial=0)
Parent module 'test0' not loaded, cannot perform relative import
import OK: module=test0.test1, pkg=
import OK: module=.test1, pkg=test0
import OK: module=test0.test1, pkg=

In python3.6 it works:

$ python3 test_impl.py 
sys.version_info(major=3, minor=6, micro=4, releaselevel='final', serial=0)
import OK: module=.test1, pkg=test0
import OK: module=test0.test1, pkg=
import OK: module=.test1, pkg=test0
import OK: module=test0.test1, pkg=

Is this expected or a bug? Update: Python2.7.12 has the same behavior as 3.6.

Upvotes: 2

Views: 346

Answers (1)

wim
wim

Reputation: 362786

The docs say:

importlib.import_module(name, package=None)

...

Changed in version 3.3: Parent packages are automatically imported.

Therefore, the 3.6.4 behaviour is correct and the 3.5.2 behaviour is buggy. You seem to be hitting #30876, and the issue says that was fixed in the version 5 micro i.e. v3.5.5.

Credit to vaultah in room 6 for finding the ticket.

Upvotes: 3

Related Questions