class ModuleNotFoundError(ImportError)
There are many programs out there, including Django, that "carefully import" a module by doing: try: import simplejson except ImportError: import whatever_instead as simplejson # or whatever This is problematic because sometimes an `ImportError` is raised not because the module is missing, but because there's some error in the module, or because the module raises an `ImportError` itself. Then the exception gets totally swallowed, resulting in delightful debugging sessions. What do you think about having an exception `ModuleNotFoundError` which is a subclass of `ImportError`? Then people could `except ModuleNotFoundError` and be sure that it was caused by a module not existing. This will be a much better way of "carefully importing" a module. Would this be backwards-compatible? Ram.
On Mon, Feb 28, 2011 at 1:21 PM, cool-RR <cool-rr@cool-rr.com> wrote:
There are many programs out there, including Django, that "carefully import" a module by doing: try: import simplejson except ImportError: import whatever_instead as simplejson # or whatever This is problematic because sometimes an `ImportError` is raised not because the module is missing, but because there's some error in the module, or because the module raises an `ImportError` itself. Then the exception gets totally swallowed, resulting in delightful debugging sessions. What do you think about having an exception `ModuleNotFoundError` which is a subclass of `ImportError`? Then people could `except ModuleNotFoundError` and be sure that it was caused by a module not existing. This will be a much better way of "carefully importing" a module. Would this be backwards-compatible?
The most problematic issue is actually that the imported module (above, simplejson) itself imports a non-existent module. Since that would still raise ModuleNotFoundError, your proposal doesn't really fix the problem. I think modules raising ImportError for some other reason is rare. What might perhaps help is if ImportError had the name of the module that could not be imported as an attribute. Then the code could be rewritten as: try: import simplejson except ImportError, err: if e.module_name != 'simplejson': raise <backup plan> -- --Guido van Rossum (python.org/~guido)
On 28 February 2011 21:28, Guido van Rossum <guido@python.org> wrote:
On Mon, Feb 28, 2011 at 1:21 PM, cool-RR <cool-rr@cool-rr.com> wrote:
There are many programs out there, including Django, that "carefully import" a module by doing: try: import simplejson except ImportError: import whatever_instead as simplejson # or whatever This is problematic because sometimes an `ImportError` is raised not because the module is missing, but because there's some error in the module, or because the module raises an `ImportError` itself. Then the exception gets totally swallowed, resulting in delightful debugging sessions. What do you think about having an exception `ModuleNotFoundError` which is a subclass of `ImportError`? Then people could `except ModuleNotFoundError` and be sure that it was caused by a module not existing. This will be a much better way of "carefully importing" a module. Would this be backwards-compatible?
The most problematic issue is actually that the imported module (above, simplejson) itself imports a non-existent module. Since that would still raise ModuleNotFoundError, your proposal doesn't really fix the problem.
I think modules raising ImportError for some other reason is rare.
What might perhaps help is if ImportError had the name of the module that could not be imported as an attribute. Then the code could be rewritten as:
try: import simplejson except ImportError, err: if e.module_name != 'simplejson': raise <backup plan>
+1 Michael
-- --Guido van Rossum (python.org/~guido) _______________________________________________ Python-ideas mailing list Python-ideas@python.org http://mail.python.org/mailman/listinfo/python-ideas
-- http://www.voidspace.org.uk/ May you do good and not evil May you find forgiveness for yourself and forgive others May you share freely, never taking more than you give. -- the sqlite blessing http://www.sqlite.org/different.html
On Tue, Mar 1, 2011 at 7:28 AM, Guido van Rossum <guido@python.org> wrote:
What might perhaps help is if ImportError had the name of the module that could not be imported as an attribute. Then the code could be rewritten as:
try: import simplejson except ImportError, err: if e.module_name != 'simplejson': raise <backup plan>
Logged the suggestion: http://bugs.python.org/issue11356 Perhaps it it worth revisiting the old "import x or y or z as whatever" syntax proposal for 3.3, since it could handle this idiom internally (although deciding what, if anything to do for "from" style imports is a hassle) Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia
Nick Coghlan wrote:
Perhaps it it worth revisiting the old "import x or y or z as whatever" syntax proposal for 3.3
+1, as the suggested idiom is getting rather long-winded. Also it gets worse when there are more than two alternatives, since you end up with another nesting level for each fallback.
(although deciding what, if anything to do for "from" style imports is a hassle)
I don't think it would be too bad: from x or y or z import foo, spam, eggs This would first try to find one of the listed modules, and having found it, import it and attempt to bind the specified names. Failures during the binding phase should probably *not* trigger a fallback to the next module, to avoid ending up with a situation where some of the names are imported from one module and some from another. Since the internals of the modules are probably incompatible with each other, that would be a bad thing. -- Greg
Cheers, Nick.
On Tue, Mar 1, 2011 at 10:07 AM, Greg Ewing <greg.ewing@canterbury.ac.nz> wrote:
Nick Coghlan wrote:
Perhaps it it worth revisiting the old "import x or y or z as whatever" syntax proposal for 3.3
+1, as the suggested idiom is getting rather long-winded. Also it gets worse when there are more than two alternatives, since you end up with another nesting level for each fallback.
(although deciding what, if anything to do for "from" style imports is a hassle)
I don't think it would be too bad:
from x or y or z import foo, spam, eggs
This would first try to find one of the listed modules, and having found it, import it and attempt to bind the specified names.
True, I guess it is really only the module naming that differs in cases like ElementTree, which would be handled just fine by the simple approach: import lxml.etree or element.ElementTree or xml.etree.ElementTree as etree from lxml.etree or element.ElementTree or xml.etree.ElementTree import Element If the internal APIs of the resolved modules differ to the point where the latter doesn't work then the longhand form remains available. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia
On Mon, Feb 28, 2011 at 4:28 PM, Guido van Rossum <guido@python.org> wrote:
On Mon, Feb 28, 2011 at 1:21 PM, cool-RR <cool-rr@cool-rr.com> wrote:
There are many programs out there, including Django, that "carefully import" a module by doing: try: import simplejson except ImportError: import whatever_instead as simplejson # or whatever This is problematic because sometimes an `ImportError` is raised not because the module is missing, but because there's some error in the module, or because the module raises an `ImportError` itself. Then the exception gets totally swallowed, resulting in delightful debugging sessions. What do you think about having an exception `ModuleNotFoundError` which is a subclass of `ImportError`? Then people could `except ModuleNotFoundError` and be sure that it was caused by a module not existing. This will be a much better way of "carefully importing" a module. Would this be backwards-compatible?
The most problematic issue is actually that the imported module (above, simplejson) itself imports a non-existent module. Since that would still raise ModuleNotFoundError, your proposal doesn't really fix the problem.
I think modules raising ImportError for some other reason is rare.
What might perhaps help is if ImportError had the name of the module that could not be imported as an attribute. Then the code could be rewritten as:
try: import simplejson except ImportError, err: if e.module_name != 'simplejson': raise <backup plan>
-- --Guido van Rossum (python.org/~guido)
I think modules sometimes raise `ImportError` because of problematic circular imports. The `e.module_name != 'simplejson'` suggestion might miss that, no? Would a combination of the `module_name` suggestion with the `ModuleNotFoundError` suggestion solve it? Ram.
cool-RR wrote:
I think modules sometimes raise `ImportError` because of problematic circular imports.
It might be more logical if the case where the module is found but a requested name is not present in it raised AttributeError or NameError instead of ImportError. I don't think I've ever had a situation where conflating them both into ImportError was helpful. ImportError itself would then have the meaning of the proposed ModuleNotFoundError. -- Greg
participants (5)
-
cool-RR
-
Greg Ewing
-
Guido van Rossum
-
Michael Foord
-
Nick Coghlan