[Import-SIG] improving ImportError

Nick Coghlan ncoghlan at gmail.com
Thu Sep 22 01:50:42 CEST 2011


On Thu, Sep 22, 2011 at 7:16 AM, Brett Cannon <brett at python.org> wrote:
> On Wed, Sep 21, 2011 at 13:43, Erik Bray <erik.m.bray at gmail.com> wrote:
>>
>> On Wed, Sep 21, 2011 at 3:06 PM, Eric Snow <ericsnowcurrently at gmail.com>
>> wrote:
>> > Armin Ronacher has an interesting blog post about some of the
>> > challenges of using Python's imports:
>> >
>> > http://lucumr.pocoo.org/2011/9/21/python-import-blackbox/
>> >
>> > In particular, his main point about "not found" vs. "broken" vs.
>> > "problem with inner import" got me thinking.  Would it be a bad idea
>> > to split ImportError into more specific exceptions?  I imagine that
>> > cataloguing the different causes of ImportError and how someone might
>> > react to those differently wouldn't be too hard...
>> >
>> > -eric
>>
>> I agree, more granularity would be good.  Would these additional
>> exceptions be subclasses of ImportError?
>
> They would have to be or this is a non-starter.

Also see PEP 3151 (Antoine's proposed restructuring of OS and IO
exceptions for 3.3) for a discussion of some of the issues and
challenges associated with creating better exception hierarchies when
the exceptions in question may be raised by third party code. Without
careful handling, such changes can become fairly pointless since
people still have to catch the top level exception to correctly handle
the legacy behaviour.

While the hierarchy in this case would be much simpler (base
ImportError vs ImportNotFound vs ImportLoadFailed), the core problem
of raising the right *kind* of error would remain. There's an even
bigger problem in this case, given that we don't have 'errno' to guide
the exception type selection the way that PEP 3151 does.

Once ImportError.module_name is available (and set correctly by the
standard machinery), then that along with the __cause__ and
__context__ attributes can be used to figure out the details of what
went wrong. However, to be completely compatible with third party
import systems, something like Armin's traceback walking approach
would still be needed to decide whether or not the module code ever
started execution.

If we decide to do something about the complex boilerplate needed to
implement fallback modules correctly, I'd prefer that we just address
that directly. "import x or y or x as name" and "from x or y or z
import name" are currently syntax errors, but could fairly readily be
made legal. This is far from a new proposal, but nobody has ever been
interested enough to turn it into reality (i.e. write a PEP and post a
patch).

One huge advantage that dedicated syntax would have is that it could
use a builtin helper function (ala Python 3's __build_class__) to
invoke the correct find_module dance:

>>> import imp
ImportError: No module named none
>>> def import_any(*args):
...     for name in args:
...         try:
...             details = imp.find_module(name)
...         except ImportError:
...             continue
...         return imp.load_module(name, *details)
...     raise ImportError('modules not found: {}'.format(args))
...
>>> x = import_any('none')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 8, in import_any
ImportError: modules not found: ('none',)
>>> x = import_any('none', 'sys')
>>> x
<module 'sys' (built-in)>

Cheers,
Nick.

-- 
Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia


More information about the Import-SIG mailing list