summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
Diffstat (limited to 'Python')
-rw-r--r--Python/Python-ast.c297
-rw-r--r--Python/ast.c66
-rw-r--r--Python/bltinmodule.c18
-rw-r--r--Python/ceval.c607
-rw-r--r--Python/compile.c86
-rw-r--r--Python/dtoa.c4
-rw-r--r--Python/dynload_aix.c2
-rw-r--r--Python/dynload_dl.c16
-rw-r--r--Python/dynload_hpux.c2
-rw-r--r--Python/dynload_next.c4
-rw-r--r--Python/dynload_os2.c2
-rw-r--r--Python/dynload_shlib.c2
-rw-r--r--Python/dynload_win.c44
-rw-r--r--Python/getargs.c55
-rw-r--r--Python/import.c2132
-rw-r--r--Python/importdl.c84
-rw-r--r--Python/importdl.h2
-rw-r--r--Python/marshal.c35
-rw-r--r--Python/peephole.c171
-rw-r--r--Python/pystrtod.c2
-rw-r--r--Python/pythonrun.c64
-rw-r--r--Python/symtable.c150
-rw-r--r--Python/sysmodule.c75
-rw-r--r--Python/thread.c87
-rw-r--r--Python/thread_pth.h3
-rw-r--r--Python/thread_pthread.h13
-rw-r--r--Python/traceback.c241
27 files changed, 2545 insertions, 1719 deletions
diff --git a/Python/Python-ast.c b/Python/Python-ast.c
index 2c09f96..b597626 100644
--- a/Python/Python-ast.c
+++ b/Python/Python-ast.c
@@ -2,7 +2,7 @@
/*
- __version__ 82163.
+ __version__ e0e663132363.
This module must be committed separately after each AST grammar change;
The __version__ number is set to the revision number of the commit
@@ -95,8 +95,7 @@ static char *If_fields[]={
};
static PyTypeObject *With_type;
static char *With_fields[]={
- "context_expr",
- "optional_vars",
+ "items",
"body",
};
static PyTypeObject *Raise_type;
@@ -104,15 +103,11 @@ static char *Raise_fields[]={
"exc",
"cause",
};
-static PyTypeObject *TryExcept_type;
-static char *TryExcept_fields[]={
+static PyTypeObject *Try_type;
+static char *Try_fields[]={
"body",
"handlers",
"orelse",
-};
-static PyTypeObject *TryFinally_type;
-static char *TryFinally_fields[]={
- "body",
"finalbody",
};
static PyTypeObject *Assert_type;
@@ -392,6 +387,12 @@ static char *alias_fields[]={
"name",
"asname",
};
+static PyTypeObject *withitem_type;
+static PyObject* ast2obj_withitem(void*);
+static char *withitem_fields[]={
+ "context_expr",
+ "optional_vars",
+};
static int
@@ -680,15 +681,12 @@ static int init_types(void)
if (!While_type) return 0;
If_type = make_type("If", stmt_type, If_fields, 3);
if (!If_type) return 0;
- With_type = make_type("With", stmt_type, With_fields, 3);
+ With_type = make_type("With", stmt_type, With_fields, 2);
if (!With_type) return 0;
Raise_type = make_type("Raise", stmt_type, Raise_fields, 2);
if (!Raise_type) return 0;
- TryExcept_type = make_type("TryExcept", stmt_type, TryExcept_fields, 3);
- if (!TryExcept_type) return 0;
- TryFinally_type = make_type("TryFinally", stmt_type, TryFinally_fields,
- 2);
- if (!TryFinally_type) return 0;
+ Try_type = make_type("Try", stmt_type, Try_fields, 4);
+ if (!Try_type) return 0;
Assert_type = make_type("Assert", stmt_type, Assert_fields, 2);
if (!Assert_type) return 0;
Import_type = make_type("Import", stmt_type, Import_fields, 1);
@@ -938,6 +936,8 @@ static int init_types(void)
if (!keyword_type) return 0;
alias_type = make_type("alias", &AST_type, alias_fields, 2);
if (!alias_type) return 0;
+ withitem_type = make_type("withitem", &AST_type, withitem_fields, 2);
+ if (!withitem_type) return 0;
initialized = 1;
return 1;
}
@@ -960,6 +960,7 @@ static int obj2ast_arguments(PyObject* obj, arguments_ty* out, PyArena* arena);
static int obj2ast_arg(PyObject* obj, arg_ty* out, PyArena* arena);
static int obj2ast_keyword(PyObject* obj, keyword_ty* out, PyArena* arena);
static int obj2ast_alias(PyObject* obj, alias_ty* out, PyArena* arena);
+static int obj2ast_withitem(PyObject* obj, withitem_ty* out, PyArena* arena);
mod_ty
Module(asdl_seq * body, PyArena *arena)
@@ -1225,21 +1226,15 @@ If(expr_ty test, asdl_seq * body, asdl_seq * orelse, int lineno, int
}
stmt_ty
-With(expr_ty context_expr, expr_ty optional_vars, asdl_seq * body, int lineno,
- int col_offset, PyArena *arena)
+With(asdl_seq * items, asdl_seq * body, int lineno, int col_offset, PyArena
+ *arena)
{
stmt_ty p;
- if (!context_expr) {
- PyErr_SetString(PyExc_ValueError,
- "field context_expr is required for With");
- return NULL;
- }
p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
if (!p)
return NULL;
p->kind = With_kind;
- p->v.With.context_expr = context_expr;
- p->v.With.optional_vars = optional_vars;
+ p->v.With.items = items;
p->v.With.body = body;
p->lineno = lineno;
p->col_offset = col_offset;
@@ -1262,33 +1257,18 @@ Raise(expr_ty exc, expr_ty cause, int lineno, int col_offset, PyArena *arena)
}
stmt_ty
-TryExcept(asdl_seq * body, asdl_seq * handlers, asdl_seq * orelse, int lineno,
- int col_offset, PyArena *arena)
+Try(asdl_seq * body, asdl_seq * handlers, asdl_seq * orelse, asdl_seq *
+ finalbody, int lineno, int col_offset, PyArena *arena)
{
stmt_ty p;
p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
if (!p)
return NULL;
- p->kind = TryExcept_kind;
- p->v.TryExcept.body = body;
- p->v.TryExcept.handlers = handlers;
- p->v.TryExcept.orelse = orelse;
- p->lineno = lineno;
- p->col_offset = col_offset;
- return p;
-}
-
-stmt_ty
-TryFinally(asdl_seq * body, asdl_seq * finalbody, int lineno, int col_offset,
- PyArena *arena)
-{
- stmt_ty p;
- p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
- if (!p)
- return NULL;
- p->kind = TryFinally_kind;
- p->v.TryFinally.body = body;
- p->v.TryFinally.finalbody = finalbody;
+ p->kind = Try_kind;
+ p->v.Try.body = body;
+ p->v.Try.handlers = handlers;
+ p->v.Try.orelse = orelse;
+ p->v.Try.finalbody = finalbody;
p->lineno = lineno;
p->col_offset = col_offset;
return p;
@@ -2135,6 +2115,23 @@ alias(identifier name, identifier asname, PyArena *arena)
return p;
}
+withitem_ty
+withitem(expr_ty context_expr, expr_ty optional_vars, PyArena *arena)
+{
+ withitem_ty p;
+ if (!context_expr) {
+ PyErr_SetString(PyExc_ValueError,
+ "field context_expr is required for withitem");
+ return NULL;
+ }
+ p = (withitem_ty)PyArena_Malloc(arena, sizeof(*p));
+ if (!p)
+ return NULL;
+ p->context_expr = context_expr;
+ p->optional_vars = optional_vars;
+ return p;
+}
+
PyObject*
ast2obj_mod(void* _o)
@@ -2390,15 +2387,9 @@ ast2obj_stmt(void* _o)
case With_kind:
result = PyType_GenericNew(With_type, NULL, NULL);
if (!result) goto failed;
- value = ast2obj_expr(o->v.With.context_expr);
+ value = ast2obj_list(o->v.With.items, ast2obj_withitem);
if (!value) goto failed;
- if (PyObject_SetAttrString(result, "context_expr", value) == -1)
- goto failed;
- Py_DECREF(value);
- value = ast2obj_expr(o->v.With.optional_vars);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "optional_vars", value) ==
- -1)
+ if (PyObject_SetAttrString(result, "items", value) == -1)
goto failed;
Py_DECREF(value);
value = ast2obj_list(o->v.With.body, ast2obj_stmt);
@@ -2421,35 +2412,25 @@ ast2obj_stmt(void* _o)
goto failed;
Py_DECREF(value);
break;
- case TryExcept_kind:
- result = PyType_GenericNew(TryExcept_type, NULL, NULL);
+ case Try_kind:
+ result = PyType_GenericNew(Try_type, NULL, NULL);
if (!result) goto failed;
- value = ast2obj_list(o->v.TryExcept.body, ast2obj_stmt);
+ value = ast2obj_list(o->v.Try.body, ast2obj_stmt);
if (!value) goto failed;
if (PyObject_SetAttrString(result, "body", value) == -1)
goto failed;
Py_DECREF(value);
- value = ast2obj_list(o->v.TryExcept.handlers,
- ast2obj_excepthandler);
+ value = ast2obj_list(o->v.Try.handlers, ast2obj_excepthandler);
if (!value) goto failed;
if (PyObject_SetAttrString(result, "handlers", value) == -1)
goto failed;
Py_DECREF(value);
- value = ast2obj_list(o->v.TryExcept.orelse, ast2obj_stmt);
+ value = ast2obj_list(o->v.Try.orelse, ast2obj_stmt);
if (!value) goto failed;
if (PyObject_SetAttrString(result, "orelse", value) == -1)
goto failed;
Py_DECREF(value);
- break;
- case TryFinally_kind:
- result = PyType_GenericNew(TryFinally_type, NULL, NULL);
- if (!result) goto failed;
- value = ast2obj_list(o->v.TryFinally.body, ast2obj_stmt);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "body", value) == -1)
- goto failed;
- Py_DECREF(value);
- value = ast2obj_list(o->v.TryFinally.finalbody, ast2obj_stmt);
+ value = ast2obj_list(o->v.Try.finalbody, ast2obj_stmt);
if (!value) goto failed;
if (PyObject_SetAttrString(result, "finalbody", value) == -1)
goto failed;
@@ -3370,6 +3351,35 @@ failed:
return NULL;
}
+PyObject*
+ast2obj_withitem(void* _o)
+{
+ withitem_ty o = (withitem_ty)_o;
+ PyObject *result = NULL, *value = NULL;
+ if (!o) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+
+ result = PyType_GenericNew(withitem_type, NULL, NULL);
+ if (!result) return NULL;
+ value = ast2obj_expr(o->context_expr);
+ if (!value) goto failed;
+ if (PyObject_SetAttrString(result, "context_expr", value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_expr(o->optional_vars);
+ if (!value) goto failed;
+ if (PyObject_SetAttrString(result, "optional_vars", value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ return result;
+failed:
+ Py_XDECREF(value);
+ Py_XDECREF(result);
+ return NULL;
+}
+
int
obj2ast_mod(PyObject* obj, mod_ty* out, PyArena* arena)
@@ -4210,33 +4220,34 @@ obj2ast_stmt(PyObject* obj, stmt_ty* out, PyArena* arena)
return 1;
}
if (isinstance) {
- expr_ty context_expr;
- expr_ty optional_vars;
+ asdl_seq* items;
asdl_seq* body;
- if (PyObject_HasAttrString(obj, "context_expr")) {
+ if (PyObject_HasAttrString(obj, "items")) {
int res;
- tmp = PyObject_GetAttrString(obj, "context_expr");
+ Py_ssize_t len;
+ Py_ssize_t i;
+ tmp = PyObject_GetAttrString(obj, "items");
if (tmp == NULL) goto failed;
- res = obj2ast_expr(tmp, &context_expr, arena);
- if (res != 0) goto failed;
+ if (!PyList_Check(tmp)) {
+ PyErr_Format(PyExc_TypeError, "With field \"items\" must be a list, not a %.200s", tmp->ob_type->tp_name);
+ goto failed;
+ }
+ len = PyList_GET_SIZE(tmp);
+ items = asdl_seq_new(len, arena);
+ if (items == NULL) goto failed;
+ for (i = 0; i < len; i++) {
+ withitem_ty value;
+ res = obj2ast_withitem(PyList_GET_ITEM(tmp, i), &value, arena);
+ if (res != 0) goto failed;
+ asdl_seq_SET(items, i, value);
+ }
Py_XDECREF(tmp);
tmp = NULL;
} else {
- PyErr_SetString(PyExc_TypeError, "required field \"context_expr\" missing from With");
+ PyErr_SetString(PyExc_TypeError, "required field \"items\" missing from With");
return 1;
}
- if (PyObject_HasAttrString(obj, "optional_vars")) {
- int res;
- tmp = PyObject_GetAttrString(obj, "optional_vars");
- if (tmp == NULL) goto failed;
- res = obj2ast_expr(tmp, &optional_vars, arena);
- if (res != 0) goto failed;
- Py_XDECREF(tmp);
- tmp = NULL;
- } else {
- optional_vars = NULL;
- }
if (PyObject_HasAttrString(obj, "body")) {
int res;
Py_ssize_t len;
@@ -4262,8 +4273,7 @@ obj2ast_stmt(PyObject* obj, stmt_ty* out, PyArena* arena)
PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from With");
return 1;
}
- *out = With(context_expr, optional_vars, body, lineno,
- col_offset, arena);
+ *out = With(items, body, lineno, col_offset, arena);
if (*out == NULL) goto failed;
return 0;
}
@@ -4301,7 +4311,7 @@ obj2ast_stmt(PyObject* obj, stmt_ty* out, PyArena* arena)
if (*out == NULL) goto failed;
return 0;
}
- isinstance = PyObject_IsInstance(obj, (PyObject*)TryExcept_type);
+ isinstance = PyObject_IsInstance(obj, (PyObject*)Try_type);
if (isinstance == -1) {
return 1;
}
@@ -4309,6 +4319,7 @@ obj2ast_stmt(PyObject* obj, stmt_ty* out, PyArena* arena)
asdl_seq* body;
asdl_seq* handlers;
asdl_seq* orelse;
+ asdl_seq* finalbody;
if (PyObject_HasAttrString(obj, "body")) {
int res;
@@ -4317,7 +4328,7 @@ obj2ast_stmt(PyObject* obj, stmt_ty* out, PyArena* arena)
tmp = PyObject_GetAttrString(obj, "body");
if (tmp == NULL) goto failed;
if (!PyList_Check(tmp)) {
- PyErr_Format(PyExc_TypeError, "TryExcept field \"body\" must be a list, not a %.200s", tmp->ob_type->tp_name);
+ PyErr_Format(PyExc_TypeError, "Try field \"body\" must be a list, not a %.200s", tmp->ob_type->tp_name);
goto failed;
}
len = PyList_GET_SIZE(tmp);
@@ -4332,7 +4343,7 @@ obj2ast_stmt(PyObject* obj, stmt_ty* out, PyArena* arena)
Py_XDECREF(tmp);
tmp = NULL;
} else {
- PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from TryExcept");
+ PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from Try");
return 1;
}
if (PyObject_HasAttrString(obj, "handlers")) {
@@ -4342,7 +4353,7 @@ obj2ast_stmt(PyObject* obj, stmt_ty* out, PyArena* arena)
tmp = PyObject_GetAttrString(obj, "handlers");
if (tmp == NULL) goto failed;
if (!PyList_Check(tmp)) {
- PyErr_Format(PyExc_TypeError, "TryExcept field \"handlers\" must be a list, not a %.200s", tmp->ob_type->tp_name);
+ PyErr_Format(PyExc_TypeError, "Try field \"handlers\" must be a list, not a %.200s", tmp->ob_type->tp_name);
goto failed;
}
len = PyList_GET_SIZE(tmp);
@@ -4357,7 +4368,7 @@ obj2ast_stmt(PyObject* obj, stmt_ty* out, PyArena* arena)
Py_XDECREF(tmp);
tmp = NULL;
} else {
- PyErr_SetString(PyExc_TypeError, "required field \"handlers\" missing from TryExcept");
+ PyErr_SetString(PyExc_TypeError, "required field \"handlers\" missing from Try");
return 1;
}
if (PyObject_HasAttrString(obj, "orelse")) {
@@ -4367,7 +4378,7 @@ obj2ast_stmt(PyObject* obj, stmt_ty* out, PyArena* arena)
tmp = PyObject_GetAttrString(obj, "orelse");
if (tmp == NULL) goto failed;
if (!PyList_Check(tmp)) {
- PyErr_Format(PyExc_TypeError, "TryExcept field \"orelse\" must be a list, not a %.200s", tmp->ob_type->tp_name);
+ PyErr_Format(PyExc_TypeError, "Try field \"orelse\" must be a list, not a %.200s", tmp->ob_type->tp_name);
goto failed;
}
len = PyList_GET_SIZE(tmp);
@@ -4382,45 +4393,7 @@ obj2ast_stmt(PyObject* obj, stmt_ty* out, PyArena* arena)
Py_XDECREF(tmp);
tmp = NULL;
} else {
- PyErr_SetString(PyExc_TypeError, "required field \"orelse\" missing from TryExcept");
- return 1;
- }
- *out = TryExcept(body, handlers, orelse, lineno, col_offset,
- arena);
- if (*out == NULL) goto failed;
- return 0;
- }
- isinstance = PyObject_IsInstance(obj, (PyObject*)TryFinally_type);
- if (isinstance == -1) {
- return 1;
- }
- if (isinstance) {
- asdl_seq* body;
- asdl_seq* finalbody;
-
- if (PyObject_HasAttrString(obj, "body")) {
- int res;
- Py_ssize_t len;
- Py_ssize_t i;
- tmp = PyObject_GetAttrString(obj, "body");
- if (tmp == NULL) goto failed;
- if (!PyList_Check(tmp)) {
- PyErr_Format(PyExc_TypeError, "TryFinally field \"body\" must be a list, not a %.200s", tmp->ob_type->tp_name);
- goto failed;
- }
- len = PyList_GET_SIZE(tmp);
- body = asdl_seq_new(len, arena);
- if (body == NULL) goto failed;
- for (i = 0; i < len; i++) {
- stmt_ty value;
- res = obj2ast_stmt(PyList_GET_ITEM(tmp, i), &value, arena);
- if (res != 0) goto failed;
- asdl_seq_SET(body, i, value);
- }
- Py_XDECREF(tmp);
- tmp = NULL;
- } else {
- PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from TryFinally");
+ PyErr_SetString(PyExc_TypeError, "required field \"orelse\" missing from Try");
return 1;
}
if (PyObject_HasAttrString(obj, "finalbody")) {
@@ -4430,7 +4403,7 @@ obj2ast_stmt(PyObject* obj, stmt_ty* out, PyArena* arena)
tmp = PyObject_GetAttrString(obj, "finalbody");
if (tmp == NULL) goto failed;
if (!PyList_Check(tmp)) {
- PyErr_Format(PyExc_TypeError, "TryFinally field \"finalbody\" must be a list, not a %.200s", tmp->ob_type->tp_name);
+ PyErr_Format(PyExc_TypeError, "Try field \"finalbody\" must be a list, not a %.200s", tmp->ob_type->tp_name);
goto failed;
}
len = PyList_GET_SIZE(tmp);
@@ -4445,10 +4418,11 @@ obj2ast_stmt(PyObject* obj, stmt_ty* out, PyArena* arena)
Py_XDECREF(tmp);
tmp = NULL;
} else {
- PyErr_SetString(PyExc_TypeError, "required field \"finalbody\" missing from TryFinally");
+ PyErr_SetString(PyExc_TypeError, "required field \"finalbody\" missing from Try");
return 1;
}
- *out = TryFinally(body, finalbody, lineno, col_offset, arena);
+ *out = Try(body, handlers, orelse, finalbody, lineno,
+ col_offset, arena);
if (*out == NULL) goto failed;
return 0;
}
@@ -6723,6 +6697,43 @@ failed:
return 1;
}
+int
+obj2ast_withitem(PyObject* obj, withitem_ty* out, PyArena* arena)
+{
+ PyObject* tmp = NULL;
+ expr_ty context_expr;
+ expr_ty optional_vars;
+
+ if (PyObject_HasAttrString(obj, "context_expr")) {
+ int res;
+ tmp = PyObject_GetAttrString(obj, "context_expr");
+ if (tmp == NULL) goto failed;
+ res = obj2ast_expr(tmp, &context_expr, arena);
+ if (res != 0) goto failed;
+ Py_XDECREF(tmp);
+ tmp = NULL;
+ } else {
+ PyErr_SetString(PyExc_TypeError, "required field \"context_expr\" missing from withitem");
+ return 1;
+ }
+ if (PyObject_HasAttrString(obj, "optional_vars")) {
+ int res;
+ tmp = PyObject_GetAttrString(obj, "optional_vars");
+ if (tmp == NULL) goto failed;
+ res = obj2ast_expr(tmp, &optional_vars, arena);
+ if (res != 0) goto failed;
+ Py_XDECREF(tmp);
+ tmp = NULL;
+ } else {
+ optional_vars = NULL;
+ }
+ *out = withitem(context_expr, optional_vars, arena);
+ return 0;
+failed:
+ Py_XDECREF(tmp);
+ return 1;
+}
+
static struct PyModuleDef _astmodule = {
PyModuleDef_HEAD_INIT, "_ast"
@@ -6739,7 +6750,7 @@ PyInit__ast(void)
NULL;
if (PyModule_AddIntConstant(m, "PyCF_ONLY_AST", PyCF_ONLY_AST) < 0)
return NULL;
- if (PyModule_AddStringConstant(m, "__version__", "82163") < 0)
+ if (PyModule_AddStringConstant(m, "__version__", "e0e663132363") < 0)
return NULL;
if (PyDict_SetItemString(d, "mod", (PyObject*)mod_type) < 0) return
NULL;
@@ -6774,10 +6785,8 @@ PyInit__ast(void)
NULL;
if (PyDict_SetItemString(d, "Raise", (PyObject*)Raise_type) < 0) return
NULL;
- if (PyDict_SetItemString(d, "TryExcept", (PyObject*)TryExcept_type) <
- 0) return NULL;
- if (PyDict_SetItemString(d, "TryFinally", (PyObject*)TryFinally_type) <
- 0) return NULL;
+ if (PyDict_SetItemString(d, "Try", (PyObject*)Try_type) < 0) return
+ NULL;
if (PyDict_SetItemString(d, "Assert", (PyObject*)Assert_type) < 0)
return NULL;
if (PyDict_SetItemString(d, "Import", (PyObject*)Import_type) < 0)
@@ -6940,6 +6949,8 @@ PyInit__ast(void)
return NULL;
if (PyDict_SetItemString(d, "alias", (PyObject*)alias_type) < 0) return
NULL;
+ if (PyDict_SetItemString(d, "withitem", (PyObject*)withitem_type) < 0)
+ return NULL;
return m;
}
diff --git a/Python/ast.c b/Python/ast.c
index 6269c64..0d4d9ee 100644
--- a/Python/ast.c
+++ b/Python/ast.c
@@ -2893,7 +2893,7 @@ ast_for_try_stmt(struct compiling *c, const node *n)
{
const int nch = NCH(n);
int n_except = (nch - 3)/3;
- asdl_seq *body, *orelse = NULL, *finally = NULL;
+ asdl_seq *body, *handlers = NULL, *orelse = NULL, *finally = NULL;
REQ(n, try_stmt);
@@ -2934,9 +2934,8 @@ ast_for_try_stmt(struct compiling *c, const node *n)
if (n_except > 0) {
int i;
- stmt_ty except_st;
/* process except statements to create a try ... except */
- asdl_seq *handlers = asdl_seq_new(n_except, c->c_arena);
+ handlers = asdl_seq_new(n_except, c->c_arena);
if (handlers == NULL)
return NULL;
@@ -2947,28 +2946,15 @@ ast_for_try_stmt(struct compiling *c, const node *n)
return NULL;
asdl_seq_SET(handlers, i, e);
}
-
- except_st = TryExcept(body, handlers, orelse, LINENO(n),
- n->n_col_offset, c->c_arena);
- if (!finally)
- return except_st;
-
- /* if a 'finally' is present too, we nest the TryExcept within a
- TryFinally to emulate try ... except ... finally */
- body = asdl_seq_new(1, c->c_arena);
- if (body == NULL)
- return NULL;
- asdl_seq_SET(body, 0, except_st);
}
- /* must be a try ... finally (except clauses are in body, if any exist) */
- assert(finally != NULL);
- return TryFinally(body, finally, LINENO(n), n->n_col_offset, c->c_arena);
+ assert(finally != NULL || asdl_seq_LEN(handlers));
+ return Try(body, handlers, orelse, finally, LINENO(n), n->n_col_offset, c->c_arena);
}
/* with_item: test ['as' expr] */
-static stmt_ty
-ast_for_with_item(struct compiling *c, const node *n, asdl_seq *content)
+static withitem_ty
+ast_for_with_item(struct compiling *c, const node *n)
{
expr_ty context_expr, optional_vars = NULL;
@@ -2987,43 +2973,32 @@ ast_for_with_item(struct compiling *c, const node *n, asdl_seq *content)
}
}
- return With(context_expr, optional_vars, content, LINENO(n),
- n->n_col_offset, c->c_arena);
+ return withitem(context_expr, optional_vars, c->c_arena);
}
/* with_stmt: 'with' with_item (',' with_item)* ':' suite */
static stmt_ty
ast_for_with_stmt(struct compiling *c, const node *n)
{
- int i;
- stmt_ty ret;
- asdl_seq *inner;
+ int i, n_items;
+ asdl_seq *items, *body;
REQ(n, with_stmt);
- /* process the with items inside-out */
- i = NCH(n) - 1;
- /* the suite of the innermost with item is the suite of the with stmt */
- inner = ast_for_suite(c, CHILD(n, i));
- if (!inner)
- return NULL;
-
- for (;;) {
- i -= 2;
- ret = ast_for_with_item(c, CHILD(n, i), inner);
- if (!ret)
- return NULL;
- /* was this the last item? */
- if (i == 1)
- break;
- /* if not, wrap the result so far in a new sequence */
- inner = asdl_seq_new(1, c->c_arena);
- if (!inner)
+ n_items = (NCH(n) - 2) / 2;
+ items = asdl_seq_new(n_items, c->c_arena);
+ for (i = 1; i < NCH(n) - 2; i += 2) {
+ withitem_ty item = ast_for_with_item(c, CHILD(n, i));
+ if (!item)
return NULL;
- asdl_seq_SET(inner, 0, ret);
+ asdl_seq_SET(items, (i - 1) / 2, item);
}
- return ret;
+ body = ast_for_suite(c, CHILD(n, NCH(n) - 1));
+ if (!body)
+ return NULL;
+
+ return With(items, body, LINENO(n), n->n_col_offset, c->c_arena);
}
static stmt_ty
@@ -3232,7 +3207,6 @@ decode_unicode(struct compiling *c, const char *s, size_t len, int rawmode, cons
const char *end;
if (encoding == NULL) {
- buf = (char *)s;
u = NULL;
} else {
/* check for integer overflow */
diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c
index 6258167..4283566 100644
--- a/Python/bltinmodule.c
+++ b/Python/bltinmodule.c
@@ -37,7 +37,7 @@ builtin___build_class__(PyObject *self, PyObject *args, PyObject *kwds)
{
PyObject *func, *name, *bases, *mkw, *meta, *prep, *ns, *cell;
PyObject *cls = NULL;
- Py_ssize_t nargs, nbases;
+ Py_ssize_t nargs;
assert(args != NULL);
if (!PyTuple_Check(args)) {
@@ -61,7 +61,6 @@ builtin___build_class__(PyObject *self, PyObject *args, PyObject *kwds)
bases = PyTuple_GetSlice(args, 2, nargs);
if (bases == NULL)
return NULL;
- nbases = nargs - 2;
if (kwds == NULL) {
meta = NULL;
@@ -156,17 +155,14 @@ builtin___import__(PyObject *self, PyObject *args, PyObject *kwds)
{
static char *kwlist[] = {"name", "globals", "locals", "fromlist",
"level", 0};
- char *name;
- PyObject *globals = NULL;
- PyObject *locals = NULL;
- PyObject *fromlist = NULL;
+ PyObject *name, *globals = NULL, *locals = NULL, *fromlist = NULL;
int level = -1;
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|OOOi:__import__",
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "U|OOOi:__import__",
kwlist, &name, &globals, &locals, &fromlist, &level))
return NULL;
- return PyImport_ImportModuleLevel(name, globals, locals,
- fromlist, level);
+ return PyImport_ImportModuleLevelObject(name, globals, locals,
+ fromlist, level);
}
PyDoc_STRVAR(import_doc,
@@ -512,7 +508,7 @@ source_as_string(PyObject *cmd, char *funcname, char *what, PyCompilerFlags *cf)
if (PyUnicode_Check(cmd)) {
cf->cf_flags |= PyCF_IGNORE_COOKIE;
- cmd = _PyUnicode_AsDefaultEncodedString(cmd, NULL);
+ cmd = _PyUnicode_AsDefaultEncodedString(cmd);
if (cmd == NULL)
return NULL;
}
@@ -766,7 +762,6 @@ builtin_exec(PyObject *self, PyObject *args)
{
PyObject *v;
PyObject *prog, *globals = Py_None, *locals = Py_None;
- int plain = 0;
if (!PyArg_UnpackTuple(args, "exec", 1, 3, &prog, &globals, &locals))
return NULL;
@@ -775,7 +770,6 @@ builtin_exec(PyObject *self, PyObject *args)
globals = PyEval_GetGlobals();
if (locals == Py_None) {
locals = PyEval_GetLocals();
- plain = 1;
}
if (!globals || !locals) {
PyErr_SetString(PyExc_SystemError,
diff --git a/Python/ceval.c b/Python/ceval.c
index 5c3bb83..5c93637 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -749,6 +749,9 @@ enum why_code {
WHY_SILENCED = 0x0080 /* Exception silenced by 'with' */
};
+static void save_exc_state(PyThreadState *, PyFrameObject *);
+static void swap_exc_state(PyThreadState *, PyFrameObject *);
+static void restore_and_clear_exc_state(PyThreadState *, PyFrameObject *);
static enum why_code do_raise(PyObject *, PyObject *);
static int unpack_iterable(PyObject *, int, int, PyObject **);
@@ -817,10 +820,6 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
unsigned char *first_instr;
PyObject *names;
PyObject *consts;
-#if defined(Py_DEBUG) || defined(LLTRACE)
- /* Make it easier to find out where we are with a debugger */
- char *filename;
-#endif
/* Computed GOTOs, or
the-optimization-commonly-but-improperly-known-as-"threaded code"
@@ -1114,59 +1113,8 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
Py_XDECREF(traceback); \
}
-#define SAVE_EXC_STATE() \
- { \
- PyObject *type, *value, *traceback; \
- Py_XINCREF(tstate->exc_type); \
- Py_XINCREF(tstate->exc_value); \
- Py_XINCREF(tstate->exc_traceback); \
- type = f->f_exc_type; \
- value = f->f_exc_value; \
- traceback = f->f_exc_traceback; \
- f->f_exc_type = tstate->exc_type; \
- f->f_exc_value = tstate->exc_value; \
- f->f_exc_traceback = tstate->exc_traceback; \
- Py_XDECREF(type); \
- Py_XDECREF(value); \
- Py_XDECREF(traceback); \
- }
-
-#define SWAP_EXC_STATE() \
- { \
- PyObject *tmp; \
- tmp = tstate->exc_type; \
- tstate->exc_type = f->f_exc_type; \
- f->f_exc_type = tmp; \
- tmp = tstate->exc_value; \
- tstate->exc_value = f->f_exc_value; \
- f->f_exc_value = tmp; \
- tmp = tstate->exc_traceback; \
- tstate->exc_traceback = f->f_exc_traceback; \
- f->f_exc_traceback = tmp; \
- }
-
-#define RESTORE_AND_CLEAR_EXC_STATE() \
- { \
- PyObject *type, *value, *tb; \
- type = tstate->exc_type; \
- value = tstate->exc_value; \
- tb = tstate->exc_traceback; \
- tstate->exc_type = f->f_exc_type; \
- tstate->exc_value = f->f_exc_value; \
- tstate->exc_traceback = f->f_exc_traceback; \
- f->f_exc_type = NULL; \
- f->f_exc_value = NULL; \
- f->f_exc_traceback = NULL; \
- Py_XDECREF(type); \
- Py_XDECREF(value); \
- Py_XDECREF(tb); \
- }
-
/* Start of code */
- if (f == NULL)
- return NULL;
-
/* push frame */
if (Py_EnterRecursiveCall(""))
return NULL;
@@ -1240,28 +1188,15 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
/* We were in an except handler when we left,
restore the exception state which was put aside
(see YIELD_VALUE). */
- SWAP_EXC_STATE();
- }
- else {
- SAVE_EXC_STATE();
+ swap_exc_state(tstate, f);
}
+ else
+ save_exc_state(tstate, f);
}
#ifdef LLTRACE
lltrace = PyDict_GetItemString(f->f_globals, "__lltrace__") != NULL;
#endif
-#if defined(Py_DEBUG) || defined(LLTRACE)
- {
- PyObject *error_type, *error_value, *error_traceback;
- PyErr_Fetch(&error_type, &error_value, &error_traceback);
- filename = _PyUnicode_AsString(co->co_filename);
- if (filename == NULL && tstate->overflowed) {
- /* maximum recursion depth exceeded */
- goto exit_eval_frame;
- }
- PyErr_Restore(error_type, error_value, error_traceback);
- }
-#endif
why = WHY_NOT;
err = 0;
@@ -2725,7 +2660,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
Py_DECREF(*pfunc);
*pfunc = self;
na++;
- n++;
+ /* n++; */
} else
Py_INCREF(func);
sp = stack_pointer;
@@ -3049,9 +2984,9 @@ fast_yield:
break;
if (i == f->f_iblock)
/* We did not create this exception. */
- RESTORE_AND_CLEAR_EXC_STATE()
+ restore_and_clear_exc_state(tstate, f);
else
- SWAP_EXC_STATE()
+ swap_exc_state(tstate, f);
}
if (tstate->use_tracing) {
@@ -3081,7 +3016,7 @@ fast_yield:
PyTrace_RETURN, retval)) {
Py_XDECREF(retval);
retval = NULL;
- why = WHY_EXCEPTION;
+ /* why = WHY_EXCEPTION; */
}
}
}
@@ -3094,6 +3029,154 @@ exit_eval_frame:
return retval;
}
+static void
+format_missing(const char *kind, PyCodeObject *co, PyObject *names)
+{
+ int err;
+ Py_ssize_t len = PyList_GET_SIZE(names);
+ PyObject *name_str, *comma, *tail, *tmp;
+
+ assert(PyList_CheckExact(names));
+ assert(len >= 1);
+ /* Deal with the joys of natural language. */
+ switch (len) {
+ case 1:
+ name_str = PyList_GET_ITEM(names, 0);
+ Py_INCREF(name_str);
+ break;
+ case 2:
+ name_str = PyUnicode_FromFormat("%U and %U",
+ PyList_GET_ITEM(names, len - 2),
+ PyList_GET_ITEM(names, len - 1));
+ break;
+ default:
+ tail = PyUnicode_FromFormat(", %U, and %U",
+ PyList_GET_ITEM(names, len - 2),
+ PyList_GET_ITEM(names, len - 1));
+ /* Chop off the last two objects in the list. This shouldn't actually
+ fail, but we can't be too careful. */
+ err = PyList_SetSlice(names, len - 2, len, NULL);
+ if (err == -1) {
+ Py_DECREF(tail);
+ return;
+ }
+ /* Stitch everything up into a nice comma-separated list. */
+ comma = PyUnicode_FromString(", ");
+ if (comma == NULL) {
+ Py_DECREF(tail);
+ return;
+ }
+ tmp = PyUnicode_Join(comma, names);
+ Py_DECREF(comma);
+ if (tmp == NULL) {
+ Py_DECREF(tail);
+ return;
+ }
+ name_str = PyUnicode_Concat(tmp, tail);
+ Py_DECREF(tmp);
+ Py_DECREF(tail);
+ break;
+ }
+ if (name_str == NULL)
+ return;
+ PyErr_Format(PyExc_TypeError,
+ "%U() missing %i required %s argument%s: %U",
+ co->co_name,
+ len,
+ kind,
+ len == 1 ? "" : "s",
+ name_str);
+ Py_DECREF(name_str);
+}
+
+static void
+missing_arguments(PyCodeObject *co, int missing, int defcount,
+ PyObject **fastlocals)
+{
+ int i, j = 0;
+ int start, end;
+ int positional = defcount != -1;
+ const char *kind = positional ? "positional" : "keyword-only";
+ PyObject *missing_names;
+
+ /* Compute the names of the arguments that are missing. */
+ missing_names = PyList_New(missing);
+ if (missing_names == NULL)
+ return;
+ if (positional) {
+ start = 0;
+ end = co->co_argcount - defcount;
+ }
+ else {
+ start = co->co_argcount;
+ end = start + co->co_kwonlyargcount;
+ }
+ for (i = start; i < end; i++) {
+ if (GETLOCAL(i) == NULL) {
+ PyObject *raw = PyTuple_GET_ITEM(co->co_varnames, i);
+ PyObject *name = PyObject_Repr(raw);
+ if (name == NULL) {
+ Py_DECREF(missing_names);
+ return;
+ }
+ PyList_SET_ITEM(missing_names, j++, name);
+ }
+ }
+ assert(j == missing);
+ format_missing(kind, co, missing_names);
+ Py_DECREF(missing_names);
+}
+
+static void
+too_many_positional(PyCodeObject *co, int given, int defcount, PyObject **fastlocals)
+{
+ int plural;
+ int kwonly_given = 0;
+ int i;
+ PyObject *sig, *kwonly_sig;
+
+ assert((co->co_flags & CO_VARARGS) == 0);
+ /* Count missing keyword-only args. */
+ for (i = co->co_argcount; i < co->co_argcount + co->co_kwonlyargcount; i++)
+ if (GETLOCAL(i) != NULL)
+ kwonly_given++;
+ if (defcount) {
+ int atleast = co->co_argcount - defcount;
+ plural = 1;
+ sig = PyUnicode_FromFormat("from %d to %d", atleast, co->co_argcount);
+ }
+ else {
+ plural = co->co_argcount != 1;
+ sig = PyUnicode_FromFormat("%d", co->co_argcount);
+ }
+ if (sig == NULL)
+ return;
+ if (kwonly_given) {
+ const char *format = " positional argument%s (and %d keyword-only argument%s)";
+ kwonly_sig = PyUnicode_FromFormat(format, given != 1 ? "s" : "", kwonly_given,
+ kwonly_given != 1 ? "s" : "");
+ if (kwonly_sig == NULL) {
+ Py_DECREF(sig);
+ return;
+ }
+ }
+ else {
+ /* This will not fail. */
+ kwonly_sig = PyUnicode_FromString("");
+ assert(kwonly_sig != NULL);
+ }
+ PyErr_Format(PyExc_TypeError,
+ "%U() takes %U positional argument%s but %d%U %s given",
+ co->co_name,
+ sig,
+ plural ? "s" : "",
+ given,
+ kwonly_sig,
+ given == 1 && !kwonly_given ? "was" : "were");
+ Py_DECREF(sig);
+ Py_DECREF(kwonly_sig);
+}
+
/* This is gonna seem *real weird*, but if you put some other code between
PyEval_EvalFrame() and PyEval_EvalCodeEx() you will need to adjust
the test in the if statements in Misc/gdbinit (pystack and pystackv). */
@@ -3110,6 +3193,9 @@ PyEval_EvalCodeEx(PyObject *_co, PyObject *globals, PyObject *locals,
PyThreadState *tstate = PyThreadState_GET();
PyObject *x, *u;
int total_args = co->co_argcount + co->co_kwonlyargcount;
+ int i;
+ int n = argcount;
+ PyObject *kwdict = NULL;
if (globals == NULL) {
PyErr_SetString(PyExc_SystemError,
@@ -3126,212 +3212,153 @@ PyEval_EvalCodeEx(PyObject *_co, PyObject *globals, PyObject *locals,
fastlocals = f->f_localsplus;
freevars = f->f_localsplus + co->co_nlocals;
- if (total_args || co->co_flags & (CO_VARARGS | CO_VARKEYWORDS)) {
- int i;
- int n = argcount;
- PyObject *kwdict = NULL;
- if (co->co_flags & CO_VARKEYWORDS) {
- kwdict = PyDict_New();
- if (kwdict == NULL)
- goto fail;
- i = total_args;
- if (co->co_flags & CO_VARARGS)
- i++;
- SETLOCAL(i, kwdict);
- }
- if (argcount > co->co_argcount) {
- if (!(co->co_flags & CO_VARARGS)) {
- PyErr_Format(PyExc_TypeError,
- "%U() takes %s %d "
- "positional argument%s (%d given)",
- co->co_name,
- defcount ? "at most" : "exactly",
- co->co_argcount,
- co->co_argcount == 1 ? "" : "s",
- argcount + kwcount);
- goto fail;
- }
- n = co->co_argcount;
- }
- for (i = 0; i < n; i++) {
+ /* Parse arguments. */
+ if (co->co_flags & CO_VARKEYWORDS) {
+ kwdict = PyDict_New();
+ if (kwdict == NULL)
+ goto fail;
+ i = total_args;
+ if (co->co_flags & CO_VARARGS)
+ i++;
+ SETLOCAL(i, kwdict);
+ }
+ if (argcount > co->co_argcount)
+ n = co->co_argcount;
+ for (i = 0; i < n; i++) {
+ x = args[i];
+ Py_INCREF(x);
+ SETLOCAL(i, x);
+ }
+ if (co->co_flags & CO_VARARGS) {
+ u = PyTuple_New(argcount - n);
+ if (u == NULL)
+ goto fail;
+ SETLOCAL(total_args, u);
+ for (i = n; i < argcount; i++) {
x = args[i];
Py_INCREF(x);
- SETLOCAL(i, x);
+ PyTuple_SET_ITEM(u, i-n, x);
}
- if (co->co_flags & CO_VARARGS) {
- u = PyTuple_New(argcount - n);
- if (u == NULL)
- goto fail;
- SETLOCAL(total_args, u);
- for (i = n; i < argcount; i++) {
- x = args[i];
- Py_INCREF(x);
- PyTuple_SET_ITEM(u, i-n, x);
- }
+ }
+ for (i = 0; i < kwcount; i++) {
+ PyObject **co_varnames;
+ PyObject *keyword = kws[2*i];
+ PyObject *value = kws[2*i + 1];
+ int j;
+ if (keyword == NULL || !PyUnicode_Check(keyword)) {
+ PyErr_Format(PyExc_TypeError,
+ "%U() keywords must be strings",
+ co->co_name);
+ goto fail;
}
- for (i = 0; i < kwcount; i++) {
- PyObject **co_varnames;
- PyObject *keyword = kws[2*i];
- PyObject *value = kws[2*i + 1];
- int j;
- if (keyword == NULL || !PyUnicode_Check(keyword)) {
- PyErr_Format(PyExc_TypeError,
- "%U() keywords must be strings",
- co->co_name);
- goto fail;
- }
- /* Speed hack: do raw pointer compares. As names are
- normally interned this should almost always hit. */
- co_varnames = ((PyTupleObject *)(co->co_varnames))->ob_item;
- for (j = 0; j < total_args; j++) {
- PyObject *nm = co_varnames[j];
- if (nm == keyword)
- goto kw_found;
- }
- /* Slow fallback, just in case */
- for (j = 0; j < total_args; j++) {
- PyObject *nm = co_varnames[j];
- int cmp = PyObject_RichCompareBool(
- keyword, nm, Py_EQ);
- if (cmp > 0)
- goto kw_found;
- else if (cmp < 0)
- goto fail;
- }
- if (j >= total_args && kwdict == NULL) {
- PyErr_Format(PyExc_TypeError,
- "%U() got an unexpected "
- "keyword argument '%S'",
- co->co_name,
- keyword);
+ /* Speed hack: do raw pointer compares. As names are
+ normally interned this should almost always hit. */
+ co_varnames = ((PyTupleObject *)(co->co_varnames))->ob_item;
+ for (j = 0; j < total_args; j++) {
+ PyObject *nm = co_varnames[j];
+ if (nm == keyword)
+ goto kw_found;
+ }
+ /* Slow fallback, just in case */
+ for (j = 0; j < total_args; j++) {
+ PyObject *nm = co_varnames[j];
+ int cmp = PyObject_RichCompareBool(
+ keyword, nm, Py_EQ);
+ if (cmp > 0)
+ goto kw_found;
+ else if (cmp < 0)
goto fail;
- }
- PyDict_SetItem(kwdict, keyword, value);
- continue;
- kw_found:
- if (GETLOCAL(j) != NULL) {
- PyErr_Format(PyExc_TypeError,
+ }
+ if (j >= total_args && kwdict == NULL) {
+ PyErr_Format(PyExc_TypeError,
+ "%U() got an unexpected "
+ "keyword argument '%S'",
+ co->co_name,
+ keyword);
+ goto fail;
+ }
+ PyDict_SetItem(kwdict, keyword, value);
+ continue;
+ kw_found:
+ if (GETLOCAL(j) != NULL) {
+ PyErr_Format(PyExc_TypeError,
"%U() got multiple "
- "values for keyword "
- "argument '%S'",
+ "values for argument '%S'",
co->co_name,
keyword);
- goto fail;
- }
- Py_INCREF(value);
- SETLOCAL(j, value);
+ goto fail;
}
- if (co->co_kwonlyargcount > 0) {
- for (i = co->co_argcount; i < total_args; i++) {
- PyObject *name;
- if (GETLOCAL(i) != NULL)
- continue;
- name = PyTuple_GET_ITEM(co->co_varnames, i);
- if (kwdefs != NULL) {
- PyObject *def = PyDict_GetItem(kwdefs, name);
- if (def) {
- Py_INCREF(def);
- SETLOCAL(i, def);
- continue;
- }
- }
- PyErr_Format(PyExc_TypeError,
- "%U() needs keyword-only argument %S",
- co->co_name, name);
- goto fail;
- }
+ Py_INCREF(value);
+ SETLOCAL(j, value);
+ }
+ if (argcount > co->co_argcount && !(co->co_flags & CO_VARARGS)) {
+ too_many_positional(co, argcount, defcount, fastlocals);
+ goto fail;
+ }
+ if (argcount < co->co_argcount) {
+ int m = co->co_argcount - defcount;
+ int missing = 0;
+ for (i = argcount; i < m; i++)
+ if (GETLOCAL(i) == NULL)
+ missing++;
+ if (missing) {
+ missing_arguments(co, missing, defcount, fastlocals);
+ goto fail;
}
- if (argcount < co->co_argcount) {
- int m = co->co_argcount - defcount;
- for (i = argcount; i < m; i++) {
- if (GETLOCAL(i) == NULL) {
- int j, given = 0;
- for (j = 0; j < co->co_argcount; j++)
- if (GETLOCAL(j))
- given++;
- PyErr_Format(PyExc_TypeError,
- "%U() takes %s %d "
- "argument%s "
- "(%d given)",
- co->co_name,
- ((co->co_flags & CO_VARARGS) ||
- defcount) ? "at least"
- : "exactly",
- m, m == 1 ? "" : "s", given);
- goto fail;
- }
+ if (n > m)
+ i = n - m;
+ else
+ i = 0;
+ for (; i < defcount; i++) {
+ if (GETLOCAL(m+i) == NULL) {
+ PyObject *def = defs[i];
+ Py_INCREF(def);
+ SETLOCAL(m+i, def);
}
- if (n > m)
- i = n - m;
- else
- i = 0;
- for (; i < defcount; i++) {
- if (GETLOCAL(m+i) == NULL) {
- PyObject *def = defs[i];
+ }
+ }
+ if (co->co_kwonlyargcount > 0) {
+ int missing = 0;
+ for (i = co->co_argcount; i < total_args; i++) {
+ PyObject *name;
+ if (GETLOCAL(i) != NULL)
+ continue;
+ name = PyTuple_GET_ITEM(co->co_varnames, i);
+ if (kwdefs != NULL) {
+ PyObject *def = PyDict_GetItem(kwdefs, name);
+ if (def) {
Py_INCREF(def);
- SETLOCAL(m+i, def);
+ SETLOCAL(i, def);
+ continue;
}
}
+ missing++;
+ }
+ if (missing) {
+ missing_arguments(co, missing, -1, fastlocals);
+ goto fail;
}
}
- else if (argcount > 0 || kwcount > 0) {
- PyErr_Format(PyExc_TypeError,
- "%U() takes no arguments (%d given)",
- co->co_name,
- argcount + kwcount);
- goto fail;
- }
+
/* Allocate and initialize storage for cell vars, and copy free
- vars into frame. This isn't too efficient right now. */
- if (PyTuple_GET_SIZE(co->co_cellvars)) {
- int i, j, nargs, found;
- Py_UNICODE *cellname, *argname;
+ vars into frame. */
+ for (i = 0; i < PyTuple_GET_SIZE(co->co_cellvars); ++i) {
PyObject *c;
-
- nargs = total_args;
- if (co->co_flags & CO_VARARGS)
- nargs++;
- if (co->co_flags & CO_VARKEYWORDS)
- nargs++;
-
- /* Initialize each cell var, taking into account
- cell vars that are initialized from arguments.
-
- Should arrange for the compiler to put cellvars
- that are arguments at the beginning of the cellvars
- list so that we can march over it more efficiently?
- */
- for (i = 0; i < PyTuple_GET_SIZE(co->co_cellvars); ++i) {
- cellname = PyUnicode_AS_UNICODE(
- PyTuple_GET_ITEM(co->co_cellvars, i));
- found = 0;
- for (j = 0; j < nargs; j++) {
- argname = PyUnicode_AS_UNICODE(
- PyTuple_GET_ITEM(co->co_varnames, j));
- if (Py_UNICODE_strcmp(cellname, argname) == 0) {
- c = PyCell_New(GETLOCAL(j));
- if (c == NULL)
- goto fail;
- GETLOCAL(co->co_nlocals + i) = c;
- found = 1;
- break;
- }
- }
- if (found == 0) {
- c = PyCell_New(NULL);
- if (c == NULL)
- goto fail;
- SETLOCAL(co->co_nlocals + i, c);
- }
- }
+ int arg;
+ /* Possibly account for the cell variable being an argument. */
+ if (co->co_cell2arg != NULL &&
+ (arg = co->co_cell2arg[i]) != CO_CELL_NOT_AN_ARG)
+ c = PyCell_New(GETLOCAL(arg));
+ else
+ c = PyCell_New(NULL);
+ if (c == NULL)
+ goto fail;
+ SETLOCAL(co->co_nlocals + i, c);
}
- if (PyTuple_GET_SIZE(co->co_freevars)) {
- int i;
- for (i = 0; i < PyTuple_GET_SIZE(co->co_freevars); ++i) {
- PyObject *o = PyTuple_GET_ITEM(closure, i);
- Py_INCREF(o);
- freevars[PyTuple_GET_SIZE(co->co_cellvars) + i] = o;
- }
+ for (i = 0; i < PyTuple_GET_SIZE(co->co_freevars); ++i) {
+ PyObject *o = PyTuple_GET_ITEM(closure, i);
+ Py_INCREF(o);
+ freevars[PyTuple_GET_SIZE(co->co_cellvars) + i] = o;
}
if (co->co_flags & CO_GENERATOR) {
@@ -3377,6 +3404,60 @@ special_lookup(PyObject *o, char *meth, PyObject **cache)
}
+/* These 3 functions deal with the exception state of generators. */
+
+static void
+save_exc_state(PyThreadState *tstate, PyFrameObject *f)
+{
+ PyObject *type, *value, *traceback;
+ Py_XINCREF(tstate->exc_type);
+ Py_XINCREF(tstate->exc_value);
+ Py_XINCREF(tstate->exc_traceback);
+ type = f->f_exc_type;
+ value = f->f_exc_value;
+ traceback = f->f_exc_traceback;
+ f->f_exc_type = tstate->exc_type;
+ f->f_exc_value = tstate->exc_value;
+ f->f_exc_traceback = tstate->exc_traceback;
+ Py_XDECREF(type);
+ Py_XDECREF(value);
+ Py_XDECREF(traceback);
+}
+
+static void
+swap_exc_state(PyThreadState *tstate, PyFrameObject *f)
+{
+ PyObject *tmp;
+ tmp = tstate->exc_type;
+ tstate->exc_type = f->f_exc_type;
+ f->f_exc_type = tmp;
+ tmp = tstate->exc_value;
+ tstate->exc_value = f->f_exc_value;
+ f->f_exc_value = tmp;
+ tmp = tstate->exc_traceback;
+ tstate->exc_traceback = f->f_exc_traceback;
+ f->f_exc_traceback = tmp;
+}
+
+static void
+restore_and_clear_exc_state(PyThreadState *tstate, PyFrameObject *f)
+{
+ PyObject *type, *value, *tb;
+ type = tstate->exc_type;
+ value = tstate->exc_value;
+ tb = tstate->exc_traceback;
+ tstate->exc_type = f->f_exc_type;
+ tstate->exc_value = f->f_exc_value;
+ tstate->exc_traceback = f->f_exc_traceback;
+ f->f_exc_type = NULL;
+ f->f_exc_value = NULL;
+ f->f_exc_traceback = NULL;
+ Py_XDECREF(type);
+ Py_XDECREF(value);
+ Py_XDECREF(tb);
+}
+
+
/* Logic for the raise statement (too complicated for inlining).
This *consumes* a reference count to each of its arguments. */
static enum why_code
@@ -4185,7 +4266,7 @@ ext_do_call(PyObject *func, PyObject ***pp_stack, int flags, int na, int nk)
if (PyErr_ExceptionMatches(PyExc_TypeError)) {
PyErr_Format(PyExc_TypeError,
"%.200s%.200s argument after * "
- "must be a sequence, not %200s",
+ "must be a sequence, not %.200s",
PyEval_GetFuncName(func),
PyEval_GetFuncDesc(func),
stararg->ob_type->tp_name);
diff --git a/Python/compile.c b/Python/compile.c
index ba593a0..567b230 100644
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -135,6 +135,7 @@ managed by compiler_enter_scope() and compiler_exit_scope().
struct compiler {
const char *c_filename;
+ PyObject *c_filename_obj;
struct symtable *c_st;
PyFutureFeatures *c_future; /* pointer to module's __future__ */
PyCompilerFlags *c_flags;
@@ -178,12 +179,13 @@ static int compiler_in_loop(struct compiler *);
static int inplace_binop(struct compiler *, operator_ty);
static int expr_constant(struct compiler *, expr_ty);
-static int compiler_with(struct compiler *, stmt_ty);
+static int compiler_with(struct compiler *, stmt_ty, int);
static int compiler_call_helper(struct compiler *c, int n,
asdl_seq *args,
asdl_seq *keywords,
expr_ty starargs,
expr_ty kwargs);
+static int compiler_try_except(struct compiler *, stmt_ty);
static PyCodeObject *assemble(struct compiler *, int addNone);
static PyObject *__doc__;
@@ -272,6 +274,9 @@ PyAST_CompileEx(mod_ty mod, const char *filename, PyCompilerFlags *flags,
if (!compiler_init(&c))
return NULL;
c.c_filename = filename;
+ c.c_filename_obj = PyUnicode_DecodeFSDefault(filename);
+ if (!c.c_filename_obj)
+ goto finally;
c.c_arena = arena;
c.c_future = PyFuture_FromAST(mod, filename);
if (c.c_future == NULL)
@@ -324,6 +329,8 @@ compiler_free(struct compiler *c)
PySymtable_Free(c->c_st);
if (c->c_future)
PyObject_Free(c->c_future);
+ if (c->c_filename_obj)
+ Py_DECREF(c->c_filename_obj);
Py_DECREF(c->c_stack);
}
@@ -1559,7 +1566,7 @@ compiler_class(struct compiler *c, stmt_ty s)
return 0;
}
/* return the (empty) __class__ cell */
- str = PyUnicode_InternFromString("__class__");
+ str = PyUnicode_InternFromString("@__class__");
if (str == NULL) {
compiler_exit_scope(c);
return 0;
@@ -1892,7 +1899,13 @@ compiler_try_finally(struct compiler *c, stmt_ty s)
compiler_use_next_block(c, body);
if (!compiler_push_fblock(c, FINALLY_TRY, body))
return 0;
- VISIT_SEQ(c, stmt, s->v.TryFinally.body);
+ if (s->v.Try.handlers && asdl_seq_LEN(s->v.Try.handlers)) {
+ if (!compiler_try_except(c, s))
+ return 0;
+ }
+ else {
+ VISIT_SEQ(c, stmt, s->v.Try.body);
+ }
ADDOP(c, POP_BLOCK);
compiler_pop_fblock(c, FINALLY_TRY, body);
@@ -1900,7 +1913,7 @@ compiler_try_finally(struct compiler *c, stmt_ty s)
compiler_use_next_block(c, end);
if (!compiler_push_fblock(c, FINALLY_END, end))
return 0;
- VISIT_SEQ(c, stmt, s->v.TryFinally.finalbody);
+ VISIT_SEQ(c, stmt, s->v.Try.finalbody);
ADDOP(c, END_FINALLY);
compiler_pop_fblock(c, FINALLY_END, end);
@@ -1954,15 +1967,15 @@ compiler_try_except(struct compiler *c, stmt_ty s)
compiler_use_next_block(c, body);
if (!compiler_push_fblock(c, EXCEPT, body))
return 0;
- VISIT_SEQ(c, stmt, s->v.TryExcept.body);
+ VISIT_SEQ(c, stmt, s->v.Try.body);
ADDOP(c, POP_BLOCK);
compiler_pop_fblock(c, EXCEPT, body);
ADDOP_JREL(c, JUMP_FORWARD, orelse);
- n = asdl_seq_LEN(s->v.TryExcept.handlers);
+ n = asdl_seq_LEN(s->v.Try.handlers);
compiler_use_next_block(c, except);
for (i = 0; i < n; i++) {
excepthandler_ty handler = (excepthandler_ty)asdl_seq_GET(
- s->v.TryExcept.handlers, i);
+ s->v.Try.handlers, i);
if (!handler->v.ExceptHandler.type && i < n-1)
return compiler_error(c, "default 'except:' must be last");
c->u->u_lineno_set = 0;
@@ -2049,12 +2062,21 @@ compiler_try_except(struct compiler *c, stmt_ty s)
}
ADDOP(c, END_FINALLY);
compiler_use_next_block(c, orelse);
- VISIT_SEQ(c, stmt, s->v.TryExcept.orelse);
+ VISIT_SEQ(c, stmt, s->v.Try.orelse);
compiler_use_next_block(c, end);
return 1;
}
static int
+compiler_try(struct compiler *c, stmt_ty s) {
+ if (s->v.Try.finalbody && asdl_seq_LEN(s->v.Try.finalbody))
+ return compiler_try_finally(c, s);
+ else
+ return compiler_try_except(c, s);
+}
+
+
+static int
compiler_import_as(struct compiler *c, identifier name, identifier asname)
{
/* The IMPORT_NAME opcode was already generated. This function
@@ -2301,10 +2323,8 @@ compiler_visit_stmt(struct compiler *c, stmt_ty s)
}
ADDOP_I(c, RAISE_VARARGS, n);
break;
- case TryExcept_kind:
- return compiler_try_except(c, s);
- case TryFinally_kind:
- return compiler_try_finally(c, s);
+ case Try_kind:
+ return compiler_try(c, s);
case Assert_kind:
return compiler_assert(c, s);
case Import_kind:
@@ -2335,7 +2355,7 @@ compiler_visit_stmt(struct compiler *c, stmt_ty s)
case Continue_kind:
return compiler_continue(c);
case With_kind:
- return compiler_with(c, s);
+ return compiler_with(c, s, 0);
}
return 1;
}
@@ -3026,7 +3046,7 @@ expr_constant(struct compiler *c, expr_ty e)
case Name_kind:
/* optimize away names that can't be reassigned */
id = PyBytes_AS_STRING(
- _PyUnicode_AsDefaultEncodedString(e->v.Name.id, NULL));
+ _PyUnicode_AsDefaultEncodedString(e->v.Name.id));
if (strcmp(id, "True") == 0) return 1;
if (strcmp(id, "False") == 0) return 0;
if (strcmp(id, "None") == 0) return 0;
@@ -3062,9 +3082,10 @@ expr_constant(struct compiler *c, expr_ty e)
exit(*exc)
*/
static int
-compiler_with(struct compiler *c, stmt_ty s)
+compiler_with(struct compiler *c, stmt_ty s, int pos)
{
basicblock *block, *finally;
+ withitem_ty item = asdl_seq_GET(s->v.With.items, pos);
assert(s->kind == With_kind);
@@ -3074,7 +3095,7 @@ compiler_with(struct compiler *c, stmt_ty s)
return 0;
/* Evaluate EXPR */
- VISIT(c, expr, s->v.With.context_expr);
+ VISIT(c, expr, item->context_expr);
ADDOP_JREL(c, SETUP_WITH, finally);
/* SETUP_WITH pushes a finally block. */
@@ -3083,16 +3104,20 @@ compiler_with(struct compiler *c, stmt_ty s)
return 0;
}
- if (s->v.With.optional_vars) {
- VISIT(c, expr, s->v.With.optional_vars);
+ if (item->optional_vars) {
+ VISIT(c, expr, item->optional_vars);
}
else {
/* Discard result from context.__enter__() */
ADDOP(c, POP_TOP);
}
- /* BLOCK code */
- VISIT_SEQ(c, stmt, s->v.With.body);
+ pos++;
+ if (pos == asdl_seq_LEN(s->v.With.items))
+ /* BLOCK code */
+ VISIT_SEQ(c, stmt, s->v.With.body)
+ else if (!compiler_with(c, s, pos))
+ return 0;
/* End of try block; start the finally block */
ADDOP(c, POP_BLOCK);
@@ -3361,7 +3386,7 @@ compiler_in_loop(struct compiler *c) {
static int
compiler_error(struct compiler *c, const char *errstr)
{
- PyObject *loc, *filename;
+ PyObject *loc;
PyObject *u = NULL, *v = NULL;
loc = PyErr_ProgramText(c->c_filename, c->u->u_lineno);
@@ -3369,16 +3394,7 @@ compiler_error(struct compiler *c, const char *errstr)
Py_INCREF(Py_None);
loc = Py_None;
}
- if (c->c_filename != NULL) {
- filename = PyUnicode_DecodeFSDefault(c->c_filename);
- if (!filename)
- goto exit;
- }
- else {
- Py_INCREF(Py_None);
- filename = Py_None;
- }
- u = Py_BuildValue("(NiiO)", filename, c->u->u_lineno,
+ u = Py_BuildValue("(OiiO)", c->c_filename_obj, c->u->u_lineno,
c->u->u_col_offset, loc);
if (!u)
goto exit;
@@ -3927,7 +3943,6 @@ makecode(struct compiler *c, struct assembler *a)
PyObject *consts = NULL;
PyObject *names = NULL;
PyObject *varnames = NULL;
- PyObject *filename = NULL;
PyObject *name = NULL;
PyObject *freevars = NULL;
PyObject *cellvars = NULL;
@@ -3951,10 +3966,6 @@ makecode(struct compiler *c, struct assembler *a)
freevars = dict_keys_inorder(c->u->u_freevars, PyTuple_Size(cellvars));
if (!freevars)
goto error;
- filename = PyUnicode_DecodeFSDefault(c->c_filename);
- if (!filename)
- goto error;
-
nlocals = PyDict_Size(c->u->u_varnames);
flags = compute_code_flags(c);
if (flags < 0)
@@ -3974,14 +3985,13 @@ makecode(struct compiler *c, struct assembler *a)
nlocals, stackdepth(c), flags,
bytecode, consts, names, varnames,
freevars, cellvars,
- filename, c->u->u_name,
+ c->c_filename_obj, c->u->u_name,
c->u->u_firstlineno,
a->a_lnotab);
error:
Py_XDECREF(consts);
Py_XDECREF(names);
Py_XDECREF(varnames);
- Py_XDECREF(filename);
Py_XDECREF(name);
Py_XDECREF(freevars);
Py_XDECREF(cellvars);
diff --git a/Python/dtoa.c b/Python/dtoa.c
index 44dc01f..82b6faa 100644
--- a/Python/dtoa.c
+++ b/Python/dtoa.c
@@ -2055,7 +2055,7 @@ _Py_dg_strtod(const char *s00, char **se)
+ Exp_msk1
;
word1(&rv) = 0;
- dsign = 0;
+ /* dsign = 0; */
break;
}
}
@@ -2092,7 +2092,7 @@ _Py_dg_strtod(const char *s00, char **se)
goto undfl;
}
}
- dsign = 1 - dsign;
+ /* dsign = 1 - dsign; */
break;
}
if ((aadj = ratio(delta, bs)) <= 2.) {
diff --git a/Python/dynload_aix.c b/Python/dynload_aix.c
index 149990d..74c7b32 100644
--- a/Python/dynload_aix.c
+++ b/Python/dynload_aix.c
@@ -154,7 +154,7 @@ aix_loaderror(const char *pathname)
}
-dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname,
+dl_funcptr _PyImport_GetDynLoadFunc(const char *shortname,
const char *pathname, FILE *fp)
{
dl_funcptr p;
diff --git a/Python/dynload_dl.c b/Python/dynload_dl.c
index 2606e1e..37519b2 100644
--- a/Python/dynload_dl.c
+++ b/Python/dynload_dl.c
@@ -10,17 +10,17 @@
extern char *Py_GetProgramName(void);
const struct filedescr _PyImport_DynLoadFiletab[] = {
- {".o", "rb", C_EXTENSION},
- {"module.o", "rb", C_EXTENSION},
- {0, 0}
+ {".o", "rb", C_EXTENSION},
+ {"module.o", "rb", C_EXTENSION},
+ {0, 0}
};
-dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname,
- const char *pathname, FILE *fp)
+dl_funcptr _PyImport_GetDynLoadFunc(const char *shortname,
+ const char *pathname, FILE *fp)
{
- char funcname[258];
+ char funcname[258];
- PyOS_snprintf(funcname, sizeof(funcname), "PyInit_%.200s", shortname);
- return dl_loadmod(Py_GetProgramName(), pathname, funcname);
+ PyOS_snprintf(funcname, sizeof(funcname), "PyInit_%.200s", shortname);
+ return dl_loadmod(Py_GetProgramName(), pathname, funcname);
}
diff --git a/Python/dynload_hpux.c b/Python/dynload_hpux.c
index 18a8137..3ebbbad 100644
--- a/Python/dynload_hpux.c
+++ b/Python/dynload_hpux.c
@@ -19,7 +19,7 @@ const struct filedescr _PyImport_DynLoadFiletab[] = {
{0, 0}
};
-dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname,
+dl_funcptr _PyImport_GetDynLoadFunc(const char *shortname,
const char *pathname, FILE *fp)
{
dl_funcptr p;
diff --git a/Python/dynload_next.c b/Python/dynload_next.c
index cabf9b9..eb17950 100644
--- a/Python/dynload_next.c
+++ b/Python/dynload_next.c
@@ -31,8 +31,8 @@ const struct filedescr _PyImport_DynLoadFiletab[] = {
#define LINKOPTIONS NSLINKMODULE_OPTION_BINDNOW| \
NSLINKMODULE_OPTION_RETURN_ON_ERROR|NSLINKMODULE_OPTION_PRIVATE
#endif
-dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname,
- const char *pathname, FILE *fp)
+dl_funcptr _PyImport_GetDynLoadFunc(const char *shortname,
+ const char *pathname, FILE *fp)
{
dl_funcptr p = NULL;
char funcname[258];
diff --git a/Python/dynload_os2.c b/Python/dynload_os2.c
index 101c024..f7264da 100644
--- a/Python/dynload_os2.c
+++ b/Python/dynload_os2.c
@@ -15,7 +15,7 @@ const struct filedescr _PyImport_DynLoadFiletab[] = {
{0, 0}
};
-dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname,
+dl_funcptr _PyImport_GetDynLoadFunc(const char *shortname,
const char *pathname, FILE *fp)
{
dl_funcptr p;
diff --git a/Python/dynload_shlib.c b/Python/dynload_shlib.c
index 7ea510e..1c215c3 100644
--- a/Python/dynload_shlib.c
+++ b/Python/dynload_shlib.c
@@ -75,7 +75,7 @@ static struct {
static int nhandles = 0;
-dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname,
+dl_funcptr _PyImport_GetDynLoadFunc(const char *shortname,
const char *pathname, FILE *fp)
{
dl_funcptr p;
diff --git a/Python/dynload_win.c b/Python/dynload_win.c
index 73a1dcf..932a637 100644
--- a/Python/dynload_win.c
+++ b/Python/dynload_win.c
@@ -171,8 +171,8 @@ static char *GetPythonImport (HINSTANCE hModule)
return NULL;
}
-dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname,
- const char *pathname, FILE *fp)
+dl_funcptr _PyImport_GetDynLoadWindows(const char *shortname,
+ PyObject *pathname, FILE *fp)
{
dl_funcptr p;
char funcname[258], *import_python;
@@ -185,29 +185,19 @@ dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname,
{
HINSTANCE hDLL = NULL;
- char pathbuf[260];
- LPTSTR dummy;
unsigned int old_mode;
ULONG_PTR cookie = 0;
- /* We use LoadLibraryEx so Windows looks for dependent DLLs
- in directory of pathname first. However, Windows95
- can sometimes not work correctly unless the absolute
- path is used. If GetFullPathName() fails, the LoadLibrary
- will certainly fail too, so use its error code */
-
+
/* Don't display a message box when Python can't load a DLL */
old_mode = SetErrorMode(SEM_FAILCRITICALERRORS);
- if (GetFullPathName(pathname,
- sizeof(pathbuf),
- pathbuf,
- &dummy)) {
- ULONG_PTR cookie = _Py_ActivateActCtx();
- /* XXX This call doesn't exist in Windows CE */
- hDLL = LoadLibraryEx(pathname, NULL,
- LOAD_WITH_ALTERED_SEARCH_PATH);
- _Py_DeactivateActCtx(cookie);
- }
+ cookie = _Py_ActivateActCtx();
+ /* We use LoadLibraryEx so Windows looks for dependent DLLs
+ in directory of pathname first. */
+ /* XXX This call doesn't exist in Windows CE */
+ hDLL = LoadLibraryExW(PyUnicode_AS_UNICODE(pathname), NULL,
+ LOAD_WITH_ALTERED_SEARCH_PATH);
+ _Py_DeactivateActCtx(cookie);
/* restore old error mode settings */
SetErrorMode(old_mode);
@@ -264,21 +254,21 @@ dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname,
} else {
char buffer[256];
+ PyOS_snprintf(buffer, sizeof(buffer),
#ifdef _DEBUG
- PyOS_snprintf(buffer, sizeof(buffer), "python%d%d_d.dll",
+ "python%d%d_d.dll",
#else
- PyOS_snprintf(buffer, sizeof(buffer), "python%d%d.dll",
+ "python%d%d.dll",
#endif
PY_MAJOR_VERSION,PY_MINOR_VERSION);
import_python = GetPythonImport(hDLL);
if (import_python &&
strcasecmp(buffer,import_python)) {
- PyOS_snprintf(buffer, sizeof(buffer),
- "Module use of %.150s conflicts "
- "with this version of Python.",
- import_python);
- PyErr_SetString(PyExc_ImportError,buffer);
+ PyErr_Format(PyExc_ImportError,
+ "Module use of %.150s conflicts "
+ "with this version of Python.",
+ import_python);
FreeLibrary(hDLL);
return NULL;
}
diff --git a/Python/getargs.c b/Python/getargs.c
index 600941d..4b57153 100644
--- a/Python/getargs.c
+++ b/Python/getargs.c
@@ -310,20 +310,18 @@ vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags)
if (max == 0) {
if (args == NULL)
return 1;
- PyOS_snprintf(msgbuf, sizeof(msgbuf),
- "%.200s%s takes no arguments",
- fname==NULL ? "function" : fname,
- fname==NULL ? "" : "()");
- PyErr_SetString(PyExc_TypeError, msgbuf);
+ PyErr_Format(PyExc_TypeError,
+ "%.200s%s takes no arguments",
+ fname==NULL ? "function" : fname,
+ fname==NULL ? "" : "()");
return 0;
}
else if (min == 1 && max == 1) {
if (args == NULL) {
- PyOS_snprintf(msgbuf, sizeof(msgbuf),
- "%.200s%s takes at least one argument",
- fname==NULL ? "function" : fname,
- fname==NULL ? "" : "()");
- PyErr_SetString(PyExc_TypeError, msgbuf);
+ PyErr_Format(PyExc_TypeError,
+ "%.200s%s takes at least one argument",
+ fname==NULL ? "function" : fname,
+ fname==NULL ? "" : "()");
return 0;
}
msg = convertitem(args, &format, p_va, flags, levels,
@@ -349,20 +347,18 @@ vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags)
len = PyTuple_GET_SIZE(args);
if (len < min || max < len) {
- if (message == NULL) {
- PyOS_snprintf(msgbuf, sizeof(msgbuf),
- "%.150s%s takes %s %d argument%s "
- "(%ld given)",
- fname==NULL ? "function" : fname,
- fname==NULL ? "" : "()",
- min==max ? "exactly"
- : len < min ? "at least" : "at most",
- len < min ? min : max,
- (len < min ? min : max) == 1 ? "" : "s",
- Py_SAFE_DOWNCAST(len, Py_ssize_t, long));
- message = msgbuf;
- }
- PyErr_SetString(PyExc_TypeError, message);
+ if (message == NULL)
+ PyErr_Format(PyExc_TypeError,
+ "%.150s%s takes %s %d argument%s (%ld given)",
+ fname==NULL ? "function" : fname,
+ fname==NULL ? "" : "()",
+ min==max ? "exactly"
+ : len < min ? "at least" : "at most",
+ len < min ? min : max,
+ (len < min ? min : max) == 1 ? "" : "s",
+ Py_SAFE_DOWNCAST(len, Py_ssize_t, long));
+ else
+ PyErr_SetString(PyExc_TypeError, message);
return 0;
}
@@ -551,7 +547,7 @@ convertitem(PyObject *arg, const char **p_format, va_list *p_va, int flags,
#define UNICODE_DEFAULT_ENCODING(arg) \
- _PyUnicode_AsDefaultEncodedString(arg, NULL)
+ _PyUnicode_AsDefaultEncodedString(arg)
/* Format an error message generated by convertsimple(). */
@@ -966,9 +962,10 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
case 'u': /* raw unicode buffer (Py_UNICODE *) */
case 'Z': /* raw unicode buffer or None */
{
+ Py_UNICODE **p = va_arg(*p_va, Py_UNICODE **);
+
if (*format == '#') { /* any buffer-like object */
/* "s#" or "Z#" */
- Py_UNICODE **p = va_arg(*p_va, Py_UNICODE **);
FETCH_SIZE;
if (c == 'Z' && arg == Py_None) {
@@ -984,8 +981,6 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
format++;
} else {
/* "s" or "Z" */
- Py_UNICODE **p = va_arg(*p_va, Py_UNICODE **);
-
if (c == 'Z' && arg == Py_None)
*p = NULL;
else if (PyUnicode_Check(arg)) {
@@ -1459,8 +1454,8 @@ vgetargskeywords(PyObject *args, PyObject *keywords, const char *format,
nargs = PyTuple_GET_SIZE(args);
nkeywords = (keywords == NULL) ? 0 : PyDict_Size(keywords);
if (nargs + nkeywords > len) {
- PyErr_Format(PyExc_TypeError, "%s%s takes at most %d "
- "argument%s (%d given)",
+ PyErr_Format(PyExc_TypeError,
+ "%s%s takes at most %d argument%s (%d given)",
(fname == NULL) ? "function" : fname,
(fname == NULL) ? "" : "()",
len,
diff --git a/Python/import.c b/Python/import.c
index 23752ee..19e975a 100644
--- a/Python/import.c
+++ b/Python/import.c
@@ -102,30 +102,43 @@ typedef unsigned short mode_t;
Python 3.2a1: 3170 (add DUP_TOP_TWO, remove DUP_TOPX and ROT_FOUR)
tag: cpython-32
Python 3.2a2 3180 (add DELETE_DEREF)
+ Python 3.3a0 3190 __class__ super closure changed
*/
/* MAGIC must change whenever the bytecode emitted by the compiler may no
longer be understood by older implementations of the eval loop (usually
due to the addition of new opcodes)
- TAG must change for each major Python release. The magic number will take
- care of any bytecode changes that occur during development.
+ TAG and PYC_TAG_UNICODE must change for each major Python release. The magic
+ number will take care of any bytecode changes that occur during development.
*/
-#define MAGIC (3180 | ((long)'\r'<<16) | ((long)'\n'<<24))
-#define TAG "cpython-32"
+#define QUOTE(arg) #arg
+#define STRIFY(name) QUOTE(name)
+#define MAJOR STRIFY(PY_MAJOR_VERSION)
+#define MINOR STRIFY(PY_MINOR_VERSION)
+#define MAGIC (3190 | ((long)'\r'<<16) | ((long)'\n'<<24))
+#define TAG "cpython-" MAJOR MINOR;
#define CACHEDIR "__pycache__"
+static const Py_UNICODE CACHEDIR_UNICODE[] = {
+ '_', '_', 'p', 'y', 'c', 'a', 'c', 'h', 'e', '_', '_', '\0'};
/* Current magic word and string tag as globals. */
static long pyc_magic = MAGIC;
static const char *pyc_tag = TAG;
-
-/* See _PyImport_FixupExtensionUnicode() below */
+static const Py_UNICODE PYC_TAG_UNICODE[] = {
+ 'c', 'p', 'y', 't', 'h', 'o', 'n', '-', PY_MAJOR_VERSION + 48, PY_MINOR_VERSION + 48, '\0'};
+#undef QUOTE
+#undef STRIFY
+#undef MAJOR
+#undef MINOR
+
+/* See _PyImport_FixupExtensionObject() below */
static PyObject *extensions = NULL;
+/* Function from Parser/tokenizer.c */
+extern char * PyTokenizer_FindEncodingFilename(int, PyObject *);
+
/* This table is defined in config.c: */
extern struct _inittab _PyImport_Inittab[];
-/* Method from Parser/tokenizer.c */
-extern char * PyTokenizer_FindEncoding(int);
-
struct _inittab *PyImport_Inittab = _PyImport_Inittab;
/* these tables define the module suffixes that Python recognizes */
@@ -140,6 +153,8 @@ static const struct filedescr _PyImport_StandardFiletab[] = {
{0, 0}
};
+static PyObject *initstr = NULL;
+
/* Initialize things */
@@ -151,6 +166,10 @@ _PyImport_Init(void)
int countD = 0;
int countS = 0;
+ initstr = PyUnicode_InternFromString("__init__");
+ if (initstr == NULL)
+ Py_FatalError("Can't initialize import variables");
+
/* prepare _PyImport_Filetab: copy entries from
_PyImport_DynLoadFiletab and _PyImport_StandardFiletab.
*/
@@ -329,7 +348,7 @@ _PyImport_ReInitLock(void)
/* Forked as a side effect of import */
long me = PyThread_get_thread_ident();
PyThread_acquire_lock(import_lock, 0);
- /* XXX: can the previous line fail? */
+ /* XXX: can the previous line fail? */
import_lock_thread = me;
import_lock_level--;
} else {
@@ -418,7 +437,6 @@ void
PyImport_Cleanup(void)
{
Py_ssize_t pos, ndone;
- char *name;
PyObject *key, *value, *dict;
PyInterpreterState *interp = PyThreadState_GET()->interp;
PyObject *modules = interp->modules;
@@ -491,14 +509,13 @@ PyImport_Cleanup(void)
if (value->ob_refcnt != 1)
continue;
if (PyUnicode_Check(key) && PyModule_Check(value)) {
- name = _PyUnicode_AsString(key);
- if (strcmp(name, "builtins") == 0)
+ if (PyUnicode_CompareWithASCIIString(key, "builtins") == 0)
continue;
- if (strcmp(name, "sys") == 0)
+ if (PyUnicode_CompareWithASCIIString(key, "sys") == 0)
continue;
if (Py_VerboseFlag)
- PySys_WriteStderr(
- "# cleanup[1] %s\n", name);
+ PySys_FormatStderr(
+ "# cleanup[1] %U\n", key);
_PyModule_Clear(value);
PyDict_SetItem(modules, key, Py_None);
ndone++;
@@ -510,13 +527,12 @@ PyImport_Cleanup(void)
pos = 0;
while (PyDict_Next(modules, &pos, &key, &value)) {
if (PyUnicode_Check(key) && PyModule_Check(value)) {
- name = _PyUnicode_AsString(key);
- if (strcmp(name, "builtins") == 0)
+ if (PyUnicode_CompareWithASCIIString(key, "builtins") == 0)
continue;
- if (strcmp(name, "sys") == 0)
+ if (PyUnicode_CompareWithASCIIString(key, "sys") == 0)
continue;
if (Py_VerboseFlag)
- PySys_WriteStderr("# cleanup[2] %s\n", name);
+ PySys_FormatStderr("# cleanup[2] %U\n", key);
_PyModule_Clear(value);
PyDict_SetItem(modules, key, Py_None);
}
@@ -566,10 +582,10 @@ PyImport_GetMagicTag(void)
once, we keep a static dictionary 'extensions' keyed by module name
(for built-in modules) or by filename (for dynamically loaded
modules), containing these modules. A copy of the module's
- dictionary is stored by calling _PyImport_FixupExtensionUnicode()
+ dictionary is stored by calling _PyImport_FixupExtensionObject()
immediately after the module initialization function succeeds. A
copy can be retrieved from there by calling
- _PyImport_FindExtensionUnicode().
+ _PyImport_FindExtensionObject().
Modules which do support multiple initialization set their m_size
field to a non-negative number (indicating the size of the
@@ -578,7 +594,8 @@ PyImport_GetMagicTag(void)
*/
int
-_PyImport_FixupExtensionUnicode(PyObject *mod, char *name, PyObject *filename)
+_PyImport_FixupExtensionObject(PyObject *mod, PyObject *name,
+ PyObject *filename)
{
PyObject *modules, *dict;
struct PyModuleDef *def;
@@ -597,10 +614,10 @@ _PyImport_FixupExtensionUnicode(PyObject *mod, char *name, PyObject *filename)
return -1;
}
modules = PyImport_GetModuleDict();
- if (PyDict_SetItemString(modules, name, mod) < 0)
+ if (PyDict_SetItem(modules, name, mod) < 0)
return -1;
if (_PyState_AddModule(mod, def) < 0) {
- PyDict_DelItemString(modules, name);
+ PyDict_DelItem(modules, name);
return -1;
}
if (def->m_size == -1) {
@@ -626,17 +643,17 @@ int
_PyImport_FixupBuiltin(PyObject *mod, char *name)
{
int res;
- PyObject *filename;
- filename = PyUnicode_FromString(name);
- if (filename == NULL)
+ PyObject *nameobj;
+ nameobj = PyUnicode_InternFromString(name);
+ if (nameobj == NULL)
return -1;
- res = _PyImport_FixupExtensionUnicode(mod, name, filename);
- Py_DECREF(filename);
+ res = _PyImport_FixupExtensionObject(mod, nameobj, nameobj);
+ Py_DECREF(nameobj);
return res;
}
PyObject *
-_PyImport_FindExtensionUnicode(char *name, PyObject *filename)
+_PyImport_FindExtensionObject(PyObject *name, PyObject *filename)
{
PyObject *mod, *mdict;
PyModuleDef* def;
@@ -649,7 +666,7 @@ _PyImport_FindExtensionUnicode(char *name, PyObject *filename)
/* Module does not support repeated initialization */
if (def->m_base.m_copy == NULL)
return NULL;
- mod = PyImport_AddModule(name);
+ mod = PyImport_AddModuleObject(name);
if (mod == NULL)
return NULL;
mdict = PyModule_GetDict(mod);
@@ -664,30 +681,30 @@ _PyImport_FindExtensionUnicode(char *name, PyObject *filename)
mod = def->m_base.m_init();
if (mod == NULL)
return NULL;
- PyDict_SetItemString(PyImport_GetModuleDict(), name, mod);
+ PyDict_SetItem(PyImport_GetModuleDict(), name, mod);
Py_DECREF(mod);
}
if (_PyState_AddModule(mod, def) < 0) {
- PyDict_DelItemString(PyImport_GetModuleDict(), name);
+ PyDict_DelItem(PyImport_GetModuleDict(), name);
Py_DECREF(mod);
return NULL;
}
if (Py_VerboseFlag)
- PySys_FormatStderr("import %s # previously loaded (%U)\n",
+ PySys_FormatStderr("import %U # previously loaded (%R)\n",
name, filename);
return mod;
}
PyObject *
-_PyImport_FindBuiltin(char *name)
+_PyImport_FindBuiltin(const char *name)
{
- PyObject *res, *filename;
- filename = PyUnicode_FromString(name);
- if (filename == NULL)
+ PyObject *res, *nameobj;
+ nameobj = PyUnicode_InternFromString(name);
+ if (nameobj == NULL)
return NULL;
- res = _PyImport_FindExtensionUnicode(name, filename);
- Py_DECREF(filename);
+ res = _PyImport_FindExtensionObject(nameobj, nameobj);
+ Py_DECREF(nameobj);
return res;
}
@@ -698,18 +715,18 @@ _PyImport_FindBuiltin(char *name)
'NEW' REFERENCE! */
PyObject *
-PyImport_AddModule(const char *name)
+PyImport_AddModuleObject(PyObject *name)
{
PyObject *modules = PyImport_GetModuleDict();
PyObject *m;
- if ((m = PyDict_GetItemString(modules, name)) != NULL &&
+ if ((m = PyDict_GetItem(modules, name)) != NULL &&
PyModule_Check(m))
return m;
- m = PyModule_New(name);
+ m = PyModule_NewObject(name);
if (m == NULL)
return NULL;
- if (PyDict_SetItemString(modules, name, m) != 0) {
+ if (PyDict_SetItem(modules, name, m) != 0) {
Py_DECREF(m);
return NULL;
}
@@ -718,22 +735,34 @@ PyImport_AddModule(const char *name)
return m;
}
+PyObject *
+PyImport_AddModule(const char *name)
+{
+ PyObject *nameobj, *module;
+ nameobj = PyUnicode_FromString(name);
+ if (nameobj == NULL)
+ return NULL;
+ module = PyImport_AddModuleObject(nameobj);
+ Py_DECREF(nameobj);
+ return module;
+}
+
+
/* Remove name from sys.modules, if it's there. */
static void
-remove_module(const char *name)
+remove_module(PyObject *name)
{
PyObject *modules = PyImport_GetModuleDict();
- if (PyDict_GetItemString(modules, name) == NULL)
+ if (PyDict_GetItem(modules, name) == NULL)
return;
- if (PyDict_DelItemString(modules, name) < 0)
+ if (PyDict_DelItem(modules, name) < 0)
Py_FatalError("import: deleting existing key in"
"sys.modules failed");
}
-static PyObject * get_sourcefile(char *file);
-static char *make_source_pathname(char *pathname, char *buf);
-static char *make_compiled_pathname(char *pathname, char *buf, size_t buflen,
- int debug);
+static PyObject * get_sourcefile(PyObject *filename);
+static PyObject *make_source_pathname(PyObject *pathname);
+static PyObject* make_compiled_pathname(Py_UNICODE *pathname, int debug);
/* Execute a code object in a module and return the module object
* WITH INCREMENTED REFERENCE COUNT. If an error occurs, name is
@@ -763,10 +792,41 @@ PyObject *
PyImport_ExecCodeModuleWithPathnames(char *name, PyObject *co, char *pathname,
char *cpathname)
{
+ PyObject *m = NULL;
+ PyObject *nameobj, *pathobj = NULL, *cpathobj = NULL;
+
+ nameobj = PyUnicode_FromString(name);
+ if (nameobj == NULL)
+ return NULL;
+
+ if (pathname != NULL) {
+ pathobj = PyUnicode_DecodeFSDefault(pathname);
+ if (pathobj == NULL)
+ goto error;
+ } else
+ pathobj = NULL;
+ if (cpathname != NULL) {
+ cpathobj = PyUnicode_DecodeFSDefault(cpathname);
+ if (cpathobj == NULL)
+ goto error;
+ } else
+ cpathobj = NULL;
+ m = PyImport_ExecCodeModuleObject(nameobj, co, pathobj, cpathobj);
+error:
+ Py_DECREF(nameobj);
+ Py_XDECREF(pathobj);
+ Py_XDECREF(cpathobj);
+ return m;
+}
+
+PyObject*
+PyImport_ExecCodeModuleObject(PyObject *name, PyObject *co, PyObject *pathname,
+ PyObject *cpathname)
+{
PyObject *modules = PyImport_GetModuleDict();
PyObject *m, *d, *v;
- m = PyImport_AddModule(name);
+ m = PyImport_AddModuleObject(name);
if (m == NULL)
return NULL;
/* If the module is being reloaded, we get the old module back
@@ -778,12 +838,13 @@ PyImport_ExecCodeModuleWithPathnames(char *name, PyObject *co, char *pathname,
goto error;
}
/* Remember the filename as the __file__ attribute */
- v = NULL;
if (pathname != NULL) {
v = get_sourcefile(pathname);
if (v == NULL)
PyErr_Clear();
}
+ else
+ v = NULL;
if (v == NULL) {
v = ((PyCodeObject *)co)->co_filename;
Py_INCREF(v);
@@ -793,27 +854,21 @@ PyImport_ExecCodeModuleWithPathnames(char *name, PyObject *co, char *pathname,
Py_DECREF(v);
/* Remember the pyc path name as the __cached__ attribute. */
- if (cpathname == NULL) {
- v = Py_None;
- Py_INCREF(v);
- }
- else if ((v = PyUnicode_FromString(cpathname)) == NULL) {
- PyErr_Clear(); /* Not important enough to report */
+ if (cpathname != NULL)
+ v = cpathname;
+ else
v = Py_None;
- Py_INCREF(v);
- }
if (PyDict_SetItemString(d, "__cached__", v) != 0)
PyErr_Clear(); /* Not important enough to report */
- Py_DECREF(v);
v = PyEval_EvalCode(co, d, d);
if (v == NULL)
goto error;
Py_DECREF(v);
- if ((m = PyDict_GetItemString(modules, name)) == NULL) {
+ if ((m = PyDict_GetItem(modules, name)) == NULL) {
PyErr_Format(PyExc_ImportError,
- "Loaded module %.200s not found in sys.modules",
+ "Loaded module %R not found in sys.modules",
name);
return NULL;
}
@@ -831,10 +886,10 @@ PyImport_ExecCodeModuleWithPathnames(char *name, PyObject *co, char *pathname,
/* Like strrchr(string, '/') but searches for the rightmost of either SEP
or ALTSEP, if the latter is defined.
*/
-static char *
-rightmost_sep(char *s)
+static Py_UNICODE*
+rightmost_sep(Py_UNICODE *s)
{
- char *found, c;
+ Py_UNICODE *found, c;
for (found = NULL; (c = *s); s++) {
if (c == SEP
#ifdef ALTSEP
@@ -852,15 +907,18 @@ rightmost_sep(char *s)
/* Given a pathname for a Python source file, fill a buffer with the
pathname for the corresponding compiled file. Return the pathname
for the compiled file, or NULL if there's no space in the buffer.
- Doesn't set an exception. */
+ Doesn't set an exception.
+
+ foo.py -> __pycache__/foo.<tag>.pyc */
-static char *
-make_compiled_pathname(char *pathname, char *buf, size_t buflen, int debug)
+static PyObject*
+make_compiled_pathname(Py_UNICODE *pathname, int debug)
{
- /* foo.py -> __pycache__/foo.<tag>.pyc */
- size_t len = strlen(pathname);
+ Py_UNICODE buf[MAXPATHLEN];
+ size_t buflen = (size_t)MAXPATHLEN;
+ size_t len = Py_UNICODE_strlen(pathname);
size_t i, save;
- char *pos;
+ Py_UNICODE *pos;
int sep = SEP;
/* Sanity check that the buffer has roughly enough space to hold what
@@ -872,35 +930,37 @@ make_compiled_pathname(char *pathname, char *buf, size_t buflen, int debug)
sanity check before writing the extension to ensure we do not
overflow the buffer.
*/
- if (len + strlen(CACHEDIR) + strlen(pyc_tag) + 5 > buflen)
+ if (len + Py_UNICODE_strlen(CACHEDIR_UNICODE) + Py_UNICODE_strlen(PYC_TAG_UNICODE) + 5 > buflen)
return NULL;
/* Find the last path separator and copy everything from the start of
the source string up to and including the separator.
*/
- if ((pos = rightmost_sep(pathname)) == NULL) {
+ pos = rightmost_sep(pathname);
+ if (pos == NULL) {
i = 0;
}
else {
sep = *pos;
i = pos - pathname + 1;
- strncpy(buf, pathname, i);
+ Py_UNICODE_strncpy(buf, pathname, i);
}
save = i;
buf[i++] = '\0';
/* Add __pycache__/ */
- strcat(buf, CACHEDIR);
- i += strlen(CACHEDIR) - 1;
+ Py_UNICODE_strcat(buf, CACHEDIR_UNICODE);
+ i += Py_UNICODE_strlen(CACHEDIR_UNICODE) - 1;
buf[i++] = sep;
- buf[i++] = '\0';
+ buf[i] = '\0';
/* Add the base filename, but remove the .py or .pyw extension, since
the tag name must go before the extension.
*/
- strcat(buf, pathname + save);
- if ((pos = strrchr(buf, '.')) != NULL)
+ Py_UNICODE_strcat(buf, pathname + save);
+ pos = Py_UNICODE_strrchr(buf + i, '.');
+ if (pos != NULL)
*++pos = '\0';
- strcat(buf, pyc_tag);
+ Py_UNICODE_strcat(buf, PYC_TAG_UNICODE);
/* The length test above assumes that we're only adding one character
to the end of what would normally be the extension. What if there
is no extension, or the string ends in '.' or '.p', and otherwise
@@ -950,11 +1010,15 @@ make_compiled_pathname(char *pathname, char *buf, size_t buflen, int debug)
#if 0
printf("strlen(buf): %d; buflen: %d\n", (int)strlen(buf), (int)buflen);
#endif
- if (strlen(buf) + 5 > buflen)
+ len = Py_UNICODE_strlen(buf);
+ if (len + 5 > buflen)
return NULL;
- strcat(buf, debug ? ".pyc" : ".pyo");
- assert(strlen(buf) < buflen);
- return buf;
+ buf[len] = '.'; len++;
+ buf[len] = 'p'; len++;
+ buf[len] = 'y'; len++;
+ buf[len] = debug ? 'c' : 'o'; len++;
+ assert(len <= buflen);
+ return PyUnicode_FromUnicode(buf, len);
}
@@ -962,20 +1026,28 @@ make_compiled_pathname(char *pathname, char *buf, size_t buflen, int debug)
source file, if the path matches the PEP 3147 format. This does not check
for any file existence, however, if the pyc file name does not match PEP
3147 style, NULL is returned. buf must be at least as big as pathname;
- the resulting path will always be shorter. */
+ the resulting path will always be shorter.
-static char *
-make_source_pathname(char *pathname, char *buf)
+ (...)/__pycache__/foo.<tag>.pyc -> (...)/foo.py */
+
+static PyObject*
+make_source_pathname(PyObject *pathobj)
{
- /* __pycache__/foo.<tag>.pyc -> foo.py */
+ Py_UNICODE buf[MAXPATHLEN];
+ Py_UNICODE *pathname;
+ Py_UNICODE *left, *right, *dot0, *dot1, sep;
size_t i, j;
- char *left, *right, *dot0, *dot1, sep;
+
+ if (PyUnicode_GET_SIZE(pathobj) > MAXPATHLEN)
+ return NULL;
+ pathname = PyUnicode_AS_UNICODE(pathobj);
/* Look back two slashes from the end. In between these two slashes
must be the string __pycache__ or this is not a PEP 3147 style
path. It's possible for there to be only one slash.
*/
- if ((right = rightmost_sep(pathname)) == NULL)
+ right = rightmost_sep(pathname);
+ if (right == NULL)
return NULL;
sep = *right;
*right = '\0';
@@ -985,19 +1057,19 @@ make_source_pathname(char *pathname, char *buf)
left = pathname;
else
left++;
- if (right-left != strlen(CACHEDIR) ||
- strncmp(left, CACHEDIR, right-left) != 0)
+ if (right-left != Py_UNICODE_strlen(CACHEDIR_UNICODE) ||
+ Py_UNICODE_strncmp(left, CACHEDIR_UNICODE, right-left) != 0)
return NULL;
/* Now verify that the path component to the right of the last slash
has two dots in it.
*/
- if ((dot0 = strchr(right + 1, '.')) == NULL)
+ if ((dot0 = Py_UNICODE_strchr(right + 1, '.')) == NULL)
return NULL;
- if ((dot1 = strchr(dot0 + 1, '.')) == NULL)
+ if ((dot1 = Py_UNICODE_strchr(dot0 + 1, '.')) == NULL)
return NULL;
/* Too many dots? */
- if (strchr(dot1 + 1, '.') != NULL)
+ if (Py_UNICODE_strchr(dot1 + 1, '.') != NULL)
return NULL;
/* This is a PEP 3147 path. Start by copying everything from the
@@ -1005,10 +1077,11 @@ make_source_pathname(char *pathname, char *buf)
copy the file's basename, removing the magic tag and adding a .py
suffix.
*/
- strncpy(buf, pathname, (i=left-pathname));
- strncpy(buf+i, right+1, (j=dot0-right));
- strcpy(buf+i+j, "py");
- return buf;
+ Py_UNICODE_strncpy(buf, pathname, (i=left-pathname));
+ Py_UNICODE_strncpy(buf+i, right+1, (j=dot0-right));
+ buf[i+j] = 'p';
+ buf[i+j+1] = 'y';
+ return PyUnicode_FromUnicode(buf, i+j+2);
}
/* Given a pathname for a Python source file, its time of last
@@ -1019,31 +1092,31 @@ make_source_pathname(char *pathname, char *buf)
Doesn't set an exception. */
static FILE *
-check_compiled_module(char *pathname, time_t mtime, char *cpathname)
+check_compiled_module(PyObject *pathname, time_t mtime, PyObject *cpathname)
{
FILE *fp;
long magic;
long pyc_mtime;
- fp = fopen(cpathname, "rb");
+ fp = _Py_fopen(cpathname, "rb");
if (fp == NULL)
return NULL;
magic = PyMarshal_ReadLongFromFile(fp);
if (magic != pyc_magic) {
if (Py_VerboseFlag)
- PySys_WriteStderr("# %s has bad magic\n", cpathname);
+ PySys_FormatStderr("# %R has bad magic\n", cpathname);
fclose(fp);
return NULL;
}
pyc_mtime = PyMarshal_ReadLongFromFile(fp);
if (pyc_mtime != mtime) {
if (Py_VerboseFlag)
- PySys_WriteStderr("# %s has bad mtime\n", cpathname);
+ PySys_FormatStderr("# %R has bad mtime\n", cpathname);
fclose(fp);
return NULL;
}
if (Py_VerboseFlag)
- PySys_WriteStderr("# %s matches %s\n", cpathname, pathname);
+ PySys_FormatStderr("# %R matches %R\n", cpathname, pathname);
return fp;
}
@@ -1051,7 +1124,7 @@ check_compiled_module(char *pathname, time_t mtime, char *cpathname)
/* Read a code object from a file and check it for validity */
static PyCodeObject *
-read_compiled_module(char *cpathname, FILE *fp)
+read_compiled_module(PyObject *cpathname, FILE *fp)
{
PyObject *co;
@@ -1060,7 +1133,7 @@ read_compiled_module(char *cpathname, FILE *fp)
return NULL;
if (!PyCode_Check(co)) {
PyErr_Format(PyExc_ImportError,
- "Non-code object in %.200s", cpathname);
+ "Non-code object in %R", cpathname);
Py_DECREF(co);
return NULL;
}
@@ -1072,7 +1145,7 @@ read_compiled_module(char *cpathname, FILE *fp)
module object WITH INCREMENTED REFERENCE COUNT */
static PyObject *
-load_compiled_module(char *name, char *cpathname, FILE *fp)
+load_compiled_module(PyObject *name, PyObject *cpathname, FILE *fp)
{
long magic;
PyCodeObject *co;
@@ -1081,7 +1154,7 @@ load_compiled_module(char *name, char *cpathname, FILE *fp)
magic = PyMarshal_ReadLongFromFile(fp);
if (magic != pyc_magic) {
PyErr_Format(PyExc_ImportError,
- "Bad magic number in %.200s", cpathname);
+ "Bad magic number in %R", cpathname);
return NULL;
}
(void) PyMarshal_ReadLongFromFile(fp);
@@ -1089,10 +1162,10 @@ load_compiled_module(char *name, char *cpathname, FILE *fp)
if (co == NULL)
return NULL;
if (Py_VerboseFlag)
- PySys_WriteStderr("import %s # precompiled from %s\n",
- name, cpathname);
- m = PyImport_ExecCodeModuleWithPathnames(
- name, (PyObject *)co, cpathname, cpathname);
+ PySys_FormatStderr("import %U # precompiled from %R\n",
+ name, cpathname);
+ m = PyImport_ExecCodeModuleObject(name, (PyObject *)co,
+ cpathname, cpathname);
Py_DECREF(co);
return m;
@@ -1101,29 +1174,40 @@ load_compiled_module(char *name, char *cpathname, FILE *fp)
/* Parse a source file and return the corresponding code object */
static PyCodeObject *
-parse_source_module(const char *pathname, FILE *fp)
+parse_source_module(PyObject *pathname, FILE *fp)
{
- PyCodeObject *co = NULL;
+ PyCodeObject *co;
+ PyObject *pathbytes;
mod_ty mod;
PyCompilerFlags flags;
- PyArena *arena = PyArena_New();
- if (arena == NULL)
+ PyArena *arena;
+
+ pathbytes = PyUnicode_EncodeFSDefault(pathname);
+ if (pathbytes == NULL)
return NULL;
+ arena = PyArena_New();
+ if (arena == NULL) {
+ Py_DECREF(pathbytes);
+ return NULL;
+ }
+
flags.cf_flags = 0;
- mod = PyParser_ASTFromFile(fp, pathname, NULL,
+ mod = PyParser_ASTFromFile(fp, PyBytes_AS_STRING(pathbytes), NULL,
Py_file_input, 0, 0, &flags,
NULL, arena);
- if (mod) {
- co = PyAST_Compile(mod, pathname, NULL, arena);
- }
+ if (mod != NULL)
+ co = PyAST_Compile(mod, PyBytes_AS_STRING(pathbytes), NULL, arena);
+ else
+ co = NULL;
+ Py_DECREF(pathbytes);
PyArena_Free(arena);
return co;
}
-
/* Helper to open a bytecode file for writing in exclusive mode */
+#ifndef MS_WINDOWS
static FILE *
open_exclusive(char *filename, mode_t mode)
{
@@ -1154,6 +1238,7 @@ open_exclusive(char *filename, mode_t mode)
return fopen(filename, "wb");
#endif
}
+#endif
/* Write a compiled module to a file, placing the time of last
@@ -1162,10 +1247,10 @@ open_exclusive(char *filename, mode_t mode)
remove the file. */
static void
-write_compiled_module(PyCodeObject *co, char *cpathname, struct stat *srcstat)
+write_compiled_module(PyCodeObject *co, PyObject *cpathname,
+ struct stat *srcstat)
{
FILE *fp;
- char *dirpath;
time_t mtime = srcstat->st_mtime;
#ifdef MS_WINDOWS /* since Windows uses different permissions */
mode_t mode = srcstat->st_mode & ~S_IEXEC;
@@ -1174,39 +1259,82 @@ write_compiled_module(PyCodeObject *co, char *cpathname, struct stat *srcstat)
mode_t dirmode = (srcstat->st_mode |
S_IXUSR | S_IXGRP | S_IXOTH |
S_IWUSR | S_IWGRP | S_IWOTH);
+ PyObject *dirbytes;
+#endif
+#ifdef MS_WINDOWS
+ int fd;
+#else
+ PyObject *cpathbytes;
#endif
- int saved;
+ PyObject *dirname;
+ Py_UNICODE *dirsep;
+ int res, ok;
/* Ensure that the __pycache__ directory exists. */
- dirpath = rightmost_sep(cpathname);
- if (dirpath == NULL) {
+ dirsep = rightmost_sep(PyUnicode_AS_UNICODE(cpathname));
+ if (dirsep == NULL) {
if (Py_VerboseFlag)
- PySys_WriteStderr(
- "# no %s path found %s\n",
- CACHEDIR, cpathname);
+ PySys_FormatStderr("# no %s path found %R\n", CACHEDIR, cpathname);
+ return;
+ }
+ dirname = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(cpathname),
+ dirsep - PyUnicode_AS_UNICODE(cpathname));
+ if (dirname == NULL) {
+ PyErr_Clear();
return;
}
- saved = *dirpath;
- *dirpath = '\0';
#ifdef MS_WINDOWS
- if (_mkdir(cpathname) < 0 && errno != EEXIST) {
+ res = CreateDirectoryW(PyUnicode_AS_UNICODE(dirname), NULL);
+ ok = (res != 0);
+ if (!ok && GetLastError() == ERROR_ALREADY_EXISTS)
+ ok = 1;
#else
- if (mkdir(cpathname, dirmode) < 0 && errno != EEXIST) {
+ dirbytes = PyUnicode_EncodeFSDefault(dirname);
+ if (dirbytes == NULL) {
+ PyErr_Clear();
+ return;
+ }
+ res = mkdir(PyBytes_AS_STRING(dirbytes), dirmode);
+ Py_DECREF(dirbytes);
+ if (0 <= res)
+ ok = 1;
+ else
+ ok = (errno == EEXIST);
#endif
- *dirpath = saved;
+ if (!ok) {
if (Py_VerboseFlag)
- PySys_WriteStderr(
- "# cannot create cache dir %s\n", cpathname);
+ PySys_FormatStderr("# cannot create cache dir %R\n", dirname);
+ Py_DECREF(dirname);
return;
}
- *dirpath = saved;
+ Py_DECREF(dirname);
- fp = open_exclusive(cpathname, mode);
+#ifdef MS_WINDOWS
+ (void)DeleteFileW(PyUnicode_AS_UNICODE(cpathname));
+ fd = _wopen(PyUnicode_AS_UNICODE(cpathname),
+ O_EXCL | O_CREAT | O_WRONLY | O_TRUNC | O_BINARY,
+ mode);
+ if (0 <= fd)
+ fp = fdopen(fd, "wb");
+ else
+ fp = NULL;
+#else
+ cpathbytes = PyUnicode_EncodeFSDefault(cpathname);
+ if (cpathbytes == NULL) {
+ PyErr_Clear();
+ return;
+ }
+
+ fp = open_exclusive(PyBytes_AS_STRING(cpathbytes), mode);
+#endif
if (fp == NULL) {
if (Py_VerboseFlag)
- PySys_WriteStderr(
- "# can't create %s\n", cpathname);
+ PySys_FormatStderr(
+ "# can't create %R\n", cpathname);
+#ifndef MS_WINDOWS
+ Py_DECREF(cpathbytes);
+#endif
return;
}
PyMarshal_WriteLongToFile(pyc_magic, fp, Py_MARSHAL_VERSION);
@@ -1215,12 +1343,20 @@ write_compiled_module(PyCodeObject *co, char *cpathname, struct stat *srcstat)
PyMarshal_WriteObjectToFile((PyObject *)co, fp, Py_MARSHAL_VERSION);
if (fflush(fp) != 0 || ferror(fp)) {
if (Py_VerboseFlag)
- PySys_WriteStderr("# can't write %s\n", cpathname);
+ PySys_FormatStderr("# can't write %R\n", cpathname);
/* Don't keep partial file */
fclose(fp);
- (void) unlink(cpathname);
+#ifdef MS_WINDOWS
+ (void)DeleteFileW(PyUnicode_AS_UNICODE(cpathname));
+#else
+ (void) unlink(PyBytes_AS_STRING(cpathbytes));
+ Py_DECREF(cpathbytes);
+#endif
return;
}
+#ifndef MS_WINDOWS
+ Py_DECREF(cpathbytes);
+#endif
/* Now write the true mtime */
fseek(fp, 4L, 0);
assert(mtime < LONG_MAX);
@@ -1228,7 +1364,7 @@ write_compiled_module(PyCodeObject *co, char *cpathname, struct stat *srcstat)
fflush(fp);
fclose(fp);
if (Py_VerboseFlag)
- PySys_WriteStderr("# wrote %s\n", cpathname);
+ PySys_FormatStderr("# wrote %R\n", cpathname);
}
static void
@@ -1255,26 +1391,44 @@ update_code_filenames(PyCodeObject *co, PyObject *oldname, PyObject *newname)
}
}
-static int
-update_compiled_module(PyCodeObject *co, char *pathname)
+static void
+update_compiled_module(PyCodeObject *co, PyObject *newname)
{
- PyObject *oldname, *newname;
-
- newname = PyUnicode_DecodeFSDefault(pathname);
- if (newname == NULL)
- return -1;
+ PyObject *oldname;
- if (!PyUnicode_Compare(co->co_filename, newname)) {
- Py_DECREF(newname);
- return 0;
- }
+ if (PyUnicode_Compare(co->co_filename, newname) == 0)
+ return;
oldname = co->co_filename;
Py_INCREF(oldname);
update_code_filenames(co, oldname, newname);
Py_DECREF(oldname);
- Py_DECREF(newname);
- return 1;
+}
+
+static PyObject *
+imp_fix_co_filename(PyObject *self, PyObject *args)
+{
+ PyObject *co;
+ PyObject *file_path;
+
+ if (!PyArg_ParseTuple(args, "OO:_fix_co_filename", &co, &file_path))
+ return NULL;
+
+ if (!PyCode_Check(co)) {
+ PyErr_SetString(PyExc_TypeError,
+ "first argument must be a code object");
+ return NULL;
+ }
+
+ if (!PyUnicode_Check(file_path)) {
+ PyErr_SetString(PyExc_TypeError,
+ "second argument must be a string");
+ return NULL;
+ }
+
+ update_compiled_module((PyCodeObject*)co, file_path);
+
+ Py_RETURN_NONE;
}
/* Load a source module from a given file and return its module
@@ -1282,20 +1436,19 @@ update_compiled_module(PyCodeObject *co, char *pathname)
byte-compiled file, use that instead. */
static PyObject *
-load_source_module(char *name, char *pathname, FILE *fp)
+load_source_module(PyObject *name, PyObject *pathname, FILE *fp)
{
struct stat st;
FILE *fpc;
- char buf[MAXPATHLEN+1];
- char *cpathname;
+ PyObject *cpathname = NULL, *cpathbytes = NULL;
PyCodeObject *co;
- PyObject *m;
+ PyObject *m = NULL;
if (fstat(fileno(fp), &st) != 0) {
PyErr_Format(PyExc_RuntimeError,
- "unable to get file status from '%s'",
+ "unable to get file status from %R",
pathname);
- return NULL;
+ goto error;
}
#if SIZEOF_TIME_T > 4
/* Python's .pyc timestamp handling presumes that the timestamp fits
@@ -1305,41 +1458,50 @@ load_source_module(char *name, char *pathname, FILE *fp)
if (st.st_mtime >> 32) {
PyErr_SetString(PyExc_OverflowError,
"modification time overflows a 4 byte field");
- return NULL;
+ goto error;
}
#endif
cpathname = make_compiled_pathname(
- pathname, buf, (size_t)MAXPATHLEN + 1, !Py_OptimizeFlag);
- if (cpathname != NULL &&
- (fpc = check_compiled_module(pathname, st.st_mtime, cpathname))) {
+ PyUnicode_AS_UNICODE(pathname),
+ !Py_OptimizeFlag);
+
+ if (cpathname != NULL)
+ fpc = check_compiled_module(pathname, st.st_mtime, cpathname);
+ else
+ fpc = NULL;
+
+ if (fpc) {
co = read_compiled_module(cpathname, fpc);
fclose(fpc);
if (co == NULL)
- return NULL;
- if (update_compiled_module(co, pathname) < 0)
- return NULL;
+ goto error;
+ update_compiled_module(co, pathname);
if (Py_VerboseFlag)
- PySys_WriteStderr("import %s # precompiled from %s\n",
- name, cpathname);
- pathname = cpathname;
+ PySys_FormatStderr("import %U # precompiled from %R\n",
+ name, cpathname);
+ m = PyImport_ExecCodeModuleObject(name, (PyObject *)co,
+ cpathname, cpathname);
}
else {
co = parse_source_module(pathname, fp);
if (co == NULL)
- return NULL;
+ goto error;
if (Py_VerboseFlag)
- PySys_WriteStderr("import %s # from %s\n",
- name, pathname);
- if (cpathname) {
+ PySys_FormatStderr("import %U # from %R\n",
+ name, pathname);
+ if (cpathname != NULL) {
PyObject *ro = PySys_GetObject("dont_write_bytecode");
if (ro == NULL || !PyObject_IsTrue(ro))
write_compiled_module(co, cpathname, &st);
}
+ m = PyImport_ExecCodeModuleObject(name, (PyObject *)co,
+ pathname, cpathname);
}
- m = PyImport_ExecCodeModuleWithPathnames(
- name, (PyObject *)co, pathname, cpathname);
Py_DECREF(co);
+error:
+ Py_XDECREF(cpathbytes);
+ Py_XDECREF(cpathname);
return m;
}
@@ -1347,101 +1509,106 @@ load_source_module(char *name, char *pathname, FILE *fp)
* Returns the path to the py file if available, else the given path
*/
static PyObject *
-get_sourcefile(char *file)
+get_sourcefile(PyObject *filename)
{
- char py[MAXPATHLEN + 1];
Py_ssize_t len;
- PyObject *u;
+ Py_UNICODE *fileuni;
+ PyObject *py;
struct stat statbuf;
- if (!file || !*file) {
+ len = PyUnicode_GET_SIZE(filename);
+ if (len == 0)
Py_RETURN_NONE;
- }
- len = strlen(file);
- /* match '*.py?' */
- if (len > MAXPATHLEN || PyOS_strnicmp(&file[len-4], ".py", 3) != 0) {
- return PyUnicode_DecodeFSDefault(file);
- }
+ /* don't match *.pyc or *.pyo? */
+ fileuni = PyUnicode_AS_UNICODE(filename);
+ if (len < 5
+ || fileuni[len-4] != '.'
+ || (fileuni[len-3] != 'p' && fileuni[len-3] != 'P')
+ || (fileuni[len-2] != 'y' && fileuni[len-2] != 'Y'))
+ goto unchanged;
/* Start by trying to turn PEP 3147 path into source path. If that
* fails, just chop off the trailing character, i.e. legacy pyc path
* to py.
*/
- if (make_source_pathname(file, py) == NULL) {
- strncpy(py, file, len-1);
- py[len-1] = '\0';
+ py = make_source_pathname(filename);
+ if (py == NULL) {
+ PyErr_Clear();
+ py = PyUnicode_FromUnicode(fileuni, len - 1);
}
+ if (py == NULL)
+ goto error;
- if (stat(py, &statbuf) == 0 &&
- S_ISREG(statbuf.st_mode)) {
- u = PyUnicode_DecodeFSDefault(py);
- }
- else {
- u = PyUnicode_DecodeFSDefault(file);
- }
- return u;
+ if (_Py_stat(py, &statbuf) == 0 && S_ISREG(statbuf.st_mode))
+ return py;
+ Py_DECREF(py);
+ goto unchanged;
+
+error:
+ PyErr_Clear();
+unchanged:
+ Py_INCREF(filename);
+ return filename;
}
/* Forward */
-static PyObject *load_module(char *, FILE *, char *, int, PyObject *);
-static struct filedescr *find_module(char *, char *, PyObject *,
- char *, size_t, FILE **, PyObject **);
-static struct _frozen * find_frozen(char *);
+static PyObject *load_module(PyObject *, FILE *, PyObject *, int, PyObject *);
+static struct filedescr *find_module(PyObject *, PyObject *, PyObject *,
+ PyObject **, FILE **, PyObject **);
+static struct _frozen * find_frozen(PyObject *);
/* Load a package and return its module object WITH INCREMENTED
REFERENCE COUNT */
static PyObject *
-load_package(char *name, char *pathname)
+load_package(PyObject *name, PyObject *pathname)
{
- PyObject *m, *d;
- PyObject *file = NULL;
- PyObject *path = NULL;
+ PyObject *m, *d, *bufobj;
+ PyObject *file = NULL, *path_list = NULL;
int err;
- char buf[MAXPATHLEN+1];
FILE *fp = NULL;
struct filedescr *fdp;
- m = PyImport_AddModule(name);
+ m = PyImport_AddModuleObject(name);
if (m == NULL)
return NULL;
if (Py_VerboseFlag)
- PySys_WriteStderr("import %s # directory %s\n",
- name, pathname);
- d = PyModule_GetDict(m);
+ PySys_FormatStderr("import %U # directory %R\n",
+ name, pathname);
file = get_sourcefile(pathname);
if (file == NULL)
- goto error;
- path = Py_BuildValue("[O]", file);
- if (path == NULL)
- goto error;
+ return NULL;
+ path_list = Py_BuildValue("[O]", file);
+ if (path_list == NULL) {
+ Py_DECREF(file);
+ return NULL;
+ }
+ d = PyModule_GetDict(m);
err = PyDict_SetItemString(d, "__file__", file);
+ Py_DECREF(file);
if (err == 0)
- err = PyDict_SetItemString(d, "__path__", path);
- if (err != 0)
- goto error;
- buf[0] = '\0';
- fdp = find_module(name, "__init__", path, buf, sizeof(buf), &fp, NULL);
+ err = PyDict_SetItemString(d, "__path__", path_list);
+ if (err != 0) {
+ Py_DECREF(path_list);
+ return NULL;
+ }
+ fdp = find_module(name, initstr, path_list,
+ &bufobj, &fp, NULL);
+ Py_DECREF(path_list);
if (fdp == NULL) {
if (PyErr_ExceptionMatches(PyExc_ImportError)) {
PyErr_Clear();
Py_INCREF(m);
+ return m;
}
else
- m = NULL;
- goto cleanup;
+ return NULL;
}
- m = load_module(name, fp, buf, fdp->type, NULL);
+ m = load_module(name, fp, bufobj, fdp->type, NULL);
+ Py_XDECREF(bufobj);
if (fp != NULL)
fclose(fp);
- goto cleanup;
-
- error:
- m = NULL;
- cleanup:
- Py_XDECREF(path);
- Py_XDECREF(file);
return m;
}
@@ -1449,11 +1616,12 @@ load_package(char *name, char *pathname)
/* Helper to test for built-in module */
static int
-is_builtin(char *name)
+is_builtin(PyObject *name)
{
- int i;
+ int i, cmp;
for (i = 0; PyImport_Inittab[i].name != NULL; i++) {
- if (strcmp(name, PyImport_Inittab[i].name) == 0) {
+ cmp = PyUnicode_CompareWithASCIIString(name, PyImport_Inittab[i].name);
+ if (cmp == 0) {
if (PyImport_Inittab[i].initfunc == NULL)
return -1;
else
@@ -1547,43 +1715,276 @@ PyImport_GetImporter(PyObject *path) {
pathname and an open file. Return NULL if the module is not found. */
#ifdef MS_COREDLL
-extern FILE *PyWin_FindRegisteredModule(const char *, struct filedescr **,
- char *, Py_ssize_t);
+extern FILE *_PyWin_FindRegisteredModule(PyObject *, struct filedescr **,
+ PyObject **p_path);
#endif
-static int case_ok(char *, Py_ssize_t, Py_ssize_t, char *);
-static int find_init_module(char *); /* Forward */
+/* Forward */
+static int case_ok(PyObject *, Py_ssize_t, PyObject *);
+static int find_init_module(PyObject *);
static struct filedescr importhookdescr = {"", "", IMP_HOOK};
-static struct filedescr *
-find_module(char *fullname, char *subname, PyObject *path, char *buf,
- size_t buflen, FILE **p_fp, PyObject **p_loader)
+/* Get the path of a module: get its importer and call importer.find_module()
+ hook, or check if the module if a package (if path/__init__.py exists).
+
+ -1: error: a Python error occurred
+ 0: ignore: an error occurred because of invalid data, but the error is not
+ important enough to be reported.
+ 1: get path: module not found, but *buf contains its path
+ 2: found: *p_fd is the file descriptor (IMP_HOOK or PKG_DIRECTORY)
+ and *buf is the path */
+
+static int
+find_module_path(PyObject *fullname, PyObject *name, PyObject *path,
+ PyObject *path_hooks, PyObject *path_importer_cache,
+ PyObject **p_path, PyObject **p_loader, struct filedescr **p_fd)
+{
+ Py_UNICODE buf[MAXPATHLEN+1];
+ Py_ssize_t buflen = MAXPATHLEN+1;
+ PyObject *path_unicode, *filename;
+ Py_ssize_t len;
+ struct stat statbuf;
+ static struct filedescr fd_package = {"", "", PKG_DIRECTORY};
+
+ if (PyUnicode_Check(path)) {
+ Py_INCREF(path);
+ path_unicode = path;
+ }
+ else if (PyBytes_Check(path)) {
+ path_unicode = PyUnicode_DecodeFSDefaultAndSize(
+ PyBytes_AS_STRING(path), PyBytes_GET_SIZE(path));
+ if (path_unicode == NULL)
+ return -1;
+ }
+ else
+ return 0;
+
+ len = PyUnicode_GET_SIZE(path_unicode);
+ if (len + 2 + PyUnicode_GET_SIZE(name) + MAXSUFFIXSIZE >= buflen) {
+ Py_DECREF(path_unicode);
+ return 0; /* Too long */
+ }
+ Py_UNICODE_strcpy(buf, PyUnicode_AS_UNICODE(path_unicode));
+ Py_DECREF(path_unicode);
+
+ if (Py_UNICODE_strlen(buf) != len)
+ return 0; /* path contains '\0' */
+
+ /* sys.path_hooks import hook */
+ if (p_loader != NULL) {
+ PyObject *importer;
+
+ importer = get_path_importer(path_importer_cache,
+ path_hooks, path);
+ if (importer == NULL) {
+ return -1;
+ }
+ /* Note: importer is a borrowed reference */
+ if (importer != Py_None) {
+ PyObject *loader;
+ loader = PyObject_CallMethod(importer,
+ "find_module", "O", fullname);
+ if (loader == NULL)
+ return -1; /* error */
+ if (loader != Py_None) {
+ /* a loader was found */
+ *p_loader = loader;
+ *p_fd = &importhookdescr;
+ return 2;
+ }
+ Py_DECREF(loader);
+ return 0;
+ }
+ }
+ /* no hook was found, use builtin import */
+
+ if (len > 0 && buf[len-1] != SEP
+#ifdef ALTSEP
+ && buf[len-1] != ALTSEP
+#endif
+ )
+ buf[len++] = SEP;
+ Py_UNICODE_strcpy(buf+len, PyUnicode_AS_UNICODE(name));
+ len += PyUnicode_GET_SIZE(name);
+
+ filename = PyUnicode_FromUnicode(buf, len);
+ if (filename == NULL)
+ return -1;
+
+ /* Check for package import (buf holds a directory name,
+ and there's an __init__ module in that directory */
+#ifdef HAVE_STAT
+ if (_Py_stat(filename, &statbuf) == 0 && /* it exists */
+ S_ISDIR(statbuf.st_mode)) /* it's a directory */
+ {
+ int match;
+
+ match = case_ok(filename, 0, name);
+ if (match < 0) {
+ Py_DECREF(filename);
+ return -1;
+ }
+ if (match) { /* case matches */
+ if (find_init_module(filename)) { /* and has __init__.py */
+ *p_path = filename;
+ *p_fd = &fd_package;
+ return 2;
+ }
+ else {
+ int err;
+ err = PyErr_WarnFormat(PyExc_ImportWarning, 1,
+ "Not importing directory %R: missing __init__.py",
+ filename);
+ if (err) {
+ Py_DECREF(filename);
+ return -1;
+ }
+ }
+ }
+ }
+#endif
+ *p_path = filename;
+ return 1;
+}
+
+/* Find a module in search_path_list. For each path, try
+ find_module_path() or try each _PyImport_Filetab suffix.
+
+ If the module is found, return a file descriptor, write the path in
+ *p_filename, write the pointer to the file object into *p_fp, and (if
+ p_loader is not NULL) the loader into *p_loader.
+
+ Otherwise, raise an exception and return NULL. */
+
+static struct filedescr*
+find_module_path_list(PyObject *fullname, PyObject *name,
+ PyObject *search_path_list, PyObject *path_hooks,
+ PyObject *path_importer_cache,
+ PyObject **p_path, FILE **p_fp, PyObject **p_loader)
{
Py_ssize_t i, npath;
- size_t len, namelen;
struct filedescr *fdp = NULL;
char *filemode;
FILE *fp = NULL;
- PyObject *path_hooks, *path_importer_cache;
- struct stat statbuf;
+ PyObject *prefix, *filename;
+ int match;
+
+ npath = PyList_Size(search_path_list);
+ for (i = 0; i < npath; i++) {
+ PyObject *path;
+ int ok;
+
+ path = PyList_GetItem(search_path_list, i);
+ if (path == NULL)
+ return NULL;
+
+ prefix = NULL;
+ ok = find_module_path(fullname, name, path,
+ path_hooks, path_importer_cache,
+ &prefix, p_loader, &fdp);
+ if (ok < 0)
+ return NULL;
+ if (ok == 0)
+ continue;
+ if (ok == 2) {
+ *p_path = prefix;
+ return fdp;
+ }
+
+ for (fdp = _PyImport_Filetab; fdp->suffix != NULL; fdp++) {
+ filemode = fdp->mode;
+ if (filemode[0] == 'U')
+ filemode = "r" PY_STDIOTEXTMODE;
+
+ filename = PyUnicode_FromFormat("%U%s", prefix, fdp->suffix);
+ if (filename == NULL) {
+ Py_DECREF(prefix);
+ return NULL;
+ }
+
+ if (Py_VerboseFlag > 1)
+ PySys_FormatStderr("# trying %R\n", filename);
+
+ fp = _Py_fopen(filename, filemode);
+ if (fp == NULL) {
+ Py_DECREF(filename);
+ if (PyErr_Occurred()) {
+ Py_DECREF(prefix);
+ return NULL;
+ }
+ continue;
+ }
+ match = case_ok(filename, -(Py_ssize_t)strlen(fdp->suffix), name);
+ if (match < 0) {
+ Py_DECREF(prefix);
+ Py_DECREF(filename);
+ return NULL;
+ }
+ if (match) {
+ Py_DECREF(prefix);
+ *p_path = filename;
+ *p_fp = fp;
+ return fdp;
+ }
+ Py_DECREF(filename);
+
+ fclose(fp);
+ fp = NULL;
+ }
+ Py_DECREF(prefix);
+ }
+ PyErr_Format(PyExc_ImportError,
+ "No module named %R", name);
+ return NULL;
+}
+
+/* Find a module:
+
+ - try find_module() of each sys.meta_path hook
+ - try find_frozen()
+ - try is_builtin()
+ - try _PyWin_FindRegisteredModule() (Windows only)
+ - otherwise, call find_module_path_list() with search_path_list (if not
+ NULL) or sys.path
+
+ fullname can be NULL, but only if p_loader is NULL.
+
+ Return:
+
+ - &fd_builtin (C_BUILTIN) if it is a builtin
+ - &fd_frozen (PY_FROZEN) if it is frozen
+ - &fd_package (PKG_DIRECTORY) and write the filename into *p_path
+ if it is a package
+ - &importhookdescr (IMP_HOOK) and write the loader into *p_loader if a
+ importer loader was found
+ - a file descriptor (PY_SOURCE, PY_COMPILED, C_EXTENSION, PY_RESOURCE or
+ PY_CODERESOURCE: see _PyImport_Filetab), write the filename into
+ *p_path and the pointer to the open file into *p_fp
+ - NULL on error
+
+ By default, *p_path, *p_fp and *p_loader (if set) are set to NULL.
+ Eg. *p_path is set to NULL for a builtin package.
+*/
+
+static struct filedescr *
+find_module(PyObject *fullname, PyObject *name, PyObject *search_path_list,
+ PyObject **p_path, FILE **p_fp, PyObject **p_loader)
+{
+ Py_ssize_t i, npath;
static struct filedescr fd_frozen = {"", "", PY_FROZEN};
static struct filedescr fd_builtin = {"", "", C_BUILTIN};
- static struct filedescr fd_package = {"", "", PKG_DIRECTORY};
- char name[MAXPATHLEN+1];
-#if defined(PYOS_OS2)
- size_t saved_len;
- size_t saved_namelen;
- char *saved_buf = NULL;
-#endif
+ PyObject *path_hooks, *path_importer_cache;
+
+ *p_path = NULL;
+ *p_fp = NULL;
if (p_loader != NULL)
*p_loader = NULL;
- if (strlen(subname) > MAXPATHLEN) {
+ if (PyUnicode_GET_SIZE(name) > MAXPATHLEN) {
PyErr_SetString(PyExc_OverflowError,
"module name is too long");
return NULL;
}
- strcpy(name, subname);
/* sys.meta_path import hook */
if (p_loader != NULL) {
@@ -1602,9 +2003,9 @@ find_module(char *fullname, char *subname, PyObject *path, char *buf,
PyObject *loader;
PyObject *hook = PyList_GetItem(meta_path, i);
loader = PyObject_CallMethod(hook, "find_module",
- "sO", fullname,
- path != NULL ?
- path : Py_None);
+ "OO", fullname,
+ search_path_list != NULL ?
+ search_path_list : Py_None);
if (loader == NULL) {
Py_DECREF(meta_path);
return NULL; /* true error */
@@ -1620,27 +2021,29 @@ find_module(char *fullname, char *subname, PyObject *path, char *buf,
Py_DECREF(meta_path);
}
- if (find_frozen(fullname) != NULL) {
- strcpy(buf, fullname);
+ if (find_frozen(fullname) != NULL)
return &fd_frozen;
- }
- if (path == NULL) {
- if (is_builtin(name)) {
- strcpy(buf, name);
+ if (search_path_list == NULL) {
+#ifdef MS_COREDLL
+ FILE *fp;
+ struct filedescr *fdp;
+#endif
+ if (is_builtin(name))
return &fd_builtin;
- }
#ifdef MS_COREDLL
- fp = PyWin_FindRegisteredModule(name, &fdp, buf, buflen);
+ fp = _PyWin_FindRegisteredModule(name, &fdp, p_path);
if (fp != NULL) {
*p_fp = fp;
return fdp;
}
+ else if (PyErr_Occurred())
+ return NULL;
#endif
- path = PySys_GetObject("path");
+ search_path_list = PySys_GetObject("path");
}
- if (path == NULL || !PyList_Check(path)) {
+ if (search_path_list == NULL || !PyList_Check(search_path_list)) {
PyErr_SetString(PyExc_ImportError,
"sys.path must be a list of directory names");
return NULL;
@@ -1661,176 +2064,13 @@ find_module(char *fullname, char *subname, PyObject *path, char *buf,
return NULL;
}
- npath = PyList_Size(path);
- namelen = strlen(name);
- for (i = 0; i < npath; i++) {
- PyObject *v = PyList_GetItem(path, i);
- PyObject *origv = v;
- const char *base;
- Py_ssize_t size;
- if (!v)
- return NULL;
- if (PyUnicode_Check(v)) {
- v = PyUnicode_EncodeFSDefault(v);
- if (v == NULL)
- return NULL;
- }
- else if (!PyBytes_Check(v))
- continue;
- else
- Py_INCREF(v);
-
- base = PyBytes_AS_STRING(v);
- size = PyBytes_GET_SIZE(v);
- len = size;
- if (len + 2 + namelen + MAXSUFFIXSIZE >= buflen) {
- Py_DECREF(v);
- continue; /* Too long */
- }
- strcpy(buf, base);
- Py_DECREF(v);
-
- if (strlen(buf) != len) {
- continue; /* v contains '\0' */
- }
-
- /* sys.path_hooks import hook */
- if (p_loader != NULL) {
- PyObject *importer;
-
- importer = get_path_importer(path_importer_cache,
- path_hooks, origv);
- if (importer == NULL) {
- return NULL;
- }
- /* Note: importer is a borrowed reference */
- if (importer != Py_None) {
- PyObject *loader;
- loader = PyObject_CallMethod(importer,
- "find_module",
- "s", fullname);
- if (loader == NULL)
- return NULL; /* error */
- if (loader != Py_None) {
- /* a loader was found */
- *p_loader = loader;
- return &importhookdescr;
- }
- Py_DECREF(loader);
- continue;
- }
- }
- /* no hook was found, use builtin import */
-
- if (len > 0 && buf[len-1] != SEP
-#ifdef ALTSEP
- && buf[len-1] != ALTSEP
-#endif
- )
- buf[len++] = SEP;
- strcpy(buf+len, name);
- len += namelen;
-
- /* Check for package import (buf holds a directory name,
- and there's an __init__ module in that directory */
-#ifdef HAVE_STAT
- if (stat(buf, &statbuf) == 0 && /* it exists */
- S_ISDIR(statbuf.st_mode) && /* it's a directory */
- case_ok(buf, len, namelen, name)) { /* case matches */
- if (find_init_module(buf)) { /* and has __init__.py */
- return &fd_package;
- }
- else {
- int err;
- PyObject *unicode = PyUnicode_DecodeFSDefault(buf);
- if (unicode == NULL)
- return NULL;
- err = PyErr_WarnFormat(PyExc_ImportWarning, 1,
- "Not importing directory '%U': missing __init__.py",
- unicode);
- Py_DECREF(unicode);
- if (err)
- return NULL;
- }
- }
-#endif
-#if defined(PYOS_OS2)
- /* take a snapshot of the module spec for restoration
- * after the 8 character DLL hackery
- */
- saved_buf = strdup(buf);
- saved_len = len;
- saved_namelen = namelen;
-#endif /* PYOS_OS2 */
- for (fdp = _PyImport_Filetab; fdp->suffix != NULL; fdp++) {
-#if defined(PYOS_OS2) && defined(HAVE_DYNAMIC_LOADING)
- /* OS/2 limits DLLs to 8 character names (w/o
- extension)
- * so if the name is longer than that and its a
- * dynamically loaded module we're going to try,
- * truncate the name before trying
- */
- if (strlen(subname) > 8) {
- /* is this an attempt to load a C extension? */
- const struct filedescr *scan;
- scan = _PyImport_DynLoadFiletab;
- while (scan->suffix != NULL) {
- if (!strcmp(scan->suffix, fdp->suffix))
- break;
- else
- scan++;
- }
- if (scan->suffix != NULL) {
- /* yes, so truncate the name */
- namelen = 8;
- len -= strlen(subname) - namelen;
- buf[len] = '\0';
- }
- }
-#endif /* PYOS_OS2 */
- strcpy(buf+len, fdp->suffix);
- if (Py_VerboseFlag > 1)
- PySys_WriteStderr("# trying %s\n", buf);
- filemode = fdp->mode;
- if (filemode[0] == 'U')
- filemode = "r" PY_STDIOTEXTMODE;
- fp = fopen(buf, filemode);
- if (fp != NULL) {
- if (case_ok(buf, len, namelen, name))
- break;
- else { /* continue search */
- fclose(fp);
- fp = NULL;
- }
- }
-#if defined(PYOS_OS2)
- /* restore the saved snapshot */
- strcpy(buf, saved_buf);
- len = saved_len;
- namelen = saved_namelen;
-#endif
- }
-#if defined(PYOS_OS2)
- /* don't need/want the module name snapshot anymore */
- if (saved_buf)
- {
- free(saved_buf);
- saved_buf = NULL;
- }
-#endif
- if (fp != NULL)
- break;
- }
- if (fp == NULL) {
- PyErr_Format(PyExc_ImportError,
- "No module named %.200s", name);
- return NULL;
- }
- *p_fp = fp;
- return fdp;
+ return find_module_path_list(fullname, name,
+ search_path_list, path_hooks,
+ path_importer_cache,
+ p_path, p_fp, p_loader);
}
-/* case_ok(char* buf, Py_ssize_t len, Py_ssize_t namelen, char* name)
+/* case_bytes(char* buf, Py_ssize_t len, Py_ssize_t namelen, char* name)
* The arguments here are tricky, best shown by example:
* /a/b/c/d/e/f/g/h/i/j/k/some_long_module_name.py\0
* ^ ^ ^ ^
@@ -1844,18 +2084,18 @@ find_module(char *fullname, char *subname, PyObject *path, char *buf,
* We've already done a successful stat() or fopen() on buf, so know that
* there's some match, possibly case-insensitive.
*
- * case_ok() is to return 1 if there's a case-sensitive match for
- * name, else 0. case_ok() is also to return 1 if envar PYTHONCASEOK
+ * case_bytes() is to return 1 if there's a case-sensitive match for
+ * name, else 0. case_bytes() is also to return 1 if envar PYTHONCASEOK
* exists.
*
- * case_ok() is used to implement case-sensitive import semantics even
+ * case_bytes() is used to implement case-sensitive import semantics even
* on platforms with case-insensitive filesystems. It's trivial to implement
* for case-sensitive filesystems. It's pretty much a cross-platform
* nightmare for systems with case-insensitive filesystems.
*/
/* First we may need a pile of platform-specific header files; the sequence
- * of #if's here should match the sequence in the body of case_ok().
+ * of #if's here should match the sequence in the body of case_bytes().
*/
#if defined(MS_WINDOWS)
#include <windows.h>
@@ -1874,33 +2114,24 @@ find_module(char *fullname, char *subname, PyObject *path, char *buf,
#include <os2.h>
#endif
+#if defined(DJGPP) \
+ || ((defined(__MACH__) && defined(__APPLE__) || defined(__CYGWIN__)) \
+ && defined(HAVE_DIRENT_H)) \
+ || defined(PYOS_OS2)
+# define USE_CASE_OK_BYTES
+#endif
+
+
+#ifdef USE_CASE_OK_BYTES
static int
-case_ok(char *buf, Py_ssize_t len, Py_ssize_t namelen, char *name)
+case_bytes(char *buf, Py_ssize_t len, Py_ssize_t namelen, const char *name)
{
/* Pick a platform-specific implementation; the sequence of #if's here should
* match the sequence just above.
*/
-/* MS_WINDOWS */
-#if defined(MS_WINDOWS)
- WIN32_FIND_DATA data;
- HANDLE h;
-
- if (Py_GETENV("PYTHONCASEOK") != NULL)
- return 1;
-
- h = FindFirstFile(buf, &data);
- if (h == INVALID_HANDLE_VALUE) {
- PyErr_Format(PyExc_NameError,
- "Can't find file for module %.100s\n(filename %.300s)",
- name, buf);
- return 0;
- }
- FindClose(h);
- return strncmp(data.cFileName, name, namelen) == 0;
-
/* DJGPP */
-#elif defined(DJGPP)
+#if defined(DJGPP)
struct ffblk ffblk;
int done;
@@ -1912,7 +2143,7 @@ case_ok(char *buf, Py_ssize_t len, Py_ssize_t namelen, char *name)
PyErr_Format(PyExc_NameError,
"Can't find file for module %.100s\n(filename %.300s)",
name, buf);
- return 0;
+ return -1;
}
return strncmp(ffblk.ff_name, name, namelen) == 0;
@@ -1979,6 +2210,70 @@ case_ok(char *buf, Py_ssize_t len, Py_ssize_t namelen, char *name)
/* assuming it's a case-sensitive filesystem, so there's nothing to do! */
#else
+# error "USE_CASE_OK_BYTES is not correctly defined"
+#endif
+}
+#endif
+
+/*
+ * Check if a filename case matchs the name case. We've already done a
+ * successful stat() or fopen() on buf, so know that there's some match,
+ * possibly case-insensitive.
+ *
+ * case_ok() is to return 1 if there's a case-sensitive match for name, 0 if it
+ * the filename doesn't match, or -1 on error. case_ok() is also to return 1
+ * if envar PYTHONCASEOK exists.
+ *
+ * case_ok() is used to implement case-sensitive import semantics even
+ * on platforms with case-insensitive filesystems. It's trivial to implement
+ * for case-sensitive filesystems. It's pretty much a cross-platform
+ * nightmare for systems with case-insensitive filesystems.
+ */
+
+static int
+case_ok(PyObject *filename, Py_ssize_t prefix_delta, PyObject *name)
+{
+#ifdef MS_WINDOWS
+ WIN32_FIND_DATAW data;
+ HANDLE h;
+ int cmp;
+
+ if (Py_GETENV("PYTHONCASEOK") != NULL)
+ return 1;
+
+ h = FindFirstFileW(PyUnicode_AS_UNICODE(filename), &data);
+ if (h == INVALID_HANDLE_VALUE) {
+ PyErr_Format(PyExc_NameError,
+ "Can't find file for module %R\n(filename %R)",
+ name, filename);
+ return 0;
+ }
+ FindClose(h);
+ cmp = wcsncmp(data.cFileName,
+ PyUnicode_AS_UNICODE(name),
+ PyUnicode_GET_SIZE(name));
+ return cmp == 0;
+#elif defined(USE_CASE_OK_BYTES)
+ int match;
+ PyObject *filebytes, *namebytes;
+ filebytes = PyUnicode_EncodeFSDefault(filename);
+ if (filebytes == NULL)
+ return -1;
+ namebytes = PyUnicode_EncodeFSDefault(name);
+ if (namebytes == NULL) {
+ Py_DECREF(filebytes);
+ return -1;
+ }
+ match = case_bytes(
+ PyBytes_AS_STRING(filebytes),
+ PyBytes_GET_SIZE(filebytes) + prefix_delta,
+ PyBytes_GET_SIZE(namebytes),
+ PyBytes_AS_STRING(namebytes));
+ Py_DECREF(filebytes);
+ Py_DECREF(namebytes);
+ return match;
+#else
+ /* assuming it's a case-sensitive filesystem, so there's nothing to do! */
return 1;
#endif
@@ -1986,89 +2281,84 @@ case_ok(char *buf, Py_ssize_t len, Py_ssize_t namelen, char *name)
#ifdef HAVE_STAT
-/* Helper to look for __init__.py or __init__.py[co] in potential package */
+/* Helper to look for __init__.py or __init__.py[co] in potential package.
+ Return 1 if __init__ was found, 0 if not, or -1 on error. */
static int
-find_init_module(char *buf)
+find_init_module(PyObject *directory)
{
- const size_t save_len = strlen(buf);
- size_t i = save_len;
- char *pname; /* pointer to start of __init__ */
struct stat statbuf;
+ PyObject *filename;
+ int match;
-/* For calling case_ok(buf, len, namelen, name):
- * /a/b/c/d/e/f/g/h/i/j/k/some_long_module_name.py\0
- * ^ ^ ^ ^
- * |--------------------- buf ---------------------|
- * |------------------- len ------------------|
- * |------ name -------|
- * |----- namelen -----|
- */
- if (save_len + 13 >= MAXPATHLEN)
- return 0;
- buf[i++] = SEP;
- pname = buf + i;
- strcpy(pname, "__init__.py");
- if (stat(buf, &statbuf) == 0) {
- if (case_ok(buf,
- save_len + 9, /* len("/__init__") */
- 8, /* len("__init__") */
- pname)) {
- buf[save_len] = '\0';
+ filename = PyUnicode_FromFormat("%U%c__init__.py", directory, SEP);
+ if (filename == NULL)
+ return -1;
+ if (_Py_stat(filename, &statbuf) == 0) {
+ /* 3=len(".py") */
+ match = case_ok(filename, -3, initstr);
+ if (match < 0) {
+ Py_DECREF(filename);
+ return -1;
+ }
+ if (match) {
+ Py_DECREF(filename);
return 1;
}
}
- i += strlen(pname);
- strcpy(buf+i, Py_OptimizeFlag ? "o" : "c");
- if (stat(buf, &statbuf) == 0) {
- if (case_ok(buf,
- save_len + 9, /* len("/__init__") */
- 8, /* len("__init__") */
- pname)) {
- buf[save_len] = '\0';
+ Py_DECREF(filename);
+
+ filename = PyUnicode_FromFormat("%U%c__init__.py%c",
+ directory, SEP, Py_OptimizeFlag ? 'o' : 'c');
+ if (filename == NULL)
+ return -1;
+ if (_Py_stat(filename, &statbuf) == 0) {
+ /* 4=len(".pyc") */
+ match = case_ok(filename, -4, initstr);
+ if (match < 0) {
+ Py_DECREF(filename);
+ return -1;
+ }
+ if (match) {
+ Py_DECREF(filename);
return 1;
}
}
- buf[save_len] = '\0';
+ Py_DECREF(filename);
return 0;
}
#endif /* HAVE_STAT */
-static int init_builtin(char *); /* Forward */
+static int init_builtin(PyObject *); /* Forward */
static PyObject*
-load_builtin(char *name, char *pathname, int type)
+load_builtin(PyObject *name, int type)
{
PyObject *m, *modules;
int err;
- if (pathname != NULL && pathname[0] != '\0')
- name = pathname;
-
if (type == C_BUILTIN)
err = init_builtin(name);
else
- err = PyImport_ImportFrozenModule(name);
+ err = PyImport_ImportFrozenModuleObject(name);
if (err < 0)
return NULL;
if (err == 0) {
PyErr_Format(PyExc_ImportError,
- "Purported %s module %.200s not found",
- type == C_BUILTIN ?
- "builtin" : "frozen",
+ "Purported %s module %R not found",
+ type == C_BUILTIN ? "builtin" : "frozen",
name);
return NULL;
}
modules = PyImport_GetModuleDict();
- m = PyDict_GetItemString(modules, name);
+ m = PyDict_GetItem(modules, name);
if (m == NULL) {
PyErr_Format(
PyExc_ImportError,
- "%s module %.200s not properly initialized",
- type == C_BUILTIN ?
- "builtin" : "frozen",
+ "%s module %R not properly initialized",
+ type == C_BUILTIN ? "builtin" : "frozen",
name);
return NULL;
}
@@ -2080,7 +2370,7 @@ load_builtin(char *name, char *pathname, int type)
its module object WITH INCREMENTED REFERENCE COUNT */
static PyObject *
-load_module(char *name, FILE *fp, char *pathname, int type, PyObject *loader)
+load_module(PyObject *name, FILE *fp, PyObject *pathname, int type, PyObject *loader)
{
PyObject *m;
@@ -2090,7 +2380,7 @@ load_module(char *name, FILE *fp, char *pathname, int type, PyObject *loader)
case PY_COMPILED:
if (fp == NULL) {
PyErr_Format(PyExc_ValueError,
- "file object required for import (type code %d)",
+ "file object required for import (type code %d)",
type);
return NULL;
}
@@ -2118,7 +2408,7 @@ load_module(char *name, FILE *fp, char *pathname, int type, PyObject *loader)
case C_BUILTIN:
case PY_FROZEN:
- m = load_builtin(name, pathname, type);
+ m = load_builtin(name, type);
break;
case IMP_HOOK: {
@@ -2127,13 +2417,13 @@ load_module(char *name, FILE *fp, char *pathname, int type, PyObject *loader)
"import hook without loader");
return NULL;
}
- m = PyObject_CallMethod(loader, "load_module", "s", name);
+ m = PyObject_CallMethod(loader, "load_module", "O", name);
break;
}
default:
PyErr_Format(PyExc_ImportError,
- "Don't know how to import %.200s (type code %d)",
+ "Don't know how to import %R (type code %d)",
name, type);
m = NULL;
@@ -2148,28 +2438,28 @@ load_module(char *name, FILE *fp, char *pathname, int type, PyObject *loader)
an exception set if the initialization failed. */
static int
-init_builtin(char *name)
+init_builtin(PyObject *name)
{
struct _inittab *p;
- if (_PyImport_FindBuiltin(name) != NULL)
+ if (_PyImport_FindExtensionObject(name, name) != NULL)
return 1;
for (p = PyImport_Inittab; p->name != NULL; p++) {
PyObject *mod;
- if (strcmp(name, p->name) == 0) {
+ if (PyUnicode_CompareWithASCIIString(name, p->name) == 0) {
if (p->initfunc == NULL) {
PyErr_Format(PyExc_ImportError,
- "Cannot re-init internal module %.200s",
+ "Cannot re-init internal module %R",
name);
return -1;
}
if (Py_VerboseFlag)
- PySys_WriteStderr("import %s # builtin\n", name);
+ PySys_FormatStderr("import %U # builtin\n", name);
mod = (*p->initfunc)();
if (mod == 0)
return -1;
- if (_PyImport_FixupBuiltin(mod, name) < 0)
+ if (_PyImport_FixupExtensionObject(mod, name, name) < 0)
return -1;
/* FixupExtension has put the module into sys.modules,
so we can release our own reference. */
@@ -2184,37 +2474,37 @@ init_builtin(char *name)
/* Frozen modules */
static struct _frozen *
-find_frozen(char *name)
+find_frozen(PyObject *name)
{
struct _frozen *p;
- if (!name)
+ if (name == NULL)
return NULL;
for (p = PyImport_FrozenModules; ; p++) {
if (p->name == NULL)
return NULL;
- if (strcmp(p->name, name) == 0)
+ if (PyUnicode_CompareWithASCIIString(name, p->name) == 0)
break;
}
return p;
}
static PyObject *
-get_frozen_object(char *name)
+get_frozen_object(PyObject *name)
{
struct _frozen *p = find_frozen(name);
int size;
if (p == NULL) {
PyErr_Format(PyExc_ImportError,
- "No such frozen object named %.200s",
+ "No such frozen object named %R",
name);
return NULL;
}
if (p->code == NULL) {
PyErr_Format(PyExc_ImportError,
- "Excluded frozen object named %.200s",
+ "Excluded frozen object named %R",
name);
return NULL;
}
@@ -2225,14 +2515,14 @@ get_frozen_object(char *name)
}
static PyObject *
-is_frozen_package(char *name)
+is_frozen_package(PyObject *name)
{
struct _frozen *p = find_frozen(name);
int size;
if (p == NULL) {
PyErr_Format(PyExc_ImportError,
- "No such frozen object named %.200s",
+ "No such frozen object named %R",
name);
return NULL;
}
@@ -2252,19 +2542,20 @@ is_frozen_package(char *name)
This function is also used from frozenmain.c */
int
-PyImport_ImportFrozenModule(char *name)
+PyImport_ImportFrozenModuleObject(PyObject *name)
{
- struct _frozen *p = find_frozen(name);
- PyObject *co;
- PyObject *m;
+ struct _frozen *p;
+ PyObject *co, *m, *path;
int ispackage;
int size;
+ p = find_frozen(name);
+
if (p == NULL)
return 0;
if (p->code == NULL) {
PyErr_Format(PyExc_ImportError,
- "Excluded frozen object named %.200s",
+ "Excluded frozen object named %R",
name);
return -1;
}
@@ -2273,40 +2564,41 @@ PyImport_ImportFrozenModule(char *name)
if (ispackage)
size = -size;
if (Py_VerboseFlag)
- PySys_WriteStderr("import %s # frozen%s\n",
+ PySys_FormatStderr("import %U # frozen%s\n",
name, ispackage ? " package" : "");
co = PyMarshal_ReadObjectFromString((char *)p->code, size);
if (co == NULL)
return -1;
if (!PyCode_Check(co)) {
PyErr_Format(PyExc_TypeError,
- "frozen object %.200s is not a code object",
+ "frozen object %R is not a code object",
name);
goto err_return;
}
if (ispackage) {
/* Set __path__ to the package name */
- PyObject *d, *s, *l;
+ PyObject *d, *l;
int err;
- m = PyImport_AddModule(name);
+ m = PyImport_AddModuleObject(name);
if (m == NULL)
goto err_return;
d = PyModule_GetDict(m);
- s = PyUnicode_InternFromString(name);
- if (s == NULL)
- goto err_return;
l = PyList_New(1);
if (l == NULL) {
- Py_DECREF(s);
goto err_return;
}
- PyList_SET_ITEM(l, 0, s);
+ Py_INCREF(name);
+ PyList_SET_ITEM(l, 0, name);
err = PyDict_SetItemString(d, "__path__", l);
Py_DECREF(l);
if (err != 0)
goto err_return;
}
- m = PyImport_ExecCodeModuleEx(name, co, "<frozen>");
+ path = PyUnicode_FromString("<frozen>");
+ if (path == NULL)
+ goto err_return;
+ m = PyImport_ExecCodeModuleObject(name, co, path, NULL);
+ Py_DECREF(path);
if (m == NULL)
goto err_return;
Py_DECREF(co);
@@ -2317,6 +2609,19 @@ err_return:
return -1;
}
+int
+PyImport_ImportFrozenModule(char *name)
+{
+ PyObject *nameobj;
+ int ret;
+ nameobj = PyUnicode_InternFromString(name);
+ if (nameobj == NULL)
+ return -1;
+ ret = PyImport_ImportFrozenModuleObject(nameobj);
+ Py_DECREF(nameobj);
+ return ret;
+}
+
/* Import a module, either built-in, frozen, or external, and return
its module object WITH INCREMENTED REFERENCE COUNT */
@@ -2347,8 +2652,7 @@ PyImport_ImportModule(const char *name)
PyObject *
PyImport_ImportModuleNoBlock(const char *name)
{
- PyObject *result;
- PyObject *modules;
+ PyObject *nameobj, *modules, *result;
long me;
/* Try to get the module from sys.modules[name] */
@@ -2356,14 +2660,16 @@ PyImport_ImportModuleNoBlock(const char *name)
if (modules == NULL)
return NULL;
- result = PyDict_GetItemString(modules, name);
+ nameobj = PyUnicode_FromString(name);
+ if (nameobj == NULL)
+ return NULL;
+ result = PyDict_GetItem(modules, nameobj);
if (result != NULL) {
+ Py_DECREF(nameobj);
Py_INCREF(result);
return result;
}
- else {
- PyErr_Clear();
- }
+ PyErr_Clear();
#ifdef WITH_THREAD
/* check the import lock
* me might be -1 but I ignore the error here, the lock function
@@ -2371,43 +2677,54 @@ PyImport_ImportModuleNoBlock(const char *name)
me = PyThread_get_thread_ident();
if (import_lock_thread == -1 || import_lock_thread == me) {
/* no thread or me is holding the lock */
- return PyImport_ImportModule(name);
+ result = PyImport_Import(nameobj);
}
else {
PyErr_Format(PyExc_ImportError,
- "Failed to import %.200s because the import lock"
+ "Failed to import %R because the import lock"
"is held by another thread.",
- name);
- return NULL;
+ nameobj);
+ result = NULL;
}
#else
- return PyImport_ImportModule(name);
+ result = PyImport_Import(nameobj);
#endif
+ Py_DECREF(nameobj);
+ return result;
}
/* Forward declarations for helper routines */
-static PyObject *get_parent(PyObject *globals, char *buf,
- Py_ssize_t *p_buflen, int level);
+static PyObject *get_parent(PyObject *globals,
+ PyObject **p_name,
+ int level);
static PyObject *load_next(PyObject *mod, PyObject *altmod,
- char **p_name, char *buf, Py_ssize_t *p_buflen);
-static int mark_miss(char *name);
+ PyObject *inputname, PyObject **p_outputname,
+ Py_UNICODE *buf, Py_ssize_t *p_buflen,
+ Py_ssize_t bufsize);
+static int mark_miss(PyObject *name);
static int ensure_fromlist(PyObject *mod, PyObject *fromlist,
- char *buf, Py_ssize_t buflen, int recursive);
-static PyObject * import_submodule(PyObject *mod, char *name, char *fullname);
+ PyObject *buf, int recursive);
+static PyObject * import_submodule(PyObject *mod, PyObject *name,
+ PyObject *fullname);
/* The Magnum Opus of dotted-name import :-) */
static PyObject *
-import_module_level(char *name, PyObject *globals, PyObject *locals,
+import_module_level(PyObject *name, PyObject *globals, PyObject *locals,
PyObject *fromlist, int level)
{
- char buf[MAXPATHLEN+1];
- Py_ssize_t buflen = 0;
- PyObject *parent, *head, *next, *tail;
+ Py_UNICODE buf[MAXPATHLEN+1];
+ Py_ssize_t buflen;
+ Py_ssize_t bufsize = MAXPATHLEN+1;
+ PyObject *parent, *head, *next, *tail, *inputname, *outputname;
+ PyObject *parent_name, *ensure_name;
+ const Py_UNICODE *nameunicode;
- if (strchr(name, '/') != NULL
-#ifdef MS_WINDOWS
- || strchr(name, '\\') != NULL
+ nameunicode = PyUnicode_AS_UNICODE(name);
+
+ if (Py_UNICODE_strchr(nameunicode, SEP) != NULL
+#ifdef ALTSEP
+ || Py_UNICODE_strchr(nameunicode, ALTSEP) != NULL
#endif
) {
PyErr_SetString(PyExc_ImportError,
@@ -2415,25 +2732,45 @@ import_module_level(char *name, PyObject *globals, PyObject *locals,
return NULL;
}
- parent = get_parent(globals, buf, &buflen, level);
+ parent = get_parent(globals, &parent_name, level);
if (parent == NULL)
return NULL;
- head = load_next(parent, level < 0 ? Py_None : parent, &name, buf,
- &buflen);
+ buflen = PyUnicode_GET_SIZE(parent_name);
+ if (buflen+1 > bufsize) {
+ Py_DECREF(parent_name);
+ PyErr_SetString(PyExc_ValueError,
+ "Module name too long");
+ return NULL;
+ }
+ Py_UNICODE_strcpy(buf, PyUnicode_AS_UNICODE(parent_name));
+ Py_DECREF(parent_name);
+
+ head = load_next(parent, level < 0 ? Py_None : parent, name, &outputname,
+ buf, &buflen, bufsize);
if (head == NULL)
return NULL;
tail = head;
Py_INCREF(tail);
- while (name) {
- next = load_next(tail, tail, &name, buf, &buflen);
- Py_DECREF(tail);
- if (next == NULL) {
- Py_DECREF(head);
- return NULL;
+
+ if (outputname != NULL) {
+ while (1) {
+ inputname = outputname;
+ next = load_next(tail, tail, inputname, &outputname,
+ buf, &buflen, bufsize);
+ Py_DECREF(tail);
+ Py_DECREF(inputname);
+ if (next == NULL) {
+ Py_DECREF(head);
+ return NULL;
+ }
+ tail = next;
+
+ if (outputname == NULL) {
+ break;
+ }
}
- tail = next;
}
if (tail == Py_None) {
/* If tail is Py_None, both get_parent and load_next found
@@ -2441,8 +2778,7 @@ import_module_level(char *name, PyObject *globals, PyObject *locals,
doctored faulty bytecode */
Py_DECREF(tail);
Py_DECREF(head);
- PyErr_SetString(PyExc_ValueError,
- "Empty module name");
+ PyErr_SetString(PyExc_ValueError, "Empty module name");
return NULL;
}
@@ -2457,44 +2793,71 @@ import_module_level(char *name, PyObject *globals, PyObject *locals,
}
Py_DECREF(head);
- if (!ensure_fromlist(tail, fromlist, buf, buflen, 0)) {
+
+ ensure_name = PyUnicode_FromUnicode(buf, Py_UNICODE_strlen(buf));
+ if (ensure_name == NULL) {
+ Py_DECREF(tail);
+ return NULL;
+ }
+ if (!ensure_fromlist(tail, fromlist, ensure_name, 0)) {
Py_DECREF(tail);
+ Py_DECREF(ensure_name);
return NULL;
}
+ Py_DECREF(ensure_name);
return tail;
}
PyObject *
-PyImport_ImportModuleLevel(char *name, PyObject *globals, PyObject *locals,
- PyObject *fromlist, int level)
+PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals,
+ PyObject *locals, PyObject *fromlist,
+ int level)
{
- PyObject *result;
+ PyObject *mod;
_PyImport_AcquireLock();
- result = import_module_level(name, globals, locals, fromlist, level);
+ mod = import_module_level(name, globals, locals, fromlist, level);
if (_PyImport_ReleaseLock() < 0) {
- Py_XDECREF(result);
+ Py_XDECREF(mod);
PyErr_SetString(PyExc_RuntimeError,
"not holding the import lock");
return NULL;
}
- return result;
+ return mod;
+}
+
+PyObject *
+PyImport_ImportModuleLevel(const char *name, PyObject *globals, PyObject *locals,
+ PyObject *fromlist, int level)
+{
+ PyObject *nameobj, *mod;
+ nameobj = PyUnicode_FromString(name);
+ if (nameobj == NULL)
+ return NULL;
+ mod = PyImport_ImportModuleLevelObject(nameobj, globals, locals,
+ fromlist, level);
+ Py_DECREF(nameobj);
+ return mod;
}
+
/* Return the package that an import is being performed in. If globals comes
from the module foo.bar.bat (not itself a package), this returns the
sys.modules entry for foo.bar. If globals is from a package's __init__.py,
the package's entry in sys.modules is returned, as a borrowed reference.
- The *name* of the returned package is returned in buf, with the length of
- the name in *p_buflen.
+ The name of the returned package is returned in *p_name.
If globals doesn't come from a package or a module in a package, or a
corresponding entry is not found in sys.modules, Py_None is returned.
*/
static PyObject *
-get_parent(PyObject *globals, char *buf, Py_ssize_t *p_buflen, int level)
+get_parent(PyObject *globals, PyObject **p_name, int level)
{
+ Py_UNICODE name[MAXPATHLEN+1];
+ const Py_ssize_t bufsize = MAXPATHLEN+1;
+ PyObject *nameobj;
+
static PyObject *namestr = NULL;
static PyObject *pathstr = NULL;
static PyObject *pkgstr = NULL;
@@ -2502,7 +2865,7 @@ get_parent(PyObject *globals, char *buf, Py_ssize_t *p_buflen, int level)
int orig_level = level;
if (globals == NULL || !PyDict_Check(globals) || !level)
- return Py_None;
+ goto return_none;
if (namestr == NULL) {
namestr = PyUnicode_InternFromString("__name__");
@@ -2520,55 +2883,46 @@ get_parent(PyObject *globals, char *buf, Py_ssize_t *p_buflen, int level)
return NULL;
}
- *buf = '\0';
- *p_buflen = 0;
pkgname = PyDict_GetItem(globals, pkgstr);
if ((pkgname != NULL) && (pkgname != Py_None)) {
/* __package__ is set, so use it */
- char *pkgname_str;
- Py_ssize_t len;
-
if (!PyUnicode_Check(pkgname)) {
PyErr_SetString(PyExc_ValueError,
"__package__ set to non-string");
return NULL;
}
- pkgname_str = _PyUnicode_AsStringAndSize(pkgname, &len);
- if (len == 0) {
+ if (PyUnicode_GET_SIZE(pkgname) == 0) {
if (level > 0) {
PyErr_SetString(PyExc_ValueError,
"Attempted relative import in non-package");
return NULL;
}
- return Py_None;
+ goto return_none;
}
- if (len > MAXPATHLEN) {
+ if (PyUnicode_GET_SIZE(pkgname)+1 > bufsize) {
PyErr_SetString(PyExc_ValueError,
"Package name too long");
return NULL;
}
- strcpy(buf, pkgname_str);
+ Py_UNICODE_strcpy(name, PyUnicode_AS_UNICODE(pkgname));
} else {
/* __package__ not set, so figure it out and set it */
modname = PyDict_GetItem(globals, namestr);
if (modname == NULL || !PyUnicode_Check(modname))
- return Py_None;
+ goto return_none;
modpath = PyDict_GetItem(globals, pathstr);
if (modpath != NULL) {
/* __path__ is set, so modname is already the package name */
- char *modname_str;
- Py_ssize_t len;
int error;
- modname_str = _PyUnicode_AsStringAndSize(modname, &len);
- if (len > MAXPATHLEN) {
+ if (PyUnicode_GET_SIZE(modname)+1 > bufsize) {
PyErr_SetString(PyExc_ValueError,
"Module name too long");
return NULL;
}
- strcpy(buf, modname_str);
+ Py_UNICODE_strcpy(name, PyUnicode_AS_UNICODE(modname));
error = PyDict_SetItem(globals, pkgstr, modname);
if (error) {
PyErr_SetString(PyExc_ValueError,
@@ -2577,9 +2931,9 @@ get_parent(PyObject *globals, char *buf, Py_ssize_t *p_buflen, int level)
}
} else {
/* Normal module, so work out the package name if any */
- char *start = _PyUnicode_AsString(modname);
- char *lastdot = strrchr(start, '.');
- size_t len;
+ Py_UNICODE *start = PyUnicode_AS_UNICODE(modname);
+ Py_UNICODE *lastdot = Py_UNICODE_strrchr(start, '.');
+ Py_ssize_t len;
int error;
if (lastdot == NULL && level > 0) {
PyErr_SetString(PyExc_ValueError,
@@ -2593,17 +2947,17 @@ get_parent(PyObject *globals, char *buf, Py_ssize_t *p_buflen, int level)
"Could not set __package__");
return NULL;
}
- return Py_None;
+ goto return_none;
}
len = lastdot - start;
- if (len >= MAXPATHLEN) {
+ if (len+1 > bufsize) {
PyErr_SetString(PyExc_ValueError,
"Module name too long");
return NULL;
}
- strncpy(buf, start, len);
- buf[len] = '\0';
- pkgname = PyUnicode_FromString(buf);
+ Py_UNICODE_strncpy(name, start, len);
+ name[len] = '\0';
+ pkgname = PyUnicode_FromUnicode(name, len);
if (pkgname == NULL) {
return NULL;
}
@@ -2617,7 +2971,7 @@ get_parent(PyObject *globals, char *buf, Py_ssize_t *p_buflen, int level)
}
}
while (--level > 0) {
- char *dot = strrchr(buf, '.');
+ Py_UNICODE *dot = Py_UNICODE_strrchr(name, '.');
if (dot == NULL) {
PyErr_SetString(PyExc_ValueError,
"Attempted relative import beyond "
@@ -2626,137 +2980,181 @@ get_parent(PyObject *globals, char *buf, Py_ssize_t *p_buflen, int level)
}
*dot = '\0';
}
- *p_buflen = strlen(buf);
+
+ nameobj = PyUnicode_FromUnicode(name, Py_UNICODE_strlen(name));
+ if (nameobj == NULL)
+ return NULL;
modules = PyImport_GetModuleDict();
- parent = PyDict_GetItemString(modules, buf);
+ parent = PyDict_GetItem(modules, nameobj);
if (parent == NULL) {
- if (orig_level < 1) {
- PyObject *err_msg = PyBytes_FromFormat(
- "Parent module '%.200s' not found "
- "while handling absolute import", buf);
- if (err_msg == NULL) {
- return NULL;
- }
- if (!PyErr_WarnEx(PyExc_RuntimeWarning,
- PyBytes_AsString(err_msg), 1)) {
- *buf = '\0';
- *p_buflen = 0;
- parent = Py_None;
- }
- Py_DECREF(err_msg);
- } else {
+ int err;
+
+ if (orig_level >= 1) {
PyErr_Format(PyExc_SystemError,
- "Parent module '%.200s' not loaded, "
- "cannot perform relative import", buf);
+ "Parent module %R not loaded, "
+ "cannot perform relative import", nameobj);
+ Py_DECREF(nameobj);
+ return NULL;
}
+
+ err = PyErr_WarnFormat(
+ PyExc_RuntimeWarning, 1,
+ "Parent module %R not found while handling absolute import",
+ nameobj);
+ Py_DECREF(nameobj);
+ if (err)
+ return NULL;
+
+ goto return_none;
}
+ *p_name = nameobj;
return parent;
/* We expect, but can't guarantee, if parent != None, that:
- - parent.__name__ == buf
+ - parent.__name__ == name
- parent.__dict__ is globals
If this is violated... Who cares? */
+
+return_none:
+ nameobj = PyUnicode_FromUnicode(NULL, 0);
+ if (nameobj == NULL)
+ return NULL;
+ *p_name = nameobj;
+ return Py_None;
}
/* altmod is either None or same as mod */
static PyObject *
-load_next(PyObject *mod, PyObject *altmod, char **p_name, char *buf,
- Py_ssize_t *p_buflen)
+load_next(PyObject *mod, PyObject *altmod,
+ PyObject *inputname, PyObject **p_outputname,
+ Py_UNICODE *buf, Py_ssize_t *p_buflen, Py_ssize_t bufsize)
{
- char *name = *p_name;
- char *dot = strchr(name, '.');
- size_t len;
- char *p;
- PyObject *result;
+ const Py_UNICODE *dot;
+ Py_ssize_t len;
+ Py_UNICODE *p;
+ PyObject *fullname, *name, *result, *mark_name;
+ const Py_UNICODE *nameuni;
- if (strlen(name) == 0) {
+ *p_outputname = NULL;
+
+ if (PyUnicode_GET_SIZE(inputname) == 0) {
/* completely empty module name should only happen in
'from . import' (or '__import__("")')*/
Py_INCREF(mod);
- *p_name = NULL;
return mod;
}
- if (dot == NULL) {
- *p_name = NULL;
- len = strlen(name);
- }
- else {
- *p_name = dot+1;
- len = dot-name;
+ nameuni = PyUnicode_AS_UNICODE(inputname);
+ if (nameuni == NULL)
+ return NULL;
+
+ dot = Py_UNICODE_strchr(nameuni, '.');
+ if (dot != NULL) {
+ len = dot - nameuni;
+ if (len == 0) {
+ PyErr_SetString(PyExc_ValueError,
+ "Empty module name");
+ return NULL;
+ }
}
- if (len == 0) {
+ else
+ len = PyUnicode_GET_SIZE(inputname);
+
+ if (*p_buflen+len+1 >= bufsize) {
PyErr_SetString(PyExc_ValueError,
- "Empty module name");
+ "Module name too long");
return NULL;
}
p = buf + *p_buflen;
- if (p != buf)
+ if (p != buf) {
*p++ = '.';
- if (p+len-buf >= MAXPATHLEN) {
- PyErr_SetString(PyExc_ValueError,
- "Module name too long");
- return NULL;
+ *p_buflen += 1;
}
- strncpy(p, name, len);
+ Py_UNICODE_strncpy(p, nameuni, len);
p[len] = '\0';
- *p_buflen = p+len-buf;
+ *p_buflen += len;
- result = import_submodule(mod, p, buf);
+ fullname = PyUnicode_FromUnicode(buf, *p_buflen);
+ if (fullname == NULL)
+ return NULL;
+ name = PyUnicode_FromUnicode(p, len);
+ if (name == NULL) {
+ Py_DECREF(fullname);
+ return NULL;
+ }
+ result = import_submodule(mod, name, fullname);
+ Py_DECREF(fullname);
if (result == Py_None && altmod != mod) {
Py_DECREF(result);
/* Here, altmod must be None and mod must not be None */
- result = import_submodule(altmod, p, p);
+ result = import_submodule(altmod, name, name);
+ Py_DECREF(name);
if (result != NULL && result != Py_None) {
- if (mark_miss(buf) != 0) {
+ mark_name = PyUnicode_FromUnicode(buf, *p_buflen);
+ if (mark_name == NULL) {
Py_DECREF(result);
return NULL;
}
- strncpy(buf, name, len);
+ if (mark_miss(mark_name) != 0) {
+ Py_DECREF(result);
+ Py_DECREF(mark_name);
+ return NULL;
+ }
+ Py_DECREF(mark_name);
+ Py_UNICODE_strncpy(buf, nameuni, len);
buf[len] = '\0';
*p_buflen = len;
}
}
+ else
+ Py_DECREF(name);
if (result == NULL)
return NULL;
if (result == Py_None) {
Py_DECREF(result);
PyErr_Format(PyExc_ImportError,
- "No module named %.200s", name);
+ "No module named %R", inputname);
return NULL;
}
+ if (dot != NULL) {
+ *p_outputname = PyUnicode_FromUnicode(dot+1, Py_UNICODE_strlen(dot+1));
+ if (*p_outputname == NULL) {
+ Py_DECREF(result);
+ return NULL;
+ }
+ }
+
return result;
}
static int
-mark_miss(char *name)
+mark_miss(PyObject *name)
{
PyObject *modules = PyImport_GetModuleDict();
- return PyDict_SetItemString(modules, name, Py_None);
+ return PyDict_SetItem(modules, name, Py_None);
}
static int
-ensure_fromlist(PyObject *mod, PyObject *fromlist, char *buf, Py_ssize_t buflen,
+ensure_fromlist(PyObject *mod, PyObject *fromlist, PyObject *name,
int recursive)
{
int i;
+ PyObject *fullname;
+ Py_ssize_t fromlist_len;
if (!PyObject_HasAttrString(mod, "__path__"))
return 1;
- for (i = 0; ; i++) {
+ fromlist_len = PySequence_Size(fromlist);
+
+ for (i = 0; i < fromlist_len; i++) {
PyObject *item = PySequence_GetItem(fromlist, i);
int hasit;
- if (item == NULL) {
- if (PyErr_ExceptionMatches(PyExc_IndexError)) {
- PyErr_Clear();
- return 1;
- }
+ if (item == NULL)
return 0;
- }
if (!PyUnicode_Check(item)) {
PyErr_SetString(PyExc_TypeError,
"Item in ``from list'' not a string");
@@ -2773,7 +3171,7 @@ ensure_fromlist(PyObject *mod, PyObject *fromlist, char *buf, Py_ssize_t buflen,
if (all == NULL)
PyErr_Clear();
else {
- int ret = ensure_fromlist(mod, all, buf, buflen, 1);
+ int ret = ensure_fromlist(mod, all, name, 1);
Py_DECREF(all);
if (!ret)
return 0;
@@ -2782,27 +3180,14 @@ ensure_fromlist(PyObject *mod, PyObject *fromlist, char *buf, Py_ssize_t buflen,
}
hasit = PyObject_HasAttr(mod, item);
if (!hasit) {
- PyObject *item8;
- char *subname;
PyObject *submod;
- char *p;
- item8 = PyUnicode_EncodeFSDefault(item);
- if (!item8) {
- PyErr_SetString(PyExc_ValueError, "Cannot encode path item");
- return 0;
- }
- subname = PyBytes_AS_STRING(item8);
- if (buflen + strlen(subname) >= MAXPATHLEN) {
- PyErr_SetString(PyExc_ValueError,
- "Module name too long");
- Py_DECREF(item);
- return 0;
+ fullname = PyUnicode_FromFormat("%U.%U", name, item);
+ if (fullname != NULL) {
+ submod = import_submodule(mod, item, fullname);
+ Py_DECREF(fullname);
}
- p = buf + buflen;
- *p++ = '.';
- strcpy(p, subname);
- submod = import_submodule(mod, subname, buf);
- Py_DECREF(item8);
+ else
+ submod = NULL;
Py_XDECREF(submod);
if (submod == NULL) {
Py_DECREF(item);
@@ -2812,12 +3197,12 @@ ensure_fromlist(PyObject *mod, PyObject *fromlist, char *buf, Py_ssize_t buflen,
Py_DECREF(item);
}
- /* NOTREACHED */
+ return 1;
}
static int
-add_submodule(PyObject *mod, PyObject *submod, char *fullname, char *subname,
- PyObject *modules)
+add_submodule(PyObject *mod, PyObject *submod, PyObject *fullname,
+ PyObject *subname, PyObject *modules)
{
if (mod == Py_None)
return 1;
@@ -2828,7 +3213,7 @@ add_submodule(PyObject *mod, PyObject *submod, char *fullname, char *subname,
load failed with a SyntaxError -- then there's no trace in
sys.modules. In that case, of course, do nothing extra.) */
if (submod == NULL) {
- submod = PyDict_GetItemString(modules, fullname);
+ submod = PyDict_GetItem(modules, fullname);
if (submod == NULL)
return 1;
}
@@ -2839,68 +3224,66 @@ add_submodule(PyObject *mod, PyObject *submod, char *fullname, char *subname,
PyObject *dict = PyModule_GetDict(mod);
if (!dict)
return 0;
- if (PyDict_SetItemString(dict, subname, submod) < 0)
+ if (PyDict_SetItem(dict, subname, submod) < 0)
return 0;
}
else {
- if (PyObject_SetAttrString(mod, subname, submod) < 0)
+ if (PyObject_SetAttr(mod, subname, submod) < 0)
return 0;
}
return 1;
}
static PyObject *
-import_submodule(PyObject *mod, char *subname, char *fullname)
+import_submodule(PyObject *mod, PyObject *subname, PyObject *fullname)
{
PyObject *modules = PyImport_GetModuleDict();
- PyObject *m = NULL;
+ PyObject *m = NULL, *bufobj, *path_list, *loader;
+ struct filedescr *fdp;
+ FILE *fp;
/* Require:
if mod == None: subname == fullname
else: mod.__name__ + "." + subname == fullname
*/
- if ((m = PyDict_GetItemString(modules, fullname)) != NULL) {
+ if ((m = PyDict_GetItem(modules, fullname)) != NULL) {
Py_INCREF(m);
+ return m;
}
- else {
- PyObject *path, *loader = NULL;
- char buf[MAXPATHLEN+1];
- struct filedescr *fdp;
- FILE *fp = NULL;
- if (mod == Py_None)
- path = NULL;
- else {
- path = PyObject_GetAttrString(mod, "__path__");
- if (path == NULL) {
- PyErr_Clear();
- Py_INCREF(Py_None);
- return Py_None;
- }
- }
-
- buf[0] = '\0';
- fdp = find_module(fullname, subname, path, buf, MAXPATHLEN+1,
- &fp, &loader);
- Py_XDECREF(path);
- if (fdp == NULL) {
- if (!PyErr_ExceptionMatches(PyExc_ImportError))
- return NULL;
+ if (mod == Py_None)
+ path_list = NULL;
+ else {
+ path_list = PyObject_GetAttrString(mod, "__path__");
+ if (path_list == NULL) {
PyErr_Clear();
Py_INCREF(Py_None);
return Py_None;
}
- m = load_module(fullname, fp, buf, fdp->type, loader);
- Py_XDECREF(loader);
- if (fp)
- fclose(fp);
- if (!add_submodule(mod, m, fullname, subname, modules)) {
- Py_XDECREF(m);
- m = NULL;
- }
}
+ fdp = find_module(fullname, subname, path_list,
+ &bufobj, &fp, &loader);
+ Py_XDECREF(path_list);
+ if (fdp == NULL) {
+ if (!PyErr_ExceptionMatches(PyExc_ImportError))
+ return NULL;
+ PyErr_Clear();
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ m = load_module(fullname, fp, bufobj, fdp->type, loader);
+ Py_XDECREF(bufobj);
+ Py_XDECREF(loader);
+ if (fp)
+ fclose(fp);
+ if (m == NULL)
+ return NULL;
+ if (!add_submodule(mod, m, fullname, subname, modules)) {
+ Py_XDECREF(m);
+ return NULL;
+ }
return m;
}
@@ -2914,12 +3297,12 @@ PyImport_ReloadModule(PyObject *m)
PyInterpreterState *interp = PyThreadState_Get()->interp;
PyObject *modules_reloading = interp->modules_reloading;
PyObject *modules = PyImport_GetModuleDict();
- PyObject *path = NULL, *loader = NULL, *existing_m = NULL;
- char *name, *subname;
- char buf[MAXPATHLEN+1];
+ PyObject *path_list = NULL, *loader = NULL, *existing_m = NULL;
+ PyObject *nameobj, *bufobj, *subnameobj;
+ Py_UNICODE *name, *subname;
struct filedescr *fdp;
FILE *fp = NULL;
- PyObject *newm;
+ PyObject *newm = NULL;
if (modules_reloading == NULL) {
Py_FatalError("PyImport_ReloadModule: "
@@ -2932,61 +3315,73 @@ PyImport_ReloadModule(PyObject *m)
"reload() argument must be module");
return NULL;
}
- name = (char*)PyModule_GetName(m);
- if (name == NULL)
+ nameobj = PyModule_GetNameObject(m);
+ if (nameobj == NULL)
return NULL;
- if (m != PyDict_GetItemString(modules, name)) {
+ if (m != PyDict_GetItem(modules, nameobj)) {
PyErr_Format(PyExc_ImportError,
- "reload(): module %.200s not in sys.modules",
- name);
+ "reload(): module %R not in sys.modules",
+ nameobj);
+ Py_DECREF(nameobj);
return NULL;
}
- existing_m = PyDict_GetItemString(modules_reloading, name);
+ existing_m = PyDict_GetItem(modules_reloading, nameobj);
if (existing_m != NULL) {
/* Due to a recursive reload, this module is already
being reloaded. */
+ Py_DECREF(nameobj);
Py_INCREF(existing_m);
return existing_m;
}
- if (PyDict_SetItemString(modules_reloading, name, m) < 0)
+ if (PyDict_SetItem(modules_reloading, nameobj, m) < 0) {
+ Py_DECREF(nameobj);
return NULL;
+ }
- subname = strrchr(name, '.');
- if (subname == NULL)
- subname = name;
+ name = PyUnicode_AS_UNICODE(nameobj);
+ subname = Py_UNICODE_strrchr(name, '.');
+ if (subname == NULL) {
+ Py_INCREF(nameobj);
+ subnameobj = nameobj;
+ }
else {
PyObject *parentname, *parent;
- parentname = PyUnicode_FromStringAndSize(name, (subname-name));
+ Py_ssize_t len;
+ len = subname - name;
+ parentname = PyUnicode_FromUnicode(name, len);
if (parentname == NULL) {
- imp_modules_reloading_clear();
- return NULL;
+ goto error;
}
parent = PyDict_GetItem(modules, parentname);
if (parent == NULL) {
PyErr_Format(PyExc_ImportError,
- "reload(): parent %U not in sys.modules",
+ "reload(): parent %R not in sys.modules",
parentname);
Py_DECREF(parentname);
- imp_modules_reloading_clear();
- return NULL;
+ goto error;
}
Py_DECREF(parentname);
- subname++;
- path = PyObject_GetAttrString(parent, "__path__");
- if (path == NULL)
+ path_list = PyObject_GetAttrString(parent, "__path__");
+ if (path_list == NULL)
PyErr_Clear();
+ subname++;
+ len = PyUnicode_GET_SIZE(nameobj) - (len + 1);
+ subnameobj = PyUnicode_FromUnicode(subname, len);
}
- buf[0] = '\0';
- fdp = find_module(name, subname, path, buf, MAXPATHLEN+1, &fp, &loader);
- Py_XDECREF(path);
+ if (subnameobj == NULL)
+ goto error;
+ fdp = find_module(nameobj, subnameobj, path_list,
+ &bufobj, &fp, &loader);
+ Py_DECREF(subnameobj);
+ Py_XDECREF(path_list);
if (fdp == NULL) {
Py_XDECREF(loader);
- imp_modules_reloading_clear();
- return NULL;
+ goto error;
}
- newm = load_module(name, fp, buf, fdp->type, loader);
+ newm = load_module(nameobj, fp, bufobj, fdp->type, loader);
+ Py_XDECREF(bufobj);
Py_XDECREF(loader);
if (fp)
@@ -2997,9 +3392,12 @@ PyImport_ReloadModule(PyObject *m)
* going to return NULL in this case regardless of whether
* replacing name succeeds, so the return value is ignored.
*/
- PyDict_SetItemString(modules, name, m);
+ PyDict_SetItem(modules, nameobj, m);
}
+
+error:
imp_modules_reloading_clear();
+ Py_DECREF(nameobj);
return newm;
}
@@ -3147,22 +3545,21 @@ imp_get_suffixes(PyObject *self, PyObject *noargs)
}
static PyObject *
-call_find_module(char *name, PyObject *path)
+call_find_module(PyObject *name, PyObject *path_list)
{
extern int fclose(FILE *);
PyObject *fob, *ret;
PyObject *pathobj;
struct filedescr *fdp;
- char pathname[MAXPATHLEN+1];
- FILE *fp = NULL;
+ FILE *fp;
int fd = -1;
char *found_encoding = NULL;
char *encoding = NULL;
- pathname[0] = '\0';
- if (path == Py_None)
- path = NULL;
- fdp = find_module(NULL, name, path, pathname, MAXPATHLEN+1, &fp, NULL);
+ if (path_list == Py_None)
+ path_list = NULL;
+ fdp = find_module(NULL, name, path_list,
+ &pathobj, &fp, NULL);
if (fdp == NULL)
return NULL;
if (fp != NULL) {
@@ -3170,22 +3567,29 @@ call_find_module(char *name, PyObject *path)
if (fd != -1)
fd = dup(fd);
fclose(fp);
+ if (fd == -1) {
+ PyErr_SetFromErrno(PyExc_OSError);
+ return NULL;
+ }
fp = NULL;
}
if (fd != -1) {
if (strchr(fdp->mode, 'b') == NULL) {
- /* PyTokenizer_FindEncoding() returns PyMem_MALLOC'ed
+ /* PyTokenizer_FindEncodingFilename() returns PyMem_MALLOC'ed
memory. */
- found_encoding = PyTokenizer_FindEncoding(fd);
+ found_encoding = PyTokenizer_FindEncodingFilename(fd, pathobj);
lseek(fd, 0, 0); /* Reset position */
- if (found_encoding == NULL && PyErr_Occurred())
+ if (found_encoding == NULL && PyErr_Occurred()) {
+ Py_XDECREF(pathobj);
return NULL;
+ }
encoding = (found_encoding != NULL) ? found_encoding :
(char*)PyUnicode_GetDefaultEncoding();
}
- fob = PyFile_FromFd(fd, pathname, fdp->mode, -1,
+ fob = PyFile_FromFd(fd, NULL, fdp->mode, -1,
(char*)encoding, NULL, NULL, 1);
if (fob == NULL) {
+ Py_XDECREF(pathobj);
close(fd);
PyMem_FREE(found_encoding);
return NULL;
@@ -3195,7 +3599,10 @@ call_find_module(char *name, PyObject *path)
fob = Py_None;
Py_INCREF(fob);
}
- pathobj = PyUnicode_DecodeFSDefault(pathname);
+ if (pathobj == NULL) {
+ Py_INCREF(Py_None);
+ pathobj = Py_None;
+ }
ret = Py_BuildValue("NN(ssi)",
fob, pathobj, fdp->suffix, fdp->mode, fdp->type);
PyMem_FREE(found_encoding);
@@ -3206,24 +3613,20 @@ call_find_module(char *name, PyObject *path)
static PyObject *
imp_find_module(PyObject *self, PyObject *args)
{
- PyObject *name;
- PyObject *ret, *path = NULL;
- if (!PyArg_ParseTuple(args, "O&|O:find_module",
- PyUnicode_FSConverter, &name,
- &path))
+ PyObject *name, *path_list = NULL;
+ if (!PyArg_ParseTuple(args, "U|O:find_module",
+ &name, &path_list))
return NULL;
- ret = call_find_module(PyBytes_AS_STRING(name), path);
- Py_DECREF(name);
- return ret;
+ return call_find_module(name, path_list);
}
static PyObject *
imp_init_builtin(PyObject *self, PyObject *args)
{
- char *name;
+ PyObject *name;
int ret;
PyObject *m;
- if (!PyArg_ParseTuple(args, "s:init_builtin", &name))
+ if (!PyArg_ParseTuple(args, "U:init_builtin", &name))
return NULL;
ret = init_builtin(name);
if (ret < 0)
@@ -3232,7 +3635,7 @@ imp_init_builtin(PyObject *self, PyObject *args)
Py_INCREF(Py_None);
return Py_None;
}
- m = PyImport_AddModule(name);
+ m = PyImport_AddModuleObject(name);
Py_XINCREF(m);
return m;
}
@@ -3240,19 +3643,19 @@ imp_init_builtin(PyObject *self, PyObject *args)
static PyObject *
imp_init_frozen(PyObject *self, PyObject *args)
{
- char *name;
+ PyObject *name;
int ret;
PyObject *m;
- if (!PyArg_ParseTuple(args, "s:init_frozen", &name))
+ if (!PyArg_ParseTuple(args, "U:init_frozen", &name))
return NULL;
- ret = PyImport_ImportFrozenModule(name);
+ ret = PyImport_ImportFrozenModuleObject(name);
if (ret < 0)
return NULL;
if (ret == 0) {
Py_INCREF(Py_None);
return Py_None;
}
- m = PyImport_AddModule(name);
+ m = PyImport_AddModuleObject(name);
Py_XINCREF(m);
return m;
}
@@ -3260,9 +3663,9 @@ imp_init_frozen(PyObject *self, PyObject *args)
static PyObject *
imp_get_frozen_object(PyObject *self, PyObject *args)
{
- char *name;
+ PyObject *name;
- if (!PyArg_ParseTuple(args, "s:get_frozen_object", &name))
+ if (!PyArg_ParseTuple(args, "U:get_frozen_object", &name))
return NULL;
return get_frozen_object(name);
}
@@ -3270,9 +3673,9 @@ imp_get_frozen_object(PyObject *self, PyObject *args)
static PyObject *
imp_is_frozen_package(PyObject *self, PyObject *args)
{
- char *name;
+ PyObject *name;
- if (!PyArg_ParseTuple(args, "s:is_frozen_package", &name))
+ if (!PyArg_ParseTuple(args, "U:is_frozen_package", &name))
return NULL;
return is_frozen_package(name);
}
@@ -3280,8 +3683,8 @@ imp_is_frozen_package(PyObject *self, PyObject *args)
static PyObject *
imp_is_builtin(PyObject *self, PyObject *args)
{
- char *name;
- if (!PyArg_ParseTuple(args, "s:is_builtin", &name))
+ PyObject *name;
+ if (!PyArg_ParseTuple(args, "U:is_builtin", &name))
return NULL;
return PyLong_FromLong(is_builtin(name));
}
@@ -3289,22 +3692,22 @@ imp_is_builtin(PyObject *self, PyObject *args)
static PyObject *
imp_is_frozen(PyObject *self, PyObject *args)
{
- char *name;
+ PyObject *name;
struct _frozen *p;
- if (!PyArg_ParseTuple(args, "s:is_frozen", &name))
+ if (!PyArg_ParseTuple(args, "U:is_frozen", &name))
return NULL;
p = find_frozen(name);
return PyBool_FromLong((long) (p == NULL ? 0 : p->size));
}
static FILE *
-get_file(char *pathname, PyObject *fob, char *mode)
+get_file(PyObject *pathname, PyObject *fob, char *mode)
{
FILE *fp;
if (mode[0] == 'U')
mode = "r" PY_STDIOTEXTMODE;
if (fob == NULL) {
- fp = fopen(pathname, mode);
+ fp = _Py_fopen(pathname, mode);
}
else {
int fd = PyObject_AsFileDescriptor(fob);
@@ -3330,22 +3733,21 @@ error:
static PyObject *
imp_load_compiled(PyObject *self, PyObject *args)
{
- char *name;
- PyObject *pathname;
+ PyObject *name, *pathname;
PyObject *fob = NULL;
PyObject *m;
FILE *fp;
- if (!PyArg_ParseTuple(args, "sO&|O:load_compiled",
+ if (!PyArg_ParseTuple(args, "UO&|O:load_compiled",
&name,
- PyUnicode_FSConverter, &pathname,
+ PyUnicode_FSDecoder, &pathname,
&fob))
return NULL;
- fp = get_file(PyBytes_AS_STRING(pathname), fob, "rb");
+ fp = get_file(pathname, fob, "rb");
if (fp == NULL) {
Py_DECREF(pathname);
return NULL;
}
- m = load_compiled_module(name, PyBytes_AS_STRING(pathname), fp);
+ m = load_compiled_module(name, pathname, fp);
fclose(fp);
Py_DECREF(pathname);
return m;
@@ -3356,28 +3758,26 @@ imp_load_compiled(PyObject *self, PyObject *args)
static PyObject *
imp_load_dynamic(PyObject *self, PyObject *args)
{
- char *name;
- PyObject *pathbytes;
- char *pathname;
- PyObject *fob = NULL;
- PyObject *m;
- FILE *fp = NULL;
- if (!PyArg_ParseTuple(args, "sO&|O:load_dynamic",
- &name, PyUnicode_FSConverter, &pathbytes, &fob))
+ PyObject *name, *pathname, *fob = NULL, *mod;
+ FILE *fp;
+
+ if (!PyArg_ParseTuple(args, "UO&|O:load_dynamic",
+ &name, PyUnicode_FSDecoder, &pathname, &fob))
return NULL;
- pathname = PyBytes_AS_STRING(pathbytes);
- if (fob) {
- fp = get_file(pathname, fob, "r");
+ if (fob != NULL) {
+ fp = get_file(NULL, fob, "r");
if (fp == NULL) {
- Py_DECREF(pathbytes);
+ Py_DECREF(pathname);
return NULL;
}
}
- m = _PyImport_LoadDynamicModule(name, pathname, fp);
- Py_DECREF(pathbytes);
+ else
+ fp = NULL;
+ mod = _PyImport_LoadDynamicModule(name, pathname, fp);
+ Py_DECREF(pathname);
if (fp)
fclose(fp);
- return m;
+ return mod;
}
#endif /* HAVE_DYNAMIC_LOADING */
@@ -3385,22 +3785,21 @@ imp_load_dynamic(PyObject *self, PyObject *args)
static PyObject *
imp_load_source(PyObject *self, PyObject *args)
{
- char *name;
- PyObject *pathname;
+ PyObject *name, *pathname;
PyObject *fob = NULL;
PyObject *m;
FILE *fp;
- if (!PyArg_ParseTuple(args, "sO&|O:load_source",
+ if (!PyArg_ParseTuple(args, "UO&|O:load_source",
&name,
- PyUnicode_FSConverter, &pathname,
+ PyUnicode_FSDecoder, &pathname,
&fob))
return NULL;
- fp = get_file(PyBytes_AS_STRING(pathname), fob, "r");
+ fp = get_file(pathname, fob, "r");
if (fp == NULL) {
Py_DECREF(pathname);
return NULL;
}
- m = load_source_module(name, PyBytes_AS_STRING(pathname), fp);
+ m = load_source_module(name, pathname, fp);
Py_DECREF(pathname);
fclose(fp);
return m;
@@ -3409,20 +3808,22 @@ imp_load_source(PyObject *self, PyObject *args)
static PyObject *
imp_load_module(PyObject *self, PyObject *args)
{
- char *name;
- PyObject *fob;
- PyObject *pathname;
- PyObject * ret;
+ PyObject *name, *fob, *pathname, *pathname_obj, *ret;
char *suffix; /* Unused */
char *mode;
int type;
FILE *fp;
- if (!PyArg_ParseTuple(args, "sOO&(ssi):load_module",
- &name, &fob,
- PyUnicode_FSConverter, &pathname,
- &suffix, &mode, &type))
+ if (!PyArg_ParseTuple(args, "UOO(ssi):load_module",
+ &name, &fob, &pathname_obj, &suffix, &mode, &type))
return NULL;
+ if (pathname_obj != Py_None) {
+ if (!PyUnicode_FSDecoder(pathname_obj, &pathname))
+ return NULL;
+ }
+ else
+ pathname = NULL;
+
if (*mode) {
/* Mode must start with 'r' or 'U' and must not contain '+'.
Implicit in this test is the assumption that the mode
@@ -3431,7 +3832,7 @@ imp_load_module(PyObject *self, PyObject *args)
if (!(*mode == 'r' || *mode == 'U') || strchr(mode, '+')) {
PyErr_Format(PyExc_ValueError,
"invalid file open mode %.200s", mode);
- Py_DECREF(pathname);
+ Py_XDECREF(pathname);
return NULL;
}
}
@@ -3440,12 +3841,12 @@ imp_load_module(PyObject *self, PyObject *args)
else {
fp = get_file(NULL, fob, mode);
if (fp == NULL) {
- Py_DECREF(pathname);
+ Py_XDECREF(pathname);
return NULL;
}
}
- ret = load_module(name, fp, PyBytes_AS_STRING(pathname), type, NULL);
- Py_DECREF(pathname);
+ ret = load_module(name, fp, pathname, type, NULL);
+ Py_XDECREF(pathname);
if (fp)
fclose(fp);
return ret;
@@ -3454,13 +3855,12 @@ imp_load_module(PyObject *self, PyObject *args)
static PyObject *
imp_load_package(PyObject *self, PyObject *args)
{
- char *name;
- PyObject *pathname;
+ PyObject *name, *pathname;
PyObject * ret;
- if (!PyArg_ParseTuple(args, "sO&:load_package",
- &name, PyUnicode_FSConverter, &pathname))
+ if (!PyArg_ParseTuple(args, "UO&:load_package",
+ &name, PyUnicode_FSDecoder, &pathname))
return NULL;
- ret = load_package(name, PyBytes_AS_STRING(pathname));
+ ret = load_package(name, pathname);
Py_DECREF(pathname);
return ret;
}
@@ -3468,10 +3868,10 @@ imp_load_package(PyObject *self, PyObject *args)
static PyObject *
imp_new_module(PyObject *self, PyObject *args)
{
- char *name;
- if (!PyArg_ParseTuple(args, "s:new_module", &name))
+ PyObject *name;
+ if (!PyArg_ParseTuple(args, "U:new_module", &name))
return NULL;
- return PyModule_New(name);
+ return PyModule_NewObject(name);
}
static PyObject *
@@ -3490,33 +3890,31 @@ imp_cache_from_source(PyObject *self, PyObject *args, PyObject *kws)
{
static char *kwlist[] = {"path", "debug_override", NULL};
- char buf[MAXPATHLEN+1];
- PyObject *pathbytes;
- char *cpathname;
+ PyObject *pathname, *cpathname;
PyObject *debug_override = NULL;
int debug = !Py_OptimizeFlag;
if (!PyArg_ParseTupleAndKeywords(
args, kws, "O&|O", kwlist,
- PyUnicode_FSConverter, &pathbytes, &debug_override))
+ PyUnicode_FSDecoder, &pathname, &debug_override))
return NULL;
if (debug_override != NULL &&
(debug = PyObject_IsTrue(debug_override)) < 0) {
- Py_DECREF(pathbytes);
+ Py_DECREF(pathname);
return NULL;
}
cpathname = make_compiled_pathname(
- PyBytes_AS_STRING(pathbytes),
- buf, MAXPATHLEN+1, debug);
- Py_DECREF(pathbytes);
+ PyUnicode_AS_UNICODE(pathname),
+ debug);
+ Py_DECREF(pathname);
if (cpathname == NULL) {
PyErr_Format(PyExc_SystemError, "path buffer too short");
return NULL;
}
- return PyUnicode_DecodeFSDefault(buf);
+ return cpathname;
}
PyDoc_STRVAR(doc_cache_from_source,
@@ -3533,25 +3931,22 @@ static PyObject *
imp_source_from_cache(PyObject *self, PyObject *args, PyObject *kws)
{
static char *kwlist[] = {"path", NULL};
-
- PyObject *pathname_obj;
- char *pathname;
- char buf[MAXPATHLEN+1];
+ PyObject *pathname, *source;
if (!PyArg_ParseTupleAndKeywords(
args, kws, "O&", kwlist,
- PyUnicode_FSConverter, &pathname_obj))
+ PyUnicode_FSDecoder, &pathname))
return NULL;
- pathname = PyBytes_AS_STRING(pathname_obj);
- if (make_source_pathname(pathname, buf) == NULL) {
- PyErr_Format(PyExc_ValueError, "Not a PEP 3147 pyc path: %s",
+ source = make_source_pathname(pathname);
+ if (source == NULL) {
+ PyErr_Format(PyExc_ValueError, "Not a PEP 3147 pyc path: %R",
pathname);
- Py_DECREF(pathname_obj);
+ Py_DECREF(pathname);
return NULL;
}
- Py_DECREF(pathname_obj);
- return PyUnicode_FromString(buf);
+ Py_DECREF(pathname);
+ return source;
}
PyDoc_STRVAR(doc_source_from_cache,
@@ -3642,6 +4037,7 @@ static PyMethodDef imp_methods[] = {
#endif
{"load_package", imp_load_package, METH_VARARGS},
{"load_source", imp_load_source, METH_VARARGS},
+ {"_fix_co_filename", imp_fix_co_filename, METH_VARARGS},
{NULL, NULL} /* sentinel */
};
diff --git a/Python/importdl.c b/Python/importdl.c
index 9caed45..9127d61 100644
--- a/Python/importdl.c
+++ b/Python/importdl.c
@@ -12,49 +12,71 @@
#include "importdl.h"
-extern dl_funcptr _PyImport_GetDynLoadFunc(const char *name,
- const char *shortname,
+#ifdef MS_WINDOWS
+extern dl_funcptr _PyImport_GetDynLoadWindows(const char *shortname,
+ PyObject *pathname, FILE *fp);
+#else
+extern dl_funcptr _PyImport_GetDynLoadFunc(const char *shortname,
const char *pathname, FILE *fp);
-
-
+#endif
PyObject *
-_PyImport_LoadDynamicModule(char *name, char *pathname, FILE *fp)
+_PyImport_LoadDynamicModule(PyObject *name, PyObject *path, FILE *fp)
{
- PyObject *m;
- PyObject *path;
- char *lastdot, *shortname, *packagecontext, *oldcontext;
+ PyObject *m = NULL;
+#ifndef MS_WINDOWS
+ PyObject *pathbytes;
+#endif
+ PyObject *nameascii;
+ char *namestr, *lastdot, *shortname, *packagecontext, *oldcontext;
dl_funcptr p0;
PyObject* (*p)(void);
struct PyModuleDef *def;
- PyObject *result;
- path = PyUnicode_DecodeFSDefault(pathname);
- if (path == NULL)
- return NULL;
-
- if ((m = _PyImport_FindExtensionUnicode(name, path)) != NULL) {
+ m = _PyImport_FindExtensionObject(name, path);
+ if (m != NULL) {
Py_INCREF(m);
- result = m;
- goto finally;
+ return m;
}
- lastdot = strrchr(name, '.');
+
+ /* name must be encodable to ASCII because dynamic module must have a
+ function called "PyInit_NAME", they are written in C, and the C language
+ doesn't accept non-ASCII identifiers. */
+ nameascii = PyUnicode_AsEncodedString(name, "ascii", NULL);
+ if (nameascii == NULL)
+ return NULL;
+
+ namestr = PyBytes_AS_STRING(nameascii);
+ if (namestr == NULL)
+ goto error;
+
+ lastdot = strrchr(namestr, '.');
if (lastdot == NULL) {
packagecontext = NULL;
- shortname = name;
+ shortname = namestr;
}
else {
- packagecontext = name;
+ packagecontext = namestr;
shortname = lastdot+1;
}
- p0 = _PyImport_GetDynLoadFunc(name, shortname, pathname, fp);
+#ifdef MS_WINDOWS
+ p0 = _PyImport_GetDynLoadWindows(shortname, path, fp);
+#else
+ pathbytes = PyUnicode_EncodeFSDefault(path);
+ if (pathbytes == NULL)
+ goto error;
+ p0 = _PyImport_GetDynLoadFunc(shortname,
+ PyBytes_AS_STRING(pathbytes), fp);
+ Py_DECREF(pathbytes);
+#endif
p = (PyObject*(*)(void))p0;
if (PyErr_Occurred())
goto error;
if (p == NULL) {
PyErr_Format(PyExc_ImportError,
- "dynamic module does not define init function (PyInit_%.200s)",
+ "dynamic module does not define init function"
+ " (PyInit_%s)",
shortname);
goto error;
}
@@ -66,7 +88,6 @@ _PyImport_LoadDynamicModule(char *name, char *pathname, FILE *fp)
goto error;
if (PyErr_Occurred()) {
- Py_DECREF(m);
PyErr_Format(PyExc_SystemError,
"initialization of %s raised unreported exception",
shortname);
@@ -83,20 +104,19 @@ _PyImport_LoadDynamicModule(char *name, char *pathname, FILE *fp)
else
Py_INCREF(path);
- if (_PyImport_FixupExtensionUnicode(m, name, path) < 0)
+ if (_PyImport_FixupExtensionObject(m, name, path) < 0)
goto error;
if (Py_VerboseFlag)
- PySys_WriteStderr(
- "import %s # dynamically loaded from %s\n",
- name, pathname);
- result = m;
- goto finally;
+ PySys_FormatStderr(
+ "import %U # dynamically loaded from %R\n",
+ name, path);
+ Py_DECREF(nameascii);
+ return m;
error:
- result = NULL;
-finally:
- Py_DECREF(path);
- return result;
+ Py_DECREF(nameascii);
+ Py_XDECREF(m);
+ return NULL;
}
#endif /* HAVE_DYNAMIC_LOADING */
diff --git a/Python/importdl.h b/Python/importdl.h
index b4d21be..e51e551 100644
--- a/Python/importdl.h
+++ b/Python/importdl.h
@@ -28,7 +28,7 @@ struct filedescr {
extern struct filedescr * _PyImport_Filetab;
extern const struct filedescr _PyImport_DynLoadFiletab[];
-extern PyObject *_PyImport_LoadDynamicModule(char *name, char *pathname,
+extern PyObject *_PyImport_LoadDynamicModule(PyObject *name, PyObject *pathname,
FILE *);
/* Max length of module suffix searched for -- accommodates "module.slb" */
diff --git a/Python/marshal.c b/Python/marshal.c
index 76d5690..35fcd3a 100644
--- a/Python/marshal.c
+++ b/Python/marshal.c
@@ -59,9 +59,9 @@ typedef struct {
/* If fp == NULL, the following are valid: */
PyObject * readable; /* Stream-like object being read from */
PyObject *str;
+ PyObject *current_filename;
char *ptr;
char *end;
- PyObject *strings; /* dict on marshal, list on unmarshal */
int version;
} WFILE;
@@ -445,7 +445,6 @@ PyMarshal_WriteLongToFile(long x, FILE *fp, int version)
wf.fp = fp;
wf.error = WFERR_OK;
wf.depth = 0;
- wf.strings = NULL;
wf.version = version;
w_long(x, &wf);
}
@@ -457,10 +456,8 @@ PyMarshal_WriteObjectToFile(PyObject *x, FILE *fp, int version)
wf.fp = fp;
wf.error = WFERR_OK;
wf.depth = 0;
- wf.strings = (version > 0) ? PyDict_New() : NULL;
wf.version = version;
w_object(x, &wf);
- Py_XDECREF(wf.strings);
}
typedef WFILE RFILE; /* Same struct with different invariants */
@@ -1069,6 +1066,18 @@ r_object(RFILE *p)
filename = r_object(p);
if (filename == NULL)
goto code_error;
+ if (PyUnicode_CheckExact(filename)) {
+ if (p->current_filename != NULL) {
+ if (!PyUnicode_Compare(filename, p->current_filename)) {
+ Py_DECREF(filename);
+ Py_INCREF(p->current_filename);
+ filename = p->current_filename;
+ }
+ }
+ else {
+ p->current_filename = filename;
+ }
+ }
name = r_object(p);
if (name == NULL)
goto code_error;
@@ -1131,7 +1140,7 @@ PyMarshal_ReadShortFromFile(FILE *fp)
assert(fp);
rf.readable = NULL;
rf.fp = fp;
- rf.strings = NULL;
+ rf.current_filename = NULL;
rf.end = rf.ptr = NULL;
return r_short(&rf);
}
@@ -1142,7 +1151,7 @@ PyMarshal_ReadLongFromFile(FILE *fp)
RFILE rf;
rf.fp = fp;
rf.readable = NULL;
- rf.strings = NULL;
+ rf.current_filename = NULL;
rf.ptr = rf.end = NULL;
return r_long(&rf);
}
@@ -1204,11 +1213,10 @@ PyMarshal_ReadObjectFromFile(FILE *fp)
PyObject *result;
rf.fp = fp;
rf.readable = NULL;
- rf.strings = PyList_New(0);
+ rf.current_filename = NULL;
rf.depth = 0;
rf.ptr = rf.end = NULL;
result = r_object(&rf);
- Py_DECREF(rf.strings);
return result;
}
@@ -1219,12 +1227,11 @@ PyMarshal_ReadObjectFromString(char *str, Py_ssize_t len)
PyObject *result;
rf.fp = NULL;
rf.readable = NULL;
+ rf.current_filename = NULL;
rf.ptr = str;
rf.end = str + len;
- rf.strings = PyList_New(0);
rf.depth = 0;
result = r_object(&rf);
- Py_DECREF(rf.strings);
return result;
}
@@ -1244,9 +1251,7 @@ PyMarshal_WriteObjectToString(PyObject *x, int version)
wf.error = WFERR_OK;
wf.depth = 0;
wf.version = version;
- wf.strings = (version > 0) ? PyDict_New() : NULL;
w_object(x, &wf);
- Py_XDECREF(wf.strings);
if (wf.str != NULL) {
char *base = PyBytes_AS_STRING((PyBytesObject *)wf.str);
if (wf.ptr - base > PY_SSIZE_T_MAX) {
@@ -1331,12 +1336,11 @@ marshal_load(PyObject *self, PyObject *f)
result = NULL;
}
else {
- rf.strings = PyList_New(0);
rf.depth = 0;
rf.fp = NULL;
rf.readable = f;
+ rf.current_filename = NULL;
result = read_object(&rf);
- Py_DECREF(rf.strings);
}
Py_DECREF(data);
return result;
@@ -1389,12 +1393,11 @@ marshal_loads(PyObject *self, PyObject *args)
n = p.len;
rf.fp = NULL;
rf.readable = NULL;
+ rf.current_filename = NULL;
rf.ptr = s;
rf.end = s + n;
- rf.strings = PyList_New(0);
rf.depth = 0;
result = read_object(&rf);
- Py_DECREF(rf.strings);
PyBuffer_Release(&p);
return result;
}
diff --git a/Python/peephole.c b/Python/peephole.c
index 359eda8..781498e 100644
--- a/Python/peephole.c
+++ b/Python/peephole.c
@@ -23,6 +23,64 @@
#define ISBASICBLOCK(blocks, start, bytes) \
(blocks[start]==blocks[start+bytes-1])
+
+#define CONST_STACK_CREATE() { \
+ const_stack_size = 256; \
+ const_stack = PyMem_New(PyObject *, const_stack_size); \
+ load_const_stack = PyMem_New(Py_ssize_t, const_stack_size); \
+ if (!const_stack || !load_const_stack) { \
+ PyErr_NoMemory(); \
+ goto exitError; \
+ } \
+ }
+
+#define CONST_STACK_DELETE() do { \
+ if (const_stack) \
+ PyMem_Free(const_stack); \
+ if (load_const_stack) \
+ PyMem_Free(load_const_stack); \
+ } while(0)
+
+#define CONST_STACK_LEN() (const_stack_top + 1)
+
+#define CONST_STACK_PUSH_OP(i) do { \
+ PyObject *_x; \
+ assert(codestr[i] == LOAD_CONST); \
+ assert(PyList_GET_SIZE(consts) > GETARG(codestr, i)); \
+ _x = PyList_GET_ITEM(consts, GETARG(codestr, i)); \
+ if (++const_stack_top >= const_stack_size) { \
+ const_stack_size *= 2; \
+ PyMem_Resize(const_stack, PyObject *, const_stack_size); \
+ PyMem_Resize(load_const_stack, Py_ssize_t, const_stack_size); \
+ if (!const_stack || !load_const_stack) { \
+ PyErr_NoMemory(); \
+ goto exitError; \
+ } \
+ } \
+ load_const_stack[const_stack_top] = i; \
+ const_stack[const_stack_top] = _x; \
+ in_consts = 1; \
+ } while(0)
+
+#define CONST_STACK_RESET() do { \
+ const_stack_top = -1; \
+ } while(0)
+
+#define CONST_STACK_TOP(x) \
+ const_stack[const_stack_top]
+
+#define CONST_STACK_LASTN(i) \
+ &const_stack[const_stack_top - i + 1]
+
+#define CONST_STACK_POP(i) do { \
+ assert(const_stack_top + 1 >= i); \
+ const_stack_top -= i; \
+ } while(0)
+
+#define CONST_STACK_OP_LASTN(i) \
+ ((const_stack_top >= i - 1) ? load_const_stack[const_stack_top - i + 1] : -1)
+
+
/* Replace LOAD_CONST c1. LOAD_CONST c2 ... LOAD_CONST cn BUILD_TUPLE n
with LOAD_CONST (c1, c2, ... cn).
The consts table must still be in list form so that the
@@ -33,17 +91,14 @@
test; for BUILD_SET it assembles a frozenset rather than a tuple.
*/
static int
-tuple_of_constants(unsigned char *codestr, Py_ssize_t n, PyObject *consts)
+tuple_of_constants(unsigned char *codestr, Py_ssize_t n,
+ PyObject *consts, PyObject **objs)
{
PyObject *newconst, *constant;
- Py_ssize_t i, arg, len_consts;
+ Py_ssize_t i, len_consts;
/* Pre-conditions */
assert(PyList_CheckExact(consts));
- assert(codestr[n*3] == BUILD_TUPLE || codestr[n*3] == BUILD_LIST || codestr[n*3] == BUILD_SET);
- assert(GETARG(codestr, (n*3)) == n);
- for (i=0 ; i<n ; i++)
- assert(codestr[i*3] == LOAD_CONST);
/* Buildup new tuple of constants */
newconst = PyTuple_New(n);
@@ -51,16 +106,14 @@ tuple_of_constants(unsigned char *codestr, Py_ssize_t n, PyObject *consts)
return 0;
len_consts = PyList_GET_SIZE(consts);
for (i=0 ; i<n ; i++) {
- arg = GETARG(codestr, (i*3));
- assert(arg < len_consts);
- constant = PyList_GET_ITEM(consts, arg);
+ constant = objs[i];
Py_INCREF(constant);
PyTuple_SET_ITEM(newconst, i, constant);
}
/* If it's a BUILD_SET, use the PyTuple we just built to create a
PyFrozenSet, and use that as the constant instead: */
- if (codestr[n*3] == BUILD_SET) {
+ if (codestr[0] == BUILD_SET) {
PyObject *tuple = newconst;
newconst = PyFrozenSet_New(tuple);
Py_DECREF(tuple);
@@ -77,9 +130,8 @@ tuple_of_constants(unsigned char *codestr, Py_ssize_t n, PyObject *consts)
/* Write NOPs over old LOAD_CONSTS and
add a new LOAD_CONST newconst on top of the BUILD_TUPLE n */
- memset(codestr, NOP, n*3);
- codestr[n*3] = LOAD_CONST;
- SETARG(codestr, (n*3), len_consts);
+ codestr[0] = LOAD_CONST;
+ SETARG(codestr, 0, len_consts);
return 1;
}
@@ -87,14 +139,14 @@ tuple_of_constants(unsigned char *codestr, Py_ssize_t n, PyObject *consts)
with LOAD_CONST binop(c1,c2)
The consts table must still be in list form so that the
new constant can be appended.
- Called with codestr pointing to the first LOAD_CONST.
+ Called with codestr pointing to the BINOP.
Abandons the transformation if the folding fails (i.e. 1+'a').
If the new constant is a sequence, only folds when the size
is below a threshold value. That keeps pyc files from
becoming large in the presence of code like: (None,)*1000.
*/
static int
-fold_binops_on_constants(unsigned char *codestr, PyObject *consts)
+fold_binops_on_constants(unsigned char *codestr, PyObject *consts, PyObject **objs)
{
PyObject *newconst, *v, *w;
Py_ssize_t len_consts, size;
@@ -102,13 +154,11 @@ fold_binops_on_constants(unsigned char *codestr, PyObject *consts)
/* Pre-conditions */
assert(PyList_CheckExact(consts));
- assert(codestr[0] == LOAD_CONST);
- assert(codestr[3] == LOAD_CONST);
/* Create new constant */
- v = PyList_GET_ITEM(consts, GETARG(codestr, 0));
- w = PyList_GET_ITEM(consts, GETARG(codestr, 3));
- opcode = codestr[6];
+ v = objs[0];
+ w = objs[1];
+ opcode = codestr[0];
switch (opcode) {
case BINARY_POWER:
newconst = PyNumber_Power(v, w, Py_None);
@@ -198,16 +248,15 @@ fold_binops_on_constants(unsigned char *codestr, PyObject *consts)
Py_DECREF(newconst);
/* Write NOP NOP NOP NOP LOAD_CONST newconst */
- memset(codestr, NOP, 4);
- codestr[4] = LOAD_CONST;
- SETARG(codestr, 4, len_consts);
+ codestr[-2] = LOAD_CONST;
+ SETARG(codestr, -2, len_consts);
return 1;
}
static int
-fold_unaryops_on_constants(unsigned char *codestr, PyObject *consts)
+fold_unaryops_on_constants(unsigned char *codestr, PyObject *consts, PyObject *v)
{
- PyObject *newconst=NULL, *v;
+ PyObject *newconst;
Py_ssize_t len_consts;
int opcode;
@@ -216,13 +265,10 @@ fold_unaryops_on_constants(unsigned char *codestr, PyObject *consts)
assert(codestr[0] == LOAD_CONST);
/* Create new constant */
- v = PyList_GET_ITEM(consts, GETARG(codestr, 0));
opcode = codestr[3];
switch (opcode) {
case UNARY_NEGATIVE:
- /* Preserve the sign of -0.0 */
- if (PyObject_IsTrue(v) == 1)
- newconst = PyNumber_Negative(v);
+ newconst = PyNumber_Negative(v);
break;
case UNARY_INVERT:
newconst = PyNumber_Invert(v);
@@ -358,7 +404,11 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,
unsigned char *lineno;
int *addrmap = NULL;
int new_line, cum_orig_line, last_line, tabsiz;
- int cumlc=0, lastlc=0; /* Count runs of consecutive LOAD_CONSTs */
+ PyObject **const_stack = NULL;
+ Py_ssize_t *load_const_stack = NULL;
+ Py_ssize_t const_stack_top = -1;
+ Py_ssize_t const_stack_size = 0;
+ int in_consts = 0; /* whether we are in a LOAD_CONST sequence */
unsigned int *blocks = NULL;
char *name;
@@ -404,12 +454,16 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,
goto exitError;
assert(PyList_Check(consts));
+ CONST_STACK_CREATE();
+
for (i=0 ; i<codelen ; i += CODESIZE(codestr[i])) {
reoptimize_current:
opcode = codestr[i];
- lastlc = cumlc;
- cumlc = 0;
+ if (!in_consts) {
+ CONST_STACK_RESET();
+ }
+ in_consts = 0;
switch (opcode) {
/* Replace UNARY_NOT POP_JUMP_IF_FALSE
@@ -450,21 +504,21 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,
goto exitError;
else if (h == 0)
continue;
- cumlc = lastlc + 1;
+ CONST_STACK_PUSH_OP(i);
break;
/* Skip over LOAD_CONST trueconst
POP_JUMP_IF_FALSE xx. This improves
"while 1" performance. */
case LOAD_CONST:
- cumlc = lastlc + 1;
+ CONST_STACK_PUSH_OP(i);
j = GETARG(codestr, i);
if (codestr[i+3] != POP_JUMP_IF_FALSE ||
!ISBASICBLOCK(blocks,i,6) ||
!PyObject_IsTrue(PyList_GET_ITEM(consts, j)))
continue;
memset(codestr+i, NOP, 6);
- cumlc = 0;
+ CONST_STACK_RESET();
break;
/* Try to fold tuples of constants (includes a case for lists and sets
@@ -476,19 +530,23 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,
case BUILD_LIST:
case BUILD_SET:
j = GETARG(codestr, i);
- h = i - 3 * j;
- if (h >= 0 &&
- j <= lastlc &&
+ if (j == 0)
+ break;
+ h = CONST_STACK_OP_LASTN(j);
+ assert((h >= 0 || CONST_STACK_LEN() < j));
+ if (h >= 0 && j > 0 && j <= CONST_STACK_LEN() &&
((opcode == BUILD_TUPLE &&
- ISBASICBLOCK(blocks, h, 3*(j+1))) ||
+ ISBASICBLOCK(blocks, h, i-h+3)) ||
((opcode == BUILD_LIST || opcode == BUILD_SET) &&
codestr[i+3]==COMPARE_OP &&
- ISBASICBLOCK(blocks, h, 3*(j+2)) &&
+ ISBASICBLOCK(blocks, h, i-h+6) &&
(GETARG(codestr,i+3)==6 ||
GETARG(codestr,i+3)==7))) &&
- tuple_of_constants(&codestr[h], j, consts)) {
+ tuple_of_constants(&codestr[i], j, consts, CONST_STACK_LASTN(j))) {
assert(codestr[i] == LOAD_CONST);
- cumlc = 1;
+ memset(&codestr[h], NOP, i - h);
+ CONST_STACK_POP(j);
+ CONST_STACK_PUSH_OP(i);
break;
}
if (codestr[i+3] != UNPACK_SEQUENCE ||
@@ -501,10 +559,12 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,
} else if (j == 2) {
codestr[i] = ROT_TWO;
memset(codestr+i+1, NOP, 5);
+ CONST_STACK_RESET();
} else if (j == 3) {
codestr[i] = ROT_THREE;
codestr[i+1] = ROT_TWO;
memset(codestr+i+2, NOP, 4);
+ CONST_STACK_RESET();
}
break;
@@ -523,12 +583,18 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,
case BINARY_AND:
case BINARY_XOR:
case BINARY_OR:
- if (lastlc >= 2 &&
- ISBASICBLOCK(blocks, i-6, 7) &&
- fold_binops_on_constants(&codestr[i-6], consts)) {
+ /* NOTE: LOAD_CONST is saved at `i-2` since it has an arg
+ while BINOP hasn't */
+ h = CONST_STACK_OP_LASTN(2);
+ assert((h >= 0 || CONST_STACK_LEN() < 2));
+ if (h >= 0 &&
+ ISBASICBLOCK(blocks, h, i-h+1) &&
+ fold_binops_on_constants(&codestr[i], consts, CONST_STACK_LASTN(2))) {
i -= 2;
+ memset(&codestr[h], NOP, i - h);
assert(codestr[i] == LOAD_CONST);
- cumlc = 1;
+ CONST_STACK_POP(2);
+ CONST_STACK_PUSH_OP(i);
}
break;
@@ -537,12 +603,15 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,
case UNARY_NEGATIVE:
case UNARY_INVERT:
case UNARY_POSITIVE:
- if (lastlc >= 1 &&
- ISBASICBLOCK(blocks, i-3, 4) &&
- fold_unaryops_on_constants(&codestr[i-3], consts)) {
+ h = CONST_STACK_OP_LASTN(1);
+ assert((h >= 0 || CONST_STACK_LEN() < 1));
+ if (h >= 0 &&
+ ISBASICBLOCK(blocks, h, i-h+1) &&
+ fold_unaryops_on_constants(&codestr[i-3], consts, CONST_STACK_TOP())) {
i -= 2;
assert(codestr[i] == LOAD_CONST);
- cumlc = 1;
+ CONST_STACK_POP(1);
+ CONST_STACK_PUSH_OP(i);
}
break;
@@ -699,6 +768,7 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,
assert(h + nops == codelen);
code = PyBytes_FromStringAndSize((char *)codestr, h);
+ CONST_STACK_DELETE();
PyMem_Free(addrmap);
PyMem_Free(codestr);
PyMem_Free(blocks);
@@ -708,6 +778,7 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,
code = NULL;
exitUnchanged:
+ CONST_STACK_DELETE();
if (blocks != NULL)
PyMem_Free(blocks);
if (addrmap != NULL)
diff --git a/Python/pystrtod.c b/Python/pystrtod.c
index 75e3032..7bf21c0 100644
--- a/Python/pystrtod.c
+++ b/Python/pystrtod.c
@@ -954,7 +954,7 @@ format_float_short(double d, char format_code,
/* shouldn't get here: Gay's code should always return
something starting with a digit, an 'I', or 'N' */
strncpy(p, "ERR", 3);
- p += 3;
+ /* p += 3; */
assert(0);
}
goto exit;
diff --git a/Python/pythonrun.c b/Python/pythonrun.c
index 084db12..232d7be 100644
--- a/Python/pythonrun.c
+++ b/Python/pythonrun.c
@@ -62,6 +62,7 @@ static PyObject *run_mod(mod_ty, const char *, PyObject *, PyObject *,
static PyObject *run_pyc_file(FILE *, const char *, PyObject *, PyObject *,
PyCompilerFlags *);
static void err_input(perrdetail *);
+static void err_free(perrdetail *);
static void initsigs(void);
static void call_py_exitfuncs(void);
static void wait_for_thread_shutdown(void);
@@ -70,6 +71,8 @@ extern void _PyUnicode_Init(void);
extern void _PyUnicode_Fini(void);
extern int _PyLong_Init(void);
extern void PyLong_Fini(void);
+extern int _PyFaulthandler_Init(void);
+extern void _PyFaulthandler_Fini(void);
#ifdef WITH_THREAD
extern void _PyGILState_Init(PyInterpreterState *, PyThreadState *);
@@ -289,6 +292,10 @@ Py_InitializeEx(int install_sigs)
_PyImportHooks_Init();
+ /* initialize the faulthandler module */
+ if (_PyFaulthandler_Init())
+ Py_FatalError("Py_Initialize: can't initialize faulthandler");
+
/* Initialize _warnings. */
_PyWarnings_Init();
@@ -462,6 +469,9 @@ Py_Finalize(void)
/* Destroy the database used by _PyImport_{Fixup,Find}Extension */
_PyImport_Fini();
+ /* unload faulthandler module */
+ _PyFaulthandler_Fini();
+
/* Debugging stuff */
#ifdef COUNT_ALLOCS
dump_counts(stdout);
@@ -1583,7 +1593,7 @@ print_exception(PyObject *f, PyObject *value)
moduleName = PyObject_GetAttrString(type, "__module__");
if (moduleName == NULL || !PyUnicode_Check(moduleName))
{
- Py_DECREF(moduleName);
+ Py_XDECREF(moduleName);
err = PyFile_WriteString("<unknown>", f);
}
else {
@@ -1892,12 +1902,13 @@ PyParser_ASTFromString(const char *s, const char *filename, int start,
flags->cf_flags |= iflags & PyCF_MASK;
mod = PyAST_FromNode(n, flags, filename, arena);
PyNode_Free(n);
- return mod;
}
else {
err_input(&err);
- return NULL;
+ mod = NULL;
}
+ err_free(&err);
+ return mod;
}
mod_ty
@@ -1922,14 +1933,15 @@ PyParser_ASTFromFile(FILE *fp, const char *filename, const char* enc,
flags->cf_flags |= iflags & PyCF_MASK;
mod = PyAST_FromNode(n, flags, filename, arena);
PyNode_Free(n);
- return mod;
}
else {
err_input(&err);
if (errcode)
*errcode = err.error;
- return NULL;
+ mod = NULL;
}
+ err_free(&err);
+ return mod;
}
/* Simplified interface to parsefile -- return node or set exception */
@@ -1943,6 +1955,7 @@ PyParser_SimpleParseFileFlags(FILE *fp, const char *filename, int start, int fla
start, NULL, NULL, &err, flags);
if (n == NULL)
err_input(&err);
+ err_free(&err);
return n;
}
@@ -1957,6 +1970,7 @@ PyParser_SimpleParseStringFlags(const char *str, int start, int flags)
start, &err, flags);
if (n == NULL)
err_input(&err);
+ err_free(&err);
return n;
}
@@ -1969,6 +1983,7 @@ PyParser_SimpleParseStringFlagsFilename(const char *str, const char *filename,
&_PyParser_Grammar, start, &err, flags);
if (n == NULL)
err_input(&err);
+ err_free(&err);
return n;
}
@@ -1982,11 +1997,23 @@ PyParser_SimpleParseStringFilename(const char *str, const char *filename, int st
even parser modules. */
void
+PyParser_ClearError(perrdetail *err)
+{
+ err_free(err);
+}
+
+void
PyParser_SetError(perrdetail *err)
{
err_input(err);
}
+static void
+err_free(perrdetail *err)
+{
+ Py_CLEAR(err->filename);
+}
+
/* Set the error appropriate to the given input error code (see errcode.h) */
static void
@@ -1994,7 +2021,6 @@ err_input(perrdetail *err)
{
PyObject *v, *w, *errtype, *errtext;
PyObject *msg_obj = NULL;
- PyObject *filename;
char *msg = NULL;
errtype = PyExc_SyntaxError;
@@ -2080,17 +2106,8 @@ err_input(perrdetail *err)
errtext = PyUnicode_DecodeUTF8(err->text, strlen(err->text),
"replace");
}
- if (err->filename != NULL)
- filename = PyUnicode_DecodeFSDefault(err->filename);
- else {
- Py_INCREF(Py_None);
- filename = Py_None;
- }
- if (filename != NULL)
- v = Py_BuildValue("(NiiN)", filename,
- err->lineno, err->offset, errtext);
- else
- v = NULL;
+ v = Py_BuildValue("(OiiN)", err->filename,
+ err->lineno, err->offset, errtext);
if (v != NULL) {
if (msg_obj)
w = Py_BuildValue("(OO)", msg_obj, v);
@@ -2114,11 +2131,24 @@ cleanup:
void
Py_FatalError(const char *msg)
{
+ const int fd = fileno(stderr);
+ PyThreadState *tstate;
+
fprintf(stderr, "Fatal Python error: %s\n", msg);
fflush(stderr); /* it helps in Windows debug build */
if (PyErr_Occurred()) {
PyErr_PrintEx(0);
}
+ else {
+ tstate = _Py_atomic_load_relaxed(&_PyThreadState_Current);
+ if (tstate != NULL) {
+ fputc('\n', stderr);
+ fflush(stderr);
+ _Py_DumpTracebackThreads(fd, tstate->interp, tstate);
+ }
+ _PyFaulthandler_Fini();
+ }
+
#ifdef MS_WINDOWS
{
size_t len = strlen(msg);
diff --git a/Python/symtable.c b/Python/symtable.c
index 5eff364..a0bedfc 100644
--- a/Python/symtable.c
+++ b/Python/symtable.c
@@ -185,6 +185,7 @@ static int symtable_visit_params(struct symtable *st, asdl_seq *args);
static int symtable_visit_argannotations(struct symtable *st, asdl_seq *args);
static int symtable_implicit_arg(struct symtable *st, int pos);
static int symtable_visit_annotations(struct symtable *st, stmt_ty s);
+static int symtable_visit_withitem(struct symtable *st, withitem_ty item);
static identifier top = NULL, lambda = NULL, genexpr = NULL,
@@ -224,10 +225,17 @@ symtable_new(void)
struct symtable *
PySymtable_Build(mod_ty mod, const char *filename, PyFutureFeatures *future)
{
- struct symtable *st = symtable_new();
+ struct symtable *st;
asdl_seq *seq;
int i;
+ if (__class__ == NULL) {
+ __class__ = PyUnicode_InternFromString("@__class__");
+ if (__class__ == NULL)
+ return NULL;
+ }
+
+ st = symtable_new();
if (st == NULL)
return st;
st->st_filename = filename;
@@ -743,14 +751,12 @@ analyze_block(PySTEntryObject *ste, PyObject *bound, PyObject *free,
}
else {
/* Special-case __class__ */
- if (!GET_IDENTIFIER(__class__))
- goto error;
assert(PySet_Contains(local, __class__) == 1);
if (PySet_Add(newbound, __class__) < 0)
goto error;
}
- /* Recursively call analyze_block() on each child block.
+ /* Recursively call analyze_child_block() on each child block.
newbound, newglobal now contain the names visible in
nested blocks. The free variables in the children will
@@ -782,7 +788,7 @@ analyze_block(PySTEntryObject *ste, PyObject *bound, PyObject *free,
NULL))
goto error;
else if (ste->ste_type == ClassBlock && !analyze_cells(scopes, newfree,
- "__class__"))
+ "@__class__"))
goto error;
/* Records the results of the analysis in the symbol table entry */
if (!update_symbols(ste->ste_symbols, scopes, bound, newfree,
@@ -893,18 +899,15 @@ symtable_warn(struct symtable *st, char *msg, int lineno)
static int
symtable_exit_block(struct symtable *st, void *ast)
{
- Py_ssize_t end;
-
- Py_CLEAR(st->st_cur);
- end = PyList_GET_SIZE(st->st_stack) - 1;
- if (end >= 0) {
- st->st_cur = (PySTEntryObject *)PyList_GET_ITEM(st->st_stack,
- end);
- if (st->st_cur == NULL)
- return 0;
- Py_INCREF(st->st_cur);
- if (PySequence_DelItem(st->st_stack, end) < 0)
+ Py_ssize_t size;
+
+ st->st_cur = NULL;
+ size = PyList_GET_SIZE(st->st_stack);
+ if (size) {
+ if (PyList_SetSlice(st->st_stack, size - 1, size, NULL) < 0)
return 0;
+ if (--size)
+ st->st_cur = (PySTEntryObject *)PyList_GET_ITEM(st->st_stack, size - 1);
}
return 1;
}
@@ -913,23 +916,23 @@ static int
symtable_enter_block(struct symtable *st, identifier name, _Py_block_ty block,
void *ast, int lineno, int col_offset)
{
- PySTEntryObject *prev = NULL;
+ PySTEntryObject *prev = NULL, *ste;
- if (st->st_cur) {
- prev = st->st_cur;
- if (PyList_Append(st->st_stack, (PyObject *)st->st_cur) < 0) {
- return 0;
- }
- Py_DECREF(st->st_cur);
- }
- st->st_cur = ste_new(st, name, block, ast, lineno, col_offset);
- if (st->st_cur == NULL)
+ ste = ste_new(st, name, block, ast, lineno, col_offset);
+ if (ste == NULL)
return 0;
+ if (PyList_Append(st->st_stack, (PyObject *)ste) < 0) {
+ Py_DECREF(ste);
+ return 0;
+ }
+ prev = st->st_cur;
+ /* The entry is owned by the stack. Borrow it for st_cur. */
+ Py_DECREF(ste);
+ st->st_cur = ste;
if (block == ModuleBlock)
st->st_global = st->st_cur->ste_symbols;
if (prev) {
- if (PyList_Append(prev->ste_children,
- (PyObject *)st->st_cur) < 0) {
+ if (PyList_Append(prev->ste_children, (PyObject *)ste) < 0) {
return 0;
}
}
@@ -1023,12 +1026,6 @@ error:
if (!symtable_visit_ ## TYPE((ST), (V))) \
return 0;
-#define VISIT_IN_BLOCK(ST, TYPE, V, S) \
- if (!symtable_visit_ ## TYPE((ST), (V))) { \
- symtable_exit_block((ST), (S)); \
- return 0; \
- }
-
#define VISIT_SEQ(ST, TYPE, SEQ) { \
int i; \
asdl_seq *seq = (SEQ); /* avoid variable capture */ \
@@ -1039,18 +1036,6 @@ error:
} \
}
-#define VISIT_SEQ_IN_BLOCK(ST, TYPE, SEQ, S) { \
- int i; \
- asdl_seq *seq = (SEQ); /* avoid variable capture */ \
- for (i = 0; i < asdl_seq_LEN(seq); i++) { \
- TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, i); \
- if (!symtable_visit_ ## TYPE((ST), elt)) { \
- symtable_exit_block((ST), (S)); \
- return 0; \
- } \
- } \
-}
-
#define VISIT_SEQ_TAIL(ST, TYPE, SEQ, START) { \
int i; \
asdl_seq *seq = (SEQ); /* avoid variable capture */ \
@@ -1061,18 +1046,6 @@ error:
} \
}
-#define VISIT_SEQ_TAIL_IN_BLOCK(ST, TYPE, SEQ, START, S) { \
- int i; \
- asdl_seq *seq = (SEQ); /* avoid variable capture */ \
- for (i = (START); i < asdl_seq_LEN(seq); i++) { \
- TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, i); \
- if (!symtable_visit_ ## TYPE((ST), elt)) { \
- symtable_exit_block((ST), (S)); \
- return 0; \
- } \
- } \
-}
-
#define VISIT_KWONLYDEFAULTS(ST, KW_DEFAULTS) { \
int i = 0; \
asdl_seq *seq = (KW_DEFAULTS); /* avoid variable capture */ \
@@ -1122,8 +1095,8 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
FunctionBlock, (void *)s, s->lineno,
s->col_offset))
return 0;
- VISIT_IN_BLOCK(st, arguments, s->v.FunctionDef.args, s);
- VISIT_SEQ_IN_BLOCK(st, stmt, s->v.FunctionDef.body, s);
+ VISIT(st, arguments, s->v.FunctionDef.args);
+ VISIT_SEQ(st, stmt, s->v.FunctionDef.body);
if (!symtable_exit_block(st, s))
return 0;
break;
@@ -1142,8 +1115,7 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
if (!symtable_enter_block(st, s->v.ClassDef.name, ClassBlock,
(void *)s, s->lineno, s->col_offset))
return 0;
- if (!GET_IDENTIFIER(__class__) ||
- !symtable_add_def(st, __class__, DEF_LOCAL) ||
+ if (!symtable_add_def(st, __class__, DEF_LOCAL) ||
!GET_IDENTIFIER(__locals__) ||
!symtable_add_def(st, __locals__, DEF_PARAM)) {
symtable_exit_block(st, s);
@@ -1151,7 +1123,7 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
}
tmp = st->st_private;
st->st_private = s->v.ClassDef.name;
- VISIT_SEQ_IN_BLOCK(st, stmt, s->v.ClassDef.body, s);
+ VISIT_SEQ(st, stmt, s->v.ClassDef.body);
st->st_private = tmp;
if (!symtable_exit_block(st, s))
return 0;
@@ -1205,19 +1177,16 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
case Raise_kind:
if (s->v.Raise.exc) {
VISIT(st, expr, s->v.Raise.exc);
- if (s->v.Raise.cause) {
- VISIT(st, expr, s->v.Raise.cause);
- }
+ if (s->v.Raise.cause) {
+ VISIT(st, expr, s->v.Raise.cause);
+ }
}
break;
- case TryExcept_kind:
- VISIT_SEQ(st, stmt, s->v.TryExcept.body);
- VISIT_SEQ(st, stmt, s->v.TryExcept.orelse);
- VISIT_SEQ(st, excepthandler, s->v.TryExcept.handlers);
- break;
- case TryFinally_kind:
- VISIT_SEQ(st, stmt, s->v.TryFinally.body);
- VISIT_SEQ(st, stmt, s->v.TryFinally.finalbody);
+ case Try_kind:
+ VISIT_SEQ(st, stmt, s->v.Try.body);
+ VISIT_SEQ(st, stmt, s->v.Try.orelse);
+ VISIT_SEQ(st, excepthandler, s->v.Try.handlers);
+ VISIT_SEQ(st, stmt, s->v.Try.finalbody);
break;
case Assert_kind:
VISIT(st, expr, s->v.Assert.test);
@@ -1305,10 +1274,7 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
/* nothing to do here */
break;
case With_kind:
- VISIT(st, expr, s->v.With.context_expr);
- if (s->v.With.optional_vars) {
- VISIT(st, expr, s->v.With.optional_vars);
- }
+ VISIT_SEQ(st, withitem, s->v.With.items);
VISIT_SEQ(st, stmt, s->v.With.body);
break;
}
@@ -1338,8 +1304,8 @@ symtable_visit_expr(struct symtable *st, expr_ty e)
FunctionBlock, (void *)e, e->lineno,
e->col_offset))
return 0;
- VISIT_IN_BLOCK(st, arguments, e->v.Lambda.args, (void*)e);
- VISIT_IN_BLOCK(st, expr, e->v.Lambda.body, (void*)e);
+ VISIT(st, arguments, e->v.Lambda.args);
+ VISIT(st, expr, e->v.Lambda.body);
if (!symtable_exit_block(st, (void *)e))
return 0;
break;
@@ -1422,8 +1388,7 @@ symtable_visit_expr(struct symtable *st, expr_ty e)
if (e->v.Name.ctx == Load &&
st->st_cur->ste_type == FunctionBlock &&
!PyUnicode_CompareWithASCIIString(e->v.Name.id, "super")) {
- if (!GET_IDENTIFIER(__class__) ||
- !symtable_add_def(st, __class__, USE))
+ if (!symtable_add_def(st, __class__, USE))
return 0;
}
break;
@@ -1540,6 +1505,16 @@ symtable_visit_excepthandler(struct symtable *st, excepthandler_ty eh)
return 1;
}
+static int
+symtable_visit_withitem(struct symtable *st, withitem_ty item)
+{
+ VISIT(st, expr, item->context_expr);
+ if (item->optional_vars) {
+ VISIT(st, expr, item->optional_vars);
+ }
+ return 1;
+}
+
static int
symtable_visit_alias(struct symtable *st, alias_ty a)
@@ -1650,13 +1625,12 @@ symtable_handle_comprehension(struct symtable *st, expr_ty e,
symtable_exit_block(st, (void *)e);
return 0;
}
- VISIT_IN_BLOCK(st, expr, outermost->target, (void*)e);
- VISIT_SEQ_IN_BLOCK(st, expr, outermost->ifs, (void*)e);
- VISIT_SEQ_TAIL_IN_BLOCK(st, comprehension,
- generators, 1, (void*)e);
+ VISIT(st, expr, outermost->target);
+ VISIT_SEQ(st, expr, outermost->ifs);
+ VISIT_SEQ_TAIL(st, comprehension, generators, 1);
if (value)
- VISIT_IN_BLOCK(st, expr, value, (void*)e);
- VISIT_IN_BLOCK(st, expr, elt, (void*)e);
+ VISIT(st, expr, value);
+ VISIT(st, expr, elt);
return symtable_exit_block(st, (void *)e);
}
diff --git a/Python/sysmodule.c b/Python/sysmodule.c
index 73dc0dd..b549203 100644
--- a/Python/sysmodule.c
+++ b/Python/sysmodule.c
@@ -17,6 +17,7 @@ Data members:
#include "Python.h"
#include "code.h"
#include "frameobject.h"
+#include "pythread.h"
#include "osdefs.h"
@@ -1177,7 +1178,6 @@ PySys_AddXOption(const wchar_t *s)
PyObject *opts;
PyObject *name = NULL, *value = NULL;
const wchar_t *name_end;
- int r;
opts = get_xoptions();
if (opts == NULL)
@@ -1195,7 +1195,7 @@ PySys_AddXOption(const wchar_t *s)
}
if (name == NULL || value == NULL)
goto error;
- r = PyDict_SetItem(opts, name, value);
+ PyDict_SetItem(opts, name, value);
Py_DECREF(name);
Py_DECREF(value);
return;
@@ -1252,21 +1252,21 @@ PyDoc_STR(
"\n\
Static objects:\n\
\n\
-float_info -- a dict with information about the float implementation.\n\
+builtin_module_names -- tuple of module names built into this interpreter\n\
+copyright -- copyright notice pertaining to this interpreter\n\
+exec_prefix -- prefix used to find the machine-specific Python library\n\
+executable -- pathname of this Python interpreter\n\
+float_info -- a struct sequence with information about the float implementation.\n\
+float_repr_style -- string indicating the style of repr() output for floats\n\
+hexversion -- version information encoded as a single integer\n\
int_info -- a struct sequence with information about the int implementation.\n\
maxsize -- the largest supported length of containers.\n\
maxunicode -- the largest supported character\n\
-builtin_module_names -- tuple of module names built into this interpreter\n\
-subversion -- subversion information of the build as tuple\n\
-version -- the version of this interpreter as a string\n\
-version_info -- version information as a named tuple\n\
-hexversion -- version information encoded as a single integer\n\
-copyright -- copyright notice pertaining to this interpreter\n\
platform -- platform identifier\n\
-executable -- pathname of this Python interpreter\n\
prefix -- prefix used to find the Python library\n\
-exec_prefix -- prefix used to find the machine-specific Python library\n\
-float_repr_style -- string indicating the style of repr() output for floats\n\
+thread_info -- a struct sequence with information about the thread implementation.\n\
+version -- the version of this interpreter as a string\n\
+version_info -- version information as a named tuple\n\
"
)
#ifdef MS_WINDOWS
@@ -1305,43 +1305,6 @@ settrace() -- set the global debug tracing function\n\
)
/* end of sys_doc */ ;
-/* Subversion branch and revision management */
-static int svn_initialized;
-static char patchlevel_revision[50]; /* Just the number */
-static char branch[50];
-static char shortbranch[50];
-static const char *svn_revision;
-
-static void
-svnversion_init(void)
-{
- if (svn_initialized)
- return;
-
- svn_initialized = 1;
- *patchlevel_revision = '\0';
- strcpy(branch, "");
- strcpy(shortbranch, "unknown");
- svn_revision = "";
-}
-
-/* Return svnversion output if available.
- Else return Revision of patchlevel.h if on branch.
- Else return empty string */
-const char*
-Py_SubversionRevision()
-{
- svnversion_init();
- return svn_revision;
-}
-
-const char*
-Py_SubversionShortBranch()
-{
- svnversion_init();
- return shortbranch;
-}
-
PyDoc_STRVAR(flags__doc__,
"sys.flags\n\
@@ -1352,7 +1315,6 @@ static PyTypeObject FlagsType;
static PyStructSequence_Field flags_fields[] = {
{"debug", "-d"},
- {"division_warning", "-Q"},
{"inspect", "-i"},
{"interactive", "-i"},
{"optimize", "-O or -OO"},
@@ -1376,9 +1338,9 @@ static PyStructSequence_Desc flags_desc = {
flags__doc__, /* doc */
flags_fields, /* fields */
#ifdef RISCOS
- 13
-#else
12
+#else
+ 11
#endif
};
@@ -1396,7 +1358,6 @@ make_flags(void)
PyStructSequence_SET_ITEM(seq, pos++, PyLong_FromLong(flag))
SetFlag(Py_DebugFlag);
- SetFlag(Py_DivisionWarningFlag);
SetFlag(Py_InspectFlag);
SetFlag(Py_InteractiveFlag);
SetFlag(Py_OptimizeFlag);
@@ -1545,10 +1506,6 @@ _PySys_Init(void)
PyUnicode_FromString(Py_GetVersion()));
SET_SYS_FROM_STRING("hexversion",
PyLong_FromLong(PY_VERSION_HEX));
- svnversion_init();
- SET_SYS_FROM_STRING("subversion",
- Py_BuildValue("(sss)", "CPython", branch,
- svn_revision));
SET_SYS_FROM_STRING("_mercurial",
Py_BuildValue("(szz)", "CPython", _Py_hgidentifier(),
_Py_hgversion()));
@@ -1656,6 +1613,10 @@ _PySys_Init(void)
PyUnicode_FromString("legacy"));
#endif
+#ifdef WITH_THREAD
+ SET_SYS_FROM_STRING("thread_info", PyThread_GetInfo());
+#endif
+
#undef SET_SYS_FROM_STRING
if (PyErr_Occurred())
return NULL;
diff --git a/Python/thread.c b/Python/thread.c
index d224046..c7d17d6 100644
--- a/Python/thread.c
+++ b/Python/thread.c
@@ -7,7 +7,6 @@
#include "Python.h"
-
#ifndef _POSIX_THREADS
/* This means pthreads are not implemented in libc headers, hence the macro
not present in unistd.h. But they still can be implemented as an external
@@ -100,6 +99,7 @@ static size_t _pythread_stacksize = 0;
#endif
#ifdef SOLARIS_THREADS
+#define PYTHREAD_NAME "solaris"
#include "thread_solaris.h"
#endif
@@ -115,6 +115,7 @@ static size_t _pythread_stacksize = 0;
#endif
#ifdef _POSIX_THREADS
+#define PYTHREAD_NAME "pthread"
#include "thread_pthread.h"
#endif
@@ -124,14 +125,17 @@ static size_t _pythread_stacksize = 0;
#endif
#ifdef NT_THREADS
+#define PYTHREAD_NAME "nt"
#include "thread_nt.h"
#endif
#ifdef OS2_THREADS
+#define PYTHREAD_NAME "os2"
#include "thread_os2.h"
#endif
#ifdef PLAN9_THREADS
+#define PYTHREAD_NAME "plan9"
#include "thread_plan9.h"
#endif
@@ -409,3 +413,84 @@ PyThread_ReInitTLS(void)
}
#endif /* Py_HAVE_NATIVE_TLS */
+
+PyDoc_STRVAR(threadinfo__doc__,
+"sys.thread_info\n\
+\n\
+A struct sequence holding information about the thread implementation.");
+
+static PyStructSequence_Field threadinfo_fields[] = {
+ {"name", "name of the thread implementation"},
+ {"lock", "name of the lock implementation"},
+ {"version", "name and version of the thread library"},
+ {0}
+};
+
+static PyStructSequence_Desc threadinfo_desc = {
+ "sys.thread_info", /* name */
+ threadinfo__doc__, /* doc */
+ threadinfo_fields, /* fields */
+ 3
+};
+
+static PyTypeObject ThreadInfoType;
+
+PyObject*
+PyThread_GetInfo(void)
+{
+ PyObject *threadinfo, *value;
+ int pos = 0;
+#if (defined(_POSIX_THREADS) && defined(HAVE_CONFSTR) \
+ && defined(_CS_GNU_LIBPTHREAD_VERSION))
+ char buffer[255];
+ int len;
+#endif
+
+ if (ThreadInfoType.tp_name == 0)
+ PyStructSequence_InitType(&ThreadInfoType, &threadinfo_desc);
+
+ threadinfo = PyStructSequence_New(&ThreadInfoType);
+ if (threadinfo == NULL)
+ return NULL;
+
+ value = PyUnicode_FromString(PYTHREAD_NAME);
+ if (value == NULL) {
+ Py_DECREF(threadinfo);
+ return NULL;
+ }
+ PyStructSequence_SET_ITEM(threadinfo, pos++, value);
+
+#ifdef _POSIX_THREADS
+#ifdef USE_SEMAPHORES
+ value = PyUnicode_FromString("semaphore");
+#else
+ value = PyUnicode_FromString("mutex+cond");
+#endif
+ if (value == NULL) {
+ Py_DECREF(threadinfo);
+ return NULL;
+ }
+#else
+ Py_INCREF(Py_None);
+ value = Py_None;
+#endif
+ PyStructSequence_SET_ITEM(threadinfo, pos++, value);
+
+#if (defined(_POSIX_THREADS) && defined(HAVE_CONFSTR) \
+ && defined(_CS_GNU_LIBPTHREAD_VERSION))
+ value = NULL;
+ len = confstr(_CS_GNU_LIBPTHREAD_VERSION, buffer, sizeof(buffer));
+ if (1 < len && len < sizeof(buffer)) {
+ value = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
+ if (value == NULL)
+ PyErr_Clear();
+ }
+ if (value == NULL)
+#endif
+ {
+ Py_INCREF(Py_None);
+ value = Py_None;
+ }
+ PyStructSequence_SET_ITEM(threadinfo, pos++, value);
+ return threadinfo;
+}
diff --git a/Python/thread_pth.h b/Python/thread_pth.h
index 82a00e7..5704266 100644
--- a/Python/thread_pth.h
+++ b/Python/thread_pth.h
@@ -69,9 +69,8 @@ long PyThread_get_thread_ident(void)
volatile pth_t threadid;
if (!initialized)
PyThread_init_thread();
- /* Jump through some hoops for Alpha OSF/1 */
threadid = pth_self();
- return (long) *(long *) &threadid;
+ return (long) threadid;
}
void PyThread_exit_thread(void)
diff --git a/Python/thread_pthread.h b/Python/thread_pthread.h
index 3efccf6..fe9dde6 100644
--- a/Python/thread_pthread.h
+++ b/Python/thread_pthread.h
@@ -144,7 +144,10 @@ typedef struct {
* Initialization.
*/
-#ifdef _HAVE_BSDI
+/* On FreeBSD6, pthread_kill() doesn't work on the main thread before
+ the creation of the first thread */
+#if defined(_HAVE_BSDI) \
+ || (defined(__FreeBSD__) && __FreeBSD_version < 700000)
static
void _noop(void)
{
@@ -240,8 +243,7 @@ PyThread_start_new_thread(void (*func)(void *), void *arg)
hosed" because:
- It does not guarantee the promise that a non-zero integer is returned.
- The cast to long is inherently unsafe.
- - It is not clear that the 'volatile' (for AIX?) and ugly casting in the
- latter return statement (for Alpha OSF/1) are any longer necessary.
+ - It is not clear that the 'volatile' (for AIX?) are any longer necessary.
*/
long
PyThread_get_thread_ident(void)
@@ -249,13 +251,8 @@ PyThread_get_thread_ident(void)
volatile pthread_t threadid;
if (!initialized)
PyThread_init_thread();
- /* Jump through some hoops for Alpha OSF/1 */
threadid = pthread_self();
-#if SIZEOF_PTHREAD_T <= SIZEOF_LONG
return (long) threadid;
-#else
- return (long) *(long *) &threadid;
-#endif
}
void
diff --git a/Python/traceback.c b/Python/traceback.c
index 59bb3f0..e74a147 100644
--- a/Python/traceback.c
+++ b/Python/traceback.c
@@ -13,8 +13,13 @@
#define OFF(x) offsetof(PyTracebackObject, x)
-/* Method from Parser/tokenizer.c */
-extern char * PyTokenizer_FindEncoding(int);
+#define PUTS(fd, str) write(fd, str, strlen(str))
+#define MAX_STRING_LENGTH 100
+#define MAX_FRAME_DEPTH 100
+#define MAX_NTHREADS 100
+
+/* Function from Parser/tokenizer.c */
+extern char * PyTokenizer_FindEncodingFilename(int, PyObject *);
static PyObject *
tb_dir(PyTracebackObject *self)
@@ -246,7 +251,7 @@ _Py_DisplaySourceLine(PyObject *f, PyObject *filename, int lineno, int indent)
/* use the right encoding to decode the file as unicode */
fd = PyObject_AsFileDescriptor(binary);
- found_encoding = PyTokenizer_FindEncoding(fd);
+ found_encoding = PyTokenizer_FindEncodingFilename(fd, filename);
encoding = (found_encoding != NULL) ? found_encoding : "utf-8";
lseek(fd, 0, 0); /* Reset position */
fob = PyObject_CallMethod(io, "TextIOWrapper", "Os", binary, encoding);
@@ -402,3 +407,233 @@ PyTraceBack_Print(PyObject *v, PyObject *f)
err = tb_printinternal((PyTracebackObject *)v, f, limit);
return err;
}
+
+/* Reverse a string. For example, "abcd" becomes "dcba".
+
+ This function is signal safe. */
+
+static void
+reverse_string(char *text, const size_t len)
+{
+ char tmp;
+ size_t i, j;
+ if (len == 0)
+ return;
+ for (i=0, j=len-1; i < j; i++, j--) {
+ tmp = text[i];
+ text[i] = text[j];
+ text[j] = tmp;
+ }
+}
+
+/* Format an integer in range [0; 999999] to decimal,
+ and write it into the file fd.
+
+ This function is signal safe. */
+
+static void
+dump_decimal(int fd, int value)
+{
+ char buffer[7];
+ int len;
+ if (value < 0 || 999999 < value)
+ return;
+ len = 0;
+ do {
+ buffer[len] = '0' + (value % 10);
+ value /= 10;
+ len++;
+ } while (value);
+ reverse_string(buffer, len);
+ write(fd, buffer, len);
+}
+
+/* Format an integer in range [0; 0xffffffff] to hexdecimal of 'width' digits,
+ and write it into the file fd.
+
+ This function is signal safe. */
+
+static void
+dump_hexadecimal(int width, unsigned long value, int fd)
+{
+ const char *hexdigits = "0123456789abcdef";
+ int len;
+ char buffer[sizeof(unsigned long) * 2 + 1];
+ len = 0;
+ do {
+ buffer[len] = hexdigits[value & 15];
+ value >>= 4;
+ len++;
+ } while (len < width || value);
+ reverse_string(buffer, len);
+ write(fd, buffer, len);
+}
+
+/* Write an unicode object into the file fd using ascii+backslashreplace.
+
+ This function is signal safe. */
+
+static void
+dump_ascii(int fd, PyObject *text)
+{
+ Py_ssize_t i, size;
+ int truncated;
+ Py_UNICODE *u;
+ char c;
+
+ size = PyUnicode_GET_SIZE(text);
+ u = PyUnicode_AS_UNICODE(text);
+
+ if (MAX_STRING_LENGTH < size) {
+ size = MAX_STRING_LENGTH;
+ truncated = 1;
+ }
+ else
+ truncated = 0;
+
+ for (i=0; i < size; i++, u++) {
+ if (*u < 128) {
+ c = (char)*u;
+ write(fd, &c, 1);
+ }
+ else if (*u < 256) {
+ PUTS(fd, "\\x");
+ dump_hexadecimal(2, *u, fd);
+ }
+ else
+#ifdef Py_UNICODE_WIDE
+ if (*u < 65536)
+#endif
+ {
+ PUTS(fd, "\\u");
+ dump_hexadecimal(4, *u, fd);
+#ifdef Py_UNICODE_WIDE
+ }
+ else {
+ PUTS(fd, "\\U");
+ dump_hexadecimal(8, *u, fd);
+#endif
+ }
+ }
+ if (truncated)
+ PUTS(fd, "...");
+}
+
+/* Write a frame into the file fd: "File "xxx", line xxx in xxx".
+
+ This function is signal safe. */
+
+static void
+dump_frame(int fd, PyFrameObject *frame)
+{
+ PyCodeObject *code;
+ int lineno;
+
+ code = frame->f_code;
+ PUTS(fd, " File ");
+ if (code != NULL && code->co_filename != NULL
+ && PyUnicode_Check(code->co_filename))
+ {
+ write(fd, "\"", 1);
+ dump_ascii(fd, code->co_filename);
+ write(fd, "\"", 1);
+ } else {
+ PUTS(fd, "???");
+ }
+
+ /* PyFrame_GetLineNumber() was introduced in Python 2.7.0 and 3.2.0 */
+ lineno = PyCode_Addr2Line(frame->f_code, frame->f_lasti);
+ PUTS(fd, ", line ");
+ dump_decimal(fd, lineno);
+ PUTS(fd, " in ");
+
+ if (code != NULL && code->co_name != NULL
+ && PyUnicode_Check(code->co_name))
+ dump_ascii(fd, code->co_name);
+ else
+ PUTS(fd, "???");
+
+ write(fd, "\n", 1);
+}
+
+static void
+dump_traceback(int fd, PyThreadState *tstate, int write_header)
+{
+ PyFrameObject *frame;
+ unsigned int depth;
+
+ if (write_header)
+ PUTS(fd, "Traceback (most recent call first):\n");
+
+ frame = _PyThreadState_GetFrame(tstate);
+ if (frame == NULL)
+ return;
+
+ depth = 0;
+ while (frame != NULL) {
+ if (MAX_FRAME_DEPTH <= depth) {
+ PUTS(fd, " ...\n");
+ break;
+ }
+ if (!PyFrame_Check(frame))
+ break;
+ dump_frame(fd, frame);
+ frame = frame->f_back;
+ depth++;
+ }
+}
+
+void
+_Py_DumpTraceback(int fd, PyThreadState *tstate)
+{
+ dump_traceback(fd, tstate, 1);
+}
+
+/* Write the thread identifier into the file 'fd': "Current thread 0xHHHH:\" if
+ is_current is true, "Thread 0xHHHH:\n" otherwise.
+
+ This function is signal safe. */
+
+static void
+write_thread_id(int fd, PyThreadState *tstate, int is_current)
+{
+ if (is_current)
+ PUTS(fd, "Current thread 0x");
+ else
+ PUTS(fd, "Thread 0x");
+ dump_hexadecimal(sizeof(long)*2, (unsigned long)tstate->thread_id, fd);
+ PUTS(fd, ":\n");
+}
+
+const char*
+_Py_DumpTracebackThreads(int fd, PyInterpreterState *interp,
+ PyThreadState *current_thread)
+{
+ PyThreadState *tstate;
+ unsigned int nthreads;
+
+ /* Get the current interpreter from the current thread */
+ tstate = PyInterpreterState_ThreadHead(interp);
+ if (tstate == NULL)
+ return "unable to get the thread head state";
+
+ /* Dump the traceback of each thread */
+ tstate = PyInterpreterState_ThreadHead(interp);
+ nthreads = 0;
+ do
+ {
+ if (nthreads != 0)
+ write(fd, "\n", 1);
+ if (nthreads >= MAX_NTHREADS) {
+ PUTS(fd, "...\n");
+ break;
+ }
+ write_thread_id(fd, tstate, tstate == current_thread);
+ dump_traceback(fd, tstate, 0);
+ tstate = PyThreadState_Next(tstate);
+ nthreads++;
+ } while (tstate != NULL);
+
+ return NULL;
+}
+