Why generate POP_TOP after an "import from?"

Chris Angelico rosuav at gmail.com
Fri Apr 17 14:36:51 EDT 2020


On Sat, Apr 18, 2020 at 4:26 AM Adam Preble <adam.preble at gmail.com> wrote:
>
> Given this in Python 3.6.8:
>
> from dis import dis
>
> def import_from_test():
>    from sys import path
>
> >>> dis(import_from_test)
>   2           0 LOAD_CONST               1 (0)
>               2 LOAD_CONST               2 (('path',))
>               4 IMPORT_NAME              0 (sys)
>               6 IMPORT_FROM              1 (path)
>               8 STORE_FAST               0 (path)
>              10 POP_TOP
>              12 LOAD_CONST               0 (None)
>              14 RETURN_VALUE
>
> I don't understand why there's a POP_TOP there that I don't get for an import_name grammatical statement.
>
> IMPORT_NAME needs to eat the top two entries of the stack for level and the from-list. BTW I don't know what level is for either since my science projects have always had it be zero, but that's another question.
>
> IMPORT_NAME will the push the module on to the stack.
>
> IMPORT_FROM will import path from the module on the stack, and push that result on the stack.
>
> STORE_FAST will store path for use, finally "modifying the namespace."
>
> At this point, my conceptual stack is empty. If I POP_TOP then I have nothing to pop and the world would end. Yet, it doesn't. What am I missing?
>

Good question, and nicely put, thank you. I like questions like this :)

Here's another function that can showcase a bit more of what's going on:

>>> def f():
...     from . import foo, bar, baz
...
>>> dis.dis(f)
  2           0 LOAD_CONST               1 (1)
              2 LOAD_CONST               2 (('foo', 'bar', 'baz'))
              4 IMPORT_NAME              0
              6 IMPORT_FROM              1 (foo)
              8 STORE_FAST               0 (foo)
             10 IMPORT_FROM              2 (bar)
             12 STORE_FAST               1 (bar)
             14 IMPORT_FROM              3 (baz)
             16 STORE_FAST               2 (baz)
             18 POP_TOP
             20 LOAD_CONST               0 (None)
             22 RETURN_VALUE

The level is used for package-relative imports, and will basically be
the number of leading dots (eg "from ...spam import x" will have a
level of 3). You're absolutely right with your analysis, with one
small clarification:

> IMPORT_FROM will import path from the module on the stack, and push that result on the stack.
>

It leaves the module on the stack, allowing chained IMPORT_FROM
operations to grab multiples from the same module. That's why it needs
to be popped off at the end.

In theory, I suppose, you could replace the POP_TOP with a STORE_FAST
into "sys", and thus get a two-way import that both grabs the module
and also grabs something out of it. Not very often wanted, but could
be done if you fiddle with the bytecode.

ChrisA


More information about the Python-list mailing list