Skip to content

Commit bfde98e

Browse files
committed
Introduce inspection.is_callable.
It uses isinstance(x, collections.Callable) where available and falls back to callable(x) otherwise. Also works around Python issue #7624.
1 parent c86b663 commit bfde98e

File tree

2 files changed

+23
-1
lines changed

2 files changed

+23
-1
lines changed

bpython/inspection.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#
2323

2424
from __future__ import with_statement
25+
import collections
2526
import inspect
2627
import pydoc
2728
import re
@@ -31,6 +32,17 @@
3132
from pygments.lexers import PythonLexer
3233
from pygments.token import Token
3334

35+
try:
36+
collections.Callable
37+
has_collections_callable = True
38+
try:
39+
import types
40+
types.InstanceType
41+
has_instance_type = True
42+
except AttributeError:
43+
has_instance_type = False
44+
except AttributeError:
45+
has_collections_callable = False
3446

3547
py3 = sys.version_info[0] == 3
3648

@@ -223,3 +235,13 @@ def is_eval_safe_name(string):
223235
return all(part.isidentifier() for part in string.split('.'))
224236
else:
225237
return all(_name.match(part) for part in string.split('.'))
238+
239+
240+
def is_callable(obj):
241+
if has_instance_type and isinstance(obj, types.InstanceType):
242+
# Work around a Python bug, see issue 7624
243+
return callable(obj)
244+
elif has_collections_callable:
245+
return isinstance(obj, collections.Callable)
246+
else:
247+
return callable(obj)

bpython/repl.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,7 @@ def attr_lookup(self, obj, expr, attr):
363363
def _callable_postfix(self, value, word):
364364
"""rlcompleter's _callable_postfix done right."""
365365
with inspection.AttrCleaner(value):
366-
if hasattr(value, '__call__'):
366+
if inspection.is_callable(value):
367367
word += '('
368368
return word
369369

0 commit comments

Comments
 (0)