summaryrefslogtreecommitdiffstats
path: root/Lib/symtable.py
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2023-11-07 16:32:16 (GMT)
committerGitHub <noreply@github.com>2023-11-07 16:32:16 (GMT)
commit70afb8d7324bc74fe64141e1af5c602bf6c0c4dd (patch)
tree79f9089295cc3e041df91b0feb61727cce2677ed /Lib/symtable.py
parentf55cb44359821e71c29903f2152b4658509dac0d (diff)
downloadcpython-70afb8d7324bc74fe64141e1af5c602bf6c0c4dd.zip
cpython-70afb8d7324bc74fe64141e1af5c602bf6c0c4dd.tar.gz
cpython-70afb8d7324bc74fe64141e1af5c602bf6c0c4dd.tar.bz2
gh-85098: Implement functional CLI of symtable (#109112)
Co-authored-by: Pablo Galindo Salgado <Pablogsal@gmail.com>
Diffstat (limited to 'Lib/symtable.py')
-rw-r--r--Lib/symtable.py57
1 files changed, 49 insertions, 8 deletions
diff --git a/Lib/symtable.py b/Lib/symtable.py
index 4b0bc6f..17f820a 100644
--- a/Lib/symtable.py
+++ b/Lib/symtable.py
@@ -233,7 +233,16 @@ class Symbol:
self.__module_scope = module_scope
def __repr__(self):
- return "<symbol {0!r}>".format(self.__name)
+ flags_str = '|'.join(self._flags_str())
+ return f'<symbol {self.__name!r}: {self._scope_str()}, {flags_str}>'
+
+ def _scope_str(self):
+ return _scopes_value_to_name.get(self.__scope) or str(self.__scope)
+
+ def _flags_str(self):
+ for flagname, flagvalue in _flags:
+ if self.__flags & flagvalue == flagvalue:
+ yield flagname
def get_name(self):
"""Return a name of a symbol.
@@ -323,11 +332,43 @@ class Symbol:
else:
return self.__namespaces[0]
+
+_flags = [('USE', USE)]
+_flags.extend(kv for kv in globals().items() if kv[0].startswith('DEF_'))
+_scopes_names = ('FREE', 'LOCAL', 'GLOBAL_IMPLICIT', 'GLOBAL_EXPLICIT', 'CELL')
+_scopes_value_to_name = {globals()[n]: n for n in _scopes_names}
+
+
+def main(args):
+ import sys
+ def print_symbols(table, level=0):
+ indent = ' ' * level
+ nested = "nested " if table.is_nested() else ""
+ if table.get_type() == 'module':
+ what = f'from file {table._filename!r}'
+ else:
+ what = f'{table.get_name()!r}'
+ print(f'{indent}symbol table for {nested}{table.get_type()} {what}:')
+ for ident in table.get_identifiers():
+ symbol = table.lookup(ident)
+ flags = ', '.join(symbol._flags_str()).lower()
+ print(f' {indent}{symbol._scope_str().lower()} symbol {symbol.get_name()!r}: {flags}')
+ print()
+
+ for table2 in table.get_children():
+ print_symbols(table2, level + 1)
+
+ for filename in args or ['-']:
+ if filename == '-':
+ src = sys.stdin.read()
+ filename = '<stdin>'
+ else:
+ with open(filename, 'rb') as f:
+ src = f.read()
+ mod = symtable(src, filename, 'exec')
+ print_symbols(mod)
+
+
if __name__ == "__main__":
- import os, sys
- with open(sys.argv[0]) as f:
- src = f.read()
- mod = symtable(src, os.path.split(sys.argv[0])[1], "exec")
- for ident in mod.get_identifiers():
- info = mod.lookup(ident)
- print(info, info.is_local(), info.is_namespace())
+ import sys
+ main(sys.argv[1:])