Original file line numberDiff line numberDiff line change@@ -832,6 +832,10 @@ Changes in the Python API
832832 inherit from it should have this method defined.
833833 (Contributed by Kyle Stanley in :issue:`34037`.)
834834835+* The constant values of future flags in the :mod:`__future__` module
836+ is updated in order to prevent collision with compiler flags. Previously
837+ ``PyCF_ALLOW_TOP_LEVEL_AWAIT`` was clashing with ``CO_FUTURE_DIVISION``.
838+ (Contributed by Batuhan Taskaya in :issue:`39562`)
835839836840CPython bytecode changes
837841------------------------
Original file line numberDiff line numberDiff line change@@ -88,19 +88,19 @@ typedef struct {
8888#defineCO_ITERABLE_COROUTINE 0x0100
8989#defineCO_ASYNC_GENERATOR 0x0200
909091-/* These are no longer used. */
92-#if0
93-#defineCO_GENERATOR_ALLOWED 0x1000
94-#endif
95-#defineCO_FUTURE_DIVISION0x2000
96-#defineCO_FUTURE_ABSOLUTE_IMPORT0x4000/* do absolute imports by default */
97-#defineCO_FUTURE_WITH_STATEMENT0x8000
98-#defineCO_FUTURE_PRINT_FUNCTION0x10000
99-#defineCO_FUTURE_UNICODE_LITERALS0x20000
100-101-#defineCO_FUTURE_BARRY_AS_BDFL0x40000
102-#defineCO_FUTURE_GENERATOR_STOP0x80000
103-#defineCO_FUTURE_ANNOTATIONS0x100000
91+/* bpo-39562: These constant values are changed in Python 3.9
92+ to prevent collision with compiler flags. CO_FUTURE_ and PyCF_
93+ constants must be kept unique. PyCF_ constants can use bits from
94+ 0x0100 to 0x10000. CO_FUTURE_ constants use bits starting at 0x20000. */
95+#defineCO_FUTURE_DIVISION0x20000
96+#defineCO_FUTURE_ABSOLUTE_IMPORT0x40000/* do absolute imports by default */
97+#defineCO_FUTURE_WITH_STATEMENT0x80000
98+#defineCO_FUTURE_PRINT_FUNCTION0x100000
99+#defineCO_FUTURE_UNICODE_LITERALS0x200000
100+101+#defineCO_FUTURE_BARRY_AS_BDFL0x400000
102+#defineCO_FUTURE_GENERATOR_STOP0x800000
103+#defineCO_FUTURE_ANNOTATIONS0x1000000
104104105105/* This value is found in the co_cell2arg array when the associated cell
106106 variable does not correspond to an argument. */
Original file line numberDiff line numberDiff line change@@ -18,12 +18,18 @@ PyAPI_FUNC(PyCodeObject *) PyNode_Compile(struct _node *, const char *);
1818 CO_FUTURE_UNICODE_LITERALS | CO_FUTURE_BARRY_AS_BDFL | \
1919 CO_FUTURE_GENERATOR_STOP | CO_FUTURE_ANNOTATIONS)
2020#definePyCF_MASK_OBSOLETE (CO_NESTED)
21+22+/* bpo-39562: CO_FUTURE_ and PyCF_ constants must be kept unique.
23+ PyCF_ constants can use bits from 0x0100 to 0x10000.
24+ CO_FUTURE_ constants use bits starting at 0x20000. */
2125#definePyCF_SOURCE_IS_UTF8 0x0100
2226#definePyCF_DONT_IMPLY_DEDENT 0x0200
2327#definePyCF_ONLY_AST 0x0400
2428#definePyCF_IGNORE_COOKIE 0x0800
2529#definePyCF_TYPE_COMMENTS 0x1000
2630#definePyCF_ALLOW_TOP_LEVEL_AWAIT 0x2000
31+#definePyCF_COMPILE_MASK (PyCF_ONLY_AST | PyCF_ALLOW_TOP_LEVEL_AWAIT | \
32+ PyCF_TYPE_COMMENTS | PyCF_DONT_IMPLY_DEDENT)
27332834#ifndefPy_LIMITED_API
2935typedefstruct {
Original file line numberDiff line numberDiff line change@@ -68,14 +68,14 @@
6868# this module.
6969CO_NESTED=0x0010# nested_scopes
7070CO_GENERATOR_ALLOWED=0# generators (obsolete, was 0x1000)
71-CO_FUTURE_DIVISION=0x2000# division
72-CO_FUTURE_ABSOLUTE_IMPORT=0x4000# perform absolute imports by default
73-CO_FUTURE_WITH_STATEMENT=0x8000# with statement
74-CO_FUTURE_PRINT_FUNCTION=0x10000# print function
75-CO_FUTURE_UNICODE_LITERALS=0x20000# unicode string literals
76-CO_FUTURE_BARRY_AS_BDFL=0x40000
77-CO_FUTURE_GENERATOR_STOP=0x80000# StopIteration becomes RuntimeError in generators
78-CO_FUTURE_ANNOTATIONS=0x100000# annotations become strings at runtime
71+CO_FUTURE_DIVISION=0x20000# division
72+CO_FUTURE_ABSOLUTE_IMPORT=0x40000# perform absolute imports by default
73+CO_FUTURE_WITH_STATEMENT=0x80000# with statement
74+CO_FUTURE_PRINT_FUNCTION=0x100000# print function
75+CO_FUTURE_UNICODE_LITERALS=0x200000# unicode string literals
76+CO_FUTURE_BARRY_AS_BDFL=0x400000
77+CO_FUTURE_GENERATOR_STOP=0x800000# StopIteration becomes RuntimeError in generators
78+CO_FUTURE_ANNOTATIONS=0x1000000# annotations become strings at runtime
79798080class_Feature:
8181def__init__(self, optionalRelease, mandatoryRelease, compiler_flag):
Original file line numberDiff line numberDiff line change@@ -1,5 +1,7 @@
11# Test various flavors of legal and illegal future statements
223+import__future__
4+importast
35importunittest
46fromtestimportsupport
57fromtextwrapimportdedent
@@ -75,6 +77,21 @@ def test_badfuture10(self):
7577fromtestimportbadsyntax_future10
7678self.check_syntax_error(cm.exception, "badsyntax_future10", 3)
777980+deftest_ensure_flags_dont_clash(self):
81+# bpo-39562: test that future flags and compiler flags doesn't clash
82+83+# obtain future flags (CO_FUTURE_***) from the __future__ module
84+flags= {
85+f"CO_FUTURE_{future.upper()}": getattr(__future__, future).compiler_flag
86+forfuturein__future__.all_feature_names
87+ }
88+# obtain some of the exported compiler flags (PyCF_***) from the ast module
89+flags|= {
90+flag: getattr(ast, flag)
91+forflagindir(ast) ifflag.startswith("PyCF_")
92+ }
93+self.assertCountEqual(set(flags.values()), flags.values())
94+7895deftest_parserhack(self):
7996# test that the parser.c::future_hack function works as expected
8097# Note: although this test must pass, it's not testing the original
Original file line numberDiff line numberDiff line change@@ -739,7 +739,7 @@ builtin_compile_impl(PyObject *module, PyObject *source, PyObject *filename,
739739 }
740740741741if (flags&
742- ~(PyCF_MASK | PyCF_MASK_OBSOLETE | PyCF_DONT_IMPLY_DEDENT | PyCF_ONLY_AST | PyCF_TYPE_COMMENTS))
742+ ~(PyCF_MASK | PyCF_MASK_OBSOLETE | PyCF_COMPILE_MASK))
743743 {
744744PyErr_SetString(PyExc_ValueError,
745745"compile(): unrecognised flags");