pythonpycharm

Is there any way to force PyCharm to always use absolute imports?


I'm using PyCharm and often rely on the Alt+Enter shortcut to automatically import classes and functions.

However, it doesn't use the absolute import path. It works fine locally but when I push to GitHub my tests fail in TravisCI.

Does anyone know a way to force PyCharm to import with the absolute path?

I need to import like this drone_squadron.api.drone_api if I use something like this api.drone_api the remote tests can't find the import. This is for all local imports.

I'd prefer for all imports to be absolute, all the time. Relative imports have caused me problems in packaging up projects. I think it's just easier to use absolute imports all the time.

GitHub repo

Tree structure

.
├── coverage.xml
├── LICENSE.md
├── pytest.ini
├── README.md
├── requirements.txt
├── drone_squadron
│   ├── app.py
│   ├── endpoints.http
│   ├── flask.cfg
│   ├── __init__.py
│   ├── load_fixtures.py
│   ├── main.py
│   ├── router.py
│   ├── schema.py
│   ├── test_flask.cfg
│   ├── api
│   │   ├── base_api.py
│   │   ├── drone_api.py
│   │   ├── gimbal_api.py
│   │   ├── __init__.py
│   │   ├── price_api.py
│   │   ├── round_type_api.py
│   │   ├── scanner_api.py
│   │   ├── squadron_api.py
│   │   ├── steering_api.py
│   │   ├── thruster_api.py
│   │   ├── user_api.py
│   │   └── weapon_api.py
│   ├── authentication
│   │   ├── __init__.py
│   │   └── login.py
│   ├── crud
│   │   ├── base_crud.py
│   │   ├── drone_crud.py
│   │   ├── gimbal_crud.py
│   │   ├── __init__.py
│   │   ├── item_crud.py
│   │   ├── price_crud.py
│   │   ├── round_type_crud.py
│   │   ├── scanner_crud.py
│   │   ├── squadron_crud.py
│   │   ├── status_crud.py
│   │   ├── steering_crud.py
│   │   ├── thruster_crud.py
│   │   ├── user_crud.py
│   │   └── weapon_crud.py
│   ├── database
│   │   ├── database.py
│   │   ├── drones.db
│   │   ├── drones_test.db
│   │   └── __init__.py
│   ├── enums
│   │   ├── __init__.py
│   │   ├── round_type.py
│   │   └── status.py
│   ├── error
│   │   ├── error.py
│   │   └── __init__.py
│   ├── fixtures
│   │   ├── gimbal_fixtures.py
│   │   ├── __init__.py
│   │   ├── round_type_fixtures.py
│   │   ├── scanner_fixtures.py
│   │   ├── status_fixtures.py
│   │   ├── steering_fixtures.py
│   │   ├── thruster_fixtures.py
│   │   ├── user_fixtures.py
│   │   └── weapon_fixtures.py
│   ├── model
│   │   ├── base_model.py
│   │   ├── drone_model.py
│   │   ├── __init__.py
│   │   └── squadron_model.py
│   ├── request
│   │   ├── __init__.py
│   │   └── json_request_handler.py
│   ├── response
│   │   ├── __init__.py
│   │   └── json_response.py
│   ├── service
│   │   └── calculate_cost.py
│   ├── transformer
│   │   ├── __init__.py
│   │   ├── json_transformer.py
│   │   └── transformer.py
│   └── validation
│       ├── abstract
│       │   ├── __init__.py
│       │   └── validation_abstract.py
│       ├── drone_validation.py
│       ├── field.py
│       ├── __init__.py
│       ├── validation_link.py
│       └── validations.py
└── tests
    ├── drones_test.db
    ├── __init__.py
    ├── test_api
    │   ├── conftest.py
    │   ├── __init__.py
    │   ├── test_auth.py
    │   ├── test_drone.py
    │   ├── test_gimbal.py
    │   ├── test_price_list.py
    │   ├── test_round_type.py
    │   ├── test_scanner.py
    │   ├── test_squadron.py
    │   ├── test_steering.py
    │   ├── test_thruster.py
    │   └── test_weapon.py
    └── test_crud
        ├── conftest.py
        ├── __init__.py
        ├── test_drone_crud.py
        ├── test_gimbal_crud.py
        ├── test_scanner_crud.py
        ├── test_squadron_crud.py
        ├── test_status_crud.py
        ├── test_steering_crud.py
        ├── test_thruster_crud.py
        ├── test_user_crud.py
        └── test_weapon_crud.py

Solution

  • In Python, imports can be relative or absolute.

    Absolute imports are resolved from your project's root directory:

    import drone_squadron.api.drone_api
    

    Relative imports are resolved from the current python package.

    import ..api.drone
    

    In your case, the issue is NOT a relative/absolute confusion, PyCharm always add absolute imports.

    The problem is that PyCharm probably consider the folder drone_squadron in your project as a "root directory". That's wrong! The root directory is the top-level folder corresponding to the whole git project (the folder containing LICENSE.md, README.md, etc.)

    In PyCharm, right click on the folder drone_squadron, then open sub-menu Mark directory as (in the bottom) then select Unmark as Source Root.

    PyCharm animated screenshot: change root directory

    After that action, your import will be added the way you want.