| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 9b49893 commit 4454057
6 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -832,6 +832,10 @@ Changes in the Python API | |||
| 832 | 832 | inherit from it should have this method defined. | |
| 833 | 833 | (Contributed by Kyle Stanley in :issue:`34037`.) | |
| 834 | 834 | ||
| 835 | + * 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`) | ||
| 835 | 839 | ||
| 836 | 840 | CPython bytecode changes | |
| 837 | 841 | ------------------------ | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -88,19 +88,19 @@ typedef struct { | |||
| 88 | 88 | #define CO_ITERABLE_COROUTINE 0x0100 | |
| 89 | 89 | #define CO_ASYNC_GENERATOR 0x0200 | |
| 90 | 90 | ||
| 91 | - /* These are no longer used. */ | ||
| 92 | - #if 0 | ||
| 93 | - #define CO_GENERATOR_ALLOWED 0x1000 | ||
| 94 | - #endif | ||
| 95 | - #define CO_FUTURE_DIVISION 0x2000 | ||
| 96 | - #define CO_FUTURE_ABSOLUTE_IMPORT 0x4000 /* do absolute imports by default */ | ||
| 97 | - #define CO_FUTURE_WITH_STATEMENT 0x8000 | ||
| 98 | - #define CO_FUTURE_PRINT_FUNCTION 0x10000 | ||
| 99 | - #define CO_FUTURE_UNICODE_LITERALS 0x20000 | ||
| 100 | - | ||
| 101 | - #define CO_FUTURE_BARRY_AS_BDFL 0x40000 | ||
| 102 | - #define CO_FUTURE_GENERATOR_STOP 0x80000 | ||
| 103 | - #define CO_FUTURE_ANNOTATIONS 0x100000 | ||
| 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 | + #define CO_FUTURE_DIVISION 0x20000 | ||
| 96 | + #define CO_FUTURE_ABSOLUTE_IMPORT 0x40000 /* do absolute imports by default */ | ||
| 97 | + #define CO_FUTURE_WITH_STATEMENT 0x80000 | ||
| 98 | + #define CO_FUTURE_PRINT_FUNCTION 0x100000 | ||
| 99 | + #define CO_FUTURE_UNICODE_LITERALS 0x200000 | ||
| 100 | + | ||
| 101 | + #define CO_FUTURE_BARRY_AS_BDFL 0x400000 | ||
| 102 | + #define CO_FUTURE_GENERATOR_STOP 0x800000 | ||
| 103 | + #define CO_FUTURE_ANNOTATIONS 0x1000000 | ||
| 104 | 104 | ||
| 105 | 105 | /* This value is found in the co_cell2arg array when the associated cell | |
| 106 | 106 | variable does not correspond to an argument. */ | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -18,12 +18,18 @@ PyAPI_FUNC(PyCodeObject *) PyNode_Compile(struct _node *, const char *); | |||
| 18 | 18 | CO_FUTURE_UNICODE_LITERALS | CO_FUTURE_BARRY_AS_BDFL | \ | |
| 19 | 19 | CO_FUTURE_GENERATOR_STOP | CO_FUTURE_ANNOTATIONS) | |
| 20 | 20 | #define PyCF_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. */ | ||
| 21 | 25 | #define PyCF_SOURCE_IS_UTF8 0x0100 | |
| 22 | 26 | #define PyCF_DONT_IMPLY_DEDENT 0x0200 | |
| 23 | 27 | #define PyCF_ONLY_AST 0x0400 | |
| 24 | 28 | #define PyCF_IGNORE_COOKIE 0x0800 | |
| 25 | 29 | #define PyCF_TYPE_COMMENTS 0x1000 | |
| 26 | 30 | #define PyCF_ALLOW_TOP_LEVEL_AWAIT 0x2000 | |
| 31 | + #define PyCF_COMPILE_MASK (PyCF_ONLY_AST | PyCF_ALLOW_TOP_LEVEL_AWAIT | \ | ||
| 32 | + PyCF_TYPE_COMMENTS | PyCF_DONT_IMPLY_DEDENT) | ||
| 27 | 33 | ||
| 28 | 34 | #ifndef Py_LIMITED_API | |
| 29 | 35 | typedef struct { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -68,14 +68,14 @@ | |||
| 68 | 68 | # this module. | |
| 69 | 69 | CO_NESTED = 0x0010 # nested_scopes | |
| 70 | 70 | CO_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 | ||
| 79 | 79 | ||
| 80 | 80 | class _Feature: | |
| 81 | 81 | def __init__(self, optionalRelease, mandatoryRelease, compiler_flag): | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,5 +1,7 @@ | |||
| 1 | 1 | # Test various flavors of legal and illegal future statements | |
| 2 | 2 | ||
| 3 | + import __future__ | ||
| 4 | + import ast | ||
| 3 | 5 | import unittest | |
| 4 | 6 | from test import support | |
| 5 | 7 | from textwrap import dedent | |
@@ -75,6 +77,21 @@ def test_badfuture10(self): | |||
| 75 | 77 | from test import badsyntax_future10 | |
| 76 | 78 | self.check_syntax_error(cm.exception, "badsyntax_future10", 3) | |
| 77 | 79 | ||
| 80 | + def test_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 | + for future in __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 | + for flag in dir(ast) if flag.startswith("PyCF_") | ||
| 92 | + } | ||
| 93 | + self.assertCountEqual(set(flags.values()), flags.values()) | ||
| 94 | + | ||
| 78 | 95 | def test_parserhack(self): | |
| 79 | 96 | # test that the parser.c::future_hack function works as expected | |
| 80 | 97 | # Note: although this test must pass, it's not testing the original | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -739,7 +739,7 @@ builtin_compile_impl(PyObject *module, PyObject *source, PyObject *filename, | |||
| 739 | 739 | } | |
| 740 | 740 | ||
| 741 | 741 | if (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)) | ||
| 743 | 743 | { | |
| 744 | 744 | PyErr_SetString(PyExc_ValueError, | |
| 745 | 745 | "compile(): unrecognised flags"); | |
| Back | FazBrowse Home | New Git URL |
0 commit comments