ipython's strange behavior with directories named "code" - python

I can't import anything from directories named "code".
I have the following directory structure:
In [1]: ls
code/ data/ pickles/
code_copy/ documentation/ submissions/
code_copy is an exact copy of code
In [2]: ls code_copy/
santander.py
__init__.py santander.pyc
In [3]: ls code
santander.py
__init__.py santander.pyc
However, the behavior of these two directories is different when I try to import something from them. For example, I can't import santander.py from code
In [4]: from code.
code.InteractiveConsole code.compile_command
code.InteractiveInterpreter code.interact
In [5]: from code import santander
---------------------------------------------------------------------------
ImportError Traceback (most recent call last)
<ipython-input-20-e36a94117eb8> in <module>()
----> 1 from code import santander
ImportError: cannot import name santander
while I'm able to do it from code_copy
In [6]: from code_copy.
code_copy.santander
In [7]: from code_copy import santander
In [8]:
Is this ipython's behavior normal? Is "code" a especial name? How can this be fixed?

Related

Import problem when launched from Python embedded

Let's say we have this file structure (downloadable MCVE here .zip):
xyz/
xyz/__init__.py <empty>
xyz/app.py from xyz import XYZ
xyz/xyz.py import ghi; print("hello xyz.py");
class XYZ: pass
xyz/ghi/__init__.py from .ghi_main import *
xyz/ghi/ghi_main.py print("hello ghi_main.py")
From the parent folder, running
python xyz/app.py
with the system-wide python works without error.
On the other hand, if we use an embedded python.exe:
python.exe
<+ other files from python-3.8.10-embed-amd64.zip>
xyz/
xyz/__init__.py
xyz/app.py
etc.
then it fails with:
Traceback (most recent call last):
File "xyz\app.py", line 1, in
from xyz import XYZ
ImportError: cannot import name 'XYZ' from 'xyz' (D:\Temp\xyz_init_.py)
Why?

Error when importing python module from folders

I have a following directory structure:
source
source_1.py
__init__.py
source1.py has class Source defined
source1.py
class Source(object):
pass
I am able to import using this
>>> from source.source1 import Source
>>> Source
<class 'source.source1.Source'>
However when trying to import using the below method it fails.
>>> from source import *
>>> source1.Source
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'source1' is not defined
Please let me know how can we use the 2nd import ?
For importing from a package (unlike importing from a module) you need to specify what * means. To do that, in __init__.py add a line like this:
__all__ = ["source1"]
See the Python documentation for Importing * From a Package.

In Python's imp, "ImportError: No frozen submodule named ..."

I'm trying to write a script which searches a directory for a module with a given name. I'd like to use the find_module method of Python's imp. However, I don't quite understand why the following doesn't work. I'm in a directory which contains a module iclib:
kurt#kurt-ThinkPad:~/dev/ipercron-compose/furion$ tree
.
├── iclib
│   ├── __init__.py
In that directory I can (in iPython) import iclib:
In [1]: import iclib
I can also use find_module without a path argument:
In [1]: import imp
In [2]: imp.find_module('iclib')
Out[2]: (None, 'iclib', ('', '', 5))
However, if I try to use find_module in the current directory only, I get an error:
In [3]: import os
In [4]: imp.find_module('iclib', os.getcwd())
---------------------------------------------------------------------------
ImportError Traceback (most recent call last)
<ipython-input-4-ada6f3744e78> in <module>()
----> 1 imp.find_module('iclib', os.getcwd())
ImportError: No frozen submodule named /home/kurt/dev/ipercron-compose/furion.iclib
Why doesn't this work?
Following this issue on bugs.python.org, the path argument needs to be embedded within a list:
In [4]: imp.find_module('iclib',[os.getcwd()])
Out[4]: (None, '/home/kurt/dev/ipercron-compose/furion/iclib', ('', '', 5))
With square brackets around the os.getcwd(), the function returns the expected output.

python from . import fails

Trying caffe python examples from: http://caffe.berkeleyvision.org/tutorial/interfaces.html gives me error:
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
caffe_root = '/opt/caffe'
import sys
sys.path.insert(0, caffe_root + 'python')
import caffe
---------------------------------------------------------------------------
ImportError Traceback (most recent call last)
<ipython-input-5-18cb333d5c1b> in <module>()
7 sys.path.insert(0, caffe_root + 'python')
8
----> 9 import caffe
...
...
/usr/lib/python2.7/site-packages/scipy/signal/__init__.py in <module>()
272 from __future__ import division, print_function, absolute_import
273
--> 274 from . import sigtools
275 from .waveforms import *
276 from ._max_len_seq import max_len_seq
ImportError: cannot import name sigtools
Apparently the sigtools import fails, but I can't figure out why. The /usr/lib/python2.7/site-packages/scipy/signal contains all files:
$ ls -1 /usr/lib/python2.7/site-packages/scipy/signal/sign*
/usr/lib/python2.7/site-packages/scipy/signal/signaltools.py
/usr/lib/python2.7/site-packages/scipy/signal/signaltools.pyc
In general, how python process directives like this, specifically what dot is resolved to if my working directory was completely different from the location where sigtools package is located?
from . import sigtools
As stated here:
`from ... import` vs `import .`
"from . import sigtools" imports the main module "." (which is "signal") than imports the object/module sigtools. If "." has been already imported it rely on that structure.
I think that this can be tricky in case you have 2 modules with the same name in the python import path: the interpreter imports the first one found and never imports the second one. If the second one has more modules than the first one, this can lead to something similar to your problem.

I want to cause an ImportError

I'm trying to reach 100% testing coverage in a bit of code that I'm writing. The following block of code, however, is giving me trouble.
try:
from south.modelsinspector import add_introspection_rules
add_introspection_rules([], ["^localized_recurrence\.duration_field\.DurationField"])
except ImportError:
pass
The code above is part of my module under test. I need to create a test (without modifying the code above) which follows the ImportError branch.
How can I programmatically cause the ImportError to occur, while only writing code in my tests?
I'd try patching sys.modules and replacing south.modelsinspector with a mock module.
See the docs on Import statement for inspiration.
In [1]: from re import sub
In [2]: import sys
In [3]: sys.modules['re'] = {}
In [4]: from re import sub
---------------------------------------------------------------------------
ImportError Traceback (most recent call last)
/home/kos/codility/frontend_v2/<ipython-input-4-6d4794835d43> in <module>()
----> 1 from re import sub
ImportError: cannot import name sub
You can do it in a narrow context by using mock.patch.dict (as a test decorator or context manager):
In [6]: with mock.patch.dict('sys.modules', {'re': {}}):
from re import sub
...:
---------------------------------------------------------------------------
ImportError Traceback (most recent call last)
<ipython-input-6-7479025ab931> in <module>()
1 with mock.patch.dict('sys.modules', {'re': {}}):
----> 2 from re import sub
3
ImportError: cannot import name sub
In [8]: from re import sub
In [9]:
You can change sys.path for the test. For example:
>>>import bs4
>>>
>>>import sys
>>>p=sys.path
>>>sys.path=['']
>>>import bs4
ImportError: No module named bs4
>>>sys.path=p
>>>import bs4
>>>
Just modify sys.path for that specific test on setUp() and later on tearDown() restore it.
Hope this helps!

Categories