[Python-checkins] (no subject)
Batuhan Taşkaya
webhook-mailer at python.org
Wed Apr 22 12:09:07 EDT 2020
To: python-checkins at python.org
Subject: bpo-39562: Prevent collision of future and compiler flags (GH-19230)
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: quoted-printable
MIME-Version: 1.0
https://github.com/python/cpython/commit/4454057269b995341b04d13f0bf97f96080f=
27d0
commit: 4454057269b995341b04d13f0bf97f96080f27d0
branch: master
author: Batuhan Ta=C5=9Fkaya <batuhanosmantaskaya at gmail.com>
committer: GitHub <noreply at github.com>
date: 2020-04-22T18:09:03+02:00
summary:
bpo-39562: Prevent collision of future and compiler flags (GH-19230)
The constant values of future flags in the __future__ module
is updated in order to prevent collision with compiler flags.
Previously PyCF_ALLOW_TOP_LEVEL_AWAIT was clashing
with CO_FUTURE_DIVISION.
files:
M Doc/whatsnew/3.9.rst
M Include/code.h
M Include/compile.h
M Lib/__future__.py
M Lib/test/test_future.py
M Python/bltinmodule.c
diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst
index 20ebe92865a14..8064785178c49 100644
--- a/Doc/whatsnew/3.9.rst
+++ b/Doc/whatsnew/3.9.rst
@@ -832,6 +832,10 @@ Changes in the Python API
inherit from it should have this method defined.
(Contributed by Kyle Stanley in :issue:`34037`.)
=20
+* The constant values of future flags in the :mod:`__future__` module
+ is updated in order to prevent collision with compiler flags. Previously
+ ``PyCF_ALLOW_TOP_LEVEL_AWAIT`` was clashing with ``CO_FUTURE_DIVISION``.
+ (Contributed by Batuhan Taskaya in :issue:`39562`)
=20
CPython bytecode changes
------------------------
diff --git a/Include/code.h b/Include/code.h
index 107eba4b9c431..b268a6aedff8d 100644
--- a/Include/code.h
+++ b/Include/code.h
@@ -88,19 +88,19 @@ typedef struct {
#define CO_ITERABLE_COROUTINE 0x0100
#define CO_ASYNC_GENERATOR 0x0200
=20
-/* These are no longer used. */
-#if 0
-#define CO_GENERATOR_ALLOWED 0x1000
-#endif
-#define CO_FUTURE_DIVISION 0x2000
-#define CO_FUTURE_ABSOLUTE_IMPORT 0x4000 /* do absolute imports by default */
-#define CO_FUTURE_WITH_STATEMENT 0x8000
-#define CO_FUTURE_PRINT_FUNCTION 0x10000
-#define CO_FUTURE_UNICODE_LITERALS 0x20000
-
-#define CO_FUTURE_BARRY_AS_BDFL 0x40000
-#define CO_FUTURE_GENERATOR_STOP 0x80000
-#define CO_FUTURE_ANNOTATIONS 0x100000
+/* bpo-39562: These constant values are changed in Python 3.9
+ to prevent collision with compiler flags. CO_FUTURE_ and PyCF_
+ constants must be kept unique. PyCF_ constants can use bits from
+ 0x0100 to 0x10000. CO_FUTURE_ constants use bits starting at 0x20000. */
+#define CO_FUTURE_DIVISION 0x20000
+#define CO_FUTURE_ABSOLUTE_IMPORT 0x40000 /* do absolute imports by default =
*/
+#define CO_FUTURE_WITH_STATEMENT 0x80000
+#define CO_FUTURE_PRINT_FUNCTION 0x100000
+#define CO_FUTURE_UNICODE_LITERALS 0x200000
+
+#define CO_FUTURE_BARRY_AS_BDFL 0x400000
+#define CO_FUTURE_GENERATOR_STOP 0x800000
+#define CO_FUTURE_ANNOTATIONS 0x1000000
=20
/* This value is found in the co_cell2arg array when the associated cell
variable does not correspond to an argument. */
diff --git a/Include/compile.h b/Include/compile.h
index c0c73b29e4d9d..a2db65d47f001 100644
--- a/Include/compile.h
+++ b/Include/compile.h
@@ -18,12 +18,18 @@ PyAPI_FUNC(PyCodeObject *) PyNode_Compile(struct _node *,=
const char *);
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.
+ CO_FUTURE_ constants use bits starting at 0x20000. */
#define PyCF_SOURCE_IS_UTF8 0x0100
#define PyCF_DONT_IMPLY_DEDENT 0x0200
#define PyCF_ONLY_AST 0x0400
#define PyCF_IGNORE_COOKIE 0x0800
#define PyCF_TYPE_COMMENTS 0x1000
#define PyCF_ALLOW_TOP_LEVEL_AWAIT 0x2000
+#define PyCF_COMPILE_MASK (PyCF_ONLY_AST | PyCF_ALLOW_TOP_LEVEL_AWAIT | \
+ PyCF_TYPE_COMMENTS | PyCF_DONT_IMPLY_DEDENT)
=20
#ifndef Py_LIMITED_API
typedef struct {
diff --git a/Lib/__future__.py b/Lib/__future__.py
index e1135685d846c..d7cb8ac5f4974 100644
--- a/Lib/__future__.py
+++ b/Lib/__future__.py
@@ -68,14 +68,14 @@
# this module.
CO_NESTED =3D 0x0010 # nested_scopes
CO_GENERATOR_ALLOWED =3D 0 # generators (obsolete, was 0x1000)
-CO_FUTURE_DIVISION =3D 0x2000 # division
-CO_FUTURE_ABSOLUTE_IMPORT =3D 0x4000 # perform absolute imports by default
-CO_FUTURE_WITH_STATEMENT =3D 0x8000 # with statement
-CO_FUTURE_PRINT_FUNCTION =3D 0x10000 # print function
-CO_FUTURE_UNICODE_LITERALS =3D 0x20000 # unicode string literals
-CO_FUTURE_BARRY_AS_BDFL =3D 0x40000
-CO_FUTURE_GENERATOR_STOP =3D 0x80000 # StopIteration becomes RuntimeError i=
n generators
-CO_FUTURE_ANNOTATIONS =3D 0x100000 # annotations become strings at runt=
ime
+CO_FUTURE_DIVISION =3D 0x20000 # division
+CO_FUTURE_ABSOLUTE_IMPORT =3D 0x40000 # perform absolute imports by default
+CO_FUTURE_WITH_STATEMENT =3D 0x80000 # with statement
+CO_FUTURE_PRINT_FUNCTION =3D 0x100000 # print function
+CO_FUTURE_UNICODE_LITERALS =3D 0x200000 # unicode string literals
+CO_FUTURE_BARRY_AS_BDFL =3D 0x400000
+CO_FUTURE_GENERATOR_STOP =3D 0x800000 # StopIteration becomes RuntimeError =
in generators
+CO_FUTURE_ANNOTATIONS =3D 0x1000000 # annotations become strings at run=
time
=20
class _Feature:
def __init__(self, optionalRelease, mandatoryRelease, compiler_flag):
diff --git a/Lib/test/test_future.py b/Lib/test/test_future.py
index fdca2312fab7c..56b7ac6865559 100644
--- a/Lib/test/test_future.py
+++ b/Lib/test/test_future.py
@@ -1,5 +1,7 @@
# Test various flavors of legal and illegal future statements
=20
+import __future__
+import ast
import unittest
from test import support
from textwrap import dedent
@@ -75,6 +77,21 @@ def test_badfuture10(self):
from test import badsyntax_future10
self.check_syntax_error(cm.exception, "badsyntax_future10", 3)
=20
+ def test_ensure_flags_dont_clash(self):
+ # bpo-39562: test that future flags and compiler flags doesn't clash
+
+ # obtain future flags (CO_FUTURE_***) from the __future__ module
+ flags =3D {
+ f"CO_FUTURE_{future.upper()}": getattr(__future__, future).compi=
ler_flag
+ for future in __future__.all_feature_names
+ }
+ # obtain some of the exported compiler flags (PyCF_***) from the ast=
module
+ flags |=3D {
+ flag: getattr(ast, flag)
+ for flag in dir(ast) if flag.startswith("PyCF_")
+ }
+ self.assertCountEqual(set(flags.values()), flags.values())
+
def test_parserhack(self):
# test that the parser.c::future_hack function works as expected
# Note: although this test must pass, it's not testing the original
diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c
index a9fc21f108774..22ee5969473f5 100644
--- a/Python/bltinmodule.c
+++ b/Python/bltinmodule.c
@@ -739,7 +739,7 @@ builtin_compile_impl(PyObject *module, PyObject *source, =
PyObject *filename,
}
=20
if (flags &
- ~(PyCF_MASK | PyCF_MASK_OBSOLETE | PyCF_DONT_IMPLY_DEDENT | PyCF_ONL=
Y_AST | PyCF_TYPE_COMMENTS))
+ ~(PyCF_MASK | PyCF_MASK_OBSOLETE | PyCF_COMPILE_MASK))
{
PyErr_SetString(PyExc_ValueError,
"compile(): unrecognised flags");
More information about the Python-checkins
mailing list