On Mon, 29 Aug 2011 17:18:33 -0400
Barry Warsaw <ba...@python.org> wrote:
> On Aug 24, 2011, at 01:57 AM, Antoine Pitrou wrote:
> 
> >> One guiding principle for me is that we should keep the abstraction as thin
> >> as possible.  In particular, I'm concerned about mapping multiple errnos
> >> into a single Error.  For example both EPIPE and ESHUTDOWN mapping to
> >> BrokePipeError, or EACESS or EPERM to PermissionError.  I think we should
> >> resist this, so that one errno maps to exactly one Error.  Where grouping
> >> is desired, Python already has mechanisms to deal with that,
> >> e.g. superclasses and multiple inheritance.  Therefore, I think it would be
> >> better to have
> >> 
> >> + FileSystemPermissionError
> >>   + AccessError (EACCES)
> >>   + PermissionError (EPERM)
> >
> >I'm not sure that's a good idea:
> 
> Was it the specific grouping under FileSystemPermissionError that you're
> objecting to, or the "keep the abstraction thin" principle?

The former. EPERM is generally returned for things which aren't
filesystem-related.
(although I also think separating EACCES and EPERM is of little value
*in practice*)

>  Let's say we
> threw out the idea of FSPE superclass, would you still want to collapse EACCES
> and EPERM into PermissionError, or would separate exceptions for each be okay?

I have a preference for the former, but am not against the latter. I
just think that, given AccessError and PermissionError, most users
won't know up front which one they should care about.

> It's still pretty easy to catch both in one except clause, and it won't be too
> annoying if it's rare.

Indeed.

> Reading your IRC message (sorry, I was afk) it sounds like you think
> FileSystemError can be removed.  I like keeping the hierarchy flat.

Ok. It can be reintroduced later on.
(the main reason why I think it can be removed is that EACCES in itself
is often tied to filesystem access rights; so the EACCES exception
class would have to be a subclass of FileSystemError, while the EPERM
one should not :-))

> >>>> open("foo")
> >Traceback (most recent call last):
> >  File "<stdin>", line 1, in <module>
> >FileNotFoundError: [Errno 2] No such file or directory: 'foo'
> >
> >(see e.g. http://bugs.python.org/issue12762)
> 
> True, but since you're going to be creating a bunch of new exception classes,
> it should be relatively painless to give them a better str.  Thanks for
> pointing out that bug; I agree with it.

Well, the str right now is exactly the same as OSError's.

> My question mostly was about raising OSError (as the current PEP states) with
> an errno that does *not* map to one of the new exceptions.  In that case, I
> don't think there's anything you could raise other than exactly OSError,
> right?

And indeed, that's what the implementation does :)

> So, for raising OSError with an errno mapping to one of the subclasses, it
> appears to break the "explicit is better than implicit" principle, and I think
> it could lead to hard-to-debug or understand code.  You'll look at code that
> raises OSError, but the exception that gets printed will be one of the
> subclasses.  I'm afraid that if you don't know that this is happening, you're
> going to think you're going crazy.

Except that it only happens if you use a recognized errno. For example
if you do:

    >>> OSError(errno.ENOENT, "not found")
    FileNotFoundError(2, 'not found')

Not if you just pass a message (or anything else, actually):

    >>> OSError("some message")
    OSError('some message',)

But if you pass an explicit errno, then the subclass doesn't appear
that surprising, does it?

> The other half is, let's say raising FileNotFoundError with the EEXIST errno.
> I'm guessing that the __init__'s for the new OSError subclasses will not have
> an `errno` attribute, so there's no way you can do that, but the PEP does not
> discuss this. 

Actually, the __new__ and the __init__ are exactly the same as
OSError's:

>>> e = FileNotFoundError("some message")
>>> e.errno
>>> e = FileNotFoundError(errno.ENOENT, "some message")
>>> e.errno
2

> >Wow, I didn't know ESRCH.
> >How would you call the respective exceptions?
> >- ChildProcessError for ECHILD?
>
[...]
> 
> >- ProcessLookupError for ESRCH?
> 
[...]
> 
> So in a sense, both are lookup errors, though I think it's going too far to
> multiply inherit from LookupError.  Maybe ChildWaitError or ChildLookupError
> for the former?  ProcessLookupError seems good to me.

Ok.

> >> What if all the errno symbolic names were mapped as attributes on IOError?
> >> The only advantage of that would be to eliminate the need to import errno,
> >> or for the ugly `e.errno == errno.ENOENT` stuff.  That would then be
> >> rewritten as `e.errno == IOError.ENOENT`.  A mild savings to be sure, but
> >> still.
> >
> >Hmm, I guess that's explorable as an orthogonal idea.
> 
> Cool.  How should we capture that?

A separate PEP perhaps, or more appropriately (IMHO) a tracker entry,
since it's just about enriching the attributes of an existing type.
I think it's a bit weird to define a whole lot of constants on a
built-in type, though.

> Okay, so here's what's still outstanding for me:
> 
> * Should we eliminate FileSystemError? (probably "yes")

Ok.

> * Should we ensure one errno == one exception?
>   - i.e. separate EACCES and EPERM
>   - i.e. separate EPIPE and ESHUTDOWN

I think that's unhelpful (or downright confusing: what is,
intuitively, the difference between an "AccessError" and a
"PermissionError"?) to most users, and users to which it is helpful
already know how to access the errno.

> * Should the str of the new exception subclasses be improved (e.g. to include
>   the symbolic name instead of the errno first)?

As I said, I think it's orthogonal, but I would +1 on including the
symbolic name instead of the integer.

> * Is the OSError.__new__() hackery a good idea?

I think it is, since it also takes care about Python code raising
OSErrors, but YMMV.

> * Should the PEP define the signature of the new exceptions (e.g. to prohibit
>   passing in an incorrect errno to an OSError subclass)?

The OSError constructor, pre-PEP, is very laxist, and I took care to
keep it like that in the implementation. Apparently it's a feature to
help migrating old code.

> * Can we add ECHILD and ESRCH, and if so, what names should we use?

I think the suggested names are ok.

> * Where can we capture the idea of putting the symbolic names on OSError class
>   attributes, or is it a dumb idea that should be ditched?

I think it's a separate task altogether, although I'm in favour of it.

> * How long should we wait for other Python implementations to chime in?

A couple of weeks? I will soon leave on holiday until the end of
September anyway.

Regards

Antoine.


_______________________________________________
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com

Reply via email to