Reputation: 4648
I am trying to figure out the best way to manage relative vs absolute imports in my project so that the testing and linting tools from pylint, pytest, vscode and pycharm are all happy and so that the app will run correctly in production.
I have not packaged the app with setup.py
because it is installed into a docker image and run from its working directory. My project directory structure is like this:
app
┣ app
┃ ┣ static
┃ ┃ ┗ myfrontend.js
┃ ┣ templates
┃ ┃ ┗ index.html
┃ ┣ tests
┃ ┃ ┣ __init__.py
┃ ┃ ┗ test_server.py
┃ ┣ __init__.py
┃ ┣ main.py
┃ ┗ utils.py
┣ Dockerfile
┗ requirements.txt
In app/app/main.py
imports are:
from app.utils import prepare_file
app = FastAPI()
and in app/app/tests/test_server.py
imports are:
from app.main import app
from app.utils import prepare_file
And the whole thing is run from a docker image built off tiangolo/uvicorn-gunicorn-fastapi by copying the files in and setting the workdir:
COPY ./app/app /app/app/
WORKDIR /app
This works with VSCode linting and testing, and with the QA toolchain:
pylint -E app/app # processes with no errors
pytest app/app/tests # correctly runs tests
docker build . -f app/Dockerfile -t myapp && docker container run myapp # app runs
However, PyCharm chokes on the imports:
Unresolved reference 'app'
Cannot find reference 'main' in 'imported module app'
Cannot find reference 'utils' in 'imported module app'
The PyCharm project has two submodules (the library with core "business logic" and the webapp that wraps it).
Pycharm can be made happy by changing app/app/main.py
to:
from ..app.utils import prepare_file
and app/app/tests/test_server.py
to:
from ...app.main import app
from ...app.utils import prepare_file
but this triggers pylint:
$ pylint -E app/app
************* Module app.main
app/app/main.py:18:0: E0402: Attempted relative import beyond top-level package (relative-beyond-top-level)
************* Module app.tests.test_server
app/app/tests/test_server.py:2:0: E0402: Attempted relative import beyond top-level package (relative-beyond-top-level)
app/app/tests/test_server.py:3:0: E0402: Attempted relative import beyond top-level package (relative-beyond-top-level)
I can think of two possible explanations:
app/app
as "sources root" but it did not help.What do you think? Is this a PyCharm compatibility issue? Or a square peg round whole design problem?
Upvotes: 0
Views: 1938
Reputation: 4648
Solution: Mark the app
as "sources root" not app/app
. Then pycharm sees what the other linters see.
Thanks @lsabi and @mx0 for the pointers.
Upvotes: 1