[Python-checkins] cpython (3.5): make recording and reporting errors and nonlocal and global directives more
benjamin.peterson
python-checkins at python.org
Tue Dec 29 11:08:58 EST 2015
https://hg.python.org/cpython/rev/4fa8c0c69ee9
changeset: 99714:4fa8c0c69ee9
branch: 3.5
parent: 99710:9f13322eba8e
user: Benjamin Peterson <benjamin at python.org>
date: Tue Dec 29 10:08:34 2015 -0600
summary:
make recording and reporting errors and nonlocal and global directives more robust (closes #25973)
files:
Lib/test/test_syntax.py | 8 ++++++++
Misc/NEWS | 3 +++
Python/symtable.c | 24 ++++++++++++++++--------
3 files changed, 27 insertions(+), 8 deletions(-)
diff --git a/Lib/test/test_syntax.py b/Lib/test/test_syntax.py
--- a/Lib/test/test_syntax.py
+++ b/Lib/test/test_syntax.py
@@ -416,6 +416,14 @@
## ...
## SyntaxWarning: name 'x' is assigned to before nonlocal declaration
+ From https://bugs.python.org/issue25973
+ >>> class A:
+ ... def f(self):
+ ... nonlocal __x
+ Traceback (most recent call last):
+ ...
+ SyntaxError: no binding for nonlocal '_A__x' found
+
This tests assignment-context; there was a bug in Python 2.5 where compiling
a complex 'if' (one with 'elif') would fail to notice an invalid suite,
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -10,6 +10,9 @@
Core and Builtins
-----------------
+- Issue #25973: Fix segfault when an invalid nonlocal statement binds a name
+ starting with two underscores.
+
- Issue #22995: Instances of extension types with a state that aren't
subclasses of list or dict and haven't implemented any pickle-related
methods (__reduce__, __reduce_ex__, __getnewargs__, __getnewargs_ex__,
diff --git a/Python/symtable.c b/Python/symtable.c
--- a/Python/symtable.c
+++ b/Python/symtable.c
@@ -368,15 +368,20 @@
Py_ssize_t i;
PyObject *data;
assert(ste->ste_directives);
- for (i = 0; ; i++) {
+ for (i = 0; i < PyList_GET_SIZE(ste->ste_directives); i++) {
data = PyList_GET_ITEM(ste->ste_directives, i);
assert(PyTuple_CheckExact(data));
- if (PyTuple_GET_ITEM(data, 0) == name)
- break;
+ assert(PyUnicode_CheckExact(PyTuple_GET_ITEM(data, 0)));
+ if (PyUnicode_Compare(PyTuple_GET_ITEM(data, 0), name) == 0) {
+ PyErr_SyntaxLocationObject(ste->ste_table->st_filename,
+ PyLong_AsLong(PyTuple_GET_ITEM(data, 1)),
+ PyLong_AsLong(PyTuple_GET_ITEM(data, 2)));
+
+ return 0;
+ }
}
- PyErr_SyntaxLocationObject(ste->ste_table->st_filename,
- PyLong_AsLong(PyTuple_GET_ITEM(data, 1)),
- PyLong_AsLong(PyTuple_GET_ITEM(data, 2)));
+ PyErr_SetString(PyExc_RuntimeError,
+ "BUG: internal directive bookkeeping broken");
return 0;
}
@@ -1115,14 +1120,17 @@
static int
symtable_record_directive(struct symtable *st, identifier name, stmt_ty s)
{
- PyObject *data;
+ PyObject *data, *mangled;
int res;
if (!st->st_cur->ste_directives) {
st->st_cur->ste_directives = PyList_New(0);
if (!st->st_cur->ste_directives)
return 0;
}
- data = Py_BuildValue("(Oii)", name, s->lineno, s->col_offset);
+ mangled = _Py_Mangle(st->st_private, name);
+ if (!mangled)
+ return 0;
+ data = Py_BuildValue("(Nii)", mangled, s->lineno, s->col_offset);
if (!data)
return 0;
res = PyList_Append(st->st_cur->ste_directives, data);
--
Repository URL: https://hg.python.org/cpython
More information about the Python-checkins
mailing list