Nick Coghlan avatar Nick Coghlan committed ba6561f Draft

PEP 432: Reduce typing in proposed API

- consistently abbreviate Config
- follow the Py*Object naming convention for Py*Config structs by
dropping the underscore after the Py/_Py prefix

Comments (0)

Files changed (1)

 To keep the implementation complexity under control, this PEP does *not*
 propose wholesale changes to the way the interpreter state is accessed at
 runtime, nor does it propose changes to the way subinterpreters are
-created after the main interpreter has already been initialized. Changing
+created after the main interpreter has already been initialized (beyond
+any changes needed to make sure they continue working as expected). Changing
 the order in which the existing initialization steps occur in order to make
 the startup sequence easier to maintain is already a substantial change, and
 attempting to make those other changes at the same time will make the
 Note that this just covers settings that are currently configurable in some
 manner when using the main CPython executable. While this PEP aims to make
 adding additional configuration settings easier in the future, it
-deliberately avoids adding any new settings of its own.
+deliberately avoids adding any new settings of its own (except where such
+additional settings arise naturally in the course of migrating existing
+settings to the new structure).
 
 
 Design Details
   * ``Py_IsInitialized()`` returns ``0``
   * The embedding application determines and applies the settings
     required to complete the initialization process by calling
-    ``Py_ReadConfiguration`` and ``Py_EndInitialization``.
+    ``Py_ReadConfig`` and ``Py_EndInitialization``.
 
 * Initialized:
 
 over the initialization process::
 
     /* Phase 1: Pre-Initialization */
-    Py_CoreConfig core_config = Py_CoreConfig_INIT;
-    Py_Config config = Py_Config_INIT;
+    PyCoreConfig core_config = PyCoreConfig_INIT;
+    PyConfig config = PyConfig_INIT;
     /* Easily control the core configuration */
     core_config.ignore_environment = 1; /* Ignore environment variables */
     core_config.use_hash_seed = 0;      /* Full hash randomisation */
     /* Phase 2: Initialization */
     /* Optionally preconfigure some settings here - they will then be
      * used to derive other settings */
-    Py_ReadConfiguration(&config);
+    Py_ReadConfig(&config);
     /* Can completely override derived settings here */
     Py_EndInitialization(&config);
     /* Phase 3: Initialized */
     /* If an embedding application has no real concept of a main module
-     * it can leave the interpreter in this state indefinitely.
-     * Otherwise, it can launch __main__ via the Py_Run*AsMain functions.
+     * it can just stop the initialization process here.
+     * Alternatively, it can launch __main__ via the PyRun_*Main functions.
      */
 
 
 for the seed (a seed value of zero disables randomised hashing). In addition,
 due to the possible use of ``PYTHONHASHSEED`` in configuring the hash
 randomisation, the question of whether or not to consider environment
-variables must also be addressed early.
+variables must also be addressed early. Finally, to support the CPython
+build process, an option is offered to completely disable the import
+system.
 
 The proposed API for this step in the startup sequence is::
 
-    void Py_BeginInitialization(const Py_CoreConfig *config);
+    void Py_BeginInitialization(const PyCoreConfig *config);
 
 Like Py_Initialize, this part of the new API treats initialization failures
 as fatal errors. While that's still not particularly embedding friendly,
 to return error codes instead of aborting would be an even larger task than
 the one already being proposed.
 
-The new ``Py_CoreConfig`` struct holds the settings required for preliminary
+The new ``PyCoreConfig`` struct holds the settings required for preliminary
 configuration::
 
-    /* Note: if changing anything in Py_CoreConfig, also update
-     * Py_CoreConfig_INIT */
+    /* Note: if changing anything in PyCoreConfig, also update
+     * PyCoreConfig_INIT */
     typedef struct {
         int ignore_environment;   /* -E switch */
         int use_hash_seed;        /* PYTHONHASHSEED */
         unsigned long hash_seed;  /* PYTHONHASHSEED */
         int _disable_importlib;   /* Needed by freeze_importlib */
-    } Py_CoreConfig;
+    } PyCoreConfig;
 
-    #define Py_CoreConfig_INIT {0, -1, 0, 0}
+    #define PyCoreConfig_INIT {0, -1, 0, 0}
 
 The core configuration settings pointer may be ``NULL``, in which case the
 default values are ``ignore_environment = -1`` and ``use_hash_seed = -1``.
 
-The ``Py_CoreConfig_INIT`` macro is designed to allow easy initialization
+The ``PyCoreConfig_INIT`` macro is designed to allow easy initialization
 of a struct instance with sensible defaults::
 
-    Py_CoreConfig core_config = Py_CoreConfig_INIT;
+    PyCoreConfig core_config = PyCoreConfig_INIT;
 
 ``ignore_environment`` controls the processing of all Python related
 environment variables. If the flag is zero, then environment variables are
 settings needed to complete the process. No changes are made to the
 interpreter state at this point. The core API for this step is::
 
-    int Py_ReadConfiguration(PyConfig *config);
+    int Py_ReadConfig(PyConfig *config);
 
 The config argument should be a pointer to a config struct (which may be
 a temporary one stored on the C stack). For any already configured value
 Supported configuration settings
 --------------------------------
 
-The new ``Py_Config`` struct holds the settings required to complete the
+The new ``PyConfig`` struct holds the settings required to complete the
 interpreter configuration. All fields are either pointers to Python
 data types (not set == ``NULL``) or numeric flags (not set == ``-1``)::
 
-    /* Note: if changing anything in Py_Config, also update Py_Config_INIT */
+    /* Note: if changing anything in PyConfig, also update PyConfig_INIT */
     typedef struct {
         /* Argument processing */
         PyListObject *raw_argv;
         int show_banner;              /* -q switch (inverted) */
         int inspect_main;             /* -i switch, PYTHONINSPECT */
 
-    } Py_Config;
+    } PyConfig;
 
 
     /* Struct initialization is pretty ugly in C89. Avoiding this mess would
      * be the most attractive aspect of using a PyDictObject* instead... */
-    #define _Py_ArgConfig_INIT  NULL, NULL, NULL, NULL
-    #define _Py_LocationConfig_INIT  NULL, NULL, NULL, NULL, NULL, NULL
-    #define _Py_SiteConfig_INIT  -1, -1
-    #define _Py_ImportConfig_INIT  -1, -1, NULL
-    #define _Py_StreamConfig_INIT  -1, NULL, NULL, NULL, NULL, NULL, NULL
-    #define _Py_FilesystemConfig_INIT  NULL
-    #define _Py_DebuggingConfig_INIT  -1, -1, -1
-    #define _Py_CodeGenConfig_INIT  -1, -1
-    #define _Py_SignalConfig_INIT  -1
-    #define _Py_ImplicitConfig_INIT  NULL
-    #define _Py_MainConfig_INIT  -1, NULL, NULL, NULL, NULL, NULL, -1
-    #define _Py_InteractiveConfig_INIT  NULL, -1, -1
+    #define _PyArgConfig_INIT  NULL, NULL, NULL, NULL
+    #define _PyLocationConfig_INIT  NULL, NULL, NULL, NULL, NULL, NULL
+    #define _PySiteConfig_INIT  -1, -1
+    #define _PyImportConfig_INIT  -1, -1, NULL
+    #define _PyStreamConfig_INIT  -1, NULL, NULL, NULL, NULL, NULL, NULL
+    #define _PyFilesystemConfig_INIT  NULL
+    #define _PyDebuggingConfig_INIT  -1, -1, -1
+    #define _PyCodeGenConfig_INIT  -1, -1
+    #define _PySignalConfig_INIT  -1
+    #define _PyImplicitConfig_INIT  NULL
+    #define _PyMainConfig_INIT  -1, NULL, NULL, NULL, NULL, NULL, -1
+    #define _PyInteractiveConfig_INIT  NULL, -1, -1
 
-    #define Py_Config_INIT {_Py_ArgConfig_INIT, _Py_LocationConfig_INIT,
-                            _Py_SiteConfig_INIT, _Py_ImportConfig_INIT,
-                            _Py_StreamConfig_INIT, _Py_FilesystemConfig_INIT,
-                            _Py_DebuggingConfig_INIT, _Py_CodeGenConfig_INIT,
-                            _Py_SignalConfig_INIT, _Py_ImplicitConfig_INIT,
-                            _Py_MainConfig_INIT, _Py_InteractiveConfig_INIT}
+    #define PyConfig_INIT {_PyArgConfig_INIT, _PyLocationConfig_INIT,
+                           _PySiteConfig_INIT, _PyImportConfig_INIT,
+                           _PyStreamConfig_INIT, _PyFilesystemConfig_INIT,
+                           _PyDebuggingConfig_INIT, _PyCodeGenConfig_INIT,
+                           _PySignalConfig_INIT, _PyImplicitConfig_INIT,
+                           _PyMainConfig_INIT, _PyInteractiveConfig_INIT}
 
 <TBD: did I miss anything?>
 
 configuration settings into effect and finish bootstrapping the interpreter
 up to full operation::
 
-    int Py_EndInitialization(const Py_Config *config);
+    int Py_EndInitialization(const PyConfig *config);
 
 Like Py_ReadConfiguration, this call will raise an exception and report an
 error return rather than exhibiting fatal errors if a problem is found with
 the config data.
 
 All configuration settings are required - the configuration struct
-should always be passed through ``Py_ReadConfiguration()`` to ensure it
+should always be passed through ``Py_ReadConfig()`` to ensure it
 is fully populated.
 
 After a successful call, ``Py_IsInitializing()`` will be false, while
 
 The interpreter state will be updated to include details of the configuration
 settings supplied during initialization by extending the interpreter state
-object with an embedded copy of the ``Py_CoreConfig`` and ``Py_Config``
+object with an embedded copy of the ``PyCoreConfig`` and ``PyConfig``
 structs.
 
 For debugging purposes, the configuration settings will be exposed as
 -----------------------
 
 Backwards compatibility will be preserved primarily by ensuring that
-``Py_ReadConfiguration()`` interrogates all the previously defined
+``Py_ReadConfig()`` interrogates all the previously defined
 configuration settings stored in global variables and environment variables,
 and that ``Py_EndInitialization()`` writes affected settings back to the
 relevant locations.
 * Should there be ``Py_PreparingMain()`` and ``Py_RunningMain()`` query APIs?
 * Should the answer to ``Py_IsInitialized()`` be exposed via the ``sys``
   module?
-* Is initialisation of the ``Py_Config`` struct too unwieldy to be
+* Is initialisation of the ``PyConfig`` struct too unwieldy to be
   maintainable? Would a Python dictionary be a better choice, despite
   being harder to work with from C code?
-* Would it be better to manage the flag variables in ``Py_Config`` as
+* Would it be better to manage the flag variables in ``PyConfig`` as
   Python integers or as "negative means false, positive means true, zero
   means not set" so the struct can be initialized with a simple
   ``memset(&config, 0, sizeof(*config))``, eliminating the need to update
-  both Py_Config and Py_Config_INIT when adding new fields?
+  both PyConfig and PyConfig_INIT when adding new fields?
 * The name of the new system Python executable is a bikeshed waiting to be
   painted. The 3 options considered so far are ``spython``, ``pysystem``
   and ``python-minimal``. The PEP text reflects my current preferred choice
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.