From 8f39572b80351f1d7a4218523af99a50e362f1c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Batuhan=20Ta=C5=9Fkaya?= Date: Thu, 23 Apr 2020 02:29:56 +0300 Subject: [PATCH 1/2] bpo-40366: Remove support for passing CO_NESTED as a flag to compile --- Doc/whatsnew/3.9.rst | 3 +++ Include/compile.h | 1 - Lib/test/test_builtin.py | 3 ++- .../2020-04-23-02-28-33.bpo-40366.pDs7Zh.rst | 1 + Python/bltinmodule.c | 5 +---- Python/ceval.c | 6 ------ 6 files changed, 7 insertions(+), 12 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-04-23-02-28-33.bpo-40366.pDs7Zh.rst diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst index ee851706055a30..f76e382788275f 100644 --- a/Doc/whatsnew/3.9.rst +++ b/Doc/whatsnew/3.9.rst @@ -791,6 +791,9 @@ Removed deprecated since 2006, and only returning ``False`` when it's called. (Contributed by Batuhan Taskaya in :issue:`40208`) +* Support for passing ``CO_NESTED`` flag to :func:`compile` has been removed. + It was obsolete and the default behavior since Python 2.2, 19 years. + (Contributed by Batuhan Taskaya in :issue:`40366`) Porting to Python 3.9 ===================== diff --git a/Include/compile.h b/Include/compile.h index dbba85bb5f653e..b7b53d10c32aa0 100644 --- a/Include/compile.h +++ b/Include/compile.h @@ -17,7 +17,6 @@ PyAPI_FUNC(PyCodeObject *) PyNode_Compile(struct _node *, const char *); CO_FUTURE_WITH_STATEMENT | CO_FUTURE_PRINT_FUNCTION | \ CO_FUTURE_UNICODE_LITERALS | CO_FUTURE_BARRY_AS_BDFL | \ CO_FUTURE_GENERATOR_STOP | CO_FUTURE_ANNOTATIONS) -#define PyCF_MASK_OBSOLETE (CO_NESTED) /* bpo-39562: CO_FUTURE_ and PyCF_ constants must be kept unique. PyCF_ constants can use bits from 0x0100 to 0x10000. diff --git a/Lib/test/test_builtin.py b/Lib/test/test_builtin.py index 290ba2cad8e5eb..767195b6b11be7 100644 --- a/Lib/test/test_builtin.py +++ b/Lib/test/test_builtin.py @@ -20,7 +20,7 @@ import warnings from contextlib import ExitStack from functools import partial -from inspect import CO_COROUTINE +from inspect import CO_COROUTINE, CO_NESTED from itertools import product from textwrap import dedent from types import AsyncGeneratorType, FunctionType @@ -339,6 +339,7 @@ def test_compile(self): compile('print("\xe5")\n', '', 'exec') self.assertRaises(ValueError, compile, chr(0), 'f', 'exec') self.assertRaises(ValueError, compile, str('a = 1'), 'f', 'bad') + self.assertRaises(ValueError, compile, 'obsolote_flag', 'f', 'exec', CO_NESTED) # test the optimize argument diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-04-23-02-28-33.bpo-40366.pDs7Zh.rst b/Misc/NEWS.d/next/Core and Builtins/2020-04-23-02-28-33.bpo-40366.pDs7Zh.rst new file mode 100644 index 00000000000000..68c0ae47e81715 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-04-23-02-28-33.bpo-40366.pDs7Zh.rst @@ -0,0 +1 @@ +Removed support for ``CO_NESTED`` flag in :func:`compile`. diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index 18883353575f35..64e2d21216e79b 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -738,14 +738,11 @@ builtin_compile_impl(PyObject *module, PyObject *source, PyObject *filename, cf.cf_feature_version = feature_version; } - if (flags & - ~(PyCF_MASK | PyCF_MASK_OBSOLETE | PyCF_COMPILE_MASK)) - { + if (flags & ~(PyCF_MASK | PyCF_COMPILE_MASK)) { PyErr_SetString(PyExc_ValueError, "compile(): unrecognised flags"); goto error; } - /* XXX Warn if (supplied_flags & PyCF_MASK_OBSOLETE) != 0? */ if (optimize < -1 || optimize > 2) { PyErr_SetString(PyExc_ValueError, diff --git a/Python/ceval.c b/Python/ceval.c index 59765d850ba1db..ed44dccc8b0ddc 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -4913,12 +4913,6 @@ PyEval_MergeCompilerFlags(PyCompilerFlags *cf) result = 1; cf->cf_flags |= compilerflags; } -#if 0 /* future keyword */ - if (codeflags & CO_GENERATOR_ALLOWED) { - result = 1; - cf->cf_flags |= CO_GENERATOR_ALLOWED; - } -#endif } return result; } From 9670aa2900bc59bdb59b0059f2e8326393b75990 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Batuhan=20Ta=C5=9Fkaya?= Date: Thu, 23 Apr 2020 03:14:37 +0300 Subject: [PATCH 2/2] Add _ObsoletedFeature --- Doc/library/__future__.rst | 5 ++++- Lib/__future__.py | 7 +++++-- Lib/test/test___future__.py | 15 +++++++++++++-- 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/Doc/library/__future__.rst b/Doc/library/__future__.rst index e3d749e6017847..2a79fc20ec1d4a 100644 --- a/Doc/library/__future__.rst +++ b/Doc/library/__future__.rst @@ -22,11 +22,14 @@ can be inspected programmatically via importing :mod:`__future__` and examining its contents. -Each statement in :file:`__future__.py` is of the form:: +Each statement in :file:`__future__.py` is in one of these forms:: FeatureName = _Feature(OptionalRelease, MandatoryRelease, CompilerFlag) + FeatureName = _ObsoletedFeature(OptionalRelease, MandatoryRelease, + CompilerFlag) + where, normally, *OptionalRelease* is less than *MandatoryRelease*, and both are 5-tuples of the same form as :data:`sys.version_info`:: diff --git a/Lib/__future__.py b/Lib/__future__.py index d7cb8ac5f49745..1474c763f472a3 100644 --- a/Lib/__future__.py +++ b/Lib/__future__.py @@ -105,11 +105,14 @@ def __repr__(self): self.mandatory, self.compiler_flag)) -nested_scopes = _Feature((2, 1, 0, "beta", 1), +class _ObsoletedFuture(_Feature): + pass + +nested_scopes = _ObsoletedFuture((2, 1, 0, "beta", 1), (2, 2, 0, "alpha", 0), CO_NESTED) -generators = _Feature((2, 2, 0, "alpha", 1), +generators = _ObsoletedFuture((2, 2, 0, "alpha", 1), (2, 3, 0, "final", 0), CO_GENERATOR_ALLOWED) diff --git a/Lib/test/test___future__.py b/Lib/test/test___future__.py index 559a1873adddc9..c77d6cf5cc0490 100644 --- a/Lib/test/test___future__.py +++ b/Lib/test/test___future__.py @@ -51,8 +51,19 @@ def check(t, name): a(hasattr(value, "compiler_flag"), "feature is missing a .compiler_flag attr") - # Make sure the compile accepts the flag. - compile("", "", "exec", value.compiler_flag) + + if isinstance(value, __future__._ObsoletedFuture) and value.compiler_flag: + self.assertRaises( + ValueError, + compile, + "", + "", + "exec", + value.compiler_flag + ) + else: + # Make sure the compile accepts the flag. + compile("", "", "exec", value.compiler_flag) a(isinstance(getattr(value, "compiler_flag"), int), ".compiler_flag isn't int")