diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2023-11-07 16:32:16 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-11-07 16:32:16 (GMT) |
commit | 70afb8d7324bc74fe64141e1af5c602bf6c0c4dd (patch) | |
tree | 79f9089295cc3e041df91b0feb61727cce2677ed /Lib/symtable.py | |
parent | f55cb44359821e71c29903f2152b4658509dac0d (diff) | |
download | cpython-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.py | 57 |
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:]) |