Description
Feature or enhancement
The purpose of introducing multiple OSError subclasses was to allow user to write except FileNotFoundError:
instead of except OSError as e: if e.errno != errno.ENOENT: raise
. OSError constructor now determines the actual type of exception by the errno argument. Of course, you can also call the subclass constructor explicitly. Unfortunately, to get a good exception you need to explicitly specify errno argument: FileNotFoundError(errno.ENOENT, "No usable temporary directory found in %s" % dirlist)
. "Good exception" is an exception which works with code that tests the errno attribute as well as with code that uses isinstance()
. There is a lot of code in the stdlib and in the wild which calls OSError subclass constructors with a single argument or even without arguments. See #109601 for example.
I propose to infer the default value for errno (and maybe for strerror) from exception class. In case if several errno's are mapped to the same exception class, one of them is chosen as the default errno. When you omit errno argument, you may still want to provide filename or other optional arguments. For this, the constructor needs to support keyword arguments. The constructor signature will be a union of the following signatures:
(errno, strerror, /, filename=None, winerror=None, filename2=None)
(strerror, /, *, filename=None, winerror=None, filename2=None)
(*, filename=None, winerror=None, filename2=None)
So, you would be able to write FileNotFound('No such file', filename=path)
or even simply FileNotFound(filename=path)
.