I am trying to run from the directory folder:
$ python subdirectoryTwo/file.py command (Python 2.7).
Folders structure:
-directory
-subdirectoryOne
__init.py__
config.py
-subdirectoryTwo
__init.py__
file.py
My file.py has:
from subdirectoryOne.config import config
However I am getting an error:
file.pyImportError: No module named subdirectoryOne.config`
(I guess it still looks in the directory folder)
There few thins you need to change.
(public)landpacks-MacBook-Pro:qx frank$ tree
.
├── __init__.py
├── __init__.pyc
├── a
│ ├── __init__.py
│ ├── __init__.pyc
│ ├── config.py
│ └── config.pyc
└── b
├── __init__.py
└── test.py
Create a __init__.py with with your subdirectoryOne and subdirectoryTwo like here I used a and b. and then add few codes at the begin of your file.py. And I name it as test.py here. the code is:
import sys
sys.path.append("..")
from project.a.config import myconf
print(myconf)
You can see I import it by project.a.config instead of a.config. because you run your code under the project.
UPDATE
My a/config.py just simple with:
(public)landpacks-MacBook-Pro:qx frank$ cat a/config.py
myconf='127.0.0.1'
One of the solutions (not the optimum one) is to set PYTHONPATH to your directory:
$ export PYTHONPATH='/absolute/path/to/directory'
Related
I am creating a Python package and want to make the example files in the example folder runnable with something like python example_file.py. How do I do it? My example_file.py and __init__.py look like below:
# example_file.py
from demandforecast import DemandForecast # module coded in demandforecast.py
if __name__ == '__main__':
# Example code here
# __init__.py
import os, sys; sys.path.append(os.path.dirname(os.path.realpath(__file__)))
When I navigate to the examples directory and run python example_file.py I get the following error:
Exception has occurred: ModuleNotFoundError
No module named 'demandforecast'
This can be solved by adding using the old sys.path.insert() trick mentioned in Importing files from different folder, but I would rather not include the absolute path because this will vary from user to user.
Here is my directory structure:
├───demandforecast
│ demandforecast.py
│ __init__.py
│
└───examples
example_file.py
I have tried a few posts here, such as Relative imports in Python 3, but without luck. Adding sys.path.append('../') to the example file before the demandforecast import also did not work.
I think your import is simply incorrect, and should be:
from demandforecast.demandforecast import DemandForecast
Since demandforecast is both the package name (the directory is definitely a package, with the __init__.py file) and a module name within that package. (I assume DemandForecast is a class within the demandforecast module.)
from src.pro.demandforecast.demandforecast import foo
if __name__ == '__main__':
foo()
output:
foo
create a folder src and inside of it create a package pro and now inside pro create two packages demandforecast and examples.
Directory structure:
/src$ tree
.
└── pro
├── demandforecast
│ ├── demandforecast.py
│ ├── __init__.py
│ └── __pycache__
│ ├── demandforecast.cpython-38.pyc
│ └── __init__.cpython-38.pyc
├── examples
│ ├── example_file.py
│ └── __init__.py
├── __init__.py
└── __pycache__
└── __init__.cpython-38.pyc
IDE:
I have the following directory structure in Ubuntu. I'm trying to import the module config from my local package my_app into my script my_app_script.py
$ tree
.
├── my_app/
│ ├── config.py
│ ├── __init__.py
│ └── test/
├── my_app-info # created by pip install -e .
│ ├── dependency_links.txt
│ ├── PKG-INFO
│ ├── requires.txt
│ ├── SOURCES.txt
│ └── top_level.txt
├── bin/
│ └── my_app_script.py
├── LICENSE
├── README.md
└── setup.py
# setup.py
setup(
name='my_app',
version='0.1.2',
description='',
url='',
packages=['my_app'],
scripts=['bin/my_app_script.py'],
install_requires=[],
python_requires='>=3.6',
)
# my_app_script.py
from my_app import config
When I run my_app_script.py it results in "ImportError: cannot import name 'config'
What am I doing wrong?
Edit:
I am trying to follow this guide on packaging a program.
You need an __init__.py file in the parent directory as well as in bin directory.
You can use either of below approaches.
The first approach seems best to me as the script will always set the path relative to it, and will also work if you clone your repos.
Add an __init__.py in parent directory(Next to setup.py).
And add below line in my_app_script.py
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir, "my_app")))
What this will do is add .../my_app to PYTHONPATH at runtime, when my_app_script.py is executed.
Add an env.sh in parent directory. Below should be the contents of env.sh.
export PYTHONPATH=$(pwd):$PYTHONPATH
Now cd int the directory where env.sh is kept and then source it
source env.sh
Now run your my_app_script.py
python bin/my_app_script.py
Set PYTHONPATH from commandline.
PYTHONPATH=$(pwd) python bin/my_app_script.py
Before I even start I want to say - I know, that there are like bazillion questions similar to this, but I couldn't find the answer to my problem. I have a dir structure like this:
.
├── project
│ ├── A
│ │ ├── __init__.py
│ │ └── somelib.py
│ ├── B
│ ├── C
│ │ └── C
│ │ ├── foo.py
│ │ └── __init__.py
│ └── __init__.py
└── run.sh
run.sh:
python3 project/C/C/foo.py
foo.py:
from project.A.somelib import somefunc
VS Code actually gets the intellisense in foo.py - it tells me what funcitons/variables I can import from somelib. But when I run run.sh, I get this error message:
from project.A.somelib import somefunc
ModuleNotFoundError: No module named 'project'
Is there a way to solve this while preserving this directory structure?
adding project/__init__.py changed nothing
the sys.path in foo.py looks like this:
['/home/dabljues/projects/project/project/C/C', '/usr/lib/python37.zip', '/usr/lib/python3.7', '/usr/lib/python3.7/lib-dynload', '/usr/lib/python3.7/site-packages']
restrictions:
I can't modify neither sys.path in the files nor PYTHONPATH before running the scripts
I can't pip-install anything
I don't have sudo-access
I can't create a virtualenv, since the scripts are supposed to be downloadable and quickly executable
IDEs like VSCode or Pycharm make their own assumptions about a project, and will usually correctly link modules even if the interpreter that will ultimately run the code can't.
The reason why project.A.somelib can't be found is visible in your sys.path output, which gives you the places where python will search for modules. Since '/home/dabljues/projects/project/project' is not included, there is no way for python to resolve it during runtime.
A quick hack
You can just add the path manually to sys.path, either in the source file by running import sys; sys.insert(0, '/home/dabljues/projects/project/project/') in foo.py before any other imports happen, or by running export PYTHONPATH="${PYTHONPATH}:/home/dabljues/projects/project/project/" in your shell before run.sh.
Installing the project
Since it looks like you're developing a library, you might as well use the mechanisms python offers to make libraries shareable and thereby fixing any import issues. Add a minimal setup.py to the project root (i.e. /home/dabljues/projects/project/project/setup.py):
from setuptools import setup, find_packages
setup(
name='project',
version='0.1.0',
packages=find_packages('project'),
)
And install your project in editable mode:
$ python3 -m pip install -e .
This will put a link in your python3 executable's site-packages that points to the project root, which makes it accessible whenever you run anything with python3.
Tests
I included print(__name__) at the top of all python files to get some output.
running run.sh without installing the package:
$ sh run.sh
Traceback (most recent call last):
File "project/C/C/foo.py", line 1, in <module>
from project.A.somelib import somefunc
ModuleNotFoundError: No module named 'project'
after installing it
$ sh run.sh
__main__
project.A.somelib
As you can see, project.C.C.foo is executed as a script, yet it finds all imports that start with project because project is installed.
Run python in package mode helps.
1) Add __init__.py for every path:
.
├── project
│ ├── A
│ │ ├── __init__.py
│ │ └── somelib.py
│ ├── B
│ ├── C
│ │ ├── __init__.py
│ │ └── C
│ │ ├── foo.py
│ │ └── __init__.py
│ └── __init__.py
└── run.sh
2) Import module with relative path in foo.py:
from ...A.somelib import somefunc
3) Run python in package mode:
python -m project.C.C.foo
It works for me.
I'm unable to reproduce this given your code (assuming run.sh just starts a script).
Are you sure it's not a case of e.g. circular imports?
$ mkdir -p project/A project/C/C
$ cat > project/C/C/foo.py
print('moof!')
$ cat > project/A/somelib.py
print('beef!')
$ cat > script.py
import project.A.somelib
import project.C.C.foo
$ tree
.
├── project
│ ├── A
│ │ └── somelib.py
│ └── C
│ └── C
│ └── foo.py
└── script.py
$ python3 script.py
beef!
moof!
Change your run.sh script to run foo as a module. python3 -m proj.C.C.foo
I have the following structure for my package
Project
- __init__.py
- my_mod
-- test
-- __init__.py
-- test_my_mod.py
If I run the nosetests in the project folder it doesn't find my tests, but if I run in the test folder then it picks it up.
Any ideas what could be the problem
Delete the __init__.py file in your Project directory. It doesn't look like you intend for Project to be a Python package, so you don't need it. Then, having this directory structure:
Project
└── my_mod
├── __init__.py
├── some_module.py
├── test
│ ├── __init__.py
│ ├── test_my_mod_again.py
│ └── test_my_mod_yet_again.py
└── test_my_mod.py
Running nosetests inside Project will now run your tests, both inside the my_mod/ directory and inside the test/ directory.
Of course, the contents of the test files should contain something that nosetests can recognize as a test, such as:
import unittest
from my_mod import some_module
class MyTestCase(unittest.TestCase):
def test_the_number(self):
assert some_module.double(10) == 20
I've a project which uses git submodules. In my python file I want to use functions from another python file in the submodule project.
In order to work I had to add the init.py file to all subfolders in the path. My folder tree is the following:
myproj
├── gitmodules
│ ├── __init__.py
│ ├── __init__.pyc
│ └── mygitsubmodule
│ ├── __init__.py
│ ├── __init__.pyc
│ └── file.py
└── myfile.py
Is there any way to make it work without touching mygitsubmodule ?
Thanks
you can add to sys.path in the file you want to be able to access the module, something like:
import sys
sys.path.append("/home/me/myproj/gitmodules")
import mygitsubmodule
This example is adding a path as a raw string to make it clear what's happening. You should really use the more sophisticated, system independent methods described below to determine and assemble the path.
Also, I have found it better, when I used this method, to use sys.path.insert(1, .. as some functionality seems to rely of sys.path[0] being the starting directory of the program.
I am used to avoiding modifying sys.path.
The problem is, when using git submodule, submodule is a project directory, not a Python package. There is a "gap" between your module and that package, so you can't import.
Suppose you have created a submodule named foo_project, and there is a foo package inside.
.
├── foo_project
│ ├── README.rst
│ └── foo
│ └── __init__.py
└── main.py
My solution will be creating a soft link to expose that package to your module:
ln -s foo_project/foo foo
.
├── foo_project
│ ├── README.rst
│ └── foo
│ └── __init__.py
├── foo -> foo_project/foo
└── main.py
Now you can import foo in the main.py.
For reference,
from submodulefolder.file import func_name
or
import submodulefolder.file as lib_name
where file excludes the extension of file.py, seems to work in relative terms without modifying the subfolder / git submodule with a init.py since python 3.3+,
as shown here.
Tested on py3.8.5 linux native and py3.7.8 anaconda Windows, both in Spyder's Ipython-console, as well as natively on linux via terminal.