Repository navigation
Improve OSError constructor #109714
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).
Activity
pitrou commentedon Sep 22, 2023
Hmm, I wouldn't be against it, but the reason I didn't do it at the time is that
errnois the system error indicator at the time was exception was raised. If you synthetize your ownerrnothen it starts meaning something else.Perhaps propose this on Discourse to get more opinions?
serhiy-storchaka commentedon Sep 22, 2023
https://discuss.python.org/t/improve-oserror-constructor/34390
serhiy-storchaka commentedon Sep 22, 2023
See also #109720 -- the changes necessary to pass errno and strerror explicitly.
srittau commentedon Sep 2, 2024
For reference, I think the discussion on Discourse was generally in favor of this (and I agree).
serhiy-storchaka commentedon Aug 26, 2026
#156430 is the implementation.
serhiy-storchaka commentedon Aug 27, 2026
There are two follow-ups:
errnoandstrerrorarguments in existing code. It does not touch the Tools scripts which should be ran by older Python versions.errnoandstrerror. It adds thefilenameargument where it is known instead of including it in the error message, and adds explicit error messages whether the default is less appropriate (for example the default forETIMEDOUTis "Connection timed out", but not allTimeoutErrors are related to connection, and "No such resource" is better than "No such file or directory" inimportlib.resources). In some sense it fixes a mild regression in gh-109714: Improve the OSError constructor #156430.