Apply SF patch #101135, adding 'import module as m' and 'from module import

name as n'. By doing some twists and turns, "as" is not a reserved word.

There is a slight change in semantics for 'from module import name' (it will
now honour the 'global' keyword) but only in cases that are explicitly
undocumented.
This commit is contained in:
Thomas Wouters 2000-08-17 22:55:00 +00:00
parent 1d75a79c00
commit 5215225ea1
12 changed files with 970 additions and 818 deletions

View file

@ -66,7 +66,8 @@ static PyObject *apply_slice(PyObject *, PyObject *, PyObject *);
static int assign_slice(PyObject *, PyObject *,
PyObject *, PyObject *);
static PyObject *cmp_outcome(int, PyObject *, PyObject *);
static int import_from(PyObject *, PyObject *, PyObject *);
static PyObject *import_from(PyObject *, PyObject *);
static int import_all_from(PyObject *, PyObject *);
static PyObject *build_class(PyObject *, PyObject *, PyObject *);
static int exec_statement(PyFrameObject *,
PyObject *, PyObject *, PyObject *);
@ -1414,20 +1415,28 @@ eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals,
if (x != NULL) continue;
break;
case IMPORT_FROM:
w = GETNAMEV(oparg);
v = TOP();
case IMPORT_STAR:
v = POP();
PyFrame_FastToLocals(f);
if ((x = f->f_locals) == NULL) {
PyErr_SetString(PyExc_SystemError,
"no locals");
break;
}
err = import_from(x, v, w);
err = import_all_from(x, v);
PyFrame_LocalsToFast(f, 0);
Py_DECREF(v);
if (err == 0) continue;
break;
case IMPORT_FROM:
w = GETNAMEV(oparg);
v = TOP();
x = import_from(v, w);
PUSH(x);
if (x != NULL) continue;
break;
case JUMP_FORWARD:
JUMPBY(oparg);
continue;
@ -2647,43 +2656,51 @@ cmp_outcome(int op, register PyObject *v, register PyObject *w)
return v;
}
static int
import_from(PyObject *locals, PyObject *v, PyObject *name)
static PyObject *
import_from(PyObject *v, PyObject *name)
{
PyObject *w, *x;
if (!PyModule_Check(v)) {
PyErr_SetString(PyExc_TypeError,
"import-from requires module object");
return NULL;
}
w = PyModule_GetDict(v); /* TDB: can this not fail ? */
x = PyDict_GetItem(w, name);
if (x == NULL) {
PyErr_Format(PyExc_ImportError,
"cannot import name %.230s",
PyString_AsString(name));
} else
Py_INCREF(x);
return x;
}
static int
import_all_from(PyObject *locals, PyObject *v)
{
int pos = 0, err;
PyObject *name, *value;
PyObject *w;
if (!PyModule_Check(v)) {
PyErr_SetString(PyExc_TypeError,
"import-from requires module object");
return -1;
}
w = PyModule_GetDict(v);
if (PyString_AsString(name)[0] == '*') {
int pos, err;
PyObject *name, *value;
pos = 0;
while (PyDict_Next(w, &pos, &name, &value)) {
if (!PyString_Check(name) ||
PyString_AsString(name)[0] == '_')
w = PyModule_GetDict(v); /* TBD: can this not fail ? */
while (PyDict_Next(w, &pos, &name, &value)) {
if (!PyString_Check(name) ||
PyString_AsString(name)[0] == '_')
continue;
Py_INCREF(value);
err = PyDict_SetItem(locals, name, value);
Py_DECREF(value);
if (err != 0)
return -1;
}
return 0;
}
else {
x = PyDict_GetItem(w, name);
if (x == NULL) {
PyErr_Format(PyExc_ImportError,
"cannot import name %.230s",
PyString_AsString(name));
Py_INCREF(value);
err = PyDict_SetItem(locals, name, value);
Py_DECREF(value);
if (err != 0)
return -1;
}
else
return PyDict_SetItem(locals, name, x);
}
return 0;
}
static PyObject *
@ -2825,7 +2842,7 @@ find_from_args(PyFrameObject *f, int nexti)
next_instr += nexti;
opcode = (*next_instr++);
if (opcode != IMPORT_FROM) {
if (opcode != IMPORT_FROM && opcode != IMPORT_STAR) {
Py_INCREF(Py_None);
return Py_None;
}
@ -2833,18 +2850,28 @@ find_from_args(PyFrameObject *f, int nexti)
list = PyList_New(0);
if (list == NULL)
return NULL;
do {
oparg = (next_instr[1]<<8) + next_instr[0];
next_instr += 2;
name = Getnamev(f, oparg);
if (PyList_Append(list, name) < 0) {
if (opcode == IMPORT_STAR) {
name = PyString_FromString("*");
if (!name)
Py_DECREF(list);
break;
else {
if (PyList_Append(list, name) < 0)
Py_DECREF(list);
Py_DECREF(name);
}
opcode = (*next_instr++);
} while (opcode == IMPORT_FROM);
} else {
do {
oparg = (next_instr[1]<<8) + next_instr[0];
next_instr += 2;
name = Getnamev(f, oparg);
if (PyList_Append(list, name) < 0) {
Py_DECREF(list);
break;
}
opcode = (*next_instr++);
} while (opcode == IMPORT_FROM);
}
return list;
}

View file

@ -2095,6 +2095,22 @@ com_raise_stmt(struct compiling *c, node *n)
com_pop(c, i);
}
static void
com_from_import(struct compiling *c, node *n)
{
com_addopname(c, IMPORT_FROM, CHILD(n, 0));
com_push(c, 1);
if (NCH(n) > 1) {
if (strcmp(STR(CHILD(n, 1)), "as") != 0) {
com_error(c, PyExc_SyntaxError, "invalid syntax");
return;
}
com_addopname(c, STORE_NAME, CHILD(n, 2));
} else
com_addopname(c, STORE_NAME, CHILD(n, 0));
com_pop(c, 1);
}
static void
com_import_stmt(struct compiling *c, node *n)
{
@ -2107,18 +2123,32 @@ com_import_stmt(struct compiling *c, node *n)
REQ(CHILD(n, 1), dotted_name);
com_addopname(c, IMPORT_NAME, CHILD(n, 1));
com_push(c, 1);
for (i = 3; i < NCH(n); i += 2)
com_addopname(c, IMPORT_FROM, CHILD(n, i));
com_addbyte(c, POP_TOP);
if (TYPE(CHILD(n, 3)) == STAR)
com_addbyte(c, IMPORT_STAR);
else {
for (i = 3; i < NCH(n); i += 2)
com_from_import(c, CHILD(n, i));
com_addbyte(c, POP_TOP);
}
com_pop(c, 1);
}
else {
/* 'import' ... */
for (i = 1; i < NCH(n); i += 2) {
REQ(CHILD(n, i), dotted_name);
com_addopname(c, IMPORT_NAME, CHILD(n, i));
node *subn = CHILD(n, i);
REQ(subn, dotted_as_name);
com_addopname(c, IMPORT_NAME, CHILD(subn, 0));
com_push(c, 1);
com_addopname(c, STORE_NAME, CHILD(CHILD(n, i), 0));
if (NCH(subn) > 1) {
if (strcmp(STR(CHILD(subn, 1)), "as") != 0) {
com_error(c, PyExc_SyntaxError,
"invalid syntax");
return;
}
com_addopname(c, STORE_NAME, CHILD(subn, 2));
} else
com_addopname(c, STORE_NAME,
CHILD(CHILD(subn, 0),0));
com_pop(c, 1);
}
}
@ -3295,12 +3325,14 @@ optimize(struct compiling *c)
case IMPORT_FROM:
com_addlocal_o(c, GETNAMEOBJ(oparg));
break;
case IMPORT_STAR:
case EXEC_STMT:
c->c_flags &= ~CO_OPTIMIZED;
break;
}
}
/* TBD: Is this still necessary ? */
if (PyDict_GetItemString(c->c_locals, "*") != NULL)
c->c_flags &= ~CO_OPTIMIZED;

File diff suppressed because it is too large Load diff

View file

@ -66,7 +66,7 @@ extern time_t PyOS_GetLastModificationTime(char *, FILE *);
/* XXX Perhaps the magic number should be frozen and a version field
added to the .pyc file header? */
/* New way to come up with the magic number: (YEAR-1995), MONTH, DAY */
#define MAGIC (50811 | ((long)'\r'<<16) | ((long)'\n'<<24))
#define MAGIC (50815 | ((long)'\r'<<16) | ((long)'\n'<<24))
/* Magic word as global; note that _PyImport_Init() can change the
value of this global to accommodate for alterations of how the