<div dir="ltr"><a href="http://bugs.python.org/issue17636">http://bugs.python.org/issue17636</a><br></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Thu, Apr 4, 2013 at 8:03 PM, Brett Cannon <span dir="ltr"><<a href="mailto:brett@python.org" target="_blank">brett@python.org</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im"><p dir="ltr"><br>
On Apr 4, 2013 6:47 PM, "Guido van Rossum" <<a href="mailto:guido@python.org" target="_blank">guido@python.org</a>> wrote:<br>
><br>
> +1 on Brett and PJE just doing this.</p>
</div><p dir="ltr">I'll file a bug when I get home.</p><span class="HOEnZb"><font color="#888888">
<p dir="ltr">-brett</p></font></span><div class="HOEnZb"><div class="h5">
<p dir="ltr">><br>
> On Thu, Apr 4, 2013 at 3:38 PM, Brett Cannon <<a href="mailto:brett@python.org" target="_blank">brett@python.org</a>> wrote:<br>
> ><br>
> ><br>
> ><br>
> > On Thu, Apr 4, 2013 at 5:00 PM, PJ Eby <<a href="mailto:pje@telecommunity.com" target="_blank">pje@telecommunity.com</a>> wrote:<br>
> >><br>
> >> On Thu, Apr 4, 2013 at 4:42 PM, Guido van Rossum <<a href="mailto:guido@python.org" target="_blank">guido@python.org</a>> wrote:<br>
> >> > I do think it would be fine if "from a import b" returned the<br>
> >> > attribute 'b' of module 'a' if it exists, and otherwise look for<br>
> >> > module 'a.b' in sys.modules.<br>
> >><br>
> >> Technically, it already does that -- but inside of __import__, not in<br>
> >> the IMPORT_FROM opcode.<br>
> >><br>
> >> But then *after* doing that check-and-fallback, __import__ doesn't<br>
> >> assign a.b, because it assumes the recursive import it called has<br>
> >> already done this...<br>
> ><br>
> ><br>
> > It's an unfortunate side-effect of having loaders set sys.modules for new<br>
> > modules not also set them as an attribute on their parent package<br>
> > immediately as well (or you could argue it's a side-effect of not passing in<br>
> > a module instead of a name to load_module() but that's another discussion).<br>
> ><br>
> >><br>
> >> which means that when __import__ returns, the<br>
> >> IMPORT_FROM opcode tries and fails to do the getattr.<br>
> >><br>
> >> This could be fixed in one of two ways. Either:<br>
> >><br>
> >> 1. Change importlib._bootstrap._handle_fromlist() to set a.b if it<br>
> >> successfully imports 'a.b' (inside its duplicate handling for what<br>
> >> IMPORT_FROM does), or<br>
> ><br>
> ><br>
> > It's three lines, one of which is 'else:'. Just did it.<br>
> ><br>
> >><br>
> >> 2. Change the IMPORT_FROM opcode to handle the fallback itself<br>
> >><br>
> >><br>
> >> While the latter involves a bit of C coding, it has fewer potential<br>
> >> side-effects on the import system as a whole, and simply ensures that<br>
> >> if "import" would succeed, then so would "from...import" targeting the<br>
> >> same module.<br>
> >><br>
> >> (There might be other fixes I haven't thought of, but really, changing<br>
> >> IMPORT_FROM to fallback to a sys.modules check is probably by far the<br>
> >> least-invasive way to handle it.)<br>
> ><br>
> ><br>
> > This is my preference as well. The change would be small: I think all you<br>
> > need to do is if the getattr() fails then fall back to sys.modules. Although<br>
> > if it were me and I was casting backwards-compatibility to the wind I would<br>
> > rip out the whole fromlist part of __import__() and let the bytecode worry<br>
> > about the fromlist, basically making the import opcode call<br>
> > importlib.import_module().<br>
> ><br>
><br>
><br>
><br>
> --<br>
> --Guido van Rossum (<a href="http://python.org/~guido" target="_blank">python.org/~guido</a>)<br>
</p>
</div></div></blockquote></div><br></div>