Python not finding local module folders - python

So I have a project that is layed out as followed:
.
└── project
└── src
├── app.py
└── connector
├── update.py
└── connect.py
└── transform
└── dataframes.py
In the project, app.py imports from the transform module which imports from the connector module. However,connector is never found. I imagine this is due to the folder structure.
Does anyone know a work around for this?

Python is bit different than java. To identify a folder as a module you need to have empty __init__.py file inside that folder.
if that file is doesn't exist it is going to throw error that it's not able to find module.
Other options is use pycharm and rather than creating a folder, right click on choose package.

Related

Properly doing relative imports in python

I always have the same problem and I finally want to get rid of it. My folder structure looks like this
project
├── scipts
│ └── folder
│ └── file.py
└── submodules
└── lab_devices
└── optical_devices
└── __init__.py
└── powermeter_driver.py
I now want to include the powermeter_driver.py in file.py. So what I do in the file.py is:
from submodules.lab_devices.optical_devices.powermeter_driver import PowermeterDriver
but this gives ModuleNotFoundError: No module named 'submodules'. I don't want to use
import sys
sys.path.insert(0, '../submodules')
Is there an easy workaround?
The imports will be resolved correctly if you run the script in the correct way, which is from the parent directory and using the -m switch. So you should cd in the parent folder, add __init__.py files as in:
project
├── scripts
└── __init__.py
│ └── folder
└── __init__.py
│ └── file.py
└── submodules
└── __init__.py
└── lab_devices
└── __init__.py
└── optical_devices
└── __init__.py
└── powermeter_driver.py
so that python knows these are packages then run
python -m scripts.folder.file # note no .py
In file.py you can then use the absolute import as you are cause submodules will be detected as a package. You should indeed avoid hacking the sys.path by all means.
You need to consider that if you write from submodules.... this is an absolute import. It means Python starts searching for the submodules in all directories in sys.path. Python usually adds your current working directory as first item to sys.path, so if you cd to your project directory and then run it as a module using python -m it could work.
Of course absolute imports suck if you have files in a relative location to each other. I've had similar issues and I've created an experimental, new import library ultraimport that allows to do file system based imports. It could solve your issue if you are willing to add a new library for this.
Instead of:
from submodules.lab_devices.optical_devices.powermeter_driver import PowermeterDriver
In file.py you would then write:
import ultraimport
PowermeterDriver = ultraimport('__dir__/../../submodules/lab_devices/optical_devices/powermeter_driver.py', 'PowermeterDriver')
The file path is relative to file.py and thus this will always work, no matter how you run your code or what is in sys.path.
One caveat when importing scripts like this is if they contain further relative imports. ultraimport has a builtin preprocessor to rewrite subsequent relative imports so they continue to work.

Python Library - Module Not Found

I'm making a python library and i want to be able to run the code i'm developing, in another folder i have a python file, but I get the error: ModuleNotFoundError: No module named
this is my folder structure
.
└── project
└── library_directory
├── __init__.py
└── main.py
└── examples_directory
├── __init__.py
└── code_directory
├── __init__.py
└── test.py
init.py from library_directory
from library_directory.main import Class
test.py file
from library_directory import Class
when I run test.py file it says: ModuleNotFoundError: No module named 'fpdf_table'
if i put test.py file at project level this configuration of init and test works, but i want to run the test.py in the code_directory because i will have a lot of files and don't want 15+ single files at project level
.
└── project
└── library_directory
├── __init__.py
└── main.py
└── examples_directory
├── __init__.py
└── code_directory
├── __init__.py
└── test.py
i already tried absolute and relative imports but they don't work
Im not sure if this is the correct solution, but you can try this:
In your test module:
import sys
sys.path.insert(0, '/Your_project_root_path'
Now can access to the packages in the root directory.
I took this solution from here.
Your library_directory folder is a Python package. Within the package, each .py file is a module.
In your library_directory/init.py file, insert the line from .main import Class. Now you have a package called "library_directory", which has a module called "Main", and a class called "Class".
Now, in your environment variables, create a user variable called PYTHONPATH and add to this, the path to your project directory.
When you import in your project file, you should import using the structure: from package.module import class, or in your case: from library_directory.main import Class. The python interpreter will be able to find the package due to being in your PYTHONPATH and the init file directory means Python will recognise it as a package.
(You may wish to rename "library_directory" to be a bit more project specific)

How to make Python try to load modules from local folder?

I have a Python package that has CLI interface. I would like to work on the package locally and add some features. What is the best way to setup the development environment so that the cli loads the modules defined in the local folder?
.
├── __init__.py
├── cli.py
├── diff_augment.py
├── diff_augment_test.py
├── lightweight_gan.py
└── version.py
python cli.py
ModuleNotFoundError: No module named 'lightweight_gan.diff_augment'; 'lightweight_gan' is not a package
If I start up cli.py (python cli.py) it is going to try to load all the modules from the virtualenv instead from the local folder. Is there a way to make Python load the modules first from the local folder?

How do I structure my python project such that my test files can import the packages in the root folder?

I would like to integrate pytest into my workflow. I made a following folder structure:
myproject
├── venv
└── src
├── __init__.py
├── foo
│ ├── __init__.py
│ └── bar.py
└── tests
├── __init__.py
└── test_bar.py
I would like to be able to import the namespace from the foo package so that I can write test scripts in the tests folder. Whenever I try to run pytest, or pytest --import-mode append I always get the following error:
ModuleNotFoundError: No module named 'foo'
I found this similar question here but adding the __init__.py files to the tests and the src folder does not solve the issue.
Does this have to do with the PYTHONPATH system variable? This folder structure works perfectly if I run the __main__.py from the src folder, but fails when I want to use pytest. Is there a way to do this without having to mess with PYTHONPATH or are there automated ways to edit the system variable?

ModuleNotFoundError when running individual Python files with absolute imports

ModuleNotFoundError running Python 3.8.x
I'm building a python package containing classes and functions each with verbose tests. Inside the package I'm trying to use these building blocks to provide end-to-end uses and examples by using absolute imports at the top of these files (like in my tests).
The project structure is as follows:
.
├── __init__.py
├── setup.py
├── examples
│   ├── __init__.py
│   └── end_to_end_1.py
├── tests
│ ├── __init__.py
│   └── utils
│ ├── __init__.py
│ ├── test_useful_one.py
│ └── test_useful_two.py
└── utils
├── __init__.py
├── useful_one.py
└── useful_two.py
I'm running all tests from the package root using python -m unittest tests/**/*.py, and both test files contain absolute package imports from utils like so,
from utils.useful_one import UsefulClass
this approach is succesful in running the tests and importing the UsefulClass class into the test files.
My issue arises when trying to use the same import statement inside the examples/end_to_end_1.py module and executing the file (again from the root of the package) using
python examples/end_to_end_1.py
Now I get a runtime ModuleNotFoundError: No module named 'utils'.
In trying to follow the python language guidelines I'm trying to use absolute imports where possible but to no avail.
I have definitely misunderstood how the __init__.py files are supposed to tell the runtime where to resolve packages from. I don't think this use case is abnormal, since I see this same pattern inside node packages and ruby gems all the time.
Makeshift (Temporary) Solution
At the moment to solve this I have applied the solution from Absolute import results in ModuleNotFoundError which, despite working, seems not too scalable when the repository is publically available and I feel like the Python ecosystem will have a solution for this issue. As Raymond Hettinger says, it feels like..
There must be a better way!

Categories