homepage

This issue tracker has been migrated to GitHub , and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: 3 bugs fixed: handling of SyntaxErrors in symbol table build
Type: Stage:
Components: Interpreter Core Versions: Python 2.3
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: jhylton Nosy List: jhylton, staschuk
Priority: high Keywords: patch

Created on 2003年06月30日 13:48 by staschuk, last changed 2022年04月10日 16:09 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
symtable-errors.patch staschuk, 2003年06月30日 13:48
Messages (2)
msg44170 - (view) Author: Steven Taschuk (staschuk) Date: 2003年06月30日 13:48
All three bugs found in both 2.2.3 and 2.3b2. It's one 
patch
instead of three because the fixes share a refactoring of
Python/compile.c:symtable_build.
Bug 1: Wrong file name
 import symtable
 symtable.symtable('def foo(a): global a', 'spam', 'exec')
The error message says '<string>' instead of 'spam'.
(Cause: PyNode_CompileSymtable doesn't set 
st_filename.)
Bug 2: Memory leak
 while True:
 try:
 compile('def foo(a): global a', 'spam', 'exec')
 except SyntaxError:
 pass
(Cause: symtable_build doesn't free c->c_symtable on 
error.)
The patch is missing a test case for this one; I don't see 
how to write it.
Bug 3: Exception clobbered
 def foo(a):
 global a # SyntaxError
 def bar():
 b = 1
 global b # SyntaxWarning
Running this as a script, the SyntaxWarning is issued, 
and then
the interpreter dies silently (that is, without printing a
traceback reporting the SyntaxError). Compiling it with 
compile()
causes a SystemError. (Cause: see below.)
What to do about bugs 1 and 2 is obvious, but bug 3 
(which was
actually reported on c.l.py) is not so clear to me. Here's 
how
the problem occurs:
symtable_global() sees the global statement in foo(), 
raises a
SyntaxError, increments st_errors, and returns. 
Processing
continues. Later, symtable_global() sees the global 
statement in
bar() and issues a warning by (indirectly) calling
PyErr_WarnExplicit(). This call clears the SyntaxError, 
which is
still pending at that time. (It's actually cleared during the
attempt to import the warnings module, in 
PyImport_Import, which
seems to think the exception was raised in 
PyEval_GetGlobals.)
But st_errors is still > 0, as it should be, so 
symtable_build()
returns -1 (resp. PyNode_CompileSymtable, NULL), its 
callers
return their error values, etc., until eventually PyErr_Print
tries to print the exception that isn't there.
What the patch implements is this:
Do not issue SyntaxWarnings if an exception is pending; 
fail
instead and let that exception propagate. Also, as a 
defensive
measure against other bugs of this type (present and 
future), when
returning with error from symtable_build(), verify that 
there's an
exception pending (and raise SystemError if not). Finally,
refactor symtable_build() so PyNode_CompileSymtable 
can use it and
thereby benefit from that defensive measure.
Alternatives (and why I don't like them):
1. Do not try to continue processing after a SyntaxError is
raised. (Seems like the Right Thing to me, but also 
seems to be
contrary to the intent of the existing code. There are 
oodles of
places in compile.c which call symtable_node without 
checking
st_errors immediately afterwards.)
2. Put the check for a pending exception in 
PyErr_WarnExplicit()
instead of in the helper function in compile.c. (Doesn't 
seem
like a common enough coding error to merit a check 
there. In
symtable_node etc we deliberately let SyntaxErrors, er, 
"pend"
while we do a bit more compiling, so *there* it's worth 
checking.
Note that jcompile() already has a check for something 
similar,
though not for the symbol-table-building phase.)
3. Squirrel the pending exception away, issue the 
warning, then
restore the exception. (Not worth the bother, IMO. And 
if the
warning gets strengthened into an exception, should that 
exception
or the squirrelled one propagate? Ick.)
msg44171 - (view) Author: Steven Taschuk (staschuk) Date: 2003年07月01日 17:31
Logged In: YES 
user_id=666873
Just noticed another alternative: leave the checking of 
whether a global statement declares a function parameter 
global to the later pass. There's already a check for this 
condition in symtable_load_symbols (with a different error 
message, which is a subject for another patch).
The problem with this idea is that it breaks 
symtable.symtable(), which only uses symtable_build. Thus this 
function would no longer raise SyntaxErrors for this case.
History
Date User Action Args
2022年04月10日 16:09:33adminsetgithub: 38750
2003年06月30日 13:48:26staschukcreate

AltStyle によって変換されたページ (->オリジナル) /