Skip to content

bpo-38304: Add PyConfig.struct_size #16451

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 28, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 39 additions & 5 deletions Doc/c-api/init_config.rst
Original file line number Diff line number Diff line change
Expand Up @@ -194,18 +194,25 @@ PyPreConfig
* Configure the LC_CTYPE locale
* Set the UTF-8 mode

The :c:member:`struct_size` field must be explicitly initialized to
``sizeof(PyPreConfig)``.

Function to initialize a preconfiguration:

.. c:function:: void PyPreConfig_InitIsolatedConfig(PyPreConfig *preconfig)
.. c:function:: PyStatus PyPreConfig_InitIsolatedConfig(PyPreConfig *preconfig)

Initialize the preconfiguration with :ref:`Python Configuration
<init-python-config>`.

.. c:function:: void PyPreConfig_InitPythonConfig(PyPreConfig *preconfig)
.. c:function:: PyStatus PyPreConfig_InitPythonConfig(PyPreConfig *preconfig)

Initialize the preconfiguration with :ref:`Isolated Configuration
<init-isolated-conf>`.

The caller of these functions is responsible to handle exceptions (error or
exit) using :c:func:`PyStatus_Exception` and
:c:func:`Py_ExitStatusException`.

Structure fields:

.. c:member:: int allocator
Expand Down Expand Up @@ -267,6 +274,13 @@ PyPreConfig
same way the regular Python parses command line arguments: see
:ref:`Command Line Arguments <using-on-cmdline>`.

.. c:member:: size_t struct_size

Size of the structure in bytes: must be initialized to
``sizeof(PyPreConfig)``.

Field used for API and ABI compatibility.

.. c:member:: int use_environment

See :c:member:`PyConfig.use_environment`.
Expand Down Expand Up @@ -316,12 +330,18 @@ the preinitialization.

Example using the preinitialization to enable the UTF-8 Mode::

PyStatus status;
PyPreConfig preconfig;
PyPreConfig_InitPythonConfig(&preconfig);
preconfig.struct_size = sizeof(PyPreConfig);

status = PyPreConfig_InitPythonConfig(&preconfig);
if (PyStatus_Exception(status)) {
Py_ExitStatusException(status);
}

preconfig.utf8_mode = 1;

PyStatus status = Py_PreInitialize(&preconfig);
status = Py_PreInitialize(&preconfig);
if (PyStatus_Exception(status)) {
Py_ExitStatusException(status);
}
Expand All @@ -340,6 +360,9 @@ PyConfig

Structure containing most parameters to configure Python.

The :c:member:`struct_size` field must be explicitly initialized to
``sizeof(PyConfig)``.

Structure methods:

.. c:function:: PyStatus PyConfig_InitPythonConfig(PyConfig *config)
Expand Down Expand Up @@ -656,6 +679,13 @@ PyConfig
Encoding and encoding errors of :data:`sys.stdin`, :data:`sys.stdout` and
:data:`sys.stderr`.

.. c:member:: size_t struct_size

Size of the structure in bytes: must be initialized to
``sizeof(PyConfig)``.

Field used for API and ABI compatibility.

.. c:member:: int tracemalloc

If non-zero, call :func:`tracemalloc.start` at startup.
Expand Down Expand Up @@ -718,6 +748,7 @@ Example setting the program name::
{
PyStatus status;
PyConfig config;
config.struct_size = sizeof(PyConfig);

status = PyConfig_InitPythonConfig(&config);
if (PyStatus_Exception(status)) {
Expand Down Expand Up @@ -750,6 +781,7 @@ configuration, and then override some parameters::
{
PyStatus status;
PyConfig config;
config.struct_size = sizeof(PyConfig);

status = PyConfig_InitPythonConfig(&config);
if (PyStatus_Exception(status)) {
Expand Down Expand Up @@ -835,8 +867,9 @@ Example of customized Python always running in isolated mode::

int main(int argc, char **argv)
{
PyConfig config;
PyStatus status;
PyConfig config;
config.struct_size = sizeof(PyConfig);

status = PyConfig_InitPythonConfig(&config);
if (PyStatus_Exception(status)) {
Expand Down Expand Up @@ -1028,6 +1061,7 @@ phases::
{
PyStatus status;
PyConfig config;
config.struct_size = sizeof(PyConfig);

status = PyConfig_InitPythonConfig(&config);
if (PyStatus_Exception(status)) {
Expand Down
17 changes: 10 additions & 7 deletions Include/cpython/initconfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,10 @@ PyAPI_FUNC(PyStatus) PyWideStringList_Insert(PyWideStringList *list,
/* --- PyPreConfig ----------------------------------------------- */

typedef struct {
int _config_version; /* Internal configuration version,
used for ABI compatibility */
/* Size of the structure in bytes: must be initialized to
sizeof(PyPreConfig). Field used for API and ABI compatibility. */
size_t struct_size;

int _config_init; /* _PyConfigInitEnum value */

/* Parse Py_PreInitializeFromBytesArgs() arguments?
Expand Down Expand Up @@ -122,15 +124,17 @@ typedef struct {
int allocator;
} PyPreConfig;

PyAPI_FUNC(void) PyPreConfig_InitPythonConfig(PyPreConfig *config);
PyAPI_FUNC(void) PyPreConfig_InitIsolatedConfig(PyPreConfig *config);
PyAPI_FUNC(PyStatus) PyPreConfig_InitPythonConfig(PyPreConfig *config);
PyAPI_FUNC(PyStatus) PyPreConfig_InitIsolatedConfig(PyPreConfig *config);


/* --- PyConfig ---------------------------------------------- */

typedef struct {
int _config_version; /* Internal configuration version,
used for ABI compatibility */
/* Size of the structure in bytes: must be initialized to
sizeof(PyConfig). Field used for API and ABI compatibility. */
size_t struct_size;

int _config_init; /* _PyConfigInitEnum value */

int isolated; /* Isolated mode? see PyPreConfig.isolated */
Expand Down Expand Up @@ -403,7 +407,6 @@ typedef struct {

/* If equal to 0, stop Python initialization before the "main" phase */
int _init_main;

} PyConfig;

PyAPI_FUNC(PyStatus) PyConfig_InitPythonConfig(PyConfig *config);
Expand Down
12 changes: 6 additions & 6 deletions Include/internal/pycore_initconfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ extern "C" {
(err._type == _PyStatus_TYPE_EXIT)
#define _PyStatus_EXCEPTION(err) \
(err._type != _PyStatus_TYPE_OK)
#define _PyStatus_UPDATE_FUNC(err) \
do { err.func = _PyStatus_GET_FUNC(); } while (0)

/* --- PyWideStringList ------------------------------------------------ */

Expand Down Expand Up @@ -118,11 +120,11 @@ extern PyStatus _PyPreCmdline_Read(_PyPreCmdline *cmdline,

/* --- PyPreConfig ----------------------------------------------- */

PyAPI_FUNC(void) _PyPreConfig_InitCompatConfig(PyPreConfig *preconfig);
extern void _PyPreConfig_InitFromConfig(
PyAPI_FUNC(PyStatus) _PyPreConfig_InitCompatConfig(PyPreConfig *preconfig);
extern PyStatus _PyPreConfig_InitFromConfig(
PyPreConfig *preconfig,
const PyConfig *config);
extern void _PyPreConfig_InitFromPreConfig(
extern PyStatus _PyPreConfig_InitFromPreConfig(
PyPreConfig *preconfig,
const PyPreConfig *config2);
extern PyObject* _PyPreConfig_AsDict(const PyPreConfig *preconfig);
Expand All @@ -135,16 +137,14 @@ extern PyStatus _PyPreConfig_Write(const PyPreConfig *preconfig);

/* --- PyConfig ---------------------------------------------- */

#define _Py_CONFIG_VERSION 1

typedef enum {
/* Py_Initialize() API: backward compatibility with Python 3.6 and 3.7 */
_PyConfig_INIT_COMPAT = 1,
_PyConfig_INIT_PYTHON = 2,
_PyConfig_INIT_ISOLATED = 3
} _PyConfigInitEnum;

PyAPI_FUNC(void) _PyConfig_InitCompatConfig(PyConfig *config);
PyAPI_FUNC(PyStatus) _PyConfig_InitCompatConfig(PyConfig *config);
extern PyStatus _PyConfig_Copy(
PyConfig *config,
const PyConfig *config2);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Add a new ``struct_size`` field to :c:type:`PyPreConfig` and :c:type:`PyConfig`
structures to allow to modify these structures in the future without breaking
the backward compatibility.
9 changes: 8 additions & 1 deletion Modules/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,20 @@ pymain_init(const _PyArgv *args)
#endif

PyPreConfig preconfig;
PyPreConfig_InitPythonConfig(&preconfig);
preconfig.struct_size = sizeof(PyPreConfig);

status = PyPreConfig_InitPythonConfig(&preconfig);
if (_PyStatus_EXCEPTION(status)) {
return status;
}

status = _Py_PreInitializeFromPyArgv(&preconfig, args);
if (_PyStatus_EXCEPTION(status)) {
return status;
}

PyConfig config;
config.struct_size = sizeof(PyConfig);
status = PyConfig_InitPythonConfig(&config);
if (_PyStatus_EXCEPTION(status)) {
goto done;
Expand Down
1 change: 1 addition & 0 deletions Programs/_freeze_importlib.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ main(int argc, char *argv[])

PyStatus status;
PyConfig config;
config.struct_size = sizeof(PyConfig);

status = PyConfig_InitIsolatedConfig(&config);
if (PyStatus_Exception(status)) {
Expand Down
Loading