From 224c370a3680132997f1e43d20a3b4ca95a060ab Mon Sep 17 00:00:00 2001 From: Brian Schubert Date: Tue, 29 Oct 2024 19:57:59 -0400 Subject: [PATCH] gh-126139: Improve error message location for future statement with unknown feature (#126140) --- Lib/test/test_exceptions.py | 4 ++-- Lib/test/test_future_stmt/test_future.py | 8 ++++---- .../2024-10-29-15-17-31.gh-issue-126139.B4OQ8a.rst | 2 ++ Python/future.c | 12 ++++++++++-- 4 files changed, 18 insertions(+), 8 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-10-29-15-17-31.gh-issue-126139.B4OQ8a.rst diff --git a/Lib/test/test_exceptions.py b/Lib/test/test_exceptions.py index b3c21cd4f3d..5beeac3adfc 100644 --- a/Lib/test/test_exceptions.py +++ b/Lib/test/test_exceptions.py @@ -319,8 +319,8 @@ def baz(): 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 44512e0101d..42c6cb3fefa 100644 --- a/Lib/test/test_future_stmt/test_future.py +++ b/Lib/test/test_future_stmt/test_future.py @@ -88,7 +88,7 @@ def test_unknown_future_flag(self): """ 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 @@ def test_future_import_star(self): 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 8aeb541cb05..79b6c0c503b 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; } }