[Python-ideas] `issubclass` shouldn't be raising exceptions for non-type inputs

Nick Coghlan ncoghlan at gmail.com
Tue Nov 30 02:55:58 CET 2010


On Tue, Nov 30, 2010 at 3:35 AM, Bill Janssen <janssen at parc.com> wrote:
> Steven D'Aprano <steve at pearwood.info> wrote:
>
>> since at least Python 1.5. It's been long considered "best practice"
>> under many circumstances to catch exceptions rather than to try to
>> preemptively guess what might go wrong.
>
> You're kidding, right?  *Programming* is about preemptively guessing
> what might go wrong :-).

LBYL (Look Before You Leap) and EAFPI (Easier to Ask Forgiveness than
Permission) is a style argument that is never going to go away though,
since the answer is "it depends".

My personal answer is usually "make the common case fast". That means
defaulting to using a try-except block (with an else clause to prevent
overreaching) since the overhead of a try-except that doesn't need to
catch an exception is close to zero and the exception normally
reflects the uncommon case. However, since raising and catching an
exception is quite expensive, if it is a situation where average
and/or worst-case performance matters more than common case
performance, testing a condition first may start to appear more
attractive if the preemptive check is faster than the exception
handling would be.

One thing to keep in mind, though, is that some pre-emptive checks are
using the moral equivalent of a try/except block under the covers
(with hasattr() being the classic example of this), so the performance
gain in the exceptional case actually isn't all that great. You really
need to profile it to figure out which is faster.

You do need to take care that the try/except isn't covering too much
though, and, depending on how obscure the exception is, potentially
add a comment as to the error condition you're checking for.

As far as the original post's request goes, no. issubclass expects to
be given two types. If you have an insanely polymorphic variable that
can contain a wide variety of objects, only some of which are type
instances, then either use isinstance to check first as you are
already doing, or a try-except block to convert the TypeError to a
False result (and bundle the combined test into a helper function if
you're doing it a lot).

Cheers,
Nick.

-- 
Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia



More information about the Python-ideas mailing list