diff Python/ceval.c @ 14038:18385172fac0 legacy-trunk

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.
author Thomas Wouters <thomas@python.org>
date Thu, 17 Aug 2000 22:55:00 +0000
parents 4eaa463c031a
children 03401af36b5c
line wrap: on
line diff
--- a/Python/ceval.c	Thu Aug 17 22:37:32 2000 +0000
+++ b/Python/ceval.c	Thu Aug 17 22:55:00 2000 +0000
@@ -66,7 +66,8 @@
 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 @@
 			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 @@
 	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;
+		Py_INCREF(value);
+		err = PyDict_SetItem(locals, name, value);
+		Py_DECREF(value);
+		if (err != 0)
+			return -1;
 	}
-	else {
-		x = PyDict_GetItem(w, name);
-		if (x == NULL) {
-			PyErr_Format(PyExc_ImportError, 
-				     "cannot import name %.230s",
-				     PyString_AsString(name));
-			return -1;
-		}
-		else
-			return PyDict_SetItem(locals, name, x);
-	}
+	return 0;
 }
 
 static PyObject *
@@ -2825,7 +2842,7 @@
 	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 @@
 	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;
 }