Executing python script from command line: error with imports - python

I have written a small script in Python with Eclipse, and it works when executed from Eclipse. But it doesn't work from command line:
>python test.py argument1 argument2
from src import Tests, ImportError: No module named src
The script is stored with the following folders:
ScriptFolder
.input
.report
.src
..test.py
..Tests
...Test1.py
...Test2.py
..TestUtils
...FileUtils.py
And this is the way I'm doing the imports at test.py:
from src import Tests
from TestUtils import FileUtils
About the init.py files, the one which shares folder with test.py is empty, and the one into Tests folder has this content:
import Test1
import Test2
And the init.py file into TestUtils has this content:
import FileUtils
The problem is that, if I change the line from src import Tests to just import Tests I'm getting error in Eclipse: Unresolved imports: Tests. found at src.Tests
How can I make it work for both Eclipse and command line?

sys.path.append(path_to_src_directory)
This will add a path to default paths where python looks for modules.
Since, currently the path to your src directory is not known to python, it gives No module named src error.
Also, your src directory does not seem to have an __init__.py file.

Related

ModuleNotFoundError: No module named after calling a script from another script

Assume I have the following file structure:
Package/
__init__.py
A.py
B.py
Inside __init__.py I have the following:
__init__.py/
import numpy as np
import pandas as pd
Then I issue the following in the A.py script:
A.py/
from Package import *
However, I receive an error message that no module name Package is defined.
ModuleNotFoundError: No module named Package
I thought from Package import * means running everything in the __init__.py.
I can run the A.py content and use the init import from B.py as I expected.(using from Package import *)
I am using VSCode and Anaconda and my OS is Windows 10.
I can append the project folder every time to my PythonPath using the following commands:
sys.path.append("Path to the Package")
But I do not want to run this piece of code every time.
Can anyone explain what is the problem?
Is this a new problem in Python since I do not recall having such issues in the past?
Because if you run the B.py, the Parent folder of Package folder will be added into the sys.path, be equal to you add sys.path.append("Path to the Package") in the A.py file.
But when you run the A.py, it will add the Package folder instead of the Parent folder of Package folder to the sys.path.
sys.path:
A list of strings that specifies the search path for modules.
Initialized from the environment variable PYTHONPATH, plus an
installation-dependent default.
As initialized upon program startup, the first item of this list,
path[0], is the directory containing the script that was used to
invoke the Python interpreter.
If you are running the python file in debug mode(F5), and the Package folder was the subfolder of your workspace, you can configure the PYTHONPATH in the launch.json file:
"env": {
"PYTHONPATH": "${workspaceFolder}"
},
In your A.py script use just use import file.py and do not use the star. Or, put all your files in a second Package2 directory and use from Package2 import * from your current A.py file.

Python: How to import a class from a parent directory

I am running a python-script that imports a class that I have created. This is the directory order:
Classes
- myClass.py
Scripts
- myScript.py
The first line of myScript.py reads:
from Classes.myClass import myClass
I have also tried:
import sys
sys.path.append('..')
from Classes.myClass import myClass
And I have tried to include an empty __init__.py file to the Classes folder.
With any of these ways, I end up with the error message:
" ModuleNotFoundError: No module named 'Classes' "
Can anyone help me?
From your top level directory
(I'm assuming it's the one containing Classes/ and Scripts/)
run: python3 -m Scripts.myScript
From man python3:
-m module-name
Searches sys.path for the named module and runs the
corresponding .py file as a script.

Pytest import error despite using conftest in root directory?

I have the following directory structure:
src
\conftest.py
\dir_A
\run_A.py
\test_run_A.py
\dir_B
\run_B.py
where run_A.py has the following code:
from dir_B import run_B
...
When I run pytest from src, I get the error:
ImportError while importing test module '/home/user/src/dir_A/run_A.py'
...
ImportError: cannot import name 'run_B'
Is there a reason why this fails despite using conftest.py?
I'd like to add that running python3 -m dir_A.test_run_A from src works perfectly fine as a test.
You'll find this link helpful: https://docs.pytest.org/en/latest/pythonpath.html
Essentially, when running these tests from the src directory, pytest will walk all the way down to /home/user/src/dir_A/run_A.py. Without any __init__.py files, it will then refuse to walk anywhere else, as it doesn't realize it is part of a larger package.

Relative imports in python with local ang global libraries

My apps are organized like this:
apps/
code/
libglobal/
funglobal.py
tests/
project/
liblocal/
funlocal.py
main.py
In main.py I have:
import liblocal.funlocal
In funlocal.py I try to import funglobal.py with:
from ....code.libglobal import funglobal
When I run
python3 -B tests/project/main.py
I get an error:
from ....code.libglobal import funglobal
ValueError: attempted relative import beyond top-level package
I have read a lot of information about relative imports with python3 and still don't find how to solve this error without changing the apps organization radically. Any solution?
As the script being executed has its __name__ set as __main__ and defines itself to be on the top level of the package, it refuses to recognize scripts in sibling directories.
You can fix this with a sys.path hack:
import sys, os
sys.path.insert(0, os.path.abspath('../..'))
or an interseting alternative with setuptools is presented in this answer.
Have you a __init__.py script in each folder ?
If no, you should create an empty script named __init__.py in each folder.

Gitlab CI Python run test - ModuleNotFoundError: No module named xxx

I saw a lot of questions about importing modules error but I could not manage to solve the problem with Gitlab CI pipeline.
My project structure:
├───config
├───docs
├───src
__init__.py
│ ├───dataset
__init__.py
│ ├───exceptions
│ ├───resources
│ └───utils
__init__.py
└───tests
__init__.py
└───resources
__init__.py
I would like to run tests using pytest.
I invoke this command python -m pytest -p no:cacheprovider or using unittest
'python -m unittest discover -v' from root directory and also tried to invoke from test directory. In both cases I have a problem with importing class from dataset module. What's interesting, I have two tests file.
First file imports:
import os import unittest
from src.utils.FileManager import FileManager
Second imports:
from src.dataset.DatasetHelper import DatasetHelper
The first file is passing but the second is failing with error:
from dataset import DatasetHelper ModuleNotFoundError: No module
named 'dataset'
So the thing is that other modules like utils from src are imported correctly, only the dataset has a problem. I am struggling with this a few days and I completely out of ideas. I also tried to change instead of from dataset to from src.dataset. It didn't work. I can run tests in PyCharm by clicking right mous button and just run tests but not on CI environment.
What I tried:
Add modules to $PYTHONPATH like
sys.path.insert(0, "/builds/USER/PROJECT/src/dataset")
sys.path.insert(0, "/builds/USER/PROJECT/src")
sys.path.insert(0, "/builds//USER/PROJECT/tests")
The content of PYTHONPATH before adding it was:
Current $PYTHONPATH: ['/builds/USER/PROJECT/config', '/usr/local/lib/python36.zip', '/usr/local/lib/python3.6', '/usr/local/lib/python3.6/lib-dynload', '/usr/local/lib/python3.6/site-packages']
The first module in list is config because I run script from this directory to add above modules to path. Doesn't Help
Run test command from root directory and add prefix src to imports in tests directory. Doesn't Help
from dataset import DatasetHelper
ModuleNotFoundError: No module named 'dataset'
Either in src.__init__ or more proabably in src.dataset.__init__ there is the import statement from dataset import DatasetHelper. You have to rewrite it as from src.dataset import…
You can try using a relative import in your __init__.py file that's inside the tests directory.
The syntax depends on the current location as well as the current location of the module,package, or object you're trying to import. Here are some examples:
from .some_module import some_class
from ..some_package import some_function
from . import some_class
Source: https://realpython.com/absolute-vs-relative-python-imports/

Categories