
As a user you are talking about in the PEP, i'm quite satisfied with the current implementation. The only change i see worth considering is concatenating IOError and OSError, possibly with EnvironmentError. It's worth giving EnvironmentError a better name too. I strongly oppose introducing 'fine-grained' exceptions. As an exception user, i care about: 1) brief, easy to remember exception hierarchy with clearly distinguished domains 2) intuitive, natural-looking handling 3) simple way to know which exceptions are thrown by a code IMO, the current implementation covers 2) excellently, 1) and 3) only have IOError/OSError ambiguities. 1)) OSError and IOError do intersect in the OS's PoV. The only reason why they're separate is because they 'feel' different. Historically, I/O and OSes come different ways: OSes are almost purely software and I/O technologies are primarily hardware-based. So, 'OSError' looks like something that is meaningful only to software logic and 'IOError' - like something that has a physical incarnation. Both OSError can be thought as part of IOError and vice versa so neither is likely to meet consensus to be made a subclass of the other. So we either 1) declare the above 'feelings' retrograde and fuse the types. In this case, EnvironmentError will become redundant so we'll have to fuse it in too; 2) just use EnvironmentError for all ambiguous cases and give it a better name. The current one is just wa-a-a-y t-o-o-o lo-o-o-ong for ubiquitous usage. 2)) The 'neat' handling except OSError,e: if e.errno==EEXIST: act() else: raise looks the most natural solution to me as all OSErrors are perceived as errors of the same type (errors caused by external factors and received as error codes from the OS standard API). Adding errno-specific subexceptions 1) makes some errnos privileged at the expense of others 2) introduces a list that isn't bound to any objective characteristic and is just an arbitrary "favorites" list 3) adds types that characterize single errors rather than error classes which is an unnecessary level of complexity. 3)) Builtin I/O operations throw IOError, OS function wrappers throw OSError, package functions throw package-specific ones - quite obvious where to expect which. There's EnvironmentError for any ambiguities, the only reason against it is the long and unusual name.