Consider the following function definition, where the exception name e
shadows a parameter:
def f(a,e):
try:
raise RuntimeError('test')
except RuntimeError as e:
pass
In the symbol table of function f
I would expect three symbols: two parameters a,e
(not assigned) and one local e
, which has been assigned. But the symbol table contains two symbols: parameter a
, which has not been assigned, and parameter e
, which has been assigned. It seems that the properties of the unassigned parameter e
and the exception name e
are combined into one symbol. Does that make sense?
See the following test code:
import symtable
def symStat(sym):
stat = []
if sym.is_parameter(): stat.append('param')
if sym.is_assigned(): stat.append('assigned')
if sym.is_referenced(): stat.append('referenced')
return stat
INDENT_STR = ' '
def printSymsRec(st, indentLevel=0):
indent = indentLevel*INDENT_STR
print('%s%s:' % (indent, st.get_name()),
[(sym.get_name(), symStat(sym)) for sym in st.get_symbols()])
for stc in st.get_children():
printSymsRec(stc, indentLevel+1)
TEST_CODE = """
def f(a,e):
try:
raise RuntimeError('test')
except RuntimeError as e:
pass
""".strip()
symRoot = symtable.symtable(TEST_CODE, "<string>", "exec")
printSymsRec(symRoot)
which gives the following output:
top: [('f', ['assigned'])]
f: [('a', ['param']), ('e', ['param', 'assigned']), ('RuntimeError', ['referenced'])]
Why is the output not like the following:
...
f: [('a', ['param']), ('e', ['param']), ('e', ['assigned']), ...]