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?
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 *
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 *
Starting from Python 3.1, you can use importlib :
import importlib
foobar = importlib.import_module("foo-bar")
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
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
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.
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
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?
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 *
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 *
Starting from Python 3.1, you can use importlib :
import importlib
foobar = importlib.import_module("foo-bar")
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
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
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.
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