Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

the pythonic way of optional imports

Tags:

python

import

I have a package that allows the user to use any one of 4 packages they want to connect to a database. It works great but I'm unhappy with the way I'm importing things.

I could simply import all the packages, but I don't want to do that in case the specific user doesn't ever need to use turbodbc for example:

import pyodbc
import pymssql
import turbodbc
from ibmdbpy.base import IdaDataBase

Currently, I have the following situation. I try to import all of them, but the ones that don't import, no problem, My program simply assumes they will not be called and if they are it errors:

# some envs may not have all these packages installed so we try each:

try:
    import pyodbc
except:
    pass

try:
    import pymssql
except:
    pass

try:
    import turbodbc
except:
    pass

try:
    from ibmdbpy.base import IdaDataBase
except:
    pass

This doesn't feel pythonic. So I know there are packages such as holoviews or tensorflow that allow you to specify a backend. They are of course orders of magnitude more complicated than mine, but they have to handle the same pattern.

How can I make this code right? it is technically buggy because if they intend to use pyodbc but don't have it installed, my program will not warn them, it will error at runtime. So really this goes beyond esthetics or philosophy; this is technically error-prone code.

How would you handle this situation?

Fyi, here is an example of how the code is called:

connect('Playground', package='pymssql')
like image 755
Legit Stack Avatar asked Dec 18 '22 20:12

Legit Stack


1 Answers

try: 
    import pyodbc
except ImportError: 
    pyodbc = None

then later:

if pyodbc is None and user_wants_to_use_pyodbc:
    print_warning()
    raise SomeConfigurationErrorOrSuch()

This approach works well for a small number of options. If you have enough options that you need to abstract out this approach, then you can use the importlib module to import modules under the control of your program.

like image 87
Sam Hartman Avatar answered Jan 02 '23 09:01

Sam Hartman