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