Skip to content

bpo-40366: Remove support for passing obsolete flags into compile #19660

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion Doc/library/__future__.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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`::
Expand Down
3 changes: 3 additions & 0 deletions Doc/whatsnew/3.9.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
=====================
Expand Down
1 change: 0 additions & 1 deletion Include/compile.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
7 changes: 5 additions & 2 deletions Lib/__future__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
15 changes: 13 additions & 2 deletions Lib/test/test___future__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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("", "<test>", "exec", value.compiler_flag)

if isinstance(value, __future__._ObsoletedFuture) and value.compiler_flag:
self.assertRaises(
ValueError,
compile,
"",
"<test>",
"exec",
value.compiler_flag
)
else:
# Make sure the compile accepts the flag.
compile("", "<test>", "exec", value.compiler_flag)
a(isinstance(getattr(value, "compiler_flag"), int),
".compiler_flag isn't int")

Expand Down
3 changes: 2 additions & 1 deletion Lib/test/test_builtin.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Removed support for ``CO_NESTED`` flag in :func:`compile`.
5 changes: 1 addition & 4 deletions Python/bltinmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
6 changes: 0 additions & 6 deletions Python/ceval.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down