Skip to content

Commit

Permalink
bpo-22257: Private C-API for core runtime initialization (PEP 432). (p…
Browse files Browse the repository at this point in the history
…ython#1772)

(patch by Nick Coghlan)
  • Loading branch information
ericsnowcurrently authored May 24, 2017
1 parent c842efc commit 1abcf67
Show file tree
Hide file tree
Showing 5 changed files with 224 additions and 62 deletions.
10 changes: 9 additions & 1 deletion Include/pylifecycle.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,14 @@ PyAPI_FUNC(wchar_t *) Py_GetPythonHome(void);
*/
PyAPI_FUNC(int) Py_SetStandardStreamEncoding(const char *encoding,
const char *errors);

/* PEP 432 Multi-phase initialization API (Private while provisional!) */
PyAPI_FUNC(void) _Py_InitializeCore(const _PyCoreConfig *);
PyAPI_FUNC(int) _Py_IsCoreInitialized(void);
PyAPI_FUNC(int) _Py_InitializeMainInterpreter(int install_sigs);
#endif

/* Initialization and finalization */
PyAPI_FUNC(void) Py_Initialize(void);
PyAPI_FUNC(void) Py_InitializeEx(int);
#ifndef Py_LIMITED_API
Expand All @@ -29,6 +35,8 @@ PyAPI_FUNC(void) _Py_InitializeEx_Private(int, int);
PyAPI_FUNC(void) Py_Finalize(void);
PyAPI_FUNC(int) Py_FinalizeEx(void);
PyAPI_FUNC(int) Py_IsInitialized(void);

/* Subinterpreter support */
PyAPI_FUNC(PyThreadState *) Py_NewInterpreter(void);
PyAPI_FUNC(void) Py_EndInterpreter(PyThreadState *);

Expand Down Expand Up @@ -85,7 +93,7 @@ PyAPI_FUNC(void) _PyImportHooks_Init(void);
PyAPI_FUNC(int) _PyFrame_Init(void);
PyAPI_FUNC(int) _PyFloat_Init(void);
PyAPI_FUNC(int) PyByteArray_Init(void);
PyAPI_FUNC(void) _Py_HashRandomization_Init(void);
PyAPI_FUNC(void) _Py_HashRandomization_Init(_PyCoreConfig *core_config);
#endif

/* Various internal finalizers */
Expand Down
11 changes: 11 additions & 0 deletions Include/pystate.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,16 @@ typedef struct _is PyInterpreterState;
#else
typedef PyObject* (*_PyFrameEvalFunction)(struct _frame *, int);


typedef struct {
int ignore_environment;
int use_hash_seed;
unsigned long hash_seed;
int _disable_importlib; /* Needed by freeze_importlib */
} _PyCoreConfig;

#define _PyCoreConfig_INIT {0, -1, 0, 0}

typedef struct _is {

struct _is *next;
Expand All @@ -42,6 +52,7 @@ typedef struct _is {
int codecs_initialized;
int fscodec_initialized;

_PyCoreConfig core_config;
#ifdef HAVE_DLOPEN
int dlopenflags;
#endif
Expand Down
35 changes: 19 additions & 16 deletions Modules/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -380,19 +380,6 @@ read_command_line(int argc, wchar_t **argv, _Py_CommandLineDetails *cmdline)
wchar_t *command = NULL;
wchar_t *module = NULL;
int c;
char *opt;

opt = Py_GETENV("PYTHONMALLOC");
if (_PyMem_SetupAllocators(opt) < 0) {
fprintf(stderr,
"Error in PYTHONMALLOC: unknown allocator \"%s\"!\n", opt);
exit(1);
}

// TODO: Move these to core runtime init.
Py_HashRandomizationFlag = 1;
_Py_HashRandomization_Init();
PySys_ResetWarnOptions();

_PyOS_ResetGetOpt();

Expand Down Expand Up @@ -584,6 +571,7 @@ Py_Main(int argc, wchar_t **argv)
#endif
int stdin_is_interactive = 0;
_Py_CommandLineDetails cmdline = _Py_CommandLineDetails_INIT;
_PyCoreConfig core_config = _PyCoreConfig_INIT;
PyCompilerFlags cf;
PyObject *main_importer_path = NULL;

Expand All @@ -602,11 +590,23 @@ Py_Main(int argc, wchar_t **argv)
break;
}
if (c == 'E' || c == 'I') {
Py_IgnoreEnvironmentFlag++;
core_config.ignore_environment++;
break;
}
}

char *pymalloc = Py_GETENV("PYTHONMALLOC");
if (_PyMem_SetupAllocators(pymalloc) < 0) {
fprintf(stderr,
"Error in PYTHONMALLOC: unknown allocator \"%s\"!\n", pymalloc);
exit(1);
}

/* Initialize the core language runtime */
Py_IgnoreEnvironmentFlag = core_config.ignore_environment;
core_config._disable_importlib = 0;
_Py_InitializeCore(&core_config);

/* Reprocess the command line with the language runtime available */
if (read_command_line(argc, argv, &cmdline)) {
return usage(2, argv[0]);
Expand Down Expand Up @@ -680,6 +680,7 @@ Py_Main(int argc, wchar_t **argv)
for (i = 0; i < PyList_GET_SIZE(cmdline.warning_options); i++) {
PySys_AddWarnOptionUnicode(PyList_GET_ITEM(cmdline.warning_options, i));
}
Py_DECREF(cmdline.warning_options);
}

stdin_is_interactive = Py_FdIsInteractive(stdin, (char *)0);
Expand Down Expand Up @@ -767,9 +768,10 @@ Py_Main(int argc, wchar_t **argv)
#else
Py_SetProgramName(argv[0]);
#endif
Py_Initialize();
Py_XDECREF(cmdline.warning_options);
if (_Py_InitializeMainInterpreter(1))
Py_FatalError("Py_Main: Py_InitializeMainInterpreter failed");

/* TODO: Move this to _PyRun_PrepareMain */
if (!Py_QuietFlag && (Py_VerboseFlag ||
(cmdline.command == NULL && cmdline.filename == NULL &&
cmdline.module == NULL && stdin_is_interactive))) {
Expand All @@ -779,6 +781,7 @@ Py_Main(int argc, wchar_t **argv)
fprintf(stderr, "%s\n", COPYRIGHT);
}

/* TODO: Move this to _Py_InitializeMainInterpreter */
if (cmdline.command != NULL) {
/* Backup _PyOS_optind and force sys.argv[0] = '-c' */
_PyOS_optind--;
Expand Down
8 changes: 5 additions & 3 deletions Python/bootstrap_hash.c
Original file line number Diff line number Diff line change
Expand Up @@ -599,18 +599,20 @@ init_hash_secret(int use_hash_seed,
}

void
_Py_HashRandomization_Init(void)
_Py_HashRandomization_Init(_PyCoreConfig *core_config)
{
char *seed_text;
int use_hash_seed = -1;
unsigned long hash_seed;
int use_hash_seed = core_config->use_hash_seed;
unsigned long hash_seed = core_config->hash_seed;

if (use_hash_seed < 0) {
seed_text = Py_GETENV("PYTHONHASHSEED");
if (Py_ReadHashSeed(seed_text, &use_hash_seed, &hash_seed) < 0) {
Py_FatalError("PYTHONHASHSEED must be \"random\" or an integer "
"in range [0; 4294967295]");
}
core_config->use_hash_seed = use_hash_seed;
core_config->hash_seed = hash_seed;
}
init_hash_secret(use_hash_seed, hash_seed);
}
Expand Down
Loading

0 comments on commit 1abcf67

Please sign in to comment.