Reputation: 5820
I'm new to Python, and I try to structure my Python application.
Given the following directory structure:
π¦app
β£ πlexer
β β£ πtoken
β β β£ πtoken.py
β β β£ πtype.py
β β β π__init__.py
β β π__init__.py
β£ πtest
β β£ πlexer
β β β£ πtoken
β β β β£ πtest_token.py
β β β β π__init__.py
β β β π__init__.py
β β£ πtest_app.py
β β π__init__.py
β πapp.py
Right now, the application is executed using the following command:
pyhton -m app
When I try to execute the application using
python -m .\app.py
The following error is raised:
Relative module names not supported.
Unit tests are being executed using:
python -m unittest
This works fine and without issues.
Now, I'm trying to use the import the token / type.py
file in the app.py
file.
The contents of this file are:
from enum import Enum, unique
@unique
class Type(Enum):
UNKNOWN = 1
EOF = 2
The following import statement is added in the app.py
file:
from app.lexer.token.type import Type
Running the application right now yields the following error:
Traceback (most recent call last):
File "C:\Python38\lib\runpy.py", line 193, in _run_module_as_main
return _run_code(code, main_globals, None,
File "C:\Python38\lib\runpy.py", line 86, in _run_code
exec(code, run_globals)
File "C:\DEV\DEMO.ONE\app\app.py", line 17, in <module>
from app.lexer.token.type import Type
File "C:\DEV\DEMO.ONE\app\app.py", line 17, in <module>
from app.lexer.token.type import Type
ModuleNotFoundError: No module named 'app.lexer'; 'app' is not a package
Any ideas on how this can be fixed?
Upvotes: 1
Views: 276
Reputation: 2433
app is not a package. A "directory" becomes a package by adding __init__.py in. Try adding app/__init__.py.
On a side note, type is a built-in class in python. It is a bad idea to name your module type.py. Rename it now or you will regret later.
Upvotes: 1
Reputation: 2433
Actually, python does not know about your app package. When you run python -m app it accedentally works because you have (I presume) started it in the app directory. Therefore python tries to look it up in current directory as well. But then you try to import app.something, and that does not work. Try importing just lexer.token.type. If that works, we know we are on the right track.
Then try
touch __init__.py
cd ..
python -m app.app
Now, to tell python about the package, you will have to make a setup.py file and then install it by doing
pip install -e .
That will put a link into python's library's site-packages directory and python will know about it. Once you have done it, you will be able to run python -m app.app from anywhere.
You might want to read about distutils: https://docs.python.org/3/distutils/setupscript.html
or python packaging: https://packaging.python.org/tutorials/packaging-projects/
Upvotes: 0
Reputation: 998
app/
itself isn't a package -since it doesn't include a __init__
file-. app/
is root of the application, while the package's path starts with lexer
. So, change
from app.lexer.token.type import Type
to
from lexer.token.type import Type
Upvotes: 1
Reputation: 1224
i think you need to set environment variable PYTHONPATH
before you execute the script from your project root folder.
in command line at your project root folder, do:
export PYTHONPATH=$(pwd)
or put the above in a .env file at project root folder and do
source .env
before executing your script
Upvotes: 0