Consider this function:
def content(path):
global file # not useful but valid
with open(path) as file:
return file.read()
When generating a symbol table (using module symtable
) and inspecting the symbol file
in the scope of the function content
, it is global and local at the same time. After calling this function the global name file
is bound to the file object. So I wonder why the symbol file
in the function scope is also considered as a local symbol?
Here is code to reproduce the behaviour (put it in a file eg called global_and_local.py
):
import symtable
def content(path):
global file
with open(path) as file:
return file.read()
symtable_root = symtable.symtable(content(__file__), __file__, "exec")
symtable_function = symtable_root.get_children()[0]
symbol_file = symtable_function.lookup('file')
print("symbol 'file' in function scope: is_global() =", symbol_file.is_global())
print("symbol 'file' in function scope: is_local() =", symbol_file.is_local())
print("global scope: file =", file)
The following output is generated:
symbol 'file' in function scope: is_global() = True
symbol 'file' in function scope: is_local() = True
global scope: file = <_io.TextIOWrapper name='global_and_local.py' ...>
For some reason, symtable
defines is_local
as a check for whether any binding operations for a symbol occur in the scope (or annotations, which are lumped together with annotated assignments at this stage):
def is_local(self):
return bool(self.__flags & DEF_BOUND)
rather than a check for whether the symbol is actually local, which would look like
def is_local(self):
return bool(self.__scope in (LOCAL, CELL))
I'm not sure why. This might be a bug. I don't think modules like this get much use - it took over a year before anyone noticed that adding the //
operator broke the old parser
module, so I could easily see this going unnoticed.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.