Issue 13258: replace hasattr(obj, 'call') with callable(obj) (original) (raw)

Created on 2011-10-24 19:46 by flox, last changed 2022-04-11 14:57 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
issue13258_callable.diff flox,2011-10-24 19:48 review
issue13258_callable_v2.diff flox,2011-10-24 20:16 review
Messages (10)
msg146320 - (view) Author: Florent Xicluna (flox) * (Python committer) Date: 2011-10-24 19:46
Now that callable() is back in 3.2, we may replace hasattr(obj, '__call__') with callable(obj). The built-in function is easier to read and gives better performance than attribute lookup. $ ./python -m timeit "hasattr(None, '__call__')" 100000 loops, best of 3: 4.09 usec per loop $ ./python -m timeit "hasattr(str, '__call__')" 1000000 loops, best of 3: 1.3 usec per loop $ ./python -m timeit "callable(None)" 1000000 loops, best of 3: 0.299 usec per loop $ ./python -m timeit "callable(str)" 1000000 loops, best of 3: 0.369 usec per loop
msg146321 - (view) Author: Florent Xicluna (flox) * (Python committer) Date: 2011-10-24 19:48
Proposed patch.
msg146323 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2011-10-24 20:07
For packaging I'm not sure it's worth complicating backporting.
msg146324 - (view) Author: Florent Xicluna (flox) * (Python committer) Date: 2011-10-24 20:16
Updated with a special note for "packaging".
msg146326 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2011-10-24 21:44
callable() is not just faster, it's also "more correct": hasattr(obj, "__call__") doesn't call base classes. See callable() of the six module: def callable(obj): return any("__call__" in klass.__dict__ for klass in type(obj).__mro__)
msg146328 - (view) Author: Florent Xicluna (flox) * (Python committer) Date: 2011-10-24 22:18
We have so many alternatives, it's funny ... def callable(obj): return hasattr(obj, '__call__') or hasattr(obj, '__bases__') def callable(obj): return isinstance(obj, collections.abc.Callable) def callable(obj): return hasattr(obj, '__call__') or type(obj) == types.ClassType def callable(obj): return any("__call__" in klass.__dict__ for klass in type(obj).__mro__)
msg146330 - (view) Author: Jesús Cea Avión (jcea) * (Python committer) Date: 2011-10-24 22:23
Is it actually appropiate to commit this to 3.2?. I am neutral to it, just asking.
msg146331 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2011-10-24 22:25
> Is it actually appropiate to commit this to 3.2? If it fixes a bug, the fix should be backported to 3.2.
msg146371 - (view) Author: Éric Araujo (eric.araujo) * (Python committer) Date: 2011-10-25 15:05
This change is fine for packaging. In the 2.x backport I already use callable (and damn the py3k warning) and the 3.x backport uses the incorrect hasattr(inst, '__call__'); I’ll change that to use a backported d2.compat.callable.
msg146557 - (view) Author: Roundup Robot (python-dev) (Python triager) Date: 2011-10-28 12:53
New changeset 8e57b5d8f58f by Florent Xicluna in branch '3.2': Closes #13258: Use callable() built-in in the standard library. http://hg.python.org/cpython/rev/8e57b5d8f58f
History
Date User Action Args
2022-04-11 14:57:23 admin set github: 57467
2011-10-28 12:53:41 python-dev set status: open -> closednosy: + python-devmessages: + resolution: fixedstage: patch review -> resolved
2011-10-25 15:05:40 eric.araujo set messages: +
2011-10-24 22:25:56 vstinner set messages: +
2011-10-24 22:23:53 jcea set nosy: + jceamessages: +
2011-10-24 22🔞38 flox set messages: + stage: patch review
2011-10-24 21:44:57 vstinner set nosy: + vstinnermessages: +
2011-10-24 20:16:12 flox set files: + issue13258_callable_v2.diffmessages: +
2011-10-24 20:07:55 pitrou set nosy: + eric.araujo, pitroumessages: +
2011-10-24 19:48:20 flox set files: + issue13258_callable.diffkeywords: + patchmessages: +
2011-10-24 19:46:14 flox create