[Python-Dev] relative import circular problem

Brett Cannon brett at python.org
Fri Apr 5 03:15:15 CEST 2013


http://bugs.python.org/issue17636


On Thu, Apr 4, 2013 at 8:03 PM, Brett Cannon <brett at python.org> wrote:

>
> On Apr 4, 2013 6:47 PM, "Guido van Rossum" <guido at python.org> wrote:
> >
> > +1 on Brett and PJE just doing this.
>
> I'll file a bug when I get home.
>
> -brett
>
> >
> > On Thu, Apr 4, 2013 at 3:38 PM, Brett Cannon <brett at python.org> wrote:
> > >
> > >
> > >
> > > On Thu, Apr 4, 2013 at 5:00 PM, PJ Eby <pje at telecommunity.com> wrote:
> > >>
> > >> On Thu, Apr 4, 2013 at 4:42 PM, Guido van Rossum <guido at python.org>
> wrote:
> > >> > 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.
> > >>
> > >> Technically, it already does that -- but inside of __import__, not in
> > >> the IMPORT_FROM opcode.
> > >>
> > >> But then *after* doing that check-and-fallback, __import__ doesn't
> > >> assign a.b, because it assumes the recursive import it called has
> > >> already done this...
> > >
> > >
> > > It's an unfortunate side-effect of having loaders set sys.modules for
> new
> > > modules not also set them as an attribute on their parent package
> > > immediately as well (or you could argue it's a side-effect of not
> passing in
> > > a module instead of a name to load_module() but that's another
> discussion).
> > >
> > >>
> > >>  which means that when __import__ returns, the
> > >> IMPORT_FROM opcode tries and fails to do the getattr.
> > >>
> > >> This could be fixed in one of two ways.   Either:
> > >>
> > >> 1. Change importlib._bootstrap._handle_fromlist() to set a.b if it
> > >> successfully imports 'a.b' (inside its duplicate handling for what
> > >> IMPORT_FROM does), or
> > >
> > >
> > > It's three lines, one of which is 'else:'. Just did it.
> > >
> > >>
> > >> 2. Change the IMPORT_FROM opcode to handle the fallback itself
> > >>
> > >>
> > >> While the latter involves a bit of C coding, it has fewer potential
> > >> side-effects on the import system as a whole, and simply ensures that
> > >> if "import" would succeed, then so would "from...import" targeting the
> > >> same module.
> > >>
> > >> (There might be other fixes I haven't thought of, but really, changing
> > >> IMPORT_FROM to fallback to a sys.modules check is probably by far the
> > >> least-invasive way to handle it.)
> > >
> > >
> > > This is my preference as well. The change would be small: I think all
> you
> > > need to do is if the getattr() fails then fall back to sys.modules.
> Although
> > > if it were me and I was casting backwards-compatibility to the wind I
> would
> > > rip out the whole fromlist part of __import__() and let the bytecode
> worry
> > > about the fromlist, basically making the import opcode call
> > > importlib.import_module().
> > >
> >
> >
> >
> > --
> > --Guido van Rossum (python.org/~guido)
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-dev/attachments/20130404/9505c1ba/attachment.html>


More information about the Python-Dev mailing list