Resolving intra-project imports in Python — A simple guide — PyCharm

Fadil Nohur
6 min readJun 19, 2021

Please click here if you wish to return to the parent article.

This article provides a minimal step-by-step guide on how to set up intra-project Python imports correctly in PyCharm.

This article will use the “simple” project structure from the parent article, where source folders and test folders are all at the same level directly under the project root folder.

project 

├─── folder1
│ │ __init__.py
│ │ file1.py

├─── folder2
│ │ __init__.py
│ │ file2.py

└─── tests
│ test_file.py

N.B. This project structure is fine for anyone who has no plans to distribute their code. If, however, you plan to distribute your code to others, e.g. through PyPI, you should consider using a src project structure instead. Follow this link (coming soon) for a step-by-step guide to project file import setup using a src project structure.

Import Statements

The first step we should do is ensure all import statements are written correctly. All imports should be absolute imports starting from under the project root.

Consider project/folder1/file1.py which contains a simple add() function.

# project/folder1/file1.pydef add(num1, num2):
return num1 + num2

We want to use this function in project/folder2/file2.py . Our import is simply from folder1 import file1 — an absolute import that starts from under the project root.

# project/folder2/file2.pyfrom folder1 import file1print('1 + 2 =', file1.add(1, 2))

Ensure all imports in your project are set up like this.

Setting up imports for PyCharm Run Configurations

If you only ever run your code through PyCharm Run configurations, no more action is required. Your code should run without a problem. However, if you wish to run your code in a shell, even in the PyCharm integrated terminal, the rest of the article covers this process.

(If you are having import issues and you are running your code through PyCharm, check your Run/Debug configurations are set up correctly. In particular, ensure that Add source roots to PYTHONPATH is selected for your configuration. This option is a default option for every Python configuration, but if you are having issues, check that this option was not accidentally unselected.)

Setting up imports for the Terminal

Running code or tests through the shell require a little bit more work. In order for imports to work correctly, you will need to turn the project into a proper Python package and install it.

You will need to do a number of things:

  • Create a venv (if you haven’t already)
  • Set up a package for your project
  • Install your project

Create a venv

If you already have a venv created and activated, feel free to skip this section.

You will need to create a venv (short for virtual environment) to install your project to. A venv is a lightweight version of Python separated from your system installation of Python, and is typically created for each new Python project. Installing packages to a venv means that packages for each Python project are isolated from each other.

In File — Settings, navigate to Project: <your project name> and then Python Interpreter. Next to the Python Interpreter dropdown field, there should be a little gear icon — click that and then click Add.

In the Add Python Interpreter window, ensure Virtualenv Environment is selected on the left pane. In the main section, ensure New environment is selected. The location should be a venv folder within your project root directory. Ensure the base interpreter is as you expect, and then click OK.

This will create the venv and automatically activate it for you. Click OK on the Settings window to go back to the IDE.

Ensure the project has the venv added to it.

project

├─── folder1
│ │ __init__.py
│ │ file1.py

├─── folder2
│ │ __init__.py
│ │ file2.py

├─── tests
│ │ test_file.py

└─── venv

Now, close any existing Terminal tabs within PyCharm and open up a fresh Terminal. You will be able to see if your venv is up and active by the (venv) prefix to the directory in the shell. If so, you are good to go.

(venv) C:\...\project> 

(For more information on virtual environments, including how to create them directly from the shell, please visit the following link: https://docs.python.org/3/tutorial/venv.html )

Set up a package for your project

Now, you will need to create a package for your project. This is done by creating a setup.py file using the setuptools package, which should already be available to you in your Python installation.

Ensure your project folder is selected in the Project pane. Then, in the Tools menu, select Create setup.py.

A dialogue box will appear asking for a bunch of details. The defaults should be fine for now; just click OK.

A setup.py file should now be created for you in your project root.

project
setup.py

├─── folder1
│ │ __init__.py
│ │ file1.py

├─── folder2
│ │ __init__.py
│ │ file2.py

├─── tests
│ │ test_file.py

└─── venv
# /project/setup.pyfrom setuptools import setup

setup(
name='project',
version='',
packages=['folder1', 'folder2'],
url='',
license='',
author='',
author_email='',
description=''
)

The contents of this file can be left like this for now for our purpose, which is getting imports working locally. If you plan to distribute your code later, you will need to return to this file and change it as necessary.

Installing your project

Now, install your project to your venv. The project will be installed in “editable” mode — this is so that any changes to the installation will automatically update as your project code changes.

Go to the Terminal. Make sure that your venv is active and that the directory is set to the project root. Then, run the following command in the shell:

  • Windows:py -m pip install -e .
  • macOS/Linux:python3 -m pip install -e .
(venv) C:\...\project> py -m pip install -e .

Once the shell says that the project has been successfully installed, you are good to go.

(venv) C:\...\project> py -m pip install -e .
Obtaining file:///C:/.../project
Installing collecting packages: project
Running setup.py develop for project
Successfully installed project

Further confirmation of the installation of your project will be the appearance of a .egg-info folder in your project folder.

project
│ setup.py

├─── folder1
│ │ __init__.py
│ │ file1.py

├─── folder2
│ │ __init__.py
│ │ file2.py

├─── project.egg-info

├─── tests
│ │ test_file.py

└─── venv

And we’re done!

It was a roundabout trip, but we got there! If you now run your code or your tests from the shell (using the py command on Windows or the python3 command on macOS/Linux) everything should just work.

project/folder1/file1.py:

def add(num1, num2):
return num1 + num2

project/folder2/file2.py:

from folder1 import file1print('1 + 2 =', file1.add(1, 2))

Running code through the terminal:

(venv) C:\...\project> py folder2\file2.py
1 + 2 = 3

Running tests through the terminal:

# output trimmed for brevityC:\...\project> pytestcollected 1 item.tests\test_file.py1 passed in 0.02s

--

--