diff options
author | Jeremy Hylton <jeremy@alum.mit.edu> | 2003-01-31 18:33:18 (GMT) |
---|---|---|
committer | Jeremy Hylton <jeremy@alum.mit.edu> | 2003-01-31 18:33:18 (GMT) |
commit | 4f0dcc9a9a4629607d4fff79912e8d0c86cd3914 (patch) | |
tree | bba33e033f6a51fec1c01a79a5f6e931f65e44f2 /Python | |
parent | 8f24cdc0d5e30e2f924ed2e8a71400fa87a70983 (diff) | |
download | cpython-4f0dcc9a9a4629607d4fff79912e8d0c86cd3914.zip cpython-4f0dcc9a9a4629607d4fff79912e8d0c86cd3914.tar.gz cpython-4f0dcc9a9a4629607d4fff79912e8d0c86cd3914.tar.bz2 |
Provide __module__ attributes for functions defined in C and Python.
__module__ is the string name of the module the function was defined
in, just like __module__ of classes. In some cases, particularly for
C functions, the __module__ may be None.
Change PyCFunction_New() from a function to a macro, but keep an
unused copy of the function around so that we don't change the binary
API.
Change pickle's save_global() to use whichmodule() if __module__ is
None, but add the __module__ logic to whichmodule() since it might be
used outside of pickle.
Diffstat (limited to 'Python')
-rw-r--r-- | Python/exceptions.c | 20 | ||||
-rw-r--r-- | Python/modsupport.c | 16 |
2 files changed, 28 insertions, 8 deletions
diff --git a/Python/exceptions.c b/Python/exceptions.c index 16b6738..0080694 100644 --- a/Python/exceptions.c +++ b/Python/exceptions.c @@ -126,22 +126,27 @@ Exception\n\ static int populate_methods(PyObject *klass, PyObject *dict, PyMethodDef *methods) { + PyObject *module; + int status = -1; + if (!methods) return 0; + module = PyString_FromString("exceptions"); + if (!module) + return 0; while (methods->ml_name) { /* get a wrapper for the built-in function */ - PyObject *func = PyCFunction_New(methods, NULL); + PyObject *func = PyCFunction_NewEx(methods, NULL, module); PyObject *meth; - int status; if (!func) - return -1; + goto status; /* turn the function into an unbound method */ if (!(meth = PyMethod_New(func, NULL, klass))) { Py_DECREF(func); - return -1; + goto status; } /* add method to dictionary */ @@ -151,11 +156,14 @@ populate_methods(PyObject *klass, PyObject *dict, PyMethodDef *methods) /* stop now if an error occurred, otherwise do the next method */ if (status) - return status; + goto status; methods++; } - return 0; + status = 0; + status: + Py_DECREF(module); + return status; } diff --git a/Python/modsupport.c b/Python/modsupport.c index bca3d6f..41e0c82 100644 --- a/Python/modsupport.c +++ b/Python/modsupport.c @@ -33,7 +33,7 @@ PyObject * Py_InitModule4(char *name, PyMethodDef *methods, char *doc, PyObject *passthrough, int module_api_version) { - PyObject *m, *d, *v; + PyObject *m, *d, *v, *n; PyMethodDef *ml; if (!Py_IsInitialized()) Py_FatalError("Interpreter not initialized (version mismatch?)"); @@ -46,6 +46,15 @@ Py_InitModule4(char *name, PyMethodDef *methods, char *doc, if (PyErr_Warn(PyExc_RuntimeWarning, message)) return NULL; } + /* Make sure name is fully qualified. + + This is a bit of a hack: when the shared library is loaded, + the module name is "package.module", but the module calls + Py_InitModule*() with just "module" for the name. The shared + library loader squirrels away the true name of the module in + _Py_PackageContext, and Py_InitModule*() will substitute this + (if the name actually matches). + */ if (_Py_PackageContext != NULL) { char *p = strrchr(_Py_PackageContext, '.'); if (p != NULL && strcmp(name, p+1) == 0) { @@ -57,6 +66,9 @@ Py_InitModule4(char *name, PyMethodDef *methods, char *doc, return NULL; d = PyModule_GetDict(m); if (methods != NULL) { + n = PyString_FromString(name); + if (n == NULL) + return NULL; for (ml = methods; ml->ml_name != NULL; ml++) { if ((ml->ml_flags & METH_CLASS) || (ml->ml_flags & METH_STATIC)) { @@ -65,7 +77,7 @@ Py_InitModule4(char *name, PyMethodDef *methods, char *doc, " METH_CLASS or METH_STATIC"); return NULL; } - v = PyCFunction_New(ml, passthrough); + v = PyCFunction_NewEx(ml, passthrough, n); if (v == NULL) return NULL; if (PyDict_SetItemString(d, ml->ml_name, v) != 0) { |