homepage

This issue tracker has been migrated to GitHub , and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: ImportError using __import__ and relative level 1
Type: Stage:
Components: Interpreter Core Versions: Python 2.7
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: brett.cannon, eric.snow, jaraco, ncoghlan
Priority: normal Keywords:

Created on 2012年01月30日 17:00 by jaraco, last changed 2022年04月11日 14:57 by admin. This issue is now closed.

Messages (12)
msg152331 - (view) Author: Jason R. Coombs (jaraco) * (Python committer) Date: 2012年01月30日 17:00
The Python 2.7.2 docs say this about __import__:
 Positive values for level indicate the number of parent directories to search relative to the directory of the module calling __import__().
But I find that even when setting level=1, the parent directory is not searched.
I've created this project tree to replicate the issue:
 jaraco@devjaraco:~$ tree master
 master
 ├── __init__.py
 ├── pkgA
 │  ├── foo.py
 │  └── __init__.py
 └── pkgB
 ├── bar.py
 └── __init.py
 2 directories, 5 files
 jaraco@devjaraco:~$ cat master/pkgA/foo.py
 bar = __import__('pkgB', level=1).bar
 jaraco@devjaraco:~$ cat master/pkgB/bar.py
 var = "success"
It fails as so with python 2.7.2:
 jaraco@devjaraco:~$ python2.7 -c "import master.pkgA.foo"
 Traceback (most recent call last):
 File "<string>", line 1, in <module>
 File "master/pkgA/foo.py", line 2, in <module>
 bar = __import__('pkgB', level=1).bar
 ImportError: No module named pkgB
It's conceivable I'm not using this correctly, but if so, I'm unable to find my mistake. I've confirmed that foo.__name__ is 'master.pkgA.foo'. I've tried using level=2 (in case I was off by one, but that wasn't the case).
msg152336 - (view) Author: Eric Snow (eric.snow) * (Python committer) Date: 2012年01月30日 17:35
what value do you see for __package__ in pkgA?
msg152341 - (view) Author: Brett Cannon (brett.cannon) * (Python committer) Date: 2012年01月30日 18:05
You have a typo in a filename: it should be pkgB/__init__.py (not the missing trailing underscores).
msg152342 - (view) Author: Jason R. Coombs (jaraco) * (Python committer) Date: 2012年01月30日 19:31
Sorry for the mistake.
I corrected the pkgB package, but the result is the same:
 jaraco@devjaraco:~$ tree master
 master
 ├── __init__.py
 ├── __init__.pyc
 ├── pkgA
 │  ├── foo.py
 │  ├── foo.pyc
 │  ├── __init__.py
 │  └── __init__.pyc
 └── pkgB
 ├── bar.py
 └── __init__.py
 2 directories, 8 files
 jaraco@devjaraco:~$ python2.7 -c 'import master.pkgA; print("pkgA.__package__ is {}".format(master.pkgA.__package__)); import master.pkgA.foo'
 pkgA.__package__ is None
 Traceback (most recent call last):
 File "<string>", line 1, in <module>
 File "master/pkgA/foo.py", line 2, in <module>
 bar = __import__('pkgB', level=1).bar
 ImportError: No module named pkgB
As you can see, __package__ for pkgA is None. Same is true for master.__package__.
msg152354 - (view) Author: Brett Cannon (brett.cannon) * (Python committer) Date: 2012年01月30日 22:42
I see your mistake now: you need to call it as __import__('pkgB', globals(), index=1), else __import__ has no clue how to anchor your import in the relative package space.
Try that and let me know if it makes it work.
And why exactly are you trying to call __import__ directly? You should be using importlib.import_module() for programmatic imports.
msg152357 - (view) Author: Jason R. Coombs (jaraco) * (Python committer) Date: 2012年01月30日 23:05
Thanks for the tip Brent. Still, no luck.
 jaraco@devjaraco:~$ python2.7 -c 'import master.pkgA; print("pkgA.__package__ is {}".format(master.pkgA.__package__)); import master.pkgA.foo'
 pkgA.__package__ is None
 Traceback (most recent call last):
 File "<string>", line 1, in <module>
 File "master/pkgA/foo.py", line 2, in <module>
 bar = __import__('pkgB', globals(), level=1).bar
 ImportError: No module named pkgB
I considered importlib, but it is only included for Python 2.7+ and I have to support Python 2.6. I'm using programmatic imports for a few reasons:
1) I'm importing the modules for the side effects, so I don't need or want the name in the namespace.
2) If I import it naturally, I get pyflakes warnings that it's an used imports.
3) The order of imports is important. If I place it too early in the imports, it doesn't have the state it needs and fails.
4) By placing it in the top of the file with other imports, it's not obvious why it's being imported, so requires comments.
5) The most appropriate place to invoke this functionality is in a specific function, "run_app".
I see now that there is an importlib backport in the cheeseshop for earlier versions of Python. Given your recommendation, I'll give that a try.
msg152361 - (view) Author: Eric Snow (eric.snow) * (Python committer) Date: 2012年01月30日 23:33
Jason: just a warning. importlib_backport is a relatively naive tool for generating the backport from the py3k source. It's also relatively fragile and at this point probably doesn't work with the default branch.
msg152365 - (view) Author: Eric Snow (eric.snow) * (Python committer) Date: 2012年01月31日 01:46
The problem is your level is off and the name is incomplete. master.pkgA.foo.py should have the following:
__import__('pkgB.bar', master.pkgA.__dict__, level=2).bar
or 
__import__('pkgB.bar', master.pkgA.__dict__, fromlist=['-'], level=2)
msg152375 - (view) Author: Alyssa Coghlan (ncoghlan) * (Python committer) Date: 2012年01月31日 12:02
It sounds like you may want runpy.run_module [1], rather than using imports at all. If you know how many levels up you want to go, it isn't hard to do your own munging of __name__ to create absolute module references to pass to runpy.
The signature of __import__ is known to be unintuitive to the point of being insane - it's really designed for the convenience of the compiler and the interpreter, not for direct use by humans.
[1] http://docs.python.org/release/2.6.7/library/runpy#runpy.run_module 
msg152391 - (view) Author: Brett Cannon (brett.cannon) * (Python committer) Date: 2012年01月31日 16:01
On Mon, Jan 30, 2012 at 18:33, Eric Snow <report@bugs.python.org> wrote:
>
> Eric Snow <ericsnowcurrently@gmail.com> added the comment:
>
> Jason: just a warning. importlib_backport is a relatively naive tool for
> generating the backport from the py3k source. It's also relatively fragile
> and at this point probably doesn't work with the default branch.
>
I think Jason was thinking of http://pypi.python.org/pypi/importlib/ which
is my personal backport of importlib from Python 2.7 all the way back to
Python 2.3.
msg175263 - (view) Author: Eric Snow (eric.snow) * (Python committer) Date: 2012年11月10日 05:42
Are you okay on this, Jason?
msg175288 - (view) Author: Jason R. Coombs (jaraco) * (Python committer) Date: 2012年11月10日 16:44
Yes. Since Nick's comment , I've been using importlib for all programmatic imports with great success.
History
Date User Action Args
2022年04月11日 14:57:26adminsetgithub: 58120
2012年11月10日 16:44:45jaracosetstatus: pending -> closed
resolution: not a bug
messages: + msg175288
2012年11月10日 05:42:56eric.snowsetstatus: open -> pending

messages: + msg175263
2012年01月31日 16:01:04brett.cannonsetmessages: + msg152391
2012年01月31日 12:02:07ncoghlansetnosy: + ncoghlan
messages: + msg152375
2012年01月31日 01:46:53eric.snowsetmessages: + msg152365
2012年01月30日 23:33:30eric.snowsetmessages: + msg152361
2012年01月30日 23:05:30jaracosetmessages: + msg152357
2012年01月30日 22:42:25brett.cannonsetmessages: + msg152354
2012年01月30日 19:31:05jaracosetstatus: closed -> open
resolution: not a bug -> (no value)
messages: + msg152342
2012年01月30日 18:05:06brett.cannonsetstatus: open -> closed

nosy: + brett.cannon
messages: + msg152341

resolution: not a bug
2012年01月30日 17:35:25eric.snowsetnosy: + eric.snow
messages: + msg152336
2012年01月30日 17:00:47jaracocreate

AltStyle によって変換されたページ (->オリジナル) /