From: Antoine Pitrou <solipsis@pitrou.net>
Date: Sat, 27 Nov 2010 22:00:11 +0000 (+0000)
Subject: Issue #10518: Bring back the callable() builtin.
X-Git-Tag: v3.2b1~187
X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e71362d3dee9de626abb7d2d564550b5e59a1151;p=python

Issue #10518: Bring back the callable() builtin.
Approved by Guido (BDFL) and Georg (RM).
---

diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst
index 1c3ee129ff..34d583a830 100644
--- a/Doc/library/functions.rst
+++ b/Doc/library/functions.rst
@@ -121,6 +121,19 @@ are always available.  They are listed here in alphabetical order.
    Bytes objects can also be created with literals, see :ref:`strings`.
 
 
+.. function:: callable(object)
+
+   Return :const:`True` if the *object* argument appears callable,
+   :const:`False` if not.  If this returns true, it is still possible that a
+   call fails, but if it is false, calling *object* will never succeed.
+   Note that classes are callable (calling a class returns a new instance);
+   instances are callable if their class has a :meth:`__call__` method.
+
+   .. versionadded:: 3.2
+      This function was first removed in Python 3.0 and then brought back
+      in Python 3.2.
+
+
 .. function:: chr(i)
 
    Return the string representing a character whose Unicode codepoint is the integer
diff --git a/Lib/test/test_bool.py b/Lib/test/test_bool.py
index 7282c0ae16..b296870b09 100644
--- a/Lib/test/test_bool.py
+++ b/Lib/test/test_bool.py
@@ -174,8 +174,8 @@ class BoolTest(unittest.TestCase):
         self.assertIs(hasattr([], "wobble"), False)
 
     def test_callable(self):
-        self.assertIs(hasattr(len, '__call__'), True)
-        self.assertIs(hasattr(1, '__call__'), False)
+        self.assertIs(callable(len), True)
+        self.assertIs(callable(1), False)
 
     def test_isinstance(self):
         self.assertIs(isinstance(True, bool), True)
diff --git a/Lib/test/test_builtin.py b/Lib/test/test_builtin.py
index 26c70349ed..7b73949267 100644
--- a/Lib/test/test_builtin.py
+++ b/Lib/test/test_builtin.py
@@ -207,22 +207,39 @@ class BuiltinTest(unittest.TestCase):
         self.assertTrue(isinstance(x, int))
         self.assertEqual(-x, sys.maxsize+1)
 
-    # XXX(nnorwitz): This test case for callable should probably be removed.
     def test_callable(self):
-        self.assertTrue(hasattr(len, '__call__'))
+        self.assertTrue(callable(len))
+        self.assertFalse(callable("a"))
+        self.assertTrue(callable(callable))
+        self.assertTrue(callable(lambda x, y: x + y))
+        self.assertFalse(callable(__builtins__))
         def f(): pass
-        self.assertTrue(hasattr(f, '__call__'))
-        class C:
+        self.assertTrue(callable(f))
+
+        class C1:
             def meth(self): pass
-        self.assertTrue(hasattr(C, '__call__'))
-        x = C()
-        self.assertTrue(hasattr(x.meth, '__call__'))
-        self.assertTrue(not hasattr(x, '__call__'))
-        class D(C):
+        self.assertTrue(callable(C1))
+        c = C1()
+        self.assertTrue(callable(c.meth))
+        self.assertFalse(callable(c))
+
+        # __call__ is looked up on the class, not the instance
+        c.__call__ = None
+        self.assertFalse(callable(c))
+        c.__call__ = lambda self: 0
+        self.assertFalse(callable(c))
+        del c.__call__
+        self.assertFalse(callable(c))
+
+        class C2(object):
             def __call__(self): pass
-        y = D()
-        self.assertTrue(hasattr(y, '__call__'))
-        y()
+        c2 = C2()
+        self.assertTrue(callable(c2))
+        c2.__call__ = None
+        self.assertTrue(callable(c2))
+        class C3(C2): pass
+        c3 = C3()
+        self.assertTrue(callable(c3))
 
     def test_chr(self):
         self.assertEqual(chr(32), ' ')
diff --git a/Misc/NEWS b/Misc/NEWS
index 07f0570e9e..27c733166c 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -10,6 +10,8 @@ What's New in Python 3.2 Beta 1?
 Core and Builtins
 -----------------
 
+- Issue #10518: Bring back the callable() builtin.
+
 - Issue #8879. Add os.link support for Windows.
 
 - Issue #10027. st_nlink was not being set on Windows calls to os.stat or
diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c
index 46045192cf..f374277f3d 100644
--- a/Python/bltinmodule.c
+++ b/Python/bltinmodule.c
@@ -311,6 +311,20 @@ PyDoc_STRVAR(bin_doc,
 Return the binary representation of an integer or long integer.");
 
 
+static PyObject *
+builtin_callable(PyObject *self, PyObject *v)
+{
+    return PyBool_FromLong((long)PyCallable_Check(v));
+}
+
+PyDoc_STRVAR(callable_doc,
+"callable(object) -> bool\n\
+\n\
+Return whether the object is callable (i.e., some kind of function).\n\
+Note that classes are callable, as are instances of classes with a\n\
+__call__() method.");
+
+
 typedef struct {
     PyObject_HEAD
     PyObject *func;
@@ -2242,6 +2256,7 @@ static PyMethodDef builtin_methods[] = {
     {"any",             builtin_any,        METH_O, any_doc},
     {"ascii",           builtin_ascii,      METH_O, ascii_doc},
     {"bin",             builtin_bin,        METH_O, bin_doc},
+    {"callable",        builtin_callable,   METH_O, callable_doc},
     {"chr",             builtin_chr,        METH_VARARGS, chr_doc},
     {"compile",         (PyCFunction)builtin_compile,    METH_VARARGS | METH_KEYWORDS, compile_doc},
     {"delattr",         builtin_delattr,    METH_VARARGS, delattr_doc},