When to use exceptions (was Re: reducing if statements...)

tanzer at swing.co.at tanzer at swing.co.at
Fri Aug 24 11:26:13 EDT 2001


"Andrew Dalke" <dalke at dalkescientific.com> wrote:

> Christian Tanzer:
> > I'd strongly prefer a IOError exception hierarchy with one exception
> > class for each different errno value to the current situation. You
> > could still catch IOError, but you could also just catch the odd
> > DeviceFull or PermissionDenied exception and leave all others to your
> > caller.
> 
> Paul Rubin:
> >This makes sense to me.
> 
> I believe though that it's complicated to implement while not
> giving much additional power.
> 
> How would it be implemented?  There would need to be a mapping
> from errno to class, and you want the classes to be named DeviceFull
> or similarly readable names, rather than ENOSPC.  So all C-level
> code raising an exception would need to call this mapping and
> construct the appropriate subclass.  And if the errno doesn't
> exists, fall back to use the IOError class it uses now.

    class NoSuchFail(IOError) : pass
    class PermissionDenied(IOError) : pass
    class NotADirectory(IOError) : pass

    IO_Exception_Map  = { 2 : NoSuchFile
                        , ...
                        , 13 : PermissionDenied
                        , ...
                        , 20 : NotADirectory
                        }

The code raising an I/O exception just would use the C equivalent of

    raise IO_Exception_Map.get(errno, IOError), (errno, message)

> That's doable, just more complicated, but the advantage is being
> able to do
> 
> try:
>   f(x)
> except DeviceFull:
>   ...
> except PermissionDenied:
>   ...
> except TextBusy:
>   ...

Looks much better to me than catching IOError and then analysing the
errno. 

> Now suppose you're on a system which doesn't have a TextBusy
> (errno == ETXTBSY, "if one tries to exec() a file that is currently
> open for writing").  Since the errno doesn't exist, should the
> TextBusy subclass exist?  If it doesn't, then on some machines
> there will be a NameError for TextBusy.
> 
> So to catch those problems you'll need to have a generic
> 
> def check(err):
>     return errno.errcode.get(err.errno)
> 
> 
> except IOError, err:
>     if check(err) == "ETXTBSY":
>         ...

I can't follow. The IO_Exception_Map could still map ETXTBSY to
TextBusy -- that this exception isn't raised on a specific system
shouldn't be a problem for anybody, should it? 

-- 
Christian Tanzer                                         tanzer at swing.co.at
Glasauergasse 32                                       Tel: +43 1 876 62 36
A-1130 Vienna, Austria                                 Fax: +43 1 877 66 92





More information about the Python-list mailing list