On Mon, 29 Aug 2011 17:18:33 -0400
Barry Warsaw <[email protected]> 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
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe:
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com