90

How do I import a module(python file) that resides in the parent directory?

Both directories have a __init__.py file in them but I still cannot import a file from the parent directory?

In this folder layout, Script B is attempting to import Script A:

Folder A:
   __init__.py
   Script A:
   Folder B:
     __init__.py
     Script B(attempting to import Script A)

The following code in Script B doesn't work:

import ../scriptA.py # I get a compile error saying the "." is invalid
Right leg
  • 16,080
  • 7
  • 48
  • 81
sazr
  • 24,984
  • 66
  • 194
  • 362
  • Not exactly answering your question, but if you run __init__.py inside Folder A and try and import Folder B or Script B, Script A will be successfully imported inside Script B. – Michael0x2a Jan 21 '12 at 07:01
  • Possible duplicate of [Importing modules from parent folder](https://stackoverflow.com/questions/714063/importing-modules-from-parent-folder) – Kaibo Nov 01 '19 at 12:54

4 Answers4

84

You don't import scripts in Python you import modules. Some python modules are also scripts that you can run directly (they do some useful work at a module-level).

In general it is preferable to use absolute imports rather than relative imports.

toplevel_package/
├── __init__.py
├── moduleA.py
└── subpackage
    ├── __init__.py
    └── moduleB.py

In moduleB:

from toplevel_package import moduleA

If you'd like to run moduleB.py as a script then make sure that parent directory for toplevel_package is in your sys.path.

jfs
  • 399,953
  • 195
  • 994
  • 1,670
  • 14
    And why shouldn't sys path "hacks" be used in this case? Python makes it so hard to do what you want here without them. What exactly is the downside here? – B T Oct 16 '12 at 00:05
  • 4
    @BT *«`sys.path.append(path_to_parent)`»* shouldn't be an answer to how to fix *«"import ../scriptA.py # I get a compile error saying the "." is invalid"»* question. There are cases where changing `sys.path` could be useful e.g., if python itself'd done it or a 3-party module that handles all corner cases correctly done it e.g., `import autopath; autopath.add_toplevel_to_syspath()` that automatically adds parent directory of toplevel_package to `sys.path` to allow a direct internal module execution as a script (or in a REPL) from any directory without proper PYTHONPATH or (virtualenv) install. – jfs Oct 16 '12 at 21:02
  • 3
    @J.F.Sebastian Is there some kind of proposal for a feature that allows us to explicit say what is the main folder or package of the whole project so that we don't have to care about adding parent directories to `sys.path` so that we can run submodules also as main files or scripts? I have a project where I really need to run scripts both as main or as modules, that is imported, but I need to do tons of hacks adding paths to `sys.path` to make them work in both cases. Would work in a virtualenv or using setuptools work somehow? I am really struggling with this... – nbro Feb 04 '16 at 23:23
  • 2
    @nbro the feature is called `pip install main-package`. You can run "submodules" already (just use their absolute names e.g., `python -ma.b.c`). If it is unclear; [ask](http://stackoverflow.com/questions/ask) – jfs Feb 04 '16 at 23:51
  • 1
    @jfs So what you are suggesting is to add toplevel_package to PYTHONPATH whenever I start to work on new application? – Xyz Dec 18 '17 at 12:36
  • @Pietrko: The answer discusses how to import `toplevel_package.moduleA` from `toplevel_package.subpackage.moduleB` that is run as a script. I don't see what it has to do with "new applications" – jfs Dec 18 '17 at 13:12
  • 1
    "If you'd like to run moduleB.py as a script then make sure that parent directory for toplevel_package is in your sys.path." This sentence is gold. That solved all my problems, thank you. – Géry Ogam Dec 22 '17 at 08:30
  • 23
    This solution doesn't work for me. It raises: "ImportError: No module named toplevel_package" – smart May 05 '18 at 08:03
  • This solution works on my local fine but when I build it on docker it throws error. Instead of that I coppied the file to the other location too. Idk if you had error while deploying on docker but this is just a warning note in case you have the same problem – alkanschtein Jul 01 '19 at 14:01
  • 1
    What if `moduleA.py` is in a folder? – David G Mar 06 '22 at 16:43
37

From the docs:

from .. import scriptA

You can do this in packages, but not in scripts you run directly. From the link above:

Note that both explicit and implicit relative imports are based on the name of the current module. Since the name of the main module is always "__main__", modules intended for use as the main module of a Python application should always use absolute imports.

If you create a script that imports A.B.B, you won't receive the ValueError.

Rob Wouters
  • 15,797
  • 3
  • 42
  • 36
6

If you want to run the script directly, you can:

  1. Add the FolderA's path to the environment variable (PYTHONPATH).
  2. Add the path to sys.path in the your script.

Then:

import module_you_wanted
kenorb
  • 155,785
  • 88
  • 678
  • 743
capfredf
  • 387
  • 1
  • 9
0

I struggled same kind of issue, and published syspend module on PyPI https://pypi.org/project/syspend/ This searches parent directories which have specific named file, and calls sys.path.append(directory: which has SYSPEND_ROOT file).

Folder A:
   __init__.py
   Script A:
   Folder B:
     __init__.py
     Script B(attempting to import Script A)
   SYSPEND_ROOT

In your case, please put SYSPEND_ROOT file. Empty file is OK. In your ScriptB.py

import syspend
import ScriptA

if __name__ == "__main__":
    ScriptA.method()
town_paddy
  • 11
  • 4