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

Tim Peters tim_one@users.sourceforge.net
Mon, 03 Sep 2001 18:20:06 -0700


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

Modified Files:
	bltinmodule.c 
Log Message:
builtin_dir():  Treat classic classes like types.  Use PyDict_Keys instead
of PyMapping_Keys because we know we have a real dict.  Tolerate that
objects may have an attr named "__dict__" that's not a dict (Py_None
popped up during testing).

test_descr.py, test_dir():  Test the new classic-class behavior; beef up
the new-style class test similarly.

test_pyclbr.py, checkModule():  dir(C) is no longer a synonym for
C.__dict__.keys() when C is a classic class (looks like the same thing
that burned distutils! -- should it be *made* a synoym again?  Then it
would be inconsistent with new-style class behavior.).


Index: bltinmodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/bltinmodule.c,v
retrieving revision 2.232
retrieving revision 2.233
diff -C2 -d -r2.232 -r2.233
*** bltinmodule.c	2001/09/03 05:47:38	2.232
--- bltinmodule.c	2001/09/04 01:20:04	2.233
***************
*** 441,447 ****
  
  	assert(PyDict_Check(dict));
- 	/* XXX Class objects fail the PyType_Check check.  Don't
- 	   XXX know of others. */
- 	/* assert(PyType_Check(aclass)); */
  	assert(aclass);
  
--- 441,444 ----
***************
*** 491,495 ****
  		if (locals == NULL)
  			goto error;
! 		result = PyMapping_Keys(locals);
  		if (result == NULL)
  			goto error;
--- 488,492 ----
  		if (locals == NULL)
  			goto error;
! 		result = PyDict_Keys(locals);
  		if (result == NULL)
  			goto error;
***************
*** 501,508 ****
  		if (masterdict == NULL)
  			goto error;
  	}
  
! 	/* Elif some form of type, recurse. */
! 	else if (PyType_Check(arg)) {
  		masterdict = PyDict_New();
  		if (masterdict == NULL)
--- 498,508 ----
  		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)
***************
*** 515,540 ****
  	else {
  		PyObject *itsclass;
! 		/* Create a dict to start with. */
  		masterdict = PyObject_GetAttrString(arg, "__dict__");
  		if (masterdict == NULL) {
  			PyErr_Clear();
  			masterdict = PyDict_New();
- 			if (masterdict == NULL)
- 				goto error;
  		}
  		else {
  			/* The object may have returned a reference to its
  			   dict, so copy it to avoid mutating it. */
  			PyObject *temp = PyDict_Copy(masterdict);
- 			if (temp == NULL)
- 				goto error;
  			Py_DECREF(masterdict);
  			masterdict = temp;
  		}
! 		/* Merge in attrs reachable from its class. */
  		itsclass = PyObject_GetAttrString(arg, "__class__");
- 		/* XXX Sometimes this is null!  Like after "class C: pass",
- 		   C.__class__ raises AttributeError.  Don't know of other
- 		   cases. */
  		if (itsclass == NULL)
  			PyErr_Clear();
--- 515,542 ----
  	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();
***************
*** 551,555 ****
  		/* The result comes from its keys. */
  		assert(result == NULL);
! 		result = PyMapping_Keys(masterdict);
  		if (result == NULL)
  			goto error;
--- 553,557 ----
  		/* The result comes from its keys. */
  		assert(result == NULL);
! 		result = PyDict_Keys(masterdict);
  		if (result == NULL)
  			goto error;
***************
*** 579,583 ****
  "No argument:  the names in the current scope.\n"
  "Module object:  the module attributes.\n"
! "Type object:  its attributes, and recursively the attributes of its bases.\n"
  "Otherwise:  its attributes, its class's attributes, and recursively the\n"
  "    attributes of its class's base classes.";
--- 581,586 ----
  "No argument:  the names in the current scope.\n"
  "Module object:  the module attributes.\n"
! "Type or class object:  its attributes, and recursively the attributes of\n"
! "    its bases.\n"
  "Otherwise:  its attributes, its class's attributes, and recursively the\n"
  "    attributes of its class's base classes.";