[Python-checkins] CVS: python/dist/src/Python ceval.c,2.275,2.276 compile.c,2.223,2.224 structmember.c,2.20,2.21 symtable.c,2.5,2.6

Guido van Rossum gvanrossum@users.sourceforge.net
2001年9月20日 13:46:21 -0700


Update of /cvsroot/python/python/dist/src/Python
In directory usw-pr-cvs1:/tmp/cvs-serv25248/Python
Modified Files:
	ceval.c compile.c structmember.c symtable.c 
Log Message:
Add optional docstrings to member descriptors. For backwards
compatibility, this required all places where an array of "struct
memberlist" structures was declared that is referenced from a type's
tp_members slot to change the type of the structure to PyMemberDef;
"struct memberlist" is now only used by old code that still calls
PyMember_Get/Set. The code in PyObject_GenericGetAttr/SetAttr now
calls the new APIs PyMember_GetOne/SetOne, which take a PyMemberDef
argument.
As examples, I added actual docstrings to the attributes of a few
types: file, complex, instance method, super, and xxsubtype.spamlist.
Also converted the symtable to new style getattr.
Index: ceval.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v
retrieving revision 2.275
retrieving revision 2.276
diff -C2 -d -r2.275 -r2.276
*** ceval.c	2001年09月13日 16:56:43	2.275
--- ceval.c	2001年09月20日 20:46:19	2.276
***************
*** 193,197 ****
 };
 
! static struct memberlist gen_memberlist[] = {
 	{"gi_frame",	T_OBJECT, offsetof(genobject, gi_frame),	RO},
 	{"gi_running",	T_INT, offsetof(genobject, gi_running),	RO},
--- 193,197 ----
 };
 
! static PyMemberDef gen_memberlist[] = {
 	{"gi_frame",	T_OBJECT, offsetof(genobject, gi_frame),	RO},
 	{"gi_running",	T_INT, offsetof(genobject, gi_running),	RO},
Index: compile.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/compile.c,v
retrieving revision 2.223
retrieving revision 2.224
diff -C2 -d -r2.223 -r2.224
*** compile.c	2001年09月14日 20:08:07	2.223
--- compile.c	2001年09月20日 20:46:19	2.224
***************
*** 74,78 ****
 #define OFF(x) offsetof(PyCodeObject, x)
 
! static struct memberlist code_memberlist[] = {
 	{"co_argcount",	T_INT,		OFF(co_argcount),	READONLY},
 	{"co_nlocals",	T_INT,		OFF(co_nlocals),	READONLY},
--- 74,78 ----
 #define OFF(x) offsetof(PyCodeObject, x)
 
! static PyMemberDef code_memberlist[] = {
 	{"co_argcount",	T_INT,		OFF(co_argcount),	READONLY},
 	{"co_nlocals",	T_INT,		OFF(co_nlocals),	READONLY},
Index: structmember.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/structmember.c,v
retrieving revision 2.20
retrieving revision 2.21
diff -C2 -d -r2.20 -r2.21
*** structmember.c	2001年09月17日 19:28:08	2.20
--- structmember.c	2001年09月20日 20:46:19	2.21
***************
*** 33,257 ****
 {
 	struct memberlist *l;
! 	
 	if (strcmp(name, "__members__") == 0)
 		return listmembers(mlist);
 	for (l = mlist; l->name != NULL; l++) {
 		if (strcmp(l->name, name) == 0) {
! 			PyObject *v;
! 			if ((l->flags & READ_RESTRICTED) &&
! 			 PyEval_GetRestricted()) {
! 				PyErr_SetString(PyExc_RuntimeError,
! 						"restricted attribute");
! 				return NULL;
! 			}
! 			addr += l->offset;
! 			switch (l->type) {
! 			case T_BYTE:
! 				v = PyInt_FromLong((long)
! 						 (((*(char*)addr & 0xff)
! 						 ^ 0x80) - 0x80));
! 				break;
! 			case T_UBYTE:
! 				v = PyInt_FromLong((long) *(char*)addr & 0xff);
! 				break;
! 			case T_SHORT:
! 				v = PyInt_FromLong((long) *(short*)addr);
! 				break;
! 			case T_USHORT:
! 				v = PyInt_FromLong((long)
! 						 *(unsigned short*)addr);
! 				break;
! 			case T_INT:
! 				v = PyInt_FromLong((long) *(int*)addr);
! 				break;
! 			case T_UINT:
! 				v = PyInt_FromLong((long)
! 						 *(unsigned int*)addr);
! 				break;
! 			case T_LONG:
! 				v = PyInt_FromLong(*(long*)addr);
! 				break;
! 			case T_ULONG:
! 				v = PyLong_FromDouble((double)
! 						 *(unsigned long*)addr);
! 				break;
! 			case T_FLOAT:
! 				v = PyFloat_FromDouble((double)*(float*)addr);
! 				break;
! 			case T_DOUBLE:
! 				v = PyFloat_FromDouble(*(double*)addr);
! 				break;
! 			case T_STRING:
! 				if (*(char**)addr == NULL) {
! 					Py_INCREF(Py_None);
! 					v = Py_None;
! 				}
! 				else
! 					v = PyString_FromString(*(char**)addr);
! 				break;
! 			case T_STRING_INPLACE:
! 				v = PyString_FromString((char*)addr);
! 				break;
! #ifdef macintosh
! 			case T_PSTRING:
! 				if (*(char**)addr == NULL) {
! 					Py_INCREF(Py_None);
! 					v = Py_None;
! 				}
! 				else
! 					v = PyString_FromStringAndSize(
! 						(*(char**)addr)+1,
! 						**(unsigned char**)addr);
! 				break;
! 			case T_PSTRING_INPLACE:
! 				v = PyString_FromStringAndSize(
! 					((char*)addr)+1,
! 					*(unsigned char*)addr);
! 				break;
! #endif /* macintosh */
! 			case T_CHAR:
! 				v = PyString_FromStringAndSize((char*)addr, 1);
! 				break;
! 			case T_OBJECT:
! 				v = *(PyObject **)addr;
! 				if (v == NULL)
! 					v = Py_None;
! 				Py_INCREF(v);
! 				break;
! 			default:
! 				PyErr_SetString(PyExc_SystemError,
! 						"bad memberlist type");
! 				v = NULL;
! 			}
! 			return v;
 		}
 	}
- 	
 	PyErr_SetString(PyExc_AttributeError, name);
 	return NULL;
 }
 
 int
 PyMember_Set(char *addr, struct memberlist *mlist, char *name, PyObject *v)
 {
 	struct memberlist *l;
! 	PyObject *oldv;
! 	
 	for (l = mlist; l->name != NULL; l++) {
 		if (strcmp(l->name, name) == 0) {
! 			if ((l->flags & READONLY) || l->type == T_STRING
! #ifdef macintosh
! 			 || l->type == T_PSTRING
! #endif
! 				)
! 			{
! 				PyErr_SetString(PyExc_TypeError,
! 						"readonly attribute");
! 				return -1;
! 			}
! 			if ((l->flags & WRITE_RESTRICTED) &&
! 			 PyEval_GetRestricted()) {
! 				PyErr_SetString(PyExc_RuntimeError,
! 						"restricted attribute");
! 				return -1;
! 			}
! 			if (v == NULL && l->type != T_OBJECT) {
! 				PyErr_SetString(PyExc_TypeError,
! 				 "can't delete numeric/char attribute");
! 				return -1;
! 			}
! 			addr += l->offset;
! 			switch (l->type) {
! 			case T_BYTE:
! 			case T_UBYTE:
! 				if (!PyInt_Check(v)) {
! 					PyErr_BadArgument();
! 					return -1;
! 				}
! 				*(char*)addr = (char) PyInt_AsLong(v);
! 				break;
! 			case T_SHORT:
! 			case T_USHORT:
! 				if (!PyInt_Check(v)) {
! 					PyErr_BadArgument();
! 					return -1;
! 				}
! 				*(short*)addr = (short) PyInt_AsLong(v);
! 				break;
! 			case T_UINT:
! 			case T_INT:
! 				if (!PyInt_Check(v)) {
! 					PyErr_BadArgument();
! 					return -1;
! 				}
! 				*(int*)addr = (int) PyInt_AsLong(v);
! 				break;
! 			case T_LONG:
! 				if (!PyInt_Check(v)) {
! 					PyErr_BadArgument();
! 					return -1;
! 				}
! 				*(long*)addr = PyInt_AsLong(v);
! 				break;
! 			case T_ULONG:
! 				if (PyInt_Check(v))
! 					*(long*)addr = PyInt_AsLong(v);
! 				else if (PyLong_Check(v))
! 					*(long*)addr = PyLong_AsLong(v);
! 				else {
! 					PyErr_BadArgument();
! 					return -1;
! 				}
! 				break;
! 			case T_FLOAT:
! 				if (PyInt_Check(v))
! 					*(float*)addr =
! 						(float) PyInt_AsLong(v);
! 				else if (PyFloat_Check(v))
! 					*(float*)addr =
! 						(float) PyFloat_AsDouble(v);
! 				else {
! 					PyErr_BadArgument();
! 					return -1;
! 				}
! 				break;
! 			case T_DOUBLE:
! 				if (PyInt_Check(v))
! 					*(double*)addr =
! 						(double) PyInt_AsLong(v);
! 				else if (PyFloat_Check(v))
! 					*(double*)addr = PyFloat_AsDouble(v);
! 				else {
! 					PyErr_BadArgument();
! 					return -1;
! 				}
! 				break;
! 			case T_OBJECT:
! 				Py_XINCREF(v);
! 				oldv = *(PyObject **)addr;
! 				*(PyObject **)addr = v;
! 				Py_XDECREF(oldv);
! 				break;
! 			case T_CHAR:
! 				if (PyString_Check(v) &&
! 				 PyString_Size(v) == 1) {
! 					*(char*)addr =
! 						PyString_AsString(v)[0];
! 				}
! 				else {
! 					PyErr_BadArgument();
! 					return -1;
! 				}
! 				break;
! 			default:
! 				PyErr_SetString(PyExc_SystemError,
! 						"bad memberlist type");
! 				return -1;
! 			}
! 			return 0;
 		}
 	}
! 	
 	PyErr_SetString(PyExc_AttributeError, name);
 	return -1;
 }
--- 33,268 ----
 {
 	struct memberlist *l;
! 
 	if (strcmp(name, "__members__") == 0)
 		return listmembers(mlist);
 	for (l = mlist; l->name != NULL; l++) {
 		if (strcmp(l->name, name) == 0) {
! 			PyMemberDef copy;
! 			copy.name = l->name;
! 			copy.type = l->type;
! 			copy.offset = l->offset;
! 			copy.flags = l->flags;
! 			copy.doc = NULL;
! 			return PyMember_GetOne(addr, &copy);
 		}
 	}
 	PyErr_SetString(PyExc_AttributeError, name);
 	return NULL;
 }
 
+ PyObject *
+ PyMember_GetOne(char *addr, PyMemberDef *l)
+ {
+ 	PyObject *v;
+ 	if ((l->flags & READ_RESTRICTED) &&
+ 	 PyEval_GetRestricted()) {
+ 		PyErr_SetString(PyExc_RuntimeError, "restricted attribute");
+ 		return NULL;
+ 	}
+ 	addr += l->offset;
+ 	switch (l->type) {
+ 	case T_BYTE:
+ 		v = PyInt_FromLong(
+ 			(long) (((*(char*)addr & 0xff) ^ 0x80) - 0x80));
+ 		break;
+ 	case T_UBYTE:
+ 		v = PyInt_FromLong((long) *(char*)addr & 0xff);
+ 		break;
+ 	case T_SHORT:
+ 		v = PyInt_FromLong((long) *(short*)addr);
+ 		break;
+ 	case T_USHORT:
+ 		v = PyInt_FromLong((long) *(unsigned short*)addr);
+ 		break;
+ 	case T_INT:
+ 		v = PyInt_FromLong((long) *(int*)addr);
+ 		break;
+ 	case T_UINT:
+ 		v = PyInt_FromLong((long) *(unsigned int*)addr);
+ 		break;
+ 	case T_LONG:
+ 		v = PyInt_FromLong(*(long*)addr);
+ 		break;
+ 	case T_ULONG:
+ 		v = PyLong_FromDouble((double) *(unsigned long*)addr);
+ 		break;
+ 	case T_FLOAT:
+ 		v = PyFloat_FromDouble((double)*(float*)addr);
+ 		break;
+ 	case T_DOUBLE:
+ 		v = PyFloat_FromDouble(*(double*)addr);
+ 		break;
+ 	case T_STRING:
+ 		if (*(char**)addr == NULL) {
+ 			Py_INCREF(Py_None);
+ 			v = Py_None;
+ 		}
+ 		else
+ 			v = PyString_FromString(*(char**)addr);
+ 		break;
+ 	case T_STRING_INPLACE:
+ 		v = PyString_FromString((char*)addr);
+ 		break;
+ #ifdef macintosh
+ 	case T_PSTRING:
+ 		if (*(char**)addr == NULL) {
+ 			Py_INCREF(Py_None);
+ 			v = Py_None;
+ 		}
+ 		else
+ 			v = PyString_FromStringAndSize(
+ 				(*(char**)addr)+1,
+ 				**(unsigned char**)addr);
+ 		break;
+ 	case T_PSTRING_INPLACE:
+ 		v = PyString_FromStringAndSize(
+ 			((char*)addr)+1,
+ 			*(unsigned char*)addr);
+ 		break;
+ #endif /* macintosh */
+ 	case T_CHAR:
+ 		v = PyString_FromStringAndSize((char*)addr, 1);
+ 		break;
+ 	case T_OBJECT:
+ 		v = *(PyObject **)addr;
+ 		if (v == NULL)
+ 			v = Py_None;
+ 		Py_INCREF(v);
+ 		break;
+ 	default:
+ 		PyErr_SetString(PyExc_SystemError, "bad memberdescr type");
+ 		v = NULL;
+ 	}
+ 	return v;
+ }
+ 
 int
 PyMember_Set(char *addr, struct memberlist *mlist, char *name, PyObject *v)
 {
 	struct memberlist *l;
! 
 	for (l = mlist; l->name != NULL; l++) {
 		if (strcmp(l->name, name) == 0) {
! 			PyMemberDef copy;
! 			copy.name = l->name;
! 			copy.type = l->type;
! 			copy.offset = l->offset;
! 			copy.flags = l->flags;
! 			copy.doc = NULL;
! 			return PyMember_SetOne(addr, &copy, v);
 		}
 	}
! 
 	PyErr_SetString(PyExc_AttributeError, name);
 	return -1;
+ }
+ 
+ int
+ PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v)
+ {
+ 	PyObject *oldv;
+ 
+ 	if ((l->flags & READONLY) || l->type == T_STRING
+ #ifdef macintosh
+ 	 || l->type == T_PSTRING
+ #endif
+ 		)
+ 	{
+ 		PyErr_SetString(PyExc_TypeError, "readonly attribute");
+ 		return -1;
+ 	}
+ 	if ((l->flags & WRITE_RESTRICTED) && PyEval_GetRestricted()) {
+ 		PyErr_SetString(PyExc_RuntimeError, "restricted attribute");
+ 		return -1;
+ 	}
+ 	if (v == NULL && l->type != T_OBJECT) {
+ 		PyErr_SetString(PyExc_TypeError,
+ 				"can't delete numeric/char attribute");
+ 		return -1;
+ 	}
+ 	addr += l->offset;
+ 	switch (l->type) {
+ 	case T_BYTE:
+ 	case T_UBYTE:
+ 		if (!PyInt_Check(v)) {
+ 			PyErr_BadArgument();
+ 			return -1;
+ 		}
+ 		*(char*)addr = (char) PyInt_AsLong(v);
+ 		break;
+ 	case T_SHORT:
+ 	case T_USHORT:
+ 		if (!PyInt_Check(v)) {
+ 			PyErr_BadArgument();
+ 			return -1;
+ 		}
+ 		*(short*)addr = (short) PyInt_AsLong(v);
+ 		break;
+ 	case T_UINT:
+ 	case T_INT:
+ 		if (!PyInt_Check(v)) {
+ 			PyErr_BadArgument();
+ 			return -1;
+ 		}
+ 		*(int*)addr = (int) PyInt_AsLong(v);
+ 		break;
+ 	case T_LONG:
+ 		if (!PyInt_Check(v)) {
+ 			PyErr_BadArgument();
+ 			return -1;
+ 		}
+ 		*(long*)addr = PyInt_AsLong(v);
+ 		break;
+ 	case T_ULONG:
+ 		if (PyInt_Check(v))
+ 			*(long*)addr = PyInt_AsLong(v);
+ 		else if (PyLong_Check(v))
+ 			*(long*)addr = PyLong_AsLong(v);
+ 		else {
+ 			PyErr_BadArgument();
+ 			return -1;
+ 		}
+ 		break;
+ 	case T_FLOAT:
+ 		if (PyInt_Check(v))
+ 			*(float*)addr =
+ 				(float) PyInt_AsLong(v);
+ 		else if (PyFloat_Check(v))
+ 			*(float*)addr =
+ 				(float) PyFloat_AsDouble(v);
+ 		else {
+ 			PyErr_BadArgument();
+ 			return -1;
+ 		}
+ 		break;
+ 	case T_DOUBLE:
+ 		if (PyInt_Check(v))
+ 			*(double*)addr = (double) PyInt_AsLong(v);
+ 		else if (PyFloat_Check(v))
+ 			*(double*)addr = PyFloat_AsDouble(v);
+ 		else {
+ 			PyErr_BadArgument();
+ 			return -1;
+ 		}
+ 		break;
+ 	case T_OBJECT:
+ 		Py_XINCREF(v);
+ 		oldv = *(PyObject **)addr;
+ 		*(PyObject **)addr = v;
+ 		Py_XDECREF(oldv);
+ 		break;
+ 	case T_CHAR:
+ 		if (PyString_Check(v) && PyString_Size(v) == 1) {
+ 			*(char*)addr = PyString_AsString(v)[0];
+ 		}
+ 		else {
+ 			PyErr_BadArgument();
+ 			return -1;
+ 		}
+ 		break;
+ 	default:
+ 		PyErr_SetString(PyExc_SystemError, "bad memberdescr type");
+ 		return -1;
+ 	}
+ 	return 0;
 }
Index: symtable.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/symtable.c,v
retrieving revision 2.5
retrieving revision 2.6
diff -C2 -d -r2.5 -r2.6
*** symtable.c	2001年06月18日 22:08:13	2.5
--- symtable.c	2001年09月20日 20:46:19	2.6
***************
*** 107,111 ****
 #define OFF(x) offsetof(PySymtableEntryObject, x)
 
! static struct memberlist ste_memberlist[] = {
 	{"id", T_OBJECT, OFF(ste_id), READONLY},
 	{"name", T_OBJECT, OFF(ste_name), READONLY},
--- 107,111 ----
 #define OFF(x) offsetof(PySymtableEntryObject, x)
 
! static PyMemberDef ste_memberlist[] = {
 	{"id", T_OBJECT, OFF(ste_id), READONLY},
 	{"name", T_OBJECT, OFF(ste_name), READONLY},
***************
*** 120,129 ****
 };
 
- static PyObject *
- ste_getattr(PySymtableEntryObject *ste, char *name)
- {
- 	return PyMember_Get((char *)ste, ste_memberlist, name);
- }
- 
 PyTypeObject PySymtableEntry_Type = {
 	PyObject_HEAD_INIT(&PyType_Type)
--- 120,123 ----
***************
*** 134,138 ****
 	(destructor)ste_dealloc, /* tp_dealloc */
 	0, /* tp_print */
! 	(getattrfunc)ste_getattr, /* tp_getattr */
 	0,					/* tp_setattr */
 	0,			 /* tp_compare */
--- 128,132 ----
 	(destructor)ste_dealloc, /* tp_dealloc */
 	0, /* tp_print */
! 	0,			 /* tp_getattr */
 	0,					/* tp_setattr */
 	0,			 /* tp_compare */
***************
*** 144,151 ****
 	0,					/* tp_call */
 	0,					/* tp_str */
! 	0,					/* tp_getattro */
 	0,					/* tp_setattro */
 	0,					/* tp_as_buffer */
 	Py_TPFLAGS_DEFAULT,	 /* tp_flags */
 	0,					/* tp_doc */
 };
--- 138,162 ----
 	0,					/* tp_call */
 	0,					/* tp_str */
! 	PyObject_GenericGetAttr,		/* tp_getattro */
 	0,					/* tp_setattro */
 	0,					/* tp_as_buffer */
 	Py_TPFLAGS_DEFAULT,	 /* tp_flags */
 	0,					/* tp_doc */
+ 	0,					/* tp_traverse */
+ 	0,					/* tp_clear */
+ 	0,					/* tp_richcompare */
+ 	0,					/* tp_weaklistoffset */
+ 	0,					/* tp_iter */
+ 	0,					/* tp_iternext */
+ 	0,					/* tp_methods */
+ 	ste_memberlist,				/* tp_members */
+ 	0,					/* tp_getset */
+ 	0,					/* tp_base */
+ 	0,					/* tp_dict */
+ 	0,					/* tp_descr_get */
+ 	0,					/* tp_descr_set */
+ 	0,					/* tp_dictoffset */
+ 	0,					/* tp_init */
+ 	0,					/* tp_alloc */
+ 	0,					/* tp_new */
 };

AltStyle によって変換されたページ (->オリジナル) /