echo
echo

Reputation: 255

Python import statement without a from clause imports a class not a module

As shown in the simple test case below, an import statement imports a class instead of a module with the same name, when that class is imported in the package's __init__.py.

Is this the expected behavior, or a bug? Whichever the case, it would be helpful if anyone could cite any relevant documentation or bug reports. If a bug, it would be useful to know what the intended behavior is: should the module pkg.a be imported, or should an error be raised?

Package layout

C:\...\imp_test
|
\---pkg
        a.py
        __init__.py

Files

__init__.py

from .a import a

a.py

class a:
    pass

Result

C:\...\imp_test> python
Python 3.7.1 (default, Dec 10 2018, 22:54:23)
[MSC v.1915 64 bit (AMD64)] :: Anaconda custom (64-bit) on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import pkg.a
>>> type(pkg.a)
<class 'type'>
>>> var = pkg.a()
>>>

Upvotes: 1

Views: 193

Answers (1)

user3643324
user3643324

Reputation: 105

Updated:

This is a namespace collision between the module binding a in pkg and the variable binding a in pkg. This is expected behaviour as described here

Old:

I believe this is because of the finder used by the import statement. The finder will search the package first before the module path, and because it finds a path that matches it immediately returns.

I took a look at the python import docs here and found this little snippet

When the name variable is of the form package.module, normally, the top-level package (the name up till the first dot) is returned, not the module named by name. However, when a non-empty fromlist argument is given, the module named by name is returned.

If you want to force a module import you can use the import_module function

import importlib
a = importlib.import_module('pkg.a')

Upvotes: 2

Related Questions