summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
authorJeremy Hylton <jeremy@alum.mit.edu>2003-01-31 18:33:18 (GMT)
committerJeremy Hylton <jeremy@alum.mit.edu>2003-01-31 18:33:18 (GMT)
commit4f0dcc9a9a4629607d4fff79912e8d0c86cd3914 (patch)
treebba33e033f6a51fec1c01a79a5f6e931f65e44f2 /Python
parent8f24cdc0d5e30e2f924ed2e8a71400fa87a70983 (diff)
downloadcpython-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.c20
-rw-r--r--Python/modsupport.c16
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) {