python - import error from a sibling folder - python

I'm working on a python 3.8.5 project which has this folder structure:
project/
├── __init__.py
|── foo.py
|── bar.py
├── utils/
│ ├── __init__py
│ └── configurator.py
└── server/
├── __init__.py
├── models.py
In server/models.py I need to use a class Configurator declared inside utils/configurator.py:
# server/models.py
from utils.configurator import Configurator
# some code here ...
Unfortunately I get this error: ModuleNotFoundError: No module named 'utils'. I dont't understand how it cannot find the utils module since I've properly set the init.py file inside that folder.
I've also tried with relative import:
# server/models.py
from ..utils.configurator import Configurator
# some code here ...
this time getting the following error: ImportError: attempted relative import with no known parent package
Finally, I've attempted with an absolute import, with no results again:
# server/models.py
from projects.utils.configurator import Configurator
# some code here ...
The error this time is: ModuleNotFoundError: No module named 'projects'
Based on this previous question it seems correct to me, I can't understand what I'm messing with.
My code editor is Visual Studio Code and when I type from utils. ... it gives the right suggestion, although I don't think this piece of information could be of any utility.

Related

Relative path ImportError when trying to import a shared module from a subdirectory in a script

I am trying to import a util package one directory up from where my code is, but I get an ImportError which I don't understand.
I have a number of different variations on the import syntax in Python, none of which are working.
There are a number of similar questions on Stack Overflow, but none have helped me understand or fix this issue.
Of the top of my head, I have tried the following variations:
import util
import ..util
from .. import util
from ..util import parser
from AdventOfCode2022 import util
from ..AdventOfCode2022 import util
from ...AdventOfCode2022 import util
Most of these I guessed wouldn't work, but I tried them anyway to be sure.
Error message:
ImportError: attempted relative import with no known parent package
Directory structure:
.
├── day03
│ ├── input.txt
│ ├── part1.py
│ ├── part2.py
│ └── test_input.txt
└── util
├── __init__.py
└── parser.py
I just want to import my util package from any "day0*/" directory - not sure why Python makes it so hard!
Two options:
Add the full path to ./util/ to your PYTHONPATH environment variable.
For example on Bash, your ~/.bashrc might have export PYTHONPATH="${PYTHONPATH}:/Users/foobar/projects/advent-of-code/util/".
Add sys.path.append('/path/to/application/app/folder') before the import.
The other solutions don't work because:
day03 and the parent directory are not modules with their own __init__.py. Lines like from ..util import parser only work if everything involved is a module.
You are presumably running the code from within ./day03/.
View this as 'I have a bunch of independent Python projects (day01, day02 etc) that all want to share a common piece of code I have living in a different project (util) that lives somewhere else on my computer.'

How do you import a class from another folder? + ImportError: attempted relative import with no known parent package

I have the following folder structure
parent Folder
├── __init__.py
├── app_folder
│ └── file_1.py
│ └── __init__.py
└── Model_Folder
└── model.py
└── __init__.py.py
I have a class_object in model.py and I want to use it in file_1.py
I have setup Model_Folder/init.py as follows:
from .model import class_object
I have setup Parent\ Folder/init.py as follows:
from Model_folder import class_object
now when I call the class_object from file_1.py I use this code:
from .. import class_object
but i receive this error:
ImportError: attempted relative import with no known parent package
Its worth mentioning that I have created a test file under the parent folder and called the class_object and it worked fine with no errors but I cant do the same for file_1.py. And the IDE does seem to have read it successfully without flagging any errors.
Moreover, I tried the following as well with the same error
from ..Model_Folder.model import class_object
from ..Model_Folder import class_object
so how do I import class_object in file_1? and what am I doing wrong?
I've had similar issues and I've created an experimental new import library ultraimport that allows to do file system based imports to solve your issue.
In your file_1.py you would then write:
import ultraimport
class_object = ultraimport('__dir__/../Model_Folder/model.py', 'class_object')
This will always work, no matter how you run your code or what is your current working directory. You would also not need the __init__.py files but you could use them of course if you wanted to.

Unable to create a import module

I was having trouble with circular dependencies, only to find some advice online that I'm better off importing an entire module rather than specific items within a module. Prior to the circular dependency issue, I was having no issue with imports.
So with the blog's advice, I setup a __init__.py in a folder containing a few models, imported each there, and now when I try to import from that module, I'm being told that module doesn't have an attribute I'm looking for.
So I have this file structure:
└── root
├── models
│ ├── __init__.py
│ ├── a.py
│ └── b.py
└── c.py
In __init__.py, I have
from models.a import A
from models.b import B
And in c.py
import models
# code
models.A.func()
But I get the error module 'models' has no attribute 'A'. As A and B both reference each other, I was getting circular imports at first, but now that they're resolved, I can't get the models to show up at all.
You either need to add your project's directory to PYTHONPATH or you need to do
from . import models
your __init__.py file doesn't require any change. I think in c.py file, type as follows :
modele_name.function_name()
If u have imported that function in your __init__.py file, this will help you, I suppose.
For more details, please edit your question and add the git link of your repo

ModuleNotFound: No module named 'module_name'

My project structure is the following:
.
└── project name
├── project name
│ ├── __init__.py
│ ├── module.py
│
├── PACKAGE_A
│ ├── __init__.py
│ ├── PACKAGE_A.py
│ ├── module_a.py
│
In PACKAGE_A.py
from module_a import Some_Class
a = Some_Class()
class Another_Class:
# class code here
In module.py
"""
Notes
-----
https://stackoverflow.com/questions/16780014/import-file-from-parent-directory
"""
# Standard library imports
import os, sys
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
# Local application imports
from PACKAGE_A.PACKAGE_A import Another_Class
from PACKAGE_A.module_a import some_function
While module_a.py and PACKAGE_A.py run without problem, running module.py fails with:
Traceback (most recent call last):
File "path\to\project name\project name\module.py", line 12, in <module>
from PACKAGE_A.PACKAGE_A import Another_Class
File "path\to\project name\PACKAGE_A\PACKAGE_A.py", line 1, in <module>
from module_a import Some_Class
ModuleNotFoundError: No module named 'module_a'
What am I doing wrong here?
You need to change your import statement in PACKAGE_A.py from:
from module_a import Some_Class
to:
from PACKAGE_A.module_a import Some_Class
The reason is that you are adding the path\to\project name\ to sys.path, but you have no module_a.py in path\to\project name\, and path\to\project name\PACKAGE_A (where module_a.py resides) is not in sys.path.
As for why you succeed in running everything in PACKAGE_A, it's because Python adds the directory containing the script you are running to the list (as explained by gaFF).
I would recommend you read a bit more about python imports, if the doc seems too cluttered, you can check this link.
This is a personal preference, but I find it simpler to add the root directory of the project to the PYTHONPATH environment variable and then running all the scripts from that directory's level and changing the import statements accordingly. In your example, the root directory would be path\to\project name\.
import search for your packages in specific places, listed in sys.path. See the doc for the full details.
The current directory is always appended to this list, that's why you succeed to run everything inside PACKAGE_A. But from project name, there is no way to know where to find PACKAGE_A.
Solutions include:
use relative import
always run from the root directory (and start all your imports from the root directory)
add the root directory to the environment variable PYTHONPATH (same)
use a tool which sets PYTHONPATH when you enter your virtual environment (same)
...
and depends on your project and your needs.

Python3 imports

I am looking for a way to import modules so that I can run a script both from the sub-folder project/v0 and from the root folder project
My file structure in python 3.6 (which is why there are no init files)
project
├── api.py
├── v0
│   ├── SearchEngine.py => contains SearchEngine class
│   └── SearchEngineBE.py
My SearchEngineBE.py module contains
from SearchEngine import SearchEngine
My api.py module contains
from v0.SearchEngineBE import SearchEngineBE
step1: When from project/v0 I run python3 SearcheEngineBE.py my module is correctly imported and everything goes well.
step2: However, when from project I run python3 run api.py I get the error:
Traceback (most recent call last):
File "api.py", line 3, in <module>
from v0.SearchEngineBE import SearchEngineBE
File "/xxx/project/v0/SearchEngineBE.py", line 3, in <module>
from SearchEngine import SearchEngine
ModuleNotFoundError: No module named 'SearchEngine'
How can I fix this so that both step 1 and step 2 would work ?
Non-relative imports are searched by the interpreter in the current directory (and any additional search paths).
You could use relative imports in your SearchEngineBE.py file to let the interpreter know you want the relative module, and not a module off the import path:
# SearchEngineBE.py
from .SearchEngine import SearchEngine
The . lets the interpreter know that you are referencing a module relative to the current module. You'll need at least a blank __init__.py file in the same directory as SearchEngine.py for relative imports to work though:
The __init__.py files are required to make Python treat directories
containing the file as packages.
https://docs.python.org/3/tutorial/modules.html
See this guide for some more discussion: https://chrisyeh96.github.io/2017/08/08/definitive-guide-python-imports.html#absolute-vs-relative-import
Edit:
Without a root package, this won't work. See this post for an alternative approach: Importing modules from a neighbouring folder in Python
Add __init__.py to make it a package.
(it could be empty file : __init__.py)
project
├── __init__.py
├── api.py
├── v0
│ ├── SearchEngine.py => contains SearchEngine class
│ └── SearchEngineBE.py
Edit 1:
try :
from project.v0.SearchEngine import SearchEngine

Categories

Resources