Why this architecture is not working ?
/test
__init__.py
app.py
models.py
/subpackage
__init__.py
subpackage.py
Here's the example code:
app.py
from test.subpackage import hi_from_subpackage
hi_from_subpackage()
subpackage/subpackage.py
from test.models import models
def hi_from_subpackage():
print('Hi')
# I nee models here too
models()
the error is:
Traceback (most recent call last):
File "app.py", line 1, in <module>
from test.subpackage import hi_from_subpackage
**ModuleNotFoundError: No module named 'test.subpackage'**
What i'm doing wrong ?
-
Thanks in advance
You are getting confused with the import system of python, it happens. When you import subpackage, you want to import a module subpackage from a package subpackage so it should look like this:
from subpackage.subpackage import hi_from_subpackage
and when you are lower in the package hierarchy, you don't need to say witch package the module come from, it already "knows" it as it is in a higher hierarchy.
from models import models
Think about it like if you were writing core. Here models is in the scope of subpackage in a global variable way. And when you are standing in test package, you need to refer to a lower lever package by its name, as you do with a variable.
Try running pip install test from your cmd if is Windows. With regard to the IDE you are using I would recommend vs-code to you.
Related
I'm having trouble with a python package that uses separate modules to structure code. The package itself is working, however when imported from another environment fails with a ModuleNotFound error.
Here's the structure:
Project-root
|
|--src/
| __init__.py
| module_a.py
| module_b.py
| module_c.py
| module_d.py
|--tests
etc.
In module_a.py I have:
from module_a import function_a1,...
from module_b import function_b1,...
from module_c import function_c1,...
In module_c I import module_d like:
from module_d import function_d1,...
As mentioned above, executing module_a or module_c directly from the CLI work as expected, the unit tests I've created in the test directory also work (with the help of sys.path.insert), however if I create a new environment and import the package I get the following error:
>>> import module_a
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/<abs_path>/.venv/lib/python3.9/site-packages/module_a.py", line 22, in <module>
from module_c import function_c1, function_c2
File /<abs_path>/.venv/lib/python3.9/site-packages/module_c.py", line 9, in <module>
import module_d
ModuleNotFoundError: No module named 'module_d'
>>>
I've exhausted all ideas how to overcome this, besides combining the code of modules c and d in one file, which I'd hate to do, or rethink the flow so that all modules are imported from module_a.
Any suggestions how to approach this would be greatly appreciated.
Update: It turned out to be a typing mistake in the name of module_d in setup.py. For whatever reason python setup.py install was failing silently or I wasn't reading the logs carefully.
The problem comes down to understanding the basics of the import system and the PYTHONPATH.
When you try to import a module (import module_a), Python will search in order in every directory listed in sys.path. If a directory matches the name (module_a)1, then it runs the __init__.py file is such exist.
When you get an [https://docs.python.org/3/library/exceptions.html#ImportError], it means that there is no directory in sys.path containing a directory with the name asked.
You said for your tests you did something like sys.path.insert(0, "some/path/"), but it is not a solution, just a broken fix.
What you should do is set your PYTHONPATH environment variable to contain the directory where your modules are located, Project-root/src in your case. That way, no need to ever use sys.path.insert, or fiddle with relative/absolute paths in import statements.
When you create your new environment, just set your environment variable PYTHONPATH to include Project-root/src and you are done. This is how installing regular Python modules (libraries) work : they are all put into a directory in site-packages.
1: this changed since old Python versions, it used to be required for the directory to contain an __init__.py file
My current projects are structured like so.
python/
__init__.py
project_1/
__init__.py
program_1.py
project_2/
__init__.py
program_2.py
project_3/
__init__.py
program_3.py
I wanted to import a class from project_3/program_3.py, called INFO, from both project_1/program_1.py and project_2/program_2.py. In both my program_1.py and program_2.py, I've tried the following import statements that didn't work.
Edit - I typically "cd" into project_1 and run my program_1.py from there.
from project_3.program_3 import INFO
Traceback (most recent call last):
File "./program_1.py", line 43, in <module>
from project_3.program_3 import INFO
ImportError: No module named 'project_3'
from python.project_3.program_3 import INFO
Traceback (most recent call last):
File "./program_1.py", line 43, in <module>
from python.project_3.program_3 import INFO
ImportError: No module named 'python'
The only way for me to import class INFO into program_1.py and program_2.py is by copying program_3.py in both program_1 and program_2's folder. My import in program_1 and program_2's statement would become:
python/
__init__.py
project_1/
__init__.py
program_1.py
program_3.py
project_2/
__init__.py
program_2.py
program_3.py
project_3/
__init__.py
program_3.py
from program_3 import INFO
This is quite inconvenience because now I have to update program_3.py in all 3 locations. Assuming my the way I structured my project folder is retarded:
What's the correct/best way to structure my folders so that I could call program_3.py from program_1/2.py?
If there's nothing wrong with my current structure, how do I correctly import the INFO class into program_1/2.py?
I have read the python documentation but it didn't say anything regarding importing classes from one subfolder to another. I also looked at another post from Stack Overflow as well but it didn't have the same structure as mine.
Update 1 - It's important to note that I'm merely using project_1/2 as folder to organized my projects. I originally had init.py in all my folders because I have no clue what I'm doing. The only module/package that I wanted to import in my project_1/program_1.py is from project_3/program_3.py. Example:
python/
project_1/
program_1.py
project_2/
program_2.py
project_3/
__init__.py
program_3.py
When using submodules, you need to use relative imports. In the example provided, importing program_3 from program_1 should be :
from ..project_3 import program_3
and then you can use the INFO class: program_3.INFO.
This works if your executable file is outside the script, that is the file which uses the module python in the example should be outside the python module.
If parts of the python package are executed as a script, the -m option should be passed to the interpreter:
python3 -m python.project_1.program_1
I hope this helps.
The previous solution provides me the same error.
I found a fix by using sys:
import sys
sys.path.append('../')
from project_3 import program_3
...
This way, you setup 'python' folder as reference (in your case it's the parent folder but you can select the path you want)
I hope it helps,
I've created two modules in the same directory:
.
├── mod1.py
├── mod2.py
There is no __init__.py, I don't want to create this as a package, I'm just creating a simple script which I have modularized by breaking into different modules.
My intention is to run mod1.py using python mod1.py
~/junk/imports$ cat mod1.py
from . import mod2
print(mod2.some_expr)
$ cat mod2.py
some_expr = 'hello world!'
Although I know that directly using import mod1 will work, but I'm deliberately not using it so that my module name doesn't clash with built in modules (which I felt is a good practice)
I'm getting the following errors with python2 and python3
~/junk/imports$ python3 --version
Python 3.4.3
kartik#kartik-lappy:~/junk/imports$ python3 mod1.py
Traceback (most recent call last):
File "mod1.py", line 1, in <module>
from . import mod2
SystemError: Parent module '' not loaded, cannot perform relative import
~/junk/imports$ python2 --version
Python 2.7.11
~/junk/imports$ python2 mod1.py
Traceback (most recent call last):
File "mod1.py", line 1, in <module>
from . import mod2
ValueError: Attempted relative import in non-package
Most of the questions like this on StackOverflow deal with packages, but I'm not using packages. I just want to run it as a simple script.
My question is not about how to do it, but I want to know the reason behind the above not working.
You shouldn't use relative, but absolute import:
import mod2
print(mod2.some_expr)
The documentation is pretty good, and this SO answers gives an alternative using importlib.
If a handmade module clash with a builtin module, the proper way to go is probably to rename it, eventually through addition of a {pre,suf}fix.
Another is to use importlib.
The motivation underlying these limitation can be found in the PEP 328, and comes mainly from BDFL preferences, over all other solutions.
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,
I am using pycharm at one of my university projects and I wanted to integrated it with unittest module, but I have a problem with structuring my project
Part of this project involves generating abstract syntax trees, so I created AST directory and put __init__.py there, then I created expression module. I wanted to put my tests in test/ subdirectory, so it would look like this:
AST/
__init__.py
expression.py
test/
some_test.py
utils.py
now I have also module in my AST called symbol_table and module called utils, example test class looks like
import unittest
from ...AST import expression
from ...AST import utils
class ConstantExpressionTest(unittest.TestCase):
def testConstantExpressionCheck(self):
constantExpression = expression.ConstantExpression(17, 5, utils.TYPES.INT)
self.assertTrue(constantExpression.check())
when I right click on this file and select Run Unittest in ... I am getting errors:
/usr/bin/python2.7 /home/xubuntu/Downloads/pycharm-2.7.2/helpers/pycharm/utrunner.py /home/xubuntu/Przedmioty/VI/kompilatory/tk-projekt/src/AST/test/test_constant_expression.py true
Testing started at 12:06 PM ...
Traceback (most recent call last):
File "/home/xubuntu/Downloads/pycharm-2.7.2/helpers/pycharm/utrunner.py", line 110, in <module>
modules = [loadSource(a[0])]
File "/home/xubuntu/Downloads/pycharm-2.7.2/helpers/pycharm/utrunner.py", line 34, in loadSource
module = imp.load_source(moduleName, fileName)
File "/home/xubuntu/Przedmioty/VI/kompilatory/tk-projekt/src/AST/test/test_constant_expression.py", line 2, in <module>
from ...AST import utils
ValueError: Attempted relative import in non-package
Process finished with exit code 1
I have read about this problem and if I understand this right, this file is treated as it would be in top-level package so I can't use any relative imports.
But if that is the case, how can I run unit-tests from pycharm and also keep my current project strcture?
If I am not mistaken, putting tests in sub-package is pretty popular (http://as.ynchrono.us/2007/12/filesystem-structure-of-python-project_21.html) so there must be some kind of solution
Well, that is a bit silly, I found out that pycharm adds the root of the project to path so I can just use normal imports from the root of my project.
So for example I can write
from AST import expression in my some_test file