Relative imports in Python 3
Asked Answered
L

33

1705

I want to import a function from another file in the same directory.

Usually, one of the following works:

from .mymodule import myfunction
from mymodule import myfunction

...but the other one gives me one of these errors:

ImportError: attempted relative import with no known parent package
ModuleNotFoundError: No module named 'mymodule'
SystemError: Parent module '' not loaded, cannot perform relative import

Why is this?

Luttrell answered 7/6, 2013 at 10:26 Comment(2)
See also: beyond top level package error in relative importReduction
and Relative imports for the billionth timeReduction
S
1305

unfortunately, this module needs to be inside the package, and it also needs to be runnable as a script, sometimes. Any idea how I could achieve that?

It's quite common to have a layout like this...

main.py
mypackage/
    __init__.py
    mymodule.py
    myothermodule.py

...with a mymodule.py like this...

#!/usr/bin/env python3

# Exported function
def as_int(a):
    return int(a)

# Test function for module  
def _test():
    assert as_int('1') == 1

if __name__ == '__main__':
    _test()

...a myothermodule.py like this...

#!/usr/bin/env python3

from .mymodule import as_int

# Exported function
def add(a, b):
    return as_int(a) + as_int(b)

# Test function for module  
def _test():
    assert add('1', '1') == 2

if __name__ == '__main__':
    _test()

...and a main.py like this...

#!/usr/bin/env python3

from mypackage.myothermodule import add

def main():
    print(add('1', '1'))

if __name__ == '__main__':
    main()

...which works fine when you run main.py or mypackage/mymodule.py, but fails with mypackage/myothermodule.py, due to the relative import...

from .mymodule import as_int

The way you're supposed to run it is by using the -m option and giving the path in the Python module system (rather than in the filesystem)...

python3 -m mypackage.myothermodule

...but it's somewhat verbose, and doesn't mix well with a shebang line like #!/usr/bin/env python3.

An alternative is to avoid using relative imports, and just use...

from mypackage.mymodule import as_int

Either way, you'll need to run from the parent of mypackage, or add that directory to PYTHONPATH (either one will ensure that mypackage is in the sys.path module search path). Or, if you want it to work "out of the box", you can frob the PYTHONPATH in code first with this...

import sys
import os

SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
sys.path.append(os.path.dirname(SCRIPT_DIR))

from mypackage.mymodule import as_int

It's kind of a pain, but there's a clue as to why in an email written by a certain Guido van Rossum...

I'm -1 on this and on any other proposed twiddlings of the __main__ machinery. 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. To make me change my mind you'd have to convince me that it isn't.

Whether running scripts inside a package is an antipattern or not is subjective, but personally I find it really useful in a package I have which contains some custom wxPython widgets, so I can run the script for any of the source files to display a wx.Frame containing only that widget for testing purposes.

Simmon answered 7/6, 2013 at 13:14 Comment(9)
A better way to get SCRIPTDIR is given in a comment of Import a module from a relative path as os.path.realpath(os.path.dirname(inspect.getfile(inspect.currentframe()))) if your confident that your module has always a proper file you could also use os.path.realpath(os.path.dirname(__file__)).Thunderpeal
@marcz: Please use os.path.abspath() instead of os.path.realpath(). There rarely is a need to resolve all symlinks along the path, and doing so can actually break advanced symlink use to collect the right packages in a single 'virtual' directory.Ichneumon
One useful use case of such antipattern would be having your tests inside some sub directories of your project which should test other components of your software?!Whipperin
@Whipperin that is the exact use case I am attempting to solve and how I ended up hereDaphne
For help understanding the sys.path.append() usage at the bottom of this answer, see my comment here and the official documentation links in that comment. The PYTHONPATH system variable is being changed whenever you append to the sys.path list of strings in your Python program. It's now starting to make sense what is going on there in this answer.Reduction
Worked for me (am using gdb python api) although I had to use sys.path.append(SCRIPT_DIR) because two os.path.dirname takes you to the parent dir?Homager
@Whipperin that is the exact use case I am attempting to solve and how I ended up here - me too :(Berton
I'm using python to do scientific data analysis and generate some paper plot. so, not like apps there is only one entrance. there will be many folders in my project, and I need to execute every script separately. However, these scripts are not independent, they may share some tool or method functions. In this case, python's confusing relative import make modularization complex.Urger
Dear god! Is there no end to the Python madness?Anemochore
V
656

Explanation

From PEP 328

Relative imports use a module's __name__ attribute to determine that module's position in the package hierarchy. If the module's name does not contain any package information (e.g. it is set to '__main__') then relative imports are resolved as if the module were a top level module, regardless of where the module is actually located on the file system.

At some point PEP 338 conflicted with PEP 328:

... relative imports rely on __name__ to determine the current module's position in the package hierarchy. In a main module, the value of __name__ is always '__main__', so explicit relative imports will always fail (as they only work for a module inside a package)

and to address the issue, PEP 366 introduced the top level variable __package__:

By adding a new module level attribute, this PEP allows relative imports to work automatically if the module is executed using the -m switch. A small amount of boilerplate in the module itself will allow the relative imports to work when the file is executed by name. [...] When it [the attribute] is present, relative imports will be based on this attribute rather than the module __name__ attribute. [...] When the main module is specified by its filename, then the __package__ attribute will be set to None. [...] When the import system encounters an explicit relative import in a module without __package__ set (or with it set to None), it will calculate and store the correct value (__name__.rpartition('.')[0] for normal modules and __name__ for package initialisation modules)

(emphasis mine)

If the __name__ is '__main__', __name__.rpartition('.')[0] returns empty string. This is why there's empty string literal in the error description:

SystemError: Parent module '' not loaded, cannot perform relative import

The relevant part of the CPython's PyImport_ImportModuleLevelObject function:

if (PyDict_GetItem(interp->modules, package) == NULL) {
    PyErr_Format(PyExc_SystemError,
            "Parent module %R not loaded, cannot perform relative "
            "import", package);
    goto error;
}

CPython raises this exception if it was unable to find package (the name of the package) in interp->modules (accessible as sys.modules). Since sys.modules is "a dictionary that maps module names to modules which have already been loaded", it's now clear that the parent module must be explicitly absolute-imported before performing relative import.

Note: The patch from the issue 18018 has added another if block, which will be executed before the code above:

if (PyUnicode_CompareWithASCIIString(package, "") == 0) {
    PyErr_SetString(PyExc_ImportError,
            "attempted relative import with no known parent package");
    goto error;
} /* else if (PyDict_GetItem(interp->modules, package) == NULL) {
    ...
*/

If package (same as above) is empty string, the error message will be

ImportError: attempted relative import with no known parent package

However, you will only see this in Python 3.6 or newer.

Solution #1: Run your script using -m

Consider a directory (which is a Python package):

.
├── package
│   ├── __init__.py
│   ├── module.py
│   └── standalone.py

All of the files in package begin with the same 2 lines of code:

from pathlib import Path
print('Running' if __name__ == '__main__' else 'Importing', Path(__file__).resolve())

I'm including these two lines only to make the order of operations obvious. We can ignore them completely, since they don't affect the execution.

__init__.py and module.py contain only those two lines (i.e., they are effectively empty).

standalone.py additionally attempts to import module.py via relative import:

from . import module  # explicit relative import

We're well aware that /path/to/python/interpreter package/standalone.py will fail. However, we can run the module with the -m command line option that will "search sys.path for the named module and execute its contents as the __main__ module":

vaultah@base:~$ python3 -i -m package.standalone
Importing /home/vaultah/package/__init__.py
Running /home/vaultah/package/standalone.py
Importing /home/vaultah/package/module.py
>>> __file__
'/home/vaultah/package/standalone.py'
>>> __package__
'package'
>>> # The __package__ has been correctly set and module.py has been imported.
... # What's inside sys.modules?
... import sys
>>> sys.modules['__main__']
<module 'package.standalone' from '/home/vaultah/package/standalone.py'>
>>> sys.modules['package.module']
<module 'package.module' from '/home/vaultah/package/module.py'>
>>> sys.modules['package']
<module 'package' from '/home/vaultah/package/__init__.py'>

-m does all the importing stuff for you and automatically sets __package__, but you can do that yourself in the

Solution #2: Set __package__ manually

Please treat it as a proof of concept rather than an actual solution. It isn't well-suited for use in real-world code.

PEP 366 has a workaround to this problem, however, it's incomplete, because setting __package__ alone is not enough. You're going to need to import at least N preceding packages in the module hierarchy, where N is the number of parent directories (relative to the directory of the script) that will be searched for the module being imported.

Thus,

  1. Add the parent directory of the Nth predecessor of the current module to sys.path

  2. Remove the current file's directory from sys.path

  3. Import the parent module of the current module using its fully-qualified name

  4. Set __package__ to the fully-qualified name from 2

  5. Perform the relative import

I'll borrow files from the Solution #1 and add some more subpackages:

package
├── __init__.py
├── module.py
└── subpackage
    ├── __init__.py
    └── subsubpackage
        ├── __init__.py
        └── standalone.py

This time standalone.py will import module.py from the package package using the following relative import

from ... import module  # N = 3

We'll need to precede that line with the boilerplate code, to make it work.

import sys
from pathlib import Path

if __name__ == '__main__' and __package__ is None:
    file = Path(__file__).resolve()
    parent, top = file.parent, file.parents[3]

    sys.path.append(str(top))
    try:
        sys.path.remove(str(parent))
    except ValueError: # Already removed
        pass

    import package.subpackage.subsubpackage
    __package__ = 'package.subpackage.subsubpackage'

from ... import module # N = 3

It allows us to execute standalone.py by filename:

vaultah@base:~$ python3 package/subpackage/subsubpackage/standalone.py
Running /home/vaultah/package/subpackage/subsubpackage/standalone.py
Importing /home/vaultah/package/__init__.py
Importing /home/vaultah/package/subpackage/__init__.py
Importing /home/vaultah/package/subpackage/subsubpackage/__init__.py
Importing /home/vaultah/package/module.py

A more general solution wrapped in a function can be found here. Example usage:

if __name__ == '__main__' and __package__ is None:
    import_parents(level=3) # N = 3

from ... import module
from ...module.submodule import thing

Solution #3: Use absolute imports and setuptools

The steps are -

  1. Replace explicit relative imports with equivalent absolute imports

  2. Install package to make it importable

For instance, the directory structure may be as follows

.
├── project
│   ├── package
│   │   ├── __init__.py
│   │   ├── module.py
│   │   └── standalone.py
│   └── setup.py

where setup.py is

from setuptools import setup, find_packages
setup(
    name = 'your_package_name',
    packages = find_packages(),
)

The rest of the files were borrowed from the Solution #1.

Installation will allow you to import the package regardless of your working directory (assuming there'll be no naming issues).

We can modify standalone.py to use this advantage (step 1):

from package import module  # absolute import

Change your working directory to project and run /path/to/python/interpreter setup.py install --user (--user installs the package in your site-packages directory) (step 2):

vaultah@base:~$ cd project
vaultah@base:~/project$ python3 setup.py install --user

Let's verify that it's now possible to run standalone.py as a script:

vaultah@base:~/project$ python3 -i package/standalone.py
Running /home/vaultah/project/package/standalone.py
Importing /home/vaultah/.local/lib/python3.6/site-packages/your_package_name-0.0.0-py3.6.egg/package/__init__.py
Importing /home/vaultah/.local/lib/python3.6/site-packages/your_package_name-0.0.0-py3.6.egg/package/module.py
>>> module
<module 'package.module' from '/home/vaultah/.local/lib/python3.6/site-packages/your_package_name-0.0.0-py3.6.egg/package/module.py'>
>>> import sys
>>> sys.modules['package']
<module 'package' from '/home/vaultah/.local/lib/python3.6/site-packages/your_package_name-0.0.0-py3.6.egg/package/__init__.py'>
>>> sys.modules['package.module']
<module 'package.module' from '/home/vaultah/.local/lib/python3.6/site-packages/your_package_name-0.0.0-py3.6.egg/package/module.py'>

Note: If you decide to go down this route, you'd be better off using virtual environments to install packages in isolation.

Solution #4: Use absolute imports and some boilerplate code

Frankly, the installation is not necessary - you could add some boilerplate code to your script to make absolute imports work.

I'm going to borrow files from Solution #1 and change standalone.py:

  1. Add the parent directory of package to sys.path before attempting to import anything from package using absolute imports:

    import sys
    from pathlib import Path # if you haven't already done so
    file = Path(__file__).resolve()
    parent, root = file.parent, file.parents[1]
    sys.path.append(str(root))
    
    # Additionally remove the current file's directory from sys.path
    try:
        sys.path.remove(str(parent))
    except ValueError: # Already removed
        pass
    
  2. Replace the relative import by the absolute import:

    from package import module  # absolute import
    

standalone.py runs without problems:

vaultah@base:~$ python3 -i package/standalone.py
Running /home/vaultah/package/standalone.py
Importing /home/vaultah/package/__init__.py
Importing /home/vaultah/package/module.py
>>> module
<module 'package.module' from '/home/vaultah/package/module.py'>
>>> import sys
>>> sys.modules['package']
<module 'package' from '/home/vaultah/package/__init__.py'>
>>> sys.modules['package.module']
<module 'package.module' from '/home/vaultah/package/module.py'>

I feel that I should warn you: try not to do this, especially if your project has a complex structure.


As a side note, PEP 8 recommends the use of absolute imports, but states that in some scenarios explicit relative imports are acceptable:

Absolute imports are recommended, as they are usually more readable and tend to be better behaved (or at least give better error messages). [...] However, explicit relative imports are an acceptable alternative to absolute imports, especially when dealing with complex package layouts where using absolute imports would be unnecessarily verbose.

Variegation answered 26/1, 2015 at 16:54 Comment(13)
Is it possible to set __package__ manually if name is __main__ in order to solve the problem?Gerfalcon
Thanks for quick reply. I'm using nltk package, I'm getting an error: ` File "/usr/local/lib/python3.5/dist-packages/nltk/__init__.py", line 115, in <module> from nltk.decorators import decorator, memoize File "/usr/local/lib/python3.5/dist-packages/nltk/decorators.py", line 23, in <module> sys.path = [p for p in sys.path if "nltk" not in p] File "/usr/local/lib/python3.5/dist-packages/nltk/decorators.py", line 23, in <listcomp> sys.path = [p for p in sys.path if "nltk" not in p] TypeError: argument of type 'PosixPath' is not iterable `Plafond
One minor gotcha with solution 2, is that this will fail if the file you're trying to run as a script from the command line has the same name as the value of __package__, as the file you're trying to run will then take precedence and be imported instead of the package.Stafani
You can also import a file by file path (relative too): docs.python.org/3/library/…Fondly
python -m worked for meMahler
This is an infuriating amount of complexity to add to accomplish something done so trivially in a language like Node.js. The import system in Python is done terribly, objectively speaking. I read the PEP document on this, they basically said "Users suggested a better solution, but it would be too much of a change", essentially admitting they designed the import feature badly and it's too late to really fix it. The fact that we even need an __init__.py in every directory is so silly, it's hard to believe it's real when you first learn of it.Sunward
Some years later (today) please have a look at the --editable option of pip to "install" a package in Development Mode.Magistrate
I cam here for quick and simple solution but now looking at the length of answer makes me delirious about how confusing this import-problem is.Sheriesherif
@SyedShaharyaarHussain It amazed me that this question has been around for 9 years, and still popular today with new comments and new ansawers.Liebknecht
Is this different between different Python 3 versions? Like 3.8 vs 3.10?Heflin
2023 and this problem still existsMicrochemistry
adding this worked for me import sys ;sys.path.append(".")Microchemistry
That's nice and easy then.Anemochore
L
297

Put this inside your package's __init__.py file:

# For relative imports to work in Python 3.6
import os, sys; sys.path.append(os.path.dirname(os.path.realpath(__file__)))

Assuming your package is like this:

├── project
│   ├── package
│   │   ├── __init__.py
│   │   ├── module1.py
│   │   └── module2.py
│   └── setup.py

Now use regular imports in you package, like:

# in module2.py
from module1 import class1

This works in both python 2 and 3.

Logway answered 20/3, 2018 at 3:7 Comment(9)
I also think this deserves more votes. Putting this in every __init__.py will basically solve all the relative import errors.Burchette
I can't speak for others, but I tend to avoid modifying sys.path because I'm concerned it might affect other code. (Partially this is because I don't know the intricacies of how it works.)Kashakashden
@Kashakashden I know what you mean, this (seemingly, after a lot of screwing around) magic fix does seem a little too easy. But it works. Would be interested not know from those-that-know if this is has negative side effects.Crooks
Wiat if you have two modules with the same name in two different packages - won't it cause a collision?Overskirt
Re: "This works in both python 2 and 3." That said if you have no installation scripts to run then the use of __init__.py has not been needed since python 3.3+Relume
In my case, module1 does not contain a Class, only functions. Then I get No module named 'module1'Manisa
@ErelSegal-Halevi I confirm a drawback is if you have two files from different modules with same name. When running python -m pytest, I have this conflict issue. Would be great if the author could provide a solution for it.Horseman
Where is the executable script here? If I try to run some script that imports from package I get an error stillManisa
This is not a relative import. It's a global import that happens to resolve to the relative file.Wheels
P
72

I ran into this issue. A hack workaround is importing via an if/else block like follows:

#!/usr/bin/env python3
#myothermodule

if __name__ == '__main__':
    from mymodule import as_int
else:
    from .mymodule import as_int


# Exported function
def add(a, b):
    return as_int(a) + as_int(b)

# Test function for module  
def _test():
    assert add('1', '1') == 2

if __name__ == '__main__':
    _test()
Phenylalanine answered 26/1, 2015 at 14:21 Comment(6)
It is SystemError here. (Py 3.4)Shill
@Perkins Well... in most cases it wouldn't. I think relative imports may be the exception though.Fizzy
Worked for me with python 3.8. I tried many other solutions and this is the first one that lets me do development in Emacs on the files within the folders as I am building the package. Other advice to make the package work was useless to me, I need to develop the package itself.Citystate
@Citystate If you're developing a package you should be testing it by installing it with an editable pip install (pip install -e . from the package root where setup.py is) and importing it as a package in your test files, not meddling around with conditional imports like this.Part
Simplest solution for me (Python 3.9) w/out messing with sys.path. Wish it was prettier (and unnecessary), but c'est la vie. +1Thorwald
Not working with -m: python3 -m packageDir.subDir.myothermodule. But yes python3 packageDir/subDir/myothermodule.py or as a package python3 -c "import packageDir.subDir.myothermodule as my; my.test()". A try-except (instead of if-else) would make it work in all these 3 cases as @darvin-rio answerCrab
I
51

SystemError: Parent module '' not loaded, cannot perform relative import

This means you are running a module inside the package as a script. Mixing scripts inside packages is tricky and should be avoided if at all possible. Use a wrapper script that imports the package and runs your scripty function instead.

If your top-level directory is called foo, which is on your PYTHONPATH module search path, and you have a package bar there (it is a directory you'd expect an __init__.py file in), scripts should not be placed inside bar, but should live on in foo at best.

Note that scripts differ from modules here in that they are used as a filename argument to the python command, either by using python <filename> or via a #! (shebang) line. It is loaded directly as the __main__ module (this is why if __name__ == "__main__": works in scripts), and there is no package context to build on for relative imports.

Your options

  • If you can, package your project with setuptools (or poetry or flit, which can help simplify packaging), and create console script entrypoints; installing your project with pip then creates scripts that know how to import your package properly. You can install your package locally with pip install -e ., so it can still be edited in-place.

  • Otherwise, never, ever, use python path/to/packagename/file.py, always use python path/to/script.py and script.py can use from packagename import ....

  • As a fallback, you could use the -m command-line switch to tell Python to import a module and use that as the __main__ file instead. This does not work with a shebang line, as there is no script file any more, however.

    If you use python -m foo.bar and foo/bar.py is found in a sys.path directory, that is then imported and executed as __main__ with the right package context. If bar is also a package, inside foo/, it must have a __main__.py file (so foo/bar/__main__.py as the path from the sys.path directory).

  • In extreme circumstances, add the metadata Python uses to resolve relative imports by setting __package__ directly; the file foo/bar/spam.py, importable as foo.bar.spam, is given the global __package__ = "foo.bar". It is just another global, like __file__ and __name__, set by Python when imported.

On sys.path

The above all requires that your package can be imported, which means it needs to be found in one of the directories (or zipfiles) listed in sys.path. There are several options here too:

  • The directory where path/to/script.py was found (so path/to) is automatically added to sys.path. Executing python path/to/foo.py adds path/to to sys.path.

  • If you packaged your project (with setuptools, poetry, flit or another Python packaging tool), and installed it, the package has been added to the right place already.

  • As a last resort, add the right directory to sys.path yourself. If the package can be located relatively to the script file, use the __file__ variable in the script global namespace (e.g. using the pathlib.Path object, HERE = Path(__file__).resolve().parent is a reference to the directory the file lives in, as absolute path).

Ichneumon answered 8/9, 2021 at 11:25 Comment(1)
I moved my file, indeed, a script, to the top-level directory (src) and changed the relative import to a regular (absolute?) import. Now it works. I'm not happy that I had to move my file, but I'm glad it now runs.Sosthina
E
29

TL;DR

You can only relatively import modules inside another module in the same package.

Concept Clarify

We see a lot of example code in books/docs/articles, they show us how to relatively import a module, but when we do so, it fails.

The reason is, put it in a simple sentence, we did not run the code as the python module mechanism expects, even though the code is written totally right. It's like some kind of runtime thing.

Module loading is depended on how you run the code. That is the source of confusion.

What is a module?

A module is a python file when and only when it is being imported by another file. Given a file mod.py, is it a module? Yes and No, if you run python mod.py, it is not a module, because it is not imported.

What is a package?

A package is a folder that includes Python module(s).

BTW, __init__.py is not necessary from python 3.3, if you don't need any package initialization or auto-load submodules. You don't need to place a blank __init__.py in a directory.

That proves a package is just a folder as long as there are files being imported.


Real Answer

Now, this description becomes clearer.

You can only relatively import modules inside another module in the same package.

Given a directory:

. CWD
|-- happy_maker.py # content: print('Sends Happy')
`-- me.py # content: from . import happy_maker

Run python me.py, we got attempted relative import with no known parent package

me.py is run directly, it is not a module, and we can't use relative import in it.

Solution 1

Use import happy_maker instead of from . import happy_maker

Solution 2

Switch our working directory to the parent folder.

. CWD
|-- happy
|   |-- happy_maker.py
    `-- me.py

Run python -m happy.me.

When we are in the directory that includes happy, happy is a package, me.py, happy_maker.py are modules, we can use relative import now, and we still want to run me.py, so we use -m which means run the module as a script.


Python Idiom

. CWD
|-- happy
|   |-- happy_maker.py # content: print('Sends Happy')
|   `-- me.py # content: from . import happy_maker
`-- main.py # content: import happy.me

This structure is the python idiom. main is our script, best practice in Python. Finally, we got there.


Siblings or Grandparents

Another common need:

.
|-- happy
|   |-- happy_maker.py
|   `-- me.py
`-- sad
    `-- sad_maker.py

We want to import sad_maker in me.py, How to do that?

First, we need to make happy and sad in the same package, so we have to go up a directory level. And then from ..sad import sad_maker in the me.py.

That is all.

Exurb answered 13/10, 2022 at 6:34 Comment(2)
from . import happy_maker in me.py (the Python Idiom) can be shortened to just from happy_maker, right? What if you have tests subdir under happy with a script test_happy.py which need relative imports from happy_maker.py? Will from .. import happy_maker (with two dots) work there?Flyback
most clear solution!Sonometer
H
22

For PyCharm users:

I also was getting ImportError: attempted relative import with no known parent package because I was adding the . notation to silence a PyCharm parsing error. PyCharm innaccurately reports not being able to find:

lib.thing import function

If you change it to:

.lib.thing import function

it silences the error but then you get the aforementioned ImportError: attempted relative import with no known parent package. Just ignore PyCharm's parser. It's wrong and the code runs fine despite what it says.

Hunkydory answered 29/7, 2020 at 20:21 Comment(3)
usually the parser in the IDE is wrong because its path has not been set. You should find the option which specifies the CWD (current workind directory) and set it to the same thing you use on the command lineVestryman
After far too much futzing around with Python and Pycharm, I'm going to: try: from .mname import symbol except: from mname import symbolMarkowitz
@Markowitz PyCharm looks at symbols based on the base folder of the project directory. If it's flopping on you that typically means there is something wonky about the location from which you're opening the project. You might try opening it in a different root directory. This is what Ciprian was talking about. Might help you - but maybe not 😂Hunkydory
P
15

To obviate this problem, I devised a solution with the repackage package, which has worked for me for some time. It adds the upper directory to the lib path:

import repackage
repackage.up()
from mypackage.mymodule import myfunction

Repackage can make relative imports that work in a wide range of cases, using an intelligent strategy (inspecting the call stack).

Pomander answered 6/12, 2017 at 9:26 Comment(3)
I tried it. Still failed: ImportError: attempted relative import with no known parent packageCitystate
@Citystate How did you do your import? Also, up() goes only one level in the directory hierarchy. You would need to check what you actually find there.Pomander
@fraulau. Thanks. I've been testing. I was trying to leave relative import after up(). That's wrong, I see from your example. If I rewrite as absolute, then up() seems have same effect as sys.path.append to add the "containing folder" in the search path. Then the absolute paths work.Citystate
E
14

TL;DR: to @Aya's answer, updated with pathlib library, and working for Jupyter notebooks where __file__ is not defined:

You want to import my_function defined under ../my_Folder_where_the_package_lives/my_package.py respect to where you are writing the code.

Then do:

import os
import sys
import pathlib

PACKAGE_PARENT = pathlib.Path(__file__).parent
#PACKAGE_PARENT = pathlib.Path.cwd().parent # if on jupyter notebook
SCRIPT_DIR = PACKAGE_PARENT / "my_Folder_where_the_package_lives"
sys.path.append(str(SCRIPT_DIR))

from my_package import my_function
Expressman answered 10/8, 2021 at 17:9 Comment(4)
I think you meant pathlib.Path.cwd().parent instead of Path.cwd().parent?Samurai
My god, I've searched EVERYWHERE. How is this that difficult?Stockjobber
@PabloCánovas The difference between showing and explaining, I guess.Expressman
@Expressman Your main answer was clearer than this comment lol. Thanks a lot btw!!Stockjobber
E
13

Hopefully, this will be of value to someone out there - I went through half a dozen stackoverflow posts trying to figure out relative imports similar to whats posted above here. I set up everything as suggested but I was still hitting ModuleNotFoundError: No module named 'my_module_name'

Since I was just developing locally and playing around, I hadn't created/run a setup.py file. I also hadn't apparently set my PYTHONPATH.

I realized that when I ran my code as I had been when the tests were in the same directory as the module, I couldn't find my module:

$ python3 test/my_module/module_test.py                                                                                                               2.4.0
Traceback (most recent call last):
  File "test/my_module/module_test.py", line 6, in <module>
    from my_module.module import *
ModuleNotFoundError: No module named 'my_module'

However, when I explicitly specified the path things started to work:

$ PYTHONPATH=. python3 test/my_module/module_test.py                                                                                                  2.4.0
...........
----------------------------------------------------------------------
Ran 11 tests in 0.001s

OK

So, in the event that anyone has tried a few suggestions, believes their code is structured correctly and still finds themselves in a similar situation as myself try either of the following if you don't export the current directory to your PYTHONPATH:

  1. Run your code and explicitly include the path like so: $ PYTHONPATH=. python3 test/my_module/module_test.py
  2. To avoid calling PYTHONPATH=., create a setup.py file with contents like the following and run python setup.py development to add packages to the path:
# setup.py
from setuptools import setup, find_packages

setup(
    name='sample',
    packages=find_packages()
)
Epicene answered 17/4, 2018 at 19:40 Comment(1)
Through setting Enviroment 【PYTHONPATH=.】 , it works for me in any scene ! Awesome Answer .Enchain
H
11

My boilerplate to make a module with relative imports in a package runnable standalone.

package/module.py

## Standalone boilerplate before relative imports
if __package__ is None:                  
    DIR = Path(__file__).resolve().parent
    sys.path.insert(0, str(DIR.parent))
    __package__ = DIR.name

from . import variable_in__init__py
from . import other_module_in_package
...

Now you can use your module in any fashion:

  1. Run module as usual: python -m package.module
  2. Use it as a module: python -c 'from package import module'
  3. Run it standalone: python package/module.py
  4. or with shebang (#!/bin/env python) just: package/module.py

NB! Using sys.path.append instead of sys.path.insert will give you a hard to trace error if your module has the same name as your package. E.g. my_script/my_script.py

Of course if you have relative imports from higher levels in your package hierarchy, than this is not enough, but for most cases, it's just okay.

Hardej answered 18/1, 2021 at 19:5 Comment(4)
Thanks for this @Andor, it helped me solve my case. For me package was preset to an empty string, so this boilerplate condition worked: if not __package__: [set __package__]Restitution
Worked like a charm. I needed to add one more .parent to line 3, but that's specific to my case of nested packages. Anyhow, thanks!Lingual
You need to add "from pathlib import Path", but otherwise works for me. Thanks!Abney
This is also what I usually do. I am surprised of not seeing this solution in top rated answers, and why.Weightless
A
9

I was getting this ImportError: attempted relative import with no known parent package

In my program I was using the file from current path for importing its function.

from .filename import function

Then I modified the current path (Dot) with package name. Which resolved my issue.

from package_name.filename import function

I hope the above answer helps you.

Andros answered 14/6, 2020 at 7:39 Comment(2)
What is package_name in your scenario?Evincive
@Evincive that was my custom package.Andros
P
8

I needed to run python3 from the main project directory to make it work.

For example, if the project has the following structure:

project_demo/
├── main.py
├── some_package/
│   ├── __init__.py
│   └── project_configs.py
└── test/
    └── test_project_configs.py

Solution

I would run python3 inside folder project_demo/ and then perform a

from some_package import project_configs
Patiencepatient answered 11/9, 2018 at 18:49 Comment(0)
P
8

Importing from same directory

Firstly, you can import from the same directory.

Here is the file structure...

Folder
 |
 ├─ Scripts
 |   ├─ module123.py
 |
 ├─ main.py
 ├─ script123.py

Here is main.py

from . import script123
from Scripts import module123

As you can see, importing from . imports from current directory.

Note: if running using anything but IDLE, make sure that your terminal is navigated to the same directory as the main.py file before running.

Also, importing from a local folder also works.

Importing from parent directory

As seen in my GitHub gist here, there is the following method.

Take the following file tree...

ParentDirectory
 ├─ Folder
 |   |
 |   ├─ Scripts
 |   |   ├─ module123.py
 |   |
 |   ├─ main.py
 |   ├─ script123.py
 |
 ├─ parentModule.py

Then, just add this code to the top of your main.py file.

import inspect
import os
import sys

current_dir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
parent_dir = os.path.dirname(current_dir)
sys.path.insert(0, parent_dir)

from ParentDirectory import Stuff
Proficiency answered 20/9, 2021 at 17:34 Comment(6)
I see examples like your main.py example constantly, but I'm never able to recreate them. Would you be willing to peek at this repo and tell me what I've done wrong? github.com/Adam-Hoelscher/relative-imports-python3Kaenel
Sure! Just doing that now.Proficiency
Would you mind raising an issue on your repository, and paste the error callback there? It'd be easier than on the comments here. I need to see the error.Proficiency
If I've understood your ask correctly, then it's done. Thanks.Kaenel
Yes it is. ThanksProficiency
@AdamHoelscher an extra note, if you run you script with PowerShell, it will return an error, whereas Command Prompt will not. Which terminal did you use? Could a change in terminal actually be where you solved your problem?Proficiency
C
6

I tried all of the above to no avail, only to realize I mistakenly had a - in my package name.

In short, don't have - in the directory where __init__.py is. I've never felt elated after finding out such inanity.

Carotid answered 18/12, 2020 at 3:36 Comment(2)
This sounds like a bug that should be reported.Axial
@JohnM. Really, somehow I'm under the impression that - in package name is illegal, or at least frowned uponCarotid
C
6

Here is a three-liner for those who disagree with Guido:

import sys
from pathlib import Path
sys.path.append(str(Path(sys.argv[0]).absolute().parent.parent))

Hope it helps.

UPDATE: Discovered that this fails when the executable is called by a relative path. The solution is to use resolve() instead of absolute():

import sys
from pathlib import Path
sys.path.append(str(Path(sys.argv[0]).resolve().parent.parent))
Coastward answered 12/10, 2022 at 12:29 Comment(0)
M
4

if both packages are in your import path (sys.path), and the module/class you want is in example/example.py, then to access the class without relative import try:

from example.example import fkt
Mcclenon answered 9/3, 2017 at 22:18 Comment(0)
P
4

If none of the above worked for you, you can specify the module explicitly.

Directory:

├── Project
│     ├── Dir
│     │    ├── __init__.py
│     │    ├── module.py
│     │    └── standalone.py

Solution:

#in standalone.py
from Project.Dir.module import ...

module - the module to be imported

Passenger answered 5/10, 2020 at 16:34 Comment(0)
E
3

I think the best solution is to create a package for your module: Here is more info on how to do it.

Once you have a package you don't need to worry about relative import, you can just do absolute imports.

Emirate answered 17/10, 2019 at 9:16 Comment(2)
The information's behind the links are today outdated (last update 2016) and wrong (e.g. tests folder inside the package folder). Please use official python docs about packaing.Magistrate
Thanks for the pointer. Will update the link nowEmirate
T
2

I encounter this a lot when I am working with Django, since a lot of functionality is performed from the manage.py script but I also want to have some of my modules runnable directly as scripts as well (ideally you would make them manage.py directives but we're not there yet).

This is a mock up of what such a project might look like;

├── dj_app
│   ├── models.py
│   ├── ops
│   │   ├── bar.py
│   │   └── foo.py
│   ├── script.py
│   ├── tests.py
│   ├── utils.py
│   └── views.py
└── manage.py

The important parts here being manage.py, dj_app/script.py, and dj_app/tests.py. We also have submodules dj_app/ops/bar.py and dj_app/ops/foo.py which contain more items we want to use throughout the project.

The source of the issue commonly comes from wanting your dj_app/script.py script methods to have test cases in dj_app/tests.py which get invoked when you run manage.py test.

This is how I set up the project and its imports;

# dj_app/ops/foo.py
# Foo operation methods and classes
foo_val = "foo123"

.

# dj_app/ops/bar.py
# Bar operations methods and classes
bar_val = "bar123"

.

# dj_app/script.py
# script to run app methods from CLI

# if run directly from command line
if __name__ == '__main__':
    from ops.bar import bar_val
    from ops.foo import foo_val

# otherwise
else:
    from .ops.bar import bar_val
    from .ops.foo import foo_val

def script_method1():
    print("this is script_method1")
    print("bar_val: {}".format(bar_val))
    print("foo_val: {}".format(foo_val))


if __name__ == '__main__':
    print("running from the script")
    script_method1()

.

# dj_app/tests.py
# test cases for the app
# do not run this directly from CLI or the imports will break
from .script import script_method1
from .ops.bar import bar_val
from .ops.foo import foo_val 

def main():
    print("Running the test case")
    print("testing script method")
    script_method1()

if __name__ == '__main__':
    print("running tests from command line")
    main()

.

# manage.py
# just run the test cases for this example
import dj_app.tests
dj_app.tests.main()

.

Running the test cases from manage.py;

$ python3 manage.py
Running the test case
testing script method
this is script_method1
bar_val: bar123
foo_val: foo123

Running the script on its own;

$ python3 dj_app/script.py
running from the script
this is script_method1
bar_val: bar123
foo_val: foo123

Note that you get an error if you try to run the test.py directly however, so don't do that;

$ python3 dj_app/tests.py
Traceback (most recent call last):
  File "dj_app/tests.py", line 5, in <module>
    from .script import script_method1
ModuleNotFoundError: No module named '__main__.script'; '__main__' is not a package

If I run into more complicated situations for imports, I usually end up implementing something like this to hack through it;

import os
import sys
THIS_DIR = os.path.dirname(os.path.realpath(__file__))
sys.path.insert(0, THIS_DIR)
from script import script_method1
sys.path.pop(0)
Tolbooth answered 30/6, 2021 at 13:44 Comment(0)
E
2

This my project structure

├── folder
|   | 
│   ├── moduleA.py
|   |   |
|   |   └--function1()
|   |       └~~ uses function2()
|   | 
│   └── moduleB.py
|       | 
|       └--function2()
|   
└── main.py
     └~~ uses function1()

Here my moduleA imports moduleB and main imports moduleA

I added the snippet below in moduleA to import moduleB

try:
    from .moduleB import function2 
except:
    from moduleB import function2 

Now I can execute both main.py as well as moduleA.py individually

Is this a solution ?

Embranchment answered 9/7, 2021 at 6:56 Comment(2)
I would use sys.version_info[0] to check if you are on python 2 or 3, or I would bind the exception to ImportError . Though in python 3 the relative path may not be a python package, and so the solution may not work either. It depends on the location of moduleB. (also modules should be in snake case by convention).Expressman
I independently came to this solution as well. I don't like it, but with the import system changing its semantics depending on unknown variables for unknown reasons, I think it's the best we can do.Sporulate
H
2

I was getting the same error and my project structure was like

->project
  ->vendors
    ->vendors.py
  ->main.py

I was trying to call like this

from .vendors.Amazon import Amazom_Purchase

Here it was throwing an error so I fixed it simply by removing the first . from the statement

from vendors.Amazon import Amazom_Purchase

Hope this helps.

Harvey answered 25/10, 2022 at 20:34 Comment(1)
I wouldn't think . causes the error. Worked for me, thanks!Testosterone
G
2

It's good to note that sometimes the cache causes of all it.
I've tried different things after re-arranging classes into new directories, and relative import started to work after I removed the __pycache__.

Glenda answered 30/10, 2022 at 13:22 Comment(0)
D
1

The below solution is tested on Python3

├── classes
|   |
|   ├──__init__.py
|   | 
│   ├── userclass.py
|   |   |
|   |   └--viewDetails()
|   |       
|   | 
│   └── groupclass.py
|       | 
|       └--viewGroupDetails()
|   
└── start.py
     └~~ uses function1()

Now, in order to use viewDetails of userclass or viewGroupDetails of groupclass define that in _ init _.py of classess directory first.

Ex: In _ init _.py

from .userclasss import viewDetails

from .groupclass import viewGroupDetails

Step2: Now, in start.py we can directly import viewDetails

Ex: In start.py

from classes import viewDetails
from classes import viewGroupDetails
Duly answered 7/1, 2022 at 5:24 Comment(0)
K
1

I ran into a similar problem when trying to write a python file that can be loaded either as a module or an executable script.

Setup

/path/to/project/
├── __init__.py
└── main.py
    └── mylib/
        ├── list_util.py
        └── args_util.py

with:

main.py:

#!/usr/bin/env python3
import sys
import mylib.args_util

if __name__ == '__main__':
    print(f'{mylib.args_util.parseargs(sys.argv[1:])=}')

mylib/list_util.py:

def to_int_list(args):
    return [int(x) for x in args]

mylib/args_util.py:

#!/usr/bin/env python3
import sys
from . import list_util as lu

def parseargs(args):
    return sum(lu.to_int_list(args))

if __name__ == '__main__':
    print(f'{parseargs(sys.argv[1:])=}')

Output

$ ./main.py 1 2 3
mylib.args_util.parseargs(sys.argv[1:])=6

$ mylib/args_util.py 1 2 3
Traceback (most recent call last):
  File "/path/to/project/mylib/args_util.py", line 10, in <module>
    from . import list_util as lu
ImportError: attempted relative import with no known parent package

Solution

I settled for a Bash/Python polyglot solution. The Bash version of the program just calls python3 -m mylib.args_util then exits.

The Python version ignores the Bash code because it's contained in the docstring.

The Bash version ignores the Python code because it uses exec to stop parsing/running lines.

mylib/args_util.py:

#!/bin/bash
# -*- Mode: python -*-
''''true
exec /usr/bin/env python3 -m mylib.args_util "$@"
'''

import sys
from . import list_util as lu

def parseargs(args):
    return sum(lu.to_int_list(args))

if __name__ == '__main__':
    print(f'{parseargs(sys.argv[1:])=}')

Output

$ ./main.py 1 2 3
mylib.args_util.parseargs(sys.argv[1:])=6

$ mylib/args_util.py 1 2 3
parseargs(sys.argv[1:])=6

Explanation

  • Line 1: #!/bin/bash; this is the "shebang" line; it tells the interactive shell how run this script.
    • Python: ignored (comment)
    • Bash: ignored (comment)
  • Line 2: # -*- Mode: python -*- optional; this is called the "mode-line"; it tells Emacs to use Python syntax highlighting instead of guessing that the language is Bash when reading the file.
    • Python: ignored (comment)
    • Bash: ignored (comment)
  • Line 3: ''''true
    • Python: views this as an unassigned docstring starting with 'true\n
    • Bash: views this as three strings (of which the first two are empty strings) that expand to true (i.e. '' + '' + 'true' = 'true'); it then runs true (which does nothing) and continues to the next line
  • Line 4: exec /usr/bin/env python3 -m mylib.args_util "$@"
    • Python: still views this as part of the docstring from line 3.
    • Bash: runs python3 -m mylib.args_util then exits (it doesn't parse anything beyond this line)
  • Line 5: '''
    • Python: views this as the end of the docstring from line 3.
    • Bash: doesn't parse this line

Caveats

  • This doesn't work on Windows:
    • Workaround: Use WSL or a Batch wrapper script to call python -m mylib.args_util.
  • This only works if the current working directory is set to /path/to/project/.
    • Workaround: Set PYTHONPATH when calling /usr/bin/env
      #!/bin/bash
      # -*- Mode: python -*-
      ''''true
      exec /usr/bin/env python3 \
          PYTHONPATH="$(cd "$(dirname "$0")/.." ; pwd)" \
          -m mylib.args_util "$@"
      '''
      
Konikow answered 23/6, 2022 at 11:11 Comment(0)
E
0

I had a similar problem: I needed a Linux service and cgi plugin which use common constants to cooperate. The 'natural' way to do this is to place them in the init.py of the package, but I cannot start the cgi plugin with the -m parameter.

My final solution was similar to Solution #2 above:

import sys
import pathlib as p
import importlib

pp = p.Path(sys.argv[0])
pack = pp.resolve().parent

pkg = importlib.import_module('__init__', package=str(pack))

The disadvantage is that you must prefix the constants (or common functions) with pkg:

print(pkg.Glob)
Ecru answered 6/4, 2020 at 7:55 Comment(0)
C
0

Moving the file from which you are importing to an outside directory helps.
This is extra useful when your main file makes any other files in its own directory.
Ex:
Before:

Project  
|---dir1  
|-------main.py  
|-------module1.py  

After:

Project  
|---module1.py  
|---dir1  
|-------main.py  
Companionship answered 1/9, 2020 at 17:9 Comment(0)
L
0

TLDR; Append Script path to the System Path by adding following in the entry point of your python script.

import os.path
import sys
PACKAGE_PARENT = '..'
SCRIPT_DIR = os.path.dirname(os.path.realpath(os.path.join(os.getcwd(), os.path.expanduser(__file__))))
sys.path.append(os.path.normpath(os.path.join(SCRIPT_DIR, PACKAGE_PARENT)))

Thats it now you can run your project in PyCharma as well as from Terminal!!

Leporide answered 5/11, 2020 at 10:32 Comment(0)
A
0

I had this issue because of a misunderstanding in setup.py You might not ever need this answer but while using setup.py to install my package from a folder I had this configuration:

packages=setuptools.find_packages(include=["package_folder.*"])

This is wrong as it was not supposed to have

.*

And should have been:

packages=setuptools.find_packages(include=["package_folder"])

It's just that the package was not installed properly, a deviation from relative imports.

Acerbity answered 8/3, 2024 at 8:27 Comment(0)
E
-1

If the following import:

from . import something 

doesn't work for you it is because this is python-packaging import and will not work with your regular implementation, and here is an example to show how to use it:

Folder structure:

.
└── funniest
    ├── funniest
    │   ├── __init__.py
    │   └── text.py
    ├── main.py
    └── setup.py 

inside __init__.py add:

def available_module(): 
    return "hello world"

text.py add:

from . import available_module

inside setup.py add

from setuptools import setup

setup(name='funniest',
  version='0.1',
  description='The funniest joke in the world',
  url='http://github.com/storborg/funniest',
  author='Flying Circus',
  author_email='[email protected]',
  license='MIT',
  packages=['funniest'],
  zip_safe=False)

Now, this is the most important part you need to install your package:

pip install .

Anywhere else in our system using the same Python, we can do this now:

>> import funnies.text as fun
>> fun.available_module() 

This should output 'hello world'

you can test this in main.py (this will not require any installation of the Package)

Here is main.py as well

import funniest.text as fun 
print(fun.available_module())
Eyeless answered 31/10, 2022 at 23:15 Comment(0)
K
-1

As this topic is still very unclear for most of us: aka 'how more complex scenario would work in-terms of relative imports in Python' (when your module is not just one .py-script in a folder, but N-classes grouped in more complex folder-hierarchy, like more complex modules often are.). Tbh, I think it does not, or at least everything related to that particular problem is so vaguely told, explained and documented online, that it is really difficult to understand how do it even nearly "right" or similar to for example C# namespaces.

So, as there are many good answers already to relative imports in more simple modules, I would like to give a shout on this to show a bullet-proof(ish) way & show the potential "blocker" to get your custom package with more complex modules to provide relative import internally (taken developing your own python program with >script-complexity), as there are some claims that Python3.3+ would handle these without __init__() files and so on. I found that claim partly false, as I tried all the given tricks (regarding use of relative, not absolute path)).

So, lets begin:

In order to enable relative references between package's N modules, you do need at least one(1) __init__.py file that defines the visibility to your custom modules.

Example:

in order to solve relative imports for good between N custom modules implemented to your custom package:

Logic that applies when wanting to enable relative imports such as defined above:

Taken the package and its modules are something like below:

`
<path to>/custom_package_folder
<path to>/custom_package_folder/my_module_a/my_custom_manager.py
<path to>/custom_package_folder/my_module_b/folder_x/subfolder_y/my_class_x.py
<path to>/custom_package_folder/my_module_n
`

At the /custom_package_folder:

Add:

`
__init__.py
`

And in __init__.py add:

`
from . import my_module_a
from . import my_module_b
from . import my_module_n
`

Now taken that the 'my_module_a/my_custom_manager.py':

`
class my_custom_manager():
    def my_func():
        print("message from module_a my_custom_manager class")
`

Now, you can access any custom module made visible for your package as demonstrated above, without need for absolute paths (or even sys/os cwd magic).

For example if we run: 'my_module_b/folder_x/subfolder/my_class_x.py':

`
# import any class from my_module_<N> via relative referencing made
# possible by offering visibility via your package's __init__.py
    
from my_module_a import my_custom_manager
    
mr_man = my_custom_manager() 
mr_man.my_func()
`
>>> 'message from module_a my_custom_manager class'

Why the above works is that visibility between our two own modules (a,b) has been granted via package's __init__.py configuration that allows the separate modules see each other.

If you're building any larger package/software in Python, there is no real reason to not manage properly these allowances/restrictions of the visibility properly anyway, as that is what they are (for designing / implementing higher level software architecture).

Note 1: I have found it really easy-when the program includes more modules, or modules include N classes, to build the software in a 'V'-flow, where objects in the same hierarchy-level of the program never access each other directly (i.e. code design patterns like 'module A <--> module B <--> module N <--> module A', will create huge mess when your program scales-up, so accessing in V shape i.e. through a separate manager module designed for managing such N modules. 'V'-shape is good any other shape is not that good (triangle, square or pentagon) in order to avoid weird unexpected "surprises" :)

Note 2: if you wish to control your program visibility in more granular detail & keep relative imports within your software,(at least in theory) you can abstract your program into layers with namespaces, in order to group your custom modules and manage their visibility in more exact manner:

  1. Add namespace_folder(s) under your package root & divide your modules into the namespaces your want.

  2. In package root's __init__.py import only the namespaces (in similar manner as above) that you wish to offer visibility here between each other.

  3. Now in each namespace, add each namespace __init__.py, that list those modules you wish to allow visibility between and offer support for relative paths, while accessing each other.

  4. So package provides/restricts visibility to N namespaces, namespaces provide/restrict visibility between & to their modules x,y,z with __init__.py files defined.

^^ Note, if you define on package level __init__().py so that your modules a,b,c can see each other (into global namespace) and then you have folder that groups modules d,e,f so that they form non-global namespace, lets say a_2.

Now if on this group parent folder you add __init__().py and include d,e,f modules to it in order to provide relative imports from these modules to the global namespace classes and also to their shared non-global namespace's module-n's children-classes (that are located in module's local hierarchy-tree in N-depth) --> Python actually does sh** on itself in errors with the latter one big time. It seemed to be that one cannot import from module n-1's child class module n's child class relatively to the namespace defined.

Might be that I am missing something, but Python seem to work on this particular use-case entirely differently than any OOP-languages I been using before (like C# for instance), which might connect to the fact Python has no real code encapsulation (private/public class/functional level etc...). Correct if I am wrong, I had no time to observe more deeper Python's interesting design philosophy.

Katinakatine answered 8/9, 2023 at 9:27 Comment(0)
H
-2

I had a similar problem and solved it by creating a symbolic link to the package in the working directory:

ln -s ../../../my_package my_package

and then import it as usual:

import my_package

I know this is more like a "Linux" solution rather than a "Python" solution. but it's a valid approach nonetheless.

Hooknosed answered 8/1, 2021 at 8:7 Comment(0)
K
-2

I had the same problem and after struggling I've solved it by using the below code:

%run fileName.ipynb
Krystynakshatriya answered 5/8, 2023 at 8:14 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.