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