Mercurial > cpython-lru_cache-weakref
diff Python/ceval.c @ 15830:e00f718e4d8a legacy-trunk
Two changes to from...import:
1) "from M import X" now works even if M is not a real module; it's
basically a getattr() operation with AttributeError exceptions
changed into ImportError.
2) "from M import *" now looks for M.__all__ to decide which names to
import; if M.__all__ doesn't exist, it uses M.__dict__.keys() but
filters out names starting with '_' as before. Whether or not
__all__ exists, there's no restriction on the type of M.
| author | Guido van Rossum <guido@python.org> |
|---|---|
| date | Fri, 12 Jan 2001 16:24:03 +0000 |
| parents | faaf9f10d849 |
| children | 152814f6cd11 |
line wrap: on
line diff
--- a/Python/ceval.c Fri Jan 12 16:03:05 2001 +0000 +++ b/Python/ceval.c Fri Jan 12 16:24:03 2001 +0000 @@ -3089,48 +3089,72 @@ static PyObject * import_from(PyObject *v, PyObject *name) { - PyObject *w, *x; - if (!PyModule_Check(v)) { - PyErr_SetString(PyExc_TypeError, - "import-from requires a module object"); - return NULL; - } - w = PyModule_GetDict(v); /* TDB: can this not fail ? */ - x = PyDict_GetItem(w, name); - if (x == NULL) { + PyObject *x; + + x = PyObject_GetAttr(v, name); + if (x == NULL && PyErr_ExceptionMatches(PyExc_AttributeError)) { 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; + PyObject *all = PyObject_GetAttrString(v, "__all__"); + PyObject *dict, *name, *value; + int skip_leading_underscores = 0; + int pos, err; - if (!PyModule_Check(v)) { - PyErr_SetString(PyExc_TypeError, - "import-from requires a module object"); - return -1; + if (all == NULL) { + if (!PyErr_ExceptionMatches(PyExc_AttributeError)) + return -1; /* Unexpected error */ + PyErr_Clear(); + dict = PyObject_GetAttrString(v, "__dict__"); + if (dict == NULL) { + if (!PyErr_ExceptionMatches(PyExc_AttributeError)) + return -1; + PyErr_SetString(PyExc_ImportError, + "from-import-* object has no __dict__ and no __all__"); + return -1; + } + all = PyMapping_Keys(dict); + Py_DECREF(dict); + if (all == NULL) + return -1; + skip_leading_underscores = 1; } - 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); + for (pos = 0, err = 0; ; pos++) { + name = PySequence_GetItem(all, pos); + if (name == NULL) { + if (!PyErr_ExceptionMatches(PyExc_IndexError)) + err = -1; + else + PyErr_Clear(); + break; + } + if (skip_leading_underscores && + PyString_Check(name) && + PyString_AS_STRING(name)[0] == '_') + { + Py_DECREF(name); + continue; + } + value = PyObject_GetAttr(v, name); + if (value == NULL) + err = -1; + else + err = PyDict_SetItem(locals, name, value); + Py_DECREF(name); + Py_XDECREF(value); if (err != 0) - return -1; + break; } - return 0; + Py_DECREF(all); + return err; } static PyObject *
