[Python-Dev] concerns regarding callable() method
Guido van Rossum
guido at python.org
Mon Apr 9 00:52:54 CEST 2007
On 4/8/07, Josiah Carlson <jcarlson at uci.edu> wrote:
> "Guido van Rossum" <guido at python.org> wrote:
> > On 4/8/07, Paul Pogonyshev <pogonyshev at gmx.net> wrote:
> > > Guido van Rossum wrote:
> > > > What if someone passes a callable that doesn't have the expected signature?
> > >
> > > Well, I don't know a way to catch such situations now, so removing
> > > callable() will not make it worse (even if you don't know about hasattr
> > > trick above.)
> > My point is that it's futile to use callable() -- even if it passes,
> > you have no assurance that you actually have a valid callback. So why
> > bother with it at all? It's counter to the spirit of Python. If
> > someone passes you a bad callback, they will see a traceback when you
> > call it. Then they fix their program. That's how it's supposed to
> > work.
> The point of using callable(x), or it's equivalent now of hasattr(x,
> '__call__') is to reduce reduce the time/lines of code between when an
> error occurs and when it is reported.
> Errors should never pass silently.
I'm not sure if that argument weighs much (taken a bit farther it
would require static typing :-). Two arguments made earlier are
- The traceback can be much clearer if it comes from setcallback(x)
rather than from the actual call, much later.
- The pragmatic ability (which often occurs in "DWIM"-ish behavior in
template systems) to do different things depending on whether
something is callable or not. (While in theory I agree with Phillip's
objection that this should be dealt with in a more systematic way, in
practice, at least for Python 2.x, I think it's an "okay" thing to
But the same thing can be said for properties like iterable, or
hashable, and other primitive operations.
FWIW, I haven't given up on doing something with abstract base classes
here. I think they (or interfaces or generic functions, for that
matter :-) provide a more systematic approach than either callable()
or hasattr(x, "__call__").
> While we currently cannot verify that some callable takes the proper
> arguments, number of arguments, etc., we *can* verify that it is
> callable. I think this is a good thing, as allowing the assignment of a
> non-callable to a name that is supposed to be callable is the silent
> passing of an error.
> With relatively minimal effort in Python 3, one could use a function
> signature object (PEPs 3107 and 362) to verify that a callable takes the
> proper number of arguments, expected keyword arguments, etc., which
> while still not allowing one to verify that the implementation of a
> callback is correct (technically impossible), it does get us closer to
> being able to know whether a callable "is" or "may not be" crap when it
> is assigned.
> If you still think that these two operations are undesireable (testing
> the callability, and that a callable takes certain arguments), that's
> fine (I disagree completely). But unless we mangle callables to not
> support these operations, people are probably going to do them anyways;
> especially those who are using annotations, function signature objects,
> etc., in their various frameworks.
> But maybe I'm misreading or reading to much into your statement of "If
> someone passes you a bad callback, they will see a traceback when you
> call it. Then they fix their program. That's how it's supposed to work."
> - Josiah
--Guido van Rossum (home page: http://www.python.org/~guido/)
More information about the Python-Dev