]> granicus.if.org Git - python/commitdiff
Closes #13258: Use callable() built-in in the standard library.
authorFlorent Xicluna <florent.xicluna@gmail.com>
Fri, 28 Oct 2011 12:45:05 +0000 (14:45 +0200)
committerFlorent Xicluna <florent.xicluna@gmail.com>
Fri, 28 Oct 2011 12:45:05 +0000 (14:45 +0200)
25 files changed:
Lib/argparse.py
Lib/copyreg.py
Lib/distutils/dist.py
Lib/encodings/__init__.py
Lib/fileinput.py
Lib/hmac.py
Lib/idlelib/rpc.py
Lib/logging/config.py
Lib/multiprocessing/managers.py
Lib/multiprocessing/pool.py
Lib/optparse.py
Lib/pickle.py
Lib/pydoc.py
Lib/re.py
Lib/rlcompleter.py
Lib/shutil.py
Lib/test/test_nntplib.py
Lib/timeit.py
Lib/tkinter/__init__.py
Lib/tkinter/tix.py
Lib/unittest/loader.py
Lib/unittest/suite.py
Lib/warnings.py
Lib/xmlrpc/server.py
Misc/NEWS

index 63561f7cb129c80f3a61cadfece4e66bb38f0c66..2202b5732024982d4eb91e2d144593bae60e9349 100644 (file)
@@ -92,10 +92,6 @@ import textwrap as _textwrap
 from gettext import gettext as _, ngettext
 
 
-def _callable(obj):
-    return hasattr(obj, '__call__') or hasattr(obj, '__bases__')
-
-
 SUPPRESS = '==SUPPRESS=='
 
 OPTIONAL = '?'
@@ -1286,13 +1282,13 @@ class _ActionsContainer(object):
 
         # create the action object, and add it to the parser
         action_class = self._pop_action_class(kwargs)
-        if not _callable(action_class):
+        if not callable(action_class):
             raise ValueError('unknown action "%s"' % (action_class,))
         action = action_class(**kwargs)
 
         # raise an error if the action type is not callable
         type_func = self._registry_get('type', action.type, action.type)
-        if not _callable(type_func):
+        if not callable(type_func):
             raise ValueError('%r is not callable' % (type_func,))
 
         # raise an error if the metavar does not match the type
@@ -2240,7 +2236,7 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer):
 
     def _get_value(self, action, arg_string):
         type_func = self._registry_get('type', action.type, action.type)
-        if not _callable(type_func):
+        if not callable(type_func):
             msg = _('%r is not callable')
             raise ArgumentError(action, msg % type_func)
 
index 81a1e7fefe0d508e87e18095a6c06da73f34110b..66c0f8a64d6edd9bcd80518e9b806800b2cb1ce6 100644 (file)
@@ -10,7 +10,7 @@ __all__ = ["pickle", "constructor",
 dispatch_table = {}
 
 def pickle(ob_type, pickle_function, constructor_ob=None):
-    if not hasattr(pickle_function, '__call__'):
+    if not callable(pickle_function):
         raise TypeError("reduction functions must be callable")
     dispatch_table[ob_type] = pickle_function
 
@@ -20,7 +20,7 @@ def pickle(ob_type, pickle_function, constructor_ob=None):
         constructor(constructor_ob)
 
 def constructor(object):
-    if not hasattr(object, '__call__'):
+    if not callable(object):
         raise TypeError("constructors must be callable")
 
 # Example: provide pickling support for complex numbers.
index 69825f206f2391d8bc6c4d726e634b5ca95808c7..a70256827817342397b3efd0e1d83b7da14f2e07 100644 (file)
@@ -537,7 +537,7 @@ Common commands: (see '--help-commands' for more)
             for (help_option, short, desc, func) in cmd_class.help_options:
                 if hasattr(opts, parser.get_attr_name(help_option)):
                     help_option_found=1
-                    if hasattr(func, '__call__'):
+                    if callable(func):
                         func()
                     else:
                         raise DistutilsClassError(
index b189bd9793ed07d63d76ec5cc2e7c8438d29552e..8dd713056ef056276782c4a7e899e80738f0eead 100644 (file)
@@ -120,12 +120,11 @@ def search_function(encoding):
         if not 4 <= len(entry) <= 7:
             raise CodecRegistryError('module "%s" (%s) failed to register'
                                      % (mod.__name__, mod.__file__))
-        if not hasattr(entry[0], '__call__') or \
-           not hasattr(entry[1], '__call__') or \
-           (entry[2] is not None and not hasattr(entry[2], '__call__')) or \
-           (entry[3] is not None and not hasattr(entry[3], '__call__')) or \
-           (len(entry) > 4 and entry[4] is not None and not hasattr(entry[4], '__call__')) or \
-           (len(entry) > 5 and entry[5] is not None and not hasattr(entry[5], '__call__')):
+        if not callable(entry[0]) or not callable(entry[1]) or \
+           (entry[2] is not None and not callable(entry[2])) or \
+           (entry[3] is not None and not callable(entry[3])) or \
+           (len(entry) > 4 and entry[4] is not None and not callable(entry[4])) or \
+           (len(entry) > 5 and entry[5] is not None and not callable(entry[5])):
             raise CodecRegistryError('incompatible codecs in module "%s" (%s)'
                                      % (mod.__name__, mod.__file__))
         if len(entry)<7 or entry[6] is None:
index a25a021eb31d28154b709d6a489cecf12c8937b0..554beb2448c7b902f1005ba2e948de336cc47109 100644 (file)
@@ -225,10 +225,11 @@ class FileInput:
             raise ValueError("FileInput opening mode must be one of "
                              "'r', 'rU', 'U' and 'rb'")
         self._mode = mode
-        if inplace and openhook:
-            raise ValueError("FileInput cannot use an opening hook in inplace mode")
-        elif openhook and not hasattr(openhook, '__call__'):
-            raise ValueError("FileInput openhook must be callable")
+        if openhook:
+            if inplace:
+                raise ValueError("FileInput cannot use an opening hook in inplace mode")
+            if not callable(openhook):
+                raise ValueError("FileInput openhook must be callable")
         self._openhook = openhook
 
     def __del__(self):
index e878e1a8096af170eaa857068aa67ea6a6e81140..956fc65d2c06173e9b76b7525df17656ba5db61d 100644 (file)
@@ -39,7 +39,7 @@ class HMAC:
             import hashlib
             digestmod = hashlib.md5
 
-        if hasattr(digestmod, '__call__'):
+        if callable(digestmod):
             self.digest_cons = digestmod
         else:
             self.digest_cons = lambda d=b'': digestmod.new(d)
index 0c56ccdcfe50532a7f6ac3ae7399acab99691132..def43945aee438aea98c3130e7ec98062c26b78d 100644 (file)
@@ -570,7 +570,7 @@ def _getmethods(obj, methods):
     # Adds names to dictionary argument 'methods'
     for name in dir(obj):
         attr = getattr(obj, name)
-        if hasattr(attr, '__call__'):
+        if callable(attr):
             methods[name] = 1
     if isinstance(obj, type):
         for super in obj.__bases__:
@@ -579,7 +579,7 @@ def _getmethods(obj, methods):
 def _getattributes(obj, attributes):
     for name in dir(obj):
         attr = getattr(obj, name)
-        if not hasattr(attr, '__call__'):
+        if not callable(attr):
             attributes[name] = 1
 
 class MethodProxy(object):
index c7359cabe904ec9e61bbf3b8e7585e590d2571b7..373da2b0764f6b74a49d9256a738ec274dd4970e 100644 (file)
@@ -471,7 +471,7 @@ class BaseConfigurator(object):
     def configure_custom(self, config):
         """Configure an object with a user-supplied factory."""
         c = config.pop('()')
-        if not hasattr(c, '__call__'):
+        if not callable(c):
             c = self.resolve(c)
         props = config.pop('.', None)
         # Check for valid identifiers
@@ -690,7 +690,7 @@ class DictConfigurator(BaseConfigurator):
         filters = config.pop('filters', None)
         if '()' in config:
             c = config.pop('()')
-            if not hasattr(c, '__call__') and hasattr(types, 'ClassType') and type(c) != types.ClassType:
+            if not callable(c):
                 c = self.resolve(c)
             factory = c
         else:
index 388bfe3c87ca79d0da4288e6a89d5c0f2cd80c23..5a57288caaffe7d6279a585196953d0d820567b5 100644 (file)
@@ -134,7 +134,7 @@ def all_methods(obj):
     temp = []
     for name in dir(obj):
         func = getattr(obj, name)
-        if hasattr(func, '__call__'):
+        if callable(func):
             temp.append(name)
     return temp
 
@@ -510,7 +510,7 @@ class BaseManager(object):
         '''
         assert self._state.value == State.INITIAL
 
-        if initializer is not None and not hasattr(initializer, '__call__'):
+        if initializer is not None and not callable(initializer):
             raise TypeError('initializer must be a callable')
 
         # pipe over which we will retrieve address of server
index 04e7c447d17b4eff9fb043da6cbf485dc5fa37a6..0c29e644ffd42832677f1e0e6ed933e20610a95a 100644 (file)
@@ -151,7 +151,7 @@ class Pool(object):
         if processes < 1:
             raise ValueError("Number of processes must be at least 1")
 
-        if initializer is not None and not hasattr(initializer, '__call__'):
+        if initializer is not None and not callable(initializer):
             raise TypeError('initializer must be a callable')
 
         self._processes = processes
index cbd019afb7d3afbfba5ad465a153c02cc2f54cb0..d97a1f7aca30534ea02f628de448ec354a914798 100644 (file)
@@ -705,7 +705,7 @@ class Option:
 
     def _check_callback(self):
         if self.action == "callback":
-            if not hasattr(self.callback, '__call__'):
+            if not callable(self.callback):
                 raise OptionError(
                     "callback not callable: %r" % self.callback, self)
             if (self.callback_args is not None and
index c770ff8bdf4e3e5f1fd9f0497ff435c7a1c97ba7..1f45f37d46c2853736f2bbba53b631f21be7f469 100644 (file)
@@ -364,7 +364,7 @@ class _Pickler:
             raise PicklingError("args from save_reduce() should be a tuple")
 
         # Assert that func is callable
-        if not hasattr(func, '__call__'):
+        if not callable(func):
             raise PicklingError("func from save_reduce() should be callable")
 
         save = self.save
index 1a5db1a66fadcabe37d27f42039d65ee1c278433..d0c6f62148f84f11d48e2045544e258e8d98104f 100755 (executable)
@@ -775,7 +775,7 @@ class HTMLDoc(Doc):
                 push(msg)
                 for name, kind, homecls, value in ok:
                     base = self.docother(getattr(object, name), name, mod)
-                    if hasattr(value, '__call__') or inspect.isdatadescriptor(value):
+                    if callable(value) or inspect.isdatadescriptor(value):
                         doc = getattr(value, "__doc__", None)
                     else:
                         doc = None
@@ -1199,7 +1199,7 @@ location listed above.
                 hr.maybe()
                 push(msg)
                 for name, kind, homecls, value in ok:
-                    if hasattr(value, '__call__') or inspect.isdatadescriptor(value):
+                    if callable(value) or inspect.isdatadescriptor(value):
                         doc = getdoc(value)
                     else:
                         doc = None
index abd7ea27b32bca30c88dbe29007fccd77560e023..4fe3bd88ac7d6d4028962bf040f33c38e94f19b7 100644 (file)
--- a/Lib/re.py
+++ b/Lib/re.py
@@ -326,7 +326,7 @@ class Scanner:
             if i == j:
                 break
             action = self.lexicon[m.lastindex-1][1]
-            if hasattr(action, "__call__"):
+            if callable(action):
                 self.match = m
                 action = action(self, m.group())
             if action is not None:
index 6eb1b3d0e93fe7ac9b6da8d09c34070419263886..8b74ffaadda019cc64d3b2e937f7c25870b1f0cf 100644 (file)
@@ -87,7 +87,7 @@ class Completer:
             return None
 
     def _callable_postfix(self, val, word):
-        if hasattr(val, '__call__'):
+        if callable(val):
             word = word + "("
         return word
 
index a0d981b0c7278965d5cc9cb11960186cf6566bf7..00bffe5f20f4ae6e7283b289695d031eee142508 100644 (file)
@@ -523,7 +523,7 @@ def register_archive_format(name, function, extra_args=None, description=''):
     """
     if extra_args is None:
         extra_args = []
-    if not isinstance(function, collections.Callable):
+    if not callable(function):
         raise TypeError('The %s object is not callable' % function)
     if not isinstance(extra_args, (tuple, list)):
         raise TypeError('extra_args needs to be a sequence')
@@ -616,7 +616,7 @@ def _check_unpack_options(extensions, function, extra_args):
             raise RegistryError(msg % (extension,
                                        existing_extensions[extension]))
 
-    if not isinstance(function, collections.Callable):
+    if not callable(function):
         raise TypeError('The registered function must be a callable')
 
 
index a387f61f1e57c14a4fdf772397f2b2cf14b7b23f..786b5f093bc5c4d8bf2d01d6a2d7a238fd0215d0 100644 (file)
@@ -4,7 +4,6 @@ import textwrap
 import unittest
 import functools
 import contextlib
-import collections
 from test import support
 from nntplib import NNTP, GroupInfo, _have_ssl
 import nntplib
@@ -246,7 +245,7 @@ class NetworkedNNTPTestsMixin:
             if not name.startswith('test_'):
                 continue
             meth = getattr(cls, name)
-            if not isinstance(meth, collections.Callable):
+            if not callable(meth):
                 continue
             # Need to use a closure so that meth remains bound to its current
             # value
index 461c8910702b171e671876b642cfc6937a3e69ba..1ae59e0cccdb1ee4b78d52653d840e131b40645a 100644 (file)
@@ -127,7 +127,7 @@ class Timer:
             if isinstance(setup, str):
                 setup = reindent(setup, 4)
                 src = template % {'stmt': stmt, 'setup': setup}
-            elif hasattr(setup, '__call__'):
+            elif callable(setup):
                 src = template % {'stmt': stmt, 'setup': '_setup()'}
                 ns['_setup'] = setup
             else:
@@ -136,13 +136,13 @@ class Timer:
             code = compile(src, dummy_src_name, "exec")
             exec(code, globals(), ns)
             self.inner = ns["inner"]
-        elif hasattr(stmt, '__call__'):
+        elif callable(stmt):
             self.src = None
             if isinstance(setup, str):
                 _setup = setup
                 def setup():
                     exec(_setup, globals(), ns)
-            elif not hasattr(setup, '__call__'):
+            elif not callable(setup):
                 raise ValueError("setup is neither a string nor callable")
             self.inner = _template_func(setup, stmt)
         else:
index e54c53f18eeef783182c3f88d59c0c6e38ee3bbc..8af506548a98d3adc87a121895e1b8013405a8ee 100644 (file)
@@ -1039,7 +1039,7 @@ class Misc:
         for k, v in cnf.items():
             if v is not None:
                 if k[-1] == '_': k = k[:-1]
-                if hasattr(v, '__call__'):
+                if callable(v):
                     v = self._register(v)
                 elif isinstance(v, (tuple, list)):
                     nv = []
@@ -1608,7 +1608,7 @@ class Wm:
         """Bind function FUNC to command NAME for this widget.
         Return the function bound to NAME if None is given. NAME could be
         e.g. "WM_SAVE_YOURSELF" or "WM_DELETE_WINDOW"."""
-        if hasattr(func, '__call__'):
+        if callable(func):
             command = self._register(func)
         else:
             command = func
@@ -3178,7 +3178,7 @@ class Image:
         elif kw: cnf = kw
         options = ()
         for k, v in cnf.items():
-            if hasattr(v, '__call__'):
+            if callable(v):
                 v = self._register(v)
             options = options + ('-'+k, v)
         self.tk.call(('image', 'create', imgtype, name,) + options)
@@ -3201,7 +3201,7 @@ class Image:
         for k, v in _cnfmerge(kw).items():
             if v is not None:
                 if k[-1] == '_': k = k[:-1]
-                if hasattr(v, '__call__'):
+                if callable(v):
                     v = self._register(v)
                 res = res + ('-'+k, v)
         self.tk.call((self.name, 'config') + res)
index 4884e2260b21fdd8360d9fb4f4c16c19ff4c034f..18866c432db1d72bffe5e347db458a6c67f3cf2b 100644 (file)
@@ -405,7 +405,7 @@ class TixWidget(tkinter.Widget):
         elif kw: cnf = kw
         options = ()
         for k, v in cnf.items():
-            if hasattr(v, '__call__'):
+            if callable(v):
                 v = self._register(v)
             options = options + ('-'+k, v)
         return master.tk.call(('image', 'create', imgtype,) + options)
index afdff671643728947cc2c7ea866009b81b6818b5..cb92fd29baf0f8b714eff631983e4bef67ff43ff 100644 (file)
@@ -113,7 +113,7 @@ class TestLoader(object):
                 return self.suiteClass([inst])
         elif isinstance(obj, suite.TestSuite):
             return obj
-        if hasattr(obj, '__call__'):
+        if callable(obj):
             test = obj()
             if isinstance(test, suite.TestSuite):
                 return test
@@ -138,7 +138,7 @@ class TestLoader(object):
         def isTestMethod(attrname, testCaseClass=testCaseClass,
                          prefix=self.testMethodPrefix):
             return attrname.startswith(prefix) and \
-                hasattr(getattr(testCaseClass, attrname), '__call__')
+                callable(getattr(testCaseClass, attrname))
         testFnNames = testFnNames = list(filter(isTestMethod,
                                                 dir(testCaseClass)))
         if self.sortTestMethodsUsing:
index 38bd6b861df726fa97160998041454e8489dfe8e..cde5d385ed1f290f0c3cf040d12f3bd974898e18 100644 (file)
@@ -42,7 +42,7 @@ class BaseTestSuite(object):
 
     def addTest(self, test):
         # sanity checks
-        if not hasattr(test, '__call__'):
+        if not callable(test):
             raise TypeError("{} is not callable".format(repr(test)))
         if isinstance(test, type) and issubclass(test,
                                                  (case.TestCase, TestSuite)):
index 5b5821b1c3d818277ef8fb293fa3b4d83318d139..edbbb5eda4f00ae884c3ed21216d416b2146d107 100644 (file)
@@ -259,7 +259,7 @@ def warn_explicit(message, category, filename, lineno,
         raise RuntimeError(
               "Unrecognized action (%r) in warnings.filters:\n %s" %
               (action, item))
-    if not hasattr(showwarning, "__call__"):
+    if not callable(showwarning):
         raise TypeError("warnings.showwarning() must be set to a "
                         "function or method")
     # Print message and context
index 9477309617817258f554fd6a6f2bb7865e2f16bd..ac252f11d36ebe7e5815ee558b51c989e98c227e 100644 (file)
@@ -149,7 +149,7 @@ def list_public_methods(obj):
 
     return [member for member in dir(obj)
                 if not member.startswith('_') and
-                    hasattr(getattr(obj, member), '__call__')]
+                    callable(getattr(obj, member))]
 
 class SimpleXMLRPCDispatcher:
     """Mix-in class that dispatches XML-RPC requests.
index 6be52fbff95263f0d7646dd951a77045cc7927dd..b3c7fd18aff110303d51e2cdeca9c31fe9ba122e 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -61,6 +61,8 @@ Core and Builtins
 Library
 -------
 
+- Issue #13258: Use callable() built-in in the standard library.
+
 - Issue #13273: fix a bug that prevented HTMLParser to properly detect some
   tags when strict=False.