mirror of https://github.com/python/cpython
bpo-44131: Py_FrozenMain() uses PyConfig_SetBytesArgv() (GH-26201)
Moreover, Py_FrozenMain() relies on Py_InitializeFromConfig() to handle the PYTHONUNBUFFERED environment variable and configure C stdio streams like stdout (make the stream unbuffered).
This commit is contained in:
parent
4d396e7d79
commit
58a993957a
|
@ -1484,14 +1484,18 @@ class MiscTests(EmbeddingTestsMixin, unittest.TestCase):
|
||||||
@unittest.skipIf(os.name == 'nt',
|
@unittest.skipIf(os.name == 'nt',
|
||||||
'Py_FrozenMain is not exported on Windows')
|
'Py_FrozenMain is not exported on Windows')
|
||||||
def test_frozenmain(self):
|
def test_frozenmain(self):
|
||||||
out, err = self.run_embedded_interpreter("test_frozenmain")
|
env = dict(os.environ)
|
||||||
exe = os.path.realpath('./argv0')
|
env['PYTHONUNBUFFERED'] = '1'
|
||||||
|
out, err = self.run_embedded_interpreter("test_frozenmain", env=env)
|
||||||
|
executable = os.path.realpath('./argv0')
|
||||||
expected = textwrap.dedent(f"""
|
expected = textwrap.dedent(f"""
|
||||||
Frozen Hello World
|
Frozen Hello World
|
||||||
sys.argv ['./argv0', '-E', 'arg1', 'arg2']
|
sys.argv ['./argv0', '-E', 'arg1', 'arg2']
|
||||||
config program_name: ./argv0
|
config program_name: ./argv0
|
||||||
config executable: {exe}
|
config executable: {executable}
|
||||||
config use_environment: 1
|
config use_environment: 1
|
||||||
|
config configure_c_stdio: 1
|
||||||
|
config buffered_stdio: 0
|
||||||
""").lstrip()
|
""").lstrip()
|
||||||
self.assertEqual(out, expected)
|
self.assertEqual(out, expected)
|
||||||
|
|
||||||
|
|
|
@ -1,30 +1,28 @@
|
||||||
// Auto-generated by Programs/freeze_test_frozenmain.py
|
// Auto-generated by Programs/freeze_test_frozenmain.py
|
||||||
unsigned char M_test_frozenmain[] = {
|
unsigned char M_test_frozenmain[] = {
|
||||||
227,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
227,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
0,4,0,0,0,64,0,0,0,115,106,0,0,0,100,0,
|
0,7,0,0,0,64,0,0,0,115,86,0,0,0,100,0,
|
||||||
100,1,108,0,90,0,100,0,100,1,108,1,90,1,101,2,
|
100,1,108,0,90,0,100,0,100,1,108,1,90,1,101,2,
|
||||||
100,2,131,1,1,0,101,2,100,3,101,0,106,3,131,2,
|
100,2,131,1,1,0,101,2,100,3,101,0,106,3,131,2,
|
||||||
1,0,101,1,160,4,161,0,100,4,25,0,90,5,101,2,
|
1,0,101,1,160,4,161,0,100,4,25,0,90,5,100,5,
|
||||||
100,5,101,5,100,6,25,0,155,0,157,2,131,1,1,0,
|
68,0,93,14,90,6,101,2,100,6,101,6,155,0,100,7,
|
||||||
101,2,100,7,101,5,100,8,25,0,155,0,157,2,131,1,
|
101,5,101,6,25,0,155,0,157,4,131,1,1,0,113,26,
|
||||||
1,0,101,2,100,9,101,5,100,10,25,0,155,0,157,2,
|
100,1,83,0,41,8,233,0,0,0,0,78,122,18,70,114,
|
||||||
131,1,1,0,100,1,83,0,41,11,233,0,0,0,0,78,
|
111,122,101,110,32,72,101,108,108,111,32,87,111,114,108,100,
|
||||||
122,18,70,114,111,122,101,110,32,72,101,108,108,111,32,87,
|
122,8,115,121,115,46,97,114,103,118,218,6,99,111,110,102,
|
||||||
111,114,108,100,122,8,115,121,115,46,97,114,103,118,218,6,
|
105,103,41,5,90,12,112,114,111,103,114,97,109,95,110,97,
|
||||||
99,111,110,102,105,103,122,21,99,111,110,102,105,103,32,112,
|
109,101,218,10,101,120,101,99,117,116,97,98,108,101,90,15,
|
||||||
114,111,103,114,97,109,95,110,97,109,101,58,32,90,12,112,
|
117,115,101,95,101,110,118,105,114,111,110,109,101,110,116,90,
|
||||||
114,111,103,114,97,109,95,110,97,109,101,122,19,99,111,110,
|
17,99,111,110,102,105,103,117,114,101,95,99,95,115,116,100,
|
||||||
102,105,103,32,101,120,101,99,117,116,97,98,108,101,58,32,
|
105,111,90,14,98,117,102,102,101,114,101,100,95,115,116,100,
|
||||||
218,10,101,120,101,99,117,116,97,98,108,101,122,24,99,111,
|
105,111,122,7,99,111,110,102,105,103,32,122,2,58,32,41,
|
||||||
110,102,105,103,32,117,115,101,95,101,110,118,105,114,111,110,
|
7,218,3,115,121,115,90,17,95,116,101,115,116,105,110,116,
|
||||||
109,101,110,116,58,32,90,15,117,115,101,95,101,110,118,105,
|
101,114,110,97,108,99,97,112,105,218,5,112,114,105,110,116,
|
||||||
114,111,110,109,101,110,116,41,6,218,3,115,121,115,90,17,
|
218,4,97,114,103,118,90,11,103,101,116,95,99,111,110,102,
|
||||||
95,116,101,115,116,105,110,116,101,114,110,97,108,99,97,112,
|
105,103,115,114,2,0,0,0,218,3,107,101,121,169,0,114,
|
||||||
105,218,5,112,114,105,110,116,218,4,97,114,103,118,90,11,
|
8,0,0,0,114,8,0,0,0,250,18,116,101,115,116,95,
|
||||||
103,101,116,95,99,111,110,102,105,103,115,114,2,0,0,0,
|
102,114,111,122,101,110,109,97,105,110,46,112,121,218,8,60,
|
||||||
169,0,114,7,0,0,0,114,7,0,0,0,250,18,116,101,
|
109,111,100,117,108,101,62,1,0,0,0,115,16,0,0,0,
|
||||||
115,116,95,102,114,111,122,101,110,109,97,105,110,46,112,121,
|
8,3,8,1,8,2,12,1,12,1,8,1,26,7,4,249,
|
||||||
218,8,60,109,111,100,117,108,101,62,1,0,0,0,115,16,
|
243,0,0,0,0,
|
||||||
0,0,0,8,3,8,1,8,2,12,1,12,1,18,1,18,
|
|
||||||
1,22,1,243,0,0,0,0,
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -7,6 +7,11 @@ import _testinternalcapi
|
||||||
print("Frozen Hello World")
|
print("Frozen Hello World")
|
||||||
print("sys.argv", sys.argv)
|
print("sys.argv", sys.argv)
|
||||||
config = _testinternalcapi.get_configs()['config']
|
config = _testinternalcapi.get_configs()['config']
|
||||||
print(f"config program_name: {config['program_name']}")
|
for key in (
|
||||||
print(f"config executable: {config['executable']}")
|
'program_name',
|
||||||
print(f"config use_environment: {config['use_environment']}")
|
'executable',
|
||||||
|
'use_environment',
|
||||||
|
'configure_c_stdio',
|
||||||
|
'buffered_stdio',
|
||||||
|
):
|
||||||
|
print(f"config {key}: {config[key]}")
|
||||||
|
|
|
@ -20,74 +20,28 @@ Py_FrozenMain(int argc, char **argv)
|
||||||
Py_ExitStatusException(status);
|
Py_ExitStatusException(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *p;
|
|
||||||
int i, n, sts = 1;
|
|
||||||
int inspect = 0;
|
|
||||||
int unbuffered = 0;
|
|
||||||
char *oldloc = NULL;
|
|
||||||
wchar_t **argv_copy = NULL;
|
|
||||||
/* We need a second copies, as Python might modify the first one. */
|
|
||||||
wchar_t **argv_copy2 = NULL;
|
|
||||||
|
|
||||||
if (argc > 0) {
|
|
||||||
argv_copy = PyMem_RawMalloc(sizeof(wchar_t*) * argc);
|
|
||||||
argv_copy2 = PyMem_RawMalloc(sizeof(wchar_t*) * argc);
|
|
||||||
if (!argv_copy || !argv_copy2) {
|
|
||||||
fprintf(stderr, "out of memory\n");
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PyConfig config;
|
PyConfig config;
|
||||||
PyConfig_InitPythonConfig(&config);
|
PyConfig_InitPythonConfig(&config);
|
||||||
config.pathconfig_warnings = 0; /* Suppress errors from getpath.c */
|
// Suppress errors from getpath.c
|
||||||
|
config.pathconfig_warnings = 0;
|
||||||
|
// Don't parse command line options like -E
|
||||||
|
config.parse_argv = 0;
|
||||||
|
|
||||||
|
status = PyConfig_SetBytesArgv(&config, argc, argv);
|
||||||
|
if (PyStatus_Exception(status)) {
|
||||||
|
PyConfig_Clear(&config);
|
||||||
|
Py_ExitStatusException(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *p;
|
||||||
|
int inspect = 0;
|
||||||
if ((p = Py_GETENV("PYTHONINSPECT")) && *p != '\0') {
|
if ((p = Py_GETENV("PYTHONINSPECT")) && *p != '\0') {
|
||||||
inspect = 1;
|
inspect = 1;
|
||||||
}
|
}
|
||||||
if ((p = Py_GETENV("PYTHONUNBUFFERED")) && *p != '\0') {
|
|
||||||
unbuffered = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (unbuffered) {
|
|
||||||
setbuf(stdin, (char *)NULL);
|
|
||||||
setbuf(stdout, (char *)NULL);
|
|
||||||
setbuf(stderr, (char *)NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
oldloc = _PyMem_RawStrdup(setlocale(LC_ALL, NULL));
|
|
||||||
if (!oldloc) {
|
|
||||||
fprintf(stderr, "out of memory\n");
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
setlocale(LC_ALL, "");
|
|
||||||
for (i = 0; i < argc; i++) {
|
|
||||||
argv_copy[i] = Py_DecodeLocale(argv[i], NULL);
|
|
||||||
argv_copy2[i] = argv_copy[i];
|
|
||||||
if (!argv_copy[i]) {
|
|
||||||
fprintf(stderr,
|
|
||||||
"Unable to decode the command line argument #%i\n",
|
|
||||||
i + 1);
|
|
||||||
argc = i;
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setlocale(LC_ALL, oldloc);
|
|
||||||
PyMem_RawFree(oldloc);
|
|
||||||
oldloc = NULL;
|
|
||||||
|
|
||||||
#ifdef MS_WINDOWS
|
#ifdef MS_WINDOWS
|
||||||
PyInitFrozenExtensions();
|
PyInitFrozenExtensions();
|
||||||
#endif /* MS_WINDOWS */
|
#endif /* MS_WINDOWS */
|
||||||
if (argc >= 1) {
|
|
||||||
status = PyConfig_SetString(&config, &config.program_name,
|
|
||||||
argv_copy[0]);
|
|
||||||
if (PyStatus_Exception(status)) {
|
|
||||||
PyConfig_Clear(&config);
|
|
||||||
Py_ExitStatusException(status);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
status = Py_InitializeFromConfig(&config);
|
status = Py_InitializeFromConfig(&config);
|
||||||
PyConfig_Clear(&config);
|
PyConfig_Clear(&config);
|
||||||
|
@ -104,9 +58,8 @@ Py_FrozenMain(int argc, char **argv)
|
||||||
Py_GetVersion(), Py_GetCopyright());
|
Py_GetVersion(), Py_GetCopyright());
|
||||||
}
|
}
|
||||||
|
|
||||||
PySys_SetArgv(argc, argv_copy);
|
int sts = 1;
|
||||||
|
int n = PyImport_ImportFrozenModule("__main__");
|
||||||
n = PyImport_ImportFrozenModule("__main__");
|
|
||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
Py_FatalError("the __main__ module is not frozen");
|
Py_FatalError("the __main__ module is not frozen");
|
||||||
}
|
}
|
||||||
|
@ -128,14 +81,5 @@ Py_FrozenMain(int argc, char **argv)
|
||||||
if (Py_FinalizeEx() < 0) {
|
if (Py_FinalizeEx() < 0) {
|
||||||
sts = 120;
|
sts = 120;
|
||||||
}
|
}
|
||||||
|
|
||||||
error:
|
|
||||||
PyMem_RawFree(argv_copy);
|
|
||||||
if (argv_copy2) {
|
|
||||||
for (i = 0; i < argc; i++)
|
|
||||||
PyMem_RawFree(argv_copy2[i]);
|
|
||||||
PyMem_RawFree(argv_copy2);
|
|
||||||
}
|
|
||||||
PyMem_RawFree(oldloc);
|
|
||||||
return sts;
|
return sts;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue