Modules in the same package cannot import each other - python

I am currently using Python 3.7.
My project has the following structure:
runner.py
pkg1/
__init__.py (empty)
mod1.py
mod1_helpers.py
In mod1.py:
import mod1_helpers
# call some functions in mod1_helpers.py
In runner.py:
import pkg1.mod1
When I run runner.py, Python threw the following error:
File "..\pkg1\mod1.py", line 1, in <module>
import mod1_helpers
ModuleNotFoundError: No module named 'mod1_helpers'
The issue resolves when I manually add the path to pkg1 to sys.path in runner.py.
Could someone please advise the proper way to resolve this issue?

Since they're in the same directory you have to prefix import of mod1_helpers with a .
try this:
import .mod1_helpers

Related

Python ModuleNotFoundError when importing custom modules

I have the following project structure
Project Structure
In utils.py I am importing a parse function form parser.py file like this
from logica.parser.parser import parse
In builder.py I am importing a function from utils.py that uses the parser function like this
from utils.utils import utils
When trying to run all this stuff I get a ModuleNotFoundError:
ModuleNotFoundError: No module named 'logica'
Do you guys have any ideas on how to resolve the issue?
Thanks
In Python you can only import modules installed via pip or files stored in the same directory of the current file.
To solve this problem you can do this:
import sys
sys.path.append(<path-of-the-module>)
I would suggest to read also this.

Python Module System - Import Sibling Subpackage

In Python, I want a file in a subpackage to import a sibling subpackage. Like so:
/proj
__init__.py
runner_main.py
/subpackageA
__init__.py
helper.py
/subpackageB
__init__.py
runnerB.py
In runner_main.py, I can call import subpackageA just fine.
However, calling from . import subpackageA fails with error
ImportError: cannot import name 'preprocessing' from '__main__'
This isn't a problem, except I want to import helper.py from runnerB. Calling from .. import subpackageA fails with a similar error.
I don't want to put /proj on my system or Python path; I want it to work as a standalone package. How can I make this simple case work?
Try
from subpackageA import classA, functionB, constantC
It depends on where you run your code. You can import helper.py from runnerB. But If you run runnerB directly, it will gives you same error as you described. However If you run from any py file placed in the parent directory that import runnder module, it will work.

Import error with unit tests: "No module named ..." from local libary

I'm new to Python (JS developer) and am trying to run a testing suite. My project folder structure is as such:
project/
__init__.py
libs/
__init__.py
s3panda.py
tests
__init__.py
tests_s3panda.py
In terminal, I'm running python tests_s3panda.py.
I don't understand how it's unable to find a local module:
Traceback (most recent call last): File "tests_s3panda.py", line 7,
in
from libs.s3panda import S3Panda ImportError: No module named libs.s3panda
tests_s3panda.py snippet:
from __future__ import absolute_import
import unittest
import pandas as pd
from libs.s3panda import S3Panda
class TestS3Panda(unittest.TestCase):
...
Doing from ..libs.s3panda import S3Panda for relative path, I get:
ValueError: Attempted relative import in non-package
I believe the fact that there is no init.py in the top-level folder means that Python is not aware that libs and tests are both part of the same module called project.
Try adding an __init__.py to your project folder, then write the import statement as from project.libs.s3panda import S3Panda. In general, you want to specify absolute imports rather than relative imports (When to use absolute imports).

Relative imports - ModuleNotFoundError: No module named x

This is the first time I've really sat down and tried python 3, and seem to be failing miserably. I have the following two files:
test.py
config.py
config.py has a few functions defined in it as well as a few variables. I've stripped it down to the following:
config.py
debug = True
test.py
import config
print (config.debug)
I also have an __init__.py
However, I'm getting the following error:
ModuleNotFoundError: No module named 'config'
I'm aware that the py3 convention is to use absolute imports:
from . import config
However, this leads to the following error:
ImportError: cannot import name 'config'
So I'm at a loss as to what to do here... Any help is greatly appreciated. :)
TL;DR: You can't do relative imports from the file you execute since __main__ module is not a part of a package.
Absolute imports - import something available on sys.path
Relative imports - import something relative to the current module, must be a part of a package
If you're running both variants in exactly the same way, one of them should work. Here is an example that should help you understand what's going on. Let's add another main.py file with the overall directory structure like this:
.
./main.py
./ryan/__init__.py
./ryan/config.py
./ryan/test.py
And let's update test.py to see what's going on:
# config.py
debug = True
# test.py
print(__name__)
try:
# Trying to find module in the parent package
from . import config
print(config.debug)
del config
except ImportError:
print('Relative import failed')
try:
# Trying to find module on sys.path
import config
print(config.debug)
except ModuleNotFoundError:
print('Absolute import failed')
# main.py
import ryan.test
Let's run test.py first:
$ python ryan/test.py
__main__
Relative import failed
True
Here "test" is the __main__ module and doesn't know anything about belonging to a package. However import config should work, since the ryan folder will be added to sys.path.
Let's run main.py instead:
$ python main.py
ryan.test
True
Absolute import failed
And here test is inside of the "ryan" package and can perform relative imports. import config fails since implicit relative imports are not allowed in Python 3.
Hope this helped.
P.S.: If you're sticking with Python 3 there is no more need for __init__.py files.
You have to append your project's path to PYTHONPATH and make sure to use absolute imports.
For UNIX (Linux, OSX, ...)
export PYTHONPATH="${PYTHONPATH}:/path/to/your/project/"
For Windows
set PYTHONPATH=%PYTHONPATH%;C:\path\to\your\project\
Absolute imports
Assuming that we have the following project structure,
└── myproject
├── mypackage
│ ├── __init__.py
│ ├── a.py
└── anotherpackage
├── __init__.py
├── b.py
├── c.py
└── mysubpackage
├── __init__.py
└── d.py
just make sure to reference each import starting from the project's root directory. For instance,
# in module a.py
import anotherpackage.mysubpackage.d
# in module b
import anotherpackage.c
import mypackage.a
For a more comprehensive explanation, refer to the article How to fix ModuleNotFoundError and ImportError
I figured it out. Very frustrating, especially coming from python2.
You have to add a . to the module, regardless of whether or not it is relative or absolute.
I created the directory setup as follows.
/main.py
--/lib
--/__init__.py
--/mody.py
--/modx.py
modx.py
def does_something():
return "I gave you this string."
mody.py
from modx import does_something
def loaded():
string = does_something()
print(string)
main.py
from lib import mody
mody.loaded()
when I execute main, this is what happens
$ python main.py
Traceback (most recent call last):
File "main.py", line 2, in <module>
from lib import mody
File "/mnt/c/Users/Austin/Dropbox/Source/Python/virtualenviron/mock/package/lib/mody.py", line 1, in <module>
from modx import does_something
ImportError: No module named 'modx'
I ran 2to3, and the core output was this
RefactoringTool: Refactored lib/mody.py
--- lib/mody.py (original)
+++ lib/mody.py (refactored)
## -1,4 +1,4 ##
-from modx import does_something
+from .modx import does_something
def loaded():
string = does_something()
RefactoringTool: Files that need to be modified:
RefactoringTool: lib/modx.py
RefactoringTool: lib/mody.py
I had to modify mody.py's import statement to fix it
try:
from modx import does_something
except ImportError:
from .modx import does_something
def loaded():
string = does_something()
print(string)
Then I ran main.py again and got the expected output
$ python main.py
I gave you this string.
Lastly, just to clean it up and make it portable between 2 and 3.
from __future__ import absolute_import
from .modx import does_something
Setting PYTHONPATH can also help with this problem.
Here is how it can be done on Windows
set PYTHONPATH=.
You can simply add following file to your tests directory, and then python will run it before the tests
__init__.py file
import os
import sys
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
Set PYTHONPATH environment variable in root project directory.
Considering UNIX-like:
export PYTHONPATH=.
Tried your example
from . import config
got the following SystemError:
/usr/bin/python3.4 test.py
Traceback (most recent call last):
File "test.py", line 1, in
from . import config
SystemError: Parent module '' not loaded, cannot perform relative import
This will work for me:
import config
print('debug=%s'%config.debug)
>>>debug=True
Tested with Python:3.4.2 - PyCharm 2016.3.2
Beside this PyCharm offers you to Import this name.
You hav to click on config and a help icon appears.
If you are using python 3+ then try adding below lines
import os, sys
dir_path = os.path.dirname(os.path.realpath(__file__))
parent_dir_path = os.path.abspath(os.path.join(dir_path, os.pardir))
sys.path.insert(0, parent_dir_path)
Declare correct sys.path list before you call module:
import os, sys
#'/home/user/example/parent/child'
current_path = os.path.abspath('.')
#'/home/user/example/parent'
parent_path = os.path.dirname(current_path)
sys.path.append(parent_path)
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'child.settings')
I am working in a Linux machine. I had the same issue when I run python my_module/__main__.py.
The error is fixed, if you run the command export PYTHONPATH=. before your run your script.
export PYTHONPATH=.
python my_module/__main__.py
Try
from . import config
What that does is import from the same folder level. If you directly try to import it assumes it's a subordinate
This example works on Python 3.6.
I suggest going to Run -> Edit Configurations in PyCharm, deleting any entries there, and trying to run the code through PyCharm again.
If that doesn't work, check your project interpreter (Settings -> Project Interpreter) and run configuration defaults (Run -> Edit Configurations...).
As was stated in the comments to the original post, this seemed to be an issue with the python interpreter I was using for whatever reason, and not something wrong with the python scripts. I switched over from the WinPython bundle to the official python 3.6 from python.org and it worked just fine. thanks for the help everyone :)
You may use these statements to set the working directory, which worked for me with python3
import os
import sys
sys.path.insert(1, os.getcwd())
For me, simply adding the current directory worked.
Using the following structure:
└── myproject
├── a.py
└── b.py
a.py:
from b import some_object
# returns ModuleNotFound error
from myproject.b import some_object
# works
In my experience, PYTHONPATH environment variable does not work everytime.
In my case, my pytest only worked when I added the absolute path:
sys.path.insert(
0, "/Users/bob/project/repo/lambda"
)
I see many answers importing sys and os. Here's a not mentioned yet shorter one that GitHub Copilot gave me:
import sys
sys.path.append(__file__.rsplit("/", 1)[0])
Adding this to the top of my python script solved the problem as well.
To have Bash automatically recognise the project dir you're in:
sudo nano ~/.bashrc
OR
sudo nano ~/.bash_profile
At the bottom of the bash file:
function set_pythonpath {
export PYTHONPATH="$(pwd):$PYTHONPATH"
}
PROMPT_COMMAND=set_pythonpath
To save and exit:
Ctrl + X
Y
Test your changes by:
cat ~/.bashrc

Python can't import package

I have a package structure like:
thePackage/
__init__.py
moduleA.py
moduleB.py
moduleC.py
The __init__.py file contains
from . import moduleA
For simplicity I cd into the directory containing the foler thePackage.
When I try to import thePackage I get the error:
Traceback (most recent call last):
File "<ipython-input-10-5fe9a18b3124>", line 1, in <module>
import thePackage
File "C:\thePackage\__init__.py", line 2, in <module>
from . import moduleA
ImportError: cannot import name 'moduleA'
I've read a few posts like
Importing packages in Python, but still can't figure out my problem. The accepted answer in that post suggests I should be able to import the submodule moduleA by import thePackage.moduleA, but when I try this I get the exact same error.
How can I important the package thePackage?
Also, how can I just import moduleA?
from thePackage import moduleA
I encountered the issue while using Spyder and Python3.4.
When I closed and restarted Spyder, I was able to import the package using import thePackage, and I was able to import moduleA using import thePackage.moduleA.
Also, originally when I first tried to import the module using import thePackage, it failed. At this point I might have modified and saved the __init__.py. Then I probably tried to import the module again using import thePackage, but maybe this doesn't always try to import the newly saved versions of thePackage. Thus, I recommend trying
import importlib
importlib.reload(thePackage)
to force the import of the newly saved version of thePackage.
you could try
sudo apt-get install python-setuptools
found it at https://bitbucket.org/pypa/setuptools/issues/368/module-object-has-no-attribute-packaging,
and it helped me when I was having challenges installing pyttsx,

Categories

Resources