those darn exceptions

steve+comp.lang.python at pearwood.info steve+comp.lang.python at pearwood.info
Sat Jun 25 10:28:55 EDT 2011


Chris Angelico wrote:

> On Sat, Jun 25, 2011 at 10:25 AM, Ben Finney <ben+python at benfinney.id.au>
> wrote:
>> No. The answer is *still* “why, any exception at all”. The name
>> ‘os.read’ could be re-bound at run-time to any object at all, so a code
>> checker that you “point at any given line of code” can't know what the
>> name will be bound to when that line gets executed.
> 
> Sure it can. And KeyboardInterrupt could be raised at any time, too.
> But this is a TOOL, not a deity. If Function X is known to call
> Function Y and built-in method Z, 

Known by whom? You? Me? The author of X, Y or Z? Everybody? The tool?

How is the tool supposed to know which functions are called? What if it
doesn't have access to the source code of Y? It might only be available via
a .pyc file, or it might be written in C, or Fortran, or Java (for Jython),
or C# (for IronPython).

Who is responsible for ensuring that every time the implementation of *any*
of X, Y and Z change, the list of exceptions is updated? What do you think
the chances are that this list will remain accurate after a few years of
maintenance?

Is this list of exceptions part of the API of function X? Should X be held
responsible if Z stops raising (say) AttributeError and starts raising
NameError instead?

Should the *implementation* of X, namely the fact that it calls Y and Z, now
considered part of the public interface?

These are serious questions, not nit-picks. Unless they can be answered
satisfactorily, this hypothetical tool *cannot exist*. It simply won't
work. I believe that you might as well be asking for a deity, because the
tool will need supernatural powers beyond the abilities of ordinary code.

And I haven't even raised the spectre of replacing functions (even builtins)
at runtime, or the use of eval/exec, or any number of other tricks.


> and also raises FooException, then 
> X's list of "most likely exceptions" would be FooException +
> Y.__exceptions__ + Z.__exceptions__. 

Even if you somehow, magically, know that X calls Y and Z, you can't draw
that conclusion. Lists of exceptions don't add like that. Consider:

def Y(a):
    if a is None: raise ValueError
    return a
Y.__exceptions__ = (ValueError,)

def X(a):
    if a is None: raise TypeError
    return Y(a)
X.__exceptions__ = (TypeError,)


You claim that X's "most likely exceptions" are given by X.__exceptions__ +
Y.__exceptions__. Under what circumstances do you think X could raise
ValueError?

For bonus points, identify the lies in the above code. (Hint: there are at
least two.)

    
> It won't be perfect, but it'd be 
> something that could go into an autodoc-style facility. Obviously you
> can fiddle with things, but in _ordinary usage_ this is what it's
> _most likely_ to produce.

All this will do is lull people into a false sense of security as they come
to rely on incorrect and out-of-date information. They'll still be in as
ignorant a position re exceptions as they are now, only they won't know it.


-- 
Steven




More information about the Python-list mailing list