On Sat, Apr 18, 2020 at 4:26 AM Adam Preble <adam.pre...@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
-- 
https://mail.python.org/mailman/listinfo/python-list

Reply via email to