]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-141004: Document remaining `PyCF_*` compiler flag macros (GH-153958)
authorBartosz Sławecki <bartosz@ilikepython.com>
Sat, 18 Jul 2026 14:42:24 +0000 (16:42 +0200)
committerGitHub <noreply@github.com>
Sat, 18 Jul 2026 14:42:24 +0000 (14:42 +0000)
Doc/c-api/veryhigh.rst
Tools/check-c-api-docs/ignored_c_api.txt

index 6256bf7a1454a9a74e1e4dd4b90a856f7344ed80..bba5c7f8ecf7751c7758dd8cb722f6e142337ba7 100644 (file)
@@ -343,11 +343,125 @@ the same library that the Python runtime is using.
       :py:mod:`!ast` Python module, which exports these constants under
       the same names.
 
+   .. rubric:: Low-level flags
+
+   The following flags and masks serve narrow needs of the standard
+   library and interactive interpreters.  Code outside the standard
+   library rarely has a reason to use them.  They are considered
+   implementation details and may change at any time.
+
+   .. c:macro:: PyCF_ALLOW_INCOMPLETE_INPUT
+
+      This flag is a private interface between the compiler and the
+      :mod:`codeop` module.  Do not use it; its behavior is unsupported
+      and may change without warning.
+
+      With this flag set, when compilation fails because the source text
+      ends where more input is expected, for example in the middle of an
+      indented block or an unterminated string literal, the error raised
+      is the undocumented ``_IncompleteInputError``, a subclass of
+      :exc:`SyntaxError`.  The :mod:`codeop` module sets this flag,
+      together with :c:macro:`PyCF_DONT_IMPLY_DEDENT`, to tell input
+      that is incomplete apart from input with a real syntax error, so
+      that interactive interpreters know when to prompt for another
+      line instead of reporting an error.
+
+      .. versionadded:: 3.11
+
+   .. c:macro:: PyCF_DONT_IMPLY_DEDENT
+
+      By default, when compiling with the :c:var:`Py_single_input` start
+      symbol, reaching the end of the source text implicitly closes any
+      open indented blocks.  With this flag set, open blocks are only
+      closed if the last line of the source ends with a newline; otherwise,
+      compilation fails with a :exc:`SyntaxError`:
+
+      .. code-block:: c
+
+         PyCompilerFlags flags = {
+             .cf_flags = 0,
+             .cf_feature_version = PY_MINOR_VERSION,
+         };
+         const char *source = "if a:\n    pass";
+
+         /* The "if" block is closed implicitly;
+            this returns a code object: */
+         Py_CompileStringFlags(source, "<input>", Py_single_input, &flags);
+
+         /* With the flag, this fails with a SyntaxError,
+            because the last line does not end with a newline: */
+         flags.cf_flags = PyCF_DONT_IMPLY_DEDENT;
+         Py_CompileStringFlags(source, "<input>", Py_single_input, &flags);
+
+      The :mod:`codeop` module uses this flag to detect incomplete
+      interactive input.  While the user is still typing inside an
+      indented block, the source does not yet end with a newline, so it
+      fails to compile and the user is prompted for another line.
+
+   .. c:macro:: PyCF_IGNORE_COOKIE
+
+      Read the source text as UTF-8, ignoring its :pep:`263` encoding
+      declaration ("coding cookie"), if any:
+
+      .. code-block:: c
+
+         PyCompilerFlags flags = {
+             .cf_flags = 0,
+             .cf_feature_version = PY_MINOR_VERSION,
+         };
+         const char *source = "# coding: latin-1\ns = '\xe9'\n";
+
+         /* The coding cookie is honored: byte 0xE9 is decoded as
+            Latin-1, and this returns a code object that sets s to "é": */
+         Py_CompileStringFlags(source, "<input>", Py_file_input, &flags);
+
+         /* With the flag, the cookie is ignored and compilation fails
+            with a SyntaxError, because 0xE9 is not valid UTF-8: */
+         flags.cf_flags = PyCF_IGNORE_COOKIE;
+         Py_CompileStringFlags(source, "<input>", Py_file_input, &flags);
+
+      The :func:`compile`, :func:`eval` and :func:`exec` built-in functions
+      set this flag when the source is a :class:`str` object, because they
+      pass the text to the parser encoded as UTF-8.
+
+   .. c:macro:: PyCF_SOURCE_IS_UTF8
+
+      Mark the source text as known to be UTF-8 encoded.
+      The :func:`compile`, :func:`eval` and :func:`exec` built-in functions
+      set this flag, but it currently has no effect.
+
    The "``PyCF``" flags above can be combined with "``CO_FUTURE``" flags such
    as :c:macro:`CO_FUTURE_ANNOTATIONS` to enable features normally
    selectable using :ref:`future statements <future>`.
    See :ref:`c_codeobject_flags` for a complete list.
 
+   The following masks combine several flags:
+
+   .. c:macro:: PyCF_MASK
+
+      Bitmask of all ``CO_FUTURE`` flags (see :ref:`c_codeobject_flags`),
+      which select features normally enabled by
+      :ref:`future statements <future>`.
+      When code compiled with a ``PyCompilerFlags *flags`` argument
+      contains a ``from __future__ import`` statement, the flag for the
+      imported feature is added to *flags*, so that code executed later
+      in the same context inherits it.
+
+   .. c:macro:: PyCF_MASK_OBSOLETE
+
+      Do not use this mask in new code.  It is kept only so that old
+      code passing its flags to :func:`compile` keeps working.
+
+      Bitmask of flags for obsolete future features that no longer
+      have any effect.
+
+   .. c:macro:: PyCF_COMPILE_MASK
+
+      Bitmask of all ``PyCF`` flags that change how the source is
+      compiled, such as :c:macro:`PyCF_ONLY_AST`.
+      The :func:`compile` built-in function uses this mask to validate
+      its *flags* argument.
+
 
 .. _start-symbols:
 
index fa53b205c4ff6afed09e648aacc8370f147205ba..e04deffc64f5104324d68afffb687d284a0bd544 100644 (file)
@@ -29,14 +29,6 @@ PY_DWORD_MAX
 PY_BIG_ENDIAN
 # cpython/methodobject.h
 PyCFunction_GET_CLASS
-# cpython/compile.h
-PyCF_ALLOW_INCOMPLETE_INPUT
-PyCF_COMPILE_MASK
-PyCF_DONT_IMPLY_DEDENT
-PyCF_IGNORE_COOKIE
-PyCF_MASK
-PyCF_MASK_OBSOLETE
-PyCF_SOURCE_IS_UTF8
 # cpython/descrobject.h
 PyDescr_NAME
 PyDescr_TYPE