What does 'from dot import asterisk' do in Python 3? - python

Question
What does the following line do in Python 3?
>>> from . import *
What I found out so far...
It does not output anything and the only change I can see in Python 3.7.3 is the following:
>>> '__warningregistry__' in locals()
False
>>> from . import *
>>> '__warningregistry__' in locals()
True
>>> locals()['__warningregistry__']
{'version': 0}
This might be part of the warnings module and indicates that there is a warning somewhere which is not printed, but the documentation mentions only a variable __warningregistry__ in the the module warnings.
The documentation explains how from . import foo works, and how from bar import * works, but I couldn't find anything about from . import *. One might expect that all names from __init__.py are loaded into the current name space (as from bla import * would do for bla.py) but this doesn't seem to be the case and also it doesn't make sense when __name__ == '__main__' (scripts and terminal).
Python 2 behaves more similar to what I had expected:
>>> # Python 2.7.16
>>> from . import *
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: Attempted relative import in non-package
PEP 328 is quite illuminative but doesn't answer my question either.

When __main__ is a script or interactive session, . is the __main__ package itself:
$ python3 -c 'from . import float'
Traceback (most recent call last):
File "<string>", line 1, in <module>
ImportError: cannot import name 'float' from '__main__' (unknown location)
This makes from . import * a noop, with __warningregistry__ added as a side-effect of the import machinery.
Relative imports from __main__ were special-cased by PEP 366. This introduced __package__ for relative package name lookup, and specifies that __main__. __package__ has the special value None.
In addition, the module import spec __main__.__spec__ may be None - namely in an interactive shell or when executing a script.
As it turns out, any module with __package__ = __spec__ = None will treat . as itself:
$ cat test.py
__package__ = __spec__ = None
from . import float
$ python3 -c 'import test'
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/Users/mfischer/PycharmProjects/lispy/test.py", line 2, in <module>
from . import float
ImportError: cannot import name 'float' from 'test' (./test.py)
The __warningregistry__ is added because there is a hidden warning from the missing attributes. It is suppressed by default, but you can see it with all warning enabled:
$ python3 -Wa -c 'from . import float'
-c:1: ImportWarning: can't resolve package from __spec__ or __package__, falling back on __name__ and __path__
Traceback (most recent call last):
File "<string>", line 1, in <module>
ImportError: cannot import name 'float' from '__main__' (unknown location)

Related

Python nested subpackage doesn't import when running tests

I have a folder structure like this:
api
-- test
-- test_api.py
-- __init__.py
-- api
-- api.py
-- __init__.py
-- sub
-- sub.py
-- __init__.py
sub.py:
Base = 'base'
api.py:
from sub.sub import Base
def stuff_to_test():
pass
test_api.py:
from api.api import stuff_to_test
def test_stuff_to_test():
stuff_to_test()
I am in directory api.
I run pytest:
==================================== ERRORS ====================================
______________________ ERROR collecting tests/test_api.py ______________________
ImportError while importing test module '/<somepath>/api/tests/test_api.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
tests/test_api.py:1: in <module>
from ..api.api import stuff_to_test
api/__init__.py:1: in <module>
from . import api
api/api.py:1: in <module>
from sub.sub import Base
E ImportError: No module named 'sub'
!!!!!!!!!!!!!!!!!!! Interrupted: 1 errors during collection !!!!!!!!!!!!!!!!!!!!
=========================== 1 error in 0.08 seconds ============================
Same happens if I run the python interpreter and import stuff from test_api.py:
>>> from tests.test_api import *
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/<somepath>/api/tests/test_api.py", line 1, in <module>
from api.api import stuff_to_test
File "/<somepath>/api/api/__init__.py", line 1, in <module>
from . import api
File "/<somepath>/api/api/api.py", line 1, in <module>
from sub.sub import Base
ImportError: No module named 'sub'
My first idea was to make the import in api.py relative:
from .sub.sub import Base
This way tests run fine.
But if I run python api/api.py I get this error:
Traceback (most recent call last):
File "api/api.py", line 1, in <module>
from .sub.sub import Base
SystemError: Parent module '' not loaded, cannot perform relative import
How can I have it so tests run and application runs?
I solved it by adding the following to test.__init__.py
project_path = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
api_path= os.path.join(project_path, 'api')
sys.path.append(api_path)
In python there are two ways to import a module, with a relative path or with an absolute path.
When you write from sub.sub import Base you are doing an absolute path import, for a relative path import write from .sub.sub import Base.
An absolute path import go look in the PYTHONPATH to find the starting point of your import, so you should write from api.sub.sub import Base.
For more information: Absolute vs. explicit relative import of Python module

Is there any module implicitly imported/loaded?

When starting the interactive Python interpreter with default
settings, is there any module implicitly imported/loaded into the
interpreter, without explicitly running import <modulename>?
I thought that modules like sys or builtins would be, but when I
type their module names,
>>> sys
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'sys' is not defined
>>> builtins
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'builtins' is not defined
So is it correct that by default, there is no module imported/loaded implicitly?
When executing a python script, is there any module implicitly
imported/loaded into the script, without explicitly specifying
import <modulename> in the script?
Thanks.
One module that is usually imported automatically is site.py. And it imports a lot of other modules. But even if you prevent it from importing using option -S Python still imports many modules. Try the following script:
#! /usr/bin/python2.7 -ESs
import sys
print(sys.modules)
and see how many modules are there. Change shebang to
#! /usr/bin/python3 -EISs
and say "Wow!" :-)
Only __builtins__:
#! /usr/bin/python2.7 -ESs
print(dir())
=> ['__builtins__', '__doc__', '__file__', '__name__', '__package__']

python absolute import of submodule fails

I have seen other posts but did not find answer that worked!
File structure
my_package/
__init__.py -- empty
test/
__init__.py -- empty
test1.py
Fail
from my_package import test
test.test1
gives
AttributeError: 'module' object has no attribute test
Following Passes
from my_package.test import test1
# or
import my_package.test.test1
from my_package import test
# now this works
test.tes1
<module 'my_package.test.test1' from ...
I have
from __future__ import absolute_import
in all files, and using python2.7
When you import a package (like test), the modules (like test1) are not automatically imported (unless perhaps you put some special code to do so in __init__.py). This is different from importing a module, where the contents of the module are available in the modules namespace. Compare with the Python standard library's xml.etree.ElementTree module:
>>> import xml
>>> xml.etree
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'etree'
>>> from xml import etree
>>> etree.ElementTree
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'ElementTree'
>>> from xml.etree import ElementTree
>>> ElementTree.ElementTree
<class 'xml.etree.ElementTree.ElementTree'>

How can you find where python imported a particular module from?

How can you find where python imported a particular module from?
Each module object has a __file__ attribute:
import module
print module.__file__
Some modules are part of the Python executable; these will not have the attribute set.
Demo:
>>> import urllib2
>>> urllib2.__file__
'/Users/mj/Development/Library/buildout.python/parts/opt/lib/python2.7/urllib2.pyc'
>>> import sys
>>> sys.__file__
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute '__file__'
You could also run Python in verbose mode, with the -v command line switch or the PYTHONVERBOSE environment variable; Python then prints out every imported file as it takes place.

How to mock python module in unittest

I have a problem when mocking in unittest.
#!/usr/bin/env python
import sys
sys.modules["foo.Bar"] = __import__("mock_bar")
import foo.Bar
print foo.Bar.__name__
I've got an ImportError exception in line 4. I don't know why since I have do some mock at line 3. There is a reference of how to mock import here.
Here's the error message:
Traceback (most recent call last):
File "test.py", line 4, in <module>
import foo.Bar
ImportError: No module named foo.Bar
"import foo.Bar" should equal to "__import__('foo.Bar')", and before that I've hacked sys.modules to pretend module 'foo.Bar' has been already imported. Why python still try to import foo.Bar and complain?
Try doing import foo before your __import__ line: I think it could help.

Categories

Resources