diff -rc Python-2.3b2-orig/Lib/test/test_symtable.py Python-2.3b2/Lib/test/test_symtable.py *** Python-2.3b2-orig/Lib/test/test_symtable.py Tue Jul 23 13:04:05 2002 --- Python-2.3b2/Lib/test/test_symtable.py Mon Jun 30 03:51:54 2003 *************** *** 1,8 **** ! from test.test_support import verify import _symtable symbols = _symtable.symtable("def f(x): return x", "?", "exec") ! verify(symbols[0].name == "global") ! verify(len([ste for ste in symbols.values() if ste.name == "f"]) == 1) --- 1,20 ---- ! from test.test_support import vereq, TestFailed import _symtable symbols = _symtable.symtable("def f(x): return x", "?", "exec") ! vereq(symbols[0].name, "global") ! vereq(len([ste for ste in symbols.values() if ste.name == "f"]), 1) ! ! # Bug tickler: SyntaxError file name correct whether error raised ! # while parsing or building symbol table. ! def checkfilename(brokencode): ! try: ! _symtable.symtable(brokencode, "spam", "exec") ! except SyntaxError, e: ! vereq(e.filename, "spam") ! else: ! raise TestFailed("no SyntaxError for %r" % (brokencode,)) ! checkfilename("def f(x): foo)(") # parse-time ! checkfilename("def f(x): global x") # symtable-build-time diff -rc Python-2.3b2-orig/Lib/test/test_syntax.py Python-2.3b2/Lib/test/test_syntax.py *** Python-2.3b2-orig/Lib/test/test_syntax.py Tue Jul 23 13:04:06 2002 --- Python-2.3b2/Lib/test/test_syntax.py Mon Jun 30 03:49:16 2003 *************** *** 1,5 **** --- 1,6 ---- import re import unittest + import warnings from test import test_support *************** *** 26,31 **** --- 27,46 ---- def test_assign_del(self): self._check_error("del f()", "delete") + + def test_global_err_then_warn(self): + # Bug tickler: The SyntaxError raised for one global statement + # shouldn't be clobbered by a SyntaxWarning issued for a later one. + source = re.sub('(?m)^ *:', '', """\ + :def error(a): + : global a # SyntaxError + :def warning(): + : b = 1 + : global b # SyntaxWarning + :""") + warnings.filterwarnings(action='ignore', category=SyntaxWarning) + self._check_error(source, "global") + warnings.filters.pop(0) def test_main(): test_support.run_unittest(SyntaxTestCase) diff -rc Python-2.3b2-orig/Python/compile.c Python-2.3b2/Python/compile.c *** Python-2.3b2-orig/Python/compile.c Fri Jun 20 10:13:17 2003 --- Python-2.3b2/Python/compile.c Mon Jun 30 04:19:27 2003 *************** *** 686,692 **** static int get_ref_type(struct compiling *, char *); /* symtable operations */ ! static int symtable_build(struct compiling *, node *); static int symtable_load_symbols(struct compiling *); static struct symtable *symtable_init(void); static void symtable_enter_scope(struct symtable *, char *, int, int); --- 686,693 ---- static int get_ref_type(struct compiling *, char *); /* symtable operations */ ! static struct symtable *symtable_build(node *, PyFutureFeatures *, ! const char *filename); static int symtable_load_symbols(struct compiling *); static struct symtable *symtable_init(void); static void symtable_enter_scope(struct symtable *, char *, int, int); *************** *** 4250,4275 **** ff = PyNode_Future(n, filename); if (ff == NULL) return NULL; ! ! st = symtable_init(); if (st == NULL) { PyObject_FREE((void *)ff); return NULL; } - st->st_future = ff; - symtable_enter_scope(st, TOP, TYPE(n), n->n_lineno); - if (st->st_errors> 0) - goto fail; - symtable_node(st, n); - if (st->st_errors> 0) - goto fail; - return st; - fail: - PyObject_FREE((void *)ff); - st->st_future = NULL; - PySymtable_Free(st); - return NULL; } static PyCodeObject * --- 4251,4262 ---- ff = PyNode_Future(n, filename); if (ff == NULL) return NULL; ! st = symtable_build(n, ff, filename); if (st == NULL) { PyObject_FREE((void *)ff); return NULL; } return st; } static PyCodeObject * *************** *** 4319,4328 **** sc.c_future->ff_features = merged; flags->cf_flags = merged; } ! if (symtable_build(&sc, n) < 0) { com_free(&sc); return NULL; } } co = NULL; if (symtable_load_symbols(&sc) < 0) { --- 4306,4319 ---- sc.c_future->ff_features = merged; flags->cf_flags = merged; } ! sc.c_symtable = symtable_build(n, sc.c_future, sc.c_filename); ! if (sc.c_symtable == NULL) { com_free(&sc); return NULL; } + /* reset symbol table for second pass */ + sc.c_symtable->st_nscopes = 1; + sc.c_symtable->st_pass = 2; } co = NULL; if (symtable_load_symbols(&sc) < 0) { *************** *** 4443,4448 **** --- 4434,4448 ---- static int issue_warning(const char *msg, const char *filename, int lineno) { + if (PyErr_Occurred()) { + /* This can happen because symtable_node continues + processing even after raising a SyntaxError. + Calling PyErr_WarnExplicit now would clobber the + pending exception; instead we fail and let that + exception propagate. + */ + return -1; + } if (PyErr_WarnExplicit(PyExc_SyntaxWarning, msg, filename, lineno, NULL, NULL) < 0) { if (PyErr_ExceptionMatches(PyExc_SyntaxWarning)) { *************** *** 4466,4488 **** /* Helper function for setting lineno and filename */ ! static int ! symtable_build(struct compiling *c, node *n) { ! if ((c->c_symtable = symtable_init()) == NULL) ! return -1; ! c->c_symtable->st_future = c->c_future; ! c->c_symtable->st_filename = c->c_filename; ! symtable_enter_scope(c->c_symtable, TOP, TYPE(n), n->n_lineno); ! if (c->c_symtable->st_errors> 0) ! return -1; ! symtable_node(c->c_symtable, n); ! if (c->c_symtable->st_errors> 0) ! return -1; ! /* reset for second pass */ ! c->c_symtable->st_nscopes = 1; ! c->c_symtable->st_pass = 2; ! return 0; } static int --- 4466,4502 ---- /* Helper function for setting lineno and filename */ ! static struct symtable * ! symtable_build(node *n, PyFutureFeatures *ff, const char *filename) { ! struct symtable *st; ! ! st = symtable_init(); ! if (st == NULL) ! return NULL; ! st->st_future = ff; ! st->st_filename = filename; ! symtable_enter_scope(st, TOP, TYPE(n), n->n_lineno); ! if (st->st_errors> 0) ! goto fail; ! symtable_node(st, n); ! if (st->st_errors> 0) ! goto fail; ! return st; ! fail: ! if (!PyErr_Occurred()) { ! /* This could happen because after a syntax error is ! detected, the symbol-table-building continues for ! a while, and PyErr_Clear() might erroneously be ! called during that process. One such case has been ! fixed, but there might be more (now or later). ! */ ! PyErr_SetString(PyExc_SystemError, "lost exception"); ! } ! st->st_future = NULL; ! st->st_filename = NULL; ! PySymtable_Free(st); ! return NULL; } static int

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