Skip to content

Commit 3b87611

Browse files
authored
PEP 432: Update for C99 initializers (#12)
PEP 432: Update for C99 initializers
1 parent cd22b95 commit 3b87611

File tree

1 file changed

+42
-60
lines changed

1 file changed

+42
-60
lines changed

pep-0432.txt

Lines changed: 42 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,11 @@ well-defined phases during the initialization sequence:
5151
As a concrete use case to help guide any design changes, and to solve a known
5252
problem where the appropriate defaults for system utilities differ from those
5353
for running user scripts, this PEP also proposes the creation and
54-
distribution of a separate system Python (``pysystem``) executable
54+
distribution of a separate system Python (``system-python``) executable
5555
which, by default, operates in "isolated mode" (as selected by the CPython
56-
``-I`` switch).
56+
``-I`` switch), as well as the creation of an example stub binary that just
57+
runs an appended zip archive (permitting single-file pure Python executables)
58+
rather than going through the normal CPython startup sequence.
5759

5860
To keep the implementation complexity under control, this PEP does *not*
5961
propose wholesale changes to the way the interpreter state is accessed at
@@ -148,12 +150,12 @@ tear down the interpreter::
148150

149151
python3 -m timeit -s "from subprocess import call" "call(['./python', '-c', 'pass'])"
150152

151-
Current numbers on my system for Python 3.5 (using the 3.4
153+
Current numbers on my system for Python 3.6 (using the 3.5
152154
subprocess and timeit modules to execute the check, all with non-debug
153155
builds)::
154156

155157
$ python3 -m timeit -s "from subprocess import call" "call(['./python', '-c', 'pass'])"
156-
10 loops, best of 3: 18.2 msec per loop
158+
100 loops, best of 3: 15.1 msec per loop
157159

158160
This PEP is not expected to have any significant effect on the startup time,
159161
as it is aimed primarily at *reordering* the existing initialization
@@ -196,7 +198,7 @@ be able to control the following aspects of the final interpreter state:
196198
* ``os.fsencode``
197199
* ``os.fsdecode``
198200

199-
* The IO encoding (if any) and the buffering used by:
201+
* The IO encoding (if any), error handling, and buffering used by:
200202

201203
* ``sys.stdin``
202204
* ``sys.stdout``
@@ -224,11 +226,11 @@ be able to control the following aspects of the final interpreter state:
224226
* ``debug`` (Enable debugging output in the pgen parser)
225227
* ``inspect`` (Enter interactive interpreter after __main__ terminates)
226228
* ``interactive`` (Treat stdin as a tty)
227-
* ``optimize`` (__debug__ status, write .pyc or .pyo, strip doc strings)
229+
* ``optimize`` (__debug__ status, .pyc optimization marker, strip doc strings)
228230
* ``no_user_site`` (don't add the user site directory to sys.path)
229231
* ``no_site`` (don't implicitly import site during startup)
230232
* ``ignore_environment`` (whether environment vars are used during config)
231-
* ``verbose`` (enable all sorts of random output)
233+
* ``verbose`` (enable a variety of additional debugging messages)
232234
* ``bytes_warning`` (warnings/errors for implicit str/bytes interaction)
233235
* ``quiet`` (disable banner output even if verbose is also enabled or
234236
stdin is a tty and the interpreter is launched in interactive mode)
@@ -281,7 +283,7 @@ The affected APIs with a leading underscore, as they would be named in CPython
281283
* ``_Py_ReadHashSeed``
282284
* ``_Py_InitializeMainInterpreter``
283285
* ``_PyMainInterpreterConfig``
284-
* ``_PyMainInterpreterConfig_INIT``
286+
* ``_PyInterpreterConfig``
285287
* ``_Py_ReadMainInterpreterConfig``
286288
* ``_PyRun_PrepareMain``
287289
* ``_PyRun_ExecMain``
@@ -365,7 +367,7 @@ over the initialization process::
365367

366368
/* Phase 1: Pre-Initialization */
367369
PyCoreConfig core_config = PyCoreConfig_INIT;
368-
PyMainInterpreterConfig config = PyMainInterpreterConfig_INIT;
370+
PyMainInterpreterConfig config;
369371
/* Easily control the core configuration */
370372
core_config.ignore_environment = 1; /* Ignore environment variables */
371373
core_config.use_hash_seed = 0; /* Full hash randomisation */
@@ -424,7 +426,11 @@ configuration of the core runtime and creation of the main interpreter::
424426
int _disable_importlib; /* Needed by freeze_importlib */
425427
} PyCoreConfig;
426428

427-
#define PyCoreConfig_INIT {0, -1, 0, 0}
429+
#define PyCoreConfig_INIT {.use_hash_seed=-1}
430+
/* The above assumes PEP 7 is updated to permit use of C99 features
431+
* Without designated initialisers, the macro would be:
432+
* #define PyCoreConfig_INIT {0, -1, 0, 0}
433+
*/
428434

429435
The core configuration settings pointer may be ``NULL``, in which case the
430436
default values are ``ignore_environment = -1`` and ``use_hash_seed = -1``.
@@ -491,7 +497,7 @@ completion of the bulk of the initialization process::
491497
int Py_IsCoreInitialized();
492498

493499
Attempting to call ``Py_InitializeCore()`` again when
494-
``Py_IsCoreInitialized()`` is true is a fatal error.
500+
``Py_IsCoreInitialized()`` is already true is a fatal error.
495501

496502
As frozen bytecode may now be legitimately run in an interpreter which is not
497503
yet fully initialized, ``sys.flags`` will gain a new ``initialized`` flag.
@@ -601,8 +607,8 @@ feasibly be made interpreter specific over the course of the implementation.
601607

602608
The ``PyMainInterpreterConfig`` struct holds the settings required to
603609
complete the main interpreter configuration. These settings are also all
604-
passed through unmodified to subinterpreters. Fields are either pointers to
605-
Python data types (not set == ``NULL``) or numeric flags (not set == ``-1``)::
610+
passed through unmodified to subinterpreters. Fields are always pointers to
611+
Python data types, with unset values indicated by ``NULL``::
606612

607613
/* Note: if changing anything in PyMainInterpreterConfig, also update
608614
* PyMainInterpreterConfig_INIT */
@@ -622,36 +628,36 @@ Python data types (not set == ``NULL``) or numeric flags (not set == ``-1``)::
622628
PyUnicodeObject *base_exec_prefix; /* pyvenv.cfg */
623629

624630
/* Site module */
625-
int enable_site_config; /* -S switch (inverted) */
626-
int no_user_site; /* -s switch, PYTHONNOUSERSITE */
631+
PyBoolObject *enable_site_config; /* -S switch (inverted) */
632+
PyBoolObject *no_user_site; /* -s switch, PYTHONNOUSERSITE */
627633

628634
/* Import configuration */
629-
int dont_write_bytecode; /* -B switch, PYTHONDONTWRITEBYTECODE */
630-
int ignore_module_case; /* PYTHONCASEOK */
631-
PyListObject *import_path; /* PYTHONPATH (etc) */
635+
PyBoolObject *dont_write_bytecode; /* -B switch, PYTHONDONTWRITEBYTECODE */
636+
PyBoolObject *ignore_module_case; /* PYTHONCASEOK */
637+
PyListObject *import_path; /* PYTHONPATH (etc) */
632638

633639
/* Standard streams */
634-
int use_unbuffered_io; /* -u switch, PYTHONUNBUFFEREDIO */
635-
PyUnicodeObject *stdin_encoding; /* PYTHONIOENCODING */
636-
PyUnicodeObject *stdin_errors; /* PYTHONIOENCODING */
637-
PyUnicodeObject *stdout_encoding; /* PYTHONIOENCODING */
638-
PyUnicodeObject *stdout_errors; /* PYTHONIOENCODING */
639-
PyUnicodeObject *stderr_encoding; /* PYTHONIOENCODING */
640-
PyUnicodeObject *stderr_errors; /* PYTHONIOENCODING */
640+
PyBoolObject *use_unbuffered_io; /* -u switch, PYTHONUNBUFFEREDIO */
641+
PyUnicodeObject *stdin_encoding; /* PYTHONIOENCODING */
642+
PyUnicodeObject *stdin_errors; /* PYTHONIOENCODING */
643+
PyUnicodeObject *stdout_encoding; /* PYTHONIOENCODING */
644+
PyUnicodeObject *stdout_errors; /* PYTHONIOENCODING */
645+
PyUnicodeObject *stderr_encoding; /* PYTHONIOENCODING */
646+
PyUnicodeObject *stderr_errors; /* PYTHONIOENCODING */
641647

642648
/* Filesystem access */
643649
PyUnicodeObject *fs_encoding;
644650

645651
/* Debugging output */
646-
int debug_parser; /* -d switch, PYTHONDEBUG */
647-
int verbosity; /* -v switch */
652+
PyBoolObject *debug_parser; /* -d switch, PYTHONDEBUG */
653+
PyLongObject *verbosity; /* -v switch */
648654

649655
/* Code generation */
650-
int bytes_warnings; /* -b switch */
651-
int optimize; /* -O switch */
656+
PyLongObject *bytes_warnings; /* -b switch */
657+
PyLongObject *optimize; /* -O switch */
652658

653659
/* Signal handling */
654-
int install_signal_handlers;
660+
PyBoolObject *install_signal_handlers;
655661

656662
/* Implicit execution */
657663
PyUnicodeObject *startup_file; /* PYTHONSTARTUP */
@@ -662,47 +668,25 @@ Python data types (not set == ``NULL``) or numeric flags (not set == ``-1``)::
662668
* be set before calling PyRun_PrepareMain (Py_ReadMainInterpreterConfig
663669
* will set one of them based on the command line arguments if
664670
* prepare_main is non-zero when that API is called).
665-
int prepare_main;
671+
PyBoolObject *prepare_main;
666672
PyUnicodeObject *main_source; /* -c switch */
667673
PyUnicodeObject *main_path; /* filesystem path */
668674
PyUnicodeObject *main_module; /* -m switch */
669675
PyCodeObject *main_code; /* Run directly from a code object */
670676
PyObject *main_stream; /* Run from stream */
671-
int run_implicit_code; /* Run implicit code during prep */
677+
PyBoolObject *run_implicit_code; /* Run implicit code during prep */
672678

673679
/* Interactive main
674680
*
675681
* Note: Settings related to interactive mode are very much in flux.
676682
*/
677683
PyObject *prompt_stream; /* Output interactive prompt */
678-
int show_banner; /* -q switch (inverted) */
679-
int inspect_main; /* -i switch, PYTHONINSPECT */
684+
PyBoolObject *show_banner; /* -q switch (inverted) */
685+
PyBoolObject *inspect_main; /* -i switch, PYTHONINSPECT */
680686

681687
} PyMainInterpreterConfig;
682688

683-
684-
/* Struct initialization is pretty horrible in C89. Avoiding this mess would
685-
* be the most attractive aspect of using a PyDictObject* instead... */
686-
#define _PyArgConfig_INIT NULL, NULL, NULL, NULL
687-
#define _PyLocationConfig_INIT NULL, NULL, NULL, NULL, NULL, NULL
688-
#define _PySiteConfig_INIT -1, -1
689-
#define _PyImportConfig_INIT -1, -1, NULL
690-
#define _PyStreamConfig_INIT -1, NULL, NULL, NULL, NULL, NULL, NULL
691-
#define _PyFilesystemConfig_INIT NULL
692-
#define _PyDebuggingConfig_INIT -1, -1, -1
693-
#define _PyCodeGenConfig_INIT -1, -1
694-
#define _PySignalConfig_INIT -1
695-
#define _PyImplicitConfig_INIT NULL
696-
#define _PyMainConfig_INIT -1, NULL, NULL, NULL, NULL, NULL, -1
697-
#define _PyInteractiveConfig_INIT NULL, -1, -1
698-
699-
#define PyMainInterpreterConfig_INIT {
700-
_PyArgConfig_INIT, _PyLocationConfig_INIT,
701-
_PySiteConfig_INIT, _PyImportConfig_INIT,
702-
_PyStreamConfig_INIT, _PyFilesystemConfig_INIT,
703-
_PyDebuggingConfig_INIT, _PyCodeGenConfig_INIT,
704-
_PySignalConfig_INIT, _PyImplicitConfig_INIT,
705-
_PyMainConfig_INIT, _PyInteractiveConfig_INIT}
689+
/* Storing all state as Python object pointers */
706690

707691
The ``PyInterpreterConfig`` struct holds the settings that may vary between
708692
the main interpreter and subinterpreters. For the main interpreter, these
@@ -713,11 +697,9 @@ settings are automatically populated by ``Py_InitializeMainInterpreter()``.
713697
/* Note: if changing anything in PyInterpreterConfig, also update
714698
* PyInterpreterConfig_INIT */
715699
typedef struct {
716-
int is_main_interpreter; /* Easily check for subinterpreters */
700+
PyBoolObject *is_main_interpreter; /* Easily check for subinterpreters */
717701
} PyInterpreterConfig;
718702

719-
#define PyInterpreterConfig_INIT {0}
720-
721703
<TBD: did I miss anything?>
722704

723705

0 commit comments

Comments
 (0)