mirror of
https://github.com/python/cpython.git
synced 2026-04-29 23:30:56 +00:00
Merge branch 'master' into feature/34632-importlib-metadata
This commit is contained in:
commit
a1c3d9c7f5
594 changed files with 33527 additions and 6692 deletions
39
Python/Python-ast.c
generated
39
Python/Python-ast.c
generated
|
|
@ -524,8 +524,10 @@ static char *withitem_fields[]={
|
|||
static PyTypeObject *type_ignore_type;
|
||||
static PyObject* ast2obj_type_ignore(void*);
|
||||
static PyTypeObject *TypeIgnore_type;
|
||||
_Py_IDENTIFIER(tag);
|
||||
static char *TypeIgnore_fields[]={
|
||||
"lineno",
|
||||
"tag",
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -1164,7 +1166,7 @@ static int init_types(void)
|
|||
if (!type_ignore_type) return 0;
|
||||
if (!add_attributes(type_ignore_type, NULL, 0)) return 0;
|
||||
TypeIgnore_type = make_type("TypeIgnore", type_ignore_type,
|
||||
TypeIgnore_fields, 1);
|
||||
TypeIgnore_fields, 2);
|
||||
if (!TypeIgnore_type) return 0;
|
||||
initialized = 1;
|
||||
return 1;
|
||||
|
|
@ -2667,14 +2669,20 @@ withitem(expr_ty context_expr, expr_ty optional_vars, PyArena *arena)
|
|||
}
|
||||
|
||||
type_ignore_ty
|
||||
TypeIgnore(int lineno, PyArena *arena)
|
||||
TypeIgnore(int lineno, string tag, PyArena *arena)
|
||||
{
|
||||
type_ignore_ty p;
|
||||
if (!tag) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"field tag is required for TypeIgnore");
|
||||
return NULL;
|
||||
}
|
||||
p = (type_ignore_ty)PyArena_Malloc(arena, sizeof(*p));
|
||||
if (!p)
|
||||
return NULL;
|
||||
p->kind = TypeIgnore_kind;
|
||||
p->v.TypeIgnore.lineno = lineno;
|
||||
p->v.TypeIgnore.tag = tag;
|
||||
return p;
|
||||
}
|
||||
|
||||
|
|
@ -4158,6 +4166,11 @@ ast2obj_type_ignore(void* _o)
|
|||
if (_PyObject_SetAttrId(result, &PyId_lineno, value) == -1)
|
||||
goto failed;
|
||||
Py_DECREF(value);
|
||||
value = ast2obj_string(o->v.TypeIgnore.tag);
|
||||
if (!value) goto failed;
|
||||
if (_PyObject_SetAttrId(result, &PyId_tag, value) == -1)
|
||||
goto failed;
|
||||
Py_DECREF(value);
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
|
|
@ -8738,6 +8751,7 @@ obj2ast_type_ignore(PyObject* obj, type_ignore_ty* out, PyArena* arena)
|
|||
}
|
||||
if (isinstance) {
|
||||
int lineno;
|
||||
string tag;
|
||||
|
||||
if (_PyObject_LookupAttrId(obj, &PyId_lineno, &tmp) < 0) {
|
||||
return 1;
|
||||
|
|
@ -8752,7 +8766,20 @@ obj2ast_type_ignore(PyObject* obj, type_ignore_ty* out, PyArena* arena)
|
|||
if (res != 0) goto failed;
|
||||
Py_CLEAR(tmp);
|
||||
}
|
||||
*out = TypeIgnore(lineno, arena);
|
||||
if (_PyObject_LookupAttrId(obj, &PyId_tag, &tmp) < 0) {
|
||||
return 1;
|
||||
}
|
||||
if (tmp == NULL) {
|
||||
PyErr_SetString(PyExc_TypeError, "required field \"tag\" missing from TypeIgnore");
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
int res;
|
||||
res = obj2ast_string(tmp, &tag, arena);
|
||||
if (res != 0) goto failed;
|
||||
Py_CLEAR(tmp);
|
||||
}
|
||||
*out = TypeIgnore(lineno, tag, arena);
|
||||
if (*out == NULL) goto failed;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -8776,6 +8803,8 @@ PyInit__ast(void)
|
|||
if (!m) return NULL;
|
||||
d = PyModule_GetDict(m);
|
||||
if (PyDict_SetItemString(d, "AST", (PyObject*)&AST_type) < 0) return NULL;
|
||||
if (PyModule_AddIntMacro(m, PyCF_ALLOW_TOP_LEVEL_AWAIT) < 0)
|
||||
return NULL;
|
||||
if (PyModule_AddIntMacro(m, PyCF_ONLY_AST) < 0)
|
||||
return NULL;
|
||||
if (PyModule_AddIntMacro(m, PyCF_TYPE_COMMENTS) < 0)
|
||||
|
|
@ -8995,6 +9024,10 @@ mod_ty PyAST_obj2mod_ex(PyObject* ast, PyArena* arena, int mode, int feature_ver
|
|||
char *req_name[] = {"Module", "Expression", "Interactive"};
|
||||
int isinstance;
|
||||
|
||||
if (PySys_Audit("compile", "OO", ast, Py_None) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
req_type[0] = (PyObject*)Module_type;
|
||||
req_type[1] = (PyObject*)Expression_type;
|
||||
req_type[2] = (PyObject*)Interactive_type;
|
||||
|
|
|
|||
|
|
@ -15,6 +15,134 @@ _Py_IDENTIFIER(default);
|
|||
_Py_IDENTIFIER(ignore);
|
||||
#endif
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
typedef struct _warnings_runtime_state WarningsState;
|
||||
|
||||
/* Forward declaration of the _warnings module definition. */
|
||||
static struct PyModuleDef warningsmodule;
|
||||
|
||||
/* Given a module object, get its per-module state. */
|
||||
static WarningsState *
|
||||
_Warnings_GetState()
|
||||
{
|
||||
PyThreadState *tstate = PyThreadState_GET();
|
||||
if (tstate == NULL) {
|
||||
PyErr_SetString(PyExc_RuntimeError,
|
||||
"_Warnings_GetState: could not identify current interpreter");
|
||||
return NULL;
|
||||
}
|
||||
return &tstate->interp->warnings;
|
||||
}
|
||||
|
||||
/* Clear the given warnings module state. */
|
||||
static void
|
||||
_Warnings_ClearState(WarningsState *st)
|
||||
{
|
||||
Py_CLEAR(st->filters);
|
||||
Py_CLEAR(st->once_registry);
|
||||
Py_CLEAR(st->default_action);
|
||||
}
|
||||
|
||||
#ifndef Py_DEBUG
|
||||
static PyObject *
|
||||
create_filter(PyObject *category, _Py_Identifier *id, const char *modname)
|
||||
{
|
||||
PyObject *modname_obj = NULL;
|
||||
PyObject *action_str = _PyUnicode_FromId(id);
|
||||
if (action_str == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Default to "no module name" for initial filter set */
|
||||
if (modname != NULL) {
|
||||
modname_obj = PyUnicode_InternFromString(modname);
|
||||
if (modname_obj == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
modname_obj = Py_None;
|
||||
}
|
||||
|
||||
/* This assumes the line number is zero for now. */
|
||||
return PyTuple_Pack(5, action_str, Py_None,
|
||||
category, modname_obj, _PyLong_Zero);
|
||||
}
|
||||
#endif
|
||||
|
||||
static PyObject *
|
||||
init_filters(void)
|
||||
{
|
||||
#ifdef Py_DEBUG
|
||||
/* Py_DEBUG builds show all warnings by default */
|
||||
return PyList_New(0);
|
||||
#else
|
||||
/* Other builds ignore a number of warning categories by default */
|
||||
PyObject *filters = PyList_New(5);
|
||||
if (filters == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t pos = 0; /* Post-incremented in each use. */
|
||||
PyList_SET_ITEM(filters, pos++,
|
||||
create_filter(PyExc_DeprecationWarning, &PyId_default, "__main__"));
|
||||
PyList_SET_ITEM(filters, pos++,
|
||||
create_filter(PyExc_DeprecationWarning, &PyId_ignore, NULL));
|
||||
PyList_SET_ITEM(filters, pos++,
|
||||
create_filter(PyExc_PendingDeprecationWarning, &PyId_ignore, NULL));
|
||||
PyList_SET_ITEM(filters, pos++,
|
||||
create_filter(PyExc_ImportWarning, &PyId_ignore, NULL));
|
||||
PyList_SET_ITEM(filters, pos++,
|
||||
create_filter(PyExc_ResourceWarning, &PyId_ignore, NULL));
|
||||
|
||||
for (size_t x = 0; x < pos; x++) {
|
||||
if (PyList_GET_ITEM(filters, x) == NULL) {
|
||||
Py_DECREF(filters);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return filters;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Initialize the given warnings module state. */
|
||||
static int
|
||||
_Warnings_InitState(WarningsState *st)
|
||||
{
|
||||
if (st->filters == NULL) {
|
||||
st->filters = init_filters();
|
||||
if (st->filters == NULL) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
if (st->once_registry == NULL) {
|
||||
st->once_registry = PyDict_New();
|
||||
if (st->once_registry == NULL) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
if (st->default_action == NULL) {
|
||||
st->default_action = PyUnicode_FromString("default");
|
||||
if (st->default_action == NULL) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
st->filters_version = 0;
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
_Warnings_ClearState(st);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
static int
|
||||
check_matched(PyObject *obj, PyObject *arg)
|
||||
{
|
||||
|
|
@ -93,7 +221,7 @@ get_warnings_attr(_Py_Identifier *attr_id, int try_import)
|
|||
|
||||
|
||||
static PyObject *
|
||||
get_once_registry(void)
|
||||
get_once_registry(WarningsState *st)
|
||||
{
|
||||
PyObject *registry;
|
||||
_Py_IDENTIFIER(onceregistry);
|
||||
|
|
@ -102,8 +230,8 @@ get_once_registry(void)
|
|||
if (registry == NULL) {
|
||||
if (PyErr_Occurred())
|
||||
return NULL;
|
||||
assert(_PyRuntime.warnings.once_registry);
|
||||
return _PyRuntime.warnings.once_registry;
|
||||
assert(st->once_registry);
|
||||
return st->once_registry;
|
||||
}
|
||||
if (!PyDict_Check(registry)) {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
|
|
@ -113,13 +241,13 @@ get_once_registry(void)
|
|||
Py_DECREF(registry);
|
||||
return NULL;
|
||||
}
|
||||
Py_SETREF(_PyRuntime.warnings.once_registry, registry);
|
||||
Py_SETREF(st->once_registry, registry);
|
||||
return registry;
|
||||
}
|
||||
|
||||
|
||||
static PyObject *
|
||||
get_default_action(void)
|
||||
get_default_action(WarningsState *st)
|
||||
{
|
||||
PyObject *default_action;
|
||||
_Py_IDENTIFIER(defaultaction);
|
||||
|
|
@ -129,8 +257,8 @@ get_default_action(void)
|
|||
if (PyErr_Occurred()) {
|
||||
return NULL;
|
||||
}
|
||||
assert(_PyRuntime.warnings.default_action);
|
||||
return _PyRuntime.warnings.default_action;
|
||||
assert(st->default_action);
|
||||
return st->default_action;
|
||||
}
|
||||
if (!PyUnicode_Check(default_action)) {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
|
|
@ -140,7 +268,7 @@ get_default_action(void)
|
|||
Py_DECREF(default_action);
|
||||
return NULL;
|
||||
}
|
||||
Py_SETREF(_PyRuntime.warnings.default_action, default_action);
|
||||
Py_SETREF(st->default_action, default_action);
|
||||
return default_action;
|
||||
}
|
||||
|
||||
|
|
@ -154,6 +282,10 @@ get_filter(PyObject *category, PyObject *text, Py_ssize_t lineno,
|
|||
Py_ssize_t i;
|
||||
PyObject *warnings_filters;
|
||||
_Py_IDENTIFIER(filters);
|
||||
WarningsState *st = _Warnings_GetState();
|
||||
if (st == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
warnings_filters = get_warnings_attr(&PyId_filters, 0);
|
||||
if (warnings_filters == NULL) {
|
||||
|
|
@ -161,17 +293,17 @@ get_filter(PyObject *category, PyObject *text, Py_ssize_t lineno,
|
|||
return NULL;
|
||||
}
|
||||
else {
|
||||
Py_SETREF(_PyRuntime.warnings.filters, warnings_filters);
|
||||
Py_SETREF(st->filters, warnings_filters);
|
||||
}
|
||||
|
||||
PyObject *filters = _PyRuntime.warnings.filters;
|
||||
PyObject *filters = st->filters;
|
||||
if (filters == NULL || !PyList_Check(filters)) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
MODULE_NAME ".filters must be a list");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* _PyRuntime.warnings.filters could change while we are iterating over it. */
|
||||
/* WarningsState.filters could change while we are iterating over it. */
|
||||
for (i = 0; i < PyList_GET_SIZE(filters); i++) {
|
||||
PyObject *tmp_item, *action, *msg, *cat, *mod, *ln_obj;
|
||||
Py_ssize_t ln;
|
||||
|
|
@ -232,7 +364,7 @@ get_filter(PyObject *category, PyObject *text, Py_ssize_t lineno,
|
|||
Py_DECREF(tmp_item);
|
||||
}
|
||||
|
||||
action = get_default_action();
|
||||
action = get_default_action(st);
|
||||
if (action != NULL) {
|
||||
Py_INCREF(Py_None);
|
||||
*item = Py_None;
|
||||
|
|
@ -252,16 +384,20 @@ already_warned(PyObject *registry, PyObject *key, int should_set)
|
|||
if (key == NULL)
|
||||
return -1;
|
||||
|
||||
WarningsState *st = _Warnings_GetState();
|
||||
if (st == NULL) {
|
||||
return -1;
|
||||
}
|
||||
version_obj = _PyDict_GetItemIdWithError(registry, &PyId_version);
|
||||
if (version_obj == NULL
|
||||
|| !PyLong_CheckExact(version_obj)
|
||||
|| PyLong_AsLong(version_obj) != _PyRuntime.warnings.filters_version)
|
||||
|| PyLong_AsLong(version_obj) != st->filters_version)
|
||||
{
|
||||
if (PyErr_Occurred()) {
|
||||
return -1;
|
||||
}
|
||||
PyDict_Clear(registry);
|
||||
version_obj = PyLong_FromLong(_PyRuntime.warnings.filters_version);
|
||||
version_obj = PyLong_FromLong(st->filters_version);
|
||||
if (version_obj == NULL)
|
||||
return -1;
|
||||
if (_PyDict_SetItemId(registry, &PyId_version, version_obj) < 0) {
|
||||
|
|
@ -567,11 +703,15 @@ warn_explicit(PyObject *category, PyObject *message,
|
|||
|
||||
if (_PyUnicode_EqualToASCIIString(action, "once")) {
|
||||
if (registry == NULL || registry == Py_None) {
|
||||
registry = get_once_registry();
|
||||
WarningsState *st = _Warnings_GetState();
|
||||
if (st == NULL) {
|
||||
goto cleanup;
|
||||
}
|
||||
registry = get_once_registry(st);
|
||||
if (registry == NULL)
|
||||
goto cleanup;
|
||||
}
|
||||
/* _PyRuntime.warnings.once_registry[(text, category)] = 1 */
|
||||
/* WarningsState.once_registry[(text, category)] = 1 */
|
||||
rc = update_registry(registry, text, category, 0);
|
||||
}
|
||||
else if (_PyUnicode_EqualToASCIIString(action, "module")) {
|
||||
|
|
@ -925,7 +1065,11 @@ warnings_warn_explicit(PyObject *self, PyObject *args, PyObject *kwds)
|
|||
static PyObject *
|
||||
warnings_filters_mutated(PyObject *self, PyObject *args)
|
||||
{
|
||||
_PyRuntime.warnings.filters_version++;
|
||||
WarningsState *st = _Warnings_GetState();
|
||||
if (st == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
st->filters_version++;
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
|
|
@ -1175,78 +1319,16 @@ static PyMethodDef warnings_functions[] = {
|
|||
};
|
||||
|
||||
|
||||
#ifndef Py_DEBUG
|
||||
static PyObject *
|
||||
create_filter(PyObject *category, _Py_Identifier *id, const char *modname)
|
||||
{
|
||||
PyObject *modname_obj = NULL;
|
||||
PyObject *action_str = _PyUnicode_FromId(id);
|
||||
if (action_str == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Default to "no module name" for initial filter set */
|
||||
if (modname != NULL) {
|
||||
modname_obj = PyUnicode_InternFromString(modname);
|
||||
if (modname_obj == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
modname_obj = Py_None;
|
||||
}
|
||||
|
||||
/* This assumes the line number is zero for now. */
|
||||
return PyTuple_Pack(5, action_str, Py_None,
|
||||
category, modname_obj, _PyLong_Zero);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static PyObject *
|
||||
init_filters(void)
|
||||
{
|
||||
#ifdef Py_DEBUG
|
||||
/* Py_DEBUG builds show all warnings by default */
|
||||
return PyList_New(0);
|
||||
#else
|
||||
/* Other builds ignore a number of warning categories by default */
|
||||
PyObject *filters = PyList_New(5);
|
||||
if (filters == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t pos = 0; /* Post-incremented in each use. */
|
||||
PyList_SET_ITEM(filters, pos++,
|
||||
create_filter(PyExc_DeprecationWarning, &PyId_default, "__main__"));
|
||||
PyList_SET_ITEM(filters, pos++,
|
||||
create_filter(PyExc_DeprecationWarning, &PyId_ignore, NULL));
|
||||
PyList_SET_ITEM(filters, pos++,
|
||||
create_filter(PyExc_PendingDeprecationWarning, &PyId_ignore, NULL));
|
||||
PyList_SET_ITEM(filters, pos++,
|
||||
create_filter(PyExc_ImportWarning, &PyId_ignore, NULL));
|
||||
PyList_SET_ITEM(filters, pos++,
|
||||
create_filter(PyExc_ResourceWarning, &PyId_ignore, NULL));
|
||||
|
||||
for (size_t x = 0; x < pos; x++) {
|
||||
if (PyList_GET_ITEM(filters, x) == NULL) {
|
||||
Py_DECREF(filters);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return filters;
|
||||
#endif
|
||||
}
|
||||
|
||||
static struct PyModuleDef warningsmodule = {
|
||||
PyModuleDef_HEAD_INIT,
|
||||
MODULE_NAME,
|
||||
warnings__doc__,
|
||||
0,
|
||||
warnings_functions,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
MODULE_NAME, /* m_name */
|
||||
warnings__doc__, /* m_doc */
|
||||
0, /* m_size */
|
||||
warnings_functions, /* m_methods */
|
||||
NULL, /* m_reload */
|
||||
NULL, /* m_traverse */
|
||||
NULL, /* m_clear */
|
||||
NULL /* m_free */
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -1256,49 +1338,46 @@ _PyWarnings_Init(void)
|
|||
PyObject *m;
|
||||
|
||||
m = PyModule_Create(&warningsmodule);
|
||||
if (m == NULL)
|
||||
if (m == NULL) {
|
||||
return NULL;
|
||||
|
||||
struct _warnings_runtime_state *state = &_PyRuntime.warnings;
|
||||
if (state->filters == NULL) {
|
||||
state->filters = init_filters();
|
||||
if (state->filters == NULL)
|
||||
return NULL;
|
||||
}
|
||||
Py_INCREF(state->filters);
|
||||
if (PyModule_AddObject(m, "filters", state->filters) < 0)
|
||||
return NULL;
|
||||
|
||||
if (state->once_registry == NULL) {
|
||||
state->once_registry = PyDict_New();
|
||||
if (state->once_registry == NULL)
|
||||
return NULL;
|
||||
WarningsState *st = _Warnings_GetState();
|
||||
if (st == NULL) {
|
||||
goto error;
|
||||
}
|
||||
Py_INCREF(state->once_registry);
|
||||
if (PyModule_AddObject(m, "_onceregistry",
|
||||
state->once_registry) < 0)
|
||||
return NULL;
|
||||
|
||||
if (state->default_action == NULL) {
|
||||
state->default_action = PyUnicode_FromString("default");
|
||||
if (state->default_action == NULL)
|
||||
return NULL;
|
||||
if (_Warnings_InitState(st) < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
Py_INCREF(st->filters);
|
||||
if (PyModule_AddObject(m, "filters", st->filters) < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
Py_INCREF(st->once_registry);
|
||||
if (PyModule_AddObject(m, "_onceregistry", st->once_registry) < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
Py_INCREF(st->default_action);
|
||||
if (PyModule_AddObject(m, "_defaultaction", st->default_action) < 0) {
|
||||
goto error;
|
||||
}
|
||||
Py_INCREF(state->default_action);
|
||||
if (PyModule_AddObject(m, "_defaultaction",
|
||||
state->default_action) < 0)
|
||||
return NULL;
|
||||
|
||||
state->filters_version = 0;
|
||||
return m;
|
||||
|
||||
error:
|
||||
if (st != NULL) {
|
||||
_Warnings_ClearState(st);
|
||||
}
|
||||
Py_DECREF(m);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
// We need this to ensure that warnings still work until late in finalization.
|
||||
void
|
||||
_PyWarnings_Fini(_PyRuntimeState *runtime)
|
||||
_PyWarnings_Fini(PyInterpreterState *interp)
|
||||
{
|
||||
struct _warnings_runtime_state *state = &runtime->warnings;
|
||||
Py_CLEAR(state->filters);
|
||||
Py_CLEAR(state->once_registry);
|
||||
Py_CLEAR(state->default_action);
|
||||
_Warnings_ClearState(&interp->warnings);
|
||||
}
|
||||
|
|
|
|||
18
Python/ast.c
18
Python/ast.c
|
|
@ -830,7 +830,10 @@ PyAST_FromNodeObject(const node *n, PyCompilerFlags *flags,
|
|||
goto out;
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
type_ignore_ty ti = TypeIgnore(LINENO(CHILD(ch, i)), arena);
|
||||
string type_comment = new_type_comment(STR(CHILD(ch, i)), &c);
|
||||
if (!type_comment)
|
||||
goto out;
|
||||
type_ignore_ty ti = TypeIgnore(LINENO(CHILD(ch, i)), type_comment, arena);
|
||||
if (!ti)
|
||||
goto out;
|
||||
asdl_seq_SET(type_ignores, i, ti);
|
||||
|
|
@ -2971,7 +2974,6 @@ ast_for_expr(struct compiling *c, const node *n)
|
|||
return Compare(expression, ops, cmps, LINENO(n), n->n_col_offset,
|
||||
n->n_end_lineno, n->n_end_col_offset, c->c_arena);
|
||||
}
|
||||
break;
|
||||
|
||||
case star_expr:
|
||||
return ast_for_starred(c, n);
|
||||
|
|
@ -3618,7 +3620,6 @@ alias_for_import_name(struct compiling *c, const node *n, int store)
|
|||
return NULL;
|
||||
return a;
|
||||
}
|
||||
break;
|
||||
case dotted_name:
|
||||
if (NCH(n) == 1) {
|
||||
node *name_node = CHILD(n, 0);
|
||||
|
|
@ -3669,7 +3670,6 @@ alias_for_import_name(struct compiling *c, const node *n, int store)
|
|||
}
|
||||
return alias(str, NULL, c->c_arena);
|
||||
}
|
||||
break;
|
||||
case STAR:
|
||||
str = PyUnicode_InternFromString("*");
|
||||
if (!str)
|
||||
|
|
@ -5228,10 +5228,15 @@ fstring_find_expr(const char **str, const char *end, int raw, int recurse_lvl,
|
|||
|
||||
}
|
||||
if (equal_flag) {
|
||||
Py_ssize_t len = expr_text_end-expr_start;
|
||||
Py_ssize_t len = expr_text_end - expr_start;
|
||||
expr_text = PyUnicode_FromStringAndSize(expr_start, len);
|
||||
if (!expr_text)
|
||||
if (!expr_text) {
|
||||
goto error;
|
||||
}
|
||||
if (PyArena_AddPyObject(c->c_arena, expr_text) < 0) {
|
||||
Py_DECREF(expr_text);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check for the format spec, if present. */
|
||||
|
|
@ -5278,7 +5283,6 @@ fstring_find_expr(const char **str, const char *end, int raw, int recurse_lvl,
|
|||
/* Falls through to error. */
|
||||
|
||||
error:
|
||||
Py_XDECREF(expr_text);
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -193,22 +193,30 @@ static int
|
|||
append_ast_args(_PyUnicodeWriter *writer, arguments_ty args)
|
||||
{
|
||||
bool first;
|
||||
Py_ssize_t i, di, arg_count, default_count;
|
||||
Py_ssize_t i, di, arg_count, posonlyarg_count, default_count;
|
||||
|
||||
first = true;
|
||||
|
||||
/* positional arguments with defaults */
|
||||
/* positional-only and positional arguments with defaults */
|
||||
posonlyarg_count = asdl_seq_LEN(args->posonlyargs);
|
||||
arg_count = asdl_seq_LEN(args->args);
|
||||
default_count = asdl_seq_LEN(args->defaults);
|
||||
for (i = 0; i < arg_count; i++) {
|
||||
for (i = 0; i < posonlyarg_count + arg_count; i++) {
|
||||
APPEND_STR_IF_NOT_FIRST(", ");
|
||||
APPEND(arg, (arg_ty)asdl_seq_GET(args->args, i));
|
||||
if (i < posonlyarg_count){
|
||||
APPEND(arg, (arg_ty)asdl_seq_GET(args->posonlyargs, i));
|
||||
} else {
|
||||
APPEND(arg, (arg_ty)asdl_seq_GET(args->args, i-posonlyarg_count));
|
||||
}
|
||||
|
||||
di = i - arg_count + default_count;
|
||||
di = i - posonlyarg_count - arg_count + default_count;
|
||||
if (di >= 0) {
|
||||
APPEND_STR("=");
|
||||
APPEND_EXPR((expr_ty)asdl_seq_GET(args->defaults, di), PR_TEST);
|
||||
}
|
||||
if (posonlyarg_count && i + 1 == posonlyarg_count) {
|
||||
APPEND_STR(", /");
|
||||
}
|
||||
}
|
||||
|
||||
/* vararg, or bare '*' if no varargs but keyword-only arguments present */
|
||||
|
|
@ -251,7 +259,9 @@ static int
|
|||
append_ast_lambda(_PyUnicodeWriter *writer, expr_ty e, int level)
|
||||
{
|
||||
APPEND_STR_IF(level > PR_TEST, "(");
|
||||
APPEND_STR(asdl_seq_LEN(e->v.Lambda.args->args) ? "lambda " : "lambda");
|
||||
Py_ssize_t n_positional = (asdl_seq_LEN(e->v.Lambda.args->args) +
|
||||
asdl_seq_LEN(e->v.Lambda.args->posonlyargs));
|
||||
APPEND_STR(n_positional ? "lambda " : "lambda");
|
||||
APPEND(args, e->v.Lambda.args);
|
||||
APPEND_STR(": ");
|
||||
APPEND_EXPR(e->v.Lambda.body, PR_TEST);
|
||||
|
|
@ -809,6 +819,17 @@ append_ast_await(_PyUnicodeWriter *writer, expr_ty e, int level)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
append_named_expr(_PyUnicodeWriter *writer, expr_ty e, int level)
|
||||
{
|
||||
APPEND_STR_IF(level > PR_TUPLE, "(");
|
||||
APPEND_EXPR(e->v.NamedExpr.target, PR_ATOM);
|
||||
APPEND_STR(":=");
|
||||
APPEND_EXPR(e->v.NamedExpr.value, PR_ATOM);
|
||||
APPEND_STR_IF(level > PR_TUPLE, ")");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
append_ast_expr(_PyUnicodeWriter *writer, expr_ty e, int level)
|
||||
{
|
||||
|
|
@ -867,6 +888,8 @@ append_ast_expr(_PyUnicodeWriter *writer, expr_ty e, int level)
|
|||
return append_ast_list(writer, e);
|
||||
case Tuple_kind:
|
||||
return append_ast_tuple(writer, e, level);
|
||||
case NamedExpr_kind:
|
||||
return append_named_expr(writer, e, level);
|
||||
default:
|
||||
PyErr_SetString(PyExc_SystemError,
|
||||
"unknown expression kind");
|
||||
|
|
|
|||
|
|
@ -977,9 +977,13 @@ builtin_eval_impl(PyObject *module, PyObject *source, PyObject *globals,
|
|||
}
|
||||
|
||||
if (PyCode_Check(source)) {
|
||||
if (PySys_Audit("exec", "O", source) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (PyCode_GetNumFree((PyCodeObject *)source) > 0) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"code object passed to eval() may not contain free variables");
|
||||
"code object passed to eval() may not contain free variables");
|
||||
return NULL;
|
||||
}
|
||||
return PyEval_EvalCode(source, globals, locals);
|
||||
|
|
@ -1061,6 +1065,10 @@ builtin_exec_impl(PyObject *module, PyObject *source, PyObject *globals,
|
|||
}
|
||||
|
||||
if (PyCode_Check(source)) {
|
||||
if (PySys_Audit("exec", "O", source) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (PyCode_GetNumFree((PyCodeObject *)source) > 0) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"code object passed to exec() may not "
|
||||
|
|
@ -1207,7 +1215,14 @@ static PyObject *
|
|||
builtin_id(PyModuleDef *self, PyObject *v)
|
||||
/*[clinic end generated code: output=0aa640785f697f65 input=5a534136419631f4]*/
|
||||
{
|
||||
return PyLong_FromVoidPtr(v);
|
||||
PyObject *id = PyLong_FromVoidPtr(v);
|
||||
|
||||
if (id && PySys_Audit("builtins.id", "O", id) < 0) {
|
||||
Py_DECREF(id);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1986,6 +2001,10 @@ builtin_input_impl(PyObject *module, PyObject *prompt)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (PySys_Audit("builtins.input", "O", prompt ? prompt : Py_None) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* First of all, flush stderr */
|
||||
tmp = _PyObject_CallMethodId(ferr, &PyId_flush, NULL);
|
||||
if (tmp == NULL)
|
||||
|
|
@ -2116,6 +2135,13 @@ builtin_input_impl(PyObject *module, PyObject *prompt)
|
|||
Py_DECREF(stdin_errors);
|
||||
Py_XDECREF(po);
|
||||
PyMem_FREE(s);
|
||||
|
||||
if (result != NULL) {
|
||||
if (PySys_Audit("builtins.input/result", "O", result) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
_readline_errors:
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#include "Python.h"
|
||||
#include "pycore_coreconfig.h"
|
||||
#ifdef MS_WINDOWS
|
||||
# include <windows.h>
|
||||
/* All sample MSDN wincrypt programs include the header below. It is at least
|
||||
|
|
|
|||
1105
Python/ceval.c
1105
Python/ceval.c
File diff suppressed because it is too large
Load diff
|
|
@ -7,10 +7,6 @@
|
|||
|
||||
#include "pycore_atomic.h"
|
||||
|
||||
/* First some general settings */
|
||||
|
||||
#define INTERVAL (_PyRuntime.ceval.gil.interval >= 1 ? _PyRuntime.ceval.gil.interval : 1)
|
||||
|
||||
|
||||
/*
|
||||
Notes about the implementation:
|
||||
|
|
@ -94,158 +90,156 @@
|
|||
|
||||
#define DEFAULT_INTERVAL 5000
|
||||
|
||||
static void _gil_initialize(struct _gil_runtime_state *state)
|
||||
static void _gil_initialize(struct _gil_runtime_state *gil)
|
||||
{
|
||||
_Py_atomic_int uninitialized = {-1};
|
||||
state->locked = uninitialized;
|
||||
state->interval = DEFAULT_INTERVAL;
|
||||
gil->locked = uninitialized;
|
||||
gil->interval = DEFAULT_INTERVAL;
|
||||
}
|
||||
|
||||
static int gil_created(void)
|
||||
static int gil_created(struct _gil_runtime_state *gil)
|
||||
{
|
||||
return (_Py_atomic_load_explicit(&_PyRuntime.ceval.gil.locked,
|
||||
_Py_memory_order_acquire)
|
||||
) >= 0;
|
||||
return (_Py_atomic_load_explicit(&gil->locked, _Py_memory_order_acquire) >= 0);
|
||||
}
|
||||
|
||||
static void create_gil(void)
|
||||
static void create_gil(struct _gil_runtime_state *gil)
|
||||
{
|
||||
MUTEX_INIT(_PyRuntime.ceval.gil.mutex);
|
||||
MUTEX_INIT(gil->mutex);
|
||||
#ifdef FORCE_SWITCHING
|
||||
MUTEX_INIT(_PyRuntime.ceval.gil.switch_mutex);
|
||||
MUTEX_INIT(gil->switch_mutex);
|
||||
#endif
|
||||
COND_INIT(_PyRuntime.ceval.gil.cond);
|
||||
COND_INIT(gil->cond);
|
||||
#ifdef FORCE_SWITCHING
|
||||
COND_INIT(_PyRuntime.ceval.gil.switch_cond);
|
||||
COND_INIT(gil->switch_cond);
|
||||
#endif
|
||||
_Py_atomic_store_relaxed(&_PyRuntime.ceval.gil.last_holder, 0);
|
||||
_Py_ANNOTATE_RWLOCK_CREATE(&_PyRuntime.ceval.gil.locked);
|
||||
_Py_atomic_store_explicit(&_PyRuntime.ceval.gil.locked, 0,
|
||||
_Py_memory_order_release);
|
||||
_Py_atomic_store_relaxed(&gil->last_holder, 0);
|
||||
_Py_ANNOTATE_RWLOCK_CREATE(&gil->locked);
|
||||
_Py_atomic_store_explicit(&gil->locked, 0, _Py_memory_order_release);
|
||||
}
|
||||
|
||||
static void destroy_gil(void)
|
||||
static void destroy_gil(struct _gil_runtime_state *gil)
|
||||
{
|
||||
/* some pthread-like implementations tie the mutex to the cond
|
||||
* and must have the cond destroyed first.
|
||||
*/
|
||||
COND_FINI(_PyRuntime.ceval.gil.cond);
|
||||
MUTEX_FINI(_PyRuntime.ceval.gil.mutex);
|
||||
COND_FINI(gil->cond);
|
||||
MUTEX_FINI(gil->mutex);
|
||||
#ifdef FORCE_SWITCHING
|
||||
COND_FINI(_PyRuntime.ceval.gil.switch_cond);
|
||||
MUTEX_FINI(_PyRuntime.ceval.gil.switch_mutex);
|
||||
COND_FINI(gil->switch_cond);
|
||||
MUTEX_FINI(gil->switch_mutex);
|
||||
#endif
|
||||
_Py_atomic_store_explicit(&_PyRuntime.ceval.gil.locked, -1,
|
||||
_Py_atomic_store_explicit(&gil->locked, -1,
|
||||
_Py_memory_order_release);
|
||||
_Py_ANNOTATE_RWLOCK_DESTROY(&_PyRuntime.ceval.gil.locked);
|
||||
_Py_ANNOTATE_RWLOCK_DESTROY(&gil->locked);
|
||||
}
|
||||
|
||||
static void recreate_gil(void)
|
||||
static void recreate_gil(struct _gil_runtime_state *gil)
|
||||
{
|
||||
_Py_ANNOTATE_RWLOCK_DESTROY(&_PyRuntime.ceval.gil.locked);
|
||||
_Py_ANNOTATE_RWLOCK_DESTROY(&gil->locked);
|
||||
/* XXX should we destroy the old OS resources here? */
|
||||
create_gil();
|
||||
create_gil(gil);
|
||||
}
|
||||
|
||||
static void drop_gil(PyThreadState *tstate)
|
||||
static void
|
||||
drop_gil(struct _ceval_runtime_state *ceval, PyThreadState *tstate)
|
||||
{
|
||||
if (!_Py_atomic_load_relaxed(&_PyRuntime.ceval.gil.locked))
|
||||
struct _gil_runtime_state *gil = &ceval->gil;
|
||||
if (!_Py_atomic_load_relaxed(&gil->locked)) {
|
||||
Py_FatalError("drop_gil: GIL is not locked");
|
||||
}
|
||||
|
||||
/* tstate is allowed to be NULL (early interpreter init) */
|
||||
if (tstate != NULL) {
|
||||
/* Sub-interpreter support: threads might have been switched
|
||||
under our feet using PyThreadState_Swap(). Fix the GIL last
|
||||
holder variable so that our heuristics work. */
|
||||
_Py_atomic_store_relaxed(&_PyRuntime.ceval.gil.last_holder,
|
||||
(uintptr_t)tstate);
|
||||
_Py_atomic_store_relaxed(&gil->last_holder, (uintptr_t)tstate);
|
||||
}
|
||||
|
||||
MUTEX_LOCK(_PyRuntime.ceval.gil.mutex);
|
||||
_Py_ANNOTATE_RWLOCK_RELEASED(&_PyRuntime.ceval.gil.locked, /*is_write=*/1);
|
||||
_Py_atomic_store_relaxed(&_PyRuntime.ceval.gil.locked, 0);
|
||||
COND_SIGNAL(_PyRuntime.ceval.gil.cond);
|
||||
MUTEX_UNLOCK(_PyRuntime.ceval.gil.mutex);
|
||||
MUTEX_LOCK(gil->mutex);
|
||||
_Py_ANNOTATE_RWLOCK_RELEASED(&gil->locked, /*is_write=*/1);
|
||||
_Py_atomic_store_relaxed(&gil->locked, 0);
|
||||
COND_SIGNAL(gil->cond);
|
||||
MUTEX_UNLOCK(gil->mutex);
|
||||
|
||||
#ifdef FORCE_SWITCHING
|
||||
if (_Py_atomic_load_relaxed(&_PyRuntime.ceval.gil_drop_request) &&
|
||||
tstate != NULL)
|
||||
{
|
||||
MUTEX_LOCK(_PyRuntime.ceval.gil.switch_mutex);
|
||||
if (_Py_atomic_load_relaxed(&ceval->gil_drop_request) && tstate != NULL) {
|
||||
MUTEX_LOCK(gil->switch_mutex);
|
||||
/* Not switched yet => wait */
|
||||
if (((PyThreadState*)_Py_atomic_load_relaxed(
|
||||
&_PyRuntime.ceval.gil.last_holder)
|
||||
) == tstate)
|
||||
if (((PyThreadState*)_Py_atomic_load_relaxed(&gil->last_holder)) == tstate)
|
||||
{
|
||||
RESET_GIL_DROP_REQUEST();
|
||||
RESET_GIL_DROP_REQUEST(ceval);
|
||||
/* NOTE: if COND_WAIT does not atomically start waiting when
|
||||
releasing the mutex, another thread can run through, take
|
||||
the GIL and drop it again, and reset the condition
|
||||
before we even had a chance to wait for it. */
|
||||
COND_WAIT(_PyRuntime.ceval.gil.switch_cond,
|
||||
_PyRuntime.ceval.gil.switch_mutex);
|
||||
}
|
||||
MUTEX_UNLOCK(_PyRuntime.ceval.gil.switch_mutex);
|
||||
COND_WAIT(gil->switch_cond, gil->switch_mutex);
|
||||
}
|
||||
MUTEX_UNLOCK(gil->switch_mutex);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void take_gil(PyThreadState *tstate)
|
||||
static void
|
||||
take_gil(struct _ceval_runtime_state *ceval, PyThreadState *tstate)
|
||||
{
|
||||
int err;
|
||||
if (tstate == NULL)
|
||||
if (tstate == NULL) {
|
||||
Py_FatalError("take_gil: NULL tstate");
|
||||
}
|
||||
|
||||
err = errno;
|
||||
MUTEX_LOCK(_PyRuntime.ceval.gil.mutex);
|
||||
struct _gil_runtime_state *gil = &ceval->gil;
|
||||
int err = errno;
|
||||
MUTEX_LOCK(gil->mutex);
|
||||
|
||||
if (!_Py_atomic_load_relaxed(&_PyRuntime.ceval.gil.locked))
|
||||
if (!_Py_atomic_load_relaxed(&gil->locked)) {
|
||||
goto _ready;
|
||||
}
|
||||
|
||||
while (_Py_atomic_load_relaxed(&_PyRuntime.ceval.gil.locked)) {
|
||||
while (_Py_atomic_load_relaxed(&gil->locked)) {
|
||||
int timed_out = 0;
|
||||
unsigned long saved_switchnum;
|
||||
|
||||
saved_switchnum = _PyRuntime.ceval.gil.switch_number;
|
||||
COND_TIMED_WAIT(_PyRuntime.ceval.gil.cond, _PyRuntime.ceval.gil.mutex,
|
||||
INTERVAL, timed_out);
|
||||
saved_switchnum = gil->switch_number;
|
||||
|
||||
|
||||
unsigned long interval = (gil->interval >= 1 ? gil->interval : 1);
|
||||
COND_TIMED_WAIT(gil->cond, gil->mutex, interval, timed_out);
|
||||
/* If we timed out and no switch occurred in the meantime, it is time
|
||||
to ask the GIL-holding thread to drop it. */
|
||||
if (timed_out &&
|
||||
_Py_atomic_load_relaxed(&_PyRuntime.ceval.gil.locked) &&
|
||||
_PyRuntime.ceval.gil.switch_number == saved_switchnum) {
|
||||
SET_GIL_DROP_REQUEST();
|
||||
_Py_atomic_load_relaxed(&gil->locked) &&
|
||||
gil->switch_number == saved_switchnum)
|
||||
{
|
||||
SET_GIL_DROP_REQUEST(ceval);
|
||||
}
|
||||
}
|
||||
_ready:
|
||||
#ifdef FORCE_SWITCHING
|
||||
/* This mutex must be taken before modifying
|
||||
_PyRuntime.ceval.gil.last_holder (see drop_gil()). */
|
||||
MUTEX_LOCK(_PyRuntime.ceval.gil.switch_mutex);
|
||||
/* This mutex must be taken before modifying gil->last_holder:
|
||||
see drop_gil(). */
|
||||
MUTEX_LOCK(gil->switch_mutex);
|
||||
#endif
|
||||
/* We now hold the GIL */
|
||||
_Py_atomic_store_relaxed(&_PyRuntime.ceval.gil.locked, 1);
|
||||
_Py_ANNOTATE_RWLOCK_ACQUIRED(&_PyRuntime.ceval.gil.locked, /*is_write=*/1);
|
||||
_Py_atomic_store_relaxed(&gil->locked, 1);
|
||||
_Py_ANNOTATE_RWLOCK_ACQUIRED(&gil->locked, /*is_write=*/1);
|
||||
|
||||
if (tstate != (PyThreadState*)_Py_atomic_load_relaxed(
|
||||
&_PyRuntime.ceval.gil.last_holder))
|
||||
{
|
||||
_Py_atomic_store_relaxed(&_PyRuntime.ceval.gil.last_holder,
|
||||
(uintptr_t)tstate);
|
||||
++_PyRuntime.ceval.gil.switch_number;
|
||||
if (tstate != (PyThreadState*)_Py_atomic_load_relaxed(&gil->last_holder)) {
|
||||
_Py_atomic_store_relaxed(&gil->last_holder, (uintptr_t)tstate);
|
||||
++gil->switch_number;
|
||||
}
|
||||
|
||||
#ifdef FORCE_SWITCHING
|
||||
COND_SIGNAL(_PyRuntime.ceval.gil.switch_cond);
|
||||
MUTEX_UNLOCK(_PyRuntime.ceval.gil.switch_mutex);
|
||||
COND_SIGNAL(gil->switch_cond);
|
||||
MUTEX_UNLOCK(gil->switch_mutex);
|
||||
#endif
|
||||
if (_Py_atomic_load_relaxed(&_PyRuntime.ceval.gil_drop_request)) {
|
||||
RESET_GIL_DROP_REQUEST();
|
||||
if (_Py_atomic_load_relaxed(&ceval->gil_drop_request)) {
|
||||
RESET_GIL_DROP_REQUEST(ceval);
|
||||
}
|
||||
if (tstate->async_exc != NULL) {
|
||||
_PyEval_SignalAsyncExc();
|
||||
_PyEval_SignalAsyncExc(ceval);
|
||||
}
|
||||
|
||||
MUTEX_UNLOCK(_PyRuntime.ceval.gil.mutex);
|
||||
MUTEX_UNLOCK(gil->mutex);
|
||||
errno = err;
|
||||
}
|
||||
|
||||
|
|
|
|||
50
Python/clinic/sysmodule.c.h
generated
50
Python/clinic/sysmodule.c.h
generated
|
|
@ -2,6 +2,38 @@
|
|||
preserve
|
||||
[clinic start generated code]*/
|
||||
|
||||
PyDoc_STRVAR(sys_addaudithook__doc__,
|
||||
"addaudithook($module, /, hook)\n"
|
||||
"--\n"
|
||||
"\n"
|
||||
"Adds a new audit hook callback.");
|
||||
|
||||
#define SYS_ADDAUDITHOOK_METHODDEF \
|
||||
{"addaudithook", (PyCFunction)(void(*)(void))sys_addaudithook, METH_FASTCALL|METH_KEYWORDS, sys_addaudithook__doc__},
|
||||
|
||||
static PyObject *
|
||||
sys_addaudithook_impl(PyObject *module, PyObject *hook);
|
||||
|
||||
static PyObject *
|
||||
sys_addaudithook(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
static const char * const _keywords[] = {"hook", NULL};
|
||||
static _PyArg_Parser _parser = {NULL, _keywords, "addaudithook", 0};
|
||||
PyObject *argsbuf[1];
|
||||
PyObject *hook;
|
||||
|
||||
args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf);
|
||||
if (!args) {
|
||||
goto exit;
|
||||
}
|
||||
hook = args[0];
|
||||
return_value = sys_addaudithook_impl(module, hook);
|
||||
|
||||
exit:
|
||||
return return_value;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(sys_displayhook__doc__,
|
||||
"displayhook($module, object, /)\n"
|
||||
"--\n"
|
||||
|
|
@ -65,6 +97,22 @@ sys_exc_info(PyObject *module, PyObject *Py_UNUSED(ignored))
|
|||
return sys_exc_info_impl(module);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(sys_unraisablehook__doc__,
|
||||
"unraisablehook($module, unraisable, /)\n"
|
||||
"--\n"
|
||||
"\n"
|
||||
"Handle an unraisable exception.\n"
|
||||
"\n"
|
||||
"The unraisable argument has the following attributes:\n"
|
||||
"\n"
|
||||
"* exc_type: Exception type.\n"
|
||||
"* exc_value: Exception value.\n"
|
||||
"* exc_tb: Exception traceback, can be None.\n"
|
||||
"* obj: Object causing the exception, can be None.");
|
||||
|
||||
#define SYS_UNRAISABLEHOOK_METHODDEF \
|
||||
{"unraisablehook", (PyCFunction)sys_unraisablehook, METH_O, sys_unraisablehook__doc__},
|
||||
|
||||
PyDoc_STRVAR(sys_exit__doc__,
|
||||
"exit($module, status=None, /)\n"
|
||||
"--\n"
|
||||
|
|
@ -1060,4 +1108,4 @@ sys_getandroidapilevel(PyObject *module, PyObject *Py_UNUSED(ignored))
|
|||
#ifndef SYS_GETANDROIDAPILEVEL_METHODDEF
|
||||
#define SYS_GETANDROIDAPILEVEL_METHODDEF
|
||||
#endif /* !defined(SYS_GETANDROIDAPILEVEL_METHODDEF) */
|
||||
/*[clinic end generated code: output=3ba4c194d00f1866 input=a9049054013a1b77]*/
|
||||
/*[clinic end generated code: output=3c32bc91ec659509 input=a9049054013a1b77]*/
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
#include "Python.h"
|
||||
|
||||
#include "Python-ast.h"
|
||||
#include "pycore_pystate.h" /* _PyInterpreterState_GET_UNSAFE() */
|
||||
#include "ast.h"
|
||||
#include "code.h"
|
||||
#include "symtable.h"
|
||||
|
|
@ -310,6 +311,7 @@ PyAST_CompileObject(mod_ty mod, PyObject *filename, PyCompilerFlags *flags,
|
|||
PyCodeObject *co = NULL;
|
||||
PyCompilerFlags local_flags;
|
||||
int merged;
|
||||
_PyCoreConfig *config = &_PyInterpreterState_GET_UNSAFE()->core_config;
|
||||
|
||||
if (!__doc__) {
|
||||
__doc__ = PyUnicode_InternFromString("__doc__");
|
||||
|
|
@ -338,7 +340,7 @@ PyAST_CompileObject(mod_ty mod, PyObject *filename, PyCompilerFlags *flags,
|
|||
c.c_future->ff_features = merged;
|
||||
flags->cf_flags = merged;
|
||||
c.c_flags = flags;
|
||||
c.c_optimize = (optimize == -1) ? Py_OptimizeFlag : optimize;
|
||||
c.c_optimize = (optimize == -1) ? config->optimization_level : optimize;
|
||||
c.c_nestlevel = 0;
|
||||
|
||||
if (!_PyAST_Optimize(mod, arena, c.c_optimize)) {
|
||||
|
|
@ -2544,13 +2546,12 @@ compiler_if(struct compiler *c, stmt_ty s)
|
|||
return 0;
|
||||
|
||||
constant = expr_constant(s->v.If.test);
|
||||
/* constant = 0: "if 0"
|
||||
/* constant = 0: "if 0" Leave the optimizations to
|
||||
* the pephole optimizer to check for syntax errors
|
||||
* in the block.
|
||||
* constant = 1: "if 1", "if 2", ...
|
||||
* constant = -1: rest */
|
||||
if (constant == 0) {
|
||||
if (s->v.If.orelse)
|
||||
VISIT_SEQ(c, stmt, s->v.If.orelse);
|
||||
} else if (constant == 1) {
|
||||
if (constant == 1) {
|
||||
VISIT_SEQ(c, stmt, s->v.If.body);
|
||||
} else {
|
||||
if (asdl_seq_LEN(s->v.If.orelse)) {
|
||||
|
|
@ -2608,7 +2609,9 @@ static int
|
|||
compiler_async_for(struct compiler *c, stmt_ty s)
|
||||
{
|
||||
basicblock *start, *except, *end;
|
||||
if (c->u->u_scope_type != COMPILER_SCOPE_ASYNC_FUNCTION) {
|
||||
if (c->c_flags->cf_flags & PyCF_ALLOW_TOP_LEVEL_AWAIT){
|
||||
c->u->u_ste->ste_coroutine = 1;
|
||||
} else if (c->u->u_scope_type != COMPILER_SCOPE_ASYNC_FUNCTION) {
|
||||
return compiler_error(c, "'async for' outside async function");
|
||||
}
|
||||
|
||||
|
|
@ -2930,7 +2933,7 @@ compiler_try_except(struct compiler *c, stmt_ty s)
|
|||
try:
|
||||
# body
|
||||
finally:
|
||||
name = None
|
||||
name = None # in case body contains "del name"
|
||||
del name
|
||||
*/
|
||||
|
||||
|
|
@ -4563,7 +4566,9 @@ compiler_async_with(struct compiler *c, stmt_ty s, int pos)
|
|||
withitem_ty item = asdl_seq_GET(s->v.AsyncWith.items, pos);
|
||||
|
||||
assert(s->kind == AsyncWith_kind);
|
||||
if (c->u->u_scope_type != COMPILER_SCOPE_ASYNC_FUNCTION) {
|
||||
if (c->c_flags->cf_flags & PyCF_ALLOW_TOP_LEVEL_AWAIT){
|
||||
c->u->u_ste->ste_coroutine = 1;
|
||||
} else if (c->u->u_scope_type != COMPILER_SCOPE_ASYNC_FUNCTION){
|
||||
return compiler_error(c, "'async with' outside async function");
|
||||
}
|
||||
|
||||
|
|
@ -4772,12 +4777,16 @@ compiler_visit_expr1(struct compiler *c, expr_ty e)
|
|||
ADDOP(c, YIELD_FROM);
|
||||
break;
|
||||
case Await_kind:
|
||||
if (c->u->u_ste->ste_type != FunctionBlock)
|
||||
return compiler_error(c, "'await' outside function");
|
||||
if (!(c->c_flags->cf_flags & PyCF_ALLOW_TOP_LEVEL_AWAIT)){
|
||||
if (c->u->u_ste->ste_type != FunctionBlock){
|
||||
return compiler_error(c, "'await' outside function");
|
||||
}
|
||||
|
||||
if (c->u->u_scope_type != COMPILER_SCOPE_ASYNC_FUNCTION &&
|
||||
c->u->u_scope_type != COMPILER_SCOPE_COMPREHENSION)
|
||||
return compiler_error(c, "'await' outside async function");
|
||||
if (c->u->u_scope_type != COMPILER_SCOPE_ASYNC_FUNCTION &&
|
||||
c->u->u_scope_type != COMPILER_SCOPE_COMPREHENSION){
|
||||
return compiler_error(c, "'await' outside async function");
|
||||
}
|
||||
}
|
||||
|
||||
VISIT(c, expr, e->v.Await.value);
|
||||
ADDOP(c, GET_AWAITABLE);
|
||||
|
|
@ -4867,7 +4876,6 @@ compiler_visit_expr1(struct compiler *c, expr_ty e)
|
|||
return compiler_error(c,
|
||||
"can't use starred expression here");
|
||||
}
|
||||
break;
|
||||
case Name_kind:
|
||||
return compiler_nameop(c, e->v.Name.id, e->v.Name.ctx);
|
||||
/* child nodes of List and Tuple will have expr_context set */
|
||||
|
|
@ -5712,6 +5720,12 @@ compute_code_flags(struct compiler *c)
|
|||
/* (Only) inherit compilerflags in PyCF_MASK */
|
||||
flags |= (c->c_flags->cf_flags & PyCF_MASK);
|
||||
|
||||
if ((c->c_flags->cf_flags & PyCF_ALLOW_TOP_LEVEL_AWAIT) &&
|
||||
ste->ste_coroutine &&
|
||||
!ste->ste_generator) {
|
||||
flags |= CO_COROUTINE;
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -107,9 +107,8 @@ static const char usage_6[] =
|
|||
/* --- Global configuration variables ----------------------------- */
|
||||
|
||||
/* UTF-8 mode (PEP 540): if equals to 1, use the UTF-8 encoding, and change
|
||||
stdin and stdout error handler to "surrogateescape". It is equal to
|
||||
-1 by default: unknown, will be set by Py_Main() */
|
||||
int Py_UTF8Mode = -1;
|
||||
stdin and stdout error handler to "surrogateescape". */
|
||||
int Py_UTF8Mode = 0;
|
||||
int Py_DebugFlag = 0; /* Needed by parser.c */
|
||||
int Py_VerboseFlag = 0; /* Needed by import.c */
|
||||
int Py_QuietFlag = 0; /* Needed by sysmodule.c */
|
||||
|
|
@ -203,6 +202,34 @@ _Py_GetGlobalVariablesAsDict(void)
|
|||
}
|
||||
|
||||
|
||||
/* --- _PyInitError ----------------------------------------------- */
|
||||
|
||||
_PyInitError _PyInitError_Ok(void)
|
||||
{ return _Py_INIT_OK(); }
|
||||
|
||||
_PyInitError _PyInitError_Error(const char *err_msg)
|
||||
{
|
||||
return (_PyInitError){._type = _Py_INIT_ERR_TYPE_ERROR,
|
||||
.err_msg = err_msg};
|
||||
}
|
||||
|
||||
_PyInitError _PyInitError_NoMemory(void)
|
||||
{ return _PyInitError_Error("memory allocation failed"); }
|
||||
|
||||
_PyInitError _PyInitError_Exit(int exitcode)
|
||||
{ return _Py_INIT_EXIT(exitcode); }
|
||||
|
||||
|
||||
int _PyInitError_IsError(_PyInitError err)
|
||||
{ return _Py_INIT_IS_ERROR(err); }
|
||||
|
||||
int _PyInitError_IsExit(_PyInitError err)
|
||||
{ return _Py_INIT_IS_EXIT(err); }
|
||||
|
||||
int _PyInitError_Failed(_PyInitError err)
|
||||
{ return _Py_INIT_FAILED(err); }
|
||||
|
||||
|
||||
/* --- _PyWstrList ------------------------------------------------ */
|
||||
|
||||
#ifndef NDEBUG
|
||||
|
|
@ -492,7 +519,6 @@ _PyCoreConfig_Clear(_PyCoreConfig *config)
|
|||
CLEAR(config->module_search_path_env);
|
||||
CLEAR(config->home);
|
||||
CLEAR(config->program_name);
|
||||
CLEAR(config->program);
|
||||
|
||||
_PyWstrList_Clear(&config->argv);
|
||||
_PyWstrList_Clear(&config->warnoptions);
|
||||
|
|
@ -504,9 +530,6 @@ _PyCoreConfig_Clear(_PyCoreConfig *config)
|
|||
CLEAR(config->prefix);
|
||||
CLEAR(config->base_prefix);
|
||||
CLEAR(config->exec_prefix);
|
||||
#ifdef MS_WINDOWS
|
||||
CLEAR(config->dll_path);
|
||||
#endif
|
||||
CLEAR(config->base_exec_prefix);
|
||||
|
||||
CLEAR(config->filesystem_encoding);
|
||||
|
|
@ -521,10 +544,115 @@ _PyCoreConfig_Clear(_PyCoreConfig *config)
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
_PyCoreConfig_InitCompatConfig(_PyCoreConfig *config)
|
||||
{
|
||||
memset(config, 0, sizeof(*config));
|
||||
|
||||
config->_config_version = _Py_CONFIG_VERSION;
|
||||
config->_config_init = (int)_PyConfig_INIT_COMPAT;
|
||||
config->isolated = -1;
|
||||
config->use_environment = -1;
|
||||
config->dev_mode = -1;
|
||||
config->install_signal_handlers = 1;
|
||||
config->use_hash_seed = -1;
|
||||
config->faulthandler = -1;
|
||||
config->tracemalloc = -1;
|
||||
config->use_module_search_paths = 0;
|
||||
config->parse_argv = 0;
|
||||
config->site_import = -1;
|
||||
config->bytes_warning = -1;
|
||||
config->inspect = -1;
|
||||
config->interactive = -1;
|
||||
config->optimization_level = -1;
|
||||
config->parser_debug= -1;
|
||||
config->write_bytecode = -1;
|
||||
config->verbose = -1;
|
||||
config->quiet = -1;
|
||||
config->user_site_directory = -1;
|
||||
config->configure_c_stdio = 0;
|
||||
config->buffered_stdio = -1;
|
||||
config->_install_importlib = 1;
|
||||
config->check_hash_pycs_mode = NULL;
|
||||
config->pathconfig_warnings = -1;
|
||||
config->_init_main = 1;
|
||||
#ifdef MS_WINDOWS
|
||||
config->legacy_windows_stdio = -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
_PyCoreConfig_InitDefaults(_PyCoreConfig *config)
|
||||
{
|
||||
_PyCoreConfig_InitCompatConfig(config);
|
||||
|
||||
config->isolated = 0;
|
||||
config->use_environment = 1;
|
||||
config->site_import = 1;
|
||||
config->bytes_warning = 0;
|
||||
config->inspect = 0;
|
||||
config->interactive = 0;
|
||||
config->optimization_level = 0;
|
||||
config->parser_debug= 0;
|
||||
config->write_bytecode = 1;
|
||||
config->verbose = 0;
|
||||
config->quiet = 0;
|
||||
config->user_site_directory = 1;
|
||||
config->buffered_stdio = 1;
|
||||
config->pathconfig_warnings = 1;
|
||||
#ifdef MS_WINDOWS
|
||||
config->legacy_windows_stdio = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
_PyInitError
|
||||
_PyCoreConfig_InitPythonConfig(_PyCoreConfig *config)
|
||||
{
|
||||
_PyCoreConfig_InitDefaults(config);
|
||||
|
||||
config->_config_init = (int)_PyConfig_INIT_PYTHON;
|
||||
config->configure_c_stdio = 1;
|
||||
config->parse_argv = 1;
|
||||
|
||||
return _Py_INIT_OK();
|
||||
}
|
||||
|
||||
|
||||
_PyInitError
|
||||
_PyCoreConfig_InitIsolatedConfig(_PyCoreConfig *config)
|
||||
{
|
||||
_PyCoreConfig_InitDefaults(config);
|
||||
|
||||
config->_config_init = (int)_PyConfig_INIT_ISOLATED;
|
||||
config->isolated = 1;
|
||||
config->use_environment = 0;
|
||||
config->user_site_directory = 0;
|
||||
config->dev_mode = 0;
|
||||
config->install_signal_handlers = 0;
|
||||
config->use_hash_seed = 0;
|
||||
config->faulthandler = 0;
|
||||
config->tracemalloc = 0;
|
||||
config->pathconfig_warnings = 0;
|
||||
#ifdef MS_WINDOWS
|
||||
config->legacy_windows_stdio = 0;
|
||||
#endif
|
||||
|
||||
return _Py_INIT_OK();
|
||||
}
|
||||
|
||||
|
||||
/* Copy str into *config_str (duplicate the string) */
|
||||
_PyInitError
|
||||
_PyCoreConfig_SetString(wchar_t **config_str, const wchar_t *str)
|
||||
_PyCoreConfig_SetString(_PyCoreConfig *config, wchar_t **config_str,
|
||||
const wchar_t *str)
|
||||
{
|
||||
_PyInitError err = _Py_PreInitializeFromCoreConfig(config, NULL);
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
return err;
|
||||
}
|
||||
|
||||
wchar_t *str2;
|
||||
if (str != NULL) {
|
||||
str2 = _PyMem_RawWcsdup(str);
|
||||
|
|
@ -542,10 +670,10 @@ _PyCoreConfig_SetString(wchar_t **config_str, const wchar_t *str)
|
|||
|
||||
|
||||
static _PyInitError
|
||||
_PyCoreConfig_DecodeLocaleErr(wchar_t **config_str, const char *str,
|
||||
const char *decode_err_msg)
|
||||
_PyCoreConfig_DecodeLocaleErr(_PyCoreConfig *config, wchar_t **config_str,
|
||||
const char *str, const char *decode_err_msg)
|
||||
{
|
||||
_PyInitError err = _Py_PreInitialize(NULL);
|
||||
_PyInitError err = _Py_PreInitializeFromCoreConfig(config, NULL);
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
return err;
|
||||
}
|
||||
|
|
@ -572,17 +700,18 @@ _PyCoreConfig_DecodeLocaleErr(wchar_t **config_str, const char *str,
|
|||
}
|
||||
|
||||
|
||||
#define CONFIG_DECODE_LOCALE(config_str, str, NAME) \
|
||||
_PyCoreConfig_DecodeLocaleErr(config_str, str, "cannot decode " NAME)
|
||||
#define CONFIG_DECODE_LOCALE(config, config_str, str, NAME) \
|
||||
_PyCoreConfig_DecodeLocaleErr(config, config_str, str, "cannot decode " NAME)
|
||||
|
||||
|
||||
/* Decode str using Py_DecodeLocale() and set the result into *config_str.
|
||||
Pre-initialize Python if needed to ensure that encodings are properly
|
||||
configured. */
|
||||
_PyInitError
|
||||
_PyCoreConfig_DecodeLocale(wchar_t **config_str, const char *str)
|
||||
_PyCoreConfig_DecodeLocale(_PyCoreConfig *config, wchar_t **config_str,
|
||||
const char *str)
|
||||
{
|
||||
return CONFIG_DECODE_LOCALE(config_str, str, "string");
|
||||
return CONFIG_DECODE_LOCALE(config, config_str, str, "string");
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -595,7 +724,7 @@ _PyCoreConfig_Copy(_PyCoreConfig *config, const _PyCoreConfig *config2)
|
|||
#define COPY_ATTR(ATTR) config->ATTR = config2->ATTR
|
||||
#define COPY_WSTR_ATTR(ATTR) \
|
||||
do { \
|
||||
err = _PyCoreConfig_SetString(&config->ATTR, config2->ATTR); \
|
||||
err = _PyCoreConfig_SetString(config, &config->ATTR, config2->ATTR); \
|
||||
if (_Py_INIT_FAILED(err)) { \
|
||||
return err; \
|
||||
} \
|
||||
|
|
@ -607,6 +736,7 @@ _PyCoreConfig_Copy(_PyCoreConfig *config, const _PyCoreConfig *config2)
|
|||
} \
|
||||
} while (0)
|
||||
|
||||
COPY_ATTR(_config_init);
|
||||
COPY_ATTR(isolated);
|
||||
COPY_ATTR(use_environment);
|
||||
COPY_ATTR(dev_mode);
|
||||
|
|
@ -626,8 +756,8 @@ _PyCoreConfig_Copy(_PyCoreConfig *config, const _PyCoreConfig *config2)
|
|||
COPY_WSTR_ATTR(module_search_path_env);
|
||||
COPY_WSTR_ATTR(home);
|
||||
COPY_WSTR_ATTR(program_name);
|
||||
COPY_WSTR_ATTR(program);
|
||||
|
||||
COPY_ATTR(parse_argv);
|
||||
COPY_WSTRLIST(argv);
|
||||
COPY_WSTRLIST(warnoptions);
|
||||
COPY_WSTRLIST(xoptions);
|
||||
|
|
@ -638,9 +768,6 @@ _PyCoreConfig_Copy(_PyCoreConfig *config, const _PyCoreConfig *config2)
|
|||
COPY_WSTR_ATTR(prefix);
|
||||
COPY_WSTR_ATTR(base_prefix);
|
||||
COPY_WSTR_ATTR(exec_prefix);
|
||||
#ifdef MS_WINDOWS
|
||||
COPY_WSTR_ATTR(dll_path);
|
||||
#endif
|
||||
COPY_WSTR_ATTR(base_exec_prefix);
|
||||
|
||||
COPY_ATTR(site_import);
|
||||
|
|
@ -653,6 +780,7 @@ _PyCoreConfig_Copy(_PyCoreConfig *config, const _PyCoreConfig *config2)
|
|||
COPY_ATTR(verbose);
|
||||
COPY_ATTR(quiet);
|
||||
COPY_ATTR(user_site_directory);
|
||||
COPY_ATTR(configure_c_stdio);
|
||||
COPY_ATTR(buffered_stdio);
|
||||
COPY_WSTR_ATTR(filesystem_encoding);
|
||||
COPY_WSTR_ATTR(filesystem_errors);
|
||||
|
|
@ -666,7 +794,8 @@ _PyCoreConfig_Copy(_PyCoreConfig *config, const _PyCoreConfig *config2)
|
|||
COPY_WSTR_ATTR(run_module);
|
||||
COPY_WSTR_ATTR(run_filename);
|
||||
COPY_WSTR_ATTR(check_hash_pycs_mode);
|
||||
COPY_ATTR(_frozen);
|
||||
COPY_ATTR(pathconfig_warnings);
|
||||
COPY_ATTR(_init_main);
|
||||
|
||||
#undef COPY_ATTR
|
||||
#undef COPY_WSTR_ATTR
|
||||
|
|
@ -710,6 +839,7 @@ _PyCoreConfig_AsDict(const _PyCoreConfig *config)
|
|||
#define SET_ITEM_WSTRLIST(LIST) \
|
||||
SET_ITEM(#LIST, _PyWstrList_AsList(&config->LIST))
|
||||
|
||||
SET_ITEM_INT(_config_init);
|
||||
SET_ITEM_INT(isolated);
|
||||
SET_ITEM_INT(use_environment);
|
||||
SET_ITEM_INT(dev_mode);
|
||||
|
|
@ -727,8 +857,8 @@ _PyCoreConfig_AsDict(const _PyCoreConfig *config)
|
|||
SET_ITEM_WSTR(filesystem_errors);
|
||||
SET_ITEM_WSTR(pycache_prefix);
|
||||
SET_ITEM_WSTR(program_name);
|
||||
SET_ITEM_INT(parse_argv);
|
||||
SET_ITEM_WSTRLIST(argv);
|
||||
SET_ITEM_WSTR(program);
|
||||
SET_ITEM_WSTRLIST(xoptions);
|
||||
SET_ITEM_WSTRLIST(warnoptions);
|
||||
SET_ITEM_WSTR(module_search_path_env);
|
||||
|
|
@ -739,9 +869,6 @@ _PyCoreConfig_AsDict(const _PyCoreConfig *config)
|
|||
SET_ITEM_WSTR(base_prefix);
|
||||
SET_ITEM_WSTR(exec_prefix);
|
||||
SET_ITEM_WSTR(base_exec_prefix);
|
||||
#ifdef MS_WINDOWS
|
||||
SET_ITEM_WSTR(dll_path);
|
||||
#endif
|
||||
SET_ITEM_INT(site_import);
|
||||
SET_ITEM_INT(bytes_warning);
|
||||
SET_ITEM_INT(inspect);
|
||||
|
|
@ -752,6 +879,7 @@ _PyCoreConfig_AsDict(const _PyCoreConfig *config)
|
|||
SET_ITEM_INT(verbose);
|
||||
SET_ITEM_INT(quiet);
|
||||
SET_ITEM_INT(user_site_directory);
|
||||
SET_ITEM_INT(configure_c_stdio);
|
||||
SET_ITEM_INT(buffered_stdio);
|
||||
SET_ITEM_WSTR(stdio_encoding);
|
||||
SET_ITEM_WSTR(stdio_errors);
|
||||
|
|
@ -764,7 +892,8 @@ _PyCoreConfig_AsDict(const _PyCoreConfig *config)
|
|||
SET_ITEM_WSTR(run_filename);
|
||||
SET_ITEM_INT(_install_importlib);
|
||||
SET_ITEM_WSTR(check_hash_pycs_mode);
|
||||
SET_ITEM_INT(_frozen);
|
||||
SET_ITEM_INT(pathconfig_warnings);
|
||||
SET_ITEM_INT(_init_main);
|
||||
|
||||
return dict;
|
||||
|
||||
|
|
@ -792,7 +921,7 @@ _PyCoreConfig_GetEnv(const _PyCoreConfig *config, const char *name)
|
|||
Return 0 on success, but *dest can be NULL.
|
||||
Return -1 on memory allocation failure. Return -2 on decoding error. */
|
||||
static _PyInitError
|
||||
_PyCoreConfig_GetEnvDup(const _PyCoreConfig *config,
|
||||
_PyCoreConfig_GetEnvDup(_PyCoreConfig *config,
|
||||
wchar_t **dest,
|
||||
wchar_t *wname, char *name,
|
||||
const char *decode_err_msg)
|
||||
|
|
@ -812,7 +941,7 @@ _PyCoreConfig_GetEnvDup(const _PyCoreConfig *config,
|
|||
return _Py_INIT_OK();
|
||||
}
|
||||
|
||||
return _PyCoreConfig_SetString(dest, var);
|
||||
return _PyCoreConfig_SetString(config, dest, var);
|
||||
#else
|
||||
const char *var = getenv(name);
|
||||
if (!var || var[0] == '\0') {
|
||||
|
|
@ -820,7 +949,7 @@ _PyCoreConfig_GetEnvDup(const _PyCoreConfig *config,
|
|||
return _Py_INIT_OK();
|
||||
}
|
||||
|
||||
return _PyCoreConfig_DecodeLocaleErr(dest, var, decode_err_msg);
|
||||
return _PyCoreConfig_DecodeLocaleErr(config, dest, var, decode_err_msg);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -832,6 +961,11 @@ _PyCoreConfig_GetEnvDup(const _PyCoreConfig *config,
|
|||
static void
|
||||
_PyCoreConfig_GetGlobalConfig(_PyCoreConfig *config)
|
||||
{
|
||||
if (config->_config_init != _PyConfig_INIT_COMPAT) {
|
||||
/* Python and Isolated configuration ignore global variables */
|
||||
return;
|
||||
}
|
||||
|
||||
#define COPY_FLAG(ATTR, VALUE) \
|
||||
if (config->ATTR == -1) { \
|
||||
config->ATTR = VALUE; \
|
||||
|
|
@ -853,7 +987,7 @@ _PyCoreConfig_GetGlobalConfig(_PyCoreConfig *config)
|
|||
#ifdef MS_WINDOWS
|
||||
COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
|
||||
#endif
|
||||
COPY_FLAG(_frozen, Py_FrozenFlag);
|
||||
COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
|
||||
|
||||
COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
|
||||
COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
|
||||
|
|
@ -890,7 +1024,7 @@ _PyCoreConfig_SetGlobalConfig(const _PyCoreConfig *config)
|
|||
#ifdef MS_WINDOWS
|
||||
COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
|
||||
#endif
|
||||
COPY_FLAG(_frozen, Py_FrozenFlag);
|
||||
COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
|
||||
|
||||
COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
|
||||
COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
|
||||
|
|
@ -912,7 +1046,6 @@ static _PyInitError
|
|||
config_init_program_name(_PyCoreConfig *config)
|
||||
{
|
||||
_PyInitError err;
|
||||
assert(config->program_name == NULL);
|
||||
|
||||
/* If Py_SetProgramName() was called, use its value */
|
||||
const wchar_t *program_name = _Py_path_config.program_name;
|
||||
|
|
@ -936,7 +1069,7 @@ config_init_program_name(_PyCoreConfig *config)
|
|||
script. */
|
||||
const char *p = _PyCoreConfig_GetEnv(config, "PYTHONEXECUTABLE");
|
||||
if (p != NULL) {
|
||||
err = CONFIG_DECODE_LOCALE(&config->program_name, p,
|
||||
err = CONFIG_DECODE_LOCALE(config, &config->program_name, p,
|
||||
"PYTHONEXECUTABLE environment variable");
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
return err;
|
||||
|
|
@ -950,7 +1083,8 @@ config_init_program_name(_PyCoreConfig *config)
|
|||
/* Used by Mac/Tools/pythonw.c to forward
|
||||
* the argv0 of the stub executable
|
||||
*/
|
||||
err = CONFIG_DECODE_LOCALE(&config->program_name, pyvenv_launcher,
|
||||
err = CONFIG_DECODE_LOCALE(config,
|
||||
&config->program_name, pyvenv_launcher,
|
||||
"__PYVENV_LAUNCHER__ environment variable");
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
return err;
|
||||
|
|
@ -961,22 +1095,24 @@ config_init_program_name(_PyCoreConfig *config)
|
|||
#endif /* WITH_NEXT_FRAMEWORK */
|
||||
#endif /* __APPLE__ */
|
||||
|
||||
/* Use argv[0] by default, if available */
|
||||
if (config->program != NULL) {
|
||||
err = _PyCoreConfig_SetString(&config->program_name, config->program);
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
return err;
|
||||
/* Use argv[0] if available and non-empty */
|
||||
const _PyWstrList *argv = &config->argv;
|
||||
if (argv->length >= 1 && argv->items[0][0] != L'\0') {
|
||||
config->program_name = _PyMem_RawWcsdup(argv->items[0]);
|
||||
if (config->program_name == NULL) {
|
||||
return _Py_INIT_NO_MEMORY();
|
||||
}
|
||||
return _Py_INIT_OK();
|
||||
}
|
||||
|
||||
/* Last fall back: hardcoded string */
|
||||
/* Last fall back: hardcoded name */
|
||||
#ifdef MS_WINDOWS
|
||||
const wchar_t *default_program_name = L"python";
|
||||
#else
|
||||
const wchar_t *default_program_name = L"python3";
|
||||
#endif
|
||||
err = _PyCoreConfig_SetString(&config->program_name, default_program_name);
|
||||
err = _PyCoreConfig_SetString(config, &config->program_name,
|
||||
default_program_name);
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
return err;
|
||||
}
|
||||
|
|
@ -991,7 +1127,8 @@ config_init_executable(_PyCoreConfig *config)
|
|||
/* If Py_SetProgramFullPath() was called, use its value */
|
||||
const wchar_t *program_full_path = _Py_path_config.program_full_path;
|
||||
if (program_full_path != NULL) {
|
||||
_PyInitError err = _PyCoreConfig_SetString(&config->executable,
|
||||
_PyInitError err = _PyCoreConfig_SetString(config,
|
||||
&config->executable,
|
||||
program_full_path);
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
return err;
|
||||
|
|
@ -1017,7 +1154,7 @@ config_init_home(_PyCoreConfig *config)
|
|||
/* If Py_SetPythonHome() was called, use its value */
|
||||
wchar_t *home = _Py_path_config.home;
|
||||
if (home) {
|
||||
_PyInitError err = _PyCoreConfig_SetString(&config->home, home);
|
||||
_PyInitError err = _PyCoreConfig_SetString(config, &config->home, home);
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
return err;
|
||||
}
|
||||
|
|
@ -1274,14 +1411,14 @@ config_get_stdio_errors(const _PyCoreConfig *config)
|
|||
|
||||
|
||||
static _PyInitError
|
||||
config_get_locale_encoding(wchar_t **locale_encoding)
|
||||
config_get_locale_encoding(_PyCoreConfig *config, wchar_t **locale_encoding)
|
||||
{
|
||||
#ifdef MS_WINDOWS
|
||||
char encoding[20];
|
||||
PyOS_snprintf(encoding, sizeof(encoding), "cp%u", GetACP());
|
||||
return _PyCoreConfig_DecodeLocale(locale_encoding, encoding);
|
||||
return _PyCoreConfig_DecodeLocale(config, locale_encoding, encoding);
|
||||
#elif defined(_Py_FORCE_UTF8_LOCALE)
|
||||
return _PyCoreConfig_SetString(locale_encoding, L"utf-8");
|
||||
return _PyCoreConfig_SetString(config, locale_encoding, L"utf-8");
|
||||
#else
|
||||
const char *encoding = nl_langinfo(CODESET);
|
||||
if (!encoding || encoding[0] == '\0') {
|
||||
|
|
@ -1289,7 +1426,8 @@ config_get_locale_encoding(wchar_t **locale_encoding)
|
|||
"nl_langinfo(CODESET) failed");
|
||||
}
|
||||
/* nl_langinfo(CODESET) is decoded by Py_DecodeLocale() */
|
||||
return CONFIG_DECODE_LOCALE(locale_encoding, encoding,
|
||||
return CONFIG_DECODE_LOCALE(config,
|
||||
locale_encoding, encoding,
|
||||
"nl_langinfo(CODESET)");
|
||||
#endif
|
||||
}
|
||||
|
|
@ -1304,7 +1442,7 @@ config_init_stdio_encoding(_PyCoreConfig *config,
|
|||
/* If Py_SetStandardStreamEncoding() have been called, use these
|
||||
parameters. */
|
||||
if (config->stdio_encoding == NULL && _Py_StandardStreamEncoding != NULL) {
|
||||
err = CONFIG_DECODE_LOCALE(&config->stdio_encoding,
|
||||
err = CONFIG_DECODE_LOCALE(config, &config->stdio_encoding,
|
||||
_Py_StandardStreamEncoding,
|
||||
"_Py_StandardStreamEncoding");
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
|
|
@ -1313,7 +1451,7 @@ config_init_stdio_encoding(_PyCoreConfig *config,
|
|||
}
|
||||
|
||||
if (config->stdio_errors == NULL && _Py_StandardStreamErrors != NULL) {
|
||||
err = CONFIG_DECODE_LOCALE(&config->stdio_errors,
|
||||
err = CONFIG_DECODE_LOCALE(config, &config->stdio_errors,
|
||||
_Py_StandardStreamErrors,
|
||||
"_Py_StandardStreamErrors");
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
|
|
@ -1345,7 +1483,7 @@ config_init_stdio_encoding(_PyCoreConfig *config,
|
|||
/* Does PYTHONIOENCODING contain an encoding? */
|
||||
if (pythonioencoding[0]) {
|
||||
if (config->stdio_encoding == NULL) {
|
||||
err = CONFIG_DECODE_LOCALE(&config->stdio_encoding,
|
||||
err = CONFIG_DECODE_LOCALE(config, &config->stdio_encoding,
|
||||
pythonioencoding,
|
||||
"PYTHONIOENCODING environment variable");
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
|
|
@ -1364,7 +1502,7 @@ config_init_stdio_encoding(_PyCoreConfig *config,
|
|||
}
|
||||
|
||||
if (config->stdio_errors == NULL && errors != NULL) {
|
||||
err = CONFIG_DECODE_LOCALE(&config->stdio_errors,
|
||||
err = CONFIG_DECODE_LOCALE(config, &config->stdio_errors,
|
||||
errors,
|
||||
"PYTHONIOENCODING environment variable");
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
|
|
@ -1379,13 +1517,13 @@ config_init_stdio_encoding(_PyCoreConfig *config,
|
|||
/* UTF-8 Mode uses UTF-8/surrogateescape */
|
||||
if (preconfig->utf8_mode) {
|
||||
if (config->stdio_encoding == NULL) {
|
||||
err = _PyCoreConfig_SetString(&config->stdio_encoding, L"utf-8");
|
||||
err = _PyCoreConfig_SetString(config, &config->stdio_encoding, L"utf-8");
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
if (config->stdio_errors == NULL) {
|
||||
err = _PyCoreConfig_SetString(&config->stdio_errors,
|
||||
err = _PyCoreConfig_SetString(config, &config->stdio_errors,
|
||||
L"surrogateescape");
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
return err;
|
||||
|
|
@ -1395,7 +1533,7 @@ config_init_stdio_encoding(_PyCoreConfig *config,
|
|||
|
||||
/* Choose the default error handler based on the current locale. */
|
||||
if (config->stdio_encoding == NULL) {
|
||||
err = config_get_locale_encoding(&config->stdio_encoding);
|
||||
err = config_get_locale_encoding(config, &config->stdio_encoding);
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
return err;
|
||||
}
|
||||
|
|
@ -1404,7 +1542,7 @@ config_init_stdio_encoding(_PyCoreConfig *config,
|
|||
const wchar_t *errors = config_get_stdio_errors(config);
|
||||
assert(errors != NULL);
|
||||
|
||||
err = _PyCoreConfig_SetString(&config->stdio_errors, errors);
|
||||
err = _PyCoreConfig_SetString(config, &config->stdio_errors, errors);
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
return err;
|
||||
}
|
||||
|
|
@ -1421,34 +1559,35 @@ config_init_fs_encoding(_PyCoreConfig *config, const _PyPreConfig *preconfig)
|
|||
|
||||
if (config->filesystem_encoding == NULL) {
|
||||
#ifdef _Py_FORCE_UTF8_FS_ENCODING
|
||||
err = _PyCoreConfig_SetString(&config->filesystem_encoding, L"utf-8");
|
||||
err = _PyCoreConfig_SetString(config, &config->filesystem_encoding, L"utf-8");
|
||||
#else
|
||||
|
||||
#ifdef MS_WINDOWS
|
||||
if (preconfig->legacy_windows_fs_encoding) {
|
||||
/* Legacy Windows filesystem encoding: mbcs/replace */
|
||||
err = _PyCoreConfig_SetString(&config->filesystem_encoding,
|
||||
err = _PyCoreConfig_SetString(config, &config->filesystem_encoding,
|
||||
L"mbcs");
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (preconfig->utf8_mode) {
|
||||
err = _PyCoreConfig_SetString(&config->filesystem_encoding,
|
||||
err = _PyCoreConfig_SetString(config, &config->filesystem_encoding,
|
||||
L"utf-8");
|
||||
}
|
||||
#ifndef MS_WINDOWS
|
||||
else if (_Py_GetForceASCII()) {
|
||||
err = _PyCoreConfig_SetString(&config->filesystem_encoding,
|
||||
err = _PyCoreConfig_SetString(config, &config->filesystem_encoding,
|
||||
L"ascii");
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
#ifdef MS_WINDOWS
|
||||
/* Windows defaults to utf-8/surrogatepass (PEP 529). */
|
||||
err = _PyCoreConfig_SetString(&config->filesystem_encoding,
|
||||
err = _PyCoreConfig_SetString(config, &config->filesystem_encoding,
|
||||
L"utf-8");
|
||||
#else
|
||||
err = config_get_locale_encoding(&config->filesystem_encoding);
|
||||
err = config_get_locale_encoding(config,
|
||||
&config->filesystem_encoding);
|
||||
#endif
|
||||
}
|
||||
#endif /* !_Py_FORCE_UTF8_FS_ENCODING */
|
||||
|
|
@ -1470,7 +1609,7 @@ config_init_fs_encoding(_PyCoreConfig *config, const _PyPreConfig *preconfig)
|
|||
#else
|
||||
errors = L"surrogateescape";
|
||||
#endif
|
||||
err = _PyCoreConfig_SetString(&config->filesystem_errors, errors);
|
||||
err = _PyCoreConfig_SetString(config, &config->filesystem_errors, errors);
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
return err;
|
||||
}
|
||||
|
|
@ -1480,19 +1619,11 @@ config_init_fs_encoding(_PyCoreConfig *config, const _PyPreConfig *preconfig)
|
|||
|
||||
|
||||
static _PyInitError
|
||||
config_read(_PyCoreConfig *config, _PyPreCmdline *cmdline)
|
||||
config_read(_PyCoreConfig *config)
|
||||
{
|
||||
_PyInitError err;
|
||||
const _PyPreConfig *preconfig = &_PyRuntime.preconfig;
|
||||
|
||||
if (_PyPreCmdline_SetCoreConfig(cmdline, config) < 0) {
|
||||
return _Py_INIT_NO_MEMORY();
|
||||
}
|
||||
|
||||
if (config->isolated > 0) {
|
||||
config->user_site_directory = 0;
|
||||
}
|
||||
|
||||
if (config->use_environment) {
|
||||
err = config_read_env_vars(config);
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
|
|
@ -1520,13 +1651,6 @@ config_read(_PyCoreConfig *config, _PyPreCmdline *cmdline)
|
|||
}
|
||||
}
|
||||
|
||||
if (config->program_name == NULL) {
|
||||
err = config_init_program_name(config);
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
if (config->executable == NULL) {
|
||||
err = config_init_executable(config);
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
|
|
@ -1577,6 +1701,18 @@ config_read(_PyCoreConfig *config, _PyPreCmdline *cmdline)
|
|||
}
|
||||
}
|
||||
|
||||
if (config->check_hash_pycs_mode == NULL) {
|
||||
err = _PyCoreConfig_SetString(config, &config->check_hash_pycs_mode,
|
||||
L"default");
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
if (config->configure_c_stdio < 0) {
|
||||
config->configure_c_stdio = 1;
|
||||
}
|
||||
|
||||
return _Py_INIT_OK();
|
||||
}
|
||||
|
||||
|
|
@ -1626,7 +1762,10 @@ void
|
|||
_PyCoreConfig_Write(const _PyCoreConfig *config, _PyRuntimeState *runtime)
|
||||
{
|
||||
_PyCoreConfig_SetGlobalConfig(config);
|
||||
config_init_stdio(config);
|
||||
|
||||
if (config->configure_c_stdio) {
|
||||
config_init_stdio(config);
|
||||
}
|
||||
|
||||
/* Write the new pre-configuration into _PyRuntime */
|
||||
_PyPreConfig *preconfig = &runtime->preconfig;
|
||||
|
|
@ -1659,12 +1798,13 @@ config_usage(int error, const wchar_t* program)
|
|||
|
||||
/* Parse the command line arguments */
|
||||
static _PyInitError
|
||||
config_parse_cmdline(_PyCoreConfig *config, _PyPreCmdline *precmdline,
|
||||
_PyWstrList *warnoptions)
|
||||
config_parse_cmdline(_PyCoreConfig *config, _PyWstrList *warnoptions,
|
||||
Py_ssize_t *opt_index)
|
||||
{
|
||||
_PyInitError err;
|
||||
const _PyWstrList *argv = &precmdline->argv;
|
||||
const _PyWstrList *argv = &config->argv;
|
||||
int print_version = 0;
|
||||
const wchar_t* program = config->program_name;
|
||||
|
||||
_PyOS_ResetGetOpt();
|
||||
do {
|
||||
|
|
@ -1713,7 +1853,7 @@ config_parse_cmdline(_PyCoreConfig *config, _PyPreCmdline *precmdline,
|
|||
|| wcscmp(_PyOS_optarg, L"never") == 0
|
||||
|| wcscmp(_PyOS_optarg, L"default") == 0)
|
||||
{
|
||||
err = _PyCoreConfig_SetString(&config->check_hash_pycs_mode,
|
||||
err = _PyCoreConfig_SetString(config, &config->check_hash_pycs_mode,
|
||||
_PyOS_optarg);
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
return err;
|
||||
|
|
@ -1721,7 +1861,7 @@ config_parse_cmdline(_PyCoreConfig *config, _PyPreCmdline *precmdline,
|
|||
} else {
|
||||
fprintf(stderr, "--check-hash-based-pycs must be one of "
|
||||
"'default', 'always', or 'never'\n");
|
||||
config_usage(1, config->program);
|
||||
config_usage(1, program);
|
||||
return _Py_INIT_EXIT(2);
|
||||
}
|
||||
break;
|
||||
|
|
@ -1781,7 +1921,7 @@ config_parse_cmdline(_PyCoreConfig *config, _PyPreCmdline *precmdline,
|
|||
|
||||
case 'h':
|
||||
case '?':
|
||||
config_usage(0, config->program);
|
||||
config_usage(0, program);
|
||||
return _Py_INIT_EXIT(0);
|
||||
|
||||
case 'V':
|
||||
|
|
@ -1806,7 +1946,7 @@ config_parse_cmdline(_PyCoreConfig *config, _PyPreCmdline *precmdline,
|
|||
|
||||
default:
|
||||
/* unknown argument: parsing failed */
|
||||
config_usage(1, config->program);
|
||||
config_usage(1, program);
|
||||
return _Py_INIT_EXIT(2);
|
||||
}
|
||||
} while (1);
|
||||
|
|
@ -1833,8 +1973,7 @@ config_parse_cmdline(_PyCoreConfig *config, _PyPreCmdline *precmdline,
|
|||
_PyOS_optind--;
|
||||
}
|
||||
|
||||
/* -c and -m options are exclusive */
|
||||
assert(!(config->run_command != NULL && config->run_module != NULL));
|
||||
*opt_index = _PyOS_optind;
|
||||
|
||||
return _Py_INIT_OK();
|
||||
}
|
||||
|
|
@ -1848,7 +1987,7 @@ config_parse_cmdline(_PyCoreConfig *config, _PyPreCmdline *precmdline,
|
|||
|
||||
/* Get warning options from PYTHONWARNINGS environment variable. */
|
||||
static _PyInitError
|
||||
config_init_env_warnoptions(const _PyCoreConfig *config, _PyWstrList *warnoptions)
|
||||
config_init_env_warnoptions(_PyCoreConfig *config, _PyWstrList *warnoptions)
|
||||
{
|
||||
_PyInitError err;
|
||||
/* CONFIG_GET_ENV_DUP requires dest to be initialized to NULL */
|
||||
|
|
@ -1880,26 +2019,6 @@ config_init_env_warnoptions(const _PyCoreConfig *config, _PyWstrList *warnoption
|
|||
}
|
||||
|
||||
|
||||
static _PyInitError
|
||||
config_init_program(_PyCoreConfig *config, const _PyPreCmdline *cmdline)
|
||||
{
|
||||
const _PyWstrList *argv = &cmdline->argv;
|
||||
wchar_t *program;
|
||||
if (argv->length >= 1) {
|
||||
program = argv->items[0];
|
||||
}
|
||||
else {
|
||||
program = L"";
|
||||
}
|
||||
config->program = _PyMem_RawWcsdup(program);
|
||||
if (config->program == NULL) {
|
||||
return _Py_INIT_NO_MEMORY();
|
||||
}
|
||||
|
||||
return _Py_INIT_OK();
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
config_add_warnoption(_PyCoreConfig *config, const wchar_t *option)
|
||||
{
|
||||
|
|
@ -1978,13 +2097,13 @@ config_init_warnoptions(_PyCoreConfig *config,
|
|||
|
||||
|
||||
static _PyInitError
|
||||
config_init_argv(_PyCoreConfig *config, const _PyPreCmdline *cmdline)
|
||||
config_update_argv(_PyCoreConfig *config, Py_ssize_t opt_index)
|
||||
{
|
||||
const _PyWstrList *cmdline_argv = &cmdline->argv;
|
||||
const _PyWstrList *cmdline_argv = &config->argv;
|
||||
_PyWstrList config_argv = _PyWstrList_INIT;
|
||||
|
||||
/* Copy argv to be able to modify it (to force -c/-m) */
|
||||
if (cmdline_argv->length <= _PyOS_optind) {
|
||||
if (cmdline_argv->length <= opt_index) {
|
||||
/* Ensure at least one (empty) argument is seen */
|
||||
if (_PyWstrList_Append(&config_argv, L"") < 0) {
|
||||
return _Py_INIT_NO_MEMORY();
|
||||
|
|
@ -1992,8 +2111,8 @@ config_init_argv(_PyCoreConfig *config, const _PyPreCmdline *cmdline)
|
|||
}
|
||||
else {
|
||||
_PyWstrList slice;
|
||||
slice.length = cmdline_argv->length - _PyOS_optind;
|
||||
slice.items = &cmdline_argv->items[_PyOS_optind];
|
||||
slice.length = cmdline_argv->length - opt_index;
|
||||
slice.items = &cmdline_argv->items[opt_index];
|
||||
if (_PyWstrList_Copy(&config_argv, &slice) < 0) {
|
||||
return _Py_INIT_NO_MEMORY();
|
||||
}
|
||||
|
|
@ -2031,46 +2150,60 @@ core_read_precmdline(_PyCoreConfig *config, _PyPreCmdline *precmdline)
|
|||
{
|
||||
_PyInitError err;
|
||||
|
||||
if (_PyWstrList_Copy(&precmdline->argv, &config->argv) < 0) {
|
||||
return _Py_INIT_NO_MEMORY();
|
||||
if (config->parse_argv) {
|
||||
if (_PyWstrList_Copy(&precmdline->argv, &config->argv) < 0) {
|
||||
return _Py_INIT_NO_MEMORY();
|
||||
}
|
||||
}
|
||||
|
||||
_PyPreConfig preconfig = _PyPreConfig_INIT;
|
||||
if (_PyPreConfig_Copy(&preconfig, &_PyRuntime.preconfig) < 0) {
|
||||
err = _Py_INIT_NO_MEMORY();
|
||||
goto done;
|
||||
}
|
||||
_PyPreConfig preconfig;
|
||||
_PyPreConfig_InitFromPreConfig(&preconfig, &_PyRuntime.preconfig);
|
||||
|
||||
_PyCoreConfig_GetCoreConfig(&preconfig, config);
|
||||
_PyPreConfig_GetCoreConfig(&preconfig, config);
|
||||
|
||||
err = _PyPreCmdline_Read(precmdline, &preconfig);
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
return err;
|
||||
}
|
||||
|
||||
done:
|
||||
_PyPreConfig_Clear(&preconfig);
|
||||
return err;
|
||||
if (_PyPreCmdline_SetCoreConfig(precmdline, config) < 0) {
|
||||
err = _Py_INIT_NO_MEMORY();
|
||||
return err;
|
||||
}
|
||||
|
||||
return _Py_INIT_OK();
|
||||
}
|
||||
|
||||
|
||||
static _PyInitError
|
||||
config_read_cmdline(_PyCoreConfig *config, _PyPreCmdline *precmdline)
|
||||
config_read_cmdline(_PyCoreConfig *config)
|
||||
{
|
||||
_PyInitError err;
|
||||
_PyWstrList cmdline_warnoptions = _PyWstrList_INIT;
|
||||
_PyWstrList env_warnoptions = _PyWstrList_INIT;
|
||||
|
||||
err = config_parse_cmdline(config, precmdline, &cmdline_warnoptions);
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
goto done;
|
||||
if (config->parse_argv < 0) {
|
||||
config->parse_argv = 1;
|
||||
}
|
||||
|
||||
err = config_init_argv(config, precmdline);
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
goto done;
|
||||
if (config->program_name == NULL) {
|
||||
err = config_init_program_name(config);
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
err = config_read(config, precmdline);
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
goto done;
|
||||
if (config->parse_argv) {
|
||||
Py_ssize_t opt_index;
|
||||
err = config_parse_cmdline(config, &cmdline_warnoptions, &opt_index);
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
err = config_update_argv(config, opt_index);
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
if (config->use_environment) {
|
||||
|
|
@ -2086,13 +2219,6 @@ config_read_cmdline(_PyCoreConfig *config, _PyPreCmdline *precmdline)
|
|||
goto done;
|
||||
}
|
||||
|
||||
if (config->check_hash_pycs_mode == NULL) {
|
||||
err = _PyCoreConfig_SetString(&config->check_hash_pycs_mode, L"default");
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
err = _Py_INIT_OK();
|
||||
|
||||
done:
|
||||
|
|
@ -2105,24 +2231,11 @@ config_read_cmdline(_PyCoreConfig *config, _PyPreCmdline *precmdline)
|
|||
_PyInitError
|
||||
_PyCoreConfig_SetPyArgv(_PyCoreConfig *config, const _PyArgv *args)
|
||||
{
|
||||
if (args->use_bytes_argv) {
|
||||
_PyInitError err;
|
||||
|
||||
err = _PyRuntime_Initialize();
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
return err;
|
||||
}
|
||||
_PyRuntimeState *runtime = &_PyRuntime;
|
||||
|
||||
/* do nothing if Python is already pre-initialized:
|
||||
_PyCoreConfig_Write() will update _PyRuntime.preconfig later */
|
||||
if (!runtime->pre_initialized) {
|
||||
err = _Py_PreInitializeFromCoreConfig(config, args);
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
_PyInitError err = _Py_PreInitializeFromCoreConfig(config, args);
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
return err;
|
||||
}
|
||||
|
||||
return _PyArgv_AsWstrList(args, &config->argv);
|
||||
}
|
||||
|
||||
|
|
@ -2130,7 +2243,7 @@ _PyCoreConfig_SetPyArgv(_PyCoreConfig *config, const _PyArgv *args)
|
|||
/* Set config.argv: decode argv using Py_DecodeLocale(). Pre-initialize Python
|
||||
if needed to ensure that encodings are properly configured. */
|
||||
_PyInitError
|
||||
_PyCoreConfig_SetArgv(_PyCoreConfig *config, int argc, char **argv)
|
||||
_PyCoreConfig_SetArgv(_PyCoreConfig *config, Py_ssize_t argc, char * const *argv)
|
||||
{
|
||||
_PyArgv args = {
|
||||
.argc = argc,
|
||||
|
|
@ -2142,7 +2255,7 @@ _PyCoreConfig_SetArgv(_PyCoreConfig *config, int argc, char **argv)
|
|||
|
||||
|
||||
_PyInitError
|
||||
_PyCoreConfig_SetWideArgv(_PyCoreConfig *config, int argc, wchar_t **argv)
|
||||
_PyCoreConfig_SetWideArgv(_PyCoreConfig *config, Py_ssize_t argc, wchar_t * const *argv)
|
||||
{
|
||||
_PyArgv args = {
|
||||
.argc = argc,
|
||||
|
|
@ -2157,11 +2270,14 @@ _PyCoreConfig_SetWideArgv(_PyCoreConfig *config, int argc, wchar_t **argv)
|
|||
|
||||
* Command line arguments
|
||||
* Environment variables
|
||||
* Py_xxx global configuration variables */
|
||||
* Py_xxx global configuration variables
|
||||
|
||||
The only side effects are to modify config and to call _Py_SetArgcArgv(). */
|
||||
_PyInitError
|
||||
_PyCoreConfig_Read(_PyCoreConfig *config)
|
||||
{
|
||||
_PyInitError err;
|
||||
_PyWstrList orig_argv = _PyWstrList_INIT;
|
||||
|
||||
err = _Py_PreInitializeFromCoreConfig(config, NULL);
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
|
|
@ -2170,26 +2286,33 @@ _PyCoreConfig_Read(_PyCoreConfig *config)
|
|||
|
||||
_PyCoreConfig_GetGlobalConfig(config);
|
||||
|
||||
if (_PyWstrList_Copy(&orig_argv, &config->argv) < 0) {
|
||||
return _Py_INIT_NO_MEMORY();
|
||||
}
|
||||
|
||||
_PyPreCmdline precmdline = _PyPreCmdline_INIT;
|
||||
err = core_read_precmdline(config, &precmdline);
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (config->program == NULL) {
|
||||
err = config_init_program(config, &precmdline);
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
goto done;
|
||||
}
|
||||
assert(config->isolated >= 0);
|
||||
if (config->isolated) {
|
||||
config->use_environment = 0;
|
||||
config->user_site_directory = 0;
|
||||
}
|
||||
|
||||
err = config_read_cmdline(config, &precmdline);
|
||||
err = config_read_cmdline(config);
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
const _PyWstrList *argv = &precmdline.argv;
|
||||
if (_Py_SetArgcArgv(argv->length, argv->items) < 0) {
|
||||
err = config_read(config);
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (_Py_SetArgcArgv(orig_argv.length, orig_argv.items) < 0) {
|
||||
err = _Py_INIT_NO_MEMORY();
|
||||
goto done;
|
||||
}
|
||||
|
|
@ -2212,22 +2335,24 @@ _PyCoreConfig_Read(_PyCoreConfig *config)
|
|||
assert(config->verbose >= 0);
|
||||
assert(config->quiet >= 0);
|
||||
assert(config->user_site_directory >= 0);
|
||||
assert(config->parse_argv >= 0);
|
||||
assert(config->configure_c_stdio >= 0);
|
||||
assert(config->buffered_stdio >= 0);
|
||||
assert(config->program_name != NULL);
|
||||
assert(config->program != NULL);
|
||||
assert(_PyWstrList_CheckConsistency(&config->argv));
|
||||
/* sys.argv must be non-empty: empty argv is replaced with [''] */
|
||||
assert(config->argv.length >= 1);
|
||||
assert(_PyWstrList_CheckConsistency(&config->xoptions));
|
||||
assert(_PyWstrList_CheckConsistency(&config->warnoptions));
|
||||
assert(_PyWstrList_CheckConsistency(&config->module_search_paths));
|
||||
if (config->_install_importlib) {
|
||||
assert(config->use_module_search_paths != 0);
|
||||
/* don't check config->module_search_paths */
|
||||
assert(config->executable != NULL);
|
||||
assert(config->prefix != NULL);
|
||||
assert(config->base_prefix != NULL);
|
||||
assert(config->exec_prefix != NULL);
|
||||
assert(config->base_exec_prefix != NULL);
|
||||
#ifdef MS_WINDOWS
|
||||
assert(config->dll_path != NULL);
|
||||
#endif
|
||||
}
|
||||
assert(config->filesystem_encoding != NULL);
|
||||
assert(config->filesystem_errors != NULL);
|
||||
|
|
@ -2236,13 +2361,16 @@ _PyCoreConfig_Read(_PyCoreConfig *config)
|
|||
#ifdef MS_WINDOWS
|
||||
assert(config->legacy_windows_stdio >= 0);
|
||||
#endif
|
||||
/* -c and -m options are exclusive */
|
||||
assert(!(config->run_command != NULL && config->run_module != NULL));
|
||||
assert(config->check_hash_pycs_mode != NULL);
|
||||
assert(config->_install_importlib >= 0);
|
||||
assert(config->_frozen >= 0);
|
||||
assert(config->pathconfig_warnings >= 0);
|
||||
|
||||
err = _Py_INIT_OK();
|
||||
|
||||
done:
|
||||
_PyWstrList_Clear(&orig_argv);
|
||||
_PyPreCmdline_Clear(&precmdline);
|
||||
return err;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,48 +19,47 @@ dl_funcptr _PyImport_FindSharedFuncptr(const char *prefix,
|
|||
const char *shortname,
|
||||
const char *pathname, FILE *fp)
|
||||
{
|
||||
dl_funcptr p;
|
||||
shl_t lib;
|
||||
int flags;
|
||||
char funcname[258];
|
||||
|
||||
flags = BIND_FIRST | BIND_DEFERRED;
|
||||
if (Py_VerboseFlag) {
|
||||
int flags = BIND_FIRST | BIND_DEFERRED;
|
||||
int verbose = _PyInterpreterState_GET_UNSAFE()->core_config.verbose;
|
||||
if (verbose) {
|
||||
flags = BIND_FIRST | BIND_IMMEDIATE |
|
||||
BIND_NONFATAL | BIND_VERBOSE;
|
||||
printf("shl_load %s\n",pathname);
|
||||
}
|
||||
lib = shl_load(pathname, flags, 0);
|
||||
|
||||
shl_t lib = shl_load(pathname, flags, 0);
|
||||
/* XXX Chuck Blake once wrote that 0 should be BIND_NOSTART? */
|
||||
if (lib == NULL) {
|
||||
char buf[256];
|
||||
PyObject *pathname_ob = NULL;
|
||||
PyObject *buf_ob = NULL;
|
||||
PyObject *shortname_ob = NULL;
|
||||
|
||||
if (Py_VerboseFlag)
|
||||
if (verbose) {
|
||||
perror(pathname);
|
||||
}
|
||||
char buf[256];
|
||||
PyOS_snprintf(buf, sizeof(buf), "Failed to load %.200s",
|
||||
pathname);
|
||||
buf_ob = PyUnicode_FromString(buf);
|
||||
shortname_ob = PyUnicode_FromString(shortname);
|
||||
pathname_ob = PyUnicode_FromString(pathname);
|
||||
PyObject *buf_ob = PyUnicode_FromString(buf);
|
||||
PyObject *shortname_ob = PyUnicode_FromString(shortname);
|
||||
PyObject *pathname_ob = PyUnicode_FromString(pathname);
|
||||
PyErr_SetImportError(buf_ob, shortname_ob, pathname_ob);
|
||||
Py_DECREF(buf_ob);
|
||||
Py_DECREF(shortname_ob);
|
||||
Py_DECREF(pathname_ob);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char funcname[258];
|
||||
PyOS_snprintf(funcname, sizeof(funcname), FUNCNAME_PATTERN,
|
||||
prefix, shortname);
|
||||
if (Py_VerboseFlag)
|
||||
if (verbose) {
|
||||
printf("shl_findsym %s\n", funcname);
|
||||
}
|
||||
|
||||
dl_funcptr p;
|
||||
if (shl_findsym(&lib, funcname, TYPE_UNDEFINED, (void *) &p) == -1) {
|
||||
shl_unload(lib);
|
||||
p = NULL;
|
||||
}
|
||||
if (p == NULL && Py_VerboseFlag)
|
||||
if (p == NULL && verbose) {
|
||||
perror(funcname);
|
||||
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
|
|
|||
662
Python/errors.c
662
Python/errors.c
File diff suppressed because it is too large
Load diff
|
|
@ -1262,6 +1262,10 @@ _Py_open_impl(const char *pathname, int flags, int gil_held)
|
|||
#endif
|
||||
|
||||
if (gil_held) {
|
||||
if (PySys_Audit("open", "sOi", pathname, Py_None, flags) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
do {
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
fd = open(pathname, flags);
|
||||
|
|
@ -1331,6 +1335,9 @@ FILE *
|
|||
_Py_wfopen(const wchar_t *path, const wchar_t *mode)
|
||||
{
|
||||
FILE *f;
|
||||
if (PySys_Audit("open", "uui", path, mode, 0) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
#ifndef MS_WINDOWS
|
||||
char *cpath;
|
||||
char cmode[10];
|
||||
|
|
@ -1366,6 +1373,10 @@ _Py_wfopen(const wchar_t *path, const wchar_t *mode)
|
|||
FILE*
|
||||
_Py_fopen(const char *pathname, const char *mode)
|
||||
{
|
||||
if (PySys_Audit("open", "ssi", pathname, mode, 0) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
FILE *f = fopen(pathname, mode);
|
||||
if (f == NULL)
|
||||
return NULL;
|
||||
|
|
@ -1401,6 +1412,9 @@ _Py_fopen_obj(PyObject *path, const char *mode)
|
|||
|
||||
assert(PyGILState_Check());
|
||||
|
||||
if (PySys_Audit("open", "Osi", path, mode, 0) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
if (!PyUnicode_Check(path)) {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"str file path expected under Windows, got %R",
|
||||
|
|
@ -1434,6 +1448,10 @@ _Py_fopen_obj(PyObject *path, const char *mode)
|
|||
return NULL;
|
||||
path_bytes = PyBytes_AS_STRING(bytes);
|
||||
|
||||
if (PySys_Audit("open", "Osi", path, mode, 0) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
do {
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
f = fopen(path_bytes, mode);
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ int
|
|||
Py_FrozenMain(int argc, char **argv)
|
||||
{
|
||||
_PyInitError err = _PyRuntime_Initialize();
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
if (_PyInitError_Failed(err)) {
|
||||
_Py_ExitInitError(err);
|
||||
}
|
||||
|
||||
|
|
@ -39,8 +39,13 @@ Py_FrozenMain(int argc, char **argv)
|
|||
}
|
||||
}
|
||||
|
||||
_PyCoreConfig config = _PyCoreConfig_INIT;
|
||||
config._frozen = 1; /* Suppress errors from getpath.c */
|
||||
_PyCoreConfig config;
|
||||
err = _PyCoreConfig_InitPythonConfig(&config);
|
||||
if (_PyInitError_Failed(err)) {
|
||||
_PyCoreConfig_Clear(&config);
|
||||
_Py_ExitInitError(err);
|
||||
}
|
||||
config.pathconfig_warnings = 0; /* Suppress errors from getpath.c */
|
||||
|
||||
if ((p = Py_GETENV("PYTHONINSPECT")) && *p != '\0')
|
||||
inspect = 1;
|
||||
|
|
@ -81,9 +86,8 @@ Py_FrozenMain(int argc, char **argv)
|
|||
Py_SetProgramName(argv_copy[0]);
|
||||
|
||||
err = _Py_InitializeFromConfig(&config);
|
||||
/* No need to call _PyCoreConfig_Clear() since we didn't allocate any
|
||||
memory: program_name is a constant string. */
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
_PyCoreConfig_Clear(&config);
|
||||
if (_PyInitError_Failed(err)) {
|
||||
_Py_ExitInitError(err);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ int _PyOS_opterr = 1; /* generate error messages */
|
|||
Py_ssize_t _PyOS_optind = 1; /* index into argv array */
|
||||
const wchar_t *_PyOS_optarg = NULL; /* optional argument */
|
||||
|
||||
static wchar_t *opt_ptr = L"";
|
||||
static const wchar_t *opt_ptr = L"";
|
||||
|
||||
/* Python command line short and long options */
|
||||
|
||||
|
|
@ -61,7 +61,7 @@ void _PyOS_ResetGetOpt(void)
|
|||
opt_ptr = L"";
|
||||
}
|
||||
|
||||
int _PyOS_GetOpt(Py_ssize_t argc, wchar_t **argv, int *longindex)
|
||||
int _PyOS_GetOpt(Py_ssize_t argc, wchar_t * const *argv, int *longindex)
|
||||
{
|
||||
wchar_t *ptr;
|
||||
wchar_t option;
|
||||
|
|
|
|||
|
|
@ -1176,7 +1176,7 @@ hamt_node_bitmap_dealloc(PyHamtNode_Bitmap *self)
|
|||
Py_ssize_t i;
|
||||
|
||||
PyObject_GC_UnTrack(self);
|
||||
Py_TRASHCAN_SAFE_BEGIN(self)
|
||||
Py_TRASHCAN_BEGIN(self, hamt_node_bitmap_dealloc)
|
||||
|
||||
if (len > 0) {
|
||||
i = len;
|
||||
|
|
@ -1186,7 +1186,7 @@ hamt_node_bitmap_dealloc(PyHamtNode_Bitmap *self)
|
|||
}
|
||||
|
||||
Py_TYPE(self)->tp_free((PyObject *)self);
|
||||
Py_TRASHCAN_SAFE_END(self)
|
||||
Py_TRASHCAN_END
|
||||
}
|
||||
|
||||
#ifdef Py_DEBUG
|
||||
|
|
@ -1584,7 +1584,7 @@ hamt_node_collision_dealloc(PyHamtNode_Collision *self)
|
|||
Py_ssize_t len = Py_SIZE(self);
|
||||
|
||||
PyObject_GC_UnTrack(self);
|
||||
Py_TRASHCAN_SAFE_BEGIN(self)
|
||||
Py_TRASHCAN_BEGIN(self, hamt_node_collision_dealloc)
|
||||
|
||||
if (len > 0) {
|
||||
|
||||
|
|
@ -1594,7 +1594,7 @@ hamt_node_collision_dealloc(PyHamtNode_Collision *self)
|
|||
}
|
||||
|
||||
Py_TYPE(self)->tp_free((PyObject *)self);
|
||||
Py_TRASHCAN_SAFE_END(self)
|
||||
Py_TRASHCAN_END
|
||||
}
|
||||
|
||||
#ifdef Py_DEBUG
|
||||
|
|
@ -1969,14 +1969,14 @@ hamt_node_array_dealloc(PyHamtNode_Array *self)
|
|||
Py_ssize_t i;
|
||||
|
||||
PyObject_GC_UnTrack(self);
|
||||
Py_TRASHCAN_SAFE_BEGIN(self)
|
||||
Py_TRASHCAN_BEGIN(self, hamt_node_array_dealloc)
|
||||
|
||||
for (i = 0; i < HAMT_ARRAY_NODE_SIZE; i++) {
|
||||
Py_XDECREF(self->a_array[i]);
|
||||
}
|
||||
|
||||
Py_TYPE(self)->tp_free((PyObject *)self);
|
||||
Py_TRASHCAN_SAFE_END(self)
|
||||
Py_TRASHCAN_END
|
||||
}
|
||||
|
||||
#ifdef Py_DEBUG
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ _PyImportHooks_Init(void)
|
|||
}
|
||||
|
||||
_PyInitError
|
||||
_PyImportZip_Init(void)
|
||||
_PyImportZip_Init(PyInterpreterState *interp)
|
||||
{
|
||||
PyObject *path_hooks, *zipimport;
|
||||
int err = 0;
|
||||
|
|
@ -102,14 +102,17 @@ _PyImportZip_Init(void)
|
|||
goto error;
|
||||
}
|
||||
|
||||
if (Py_VerboseFlag)
|
||||
int verbose = interp->core_config.verbose;
|
||||
if (verbose) {
|
||||
PySys_WriteStderr("# installing zipimport hook\n");
|
||||
}
|
||||
|
||||
zipimport = PyImport_ImportModule("zipimport");
|
||||
if (zipimport == NULL) {
|
||||
PyErr_Clear(); /* No zip import module -- okay */
|
||||
if (Py_VerboseFlag)
|
||||
if (verbose) {
|
||||
PySys_WriteStderr("# can't import zipimport\n");
|
||||
}
|
||||
}
|
||||
else {
|
||||
_Py_IDENTIFIER(zipimporter);
|
||||
|
|
@ -118,9 +121,9 @@ _PyImportZip_Init(void)
|
|||
Py_DECREF(zipimport);
|
||||
if (zipimporter == NULL) {
|
||||
PyErr_Clear(); /* No zipimporter object -- okay */
|
||||
if (Py_VerboseFlag)
|
||||
PySys_WriteStderr(
|
||||
"# can't import zipimport.zipimporter\n");
|
||||
if (verbose) {
|
||||
PySys_WriteStderr("# can't import zipimport.zipimporter\n");
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* sys.path_hooks.insert(0, zipimporter) */
|
||||
|
|
@ -129,9 +132,9 @@ _PyImportZip_Init(void)
|
|||
if (err < 0) {
|
||||
goto error;
|
||||
}
|
||||
if (Py_VerboseFlag)
|
||||
PySys_WriteStderr(
|
||||
"# installed zipimport hook\n");
|
||||
if (verbose) {
|
||||
PySys_WriteStderr("# installed zipimport hook\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -415,22 +418,26 @@ PyImport_Cleanup(void)
|
|||
|
||||
/* XXX Perhaps these precautions are obsolete. Who knows? */
|
||||
|
||||
if (Py_VerboseFlag)
|
||||
int verbose = interp->core_config.verbose;
|
||||
if (verbose) {
|
||||
PySys_WriteStderr("# clear builtins._\n");
|
||||
}
|
||||
if (PyDict_SetItemString(interp->builtins, "_", Py_None) < 0) {
|
||||
PyErr_WriteUnraisable(NULL);
|
||||
}
|
||||
|
||||
for (p = sys_deletes; *p != NULL; p++) {
|
||||
if (Py_VerboseFlag)
|
||||
if (verbose) {
|
||||
PySys_WriteStderr("# clear sys.%s\n", *p);
|
||||
}
|
||||
if (PyDict_SetItemString(interp->sysdict, *p, Py_None) < 0) {
|
||||
PyErr_WriteUnraisable(NULL);
|
||||
}
|
||||
}
|
||||
for (p = sys_files; *p != NULL; p+=2) {
|
||||
if (Py_VerboseFlag)
|
||||
if (verbose) {
|
||||
PySys_WriteStderr("# restore sys.%s\n", *p);
|
||||
}
|
||||
value = _PyDict_GetItemStringWithError(interp->sysdict, *(p+1));
|
||||
if (value == NULL) {
|
||||
if (PyErr_Occurred()) {
|
||||
|
|
@ -469,8 +476,9 @@ PyImport_Cleanup(void)
|
|||
}
|
||||
#define CLEAR_MODULE(name, mod) \
|
||||
if (PyModule_Check(mod)) { \
|
||||
if (Py_VerboseFlag && PyUnicode_Check(name)) \
|
||||
if (verbose && PyUnicode_Check(name)) { \
|
||||
PySys_FormatStderr("# cleanup[2] removing %U\n", name); \
|
||||
} \
|
||||
STORE_MODULE_WEAKREF(name, mod); \
|
||||
if (PyObject_SetItem(modules, name, Py_None) < 0) { \
|
||||
PyErr_WriteUnraisable(NULL); \
|
||||
|
|
@ -563,8 +571,9 @@ PyImport_Cleanup(void)
|
|||
if (dict == interp->builtins || dict == interp->sysdict)
|
||||
continue;
|
||||
Py_INCREF(mod);
|
||||
if (Py_VerboseFlag && PyUnicode_Check(name))
|
||||
if (verbose && PyUnicode_Check(name)) {
|
||||
PySys_FormatStderr("# cleanup[3] wiping %U\n", name);
|
||||
}
|
||||
_PyModule_Clear(mod);
|
||||
Py_DECREF(mod);
|
||||
}
|
||||
|
|
@ -572,11 +581,13 @@ PyImport_Cleanup(void)
|
|||
}
|
||||
|
||||
/* Next, delete sys and builtins (in that order) */
|
||||
if (Py_VerboseFlag)
|
||||
if (verbose) {
|
||||
PySys_FormatStderr("# cleanup[3] wiping sys\n");
|
||||
}
|
||||
_PyModule_ClearDict(interp->sysdict);
|
||||
if (Py_VerboseFlag)
|
||||
if (verbose) {
|
||||
PySys_FormatStderr("# cleanup[3] wiping builtins\n");
|
||||
}
|
||||
_PyModule_ClearDict(interp->builtins);
|
||||
|
||||
/* Clear and delete the modules directory. Actual modules will
|
||||
|
|
@ -755,9 +766,11 @@ _PyImport_FindExtensionObjectEx(PyObject *name, PyObject *filename,
|
|||
PyMapping_DelItem(modules, name);
|
||||
return NULL;
|
||||
}
|
||||
if (Py_VerboseFlag)
|
||||
int verbose = _PyInterpreterState_Get()->core_config.verbose;
|
||||
if (verbose) {
|
||||
PySys_FormatStderr("import %U # previously loaded (%R)\n",
|
||||
name, filename);
|
||||
name, filename);
|
||||
}
|
||||
return mod;
|
||||
|
||||
}
|
||||
|
|
@ -1427,7 +1440,7 @@ PyImport_ImportModuleNoBlock(const char *name)
|
|||
/* Remove importlib frames from the traceback,
|
||||
* except in Verbose mode. */
|
||||
static void
|
||||
remove_importlib_frames(void)
|
||||
remove_importlib_frames(PyInterpreterState *interp)
|
||||
{
|
||||
const char *importlib_filename = "<frozen importlib._bootstrap>";
|
||||
const char *external_filename = "<frozen importlib._bootstrap_external>";
|
||||
|
|
@ -1442,8 +1455,10 @@ remove_importlib_frames(void)
|
|||
which end with a call to "_call_with_frames_removed". */
|
||||
|
||||
PyErr_Fetch(&exception, &value, &base_tb);
|
||||
if (!exception || Py_VerboseFlag)
|
||||
if (!exception || interp->core_config.verbose) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (PyType_IsSubtype((PyTypeObject *) exception,
|
||||
(PyTypeObject *) PyExc_ImportError))
|
||||
always_trim = 1;
|
||||
|
|
@ -1646,6 +1661,17 @@ import_find_and_load(PyObject *abs_name)
|
|||
|
||||
_PyTime_t t1 = 0, accumulated_copy = accumulated;
|
||||
|
||||
PyObject *sys_path = PySys_GetObject("path");
|
||||
PyObject *sys_meta_path = PySys_GetObject("meta_path");
|
||||
PyObject *sys_path_hooks = PySys_GetObject("path_hooks");
|
||||
if (PySys_Audit("import", "OOOOO",
|
||||
abs_name, Py_None, sys_path ? sys_path : Py_None,
|
||||
sys_meta_path ? sys_meta_path : Py_None,
|
||||
sys_path_hooks ? sys_path_hooks : Py_None) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* XOptions is initialized after first some imports.
|
||||
* So we can't have negative cache before completed initialization.
|
||||
* Anyway, importlib._find_and_load is much slower than
|
||||
|
|
@ -1853,8 +1879,9 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals,
|
|||
Py_XDECREF(abs_name);
|
||||
Py_XDECREF(mod);
|
||||
Py_XDECREF(package);
|
||||
if (final_mod == NULL)
|
||||
remove_importlib_frames();
|
||||
if (final_mod == NULL) {
|
||||
remove_importlib_frames(interp);
|
||||
}
|
||||
return final_mod;
|
||||
}
|
||||
|
||||
|
|
@ -2303,13 +2330,16 @@ PyInit__imp(void)
|
|||
PyObject *m, *d;
|
||||
|
||||
m = PyModule_Create(&impmodule);
|
||||
if (m == NULL)
|
||||
if (m == NULL) {
|
||||
goto failure;
|
||||
}
|
||||
d = PyModule_GetDict(m);
|
||||
if (d == NULL)
|
||||
if (d == NULL) {
|
||||
goto failure;
|
||||
_PyCoreConfig *config = &_PyInterpreterState_Get()->core_config;
|
||||
PyObject *pyc_mode = PyUnicode_FromWideChar(config->check_hash_pycs_mode, -1);
|
||||
}
|
||||
|
||||
const wchar_t *mode = _PyInterpreterState_Get()->core_config.check_hash_pycs_mode;
|
||||
PyObject *pyc_mode = PyUnicode_FromWideChar(mode, -1);
|
||||
if (pyc_mode == NULL) {
|
||||
goto failure;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -119,6 +119,11 @@ _PyImport_LoadDynamicModuleWithSpec(PyObject *spec, FILE *fp)
|
|||
if (path == NULL)
|
||||
goto error;
|
||||
|
||||
if (PySys_Audit("import", "OOOOO", name_unicode, path,
|
||||
Py_None, Py_None, Py_None) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef MS_WINDOWS
|
||||
exportfunc = _PyImport_FindSharedFuncptrWindows(hook_prefix, name_buf,
|
||||
path, fp);
|
||||
|
|
|
|||
120
Python/importlib.h
generated
120
Python/importlib.h
generated
|
|
@ -1326,8 +1326,8 @@ const unsigned char _Py_M__importlib_bootstrap[] = {
|
|||
97,114,100,108,101,115,115,32,111,102,32,97,110,121,32,114,
|
||||
97,105,115,101,100,32,101,120,99,101,112,116,105,111,110,115,
|
||||
46,78,41,2,114,57,0,0,0,114,60,0,0,0,41,4,
|
||||
114,30,0,0,0,90,8,101,120,99,95,116,121,112,101,90,
|
||||
9,101,120,99,95,118,97,108,117,101,90,13,101,120,99,95,
|
||||
114,30,0,0,0,218,8,101,120,99,95,116,121,112,101,218,
|
||||
9,101,120,99,95,118,97,108,117,101,218,13,101,120,99,95,
|
||||
116,114,97,99,101,98,97,99,107,114,10,0,0,0,114,10,
|
||||
0,0,0,114,11,0,0,0,114,56,0,0,0,99,3,0,
|
||||
0,115,2,0,0,0,0,2,122,27,95,73,109,112,111,114,
|
||||
|
|
@ -1358,7 +1358,7 @@ const unsigned char _Py_M__importlib_bootstrap[] = {
|
|||
98,97,115,101,114,10,0,0,0,114,10,0,0,0,114,11,
|
||||
0,0,0,218,13,95,114,101,115,111,108,118,101,95,110,97,
|
||||
109,101,104,3,0,0,115,10,0,0,0,0,2,16,1,12,
|
||||
1,8,1,8,1,114,185,0,0,0,99,3,0,0,0,0,
|
||||
1,8,1,8,1,114,188,0,0,0,99,3,0,0,0,0,
|
||||
0,0,0,0,0,0,0,4,0,0,0,4,0,0,0,67,
|
||||
0,0,0,115,34,0,0,0,124,0,160,0,124,1,124,2,
|
||||
161,2,125,3,124,3,100,0,107,8,114,24,100,0,83,0,
|
||||
|
|
@ -1368,7 +1368,7 @@ const unsigned char _Py_M__importlib_bootstrap[] = {
|
|||
109,0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,
|
||||
0,0,0,218,17,95,102,105,110,100,95,115,112,101,99,95,
|
||||
108,101,103,97,99,121,113,3,0,0,115,8,0,0,0,0,
|
||||
3,12,1,8,1,4,1,114,187,0,0,0,99,3,0,0,
|
||||
3,12,1,8,1,4,1,114,190,0,0,0,99,3,0,0,
|
||||
0,0,0,0,0,0,0,0,0,10,0,0,0,10,0,0,
|
||||
0,67,0,0,0,115,12,1,0,0,116,0,106,1,125,3,
|
||||
124,3,100,1,107,8,114,22,116,2,100,2,131,1,130,1,
|
||||
|
|
@ -1398,17 +1398,17 @@ const unsigned char _Py_M__importlib_bootstrap[] = {
|
|||
104,114,79,0,0,0,218,9,95,119,97,114,110,105,110,103,
|
||||
115,218,4,119,97,114,110,218,13,73,109,112,111,114,116,87,
|
||||
97,114,110,105,110,103,114,92,0,0,0,114,178,0,0,0,
|
||||
114,166,0,0,0,114,106,0,0,0,114,187,0,0,0,114,
|
||||
114,166,0,0,0,114,106,0,0,0,114,190,0,0,0,114,
|
||||
105,0,0,0,41,10,114,17,0,0,0,114,164,0,0,0,
|
||||
114,165,0,0,0,114,188,0,0,0,90,9,105,115,95,114,
|
||||
101,108,111,97,100,114,186,0,0,0,114,166,0,0,0,114,
|
||||
114,165,0,0,0,114,191,0,0,0,90,9,105,115,95,114,
|
||||
101,108,111,97,100,114,189,0,0,0,114,166,0,0,0,114,
|
||||
95,0,0,0,114,96,0,0,0,114,105,0,0,0,114,10,
|
||||
0,0,0,114,10,0,0,0,114,11,0,0,0,218,10,95,
|
||||
102,105,110,100,95,115,112,101,99,122,3,0,0,115,54,0,
|
||||
0,0,0,2,6,1,8,2,8,3,4,1,12,5,10,1,
|
||||
8,1,8,1,2,1,10,1,14,1,12,1,8,1,20,2,
|
||||
22,1,8,2,18,1,10,1,2,1,10,1,14,4,14,2,
|
||||
8,1,8,2,10,2,10,2,114,192,0,0,0,99,3,0,
|
||||
8,1,8,2,10,2,10,2,114,195,0,0,0,99,3,0,
|
||||
0,0,0,0,0,0,0,0,0,0,3,0,0,0,5,0,
|
||||
0,0,67,0,0,0,115,108,0,0,0,116,0,124,0,116,
|
||||
1,131,2,115,28,116,2,100,1,160,3,116,4,124,0,131,
|
||||
|
|
@ -1432,12 +1432,12 @@ const unsigned char _Py_M__importlib_bootstrap[] = {
|
|||
121,32,109,111,100,117,108,101,32,110,97,109,101,78,41,7,
|
||||
218,10,105,115,105,110,115,116,97,110,99,101,218,3,115,116,
|
||||
114,218,9,84,121,112,101,69,114,114,111,114,114,45,0,0,
|
||||
0,114,14,0,0,0,114,182,0,0,0,114,79,0,0,0,
|
||||
169,3,114,17,0,0,0,114,183,0,0,0,114,184,0,0,
|
||||
0,114,14,0,0,0,114,185,0,0,0,114,79,0,0,0,
|
||||
169,3,114,17,0,0,0,114,186,0,0,0,114,187,0,0,
|
||||
0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,
|
||||
218,13,95,115,97,110,105,116,121,95,99,104,101,99,107,169,
|
||||
3,0,0,115,22,0,0,0,0,2,10,1,18,1,8,1,
|
||||
8,1,8,1,10,1,10,1,4,1,8,2,12,1,114,197,
|
||||
8,1,8,1,10,1,10,1,4,1,8,2,12,1,114,200,
|
||||
0,0,0,122,16,78,111,32,109,111,100,117,108,101,32,110,
|
||||
97,109,101,100,32,122,4,123,33,114,125,99,2,0,0,0,
|
||||
0,0,0,0,0,0,0,0,8,0,0,0,8,0,0,0,
|
||||
|
|
@ -1462,7 +1462,7 @@ const unsigned char _Py_M__importlib_bootstrap[] = {
|
|||
0,114,92,0,0,0,114,67,0,0,0,114,141,0,0,0,
|
||||
114,106,0,0,0,218,8,95,69,82,82,95,77,83,71,114,
|
||||
45,0,0,0,218,19,77,111,100,117,108,101,78,111,116,70,
|
||||
111,117,110,100,69,114,114,111,114,114,192,0,0,0,114,159,
|
||||
111,117,110,100,69,114,114,111,114,114,195,0,0,0,114,159,
|
||||
0,0,0,114,5,0,0,0,41,8,114,17,0,0,0,218,
|
||||
7,105,109,112,111,114,116,95,114,164,0,0,0,114,130,0,
|
||||
0,0,90,13,112,97,114,101,110,116,95,109,111,100,117,108,
|
||||
|
|
@ -1472,7 +1472,7 @@ const unsigned char _Py_M__importlib_bootstrap[] = {
|
|||
117,110,108,111,99,107,101,100,188,3,0,0,115,42,0,0,
|
||||
0,0,1,4,1,14,1,4,1,10,1,10,2,10,1,10,
|
||||
1,10,1,2,1,10,1,14,1,16,1,20,1,10,1,8,
|
||||
1,20,2,8,1,4,2,10,1,22,1,114,202,0,0,0,
|
||||
1,20,2,8,1,4,2,10,1,22,1,114,205,0,0,0,
|
||||
99,2,0,0,0,0,0,0,0,0,0,0,0,4,0,0,
|
||||
0,10,0,0,0,67,0,0,0,115,106,0,0,0,116,0,
|
||||
124,0,131,1,143,50,1,0,116,1,106,2,160,3,124,0,
|
||||
|
|
@ -1488,14 +1488,14 @@ const unsigned char _Py_M__importlib_bootstrap[] = {
|
|||
101,32,105,110,32,115,121,115,46,109,111,100,117,108,101,115,
|
||||
114,16,0,0,0,41,9,114,50,0,0,0,114,15,0,0,
|
||||
0,114,92,0,0,0,114,34,0,0,0,218,14,95,78,69,
|
||||
69,68,83,95,76,79,65,68,73,78,71,114,202,0,0,0,
|
||||
114,45,0,0,0,114,200,0,0,0,114,65,0,0,0,41,
|
||||
4,114,17,0,0,0,114,201,0,0,0,114,96,0,0,0,
|
||||
69,68,83,95,76,79,65,68,73,78,71,114,205,0,0,0,
|
||||
114,45,0,0,0,114,203,0,0,0,114,65,0,0,0,41,
|
||||
4,114,17,0,0,0,114,204,0,0,0,114,96,0,0,0,
|
||||
114,75,0,0,0,114,10,0,0,0,114,10,0,0,0,114,
|
||||
11,0,0,0,218,14,95,102,105,110,100,95,97,110,100,95,
|
||||
108,111,97,100,218,3,0,0,115,22,0,0,0,0,2,10,
|
||||
1,14,1,8,1,32,2,8,1,4,1,2,255,4,2,12,
|
||||
2,8,1,114,204,0,0,0,114,22,0,0,0,99,3,0,
|
||||
2,8,1,114,207,0,0,0,114,22,0,0,0,99,3,0,
|
||||
0,0,0,0,0,0,0,0,0,0,3,0,0,0,4,0,
|
||||
0,0,67,0,0,0,115,42,0,0,0,116,0,124,0,124,
|
||||
1,124,2,131,3,1,0,124,2,100,1,107,4,114,32,116,
|
||||
|
|
@ -1520,11 +1520,11 @@ const unsigned char _Py_M__importlib_bootstrap[] = {
|
|||
103,32,95,95,112,97,99,107,97,103,101,95,95,32,105,102,
|
||||
10,32,32,32,32,116,104,101,32,108,111,97,100,101,114,32,
|
||||
100,105,100,32,110,111,116,46,10,10,32,32,32,32,114,22,
|
||||
0,0,0,41,4,114,197,0,0,0,114,185,0,0,0,114,
|
||||
204,0,0,0,218,11,95,103,99,100,95,105,109,112,111,114,
|
||||
116,114,196,0,0,0,114,10,0,0,0,114,10,0,0,0,
|
||||
114,11,0,0,0,114,205,0,0,0,234,3,0,0,115,8,
|
||||
0,0,0,0,9,12,1,8,1,12,1,114,205,0,0,0,
|
||||
0,0,0,41,4,114,200,0,0,0,114,188,0,0,0,114,
|
||||
207,0,0,0,218,11,95,103,99,100,95,105,109,112,111,114,
|
||||
116,114,199,0,0,0,114,10,0,0,0,114,10,0,0,0,
|
||||
114,11,0,0,0,114,208,0,0,0,234,3,0,0,115,8,
|
||||
0,0,0,0,9,12,1,8,1,12,1,114,208,0,0,0,
|
||||
169,1,218,9,114,101,99,117,114,115,105,118,101,99,3,0,
|
||||
0,0,0,0,0,0,1,0,0,0,8,0,0,0,11,0,
|
||||
0,0,67,0,0,0,115,226,0,0,0,124,1,68,0,93,
|
||||
|
|
@ -1561,21 +1561,21 @@ const unsigned char _Py_M__importlib_bootstrap[] = {
|
|||
109,32,108,105,115,116,39,39,122,8,73,116,101,109,32,105,
|
||||
110,32,122,18,32,109,117,115,116,32,98,101,32,115,116,114,
|
||||
44,32,110,111,116,32,250,1,42,218,7,95,95,97,108,108,
|
||||
95,95,84,114,206,0,0,0,114,179,0,0,0,78,41,16,
|
||||
114,193,0,0,0,114,194,0,0,0,114,1,0,0,0,114,
|
||||
195,0,0,0,114,14,0,0,0,114,4,0,0,0,218,16,
|
||||
95,95,84,114,209,0,0,0,114,182,0,0,0,78,41,16,
|
||||
114,196,0,0,0,114,197,0,0,0,114,1,0,0,0,114,
|
||||
198,0,0,0,114,14,0,0,0,114,4,0,0,0,218,16,
|
||||
95,104,97,110,100,108,101,95,102,114,111,109,108,105,115,116,
|
||||
114,209,0,0,0,114,45,0,0,0,114,67,0,0,0,114,
|
||||
200,0,0,0,114,17,0,0,0,114,15,0,0,0,114,92,
|
||||
0,0,0,114,34,0,0,0,114,203,0,0,0,41,8,114,
|
||||
96,0,0,0,218,8,102,114,111,109,108,105,115,116,114,201,
|
||||
0,0,0,114,207,0,0,0,218,1,120,90,5,119,104,101,
|
||||
114,212,0,0,0,114,45,0,0,0,114,67,0,0,0,114,
|
||||
203,0,0,0,114,17,0,0,0,114,15,0,0,0,114,92,
|
||||
0,0,0,114,34,0,0,0,114,206,0,0,0,41,8,114,
|
||||
96,0,0,0,218,8,102,114,111,109,108,105,115,116,114,204,
|
||||
0,0,0,114,210,0,0,0,218,1,120,90,5,119,104,101,
|
||||
114,101,90,9,102,114,111,109,95,110,97,109,101,90,3,101,
|
||||
120,99,114,10,0,0,0,114,10,0,0,0,114,11,0,0,
|
||||
0,114,210,0,0,0,249,3,0,0,115,44,0,0,0,0,
|
||||
0,114,213,0,0,0,249,3,0,0,115,44,0,0,0,0,
|
||||
10,8,1,10,1,4,1,12,2,4,1,28,2,8,1,14,
|
||||
1,10,1,2,255,8,2,10,1,14,1,2,1,14,1,16,
|
||||
4,10,1,16,255,2,2,8,1,22,1,114,210,0,0,0,
|
||||
4,10,1,16,255,2,2,8,1,22,1,114,213,0,0,0,
|
||||
99,1,0,0,0,0,0,0,0,0,0,0,0,3,0,0,
|
||||
0,6,0,0,0,67,0,0,0,115,146,0,0,0,124,0,
|
||||
160,0,100,1,161,1,125,1,124,0,160,0,100,2,161,1,
|
||||
|
|
@ -1610,14 +1610,14 @@ const unsigned char _Py_M__importlib_bootstrap[] = {
|
|||
95,95,32,97,110,100,32,95,95,112,97,116,104,95,95,114,
|
||||
1,0,0,0,114,141,0,0,0,114,128,0,0,0,114,22,
|
||||
0,0,0,41,6,114,34,0,0,0,114,130,0,0,0,114,
|
||||
189,0,0,0,114,190,0,0,0,114,191,0,0,0,114,129,
|
||||
0,0,0,41,3,218,7,103,108,111,98,97,108,115,114,183,
|
||||
192,0,0,0,114,193,0,0,0,114,194,0,0,0,114,129,
|
||||
0,0,0,41,3,218,7,103,108,111,98,97,108,115,114,186,
|
||||
0,0,0,114,95,0,0,0,114,10,0,0,0,114,10,0,
|
||||
0,0,114,11,0,0,0,218,17,95,99,97,108,99,95,95,
|
||||
95,112,97,99,107,97,103,101,95,95,30,4,0,0,115,38,
|
||||
0,0,0,0,7,10,1,10,1,8,1,18,1,22,2,2,
|
||||
0,2,254,6,3,4,1,8,1,6,2,6,2,2,0,2,
|
||||
254,6,3,8,1,8,1,14,1,114,216,0,0,0,114,10,
|
||||
254,6,3,8,1,8,1,14,1,114,219,0,0,0,114,10,
|
||||
0,0,0,99,5,0,0,0,0,0,0,0,0,0,0,0,
|
||||
9,0,0,0,5,0,0,0,67,0,0,0,115,180,0,0,
|
||||
0,124,4,100,1,107,2,114,18,116,0,124,0,131,1,125,
|
||||
|
|
@ -1662,18 +1662,18 @@ const unsigned char _Py_M__importlib_bootstrap[] = {
|
|||
96,32,119,111,117,108,100,32,104,97,118,101,32,97,32,39,
|
||||
108,101,118,101,108,39,32,111,102,32,50,41,46,10,10,32,
|
||||
32,32,32,114,22,0,0,0,78,114,128,0,0,0,114,141,
|
||||
0,0,0,41,9,114,205,0,0,0,114,216,0,0,0,218,
|
||||
9,112,97,114,116,105,116,105,111,110,114,181,0,0,0,114,
|
||||
0,0,0,41,9,114,208,0,0,0,114,219,0,0,0,218,
|
||||
9,112,97,114,116,105,116,105,111,110,114,184,0,0,0,114,
|
||||
15,0,0,0,114,92,0,0,0,114,1,0,0,0,114,4,
|
||||
0,0,0,114,210,0,0,0,41,9,114,17,0,0,0,114,
|
||||
215,0,0,0,218,6,108,111,99,97,108,115,114,211,0,0,
|
||||
0,114,184,0,0,0,114,96,0,0,0,90,8,103,108,111,
|
||||
98,97,108,115,95,114,183,0,0,0,90,7,99,117,116,95,
|
||||
0,0,0,114,213,0,0,0,41,9,114,17,0,0,0,114,
|
||||
218,0,0,0,218,6,108,111,99,97,108,115,114,214,0,0,
|
||||
0,114,187,0,0,0,114,96,0,0,0,90,8,103,108,111,
|
||||
98,97,108,115,95,114,186,0,0,0,90,7,99,117,116,95,
|
||||
111,102,102,114,10,0,0,0,114,10,0,0,0,114,11,0,
|
||||
0,0,218,10,95,95,105,109,112,111,114,116,95,95,57,4,
|
||||
0,0,115,30,0,0,0,0,11,8,1,10,2,16,1,8,
|
||||
1,12,1,4,3,8,1,18,1,4,1,4,4,26,3,32,
|
||||
1,10,1,12,2,114,219,0,0,0,99,1,0,0,0,0,
|
||||
1,10,1,12,2,114,222,0,0,0,99,1,0,0,0,0,
|
||||
0,0,0,0,0,0,0,2,0,0,0,3,0,0,0,67,
|
||||
0,0,0,115,38,0,0,0,116,0,160,1,124,0,161,1,
|
||||
125,1,124,1,100,0,107,8,114,30,116,2,100,1,124,0,
|
||||
|
|
@ -1685,7 +1685,7 @@ const unsigned char _Py_M__importlib_bootstrap[] = {
|
|||
0,0,0,114,10,0,0,0,114,11,0,0,0,218,18,95,
|
||||
98,117,105,108,116,105,110,95,102,114,111,109,95,110,97,109,
|
||||
101,94,4,0,0,115,8,0,0,0,0,1,10,1,8,1,
|
||||
12,1,114,220,0,0,0,99,2,0,0,0,0,0,0,0,
|
||||
12,1,114,223,0,0,0,99,2,0,0,0,0,0,0,0,
|
||||
0,0,0,0,10,0,0,0,5,0,0,0,67,0,0,0,
|
||||
115,166,0,0,0,124,1,97,0,124,0,97,1,116,2,116,
|
||||
1,131,1,125,2,116,1,106,3,160,4,161,0,68,0,93,
|
||||
|
|
@ -1714,12 +1714,12 @@ const unsigned char _Py_M__importlib_bootstrap[] = {
|
|||
100,117,108,101,115,32,109,117,115,116,32,98,101,32,101,120,
|
||||
112,108,105,99,105,116,108,121,32,112,97,115,115,101,100,32,
|
||||
105,110,46,10,10,32,32,32,32,41,3,114,23,0,0,0,
|
||||
114,189,0,0,0,114,64,0,0,0,78,41,15,114,57,0,
|
||||
114,192,0,0,0,114,64,0,0,0,78,41,15,114,57,0,
|
||||
0,0,114,15,0,0,0,114,14,0,0,0,114,92,0,0,
|
||||
0,218,5,105,116,101,109,115,114,193,0,0,0,114,78,0,
|
||||
0,218,5,105,116,101,109,115,114,196,0,0,0,114,78,0,
|
||||
0,0,114,160,0,0,0,114,88,0,0,0,114,173,0,0,
|
||||
0,114,142,0,0,0,114,148,0,0,0,114,1,0,0,0,
|
||||
114,220,0,0,0,114,5,0,0,0,41,10,218,10,115,121,
|
||||
114,223,0,0,0,114,5,0,0,0,41,10,218,10,115,121,
|
||||
115,95,109,111,100,117,108,101,218,11,95,105,109,112,95,109,
|
||||
111,100,117,108,101,90,11,109,111,100,117,108,101,95,116,121,
|
||||
112,101,114,17,0,0,0,114,96,0,0,0,114,109,0,0,
|
||||
|
|
@ -1730,7 +1730,7 @@ const unsigned char _Py_M__importlib_bootstrap[] = {
|
|||
218,6,95,115,101,116,117,112,101,4,0,0,115,36,0,0,
|
||||
0,0,9,4,1,4,3,8,1,18,1,10,1,10,1,6,
|
||||
1,10,1,6,2,2,1,10,1,12,3,10,1,8,1,10,
|
||||
1,10,2,10,1,114,224,0,0,0,99,2,0,0,0,0,
|
||||
1,10,2,10,1,114,227,0,0,0,99,2,0,0,0,0,
|
||||
0,0,0,0,0,0,0,2,0,0,0,3,0,0,0,67,
|
||||
0,0,0,115,38,0,0,0,116,0,124,0,124,1,131,2,
|
||||
1,0,116,1,106,2,160,3,116,4,161,1,1,0,116,1,
|
||||
|
|
@ -1738,12 +1738,12 @@ const unsigned char _Py_M__importlib_bootstrap[] = {
|
|||
122,48,73,110,115,116,97,108,108,32,105,109,112,111,114,116,
|
||||
101,114,115,32,102,111,114,32,98,117,105,108,116,105,110,32,
|
||||
97,110,100,32,102,114,111,122,101,110,32,109,111,100,117,108,
|
||||
101,115,78,41,6,114,224,0,0,0,114,15,0,0,0,114,
|
||||
188,0,0,0,114,120,0,0,0,114,160,0,0,0,114,173,
|
||||
0,0,0,41,2,114,222,0,0,0,114,223,0,0,0,114,
|
||||
101,115,78,41,6,114,227,0,0,0,114,15,0,0,0,114,
|
||||
191,0,0,0,114,120,0,0,0,114,160,0,0,0,114,173,
|
||||
0,0,0,41,2,114,225,0,0,0,114,226,0,0,0,114,
|
||||
10,0,0,0,114,10,0,0,0,114,11,0,0,0,218,8,
|
||||
95,105,110,115,116,97,108,108,136,4,0,0,115,6,0,0,
|
||||
0,0,2,10,2,12,1,114,225,0,0,0,99,0,0,0,
|
||||
0,0,2,10,2,12,1,114,228,0,0,0,99,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,1,0,0,0,4,0,0,
|
||||
0,67,0,0,0,115,32,0,0,0,100,1,100,2,108,0,
|
||||
125,0,124,0,97,1,124,0,160,2,116,3,106,4,116,5,
|
||||
|
|
@ -1754,12 +1754,12 @@ const unsigned char _Py_M__importlib_bootstrap[] = {
|
|||
32,97,99,99,101,115,115,114,22,0,0,0,78,41,6,218,
|
||||
26,95,102,114,111,122,101,110,95,105,109,112,111,114,116,108,
|
||||
105,98,95,101,120,116,101,114,110,97,108,114,126,0,0,0,
|
||||
114,225,0,0,0,114,15,0,0,0,114,92,0,0,0,114,
|
||||
1,0,0,0,41,1,114,226,0,0,0,114,10,0,0,0,
|
||||
114,228,0,0,0,114,15,0,0,0,114,92,0,0,0,114,
|
||||
1,0,0,0,41,1,114,229,0,0,0,114,10,0,0,0,
|
||||
114,10,0,0,0,114,11,0,0,0,218,27,95,105,110,115,
|
||||
116,97,108,108,95,101,120,116,101,114,110,97,108,95,105,109,
|
||||
112,111,114,116,101,114,115,144,4,0,0,115,6,0,0,0,
|
||||
0,3,8,1,4,1,114,227,0,0,0,41,2,78,78,41,
|
||||
0,3,8,1,4,1,114,230,0,0,0,41,2,78,78,41,
|
||||
1,78,41,2,78,114,22,0,0,0,41,4,78,78,114,10,
|
||||
0,0,0,114,22,0,0,0,41,50,114,3,0,0,0,114,
|
||||
126,0,0,0,114,12,0,0,0,114,18,0,0,0,114,59,
|
||||
|
|
@ -1771,13 +1771,13 @@ const unsigned char _Py_M__importlib_bootstrap[] = {
|
|||
0,0,0,114,142,0,0,0,114,148,0,0,0,114,152,0,
|
||||
0,0,114,107,0,0,0,114,93,0,0,0,114,158,0,0,
|
||||
0,114,159,0,0,0,114,94,0,0,0,114,160,0,0,0,
|
||||
114,173,0,0,0,114,178,0,0,0,114,185,0,0,0,114,
|
||||
187,0,0,0,114,192,0,0,0,114,197,0,0,0,90,15,
|
||||
114,173,0,0,0,114,178,0,0,0,114,188,0,0,0,114,
|
||||
190,0,0,0,114,195,0,0,0,114,200,0,0,0,90,15,
|
||||
95,69,82,82,95,77,83,71,95,80,82,69,70,73,88,114,
|
||||
199,0,0,0,114,202,0,0,0,218,6,111,98,106,101,99,
|
||||
116,114,203,0,0,0,114,204,0,0,0,114,205,0,0,0,
|
||||
114,210,0,0,0,114,216,0,0,0,114,219,0,0,0,114,
|
||||
220,0,0,0,114,224,0,0,0,114,225,0,0,0,114,227,
|
||||
202,0,0,0,114,205,0,0,0,218,6,111,98,106,101,99,
|
||||
116,114,206,0,0,0,114,207,0,0,0,114,208,0,0,0,
|
||||
114,213,0,0,0,114,219,0,0,0,114,222,0,0,0,114,
|
||||
223,0,0,0,114,227,0,0,0,114,228,0,0,0,114,230,
|
||||
0,0,0,114,10,0,0,0,114,10,0,0,0,114,10,0,
|
||||
0,0,114,11,0,0,0,218,8,60,109,111,100,117,108,101,
|
||||
62,1,0,0,0,115,94,0,0,0,4,24,4,2,8,8,
|
||||
|
|
|
|||
2724
Python/importlib_external.h
generated
2724
Python/importlib_external.h
generated
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -214,7 +214,8 @@ _PyCoreConfig_SetPathConfig(const _PyCoreConfig *core_config)
|
|||
goto no_memory;
|
||||
}
|
||||
#ifdef MS_WINDOWS
|
||||
if (copy_wstr(&path_config.dll_path, core_config->dll_path) < 0) {
|
||||
path_config.dll_path = _Py_GetDLLPath();
|
||||
if (path_config.dll_path == NULL) {
|
||||
goto no_memory;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -322,14 +323,6 @@ _PyCoreConfig_CalculatePathConfig(_PyCoreConfig *config)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef MS_WINDOWS
|
||||
if (config->dll_path == NULL) {
|
||||
if (copy_wstr(&config->dll_path, path_config.dll_path) < 0) {
|
||||
goto no_memory;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (path_config.isolated != -1) {
|
||||
config->isolated = path_config.isolated;
|
||||
}
|
||||
|
|
@ -356,9 +349,6 @@ _PyCoreConfig_InitPathConfig(_PyCoreConfig *config)
|
|||
if (!config->use_module_search_paths
|
||||
|| (config->executable == NULL)
|
||||
|| (config->prefix == NULL)
|
||||
#ifdef MS_WINDOWS
|
||||
|| (config->dll_path == NULL)
|
||||
#endif
|
||||
|| (config->exec_prefix == NULL))
|
||||
{
|
||||
_PyInitError err = _PyCoreConfig_CalculatePathConfig(config);
|
||||
|
|
@ -392,7 +382,8 @@ pathconfig_global_init(void)
|
|||
}
|
||||
|
||||
_PyInitError err;
|
||||
_PyCoreConfig config = _PyCoreConfig_INIT;
|
||||
_PyCoreConfig config;
|
||||
_PyCoreConfig_InitCompatConfig(&config);
|
||||
|
||||
err = _PyCoreConfig_Read(&config);
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
|
|
@ -434,7 +425,7 @@ Py_SetPath(const wchar_t *path)
|
|||
new_config.exec_prefix = _PyMem_RawWcsdup(L"");
|
||||
alloc_error |= (new_config.exec_prefix == NULL);
|
||||
#ifdef MS_WINDOWS
|
||||
new_config.dll_path = _PyMem_RawWcsdup(L"");
|
||||
new_config.dll_path = _Py_GetDLLPath();
|
||||
alloc_error |= (new_config.dll_path == NULL);
|
||||
#endif
|
||||
new_config.module_search_path = _PyMem_RawWcsdup(path);
|
||||
|
|
@ -570,18 +561,17 @@ Py_GetProgramName(void)
|
|||
directory ("-m module" case) which will be prepended to sys.argv:
|
||||
sys.path[0].
|
||||
|
||||
Return 1 if the path is correctly resolved, but *path0_p can be NULL
|
||||
if the Unicode object fail to be created.
|
||||
Return 1 if the path is correctly resolved and written into *path0_p.
|
||||
|
||||
Return 0 if it fails to resolve the full path (and *path0_p will be NULL).
|
||||
For example, return 0 if the current working directory has been removed
|
||||
(bpo-36236) or if argv is empty.
|
||||
Return 0 if it fails to resolve the full path. For example, return 0 if the
|
||||
current working directory has been removed (bpo-36236) or if argv is empty.
|
||||
|
||||
Raise an exception and return -1 on error.
|
||||
*/
|
||||
int
|
||||
_PyPathConfig_ComputeSysPath0(const _PyWstrList *argv, PyObject **path0_p)
|
||||
{
|
||||
assert(_PyWstrList_CheckConsistency(argv));
|
||||
assert(*path0_p == NULL);
|
||||
|
||||
if (argv->length == 0) {
|
||||
/* Leave sys.path unchanged if sys.argv is empty */
|
||||
|
|
@ -697,7 +687,12 @@ _PyPathConfig_ComputeSysPath0(const _PyWstrList *argv, PyObject **path0_p)
|
|||
}
|
||||
#endif /* All others */
|
||||
|
||||
*path0_p = PyUnicode_FromWideChar(path0, n);
|
||||
PyObject *path0_obj = PyUnicode_FromWideChar(path0, n);
|
||||
if (path0_obj == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
*path0_p = path0_obj;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -302,11 +302,19 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,
|
|||
case LOAD_CONST:
|
||||
cumlc = lastlc + 1;
|
||||
if (nextop != POP_JUMP_IF_FALSE ||
|
||||
!ISBASICBLOCK(blocks, op_start, i + 1) ||
|
||||
!PyObject_IsTrue(PyList_GET_ITEM(consts, get_arg(codestr, i))))
|
||||
!ISBASICBLOCK(blocks, op_start, i + 1)) {
|
||||
break;
|
||||
fill_nops(codestr, op_start, nexti + 1);
|
||||
cumlc = 0;
|
||||
}
|
||||
PyObject* cnt = PyList_GET_ITEM(consts, get_arg(codestr, i));
|
||||
int is_true = PyObject_IsTrue(cnt);
|
||||
if (is_true == 1) {
|
||||
fill_nops(codestr, op_start, nexti + 1);
|
||||
cumlc = 0;
|
||||
} else if (is_true == 0) {
|
||||
h = get_arg(codestr, nexti) / sizeof(_Py_CODEUNIT);
|
||||
tgt = find_op(codestr, codelen, h);
|
||||
fill_nops(codestr, op_start, tgt);
|
||||
}
|
||||
break;
|
||||
|
||||
/* Try to fold tuples of constants.
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ _PyArgv_AsWstrList(const _PyArgv *args, _PyWstrList *list)
|
|||
}
|
||||
else {
|
||||
wargv.length = args->argc;
|
||||
wargv.items = args->wchar_argv;
|
||||
wargv.items = (wchar_t **)args->wchar_argv;
|
||||
if (_PyWstrList_Copy(list, &wargv) < 0) {
|
||||
return _Py_INIT_NO_MEMORY();
|
||||
}
|
||||
|
|
@ -174,7 +174,7 @@ _PyPreCmdline_SetCoreConfig(const _PyPreCmdline *cmdline, _PyCoreConfig *config)
|
|||
static _PyInitError
|
||||
precmdline_parse_cmdline(_PyPreCmdline *cmdline)
|
||||
{
|
||||
_PyWstrList *argv = &cmdline->argv;
|
||||
const _PyWstrList *argv = &cmdline->argv;
|
||||
|
||||
_PyOS_ResetGetOpt();
|
||||
/* Don't log parsing errors into stderr here: _PyCoreConfig_Read()
|
||||
|
|
@ -217,16 +217,15 @@ precmdline_parse_cmdline(_PyPreCmdline *cmdline)
|
|||
|
||||
|
||||
_PyInitError
|
||||
_PyPreCmdline_Read(_PyPreCmdline *cmdline,
|
||||
const _PyPreConfig *preconfig)
|
||||
_PyPreCmdline_Read(_PyPreCmdline *cmdline, const _PyPreConfig *preconfig)
|
||||
{
|
||||
if (preconfig) {
|
||||
_PyPreCmdline_GetPreConfig(cmdline, preconfig);
|
||||
}
|
||||
_PyPreCmdline_GetPreConfig(cmdline, preconfig);
|
||||
|
||||
_PyInitError err = precmdline_parse_cmdline(cmdline);
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
return err;
|
||||
if (preconfig->parse_argv) {
|
||||
_PyInitError err = precmdline_parse_cmdline(cmdline);
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
/* isolated, use_environment */
|
||||
|
|
@ -241,8 +240,9 @@ _PyPreCmdline_Read(_PyPreCmdline *cmdline,
|
|||
}
|
||||
|
||||
/* dev_mode */
|
||||
if ((cmdline && _Py_get_xoption(&cmdline->xoptions, L"dev"))
|
||||
|| _Py_GetEnv(cmdline->use_environment, "PYTHONDEVMODE"))
|
||||
if ((cmdline->dev_mode < 0)
|
||||
&& (_Py_get_xoption(&cmdline->xoptions, L"dev")
|
||||
|| _Py_GetEnv(cmdline->use_environment, "PYTHONDEVMODE")))
|
||||
{
|
||||
cmdline->dev_mode = 1;
|
||||
}
|
||||
|
|
@ -260,44 +260,123 @@ _PyPreCmdline_Read(_PyPreCmdline *cmdline,
|
|||
|
||||
/* --- _PyPreConfig ----------------------------------------------- */
|
||||
|
||||
|
||||
void
|
||||
_PyPreConfig_Clear(_PyPreConfig *config)
|
||||
_PyPreConfig_InitCompatConfig(_PyPreConfig *config)
|
||||
{
|
||||
PyMem_RawFree(config->allocator);
|
||||
config->allocator = NULL;
|
||||
memset(config, 0, sizeof(*config));
|
||||
|
||||
config->_config_version = _Py_CONFIG_VERSION;
|
||||
config->_config_init = (int)_PyConfig_INIT_COMPAT;
|
||||
config->parse_argv = 0;
|
||||
config->isolated = -1;
|
||||
config->use_environment = -1;
|
||||
config->configure_locale = 1;
|
||||
|
||||
/* bpo-36443: C locale coercion (PEP 538) and UTF-8 Mode (PEP 540)
|
||||
are disabled by default using the Compat configuration.
|
||||
|
||||
Py_UTF8Mode=1 enables the UTF-8 mode. PYTHONUTF8 environment variable
|
||||
is ignored (even if use_environment=1). */
|
||||
config->utf8_mode = 0;
|
||||
config->coerce_c_locale = 0;
|
||||
config->coerce_c_locale_warn = 0;
|
||||
|
||||
config->dev_mode = -1;
|
||||
config->allocator = PYMEM_ALLOCATOR_NOT_SET;
|
||||
#ifdef MS_WINDOWS
|
||||
config->legacy_windows_fs_encoding = -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
void
|
||||
_PyPreConfig_InitPythonConfig(_PyPreConfig *config)
|
||||
{
|
||||
_PyPreConfig_InitCompatConfig(config);
|
||||
|
||||
config->_config_init = (int)_PyConfig_INIT_PYTHON;
|
||||
config->isolated = 0;
|
||||
config->parse_argv = 1;
|
||||
config->use_environment = 1;
|
||||
/* Set to -1 to enable C locale coercion (PEP 538) and UTF-8 Mode (PEP 540)
|
||||
depending on the LC_CTYPE locale, PYTHONUTF8 and PYTHONCOERCECLOCALE
|
||||
environment variables. */
|
||||
config->coerce_c_locale = -1;
|
||||
config->coerce_c_locale_warn = -1;
|
||||
config->utf8_mode = -1;
|
||||
#ifdef MS_WINDOWS
|
||||
config->legacy_windows_fs_encoding = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_PyPreConfig_InitIsolatedConfig(_PyPreConfig *config)
|
||||
{
|
||||
_PyPreConfig_InitCompatConfig(config);
|
||||
|
||||
config->_config_init = (int)_PyConfig_INIT_ISOLATED;
|
||||
config->configure_locale = 0;
|
||||
config->isolated = 1;
|
||||
config->use_environment = 0;
|
||||
config->utf8_mode = 0;
|
||||
config->dev_mode = 0;
|
||||
#ifdef MS_WINDOWS
|
||||
config->legacy_windows_fs_encoding = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_PyPreConfig_InitFromPreConfig(_PyPreConfig *config,
|
||||
const _PyPreConfig *config2)
|
||||
{
|
||||
_PyPreConfig_InitCompatConfig(config);
|
||||
_PyPreConfig_Copy(config, config2);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_PyPreConfig_InitFromCoreConfig(_PyPreConfig *config,
|
||||
const _PyCoreConfig *coreconfig)
|
||||
{
|
||||
_PyConfigInitEnum config_init = (_PyConfigInitEnum)coreconfig->_config_init;
|
||||
switch (config_init) {
|
||||
case _PyConfig_INIT_PYTHON:
|
||||
_PyPreConfig_InitPythonConfig(config);
|
||||
break;
|
||||
case _PyConfig_INIT_ISOLATED:
|
||||
_PyPreConfig_InitIsolatedConfig(config);
|
||||
break;
|
||||
case _PyConfig_INIT_COMPAT:
|
||||
default:
|
||||
_PyPreConfig_InitCompatConfig(config);
|
||||
}
|
||||
_PyPreConfig_GetCoreConfig(config, coreconfig);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_PyPreConfig_Copy(_PyPreConfig *config, const _PyPreConfig *config2)
|
||||
{
|
||||
_PyPreConfig_Clear(config);
|
||||
|
||||
#define COPY_ATTR(ATTR) config->ATTR = config2->ATTR
|
||||
#define COPY_STR_ATTR(ATTR) \
|
||||
do { \
|
||||
if (config2->ATTR != NULL) { \
|
||||
config->ATTR = _PyMem_RawStrdup(config2->ATTR); \
|
||||
if (config->ATTR == NULL) { \
|
||||
return -1; \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
COPY_ATTR(_config_init);
|
||||
COPY_ATTR(parse_argv);
|
||||
COPY_ATTR(isolated);
|
||||
COPY_ATTR(use_environment);
|
||||
COPY_ATTR(configure_locale);
|
||||
COPY_ATTR(dev_mode);
|
||||
COPY_ATTR(coerce_c_locale);
|
||||
COPY_ATTR(coerce_c_locale_warn);
|
||||
COPY_ATTR(utf8_mode);
|
||||
COPY_ATTR(allocator);
|
||||
#ifdef MS_WINDOWS
|
||||
COPY_ATTR(legacy_windows_fs_encoding);
|
||||
#endif
|
||||
COPY_ATTR(utf8_mode);
|
||||
COPY_STR_ATTR(allocator);
|
||||
|
||||
#undef COPY_ATTR
|
||||
#undef COPY_STR_ATTR
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -311,29 +390,24 @@ _PyPreConfig_AsDict(const _PyPreConfig *config)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
#define SET_ITEM(KEY, EXPR) \
|
||||
#define SET_ITEM_INT(ATTR) \
|
||||
do { \
|
||||
PyObject *obj = (EXPR); \
|
||||
PyObject *obj = PyLong_FromLong(config->ATTR); \
|
||||
if (obj == NULL) { \
|
||||
goto fail; \
|
||||
} \
|
||||
int res = PyDict_SetItemString(dict, (KEY), obj); \
|
||||
int res = PyDict_SetItemString(dict, #ATTR, obj); \
|
||||
Py_DECREF(obj); \
|
||||
if (res < 0) { \
|
||||
goto fail; \
|
||||
} \
|
||||
} while (0)
|
||||
#define SET_ITEM_INT(ATTR) \
|
||||
SET_ITEM(#ATTR, PyLong_FromLong(config->ATTR))
|
||||
#define FROM_STRING(STR) \
|
||||
((STR != NULL) ? \
|
||||
PyUnicode_FromString(STR) \
|
||||
: (Py_INCREF(Py_None), Py_None))
|
||||
#define SET_ITEM_STR(ATTR) \
|
||||
SET_ITEM(#ATTR, FROM_STRING(config->ATTR))
|
||||
|
||||
SET_ITEM_INT(_config_init);
|
||||
SET_ITEM_INT(parse_argv);
|
||||
SET_ITEM_INT(isolated);
|
||||
SET_ITEM_INT(use_environment);
|
||||
SET_ITEM_INT(configure_locale);
|
||||
SET_ITEM_INT(coerce_c_locale);
|
||||
SET_ITEM_INT(coerce_c_locale_warn);
|
||||
SET_ITEM_INT(utf8_mode);
|
||||
|
|
@ -341,22 +415,19 @@ _PyPreConfig_AsDict(const _PyPreConfig *config)
|
|||
SET_ITEM_INT(legacy_windows_fs_encoding);
|
||||
#endif
|
||||
SET_ITEM_INT(dev_mode);
|
||||
SET_ITEM_STR(allocator);
|
||||
SET_ITEM_INT(allocator);
|
||||
return dict;
|
||||
|
||||
fail:
|
||||
Py_DECREF(dict);
|
||||
return NULL;
|
||||
|
||||
#undef FROM_STRING
|
||||
#undef SET_ITEM
|
||||
#undef SET_ITEM_INT
|
||||
#undef SET_ITEM_STR
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_PyCoreConfig_GetCoreConfig(_PyPreConfig *config,
|
||||
_PyPreConfig_GetCoreConfig(_PyPreConfig *config,
|
||||
const _PyCoreConfig *core_config)
|
||||
{
|
||||
#define COPY_ATTR(ATTR) \
|
||||
|
|
@ -364,6 +435,7 @@ _PyCoreConfig_GetCoreConfig(_PyPreConfig *config,
|
|||
config->ATTR = core_config->ATTR; \
|
||||
}
|
||||
|
||||
COPY_ATTR(parse_argv);
|
||||
COPY_ATTR(isolated);
|
||||
COPY_ATTR(use_environment);
|
||||
COPY_ATTR(dev_mode);
|
||||
|
|
@ -375,23 +447,28 @@ _PyCoreConfig_GetCoreConfig(_PyPreConfig *config,
|
|||
static void
|
||||
_PyPreConfig_GetGlobalConfig(_PyPreConfig *config)
|
||||
{
|
||||
if (config->_config_init != _PyConfig_INIT_COMPAT) {
|
||||
/* Python and Isolated configuration ignore global variables */
|
||||
return;
|
||||
}
|
||||
|
||||
#define COPY_FLAG(ATTR, VALUE) \
|
||||
if (config->ATTR == -1) { \
|
||||
if (config->ATTR < 0) { \
|
||||
config->ATTR = VALUE; \
|
||||
}
|
||||
#define COPY_NOT_FLAG(ATTR, VALUE) \
|
||||
if (config->ATTR == -1) { \
|
||||
if (config->ATTR < 0) { \
|
||||
config->ATTR = !(VALUE); \
|
||||
}
|
||||
|
||||
COPY_FLAG(isolated, Py_IsolatedFlag);
|
||||
COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
|
||||
if (Py_UTF8Mode > 0) {
|
||||
config->utf8_mode = Py_UTF8Mode;
|
||||
}
|
||||
#ifdef MS_WINDOWS
|
||||
COPY_FLAG(legacy_windows_fs_encoding, Py_LegacyWindowsFSEncodingFlag);
|
||||
#endif
|
||||
if (Py_UTF8Mode > 0) {
|
||||
config->utf8_mode = 1;
|
||||
}
|
||||
|
||||
#undef COPY_FLAG
|
||||
#undef COPY_NOT_FLAG
|
||||
|
|
@ -402,11 +479,11 @@ static void
|
|||
_PyPreConfig_SetGlobalConfig(const _PyPreConfig *config)
|
||||
{
|
||||
#define COPY_FLAG(ATTR, VAR) \
|
||||
if (config->ATTR != -1) { \
|
||||
if (config->ATTR >= 0) { \
|
||||
VAR = config->ATTR; \
|
||||
}
|
||||
#define COPY_NOT_FLAG(ATTR, VAR) \
|
||||
if (config->ATTR != -1) { \
|
||||
if (config->ATTR >= 0) { \
|
||||
VAR = !config->ATTR; \
|
||||
}
|
||||
|
||||
|
|
@ -512,12 +589,7 @@ preconfig_init_utf8_mode(_PyPreConfig *config, const _PyPreCmdline *cmdline)
|
|||
}
|
||||
|
||||
const wchar_t *xopt;
|
||||
if (cmdline) {
|
||||
xopt = _Py_get_xoption(&cmdline->xoptions, L"utf8");
|
||||
}
|
||||
else {
|
||||
xopt = NULL;
|
||||
}
|
||||
xopt = _Py_get_xoption(&cmdline->xoptions, L"utf8");
|
||||
if (xopt) {
|
||||
wchar_t *sep = wcschr(xopt, L'=');
|
||||
if (sep) {
|
||||
|
|
@ -577,6 +649,12 @@ preconfig_init_utf8_mode(_PyPreConfig *config, const _PyPreCmdline *cmdline)
|
|||
static void
|
||||
preconfig_init_coerce_c_locale(_PyPreConfig *config)
|
||||
{
|
||||
if (!config->configure_locale) {
|
||||
config->coerce_c_locale = 0;
|
||||
config->coerce_c_locale_warn = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
const char *env = _Py_GetEnv(config->use_environment, "PYTHONCOERCECLOCALE");
|
||||
if (env) {
|
||||
if (strcmp(env, "0") == 0) {
|
||||
|
|
@ -585,7 +663,9 @@ preconfig_init_coerce_c_locale(_PyPreConfig *config)
|
|||
}
|
||||
}
|
||||
else if (strcmp(env, "warn") == 0) {
|
||||
config->coerce_c_locale_warn = 1;
|
||||
if (config->coerce_c_locale_warn < 0) {
|
||||
config->coerce_c_locale_warn = 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (config->coerce_c_locale < 0) {
|
||||
|
|
@ -597,44 +677,42 @@ preconfig_init_coerce_c_locale(_PyPreConfig *config)
|
|||
/* Test if coerce_c_locale equals to -1 or equals to 1:
|
||||
PYTHONCOERCECLOCALE=1 doesn't imply that the C locale is always coerced.
|
||||
It is only coerced if if the LC_CTYPE locale is "C". */
|
||||
if (config->coerce_c_locale == 0 || config->coerce_c_locale == 2) {
|
||||
return;
|
||||
if (config->coerce_c_locale < 0 || config->coerce_c_locale == 1) {
|
||||
/* The C locale enables the C locale coercion (PEP 538) */
|
||||
if (_Py_LegacyLocaleDetected(0)) {
|
||||
config->coerce_c_locale = 2;
|
||||
}
|
||||
else {
|
||||
config->coerce_c_locale = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* The C locale enables the C locale coercion (PEP 538) */
|
||||
if (_Py_LegacyLocaleDetected()) {
|
||||
config->coerce_c_locale = 2;
|
||||
if (config->coerce_c_locale_warn < 0) {
|
||||
config->coerce_c_locale_warn = 0;
|
||||
}
|
||||
else {
|
||||
config->coerce_c_locale = 0;
|
||||
}
|
||||
|
||||
assert(config->coerce_c_locale >= 0);
|
||||
}
|
||||
|
||||
|
||||
static _PyInitError
|
||||
preconfig_init_allocator(_PyPreConfig *config)
|
||||
{
|
||||
if (config->allocator == NULL) {
|
||||
if (config->allocator == PYMEM_ALLOCATOR_NOT_SET) {
|
||||
/* bpo-34247. The PYTHONMALLOC environment variable has the priority
|
||||
over PYTHONDEV env var and "-X dev" command line option.
|
||||
For example, PYTHONMALLOC=malloc PYTHONDEVMODE=1 sets the memory
|
||||
allocators to "malloc" (and not to "debug"). */
|
||||
const char *allocator = _Py_GetEnv(config->use_environment, "PYTHONMALLOC");
|
||||
if (allocator) {
|
||||
config->allocator = _PyMem_RawStrdup(allocator);
|
||||
if (config->allocator == NULL) {
|
||||
return _Py_INIT_NO_MEMORY();
|
||||
const char *envvar = _Py_GetEnv(config->use_environment, "PYTHONMALLOC");
|
||||
if (envvar) {
|
||||
PyMemAllocatorName name;
|
||||
if (_PyMem_GetAllocatorName(envvar, &name) < 0) {
|
||||
return _Py_INIT_ERR("PYTHONMALLOC: unknown allocator");
|
||||
}
|
||||
config->allocator = (int)name;
|
||||
}
|
||||
}
|
||||
|
||||
if (config->dev_mode && config->allocator == NULL) {
|
||||
config->allocator = _PyMem_RawStrdup("debug");
|
||||
if (config->allocator == NULL) {
|
||||
return _Py_INIT_NO_MEMORY();
|
||||
}
|
||||
if (config->dev_mode && config->allocator == PYMEM_ALLOCATOR_NOT_SET) {
|
||||
config->allocator = PYMEM_ALLOCATOR_DEBUG;
|
||||
}
|
||||
return _Py_INIT_OK();
|
||||
}
|
||||
|
|
@ -673,6 +751,7 @@ preconfig_read(_PyPreConfig *config, _PyPreCmdline *cmdline)
|
|||
}
|
||||
|
||||
assert(config->coerce_c_locale >= 0);
|
||||
assert(config->coerce_c_locale_warn >= 0);
|
||||
#ifdef MS_WINDOWS
|
||||
assert(config->legacy_windows_fs_encoding >= 0);
|
||||
#endif
|
||||
|
|
@ -714,13 +793,13 @@ _PyPreConfig_Read(_PyPreConfig *config, const _PyArgv *args)
|
|||
}
|
||||
|
||||
/* Save the config to be able to restore it if encodings change */
|
||||
_PyPreConfig save_config = _PyPreConfig_INIT;
|
||||
if (_PyPreConfig_Copy(&save_config, config) < 0) {
|
||||
return _Py_INIT_NO_MEMORY();
|
||||
}
|
||||
_PyPreConfig save_config;
|
||||
_PyPreConfig_InitFromPreConfig(&save_config, config);
|
||||
|
||||
/* Set LC_CTYPE to the user preferred locale */
|
||||
_Py_SetLocaleFromEnv(LC_CTYPE);
|
||||
if (config->configure_locale) {
|
||||
_Py_SetLocaleFromEnv(LC_CTYPE);
|
||||
}
|
||||
|
||||
_PyPreCmdline cmdline = _PyPreCmdline_INIT;
|
||||
int init_utf8_mode = Py_UTF8Mode;
|
||||
|
|
@ -798,10 +877,7 @@ _PyPreConfig_Read(_PyPreConfig *config, const _PyArgv *args)
|
|||
just keep UTF-8 Mode value. */
|
||||
int new_utf8_mode = config->utf8_mode;
|
||||
int new_coerce_c_locale = config->coerce_c_locale;
|
||||
if (_PyPreConfig_Copy(config, &save_config) < 0) {
|
||||
err = _Py_INIT_NO_MEMORY();
|
||||
goto done;
|
||||
}
|
||||
_PyPreConfig_Copy(config, &save_config);
|
||||
config->utf8_mode = new_utf8_mode;
|
||||
config->coerce_c_locale = new_coerce_c_locale;
|
||||
|
||||
|
|
@ -815,7 +891,6 @@ _PyPreConfig_Read(_PyPreConfig *config, const _PyArgv *args)
|
|||
setlocale(LC_CTYPE, init_ctype_locale);
|
||||
PyMem_RawFree(init_ctype_locale);
|
||||
}
|
||||
_PyPreConfig_Clear(&save_config);
|
||||
Py_UTF8Mode = init_utf8_mode ;
|
||||
#ifdef MS_WINDOWS
|
||||
Py_LegacyWindowsFSEncodingFlag = init_legacy_encoding;
|
||||
|
|
@ -825,40 +900,6 @@ _PyPreConfig_Read(_PyPreConfig *config, const _PyArgv *args)
|
|||
}
|
||||
|
||||
|
||||
static _PyInitError
|
||||
_PyPreConfig_SetAllocator(_PyPreConfig *config)
|
||||
{
|
||||
assert(!_PyRuntime.core_initialized);
|
||||
|
||||
PyMemAllocatorEx old_alloc;
|
||||
PyMem_GetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
|
||||
|
||||
if (_PyMem_SetupAllocators(config->allocator) < 0) {
|
||||
return _Py_INIT_ERR("Unknown PYTHONMALLOC allocator");
|
||||
}
|
||||
|
||||
/* Copy the pre-configuration with the new allocator */
|
||||
_PyPreConfig config2 = _PyPreConfig_INIT;
|
||||
if (_PyPreConfig_Copy(&config2, config) < 0) {
|
||||
_PyPreConfig_Clear(&config2);
|
||||
PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
|
||||
return _Py_INIT_NO_MEMORY();
|
||||
}
|
||||
|
||||
/* Free the old config and replace config with config2. Since config now
|
||||
owns the data, don't free config2. */
|
||||
PyMemAllocatorEx new_alloc;
|
||||
PyMem_GetAllocator(PYMEM_DOMAIN_RAW, &new_alloc);
|
||||
PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
|
||||
_PyPreConfig_Clear(config);
|
||||
PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &new_alloc);
|
||||
|
||||
*config = config2;
|
||||
|
||||
return _Py_INIT_OK();
|
||||
}
|
||||
|
||||
|
||||
/* Write the pre-configuration:
|
||||
|
||||
- set the memory allocators
|
||||
|
|
@ -866,44 +907,46 @@ _PyPreConfig_SetAllocator(_PyPreConfig *config)
|
|||
- set the LC_CTYPE locale (coerce C locale, PEP 538) and set the UTF-8 mode
|
||||
(PEP 540)
|
||||
|
||||
If the memory allocator is changed, config is re-allocated with new
|
||||
allocator. So calling _PyPreConfig_Clear(config) is safe after this call.
|
||||
The applied configuration is written into _PyRuntime.preconfig.
|
||||
If the C locale cannot be coerced, set coerce_c_locale to 0.
|
||||
|
||||
Do nothing if called after Py_Initialize(): ignore the new
|
||||
pre-configuration. */
|
||||
_PyInitError
|
||||
_PyPreConfig_Write(_PyPreConfig *config)
|
||||
_PyPreConfig_Write(const _PyPreConfig *src_config)
|
||||
{
|
||||
_PyPreConfig config;
|
||||
_PyPreConfig_InitFromPreConfig(&config, src_config);
|
||||
|
||||
if (_PyRuntime.core_initialized) {
|
||||
/* bpo-34008: Calling this functions after Py_Initialize() ignores
|
||||
the new configuration. */
|
||||
return _Py_INIT_OK();
|
||||
}
|
||||
|
||||
if (config->allocator != NULL) {
|
||||
_PyInitError err = _PyPreConfig_SetAllocator(config);
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
return err;
|
||||
PyMemAllocatorName name = (PyMemAllocatorName)config.allocator;
|
||||
if (name != PYMEM_ALLOCATOR_NOT_SET) {
|
||||
if (_PyMem_SetupAllocators(name) < 0) {
|
||||
return _Py_INIT_ERR("Unknown PYTHONMALLOC allocator");
|
||||
}
|
||||
}
|
||||
|
||||
_PyPreConfig_SetGlobalConfig(config);
|
||||
_PyPreConfig_SetGlobalConfig(&config);
|
||||
|
||||
if (config->coerce_c_locale) {
|
||||
_Py_CoerceLegacyLocale(config->coerce_c_locale_warn);
|
||||
if (config.configure_locale) {
|
||||
if (config.coerce_c_locale) {
|
||||
if (!_Py_CoerceLegacyLocale(config.coerce_c_locale_warn)) {
|
||||
/* C locale not coerced */
|
||||
config.coerce_c_locale = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set LC_CTYPE to the user preferred locale */
|
||||
_Py_SetLocaleFromEnv(LC_CTYPE);
|
||||
}
|
||||
|
||||
/* Set LC_CTYPE to the user preferred locale */
|
||||
_Py_SetLocaleFromEnv(LC_CTYPE);
|
||||
|
||||
/* Write the new pre-configuration into _PyRuntime */
|
||||
PyMemAllocatorEx old_alloc;
|
||||
_PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
|
||||
int res = _PyPreConfig_Copy(&_PyRuntime.preconfig, config);
|
||||
PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
|
||||
if (res < 0) {
|
||||
return _Py_INIT_NO_MEMORY();
|
||||
}
|
||||
_PyPreConfig_Copy(&_PyRuntime.preconfig, &config);
|
||||
|
||||
return _Py_INIT_OK();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,14 +4,16 @@
|
|||
|
||||
#include "Python-ast.h"
|
||||
#undef Yield /* undefine macro conflicting with <winbase.h> */
|
||||
#include "pycore_coreconfig.h"
|
||||
#include "pycore_ceval.h"
|
||||
#include "pycore_context.h"
|
||||
#include "pycore_coreconfig.h"
|
||||
#include "pycore_fileutils.h"
|
||||
#include "pycore_hamt.h"
|
||||
#include "pycore_pathconfig.h"
|
||||
#include "pycore_pylifecycle.h"
|
||||
#include "pycore_pymem.h"
|
||||
#include "pycore_pystate.h"
|
||||
#include "pycore_traceback.h"
|
||||
#include "grammar.h"
|
||||
#include "node.h"
|
||||
#include "token.h"
|
||||
|
|
@ -149,12 +151,13 @@ init_importlib(PyInterpreterState *interp, PyObject *sysmod)
|
|||
PyObject *importlib;
|
||||
PyObject *impmod;
|
||||
PyObject *value;
|
||||
int verbose = interp->core_config.verbose;
|
||||
|
||||
/* Import _importlib through its frozen version, _frozen_importlib. */
|
||||
if (PyImport_ImportFrozenModule("_frozen_importlib") <= 0) {
|
||||
return _Py_INIT_ERR("can't import _frozen_importlib");
|
||||
}
|
||||
else if (Py_VerboseFlag) {
|
||||
else if (verbose) {
|
||||
PySys_FormatStderr("import _frozen_importlib # frozen\n");
|
||||
}
|
||||
importlib = PyImport_AddModule("_frozen_importlib");
|
||||
|
|
@ -174,7 +177,7 @@ init_importlib(PyInterpreterState *interp, PyObject *sysmod)
|
|||
if (impmod == NULL) {
|
||||
return _Py_INIT_ERR("can't import _imp");
|
||||
}
|
||||
else if (Py_VerboseFlag) {
|
||||
else if (verbose) {
|
||||
PySys_FormatStderr("import _imp # builtin\n");
|
||||
}
|
||||
if (_PyImport_SetModuleString("_imp", impmod) < 0) {
|
||||
|
|
@ -204,7 +207,7 @@ init_importlib_external(PyInterpreterState *interp)
|
|||
return _Py_INIT_ERR("external importer setup failed");
|
||||
}
|
||||
Py_DECREF(value);
|
||||
return _PyImportZip_Init();
|
||||
return _PyImportZip_Init(interp);
|
||||
}
|
||||
|
||||
/* Helper functions to better handle the legacy C locale
|
||||
|
|
@ -228,9 +231,18 @@ init_importlib_external(PyInterpreterState *interp)
|
|||
*/
|
||||
|
||||
int
|
||||
_Py_LegacyLocaleDetected(void)
|
||||
_Py_LegacyLocaleDetected(int warn)
|
||||
{
|
||||
#ifndef MS_WINDOWS
|
||||
if (!warn) {
|
||||
const char *locale_override = getenv("LC_ALL");
|
||||
if (locale_override != NULL && *locale_override != '\0') {
|
||||
/* Don't coerce C locale if the LC_ALL environment variable
|
||||
is set */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* On non-Windows systems, the C locale is considered a legacy locale */
|
||||
/* XXX (ncoghlan): some platforms (notably Mac OS X) don't appear to treat
|
||||
* the POSIX locale as a simple alias for the C locale, so
|
||||
|
|
@ -254,7 +266,7 @@ static void
|
|||
emit_stderr_warning_for_legacy_locale(_PyRuntimeState *runtime)
|
||||
{
|
||||
const _PyPreConfig *preconfig = &runtime->preconfig;
|
||||
if (preconfig->coerce_c_locale_warn && _Py_LegacyLocaleDetected()) {
|
||||
if (preconfig->coerce_c_locale_warn && _Py_LegacyLocaleDetected(1)) {
|
||||
PySys_FormatStderr("%s", _C_LOCALE_WARNING);
|
||||
}
|
||||
}
|
||||
|
|
@ -289,7 +301,7 @@ static const char C_LOCALE_COERCION_WARNING[] =
|
|||
"Python detected LC_CTYPE=C: LC_CTYPE coerced to %.20s (set another locale "
|
||||
"or PYTHONCOERCECLOCALE=0 to disable this locale coercion behavior).\n";
|
||||
|
||||
static void
|
||||
static int
|
||||
_coerce_default_locale_settings(int warn, const _LocaleCoercionTarget *target)
|
||||
{
|
||||
const char *newloc = target->locale_name;
|
||||
|
|
@ -301,7 +313,7 @@ _coerce_default_locale_settings(int warn, const _LocaleCoercionTarget *target)
|
|||
if (setenv("LC_CTYPE", newloc, 1)) {
|
||||
fprintf(stderr,
|
||||
"Error setting LC_CTYPE, skipping C locale coercion\n");
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
if (warn) {
|
||||
fprintf(stderr, C_LOCALE_COERCION_WARNING, newloc);
|
||||
|
|
@ -309,18 +321,20 @@ _coerce_default_locale_settings(int warn, const _LocaleCoercionTarget *target)
|
|||
|
||||
/* Reconfigure with the overridden environment variables */
|
||||
_Py_SetLocaleFromEnv(LC_ALL);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
int
|
||||
_Py_CoerceLegacyLocale(int warn)
|
||||
{
|
||||
int coerced = 0;
|
||||
#ifdef PY_COERCE_C_LOCALE
|
||||
char *oldloc = NULL;
|
||||
|
||||
oldloc = _PyMem_RawStrdup(setlocale(LC_CTYPE, NULL));
|
||||
if (oldloc == NULL) {
|
||||
return;
|
||||
return coerced;
|
||||
}
|
||||
|
||||
const char *locale_override = getenv("LC_ALL");
|
||||
|
|
@ -342,7 +356,7 @@ _Py_CoerceLegacyLocale(int warn)
|
|||
}
|
||||
#endif
|
||||
/* Successfully configured locale, so make it the default */
|
||||
_coerce_default_locale_settings(warn, target);
|
||||
coerced = _coerce_default_locale_settings(warn, target);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
|
@ -354,6 +368,7 @@ _Py_CoerceLegacyLocale(int warn)
|
|||
done:
|
||||
PyMem_RawFree(oldloc);
|
||||
#endif
|
||||
return coerced;
|
||||
}
|
||||
|
||||
/* _Py_SetLocaleFromEnv() is a wrapper around setlocale(category, "") to
|
||||
|
|
@ -432,9 +447,9 @@ _Py_SetLocaleFromEnv(int category)
|
|||
*/
|
||||
|
||||
static _PyInitError
|
||||
_Py_Initialize_ReconfigureCore(_PyRuntimeState *runtime,
|
||||
PyInterpreterState **interp_p,
|
||||
const _PyCoreConfig *core_config)
|
||||
pyinit_core_reconfigure(_PyRuntimeState *runtime,
|
||||
PyInterpreterState **interp_p,
|
||||
const _PyCoreConfig *core_config)
|
||||
{
|
||||
_PyInitError err;
|
||||
PyThreadState *tstate = _PyThreadState_GET();
|
||||
|
|
@ -527,7 +542,7 @@ pycore_create_interpreter(_PyRuntimeState *runtime,
|
|||
another running thread (see issue #9901).
|
||||
Instead we destroy the previously created GIL here, which ensures
|
||||
that we can call Py_Initialize / Py_FinalizeEx multiple times. */
|
||||
_PyEval_FiniThreads();
|
||||
_PyEval_FiniThreads(&runtime->ceval);
|
||||
|
||||
/* Auto-thread-state API */
|
||||
_PyGILState_Init(runtime, interp, tstate);
|
||||
|
|
@ -572,6 +587,12 @@ pycore_init_types(void)
|
|||
if (!_PyContext_Init()) {
|
||||
return _Py_INIT_ERR("can't init context");
|
||||
}
|
||||
|
||||
err = _PyErr_Init();
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
return err;
|
||||
}
|
||||
|
||||
return _Py_INIT_OK();
|
||||
}
|
||||
|
||||
|
|
@ -636,9 +657,9 @@ pycore_init_import_warnings(PyInterpreterState *interp, PyObject *sysmod)
|
|||
|
||||
|
||||
static _PyInitError
|
||||
_Py_InitializeCore_impl(_PyRuntimeState *runtime,
|
||||
PyInterpreterState **interp_p,
|
||||
const _PyCoreConfig *core_config)
|
||||
pyinit_core_config(_PyRuntimeState *runtime,
|
||||
PyInterpreterState **interp_p,
|
||||
const _PyCoreConfig *core_config)
|
||||
{
|
||||
PyInterpreterState *interp;
|
||||
|
||||
|
|
@ -688,6 +709,10 @@ _Py_PreInitializeFromPyArgv(const _PyPreConfig *src_config, const _PyArgv *args)
|
|||
{
|
||||
_PyInitError err;
|
||||
|
||||
if (src_config == NULL) {
|
||||
return _Py_INIT_ERR("preinitialization config is NULL");
|
||||
}
|
||||
|
||||
err = _PyRuntime_Initialize();
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
return err;
|
||||
|
|
@ -699,36 +724,26 @@ _Py_PreInitializeFromPyArgv(const _PyPreConfig *src_config, const _PyArgv *args)
|
|||
return _Py_INIT_OK();
|
||||
}
|
||||
|
||||
_PyPreConfig config = _PyPreConfig_INIT;
|
||||
|
||||
if (src_config) {
|
||||
if (_PyPreConfig_Copy(&config, src_config) < 0) {
|
||||
err = _Py_INIT_NO_MEMORY();
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
_PyPreConfig config;
|
||||
_PyPreConfig_InitFromPreConfig(&config, src_config);
|
||||
|
||||
err = _PyPreConfig_Read(&config, args);
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
goto done;
|
||||
return err;
|
||||
}
|
||||
|
||||
err = _PyPreConfig_Write(&config);
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
goto done;
|
||||
return err;
|
||||
}
|
||||
|
||||
runtime->pre_initialized = 1;
|
||||
err = _Py_INIT_OK();
|
||||
|
||||
done:
|
||||
_PyPreConfig_Clear(&config);
|
||||
return err;
|
||||
return _Py_INIT_OK();
|
||||
}
|
||||
|
||||
|
||||
_PyInitError
|
||||
_Py_PreInitializeFromArgs(const _PyPreConfig *src_config, int argc, char **argv)
|
||||
_Py_PreInitializeFromArgs(const _PyPreConfig *src_config, Py_ssize_t argc, char **argv)
|
||||
{
|
||||
_PyArgv args = {.use_bytes_argv = 1, .argc = argc, .bytes_argv = argv};
|
||||
return _Py_PreInitializeFromPyArgv(src_config, &args);
|
||||
|
|
@ -736,7 +751,7 @@ _Py_PreInitializeFromArgs(const _PyPreConfig *src_config, int argc, char **argv)
|
|||
|
||||
|
||||
_PyInitError
|
||||
_Py_PreInitializeFromWideArgs(const _PyPreConfig *src_config, int argc, wchar_t **argv)
|
||||
_Py_PreInitializeFromWideArgs(const _PyPreConfig *src_config, Py_ssize_t argc, wchar_t **argv)
|
||||
{
|
||||
_PyArgv args = {.use_bytes_argv = 0, .argc = argc, .wchar_argv = argv};
|
||||
return _Py_PreInitializeFromPyArgv(src_config, &args);
|
||||
|
|
@ -754,49 +769,34 @@ _PyInitError
|
|||
_Py_PreInitializeFromCoreConfig(const _PyCoreConfig *coreconfig,
|
||||
const _PyArgv *args)
|
||||
{
|
||||
_PyPreConfig config = _PyPreConfig_INIT;
|
||||
if (coreconfig != NULL) {
|
||||
_PyCoreConfig_GetCoreConfig(&config, coreconfig);
|
||||
}
|
||||
return _Py_PreInitializeFromPyArgv(&config, args);
|
||||
/* No need to clear config:
|
||||
_PyCoreConfig_GetCoreConfig() doesn't allocate memory */
|
||||
}
|
||||
assert(coreconfig != NULL);
|
||||
|
||||
|
||||
static _PyInitError
|
||||
pyinit_coreconfig(_PyRuntimeState *runtime,
|
||||
_PyCoreConfig *config,
|
||||
const _PyCoreConfig *src_config,
|
||||
const _PyArgv *args,
|
||||
PyInterpreterState **interp_p)
|
||||
{
|
||||
_PyInitError err;
|
||||
|
||||
if (src_config) {
|
||||
err = _PyCoreConfig_Copy(config, src_config);
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
if (args) {
|
||||
err = _PyCoreConfig_SetPyArgv(config, args);
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
err = _PyCoreConfig_Read(config);
|
||||
_PyInitError err = _PyRuntime_Initialize();
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
return err;
|
||||
}
|
||||
_PyRuntimeState *runtime = &_PyRuntime;
|
||||
|
||||
if (!runtime->core_initialized) {
|
||||
return _Py_InitializeCore_impl(runtime, interp_p, config);
|
||||
if (runtime->pre_initialized) {
|
||||
/* Already initialized: do nothing */
|
||||
return _Py_INIT_OK();
|
||||
}
|
||||
|
||||
_PyPreConfig preconfig;
|
||||
_PyPreConfig_InitFromCoreConfig(&preconfig, coreconfig);
|
||||
|
||||
if (!coreconfig->parse_argv) {
|
||||
return _Py_PreInitialize(&preconfig);
|
||||
}
|
||||
else if (args == NULL) {
|
||||
_PyArgv config_args = {
|
||||
.use_bytes_argv = 0,
|
||||
.argc = coreconfig->argv.length,
|
||||
.wchar_argv = coreconfig->argv.items};
|
||||
return _Py_PreInitializeFromPyArgv(&preconfig, &config_args);
|
||||
}
|
||||
else {
|
||||
return _Py_Initialize_ReconfigureCore(runtime, interp_p, config);
|
||||
return _Py_PreInitializeFromPyArgv(&preconfig, args);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -819,10 +819,10 @@ pyinit_coreconfig(_PyRuntimeState *runtime,
|
|||
* safe to call without calling Py_Initialize first)
|
||||
*/
|
||||
static _PyInitError
|
||||
_Py_InitializeCore(_PyRuntimeState *runtime,
|
||||
const _PyCoreConfig *src_config,
|
||||
const _PyArgv *args,
|
||||
PyInterpreterState **interp_p)
|
||||
pyinit_core(_PyRuntimeState *runtime,
|
||||
const _PyCoreConfig *src_config,
|
||||
const _PyArgv *args,
|
||||
PyInterpreterState **interp_p)
|
||||
{
|
||||
_PyInitError err;
|
||||
|
||||
|
|
@ -831,9 +831,38 @@ _Py_InitializeCore(_PyRuntimeState *runtime,
|
|||
return err;
|
||||
}
|
||||
|
||||
_PyCoreConfig local_config = _PyCoreConfig_INIT;
|
||||
err = pyinit_coreconfig(runtime, &local_config, src_config, args, interp_p);
|
||||
_PyCoreConfig_Clear(&local_config);
|
||||
_PyCoreConfig config;
|
||||
_PyCoreConfig_InitCompatConfig(&config);
|
||||
|
||||
err = _PyCoreConfig_Copy(&config, src_config);
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (args) {
|
||||
err = _PyCoreConfig_SetPyArgv(&config, args);
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
err = _PyCoreConfig_Read(&config);
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!runtime->core_initialized) {
|
||||
err = pyinit_core_config(runtime, interp_p, &config);
|
||||
}
|
||||
else {
|
||||
err = pyinit_core_reconfigure(runtime, interp_p, &config);
|
||||
}
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
done:
|
||||
_PyCoreConfig_Clear(&config);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
|
@ -871,8 +900,7 @@ _Py_ReconfigureMainInterpreter(PyInterpreterState *interp)
|
|||
* non-zero return code.
|
||||
*/
|
||||
static _PyInitError
|
||||
_Py_InitializeMainInterpreter(_PyRuntimeState *runtime,
|
||||
PyInterpreterState *interp)
|
||||
pyinit_main(_PyRuntimeState *runtime, PyInterpreterState *interp)
|
||||
{
|
||||
if (!runtime->core_initialized) {
|
||||
return _Py_INIT_ERR("runtime core not initialized");
|
||||
|
|
@ -968,11 +996,30 @@ _Py_InitializeMainInterpreter(_PyRuntimeState *runtime,
|
|||
return _Py_INIT_OK();
|
||||
}
|
||||
|
||||
|
||||
_PyInitError
|
||||
_Py_InitializeMain(void)
|
||||
{
|
||||
_PyInitError err = _PyRuntime_Initialize();
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
return err;
|
||||
}
|
||||
_PyRuntimeState *runtime = &_PyRuntime;
|
||||
PyInterpreterState *interp = _PyRuntimeState_GetThreadState(runtime)->interp;
|
||||
|
||||
return pyinit_main(runtime, interp);
|
||||
}
|
||||
|
||||
|
||||
#undef _INIT_DEBUG_PRINT
|
||||
|
||||
static _PyInitError
|
||||
init_python(const _PyCoreConfig *config, const _PyArgv *args)
|
||||
pyinit_python(const _PyCoreConfig *config, const _PyArgv *args)
|
||||
{
|
||||
if (config == NULL) {
|
||||
return _Py_INIT_ERR("initialization config is NULL");
|
||||
}
|
||||
|
||||
_PyInitError err;
|
||||
|
||||
err = _PyRuntime_Initialize();
|
||||
|
|
@ -982,14 +1029,14 @@ init_python(const _PyCoreConfig *config, const _PyArgv *args)
|
|||
_PyRuntimeState *runtime = &_PyRuntime;
|
||||
|
||||
PyInterpreterState *interp = NULL;
|
||||
err = _Py_InitializeCore(runtime, config, args, &interp);
|
||||
err = pyinit_core(runtime, config, args, &interp);
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
return err;
|
||||
}
|
||||
config = &interp->core_config;
|
||||
|
||||
if (!config->_frozen) {
|
||||
err = _Py_InitializeMainInterpreter(runtime, interp);
|
||||
if (config->_init_main) {
|
||||
err = pyinit_main(runtime, interp);
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
return err;
|
||||
}
|
||||
|
|
@ -1000,25 +1047,27 @@ init_python(const _PyCoreConfig *config, const _PyArgv *args)
|
|||
|
||||
|
||||
_PyInitError
|
||||
_Py_InitializeFromArgs(const _PyCoreConfig *config, int argc, char **argv)
|
||||
_Py_InitializeFromArgs(const _PyCoreConfig *config,
|
||||
Py_ssize_t argc, char * const *argv)
|
||||
{
|
||||
_PyArgv args = {.use_bytes_argv = 1, .argc = argc, .bytes_argv = argv};
|
||||
return init_python(config, &args);
|
||||
return pyinit_python(config, &args);
|
||||
}
|
||||
|
||||
|
||||
_PyInitError
|
||||
_Py_InitializeFromWideArgs(const _PyCoreConfig *config, int argc, wchar_t **argv)
|
||||
_Py_InitializeFromWideArgs(const _PyCoreConfig *config,
|
||||
Py_ssize_t argc, wchar_t * const *argv)
|
||||
{
|
||||
_PyArgv args = {.use_bytes_argv = 0, .argc = argc, .wchar_argv = argv};
|
||||
return init_python(config, &args);
|
||||
return pyinit_python(config, &args);
|
||||
}
|
||||
|
||||
|
||||
_PyInitError
|
||||
_Py_InitializeFromConfig(const _PyCoreConfig *config)
|
||||
{
|
||||
return init_python(config, NULL);
|
||||
return pyinit_python(config, NULL);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1038,7 +1087,8 @@ Py_InitializeEx(int install_sigs)
|
|||
return;
|
||||
}
|
||||
|
||||
_PyCoreConfig config = _PyCoreConfig_INIT;
|
||||
_PyCoreConfig config;
|
||||
_PyCoreConfig_InitCompatConfig(&config);
|
||||
config.install_signal_handlers = install_sigs;
|
||||
|
||||
err = _Py_InitializeFromConfig(&config);
|
||||
|
|
@ -1135,10 +1185,10 @@ Py_FinalizeEx(void)
|
|||
wait_for_thread_shutdown();
|
||||
|
||||
// Make any remaining pending calls.
|
||||
_Py_FinishPendingCalls();
|
||||
_Py_FinishPendingCalls(runtime);
|
||||
|
||||
/* Get current thread state and interpreter pointer */
|
||||
PyThreadState *tstate = _PyThreadState_GET();
|
||||
PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime);
|
||||
PyInterpreterState *interp = tstate->interp;
|
||||
|
||||
/* The interpreter is still entirely intact at this point, and the
|
||||
|
|
@ -1200,6 +1250,13 @@ Py_FinalizeEx(void)
|
|||
/* nothing */;
|
||||
#endif
|
||||
|
||||
/* Clear all loghooks */
|
||||
/* We want minimal exposure of this function, so define the extern
|
||||
* here. The linker should discover the correct function without
|
||||
* exporting a symbol. */
|
||||
extern void _PySys_ClearAuditHooks(void);
|
||||
_PySys_ClearAuditHooks();
|
||||
|
||||
/* Destroy all modules */
|
||||
PyImport_Cleanup();
|
||||
|
||||
|
|
@ -1288,7 +1345,7 @@ Py_FinalizeEx(void)
|
|||
PyDict_Fini();
|
||||
PySlice_Fini();
|
||||
_PyGC_Fini(runtime);
|
||||
_PyWarnings_Fini(runtime);
|
||||
_PyWarnings_Fini(interp);
|
||||
_Py_HashRandomization_Fini();
|
||||
_PyArg_Fini();
|
||||
PyAsyncGen_Fini();
|
||||
|
|
@ -1410,6 +1467,12 @@ new_interpreter(PyThreadState **tstate_p)
|
|||
return err;
|
||||
}
|
||||
|
||||
err = _PyErr_Init();
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
/* XXX The following is lax in error checking */
|
||||
PyObject *modules = PyDict_New();
|
||||
if (modules == NULL) {
|
||||
|
|
@ -2122,17 +2185,14 @@ Py_FatalError(const char *msg)
|
|||
void _Py_NO_RETURN
|
||||
_Py_ExitInitError(_PyInitError err)
|
||||
{
|
||||
assert(_Py_INIT_FAILED(err));
|
||||
if (_Py_INIT_IS_EXIT(err)) {
|
||||
#ifdef MS_WINDOWS
|
||||
ExitProcess(err.exitcode);
|
||||
#else
|
||||
exit(err.exitcode);
|
||||
#endif
|
||||
}
|
||||
else if (_Py_INIT_IS_ERROR(err)) {
|
||||
fatal_error(err._func, err.err_msg, 1);
|
||||
}
|
||||
else {
|
||||
assert(_Py_INIT_IS_ERROR(err));
|
||||
fatal_error(err._func, err.err_msg, 1);
|
||||
Py_FatalError("_Py_ExitInitError() must not be called on success");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,9 +2,11 @@
|
|||
/* Thread and interpreter state structures and their interfaces */
|
||||
|
||||
#include "Python.h"
|
||||
#include "pycore_ceval.h"
|
||||
#include "pycore_coreconfig.h"
|
||||
#include "pycore_pymem.h"
|
||||
#include "pycore_pystate.h"
|
||||
#include "pycore_pylifecycle.h"
|
||||
|
||||
/* --------------------------------------------------------------------------
|
||||
CAUTION
|
||||
|
|
@ -38,17 +40,27 @@ extern "C" {
|
|||
/* Forward declarations */
|
||||
static PyThreadState *_PyGILState_GetThisThreadState(struct _gilstate_runtime_state *gilstate);
|
||||
static void _PyThreadState_Delete(_PyRuntimeState *runtime, PyThreadState *tstate);
|
||||
static PyThreadState *_PyThreadState_Swap(struct _gilstate_runtime_state *gilstate, PyThreadState *newts);
|
||||
|
||||
|
||||
static _PyInitError
|
||||
_PyRuntimeState_Init_impl(_PyRuntimeState *runtime)
|
||||
{
|
||||
/* We preserve the hook across init, because there is
|
||||
currently no public API to set it between runtime
|
||||
initialization and interpreter initialization. */
|
||||
void *open_code_hook = runtime->open_code_hook;
|
||||
void *open_code_userdata = runtime->open_code_userdata;
|
||||
_Py_AuditHookEntry *audit_hook_head = runtime->audit_hook_head;
|
||||
|
||||
memset(runtime, 0, sizeof(*runtime));
|
||||
|
||||
runtime->open_code_hook = open_code_hook;
|
||||
runtime->open_code_userdata = open_code_userdata;
|
||||
runtime->audit_hook_head = audit_hook_head;
|
||||
|
||||
_PyGC_Initialize(&runtime->gc);
|
||||
_PyEval_Initialize(&runtime->ceval);
|
||||
runtime->preconfig = _PyPreConfig_INIT;
|
||||
_PyPreConfig_InitPythonConfig(&runtime->preconfig);
|
||||
|
||||
runtime->gilstate.check_enabled = 1;
|
||||
|
||||
|
|
@ -105,8 +117,6 @@ _PyRuntimeState_Fini(_PyRuntimeState *runtime)
|
|||
runtime->xidregistry.mutex = NULL;
|
||||
}
|
||||
|
||||
_PyPreConfig_Clear(&runtime->preconfig);
|
||||
|
||||
PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
|
||||
}
|
||||
|
||||
|
|
@ -182,6 +192,10 @@ _PyInterpreterState_Enable(_PyRuntimeState *runtime)
|
|||
PyInterpreterState *
|
||||
PyInterpreterState_New(void)
|
||||
{
|
||||
if (PySys_Audit("cpython.PyInterpreterState_New", NULL) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PyInterpreterState *interp = PyMem_RawMalloc(sizeof(PyInterpreterState));
|
||||
if (interp == NULL) {
|
||||
return NULL;
|
||||
|
|
@ -190,7 +204,13 @@ PyInterpreterState_New(void)
|
|||
memset(interp, 0, sizeof(*interp));
|
||||
interp->id_refcount = -1;
|
||||
interp->check_interval = 100;
|
||||
interp->core_config = _PyCoreConfig_INIT;
|
||||
|
||||
_PyInitError err = _PyCoreConfig_InitPythonConfig(&interp->core_config);
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
PyMem_RawFree(interp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
interp->eval_frame = _PyEval_EvalFrameDefault;
|
||||
#ifdef HAVE_DLOPEN
|
||||
#if HAVE_DECL_RTLD_NOW
|
||||
|
|
@ -228,6 +248,8 @@ PyInterpreterState_New(void)
|
|||
|
||||
interp->tstate_next_unique_id = 0;
|
||||
|
||||
interp->audit_hooks = NULL;
|
||||
|
||||
return interp;
|
||||
}
|
||||
|
||||
|
|
@ -235,11 +257,18 @@ PyInterpreterState_New(void)
|
|||
static void
|
||||
_PyInterpreterState_Clear(_PyRuntimeState *runtime, PyInterpreterState *interp)
|
||||
{
|
||||
if (PySys_Audit("cpython.PyInterpreterState_Clear", NULL) < 0) {
|
||||
PyErr_Clear();
|
||||
}
|
||||
|
||||
HEAD_LOCK(runtime);
|
||||
for (PyThreadState *p = interp->tstate_head; p != NULL; p = p->next) {
|
||||
PyThreadState_Clear(p);
|
||||
}
|
||||
HEAD_UNLOCK(runtime);
|
||||
|
||||
Py_CLEAR(interp->audit_hooks);
|
||||
|
||||
_PyCoreConfig_Clear(&interp->core_config);
|
||||
Py_CLEAR(interp->codec_search_path);
|
||||
Py_CLEAR(interp->codec_search_cache);
|
||||
|
|
@ -257,6 +286,9 @@ _PyInterpreterState_Clear(_PyRuntimeState *runtime, PyInterpreterState *interp)
|
|||
Py_CLEAR(interp->after_forkers_parent);
|
||||
Py_CLEAR(interp->after_forkers_child);
|
||||
#endif
|
||||
if (runtime->finalizing == NULL) {
|
||||
_PyWarnings_Fini(interp);
|
||||
}
|
||||
// XXX Once we have one allocator per interpreter (i.e.
|
||||
// per-interpreter GC) we must ensure that all of the interpreter's
|
||||
// objects have been cleaned up at the point.
|
||||
|
|
@ -863,9 +895,8 @@ PyThreadState_DeleteCurrent()
|
|||
* be kept in those other interpreteres.
|
||||
*/
|
||||
void
|
||||
_PyThreadState_DeleteExcept(PyThreadState *tstate)
|
||||
_PyThreadState_DeleteExcept(_PyRuntimeState *runtime, PyThreadState *tstate)
|
||||
{
|
||||
_PyRuntimeState *runtime = &_PyRuntime;
|
||||
PyInterpreterState *interp = tstate->interp;
|
||||
PyThreadState *p, *next, *garbage;
|
||||
HEAD_LOCK(runtime);
|
||||
|
|
@ -911,7 +942,7 @@ PyThreadState_Get(void)
|
|||
}
|
||||
|
||||
|
||||
static PyThreadState *
|
||||
PyThreadState *
|
||||
_PyThreadState_Swap(struct _gilstate_runtime_state *gilstate, PyThreadState *newts)
|
||||
{
|
||||
PyThreadState *oldts = _PyRuntimeGILState_GetThreadState(gilstate);
|
||||
|
|
@ -976,8 +1007,8 @@ PyThreadState_GetDict(void)
|
|||
int
|
||||
PyThreadState_SetAsyncExc(unsigned long id, PyObject *exc)
|
||||
{
|
||||
PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE();
|
||||
PyThreadState *p;
|
||||
_PyRuntimeState *runtime = &_PyRuntime;
|
||||
PyInterpreterState *interp = _PyRuntimeState_GetThreadState(runtime)->interp;
|
||||
|
||||
/* Although the GIL is held, a few C API functions can be called
|
||||
* without the GIL held, and in particular some that create and
|
||||
|
|
@ -985,9 +1016,8 @@ PyThreadState_SetAsyncExc(unsigned long id, PyObject *exc)
|
|||
* list of thread states we're traversing, so to prevent that we lock
|
||||
* head_mutex for the duration.
|
||||
*/
|
||||
_PyRuntimeState *runtime = &_PyRuntime;
|
||||
HEAD_LOCK(runtime);
|
||||
for (p = interp->tstate_head; p != NULL; p = p->next) {
|
||||
for (PyThreadState *p = interp->tstate_head; p != NULL; p = p->next) {
|
||||
if (p->thread_id == id) {
|
||||
/* Tricky: we need to decref the current value
|
||||
* (if any) in p->async_exc, but that can in turn
|
||||
|
|
@ -1001,7 +1031,7 @@ PyThreadState_SetAsyncExc(unsigned long id, PyObject *exc)
|
|||
p->async_exc = exc;
|
||||
HEAD_UNLOCK(runtime);
|
||||
Py_XDECREF(old_exc);
|
||||
_PyEval_SignalAsyncExc();
|
||||
_PyEval_SignalAsyncExc(&runtime->ceval);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
|
@ -1051,6 +1081,10 @@ _PyThread_CurrentFrames(void)
|
|||
PyObject *result;
|
||||
PyInterpreterState *i;
|
||||
|
||||
if (PySys_Audit("sys._current_frames", NULL) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
result = PyDict_New();
|
||||
if (result == NULL)
|
||||
return NULL;
|
||||
|
|
|
|||
|
|
@ -353,15 +353,15 @@ PyOS_string_to_double(const char *s,
|
|||
else if (!endptr && (fail_pos == s || *fail_pos != '\0'))
|
||||
PyErr_Format(PyExc_ValueError,
|
||||
"could not convert string to float: "
|
||||
"%.200s", s);
|
||||
"'%.200s'", s);
|
||||
else if (fail_pos == s)
|
||||
PyErr_Format(PyExc_ValueError,
|
||||
"could not convert string to float: "
|
||||
"%.200s", s);
|
||||
"'%.200s'", s);
|
||||
else if (errno == ERANGE && fabs(x) >= 1.0 && overflow_exception)
|
||||
PyErr_Format(overflow_exception,
|
||||
"value too large to convert to float: "
|
||||
"%.200s", s);
|
||||
"'%.200s'", s);
|
||||
else
|
||||
result = x;
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
#include "Python-ast.h"
|
||||
#undef Yield /* undefine macro conflicting with <winbase.h> */
|
||||
#include "pycore_pyerrors.h"
|
||||
#include "pycore_pylifecycle.h"
|
||||
#include "pycore_pystate.h"
|
||||
#include "grammar.h"
|
||||
|
|
@ -542,12 +543,6 @@ parse_syntax_error(PyObject *err, PyObject **message, PyObject **filename,
|
|||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
PyErr_Print(void)
|
||||
{
|
||||
PyErr_PrintEx(1);
|
||||
}
|
||||
|
||||
static void
|
||||
print_error_text(PyObject *f, int offset, PyObject *text_obj)
|
||||
{
|
||||
|
|
@ -585,21 +580,31 @@ print_error_text(PyObject *f, int offset, PyObject *text_obj)
|
|||
PyFile_WriteString("^\n", f);
|
||||
}
|
||||
|
||||
static void
|
||||
handle_system_exit(void)
|
||||
{
|
||||
PyObject *exception, *value, *tb;
|
||||
int exitcode = 0;
|
||||
|
||||
if (Py_InspectFlag)
|
||||
int
|
||||
_Py_HandleSystemExit(int *exitcode_p)
|
||||
{
|
||||
int inspect = _PyInterpreterState_GET_UNSAFE()->core_config.inspect;
|
||||
if (inspect) {
|
||||
/* Don't exit if -i flag was given. This flag is set to 0
|
||||
* when entering interactive mode for inspecting. */
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!PyErr_ExceptionMatches(PyExc_SystemExit)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyObject *exception, *value, *tb;
|
||||
PyErr_Fetch(&exception, &value, &tb);
|
||||
|
||||
fflush(stdout);
|
||||
if (value == NULL || value == Py_None)
|
||||
|
||||
int exitcode = 0;
|
||||
if (value == NULL || value == Py_None) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (PyExceptionInstance_Check(value)) {
|
||||
/* The error code should be in the `code' attribute. */
|
||||
_Py_IDENTIFIER(code);
|
||||
|
|
@ -613,8 +618,10 @@ handle_system_exit(void)
|
|||
/* If we failed to dig out the 'code' attribute,
|
||||
just let the else clause below print the error. */
|
||||
}
|
||||
if (PyLong_Check(value))
|
||||
|
||||
if (PyLong_Check(value)) {
|
||||
exitcode = (int)PyLong_AsLong(value);
|
||||
}
|
||||
else {
|
||||
PyObject *sys_stderr = _PySys_GetObjectId(&PyId_stderr);
|
||||
/* We clear the exception here to avoid triggering the assertion
|
||||
|
|
@ -631,6 +638,7 @@ handle_system_exit(void)
|
|||
PySys_WriteStderr("\n");
|
||||
exitcode = 1;
|
||||
}
|
||||
|
||||
done:
|
||||
/* Restore and clear the exception info, in order to properly decref
|
||||
* the exception, value, and traceback. If we just exit instead,
|
||||
|
|
@ -639,39 +647,53 @@ handle_system_exit(void)
|
|||
*/
|
||||
PyErr_Restore(exception, value, tb);
|
||||
PyErr_Clear();
|
||||
Py_Exit(exitcode);
|
||||
/* NOTREACHED */
|
||||
*exitcode_p = exitcode;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
PyErr_PrintEx(int set_sys_last_vars)
|
||||
|
||||
static void
|
||||
handle_system_exit(void)
|
||||
{
|
||||
int exitcode;
|
||||
if (_Py_HandleSystemExit(&exitcode)) {
|
||||
Py_Exit(exitcode);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
_PyErr_PrintEx(PyThreadState *tstate, int set_sys_last_vars)
|
||||
{
|
||||
PyObject *exception, *v, *tb, *hook;
|
||||
|
||||
if (PyErr_ExceptionMatches(PyExc_SystemExit)) {
|
||||
handle_system_exit();
|
||||
handle_system_exit();
|
||||
|
||||
_PyErr_Fetch(tstate, &exception, &v, &tb);
|
||||
if (exception == NULL) {
|
||||
goto done;
|
||||
}
|
||||
PyErr_Fetch(&exception, &v, &tb);
|
||||
if (exception == NULL)
|
||||
return;
|
||||
PyErr_NormalizeException(&exception, &v, &tb);
|
||||
|
||||
_PyErr_NormalizeException(tstate, &exception, &v, &tb);
|
||||
if (tb == NULL) {
|
||||
tb = Py_None;
|
||||
Py_INCREF(tb);
|
||||
}
|
||||
PyException_SetTraceback(v, tb);
|
||||
if (exception == NULL)
|
||||
return;
|
||||
if (exception == NULL) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Now we know v != NULL too */
|
||||
if (set_sys_last_vars) {
|
||||
if (_PySys_SetObjectId(&PyId_last_type, exception) < 0) {
|
||||
PyErr_Clear();
|
||||
_PyErr_Clear(tstate);
|
||||
}
|
||||
if (_PySys_SetObjectId(&PyId_last_value, v) < 0) {
|
||||
PyErr_Clear();
|
||||
_PyErr_Clear(tstate);
|
||||
}
|
||||
if (_PySys_SetObjectId(&PyId_last_traceback, tb) < 0) {
|
||||
PyErr_Clear();
|
||||
_PyErr_Clear(tstate);
|
||||
}
|
||||
}
|
||||
hook = _PySys_GetObjectId(&PyId_excepthook);
|
||||
|
|
@ -684,12 +706,11 @@ PyErr_PrintEx(int set_sys_last_vars)
|
|||
stack[2] = tb;
|
||||
result = _PyObject_FastCall(hook, stack, 3);
|
||||
if (result == NULL) {
|
||||
handle_system_exit();
|
||||
|
||||
PyObject *exception2, *v2, *tb2;
|
||||
if (PyErr_ExceptionMatches(PyExc_SystemExit)) {
|
||||
handle_system_exit();
|
||||
}
|
||||
PyErr_Fetch(&exception2, &v2, &tb2);
|
||||
PyErr_NormalizeException(&exception2, &v2, &tb2);
|
||||
_PyErr_Fetch(tstate, &exception2, &v2, &tb2);
|
||||
_PyErr_NormalizeException(tstate, &exception2, &v2, &tb2);
|
||||
/* It should not be possible for exception2 or v2
|
||||
to be NULL. However PyErr_Display() can't
|
||||
tolerate NULLs, so just be safe. */
|
||||
|
|
@ -711,15 +732,37 @@ PyErr_PrintEx(int set_sys_last_vars)
|
|||
Py_XDECREF(tb2);
|
||||
}
|
||||
Py_XDECREF(result);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
PySys_WriteStderr("sys.excepthook is missing\n");
|
||||
PyErr_Display(exception, v, tb);
|
||||
}
|
||||
|
||||
done:
|
||||
Py_XDECREF(exception);
|
||||
Py_XDECREF(v);
|
||||
Py_XDECREF(tb);
|
||||
}
|
||||
|
||||
void
|
||||
_PyErr_Print(PyThreadState *tstate)
|
||||
{
|
||||
_PyErr_PrintEx(tstate, 1);
|
||||
}
|
||||
|
||||
void
|
||||
PyErr_PrintEx(int set_sys_last_vars)
|
||||
{
|
||||
PyThreadState *tstate = _PyThreadState_GET();
|
||||
_PyErr_PrintEx(tstate, set_sys_last_vars);
|
||||
}
|
||||
|
||||
void
|
||||
PyErr_Print(void)
|
||||
{
|
||||
PyErr_PrintEx(1);
|
||||
}
|
||||
|
||||
static void
|
||||
print_exception(PyObject *f, PyObject *value)
|
||||
{
|
||||
|
|
@ -1044,6 +1087,15 @@ run_eval_code_obj(PyCodeObject *co, PyObject *globals, PyObject *locals)
|
|||
* Py_Main() based one.
|
||||
*/
|
||||
_Py_UnhandledKeyboardInterrupt = 0;
|
||||
|
||||
/* Set globals['__builtins__'] if it doesn't exist */
|
||||
if (globals != NULL && PyDict_GetItemString(globals, "__builtins__") == NULL) {
|
||||
PyInterpreterState *interp = _PyInterpreterState_Get();
|
||||
if (PyDict_SetItemString(globals, "__builtins__", interp->builtins) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
v = PyEval_EvalCode((PyObject*)co, globals, locals);
|
||||
if (!v && PyErr_Occurred() == PyExc_KeyboardInterrupt) {
|
||||
_Py_UnhandledKeyboardInterrupt = 1;
|
||||
|
|
@ -1060,6 +1112,12 @@ run_mod(mod_ty mod, PyObject *filename, PyObject *globals, PyObject *locals,
|
|||
co = PyAST_CompileObject(mod, filename, flags, -1, arena);
|
||||
if (co == NULL)
|
||||
return NULL;
|
||||
|
||||
if (PySys_Audit("exec", "O", co) < 0) {
|
||||
Py_DECREF(co);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
v = run_eval_code_obj(co, globals, locals);
|
||||
Py_DECREF(co);
|
||||
return v;
|
||||
|
|
|
|||
|
|
@ -22,7 +22,9 @@ Data members:
|
|||
#include "pycore_pymem.h"
|
||||
#include "pycore_pathconfig.h"
|
||||
#include "pycore_pystate.h"
|
||||
#include "pycore_tupleobject.h"
|
||||
#include "pythread.h"
|
||||
#include "pydtrace.h"
|
||||
|
||||
#include "osdefs.h"
|
||||
#include <locale.h>
|
||||
|
|
@ -111,6 +113,308 @@ PySys_SetObject(const char *name, PyObject *v)
|
|||
}
|
||||
}
|
||||
|
||||
static int
|
||||
should_audit(void)
|
||||
{
|
||||
PyThreadState *ts = _PyThreadState_GET();
|
||||
if (!ts) {
|
||||
return 0;
|
||||
}
|
||||
PyInterpreterState *is = ts ? ts->interp : NULL;
|
||||
return _PyRuntime.audit_hook_head
|
||||
|| (is && is->audit_hooks)
|
||||
|| PyDTrace_AUDIT_ENABLED();
|
||||
}
|
||||
|
||||
int
|
||||
PySys_Audit(const char *event, const char *argFormat, ...)
|
||||
{
|
||||
PyObject *eventName = NULL;
|
||||
PyObject *eventArgs = NULL;
|
||||
PyObject *hooks = NULL;
|
||||
PyObject *hook = NULL;
|
||||
int res = -1;
|
||||
|
||||
/* N format is inappropriate, because you do not know
|
||||
whether the reference is consumed by the call.
|
||||
Assert rather than exception for perf reasons */
|
||||
assert(!argFormat || !strchr(argFormat, 'N'));
|
||||
|
||||
/* Early exit when no hooks are registered */
|
||||
if (!should_audit()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
_Py_AuditHookEntry *e = _PyRuntime.audit_hook_head;
|
||||
PyThreadState *ts = _PyThreadState_GET();
|
||||
PyInterpreterState *is = ts ? ts->interp : NULL;
|
||||
int dtrace = PyDTrace_AUDIT_ENABLED();
|
||||
|
||||
PyObject *exc_type, *exc_value, *exc_tb;
|
||||
if (ts) {
|
||||
PyErr_Fetch(&exc_type, &exc_value, &exc_tb);
|
||||
}
|
||||
|
||||
/* Initialize event args now */
|
||||
if (argFormat && argFormat[0]) {
|
||||
va_list args;
|
||||
va_start(args, argFormat);
|
||||
eventArgs = Py_VaBuildValue(argFormat, args);
|
||||
if (eventArgs && !PyTuple_Check(eventArgs)) {
|
||||
PyObject *argTuple = PyTuple_Pack(1, eventArgs);
|
||||
Py_DECREF(eventArgs);
|
||||
eventArgs = argTuple;
|
||||
}
|
||||
} else {
|
||||
eventArgs = PyTuple_New(0);
|
||||
}
|
||||
if (!eventArgs) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Call global hooks */
|
||||
for (; e; e = e->next) {
|
||||
if (e->hookCFunction(event, eventArgs, e->userData) < 0) {
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
/* Dtrace USDT point */
|
||||
if (dtrace) {
|
||||
PyDTrace_AUDIT(event, (void *)eventArgs);
|
||||
}
|
||||
|
||||
/* Call interpreter hooks */
|
||||
if (is && is->audit_hooks) {
|
||||
eventName = PyUnicode_FromString(event);
|
||||
if (!eventName) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
hooks = PyObject_GetIter(is->audit_hooks);
|
||||
if (!hooks) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Disallow tracing in hooks unless explicitly enabled */
|
||||
ts->tracing++;
|
||||
ts->use_tracing = 0;
|
||||
while ((hook = PyIter_Next(hooks)) != NULL) {
|
||||
PyObject *o;
|
||||
int canTrace = -1;
|
||||
o = PyObject_GetAttrString(hook, "__cantrace__");
|
||||
if (o) {
|
||||
canTrace = PyObject_IsTrue(o);
|
||||
Py_DECREF(o);
|
||||
} else if (PyErr_Occurred() &&
|
||||
PyErr_ExceptionMatches(PyExc_AttributeError)) {
|
||||
PyErr_Clear();
|
||||
canTrace = 0;
|
||||
}
|
||||
if (canTrace < 0) {
|
||||
break;
|
||||
}
|
||||
if (canTrace) {
|
||||
ts->use_tracing = (ts->c_tracefunc || ts->c_profilefunc);
|
||||
ts->tracing--;
|
||||
}
|
||||
o = PyObject_CallFunctionObjArgs(hook, eventName,
|
||||
eventArgs, NULL);
|
||||
if (canTrace) {
|
||||
ts->tracing++;
|
||||
ts->use_tracing = 0;
|
||||
}
|
||||
if (!o) {
|
||||
break;
|
||||
}
|
||||
Py_DECREF(o);
|
||||
Py_CLEAR(hook);
|
||||
}
|
||||
ts->use_tracing = (ts->c_tracefunc || ts->c_profilefunc);
|
||||
ts->tracing--;
|
||||
if (PyErr_Occurred()) {
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
res = 0;
|
||||
|
||||
exit:
|
||||
Py_XDECREF(hook);
|
||||
Py_XDECREF(hooks);
|
||||
Py_XDECREF(eventName);
|
||||
Py_XDECREF(eventArgs);
|
||||
|
||||
if (ts) {
|
||||
if (!res) {
|
||||
PyErr_Restore(exc_type, exc_value, exc_tb);
|
||||
} else {
|
||||
assert(PyErr_Occurred());
|
||||
Py_XDECREF(exc_type);
|
||||
Py_XDECREF(exc_value);
|
||||
Py_XDECREF(exc_tb);
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/* We expose this function primarily for our own cleanup during
|
||||
* finalization. In general, it should not need to be called,
|
||||
* and as such it is not defined in any header files.
|
||||
*/
|
||||
void _PySys_ClearAuditHooks(void) {
|
||||
/* Must be finalizing to clear hooks */
|
||||
_PyRuntimeState *runtime = &_PyRuntime;
|
||||
PyThreadState *ts = _PyRuntimeState_GetThreadState(runtime);
|
||||
assert(!ts || _Py_CURRENTLY_FINALIZING(runtime, ts));
|
||||
if (!ts || !_Py_CURRENTLY_FINALIZING(runtime, ts))
|
||||
return;
|
||||
|
||||
if (Py_VerboseFlag) {
|
||||
PySys_WriteStderr("# clear sys.audit hooks\n");
|
||||
}
|
||||
|
||||
/* Hooks can abort later hooks for this event, but cannot
|
||||
abort the clear operation itself. */
|
||||
PySys_Audit("cpython._PySys_ClearAuditHooks", NULL);
|
||||
PyErr_Clear();
|
||||
|
||||
_Py_AuditHookEntry *e = _PyRuntime.audit_hook_head, *n;
|
||||
_PyRuntime.audit_hook_head = NULL;
|
||||
while (e) {
|
||||
n = e->next;
|
||||
PyMem_RawFree(e);
|
||||
e = n;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
PySys_AddAuditHook(Py_AuditHookFunction hook, void *userData)
|
||||
{
|
||||
/* Invoke existing audit hooks to allow them an opportunity to abort. */
|
||||
/* Cannot invoke hooks until we are initialized */
|
||||
if (Py_IsInitialized()) {
|
||||
if (PySys_Audit("sys.addaudithook", NULL) < 0) {
|
||||
if (PyErr_ExceptionMatches(PyExc_Exception)) {
|
||||
/* We do not report errors derived from Exception */
|
||||
PyErr_Clear();
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
_Py_AuditHookEntry *e = _PyRuntime.audit_hook_head;
|
||||
if (!e) {
|
||||
e = (_Py_AuditHookEntry*)PyMem_RawMalloc(sizeof(_Py_AuditHookEntry));
|
||||
_PyRuntime.audit_hook_head = e;
|
||||
} else {
|
||||
while (e->next)
|
||||
e = e->next;
|
||||
e = e->next = (_Py_AuditHookEntry*)PyMem_RawMalloc(
|
||||
sizeof(_Py_AuditHookEntry));
|
||||
}
|
||||
|
||||
if (!e) {
|
||||
if (Py_IsInitialized())
|
||||
PyErr_NoMemory();
|
||||
return -1;
|
||||
}
|
||||
|
||||
e->next = NULL;
|
||||
e->hookCFunction = (Py_AuditHookFunction)hook;
|
||||
e->userData = userData;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*[clinic input]
|
||||
sys.addaudithook
|
||||
|
||||
hook: object
|
||||
|
||||
Adds a new audit hook callback.
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
sys_addaudithook_impl(PyObject *module, PyObject *hook)
|
||||
/*[clinic end generated code: output=4f9c17aaeb02f44e input=0f3e191217a45e34]*/
|
||||
{
|
||||
/* Invoke existing audit hooks to allow them an opportunity to abort. */
|
||||
if (PySys_Audit("sys.addaudithook", NULL) < 0) {
|
||||
if (PyErr_ExceptionMatches(PyExc_Exception)) {
|
||||
/* We do not report errors derived from Exception */
|
||||
PyErr_Clear();
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PyInterpreterState *is = _PyInterpreterState_Get();
|
||||
|
||||
if (is->audit_hooks == NULL) {
|
||||
is->audit_hooks = PyList_New(0);
|
||||
if (is->audit_hooks == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (PyList_Append(is->audit_hooks, hook) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(audit_doc,
|
||||
"audit(event, *args)\n\
|
||||
\n\
|
||||
Passes the event to any audit hooks that are attached.");
|
||||
|
||||
static PyObject *
|
||||
sys_audit(PyObject *self, PyObject *const *args, Py_ssize_t argc)
|
||||
{
|
||||
if (argc == 0) {
|
||||
PyErr_SetString(PyExc_TypeError, "audit() missing 1 required positional argument: 'event'");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!should_audit()) {
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyObject *auditEvent = args[0];
|
||||
if (!auditEvent) {
|
||||
PyErr_SetString(PyExc_TypeError, "expected str for argument 'event'");
|
||||
return NULL;
|
||||
}
|
||||
if (!PyUnicode_Check(auditEvent)) {
|
||||
PyErr_Format(PyExc_TypeError, "expected str for argument 'event', not %.200s",
|
||||
Py_TYPE(auditEvent)->tp_name);
|
||||
return NULL;
|
||||
}
|
||||
const char *event = PyUnicode_AsUTF8(auditEvent);
|
||||
if (!event) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PyObject *auditArgs = _PyTuple_FromArray(args + 1, argc - 1);
|
||||
if (!auditArgs) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int res = PySys_Audit(event, "O", auditArgs);
|
||||
Py_DECREF(auditArgs);
|
||||
|
||||
if (res < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
|
||||
static PyObject *
|
||||
sys_breakpointhook(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *keywords)
|
||||
{
|
||||
|
|
@ -374,6 +678,30 @@ sys_exc_info_impl(PyObject *module)
|
|||
}
|
||||
|
||||
|
||||
/*[clinic input]
|
||||
sys.unraisablehook
|
||||
|
||||
unraisable: object
|
||||
/
|
||||
|
||||
Handle an unraisable exception.
|
||||
|
||||
The unraisable argument has the following attributes:
|
||||
|
||||
* exc_type: Exception type.
|
||||
* exc_value: Exception value.
|
||||
* exc_tb: Exception traceback, can be None.
|
||||
* obj: Object causing the exception, can be None.
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
sys_unraisablehook(PyObject *module, PyObject *unraisable)
|
||||
/*[clinic end generated code: output=bb92838b32abaa14 input=fdbdb47fdd0bee06]*/
|
||||
{
|
||||
return _PyErr_WriteUnraisableDefaultHook(unraisable);
|
||||
}
|
||||
|
||||
|
||||
/*[clinic input]
|
||||
sys.exit
|
||||
|
||||
|
|
@ -1445,6 +1773,10 @@ sys__getframe_impl(PyObject *module, int depth)
|
|||
{
|
||||
PyFrameObject *f = _PyThreadState_GET()->frame;
|
||||
|
||||
if (PySys_Audit("sys._getframe", "O", f) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
while (depth > 0 && f != NULL) {
|
||||
f = f->f_back;
|
||||
--depth;
|
||||
|
|
@ -1618,8 +1950,11 @@ sys_getandroidapilevel_impl(PyObject *module)
|
|||
#endif /* ANDROID_API_LEVEL */
|
||||
|
||||
|
||||
|
||||
static PyMethodDef sys_methods[] = {
|
||||
/* Might as well keep this in alphabetic order */
|
||||
SYS_ADDAUDITHOOK_METHODDEF
|
||||
{"audit", (PyCFunction)(void(*)(void))sys_audit, METH_FASTCALL, audit_doc },
|
||||
{"breakpointhook", (PyCFunction)(void(*)(void))sys_breakpointhook,
|
||||
METH_FASTCALL | METH_KEYWORDS, breakpointhook_doc},
|
||||
SYS_CALLSTATS_METHODDEF
|
||||
|
|
@ -1672,6 +2007,7 @@ static PyMethodDef sys_methods[] = {
|
|||
METH_VARARGS | METH_KEYWORDS, set_asyncgen_hooks_doc},
|
||||
SYS_GET_ASYNCGEN_HOOKS_METHODDEF
|
||||
SYS_GETANDROIDAPILEVEL_METHODDEF
|
||||
SYS_UNRAISABLEHOOK_METHODDEF
|
||||
{NULL, NULL} /* sentinel */
|
||||
};
|
||||
|
||||
|
|
@ -2369,6 +2705,9 @@ _PySys_InitCore(_PyRuntimeState *runtime, PyInterpreterState *interp,
|
|||
SET_SYS_FROM_STRING_BORROW(
|
||||
"__breakpointhook__",
|
||||
PyDict_GetItemString(sysdict, "breakpointhook"));
|
||||
SET_SYS_FROM_STRING_BORROW("__unraisablehook__",
|
||||
PyDict_GetItemString(sysdict, "unraisablehook"));
|
||||
|
||||
SET_SYS_FROM_STRING("version",
|
||||
PyUnicode_FromString(Py_GetVersion()));
|
||||
SET_SYS_FROM_STRING("hexversion",
|
||||
|
|
|
|||
|
|
@ -143,6 +143,10 @@ LeaveNonRecursiveMutex(PNRMUTEX mutex)
|
|||
|
||||
unsigned long PyThread_get_thread_ident(void);
|
||||
|
||||
#ifdef PY_HAVE_THREAD_NATIVE_ID
|
||||
unsigned long PyThread_get_thread_native_id(void);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Initialization of the C package, should not be needed.
|
||||
*/
|
||||
|
|
@ -227,6 +231,25 @@ PyThread_get_thread_ident(void)
|
|||
return GetCurrentThreadId();
|
||||
}
|
||||
|
||||
#ifdef PY_HAVE_THREAD_NATIVE_ID
|
||||
/*
|
||||
* Return the native Thread ID (TID) of the calling thread.
|
||||
* The native ID of a thread is valid and guaranteed to be unique system-wide
|
||||
* from the time the thread is created until the thread has been terminated.
|
||||
*/
|
||||
unsigned long
|
||||
PyThread_get_thread_native_id(void)
|
||||
{
|
||||
if (!initialized) {
|
||||
PyThread_init_thread();
|
||||
}
|
||||
|
||||
DWORD native_id;
|
||||
native_id = GetCurrentThreadId();
|
||||
return (unsigned long) native_id;
|
||||
}
|
||||
#endif
|
||||
|
||||
void _Py_NO_RETURN
|
||||
PyThread_exit_thread(void)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -12,6 +12,12 @@
|
|||
#endif
|
||||
#include <signal.h>
|
||||
|
||||
#if defined(__linux__)
|
||||
# include <sys/syscall.h> /* syscall(SYS_gettid) */
|
||||
#elif defined(__FreeBSD__)
|
||||
# include <pthread_np.h> /* pthread_getthreadid_np() */
|
||||
#endif
|
||||
|
||||
/* The POSIX spec requires that use of pthread_attr_setstacksize
|
||||
be conditional on _POSIX_THREAD_ATTR_STACKSIZE being defined. */
|
||||
#ifdef _POSIX_THREAD_ATTR_STACKSIZE
|
||||
|
|
@ -302,6 +308,26 @@ PyThread_get_thread_ident(void)
|
|||
return (unsigned long) threadid;
|
||||
}
|
||||
|
||||
#ifdef PY_HAVE_THREAD_NATIVE_ID
|
||||
unsigned long
|
||||
PyThread_get_thread_native_id(void)
|
||||
{
|
||||
if (!initialized)
|
||||
PyThread_init_thread();
|
||||
#ifdef __APPLE__
|
||||
uint64_t native_id;
|
||||
(void) pthread_threadid_np(NULL, &native_id);
|
||||
#elif defined(__linux__)
|
||||
pid_t native_id;
|
||||
native_id = syscall(SYS_gettid);
|
||||
#elif defined(__FreeBSD__)
|
||||
int native_id;
|
||||
native_id = pthread_getthreadid_np();
|
||||
#endif
|
||||
return (unsigned long) native_id;
|
||||
}
|
||||
#endif
|
||||
|
||||
void _Py_NO_RETURN
|
||||
PyThread_exit_thread(void)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -163,11 +163,11 @@ static void
|
|||
tb_dealloc(PyTracebackObject *tb)
|
||||
{
|
||||
PyObject_GC_UnTrack(tb);
|
||||
Py_TRASHCAN_SAFE_BEGIN(tb)
|
||||
Py_TRASHCAN_BEGIN(tb, tb_dealloc)
|
||||
Py_XDECREF(tb->tb_next);
|
||||
Py_XDECREF(tb->tb_frame);
|
||||
PyObject_GC_Del(tb);
|
||||
Py_TRASHCAN_SAFE_END(tb)
|
||||
Py_TRASHCAN_END
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -227,13 +227,24 @@ PyTypeObject PyTraceBack_Type = {
|
|||
tb_new, /* tp_new */
|
||||
};
|
||||
|
||||
|
||||
PyObject*
|
||||
_PyTraceBack_FromFrame(PyObject *tb_next, PyFrameObject *frame)
|
||||
{
|
||||
assert(tb_next == NULL || PyTraceBack_Check(tb_next));
|
||||
assert(frame != NULL);
|
||||
|
||||
return tb_create_raw((PyTracebackObject *)tb_next, frame, frame->f_lasti,
|
||||
PyFrame_GetLineNumber(frame));
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
PyTraceBack_Here(PyFrameObject *frame)
|
||||
{
|
||||
PyObject *exc, *val, *tb, *newtb;
|
||||
PyErr_Fetch(&exc, &val, &tb);
|
||||
newtb = tb_create_raw((PyTracebackObject *)tb, frame, frame->f_lasti,
|
||||
PyFrame_GetLineNumber(frame));
|
||||
newtb = _PyTraceBack_FromFrame(tb, frame);
|
||||
if (newtb == NULL) {
|
||||
_PyErr_ChainExceptions(exc, val, tb);
|
||||
return -1;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue