1

I am trying to import a util package one directory up from where my code is, but I get an ImportError which I don't understand.

I have a number of different variations on the import syntax in Python, none of which are working.

There are a number of similar questions on Stack Overflow, but none have helped me understand or fix this issue.

Of the top of my head, I have tried the following variations:

import util
import ..util
from .. import util
from ..util import parser
from AdventOfCode2022 import util
from ..AdventOfCode2022 import util
from ...AdventOfCode2022 import util

Most of these I guessed wouldn't work, but I tried them anyway to be sure.

Error message:

ImportError: attempted relative import with no known parent package

Directory structure:

.
├── day03
│   ├── input.txt
│   ├── part1.py
│   ├── part2.py
│   └── test_input.txt
└── util
    ├── __init__.py
    └── parser.py

I just want to import my util package from any "day0*/" directory - not sure why Python makes it so hard!

mkrieger1
  • 19,194
  • 5
  • 54
  • 65
Sam Wood
  • 327
  • 3
  • 17
  • 1
    Does this answer your question? [Relative imports for the billionth time](https://stackoverflow.com/questions/14132789/relative-imports-for-the-billionth-time) – Brian61354270 Jan 15 '23 at 21:26
  • Which directory or directories do you want to be top-level packages? – Brian61354270 Jan 15 '23 at 21:27
  • 2
    Relative imports are not a directory traversal mechanism. If you ever find yourself thinking "I want to import this thing in this directory", relative imports are not the answer. – user2357112 Jan 15 '23 at 21:27
  • I'm sorry but that doesn't help me. I'm sure it's very accurate and correct, but it's also extremely verbose and difficult to understand and apply to my exact situation. What exactly do I need to type in order for "day03/part1.py" to import "util/parser.py"? Note that the top level directory in the structure I posted, isn't a Python package and that's intentional, I don't need or want it to be one. I just want "day*/*.py" to be able to import "util/*.py" and run without error. – Sam Wood Jan 15 '23 at 22:46
  • Create a `__init__.py` file in the parent directory and check again by calling `from AdventOfCode2022.util import ` – Patryk Jan 16 '23 at 01:37
  • 1
    @Patryk They don't want to make the `AdventOfCode2022` directory into a package. – mkrieger1 Jan 16 '23 at 01:43
  • 1
    Does this answer your question? [ImportError: No module named ](https://stackoverflow.com/a/43476575/674039) – wim Jan 16 '23 at 02:24

1 Answers1

1

Two options:

  1. Add the full path to ./util/ to your PYTHONPATH environment variable.

For example on Bash, your ~/.bashrc might have export PYTHONPATH="${PYTHONPATH}:/Users/foobar/projects/advent-of-code/util/".

  1. Add sys.path.append('/path/to/application/app/folder') before the import.

The other solutions don't work because:

  1. day03 and the parent directory are not modules with their own __init__.py. Lines like from ..util import parser only work if everything involved is a module.
  2. You are presumably running the code from within ./day03/.

View this as 'I have a bunch of independent Python projects (day01, day02 etc) that all want to share a common piece of code I have living in a different project (util) that lives somewhere else on my computer.'

Gamma032
  • 441
  • 4
  • 7
  • 1
    It is not the full path to `./util/` that should be added to PYTHONPATH, but the parent directory of that path. – wim Jan 16 '23 at 02:20
  • Is there a functional difference @wim ? Both both work for me. – Gamma032 Jan 16 '23 at 03:31
  • 1
    There is - for `from util import parser` to work, it's the _parent_ of util that needs to be on `sys.path`. – wim Jan 16 '23 at 04:36