How to import module when module name has a '-' dash or hyphen in it?

Question:

I want to import foo-bar.py, this works:

foobar = __import__("foo-bar")

This does not:

from "foo-bar" import *

My question: Is there any way that I can use the above format i.e., from "foo-bar" import * to import a module that has a - in it?

Asked By: Bala

||

Answers:

In Python 2, you can’t. foo-bar is not an identifier. rename the file to foo_bar.py


It’s possible since Python 3.1+, see Julien’s answer.


If import is not your goal (as in: you don’t care what happens with sys.modules, you don’t need it to import itself), just getting all of the file’s globals into your own scope, you can use execfile

# contents of foo-bar.py
baz = 'quux'
>>> execfile('foo-bar.py')
>>> baz
'quux'
>>> 

Solution: If you can’t rename the module to match Python naming conventions, create a new module to act as an intermediary:

New module foo_proxy.py:

 tmp = __import__('foo-bar')
 globals().update(vars(tmp))

Module doing the import main.py:

 from foo_proxy import * 
Answered By: Raymond Hettinger

If you can’t rename the original file, you could also use a symlink:

ln -s foo-bar.py foo_bar.py

Then you can just do:

from foo_bar import *
Answered By: gitaarik

Starting from Python 3.1, you can use importlib :

import importlib  
foobar = importlib.import_module("foo-bar")

( https://docs.python.org/3/library/importlib.html )

Answered By: Julien

Like other said you can’t use a - in python naming, there are many workarounds, one such workaround which would be useful if you had to add multiple modules from a path is using sys.path

For example if your structure is like this:

foo-bar
├── barfoo.py
└── __init__.py

import sys
sys.path.append('foo-bar')

import barfoo
Answered By: Reda Drissi

in Python 3.6
I had the same problem "invalid syntax" when directly

import 'jaro-winkler' as jw

said
"No module named 'jaro-winkler'" when using:

jw = __import__('jaro-winkler')

and importlib.import_module() same.

finally i use pip uninstall the jaro-winkler module…just FYI

Answered By: kk120120

This was my scenario: I have a python library cloned in a git submodule which has a dash in its name:

|- python-my-lib
| `- mylib.py
`- my-script.py

It took me a long time to figure out the equivalent of:

# Do NOT use this!
sys.path.insert(1, './my-lib')
from mylib import MyClass

Appending the path is not an option, as it would only work if you run the script within the same directory. If you do /home/user/bin/my-script.py, this will fail.

This is the solution:

import importlib
mylib_module = importlib.import_module("python-my-lib.mylib")
MyClass = mylib_module.MyClass

Feel free to further improve this solution, if you know a simpler solution.

Answered By: NicoHood

Python has issues with dash -. So use importlib instead.
You can run your test scripts just like this –

# importlib, because python has issues with dash '-' in module names
import importlib
img2txt = importlib.import_module("img2txt-textextractor")

event_with_txt = {...}

event_with_no_txt = {...}


def test_no_text():
    response = img2txt.handler(event=event_with_txt, context='')
    assert response["body"] == '"Detect Me If You Can. "'

def test_detected_text():
    response = img2txt.handler(event=event_with_no_txt, context='')
    assert response["body"] == '"unable to find anything"'

Name your test code as test_someName.py. To run, from the same directory on terminal type –

pytest
Answered By: ashraf minhaj
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.