[Python-Dev] relative import circular problem
Guido van Rossum
guido at python.org
Thu Apr 4 22:42:08 CEST 2013
Thanks for the insight. That could indeed be done and I would
encourage someone to come up with a fix.
FWIW there is another difference between the two forms -- "from a
import b" allows b to be any attribute of a, whereas "import a.b"
requires b to be a submodule of a. I don't want to compromise on the
latter. I do think it would be fine if "from a import b" returned the
attribute 'b' of module 'a' if it exists, and otherwise look for
module 'a.b' in sys.modules.
On Thu, Apr 4, 2013 at 1:28 PM, PJ Eby <pje at telecommunity.com> wrote:
> On Thu, Apr 4, 2013 at 11:17 AM, Guido van Rossum <guido at python.org> wrote:
>> I don't really see what we could change to avoid breaking code in any
>> particular case
> Actually, the problem has *nothing* to do with circularity per se;
> it's that "import a.b" and "from a import b" behave differently in
> terms of how they obtain the module 'a.b'...
> And "from a import b" will *always* fail if 'a.b' is part of a cycle
> with the current module, whereas "import a.b" will *always* succeed.
> The workaround is to tell people to always use "import a.b" in the
> case of circular imports; it's practically a FAQ, at least to me. ;-)
> The problem with "from import" is that it always tries to
> getattr(a,'b'), even if 'a.b' is in sys.modules. In contrast, a plain
> import will simply fetch a.b from sys.modules first.
> In the case of a normal import, this is no problem, because a.b is set
> to sys.modules['a.b'] at the end of the module loading process. But
> if the import is circular, then the module is in sys.modules['a.b'],
> but *not* yet bound to a.b. So the "from import" fails.
> So, this is actually an implementation quirk that could be fixed in a
> (somewhat) straightforward manner: by making "from a import b" succeed
> if 'a.b' is in sys.modules, the same way "import a.b" does. It would
> require a little bit of discussion to hash out the exact way to do it,
> but it could be done.
--Guido van Rossum (python.org/~guido)
More information about the Python-Dev