[Python-checkins] CVS: python/dist/src/Python bltinmodule.c,2.233,2.234

Tim Peters tim_one@users.sourceforge.net
2001年9月04日 15:08:58 -0700


Update of /cvsroot/python/python/dist/src/Python
In directory usw-pr-cvs1:/tmp/cvs-serv11322/python/Python
Modified Files:
	bltinmodule.c 
Log Message:
At Guido's suggestion, here's a new C API function, PyObject_Dir(), like
__builtin__.dir(). Moved the guts from bltinmodule.c to object.c.
Index: bltinmodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/bltinmodule.c,v
retrieving revision 2.233
retrieving revision 2.234
diff -C2 -d -r2.233 -r2.234
*** bltinmodule.c	2001年09月04日 01:20:04	2.233
--- bltinmodule.c	2001年09月04日 22:08:56	2.234
***************
*** 427,574 ****
 in addition to any features explicitly specified.";
 
- /* Merge the __dict__ of aclass into dict, and recursively also all
- the __dict__s of aclass's base classes. The order of merging isn't
- defined, as it's expected that only the final set of dict keys is
- interesting.
- Return 0 on success, -1 on error.
- */
- 
- static int
- merge_class_dict(PyObject* dict, PyObject* aclass)
- {
- 	PyObject *classdict;
- 	PyObject *bases;
- 
- 	assert(PyDict_Check(dict));
- 	assert(aclass);
- 
- 	/* Merge in the type's dict (if any). */
- 	classdict = PyObject_GetAttrString(aclass, "__dict__");
- 	if (classdict == NULL)
- 		PyErr_Clear();
- 	else {
- 		int status = PyDict_Update(dict, classdict);
- 		Py_DECREF(classdict);
- 		if (status < 0)
- 			return -1;
- 	}
- 
- 	/* Recursively merge in the base types' (if any) dicts. */
- 	bases = PyObject_GetAttrString(aclass, "__bases__");
- 	if (bases != NULL) {
- 		int i, n;
- 		assert(PyTuple_Check(bases));
- 		n = PyTuple_GET_SIZE(bases);
- 		for (i = 0; i < n; i++) {
- 			PyObject *base = PyTuple_GET_ITEM(bases, i);
- 			if (merge_class_dict(dict, base) < 0) {
- 				Py_DECREF(bases);
- 				return -1;
- 			}
- 		}
- 		Py_DECREF(bases);
- 	}
- 	return 0;
- }
- 
 static PyObject *
 builtin_dir(PyObject *self, PyObject *args)
 {
 	PyObject *arg = NULL;
- 	/* Set exactly one of these non-NULL before the end. */
- 	PyObject *result = NULL;	/* result list */
- 	PyObject *masterdict = NULL;	/* result is masterdict.keys() */
 
 	if (!PyArg_ParseTuple(args, "|O:dir", &arg))
 		return NULL;
! 
! 	/* If no arg, return the locals. */
! 	if (arg == NULL) {
! 		PyObject *locals = PyEval_GetLocals();
! 		if (locals == NULL)
! 			goto error;
! 		result = PyDict_Keys(locals);
! 		if (result == NULL)
! 			goto error;
! 	}
! 
! 	/* Elif this is some form of module, we only want its dict. */
! 	else if (PyObject_TypeCheck(arg, &PyModule_Type)) {
! 		masterdict = PyObject_GetAttrString(arg, "__dict__");
! 		if (masterdict == NULL)
! 			goto error;
! 		assert(PyDict_Check(masterdict));
! 	}
! 
! 	/* Elif some form of type or class, grab its dict and its bases.
! 	 We deliberately don't suck up its __class__, as methods belonging
! 	 to the metaclass would probably be more confusing than helpful. */
! 	else if (PyType_Check(arg) || PyClass_Check(arg)) {
! 		masterdict = PyDict_New();
! 		if (masterdict == NULL)
! 			goto error;
! 		if (merge_class_dict(masterdict, arg) < 0)
! 			goto error;
! 	}
! 
! 	/* Else look at its dict, and the attrs reachable from its class. */
! 	else {
! 		PyObject *itsclass;
! 		/* Create a dict to start with. CAUTION: Not everything
! 		 responding to __dict__ returns a dict! */
! 		masterdict = PyObject_GetAttrString(arg, "__dict__");
! 		if (masterdict == NULL) {
! 			PyErr_Clear();
! 			masterdict = PyDict_New();
! 		}
! 		else if (!PyDict_Check(masterdict)) {
! 			Py_DECREF(masterdict);
! 			masterdict = PyDict_New();
! 		}
! 		else {
! 			/* The object may have returned a reference to its
! 			 dict, so copy it to avoid mutating it. */
! 			PyObject *temp = PyDict_Copy(masterdict);
! 			Py_DECREF(masterdict);
! 			masterdict = temp;
! 		}
! 		if (masterdict == NULL)
! 			goto error;
! 
! 		/* Merge in attrs reachable from its class.
! 		 CAUTION: Not all objects have a __class__ attr. */
! 		itsclass = PyObject_GetAttrString(arg, "__class__");
! 		if (itsclass == NULL)
! 			PyErr_Clear();
! 		else {
! 			int status = merge_class_dict(masterdict, itsclass);
! 			Py_DECREF(itsclass);
! 			if (status < 0)
! 				goto error;
! 		}
! 	}
! 
! 	assert((result == NULL) ^ (masterdict == NULL));
! 	if (masterdict != NULL) {
! 		/* The result comes from its keys. */
! 		assert(result == NULL);
! 		result = PyDict_Keys(masterdict);
! 		if (result == NULL)
! 			goto error;
! 	}
! 
! 	assert(result);
! 	if (PyList_Sort(result) != 0)
! 		goto error;
! 	else
! 		goto normal_return;
! 
! error:
! 	Py_XDECREF(result);
! 	result = NULL;
! 	/* fall through */
! normal_return:
! 	Py_XDECREF(masterdict);
! 	return result;
 }
 
--- 427,438 ----
 in addition to any features explicitly specified.";
 
 static PyObject *
 builtin_dir(PyObject *self, PyObject *args)
 {
 	PyObject *arg = NULL;
 
 	if (!PyArg_ParseTuple(args, "|O:dir", &arg))
 		return NULL;
! 	return PyObject_Dir(arg);
 }
 

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