[Python-checkins] r72508 - in python/trunk: Lib/test/test_descr.py Objects/abstract.c Python/sysmodule.c

benjamin.peterson python-checkins at python.org
Sat May 9 18:36:39 CEST 2009


Author: benjamin.peterson
Date: Sat May  9 18:36:39 2009
New Revision: 72508

Log:
convert some more special methods to use _PyObject_LookupSpecial

Modified:
   python/trunk/Lib/test/test_descr.py
   python/trunk/Objects/abstract.c
   python/trunk/Python/sysmodule.c

Modified: python/trunk/Lib/test/test_descr.py
==============================================================================
--- python/trunk/Lib/test/test_descr.py	(original)
+++ python/trunk/Lib/test/test_descr.py	Sat May  9 18:36:39 2009
@@ -1,4 +1,5 @@
 import __builtin__
+import sys
 import types
 import unittest
 import warnings
@@ -1678,13 +1679,20 @@
             return "hello"
         def empty_seq(self):
             return []
+        def zero(self):
+            return 0
+        def stop(self):
+            raise StopIteration
 
         # It would be nice to have every special method tested here, but I'm
         # only listing the ones I can remember outside of typeobject.c, since it
         # does it right.
         specials = [
-            ("__unicode__", unicode, hello),
-            ("__reversed__", reversed, empty_seq),
+            ("__unicode__", unicode, hello, {}),
+            ("__reversed__", reversed, empty_seq, {}),
+            ("__length_hint__", list, zero,
+             {"__iter__" : iden, "next" : stop}),
+            ("__sizeof__", sys.getsizeof, zero, {}),
             # These two fail because the compiler generates LOAD_ATTR to look
             # them up.  We'd have to add a new opcode to fix this, and it's
             # probably not worth it.
@@ -1705,15 +1713,19 @@
                 return self.impl.__get__(obj, owner)
 
 
-        for name, runner, meth_impl in specials:
+        for name, runner, meth_impl, env in specials:
             class X(Checker):
                 pass
+            for attr, obj in env.iteritems():
+                setattr(X, attr, obj)
             setattr(X, name, meth_impl)
             runner(X())
 
             record = []
             class X(Checker):
                 pass
+            for attr, obj in env.iteritems():
+                setattr(X, attr, obj)
             setattr(X, name, SpecialDescr(meth_impl))
             runner(X())
             self.assertEqual(record, [1], name)

Modified: python/trunk/Objects/abstract.c
==============================================================================
--- python/trunk/Objects/abstract.c	(original)
+++ python/trunk/Objects/abstract.c	Sat May  9 18:36:39 2009
@@ -93,7 +93,7 @@
 _PyObject_LengthHint(PyObject *o, Py_ssize_t defaultvalue)
 {
 	static PyObject *hintstrobj = NULL;
-	PyObject *ro;
+	PyObject *ro, *hintmeth;
 	Py_ssize_t rv;
 
 	/* try o.__len__() */
@@ -107,20 +107,15 @@
 		PyErr_Clear();
 	}
 
-	/* cache a hashed version of the attribute string */
-	if (hintstrobj == NULL) {
-		hintstrobj = PyString_InternFromString("__length_hint__");
-		if (hintstrobj == NULL)
-			return -1;
-	}
-
 	/* try o.__length_hint__() */
-	ro = PyObject_CallMethodObjArgs(o, hintstrobj, NULL);
+        hintmeth = _PyObject_LookupSpecial(o, "__length_hint__", &hintstrobj);
+	if (hintmeth == NULL)
+		return defaultvalue;
+	ro = PyObject_CallFunctionObjArgs(hintmeth, NULL);
+	Py_DECREF(hintmeth);
 	if (ro == NULL) {
-		if (!PyErr_ExceptionMatches(PyExc_TypeError) &&
-			!PyErr_ExceptionMatches(PyExc_AttributeError))
-				return -1;
-		PyErr_Clear();
+		if (!PyErr_ExceptionMatches(PyExc_TypeError))
+			return -1;
 		return defaultvalue;
 	}
 	rv = PyLong_Check(ro) ? PyLong_AsSsize_t(ro) : defaultvalue;

Modified: python/trunk/Python/sysmodule.c
==============================================================================
--- python/trunk/Python/sysmodule.c	(original)
+++ python/trunk/Python/sysmodule.c	Sat May  9 18:36:39 2009
@@ -643,7 +643,7 @@
 sys_getsizeof(PyObject *self, PyObject *args, PyObject *kwds)
 {
 	PyObject *res = NULL;
-	static PyObject *str__sizeof__, *gc_head_size = NULL;
+	static PyObject *str__sizeof__ = NULL, *gc_head_size = NULL;
 	static char *kwlist[] = {"object", "default", 0};
 	PyObject *o, *dflt = NULL;
 
@@ -651,13 +651,6 @@
 					 kwlist, &o, &dflt))
 		return NULL;
 
-	/* Initialize static variable needed by _PyType_Lookup */
-	if (str__sizeof__ == NULL) {
-		str__sizeof__ = PyString_InternFromString("__sizeof__");
-		if (str__sizeof__ == NULL)
-			return NULL;
-	}
-
         /* Initialize static variable for GC head size */
 	if (gc_head_size == NULL) {
 		gc_head_size = PyInt_FromSsize_t(sizeof(PyGC_Head));
@@ -674,14 +667,16 @@
 		res = PyInt_FromSsize_t(PyInstance_Type.tp_basicsize);
 	/* all other objects */
 	else {
-		PyObject *method = _PyType_Lookup(Py_TYPE(o),
-						  str__sizeof__);
+		PyObject *method = _PyObject_LookupSpecial(o, "__sizeof__",
+							   &str__sizeof__);
 		if (method == NULL)
 			PyErr_Format(PyExc_TypeError,
 				     "Type %.100s doesn't define __sizeof__",
 				     Py_TYPE(o)->tp_name);
-		else
-			res = PyObject_CallFunctionObjArgs(method, o, NULL);
+		else {
+			res = PyObject_CallFunctionObjArgs(method, NULL);
+			Py_DECREF(method);
+		}
 	}
 	
 	/* Has a default value been given? */


More information about the Python-checkins mailing list