classification
Title: old-style (level=-1) importing broken after importlib changes
Type: behavior Stage: resolved
Components: Interpreter Core Versions: Python 3.3
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: brett.cannon Nosy List: Arfrever, benjamin.peterson, brett.cannon, eric.snow, python-dev, scoder
Priority: normal Keywords:

Created on 2012-04-16 11:33 by scoder, last changed 2012-04-17 23:05 by brett.cannon. This issue is now closed.

Messages (12)
msg158409 - (view) Author: Stefan Behnel (scoder) * Date: 2012-04-16 11:33
Up to the early Py3.3 developer versions, calling __import__() with a level of -1 worked as in Python 2, i.e. it tried a relative import first and then a global import.

This no longer seems to be available after the importlib rewrite (e.g. as of rev f341b99bb370).
msg158437 - (view) Author: Benjamin Peterson (benjamin.peterson) * (Python committer) Date: 2012-04-16 13:14
Relative imports are no longer supported in python 3, so this makes sense.
msg158438 - (view) Author: Benjamin Peterson (benjamin.peterson) * (Python committer) Date: 2012-04-16 13:14
By "relative" I meant "sibling".
msg158466 - (view) Author: Brett Cannon (brett.cannon) * (Python committer) Date: 2012-04-16 15:27
What Benjamin said. PEP 328 should have done away with relative imports, but somehow the __import__() function itself was not updated even though its docs were changed to say that index defaulted to 0.

So this isn't actually a regressions because of importlib but actually just the implicit fixing of a bug. I was going to make sure to mention it in the "What's New" entry, but I will also add something to Misc/NEWS.
msg158469 - (view) Author: Brett Cannon (brett.cannon) * (Python committer) Date: 2012-04-16 15:32
I should also mention that the support for -1 indexing in Python 3 was weird because support was partially removed, but some 'if' checks only did ``< 1`` and so negative indices didn't trigger an error.
msg158492 - (view) Author: Stefan Behnel (scoder) * Date: 2012-04-16 18:42
It turns out that it wasn't all that hard to work around. Calling __import__ twice seems to do the trick. It's more overhead, but if people want speed, they can just be explicit about what kind of import they actually mean.

So I wouldn't mind considering this an accidental left-over, and given that this behaviour has officially been removed for source code imports in 3.0 and taken out of documentation since then, it should be enough to consider its (partial) support in __import__ a bug and document it as being fixed in 3.3.
msg158502 - (view) Author: Brett Cannon (brett.cannon) * (Python committer) Date: 2012-04-16 21:18
Yeah, the fix is dead-simple, import with level=1 and if that fails import with level=0.

I plan to cover this specific issue in the "What's New" for Python 3.3.
msg158529 - (view) Author: Stefan Behnel (scoder) * Date: 2012-04-17 05:24
> Yeah, the fix is dead-simple, import with level=1 and if that fails import with level=0.

With one caveat: relative imports don't work outside of packages, so the
importing code has to know when it's in a package or not. Otherwise, the
relative import would raise an exception (not an ImportError).

Interesting enough, I now get this when trying it at the prompt:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
SystemError: error return without exception set
msg158530 - (view) Author: Stefan Behnel (scoder) * Date: 2012-04-17 05:31
Hmm, interesting - it stripped the command from my e-mail. I was doing this:

>>> __import__("sys", level=1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
SystemError: error return without exception set
msg158553 - (view) Author: Brett Cannon (brett.cannon) * (Python committer) Date: 2012-04-17 16:03
Detecting if you are in a package is as simple as ``'.' in __name__ or hasattr(mod, '__path__')`` or alternatively for the last guard, ``__name__ == __package__``.

As for the failure, I will have a look.
msg158571 - (view) Author: Roundup Robot (python-dev) Date: 2012-04-17 23:05
New changeset 68f9ad6a3b13 by Brett Cannon in branch 'default':
Issue #14592: A relative import will raise a KeyError if __package__
http://hg.python.org/cpython/rev/68f9ad6a3b13
msg158572 - (view) Author: Brett Cannon (brett.cannon) * (Python committer) Date: 2012-04-17 23:05
SystemError fixed (stemming from a misunderstanding of what PyDict_GetItemWithError() did).
History
Date User Action Args
2012-04-17 23:05:59brett.cannonsetstatus: open -> closed
messages: + msg158572

assignee: brett.cannon
resolution: fixed
stage: resolved
2012-04-17 23:05:20python-devsetnosy: + python-dev
messages: + msg158571
2012-04-17 22:04:04Arfreversetnosy: + Arfrever
2012-04-17 16:03:24brett.cannonsetmessages: + msg158553
2012-04-17 05:31:57scodersetmessages: + msg158530
2012-04-17 05:24:45scodersetmessages: + msg158529
2012-04-16 21:18:43brett.cannonsetmessages: + msg158502
2012-04-16 18:42:51scodersetmessages: + msg158492
2012-04-16 16:18:54eric.snowsetnosy: + eric.snow
2012-04-16 15:32:26brett.cannonsetmessages: + msg158469
2012-04-16 15:27:13brett.cannonsetmessages: + msg158466
2012-04-16 13:14:48benjamin.petersonsetmessages: + msg158438
2012-04-16 13:14:37benjamin.petersonsetnosy: + benjamin.peterson
messages: + msg158437
2012-04-16 13:13:40r.david.murraysetnosy: + brett.cannon
2012-04-16 11:33:01scodercreate