mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 05:31:20 +00:00 
			
		
		
		
	This is my patch
[ 1004703 ] Make func_name writable plus fixing a couple of nits in the documentation changes spotted by MvL and a Misc/NEWS entry.
This commit is contained in:
		
							parent
							
								
									5523c2517f
								
							
						
					
					
						commit
						5e897959db
					
				
					 5 changed files with 94 additions and 46 deletions
				
			
		|  | @ -1682,25 +1682,8 @@ and user-defined functions.  Both support the same operation (to call | |||
| the function), but the implementation is different, hence the | ||||
| different object types. | ||||
| 
 | ||||
| The implementation adds two special read-only attributes: | ||||
| \code{\var{f}.func_code} is a function's \dfn{code | ||||
| object}\obindex{code} (see below) and \code{\var{f}.func_globals} is | ||||
| the dictionary used as the function's global namespace (this is the | ||||
| same as \code{\var{m}.__dict__} where \var{m} is the module in which | ||||
| the function \var{f} was defined). | ||||
| 
 | ||||
| Function objects also support getting and setting arbitrary | ||||
| attributes, which can be used, for example, to attach metadata to | ||||
| functions.  Regular attribute dot-notation is used to get and set such | ||||
| attributes. \emph{Note that the current implementation only supports | ||||
| function attributes on user-defined functions.  Function attributes on | ||||
| built-in functions may be supported in the future.} | ||||
| 
 | ||||
| Functions have another special attribute \code{\var{f}.__dict__} | ||||
| (a.k.a. \code{\var{f}.func_dict}) which contains the namespace used to | ||||
| support function attributes.  \code{__dict__} and \code{func_dict} can | ||||
| be accessed directly or set to a dictionary object.  A function's | ||||
| dictionary cannot be deleted. | ||||
| See the \citetitle[../ref/ref.html]{Python Reference Manual} for more | ||||
| information. | ||||
| 
 | ||||
| \subsubsection{Methods \label{typesmethods}} | ||||
| \obindex{method} | ||||
|  |  | |||
|  | @ -433,28 +433,55 @@ parameter list. | |||
| \obindex{function} | ||||
| \obindex{user-defined function} | ||||
| 
 | ||||
| Special attributes: \member{func_doc} or \member{__doc__} is the | ||||
| function's documentation string, or \code{None} if unavailable; | ||||
| \member{func_name} or \member{__name__} is the function's name; | ||||
| \member{__module__} is the name of the module the function was defined | ||||
| in, or \code{None} if unavailable; | ||||
| \member{func_defaults} is a tuple containing default argument values for | ||||
| those arguments that have defaults, or \code{None} if no arguments | ||||
| have a default value; \member{func_code} is the code object representing | ||||
| the compiled function body; \member{func_globals} is (a reference to) | ||||
| the dictionary that holds the function's global variables --- it | ||||
| defines the global namespace of the module in which the function was | ||||
| defined; \member{func_dict} or \member{__dict__} contains the | ||||
| namespace supporting arbitrary function attributes; | ||||
| \member{func_closure} is \code{None} or a tuple of cells that contain | ||||
| bindings for the function's free variables. | ||||
| Special attributes:  | ||||
| 
 | ||||
| Of these, \member{func_code}, \member{func_defaults},  | ||||
| \member{func_doc}/\member{__doc__}, and | ||||
| \member{func_dict}/\member{__dict__} may be writable; the | ||||
| others can never be changed.  Additional information about a | ||||
| function's definition can be retrieved from its code object; see the | ||||
| description of internal types below. | ||||
| \begin{tableiii}{lll}{member}{Attribute}{Meaning}{} | ||||
|   \lineiii{func_doc}{The function's documentation string, or | ||||
|     \code{None} if unavailable}{Writable} | ||||
| 
 | ||||
|   \lineiii{__doc__}{Another way of spelling | ||||
|     \member{func_doc}}{Writable} | ||||
| 
 | ||||
|   \lineiii{func_name}{The function's name}{Writable} | ||||
| 
 | ||||
|   \lineiii{__name__}{Another way of spelling | ||||
|     \member{func_name}}{Writable} | ||||
| 
 | ||||
|   \lineiii{__module__}{The name of the module the function was defined | ||||
|     in, or \code{None} if unavailable.}{Writable} | ||||
| 
 | ||||
|   \lineiii{func_defaults}{Atuple containing default argument values | ||||
|     for those arguments that have defaults, or \code{None} if no | ||||
|     arguments have a default value}{Writable} | ||||
| 
 | ||||
|   \lineiii{func_code}{The code object representing the compiled | ||||
|     function body.}{Writable} | ||||
| 
 | ||||
|   \lineiii{func_globals}{A reference to the dictionary that holds the | ||||
|     function's global variables --- the global namespace of the module | ||||
|     in which the function was defined.}{Read-only} | ||||
| 
 | ||||
|   \lineiii{func_dict}{The namespace supporting arbitrary function | ||||
|     attributes.}{Writable} | ||||
| 
 | ||||
|   \lineiii{func_closure}{\code{None} or a tuple of cells that contain | ||||
|     bindings for the function's free variables.}{Read-only} | ||||
| \end{tableiii} | ||||
| 
 | ||||
| Most of the attributes labelled ``Writable'' check the type of the | ||||
| assigned value. | ||||
| 
 | ||||
| \versionchanged[\code{func_name} is now writable]{2.4} | ||||
| 
 | ||||
| Function objects also support getting and setting arbitrary | ||||
| attributes, which can be used, for example, to attach metadata to | ||||
| functions.  Regular attribute dot-notation is used to get and set such | ||||
| attributes. \emph{Note that the current implementation only supports | ||||
| function attributes on user-defined functions.  Function attributes on | ||||
| built-in functions may be supported in the future.} | ||||
| 
 | ||||
| Additional information about a function's definition can be retrieved | ||||
| from its code object; see the description of internal types below. | ||||
| 
 | ||||
| \withsubitem{(function attribute)}{ | ||||
|   \ttindex{func_doc} | ||||
|  |  | |||
|  | @ -268,8 +268,15 @@ def test_func_name(): | |||
|     def f(): pass | ||||
|     verify(f.__name__ == "f") | ||||
|     verify(f.func_name == "f") | ||||
|     cantset(f, "func_name", "f") | ||||
|     cantset(f, "__name__", "f") | ||||
|     f.__name__ = "g" | ||||
|     verify(f.__name__ == "g") | ||||
|     verify(f.func_name == "g") | ||||
|     f.func_name = "h" | ||||
|     verify(f.__name__ == "h") | ||||
|     verify(f.func_name == "h") | ||||
|     cantset(f, "func_globals", 1) | ||||
|     cantset(f, "__name__", 1) | ||||
|      | ||||
| 
 | ||||
| def test_func_code(): | ||||
|     def f(): pass | ||||
|  |  | |||
|  | @ -12,6 +12,9 @@ What's New in Python 2.4 alpha 3? | |||
| Core and builtins | ||||
| ----------------- | ||||
| 
 | ||||
| - The ``func_name`` (a.k.a. ``__name__``) attribute of user-defined | ||||
|   functions is now writable. | ||||
| 
 | ||||
| - code_new (a.k.a new.code()) now checks its arguments sufficiently | ||||
|   carefully that passing them on to PyCode_New() won't trigger calls | ||||
|   to Py_FatalError() or PyErr_BadInternalCall().  It is still the case | ||||
|  |  | |||
|  | @ -163,8 +163,6 @@ static PyMemberDef func_memberlist[] = { | |||
|         {"__doc__",       T_OBJECT,     OFF(func_doc), WRITE_RESTRICTED}, | ||||
|         {"func_globals",  T_OBJECT,     OFF(func_globals), | ||||
| 	 RESTRICTED|READONLY}, | ||||
|         {"func_name",     T_OBJECT,     OFF(func_name),         READONLY}, | ||||
|         {"__name__",      T_OBJECT,     OFF(func_name),         READONLY}, | ||||
|         {"__module__",    T_OBJECT,     OFF(func_module), WRITE_RESTRICTED}, | ||||
|         {NULL}  /* Sentinel */ | ||||
| }; | ||||
|  | @ -249,6 +247,36 @@ func_set_code(PyFunctionObject *op, PyObject *value) | |||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static PyObject * | ||||
| func_get_name(PyFunctionObject *op) | ||||
| { | ||||
| 	if (restricted()) | ||||
| 		return NULL; | ||||
| 	Py_INCREF(op->func_name); | ||||
| 	return op->func_name; | ||||
| } | ||||
| 
 | ||||
| static int | ||||
| func_set_name(PyFunctionObject *op, PyObject *value) | ||||
| { | ||||
| 	PyObject *tmp; | ||||
| 
 | ||||
| 	if (restricted()) | ||||
| 		return -1; | ||||
| 	/* Not legal to del f.func_name or to set it to anything
 | ||||
| 	 * other than a string object. */ | ||||
| 	if (value == NULL || !PyString_Check(value)) { | ||||
| 		PyErr_SetString(PyExc_TypeError, | ||||
| 				"func_name must be set to a string object"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 	tmp = op->func_name; | ||||
| 	Py_INCREF(value); | ||||
| 	op->func_name = value; | ||||
| 	Py_DECREF(tmp); | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static PyObject * | ||||
| func_get_defaults(PyFunctionObject *op) | ||||
| { | ||||
|  | @ -291,6 +319,8 @@ static PyGetSetDef func_getsetlist[] = { | |||
| 	 (setter)func_set_defaults}, | ||||
| 	{"func_dict", (getter)func_get_dict, (setter)func_set_dict}, | ||||
| 	{"__dict__", (getter)func_get_dict, (setter)func_set_dict}, | ||||
| 	{"func_name", (getter)func_get_name, (setter)func_set_name}, | ||||
| 	{"__name__", (getter)func_get_name, (setter)func_set_name}, | ||||
| 	{NULL} /* Sentinel */ | ||||
| }; | ||||
| 
 | ||||
|  | @ -416,8 +446,6 @@ func_dealloc(PyFunctionObject *op) | |||
| static PyObject* | ||||
| func_repr(PyFunctionObject *op) | ||||
| { | ||||
| 	if (op->func_name == Py_None) | ||||
| 		return PyString_FromFormat("<anonymous function at %p>", op); | ||||
| 	return PyString_FromFormat("<function %s at %p>", | ||||
| 				   PyString_AsString(op->func_name), | ||||
| 				   op); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Michael W. Hudson
						Michael W. Hudson