[Python-checkins] python/dist/src/Python exceptions.c,1.42,1.43 modsupport.c,2.64,2.65

jhylton@users.sourceforge.net jhylton@users.sourceforge.net
Fri, 31 Jan 2003 10:33:20 -0800


Update of /cvsroot/python/python/dist/src/Python
In directory sc8-pr-cvs1:/tmp/cvs-serv18557/Python

Modified Files:
	exceptions.c modsupport.c 
Log Message:
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.



Index: exceptions.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/exceptions.c,v
retrieving revision 1.42
retrieving revision 1.43
diff -C2 -d -r1.42 -r1.43
*** exceptions.c	6 Dec 2002 12:48:53 -0000	1.42
--- exceptions.c	31 Jan 2003 18:33:18 -0000	1.43
***************
*** 127,146 ****
  populate_methods(PyObject *klass, PyObject *dict, PyMethodDef *methods)
  {
      if (!methods)
  	return 0;
  
      while (methods->ml_name) {
  	/* get a wrapper for the built-in function */
! 	PyObject *func = PyCFunction_New(methods, NULL);
  	PyObject *meth;
- 	int status;
  
  	if (!func)
! 	    return -1;
  
  	/* turn the function into an unbound method */
  	if (!(meth = PyMethod_New(func, NULL, klass))) {
  	    Py_DECREF(func);
! 	    return -1;
  	}
  
--- 127,151 ----
  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_NewEx(methods, NULL, module);
  	PyObject *meth;
  
  	if (!func)
! 	    goto status;
  
  	/* turn the function into an unbound method */
  	if (!(meth = PyMethod_New(func, NULL, klass))) {
  	    Py_DECREF(func);
! 	    goto status;
  	}
  
***************
*** 152,160 ****
  	/* stop now if an error occurred, otherwise do the next method */
  	if (status)
! 	    return status;
  
  	methods++;
      }
!     return 0;
  }
  
--- 157,168 ----
  	/* stop now if an error occurred, otherwise do the next method */
  	if (status)
! 	    goto status;
  
  	methods++;
      }
!     status = 0;
!  status:
!     Py_DECREF(module);
!     return status;
  }
  

Index: modsupport.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/modsupport.c,v
retrieving revision 2.64
retrieving revision 2.65
diff -C2 -d -r2.64 -r2.65
*** modsupport.c	30 Jan 2003 15:08:25 -0000	2.64
--- modsupport.c	31 Jan 2003 18:33:18 -0000	2.65
***************
*** 34,38 ****
  	       PyObject *passthrough, int module_api_version)
  {
! 	PyObject *m, *d, *v;
  	PyMethodDef *ml;
  	if (!Py_IsInitialized())
--- 34,38 ----
  	       PyObject *passthrough, int module_api_version)
  {
! 	PyObject *m, *d, *v, *n;
  	PyMethodDef *ml;
  	if (!Py_IsInitialized())
***************
*** 47,50 ****
--- 47,59 ----
  			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, '.');
***************
*** 58,61 ****
--- 67,73 ----
  	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) ||
***************
*** 66,70 ****
  				return NULL;
  			}
! 			v = PyCFunction_New(ml, passthrough);
  			if (v == NULL)
  				return NULL;
--- 78,82 ----
  				return NULL;
  			}
! 			v = PyCFunction_NewEx(ml, passthrough, n);
  			if (v == NULL)
  				return NULL;