You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
symtable: repr() of a Symbol raises TypeError under -X lazy_imports=all #160810
$ ./python -X lazy_imports=all repro.py
Traceback (most recent call last):
File "repro.py", line 3, in <module>
print(top.get_symbols())
~~~~~^^^^^^^^^^^^^^^^^^^
File "Lib/symtable.py", line 264, in __repr__
flags_str = '|'.join(self._flags_str())
File "Lib/symtable.py", line 272, in _flags_str
if self.__flags & flagvalue == flagvalue:
~~~~~~~~~~~~~^~~~~~~~~~~
TypeError: unsupported operand type(s) for &: 'int' and 'lazy_import'
Without the option it prints [<symbol 'x': LOCAL, DEF_LOCAL>].
Lib/symtable.py builds its _flags and _scopes_value_to_name tables from globals():
With lazy_imports=all, the from _symtable import ... at the top of the module is lazy, so globals() holds lazy_import objects instead of the integer constants. _flags breaks repr() as above, and once that is fixed, _scopes_value_to_name still makes the scope print as 1 instead of LOCAL.
This is the test_symtable failure mentioned in gh-149640, and why test_symtable is in Lib/test/lazy_imports_all_exclude.txt. The 3.15 branch has the same code.
Possible fix: take the values from the _symtable module (for example getattr(_symtable, name)) instead of from globals(). With that, test_symtable passes with and without -X lazy_imports=all and can come off the exclusion list. I can open a PR if this sounds right.
@JelleZijlstra you spotted this in gh-149640. Does taking the values from _symtable look like the right fix to you, or would you rather handle it another way?
I don't really like the fact that lazy imports don't work well with globals() in a loop. I think we can fix it that way for now. However, I still think that existing code shouldn't be broken because of lazy imports that way. So I still want to know whether there is a plan to make this "work" without users having to change the code (IMO, this should cause reification but I don't know how it could be done properly)
PEP 810 explicitly leaves lazy objects in globals() so introspection does not trigger imports. Resolution during iteration needs changes to dict semantics, and the imports can themselves change the dict.
@DinoV@Yhg1s, what do you think? Is there a practical way to support this within the current design?
Yes, using _symtable and getting attributes off it seems like the right fix, I'd welcome a PR making that change.
As for whether we need to do something broader, I think the design of making globals() return the lazy import objects was discussed in some depth during the PEP discussions. It causes some problems but so would other variants. This only affects -X lazy_imports=all which is a fairly advanced feature.
Activity
anistark commentedon Oct 28, 2026
@JelleZijlstra you spotted this in gh-149640. Does taking the values from
_symtablelook like the right fix to you, or would you rather handle it another way?picnixz commentedon Oct 28, 2026
I don't really like the fact that lazy imports don't work well with
globals()in a loop. I think we can fix it that way for now. However, I still think that existing code shouldn't be broken because of lazy imports that way. So I still want to know whether there is a plan to make this "work" without users having to change the code (IMO, this should cause reification but I don't know how it could be done properly)cc @pablogsal @DinoV @Yhg1s
pablogsal commentedon Oct 29, 2026
The
_symtablefix looks right to me.PEP 810 explicitly leaves lazy objects in
globals()so introspection does not trigger imports. Resolution during iteration needs changes to dict semantics, and the imports can themselves change the dict.@DinoV @Yhg1s, what do you think? Is there a practical way to support this within the current design?
JelleZijlstra commentedon Oct 29, 2026
Yes, using
_symtableand getting attributes off it seems like the right fix, I'd welcome a PR making that change.As for whether we need to do something broader, I think the design of making
globals()return the lazy import objects was discussed in some depth during the PEP discussions. It causes some problems but so would other variants. This only affects-X lazy_imports=allwhich is a fairly advanced feature.