Author brett.cannon
Recipients Arfrever, asvetlov, barry, brett.cannon, chris.jerdonek, cvrebert, eric.snow, ezio.melotti, gvanrossum, pitrou, python-dev, serhiy.storchaka
Date 2013-07-01.23:38:20
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1372721900.73.0.117241414476.issue15767@psf.upfronthosting.co.za>
In-reply-to
Content
The impetus of ModuleNotFoundError is the need for something similar in importlib thanks to ``from ... import``. When you do something like __import__('os', fromlist=['path']), any ImportError must be silenced **if** it relates only to the fact that the module can't be found. Other errors directly related to technical errors which also raised ImportError are supposed to propagate.

Before ModuleNotFoundError I was setting a made-up attribute called _not_found on ImportError and then raising the exception. I could then catch the exception and introspect for that case as necessary. See http://hg.python.org/cpython/file/3e10025346c1/Lib/importlib/_bootstrap.py for the last revision that contained _not_found.

Since I had a legitimate case of wanting to differentiate between ImportError (which represents both technical errors and an inability to find a module) and the more specific case of simply not finding a module, I decided to formalize the distinction. It made sense to me so that the old try/except ImportError trick to ignore missing module could not accidentally catch the technical error use of ImportError by accident and mask the problem.

Now if you still think the subclass is not worth it then I probably need a better solution than a faked private attribute on ImportError to delineate the technical error/module not found difference as I had already received one bug report asking to define what _not_found was. ImportError could grow a not_found attribute formally or even a 'reason' attribute which could be set to some enum value representing the fact the exception was triggered because the module simply wasn't found (although that seems unnecessary and more like errno from OSError).

To summarize, the options I see are:

1. Back to _not_found on ImportError (only existed to start with as it was too late in 3.3 to come up with a better solution)

2. Keep ModuleNotFoundError (this option can include reverting all of the ``except ImportError`` changes I made and just allow the exception to exist if you want)

3. Add a not_found attribute to ImportError more formally (defaults to None for undefined, set to True/False to clearly signal when an obvious answer is known)

4. Add a 'reason' attribute that can be set to an enum which has a value which represents "module not found"

I can't easily make it a private exception that I prevent from escaping importlib thanks to trying to allow the accelerated version of import to use importlib's fromlist code (see how _handle_fromlist is called with its import_ argument).
History
Date User Action Args
2013-07-01 23:38:20brett.cannonsetrecipients: + brett.cannon, gvanrossum, barry, pitrou, ezio.melotti, Arfrever, cvrebert, asvetlov, chris.jerdonek, python-dev, eric.snow, serhiy.storchaka
2013-07-01 23:38:20brett.cannonsetmessageid: <1372721900.73.0.117241414476.issue15767@psf.upfronthosting.co.za>
2013-07-01 23:38:20brett.cannonlinkissue15767 messages
2013-07-01 23:38:20brett.cannoncreate