Skip to content

Commit 54b43bb

Browse files
authored
bpo-36763: Add _PyCoreConfig.configure_c_stdio (GH-13363)
Add tests for configure_c_stdio and pathconfig_warnings parameters.
1 parent 9ef5dca commit 54b43bb

File tree

4 files changed

+37
-3
lines changed

4 files changed

+37
-3
lines changed

Include/cpython/coreconfig.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,14 @@ typedef struct {
312312
!Py_NoUserSiteDirectory. */
313313
int user_site_directory;
314314

315+
/* If non-zero, configure C standard steams (stdio, stdout,
316+
stderr):
317+
318+
- Set O_BINARY mode on Windows.
319+
- If buffered_stdio is equal to zero, make streams unbuffered.
320+
Otherwise, enable streams buffering if interactive is non-zero. */
321+
int configure_c_stdio;
322+
315323
/* If equal to 0, enable unbuffered mode: force the stdout and stderr
316324
streams to be unbuffered.
317325
@@ -439,6 +447,7 @@ typedef struct {
439447
.verbose = -1, \
440448
.quiet = -1, \
441449
.user_site_directory = -1, \
450+
.configure_c_stdio = 1, \
442451
.buffered_stdio = -1, \
443452
._install_importlib = 1, \
444453
.check_hash_pycs_mode = NULL, \

Lib/test/test_embed.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
331331
'verbose': 0,
332332
'quiet': 0,
333333
'user_site_directory': 1,
334+
'configure_c_stdio': 1,
334335
'buffered_stdio': 1,
335336

336337
'stdio_encoding': GET_DEFAULT_CONFIG,
@@ -558,6 +559,7 @@ def test_init_global_config(self):
558559
'filesystem_encoding': 'utf-8',
559560
'filesystem_errors': self.UTF8_MODE_ERRORS,
560561
'user_site_directory': 0,
562+
'pathconfig_warnings': 0,
561563
}
562564
self.check_config("init_global_config", config, preconfig)
563565

@@ -597,11 +599,13 @@ def test_init_from_config(self):
597599
'write_bytecode': 0,
598600
'verbose': 1,
599601
'quiet': 1,
602+
'configure_c_stdio': 0,
600603
'buffered_stdio': 0,
601604
'user_site_directory': 0,
602605
'faulthandler': 1,
603606

604607
'check_hash_pycs_mode': 'always',
608+
'pathconfig_warnings': 0,
605609
}
606610
self.check_config("init_from_config", config, preconfig)
607611

Programs/_testembed.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,8 @@ static int test_init_global_config(void)
360360
putenv("PYTHONUNBUFFERED=");
361361
Py_UnbufferedStdioFlag = 1;
362362

363+
Py_FrozenFlag = 1;
364+
363365
/* FIXME: test Py_LegacyWindowsFSEncodingFlag */
364366
/* FIXME: test Py_LegacyWindowsStdioFlag */
365367

@@ -481,6 +483,8 @@ static int test_init_from_config(void)
481483
Py_QuietFlag = 0;
482484
config.quiet = 1;
483485

486+
config.configure_c_stdio = 0;
487+
484488
putenv("PYTHONUNBUFFERED=");
485489
Py_UnbufferedStdioFlag = 0;
486490
config.buffered_stdio = 0;
@@ -501,6 +505,9 @@ static int test_init_from_config(void)
501505

502506
config.check_hash_pycs_mode = L"always";
503507

508+
Py_FrozenFlag = 0;
509+
config.pathconfig_warnings = 0;
510+
504511
err = _Py_InitializeFromConfig(&config);
505512
if (_Py_INIT_FAILED(err)) {
506513
_Py_ExitInitError(err);

Python/coreconfig.c

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -654,6 +654,7 @@ _PyCoreConfig_Copy(_PyCoreConfig *config, const _PyCoreConfig *config2)
654654
COPY_ATTR(verbose);
655655
COPY_ATTR(quiet);
656656
COPY_ATTR(user_site_directory);
657+
COPY_ATTR(configure_c_stdio);
657658
COPY_ATTR(buffered_stdio);
658659
COPY_WSTR_ATTR(filesystem_encoding);
659660
COPY_WSTR_ATTR(filesystem_errors);
@@ -755,6 +756,7 @@ _PyCoreConfig_AsDict(const _PyCoreConfig *config)
755756
SET_ITEM_INT(verbose);
756757
SET_ITEM_INT(quiet);
757758
SET_ITEM_INT(user_site_directory);
759+
SET_ITEM_INT(configure_c_stdio);
758760
SET_ITEM_INT(buffered_stdio);
759761
SET_ITEM_WSTR(stdio_encoding);
760762
SET_ITEM_WSTR(stdio_errors);
@@ -1582,7 +1584,6 @@ config_read(_PyCoreConfig *config, _PyPreCmdline *cmdline)
15821584
return _Py_INIT_NO_MEMORY();
15831585
}
15841586
}
1585-
15861587
return _Py_INIT_OK();
15871588
}
15881589

@@ -1632,7 +1633,10 @@ void
16321633
_PyCoreConfig_Write(const _PyCoreConfig *config, _PyRuntimeState *runtime)
16331634
{
16341635
_PyCoreConfig_SetGlobalConfig(config);
1635-
config_init_stdio(config);
1636+
1637+
if (config->configure_c_stdio) {
1638+
config_init_stdio(config);
1639+
}
16361640

16371641
/* Write the new pre-configuration into _PyRuntime */
16381642
_PyPreConfig *preconfig = &runtime->preconfig;
@@ -2067,6 +2071,9 @@ config_read_cmdline(_PyCoreConfig *config, _PyPreCmdline *precmdline)
20672071
if (config->parse_argv < 0) {
20682072
config->parse_argv = 1;
20692073
}
2074+
if (config->configure_c_stdio < 0) {
2075+
config->configure_c_stdio = 1;
2076+
}
20702077

20712078
if (config->parse_argv) {
20722079
int opt_index;
@@ -2171,7 +2178,9 @@ _PyCoreConfig_SetWideArgv(_PyCoreConfig *config, int argc, wchar_t **argv)
21712178
21722179
* Command line arguments
21732180
* Environment variables
2174-
* Py_xxx global configuration variables */
2181+
* Py_xxx global configuration variables
2182+
2183+
The only side effects are to modify config and to call _Py_SetArgcArgv(). */
21752184
_PyInitError
21762185
_PyCoreConfig_Read(_PyCoreConfig *config)
21772186
{
@@ -2227,14 +2236,19 @@ _PyCoreConfig_Read(_PyCoreConfig *config)
22272236
assert(config->quiet >= 0);
22282237
assert(config->user_site_directory >= 0);
22292238
assert(config->parse_argv >= 0);
2239+
assert(config->configure_c_stdio >= 0);
22302240
assert(config->buffered_stdio >= 0);
22312241
assert(config->program_name != NULL);
22322242
assert(config->program != NULL);
22332243
assert(_PyWstrList_CheckConsistency(&config->argv));
2244+
/* sys.argv must be non-empty: empty argv is replaced with [''] */
2245+
assert(config->argv.length >= 1);
22342246
assert(_PyWstrList_CheckConsistency(&config->xoptions));
22352247
assert(_PyWstrList_CheckConsistency(&config->warnoptions));
22362248
assert(_PyWstrList_CheckConsistency(&config->module_search_paths));
22372249
if (config->_install_importlib) {
2250+
assert(config->use_module_search_paths != 0);
2251+
/* don't check config->module_search_paths */
22382252
assert(config->executable != NULL);
22392253
assert(config->prefix != NULL);
22402254
assert(config->base_prefix != NULL);

0 commit comments

Comments
 (0)