]> granicus.if.org Git - python/commitdiff
Merged revisions 72508 via svnmerge from
authorBenjamin Peterson <benjamin@python.org>
Sat, 9 May 2009 18:15:04 +0000 (18:15 +0000)
committerBenjamin Peterson <benjamin@python.org>
Sat, 9 May 2009 18:15:04 +0000 (18:15 +0000)
svn+ssh://pythondev@svn.python.org/python/trunk

........
  r72508 | benjamin.peterson | 2009-05-09 11:36:39 -0500 (Sat, 09 May 2009) | 1 line

  convert some more special methods to use _PyObject_LookupSpecial
........

Lib/test/test_descr.py
Objects/abstract.c
Python/sysmodule.c

index b4bd948f82ef94eaf3e60c6bb5b8c05f8ca8284e..afb0f877b28f6e4a72c04043bc86bdb47f56844d 100644 (file)
@@ -1,4 +1,5 @@
 import builtins
+import sys
 import types
 import unittest
 import warnings
@@ -1551,13 +1552,20 @@ order (MRO) for bases """
             return b"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 = [
-            ("__bytes__", bytes, hello),
-            ("__reversed__", reversed, empty_seq),
+            ("__bytes__", bytes, 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.
@@ -1578,15 +1586,19 @@ order (MRO) for bases """
                 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.items():
+                setattr(X, attr, obj)
             setattr(X, name, meth_impl)
             runner(X())
 
             record = []
             class X(Checker):
                 pass
+            for attr, obj in env.items():
+                setattr(X, attr, obj)
             setattr(X, name, SpecialDescr(meth_impl))
             runner(X())
             self.assertEqual(record, [1], name)
index 7679d5b2f6654fd3c22cd575fa9106305e02c991..83f536702b3b5b0872650886918b409836902d85 100644 (file)
@@ -75,7 +75,7 @@ Py_ssize_t
 _PyObject_LengthHint(PyObject *o, Py_ssize_t defaultvalue)
 {
        static PyObject *hintstrobj = NULL;
-       PyObject *ro;
+       PyObject *ro, *hintmeth;
        Py_ssize_t rv;
 
        /* try o.__len__() */
@@ -89,20 +89,15 @@ _PyObject_LengthHint(PyObject *o, Py_ssize_t defaultvalue)
                PyErr_Clear();
        }
 
-       /* cache a hashed version of the attribute string */
-       if (hintstrobj == NULL) {
-               hintstrobj = PyUnicode_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;
index 262f5a1199e59da9641084157858431babdba4e8..b9d5dbaefee9049e4beb2105e898c0ac86b8f5da 100644 (file)
@@ -630,7 +630,7 @@ static PyObject *
 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;
        PyObject *method;
@@ -639,13 +639,6 @@ sys_getsizeof(PyObject *self, PyObject *args, PyObject *kwds)
                                         kwlist, &o, &dflt))
                return NULL;
 
-       /* Initialize static variable needed by _PyType_Lookup */
-       if (str__sizeof__ == NULL) {
-               str__sizeof__ = PyUnicode_InternFromString("__sizeof__");
-               if (str__sizeof__ == NULL)
-                       return NULL;
-       }
-
         /* Initialize static variable for GC head size */
        if (gc_head_size == NULL) {
                gc_head_size = PyLong_FromSsize_t(sizeof(PyGC_Head));
@@ -656,14 +649,17 @@ sys_getsizeof(PyObject *self, PyObject *args, PyObject *kwds)
        /* Make sure the type is initialized. float gets initialized late */
        if (PyType_Ready(Py_TYPE(o)) < 0)
                return NULL;
-       
-       method = _PyType_Lookup(Py_TYPE(o), str__sizeof__);
+
+       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 */
        if ((res == NULL) && (dflt != NULL) &&