diff --git a/Lib/test/test_exceptions.py b/Lib/test/test_exceptions.py index 313345b3b7a..6a29bc38252 100644 --- a/Lib/test/test_exceptions.py +++ b/Lib/test/test_exceptions.py @@ -319,8 +319,8 @@ class ExceptionTests(unittest.TestCase): check('def f():\n global x\n nonlocal x', 2, 3) # Errors thrown by future.c - check('from __future__ import doesnt_exist', 1, 1) - check('from __future__ import braces', 1, 1) + check('from __future__ import doesnt_exist', 1, 24) + check('from __future__ import braces', 1, 24) check('x=1\nfrom __future__ import division', 2, 1) check('foo(1=2)', 1, 5) check('def f():\n x, y: int', 2, 3) diff --git a/Lib/test/test_future_stmt/test_future.py b/Lib/test/test_future_stmt/test_future.py index bb31d0a0023..94a6f46d0dc 100644 --- a/Lib/test/test_future_stmt/test_future.py +++ b/Lib/test/test_future_stmt/test_future.py @@ -88,7 +88,7 @@ class FutureTest(unittest.TestCase): """ self.assertSyntaxError( code, lineno=2, - message='future feature rested_snopes is not defined', + message='future feature rested_snopes is not defined', offset=24, ) def test_future_import_not_on_top(self): @@ -137,19 +137,19 @@ class FutureTest(unittest.TestCase): code = """ from __future__ import * """ - self.assertSyntaxError(code, message='future feature * is not defined') + self.assertSyntaxError(code, message='future feature * is not defined', offset=24) def test_future_import_braces(self): code = """ from __future__ import braces """ # Congrats, you found an easter egg! - self.assertSyntaxError(code, message='not a chance') + self.assertSyntaxError(code, message='not a chance', offset=24) code = """ from __future__ import nested_scopes, braces """ - self.assertSyntaxError(code, message='not a chance') + self.assertSyntaxError(code, message='not a chance', offset=39) def test_module_with_future_import_not_on_top(self): with self.assertRaises(SyntaxError) as cm: diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-10-29-15-17-31.gh-issue-126139.B4OQ8a.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-10-29-15-17-31.gh-issue-126139.B4OQ8a.rst new file mode 100644 index 00000000000..278971b46d1 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2024-10-29-15-17-31.gh-issue-126139.B4OQ8a.rst @@ -0,0 +1,2 @@ +Provide better error location when attempting to use a :term:`future +statement <__future__>` with an unknown future feature. diff --git a/Python/future.c b/Python/future.c index 8d94d515605..e411e659dfc 100644 --- a/Python/future.c +++ b/Python/future.c @@ -41,12 +41,20 @@ future_check_features(_PyFutureFeatures *ff, stmt_ty s, PyObject *filename) } else if (strcmp(feature, "braces") == 0) { PyErr_SetString(PyExc_SyntaxError, "not a chance"); - PyErr_SyntaxLocationObject(filename, s->lineno, s->col_offset + 1); + PyErr_RangedSyntaxLocationObject(filename, + name->lineno, + name->col_offset + 1, + name->end_lineno, + name->end_col_offset + 1); return 0; } else { PyErr_Format(PyExc_SyntaxError, UNDEFINED_FUTURE_FEATURE, feature); - PyErr_SyntaxLocationObject(filename, s->lineno, s->col_offset + 1); + PyErr_RangedSyntaxLocationObject(filename, + name->lineno, + name->col_offset + 1, + name->end_lineno, + name->end_col_offset + 1); return 0; } }