Skip to content

Commit 445778f

Browse files
pablogsal1st1vstinner
committed
bpo-2506: Add -X noopt command line option
Add -X noopt command line option to disable compiler optimizations. distutils ignores noopt: always enable compiler optimizations. * Add sys.flags.noopt flag. * Add 'noopt' keyword-only parameter to builtin compile(), importlib.util.cache_from_source() and py_compile.compile(). * importlib: SourceLoader gets an additional keyword-only '_noopt' parameter. It is used by py_compile.compile(). * importlib uses ``.noopt.pyc`` suffix for .pyc files if sys.flags.noopt is true. * Add PyConfig.optimize parameter. * Update subprocess._optim_args_from_interpreter_flags(). * Add support.requires_compiler_optimizations() * Update unit tests which rely on compiler optimizations for noopt: add @support.requires_compiler_optimizations. * Rename c_optimize to c_optimization_level in compiler.c Co-Authored-By: Yury Selivanov <yury@magic.io> Co-Authored-By: Victor Stinner <vstinner@python.org>
1 parent c3a651a commit 445778f

40 files changed

+3087
-2772
lines changed

Doc/c-api/init_config.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -580,6 +580,14 @@ PyConfig
580580
by the function calculating the :ref:`Path Configuration
581581
<init-path-config>`.
582582
583+
.. c:member:: int optimize
584+
585+
Should the compiler optimize bytecode? If equal to 0, disable the
586+
compiler optimizations and set :c:member:`~PyConfig.optimization_level`
587+
to 0. Set to 0 by :option:`-X noopt <-X>` command line option.
588+
589+
.. versionadded:: 3.10
590+
583591
.. c:member:: int optimization_level
584592
585593
Compilation optimization level:

Doc/library/functions.rst

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ are always available. They are listed here in alphabetical order.
242242
Class methods can now wrap other :term:`descriptors <descriptor>` such as
243243
:func:`property`.
244244

245-
.. function:: compile(source, filename, mode, flags=0, dont_inherit=False, optimize=-1)
245+
.. function:: compile(source, filename, mode, flags=0, dont_inherit=False, optimize=-1, noopt=None)
246246

247247
Compile the *source* into a code or AST object. Code objects can be executed
248248
by :func:`exec` or :func:`eval`. *source* can either be a normal string, a
@@ -286,6 +286,9 @@ are always available. They are listed here in alphabetical order.
286286
``__debug__`` is true), ``1`` (asserts are removed, ``__debug__`` is false)
287287
or ``2`` (docstrings are removed too).
288288

289+
If *noopt* is false, disable compiler optimizations and ignore *optimize*
290+
argument. If it is ``None``, use ``sys.flags.noopt`` value.
291+
289292
This function raises :exc:`SyntaxError` if the compiled source is invalid,
290293
and :exc:`ValueError` if the source contains null bytes.
291294

@@ -319,10 +322,13 @@ are always available. They are listed here in alphabetical order.
319322
Previously, :exc:`TypeError` was raised when null bytes were encountered
320323
in *source*.
321324

322-
.. versionadded:: 3.8
325+
.. versionchanged:: 3.8
323326
``ast.PyCF_ALLOW_TOP_LEVEL_AWAIT`` can now be passed in flags to enable
324327
support for top-level ``await``, ``async for``, and ``async with``.
325328

329+
.. versionachanged:: 3.10
330+
New *noopt* optional keyword-only parameter.
331+
326332

327333
.. class:: complex([real[, imag]])
328334

Doc/library/importlib.rst

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1410,7 +1410,7 @@ an :term:`importer`.
14101410

14111411
.. versionadded:: 3.4
14121412

1413-
.. function:: cache_from_source(path, debug_override=None, *, optimization=None)
1413+
.. function:: cache_from_source(path, debug_override=None, *, optimization=None, noopt=None)
14141414

14151415
Return the :pep:`3147`/:pep:`488` path to the byte-compiled file associated
14161416
with the source *path*. For example, if *path* is ``/foo/bar/baz.py`` the return
@@ -1429,6 +1429,11 @@ an :term:`importer`.
14291429
``/foo/bar/__pycache__/baz.cpython-32.opt-2.pyc``. The string representation
14301430
of *optimization* can only be alphanumeric, else :exc:`ValueError` is raised.
14311431

1432+
The *noopt* parameter is used to specify if compiler optimization are
1433+
disabled. If it is true, *optimization* is ignored and ``.noopt`` suffix is
1434+
used (ex: ``baz.cpython-32.noopt.pyc``). If it is ``None``, use
1435+
``sys.flags.noopt`` value.
1436+
14321437
The *debug_override* parameter is deprecated and can be used to override
14331438
the system's value for ``__debug__``. A ``True`` value is the equivalent of
14341439
setting *optimization* to the empty string. A ``False`` value is the same as
@@ -1444,6 +1449,9 @@ an :term:`importer`.
14441449
.. versionchanged:: 3.6
14451450
Accepts a :term:`path-like object`.
14461451

1452+
.. versionchanged:: 3.10
1453+
Added *noopt* parameter.
1454+
14471455

14481456
.. function:: source_from_cache(path)
14491457

Doc/library/py_compile.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ byte-code cache files in the directory containing the source code.
6060
:func:`compile` function. The default of ``-1`` selects the optimization
6161
level of the current interpreter.
6262

63+
If *noopt* is true, disable compiler optimizations and ignore *optimize*
64+
argument. If it is ``None``, use ``sys.flags.noopt`` value.
65+
6366
*invalidation_mode* should be a member of the :class:`PycInvalidationMode`
6467
enum and controls how the generated bytecode cache is invalidated at
6568
runtime. The default is :attr:`PycInvalidationMode.CHECKED_HASH` if
@@ -92,6 +95,9 @@ byte-code cache files in the directory containing the source code.
9295
.. versionchanged:: 3.8
9396
The *quiet* parameter was added.
9497

98+
.. versionchanged:: 3.10
99+
The *noopt* parameter was added.
100+
95101

96102
.. class:: PycInvalidationMode
97103

Doc/library/sys.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,7 @@ always available.
439439
:const:`inspect` :option:`-i`
440440
:const:`interactive` :option:`-i`
441441
:const:`isolated` :option:`-I`
442+
:const:`noopt` :option:`-X noopt <-X>`
442443
:const:`optimize` :option:`-O` or :option:`-OO`
443444
:const:`dont_write_bytecode` :option:`-B`
444445
:const:`no_user_site` :option:`-s`
@@ -469,6 +470,9 @@ always available.
469470
Mode <devmode>` and the ``utf8_mode`` attribute for the new :option:`-X`
470471
``utf8`` flag.
471472

473+
.. versionchanged:: 3.10
474+
Added ``noopt`` attribute for the new :option:`-X noopt <-X>` option.
475+
472476

473477
.. data:: float_info
474478

Doc/using/cmdline.rst

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,7 @@ Miscellaneous options
454454
* ``-X pycache_prefix=PATH`` enables writing ``.pyc`` files to a parallel
455455
tree rooted at the given directory instead of to the code tree. See also
456456
:envvar:`PYTHONPYCACHEPREFIX`.
457+
* ``-X noopt`` disables the compiler optimizations.
457458

458459
It also allows passing arbitrary values and retrieving them through the
459460
:data:`sys._xoptions` dictionary.
@@ -477,9 +478,9 @@ Miscellaneous options
477478
The ``-X pycache_prefix`` option. The ``-X dev`` option now logs
478479
``close()`` exceptions in :class:`io.IOBase` destructor.
479480

480-
.. versionchanged:: 3.9
481-
Using ``-X dev`` option, check *encoding* and *errors* arguments on
482-
string encoding and decoding operations.
481+
.. versionadded:: 3.10
482+
The ``-X noopt`` option. Using ``-X dev`` option, check *encoding* and
483+
*errors* arguments on string encoding and decoding operations.
483484

484485
The ``-X showalloccount`` option has been removed.
485486

Doc/whatsnew/3.10.rst

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,11 @@ Other Language Changes
9393
:meth:`~object.__index__` method).
9494
(Contributed by Serhiy Storchaka in :issue:`37999`.)
9595

96+
* Added :option:`-X noopt <-X>` command line to disable compiler optimizations.
97+
:mod:`importlib` uses ``.noopt.pyc`` suffix for ``.pyc`` filenames if
98+
:data:`sys.flags.noopt` is true.
99+
(Contributed by Yury Selivanov, Victor Stinner and Pablo Galindo in :issue:`2506`)
100+
96101

97102
New Modules
98103
===========
@@ -109,6 +114,12 @@ base64
109114
Add :func:`base64.b32hexencode` and :func:`base64.b32hexdecode` to support the
110115
Base32 Encoding with Extended Hex Alphabet.
111116

117+
builtins
118+
--------
119+
120+
The :func:`compile` function gets a new optional keyword-only *noopt* parameter
121+
to disable compiler optimizations.
122+
112123
curses
113124
------
114125

@@ -126,6 +137,20 @@ Added the *root_dir* and *dir_fd* parameters in :func:`~glob.glob` and
126137
:func:`~glob.iglob` which allow to specify the root directory for searching.
127138
(Contributed by Serhiy Storchaka in :issue:`38144`.)
128139

140+
importlib
141+
---------
142+
143+
Add a new *noopt* optional keyword-only parameter to
144+
:func:`importlib.util.cache_from_source` to disable compiler optimizations.
145+
(Contributed by Yury Selivanov, Victor Stinner and Pablo Galindo in :issue:`2506`)
146+
147+
py_compile
148+
----------
149+
150+
Add a new *noopt* optional keyword-only parameter to :func:`py_compile.compile`
151+
to disable compiler optimizations.
152+
(Contributed by Yury Selivanov, Victor Stinner and Pablo Galindo in :issue:`2506`)
153+
129154
os
130155
--
131156

@@ -145,6 +170,11 @@ Add :data:`sys.orig_argv` attribute: the list of the original command line
145170
arguments passed to the Python executable.
146171
(Contributed by Victor Stinner in :issue:`23427`.)
147172

173+
174+
Add new :data:`sys.flags.noopt` flag for the new :option:`-X noopt <-X>` option
175+
(disable compiler optimizations).
176+
(Contributed by Yury Selivanov, Victor Stinner and Pablo Galindo in :issue:`2506`)
177+
148178
xml
149179
---
150180

Include/compile.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,4 +106,7 @@ PyAPI_FUNC(int) _PyAST_Optimize(struct _mod *, PyArena *arena, _PyASTOptimizeSta
106106
/* This doesn't need to match anything */
107107
#define Py_fstring_input 800
108108

109+
/* Value of 'optimize' to deactivate all optimizations */
110+
#define _PyCompiler_disable_all_optimizations -2
111+
109112
#endif /* !Py_COMPILE_H */

Include/cpython/initconfig.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,17 @@ typedef struct {
417417
418418
_PyConfig_Write() initializes Py_GetArgcArgv() to this list. */
419419
PyWideStringList orig_argv;
420+
421+
/* Should the compiler optimize bytecode?
422+
423+
If equal to 0, disable compiler optimizations and set optimization_level
424+
to 0.
425+
426+
If equal to 1, enable compiler optimizations.
427+
428+
Set to 0 by -X noopt. */
429+
int optimize;
430+
420431
} PyConfig;
421432

422433
PyAPI_FUNC(void) PyConfig_InitPythonConfig(PyConfig *config);

Include/pythonrun.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,11 @@ PyAPI_FUNC(PyObject *) Py_CompileStringObject(
6262
PyObject *filename, int start,
6363
PyCompilerFlags *flags,
6464
int optimize);
65+
PyAPI_FUNC(PyObject *) _Py_CompileString(
66+
const char *str,
67+
PyObject *filename, int start,
68+
PyCompilerFlags *flags,
69+
int optimize);
6570
#endif
6671
PyAPI_FUNC(struct symtable *) Py_SymtableString(
6772
const char *str,

0 commit comments

Comments
 (0)