[Python-3000] PEP 3100 Comments

Barry Warsaw barry at python.org
Mon May 8 16:52:02 CEST 2006


On Mon, 2006-05-08 at 15:55 +0200, Thomas Wouters wrote:

> Dare I suggest you convince Guido not to remove callable(), then? That
> is, after all, what this discussion is about.

We use callable() and PyCallable_Check() in a couple of places.  I'm not
sure that our uses are enough to keep these alive, since I can think of
alternative implementations that would probably work almost as well.
But I'll explain the general idea anyway in case it's useful to the
discussion.

There are a couple of places where we register callbacks with our
engine.  These callbacks can come from our own code or extensions that
users write.  Some of these callbacks will be called very often, some
not so often (think: every time through the inner loop or occasionally
through an outer loop).

Obviously if someone registers a callback that isn't callable, we don't
want to waste time on every iteration trying to call it, only to catch
whatever error might occur.  So right now we do a
callable()/PyCallable_Check() at the time of registration, and if that
fails, we don't even create the internal (i.e. in C) data structures to
register the callback and thus pay no penalty in the inner loop for
(some class of) bogus callbacks.

One advantage of this is that we have early detection of errors so that
we can complain when the registration occurs instead of some time later
when the first use occurs.  We cannot call the callbacks at the time of
registration, so that's not an option.

Should callable()/PyCallable_Check() go away, then we'd have to rewrite
the callback usage code to throw away or otherwise mark the callback as
unusable on the first use error, so that subsequent iterations through
the loop won't waste time on an unusable callback.  This may not be too
big a deal because obviously, other errors could occur during the use of
the callback that would have to be caught.  The question is whether
those other errors are permanent or temporary errors, and how you would
tell the difference.

What I mean is, if a registered callback isn't callable, that's
obviously a permanent error, so the callback should be disabled.  If you
got some other kind of error, it would be nice to be able to decide
whether that was a temporary error, meaning just this call should be
ignored, or a permanent error causing the callback to be disabled.  The
question then is whether a TypeError is enough to tell the difference.
Maybe not, because TypeErrors can occur for all kinds of reasons, and I
think it would be very difficult to tell whether they occurred because
the callback wasn't callable or some other error deeper into the
execution stack occurred just because we accidentally passed a bogus
argument to the callable.

Perhaps then, if we get rid of callable()/PyCallable_Check() it would be
useful to add a NotCallableError (as a subclass of TypeError?) that
would get thrown should you try to call something that's not callable.
The argument to the exception would be the thing you tried to
erroneously called.

In our use case then, it would be a fairly simple matter of catching
NotCallableError and comparing the argument to the callback we just
tried to call.  If they match, we'd know that a bogus callback was
registered and we could permanently disable it.  If they didn't match,
or it was some other kind of error, we could potentially treat that as a
temporary problem and just skip the callback but not permanently disable
it.

-Barry


-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 309 bytes
Desc: This is a digitally signed message part
Url : http://mail.python.org/pipermail/python-3000/attachments/20060508/a396d4bf/attachment.pgp 


More information about the Python-3000 mailing list