0

I want to import a module, only if installed, in a published package and am looking for the proper way.

Several existing questions on optional modules are duped and point here. What's Python good practice for importing and offering optional features? But they all rely on try except ImportError: blocks to work.

More recent discussions on better ways (python version specific) to check for module presence are here: How to check if a python module exists without importing it It gives good ways to check, but they dip into the dangers of ImportError masking module issues, rather than actual non-existence. The general discussion seems centered around stand alone code for one version or another, not a package intended for any version and distribution.

So, if I combine the two discussions I get this:

def module_exists(module_name):
    import sys
    import pkgutil
    import importlib

    if sys.version_info < (3,0):
        return pkgutil.find_loader(module_name) is not None

    elif sys.version_info >= (3,0) and sys.version_info <= (3,3):
        return importlib.find_loader(module_name) is not None

    elif sys.version_info > (3,3):
        return importlib.util.find_spec(module_name) is not None

    return False

My concern is that this seems fragile. Or at least like I'm reinventing a wheel.

Should I just continue using the old answer of the try except ImportError? Because, unlike the second reference's ImportError concerns, I still won't be able to actually use a present module if it errors on import. Or would the polite thing to do be to try and use it and crash because of the problem with the present module, rather than pretend it's not there (ImportError) when it is?

My use case is just to deliver enhanced functionality if a certain module exists under one localization profile of a widely distributed package. I wouldn't want to burden any of the users in other localizations with a requirement of a module that wouldn't help them at all. Normal functionality would continue even without the third-party module.

Community
  • 1
  • 1
Dethpickle
  • 25
  • 4

1 Answers1

0

Use

try:
    import somemodule
except ImportError:
    # handle module not being available

It doesn't really matter whether ImportError is masking a problem with the module or not - you only care if it's importable, so importing it is the best test.

snakecharmerb
  • 47,570
  • 11
  • 100
  • 153
  • Really that simple? So I should ignore the case where someone actually has the module, but it's broken. As in, it's their problem. I'd just proceed as if it wasn't there. – Dethpickle Apr 02 '16 at 15:58
  • I think so - you can't fix their broken module, so ignore it. Otherwise you risk having lots of complicated code that _still_ might not work. – snakecharmerb Apr 02 '16 at 16:08
  • Sounds good to me. And frankly, thats the only explanation that squares with why there isn't a more sensible existing solution _if_ something more sophisticated was actually required. Thanks! – Dethpickle Apr 03 '16 at 21:40