If all occurring directories are Python packages, i.e. they all contain __init__.py, then you can use

from ..bar_dir import bar

If the directories aren't Python packages, you can do this by messing around with sys.path, but you shouldn't.

Answer from Sven Marnach on Stack Overflow
🌐
Reddit
reddit.com β€Ί r/learnpython β€Ί is there a human way to make imports from sibling directories?
r/learnpython on Reddit: Is there a human way to make imports from sibling directories?
August 17, 2022 -

I am at a loss. For over two hours, I have been trying to figure out how to make a simple import from one directory to another, like this:

Parent Dir

Dir 1

script1.py

Dir2

script2.py

So, I'd like to import a function2 from script2 to script1. I tried relative imports, absolute imports - it doesn't work (resulting in various errors) . It only worked after I added script2 to the system path, but it seems like a hack and people advise against using it.

Can someone explain this to me like I am five?

Discussions

python - Import from sibling directory - Stack Overflow
I have a Python class called "ClassA" and another Python class which is supposed to import ClassA which is "ClassB". The directory structure is as follows: MainDir ../Dir ..../DirA/ClassA ..../DirB/ More on stackoverflow.com
🌐 stackoverflow.com
How to import module from sibling directory?
You have to run your project as a module so that the PYTHONPATH includes the containing directory: python -m project.tests.test_shell and then test_shell.py can import import utils.shell. More on reddit.com
🌐 r/learnpython
9
2
November 21, 2021
python - Sibling package imports - Stack Overflow
I think without this "src" directory/package, the subpackages didn't have common root package. 2023-05-08T16:58:07.157Z+00:00 ... Save this answer. ... Show activity on this post. I don't yet have the comprehension of Pythonology necessary to see the intended way of sharing code amongst unrelated projects without a sibling/relative import hack. Until that day, this is my solution. For examples or tests to import stuff from ... More on stackoverflow.com
🌐 stackoverflow.com
How to import a Python module from a sibling folder? - Stack Overflow
I'm on Python 3.7. What gives? 2019-02-01T02:44:25.17Z+00:00 ... In my case adding __init__.py was not enough. You also have to append the path of the parent directory if you get module not found error. root : | |__SiblingA: | \__A.py | |__SiblingB: | \_ __init__.py | \__B.py | To import B.py from ... More on stackoverflow.com
🌐 stackoverflow.com
🌐
GeeksforGeeks
geeksforgeeks.org β€Ί python β€Ί python-import-from-sibling-directory
Python - Import from sibling directory - GeeksforGeeks
July 23, 2025 - Another similar way of performing the same task is by making the sibling directories as a package by putting the __init__.py file in the folders and then importing it from the sibling directory.
🌐
GitHub
github.com β€Ί brossetti β€Ί important-siblings
GitHub - brossetti/important-siblings: An exploration of how best to important python modules within sibling directories Β· GitHub
Although they require a bit of extra work, the __init__.py files are a clear indicator to other programmers that they are working with a Python package. If you are in a rush (or have one-off code), you can import myclass.py into myscript.py from sibling directories using the following code.
🌐
MLJAR
mljar.com β€Ί answers β€Ί import-files-from-different-folder-python
Import files from different folder in Python
To import files from parent or sibling directories, you can use package relative imports. First, you have to creaty an empty file named __init__.py in each directory to make them recognized as packages by Python:
🌐
Python
wiki.python.org β€Ί moin β€Ί Asking(20)for(20)Help(2f)How(20)can(20)I(20)import(20)a(20)module(20)from(20)a(20)sibling(20)directory(3f).html
Asking for Help/How can I import a module from a sibling directory?
I am new to Python from Java background, I have following structure Β· /root /folder1 Class1.py Class2.py /folder2 Class3.py Β· I am in the folder2 and want to run class3.py but it need to import a module from Class1.py Could someone please help me?
Find elsewhere
🌐
Sentry
sentry.io β€Ί sentry answers β€Ί python β€Ί import files from a different folder in python
Python Import From Parent Directory and Subfolders | Sentry
To import scripts from parent or sibling directories, we can use package relative imports. First, we must ensure that our directories are recognized as packages by Python, which we can do by creating an empty file named __init__.py in each of them.
🌐
Reddit
reddit.com β€Ί r/learnpython β€Ί how to import module from sibling directory?
r/learnpython on Reddit: How to import module from sibling directory?
November 21, 2021 -

I have a directory structure like this:

project/

  • utils/

    • __init__.py

    • shell.py

  • tests/

    • __init__.py

    • test_shell.py

  • __init__.py

I want to import module shell.py from test_shell.py. How do I do this?

Note: All the __init__.py files are empty.

Edit - Solution Found:

After reading the comments, using Relative Imports has worked for me:

# in tests/test_shell.py
from ..utils import shell

Then I can run the script from outside the project directory as:

python -m project.tests.test_shell

Here, project is the name of the containing folder.

Also, running py.test to run PyTest on all tests (inside tests folder) works correctly.

Top answer
1 of 12
453

Tired of sys.path hacks?

There are plenty of sys.path.append -hacks available, but I found an alternative way of solving the problem in hand.

Summary

  • Wrap the code into one folder (e.g., packaged_stuff)
  • Create pyproject.toml file to describe your package (see minimal pyproject.toml below)
  • Pip install the package in editable state with pip install -e <myproject_folder>
  • Import using from packaged_stuff.modulename import function_name

Setup

The starting point is the file structure you have provided, wrapped in a folder called myproject.

.
└── myproject
    β”œβ”€β”€ api
    β”‚   β”œβ”€β”€ api_key.py
    β”‚   β”œβ”€β”€ api.py
    β”‚   └── __init__.py
    β”œβ”€β”€ examples
    β”‚   β”œβ”€β”€ example_one.py
    β”‚   β”œβ”€β”€ example_two.py
    β”‚   └── __init__.py
    β”œβ”€β”€ LICENCE.md
    β”œβ”€β”€ README.md
    └── tests
        β”œβ”€β”€ __init__.py
        └── test_one.py

I will call the . the root folder, and in my example case it is located at C:\tmp\test_imports\.

api.py

As a test case, let's use the following ./api/api.py

def function_from_api():
    return 'I am the return value from api.api!'

test_one.py

from api.api import function_from_api

def test_function():
    print(function_from_api())

if __name__ == '__main__':
    test_function()

Try to run test_one:

PS C:\tmp\test_imports> python .\myproject\tests\test_one.py
Traceback (most recent call last):
  File ".\myproject\tests\test_one.py", line 1, in <module>
    from api.api import function_from_api
ModuleNotFoundError: No module named 'api'

Also trying relative imports wont work:

Using from ..api.api import function_from_api would result into

PS C:\tmp\test_imports> python .\myproject\tests\test_one.py
Traceback (most recent call last):
  File ".\tests\test_one.py", line 1, in <module>
    from ..api.api import function_from_api
ValueError: attempted relative import beyond top-level package

Steps

1) Make a pyproject.toml file to the root level directory

(previously, people used a setup.py file)

The contents for a minimal pyproject.toml would be*

[project]
name = "myproject"
version = "0.1.0"
description = "My small project"

[build-system]
build-backend = "flit_core.buildapi"
requires = ["flit_core >=3.2,<4"]

2) Use a virtual environment

If you are familiar with virtual environments, activate one, and skip to the next step. Usage of virtual environments are not absolutely required, but they will really help you out in the long run (when you have more than one project ongoing...). The most basic steps are (run in the root folder):

  • Create virtual env
    • python -m venv venv
  • Activate virtual env
    • source ./venv/bin/activate (Linux, macOS) or ./venv/Scripts/activate (Win)

To learn more about this, just Google out "python virtual env tutorial" or similar. You probably never need any other commands than creating, activating and deactivating.

Once you have made and activated a virtual environment, your console should give the name of the virtual environment in parenthesis

PS C:\tmp\test_imports> python -m venv venv
PS C:\tmp\test_imports> .\venv\Scripts\activate
(venv) PS C:\tmp\test_imports>

and your folder tree should look like this**

.
β”œβ”€β”€ myproject
β”‚   β”œβ”€β”€ api
β”‚   β”‚   β”œβ”€β”€ api_key.py
β”‚   β”‚   β”œβ”€β”€ api.py
β”‚   β”‚   └── __init__.py
β”‚   β”œβ”€β”€ examples
β”‚   β”‚   β”œβ”€β”€ example_one.py
β”‚   β”‚   β”œβ”€β”€ example_two.py
β”‚   β”‚   └── __init__.py
β”‚   β”œβ”€β”€ LICENCE.md
β”‚   β”œβ”€β”€ README.md
β”‚   └── tests
β”‚       β”œβ”€β”€ __init__.py
β”‚       └── test_one.py
β”œβ”€β”€ pyproject.toml
└── venv
    β”œβ”€β”€ Include
    β”œβ”€β”€ Lib
    β”œβ”€β”€ pyvenv.cfg
    └── Scripts [87 entries exceeds filelimit, not opening dir]

3) pip install your project in editable state

Install your top level package myproject using pip. The trick is to use the -e flag when doing the install. This way it is installed in an editable state, and all the edits made to the .py files will be automatically included in the installed package. Using pyproject.toml and -e flag requires pip >= 21.3

In the root directory, run

pip install -e . (note the dot, it stands for "current directory")

You can also see that it is installed by using pip freeze

Obtaining file:///home/user/projects/myproject
  Installing build dependencies ... done
  Checking if build backend supports build_editable ... done
  Getting requirements to build editable ... done
  Preparing editable metadata (pyproject.toml) ... done
Building wheels for collected packages: myproj
  Building editable for myproj (pyproject.toml) ... done
  Created wheel for myproj: filename=myproj-0.1.0-py2.py3-none-any.whl size=903 sha256=f19858b080d4e770c2a172b9a73afcad5f33f4c43c86e8eb9bdacbe50a627064
  Stored in directory: /tmp/pip-ephem-wheel-cache-qohzx1u0/wheels/55/5f/e4/507fdeb40cdef333e3e0a8c50c740a430b8ce84cbe17ae5875
Successfully built myproject
Installing collected packages: myproject
Successfully installed myproject-0.1.0
(venv) PS C:\tmp\test_imports> pip freeze
myproject==0.1.0

4) Add myproject. into your imports

Note that you will have to add myproject. only into imports that would not work otherwise. Imports that worked without the pyproject.toml & pip install will work still work fine. See an example below.


Test the solution

Now, let's test the solution using api.py defined above, and test_one.py defined below.

test_one.py

from myproject.api.api import function_from_api

def test_function():
    print(function_from_api())

if __name__ == '__main__':
    test_function()

Running the test

(venv) PS C:\tmp\test_imports> python .\myproject\tests\test_one.py
I am the return value from api.api!

* Here using Flit as the build backend. Other alternatives exist.

** In reality, you could put your virtual environment anywhere on your hard disk.

2 of 12
122

Seven years after

Since I wrote the answer below, modifying sys.path is still a quick-and-dirty trick that works well for private scripts, but there has been several improvements

  • Installing the package (in a virtualenv or not) will give you what you want, though I would suggest using pip to do it rather than using setuptools directly (and using setup.cfg to store the metadata)
  • Using the -m flag and running as a package works too (but will turn out a bit awkward if you want to convert your working directory into an installable package).
  • For the tests, specifically, pytest is able to find the api package in this situation and takes care of the sys.path hacks for you

So it really depends on what you want to do. In your case, though, since it seems that your goal is to make a proper package at some point, installing through pip -e is probably your best bet, even if it is not perfect yet.

Old answer

As already stated elsewhere, the awful truth is that you have to do ugly hacks to allow imports from siblings modules or parents package from a __main__ module. The issue is detailed in PEP 366. PEP 3122 attempted to handle imports in a more rational way but Guido has rejected it one the account of

The only use case seems to be running scripts that happen to be living inside a module's directory, which I've always seen as an antipattern.

(here)

Though, I use this pattern on a regular basis with

# Ugly hack to allow absolute import from the root folder
# whatever its name is. Please forgive the heresy.
if __name__ == "__main__" and __package__ is None:
    from sys import path
    from os.path import dirname as dir

    path.append(dir(path[0]))
    __package__ = "examples"

import api

Here path[0] is your running script's parent folder and dir(path[0]) your top level folder.

I have still not been able to use relative imports with this, though, but it does allow absolute imports from the top level (in your example api's parent folder).

🌐
GitHub
github.com β€Ί ADataGMan β€Ί python-sibling-import-example
GitHub - ADataGMan/python-sibling-import-example: Learn how to import a sibling package or module in python Β· GitHub
However, if you want to run wav_write.py with a call to echo.py, this requires additional work to make functional. You can use the Snippet from above at the top of your lower level code to run individually, and still take advantage of what is written in another folder. This leverages the Python OS function to get the Current Working Directory.
Author: ADataGMan
🌐
Codemia
codemia.io β€Ί knowledge-hub β€Ί path β€Ί parallel_import_a_python_file_from_sibling_folder
Parallel Import a python file from sibling folder
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises
🌐
Medium
pavolkutaj.medium.com β€Ί why-import-of-sibling-packages-does-not-always-work-in-python-16b87d2134a
Why Import Of Sibling Packages Does Not Always Work In Python
February 18, 2022 - the CWD in Python does not work as a package β€” therefore you can’t refer from first-level subfolders across each other ... module make_change.py will NOT be able to call logger.py because they become siblings, i.e. 2 top-level packages Β· python β€” Relative imports for the billionth time β€” Stack Overflow
🌐
Stack Overflow
stackoverflow.com β€Ί questions β€Ί 48690887 β€Ί python-import-from-sibling-folder
python import from sibling folder - Stack Overflow
February 9, 2018 - you can also add the directory to the PATH var of the Linux system (I use it while I'm working on a project, at the end i modified the PATH to it's origin value) if you maintain the following structre than it is working out side the box Β· parentfolder/gfolder/codefolder/fileA.py parentfolder/gfolder/utilfolder/util.py parentfolder/gfolder/main.py ... Sign up to request clarification or add additional context in comments. ... import pathlib import sys root = pathlib.Path(__file__).parent.parent.parent sys.path.append(str(root)) from gfolder.utilfolder import util
🌐
Iditect
iditect.com β€Ί faq β€Ί python β€Ί how-to-import-a-python-script-from-a-sibling-directory.html
How to import a Python script from a sibling directory?
To import a Python script from a sibling directory, you can modify the sys.path variable temporarily or use relative imports if your Python version supports them (Python 3 and later).
🌐
Gaopinghuang0
gaopinghuang0.github.io β€Ί 2018 β€Ί 08 β€Ί 03 β€Ί python3-import-and-project-layout
Python3 import and project layout Β· Gaoping Huang's Blog
$ python sub1/helper.py # may throw import error if it uses relative import Β· Instead, we should use the same technique as running a test module: ... Sometimes, we may want to import a module/method from a sibling directory. For example, sub1/helper.py wants to import sub2/utils.py.
🌐
A Data Gman
aaronjgrossman.com β€Ί 2019 β€Ί 08 β€Ί 04 β€Ί importing-sibling-packages-in-python
Importing Sibling Packages in Python - A Data Gman
August 4, 2019 - I've put together a snippet of code to demonstrate how to import sibling packages and modules in Python 3, with a working example out on GitHub as python-sibling-import-example.
🌐
sqlpey
sqlpey.com β€Ί python β€Ί top-2-methods-to-import-a-python-script-from-a-sibling-directory
Top 2 Methods to Import a Python Script from a Sibling Directory
November 23, 2024 - If both foo_dir and bar_dir are treated as Python packagesβ€”meaning they contain an __init__.py file, you can easily import bar.py in foo.py using a relative import. Here’s how: ... parent_dir/ β”œβ”€β”€ foo_dir/ β”‚ β”œβ”€β”€ __init__.py β”‚ └── foo.py └── bar_dir/ β”œβ”€β”€ __init__.py └── bar.py ... This method is straightforward and takes advantage of Python’s built-in package management. If the directories are not recognized as packages (i.e., lacking an __init__.py file), you can dynamically modify the Python path to include the sibling directory.