0

Given

Let's say I have a code repository "my_tools" with some common code and some scripts (here e.g. fooscript) residing in subdirectories.

utils.py

def my_util():
    print("baz")

fooscript.py

import sys; print(sys.path)
from commons.utils import my_util
my_util()

(all __init__.py are empty)

repo structure

What happens when running it

When I run fooscript from the my_tools root directory, here is what happens:

> python foo/fooscript.py
['/home/michel/my_tools/foo', ... python internals ... ]
Traceback (most recent call last):
  File "foo/fooscript.py", line 3, in <module>
    from commons.utils import my_util
ModuleNotFoundError: No module named 'commons'

This surprised me - I was expecting that running python interpreter from my_tools directory it would put my_tools onto sys.path. Instead it puts the parent directory of the script actually being run. Putting an __init__.py in the root directory makes no difference.

Question

What are best practices to resolve this import issue? Approaches I have considered:

  1. Adding my_tools manually onto PYTHONPATH variable, e.g. in a Makefile target.

  2. Messing with sys.path inside the code. This is strictly worse than the above solution IMO.

  3. Wrapping the scripts to be run under a common my_tools.py under the root directory. I guess OK, but it would be something that lives in addition to what is going to be run in AWS Lambda (each lambda only needing the commons directory plus the invidual script directory).

  4. Doing only relative imports instead. Not really an option here because for deployment I want to package commons on a separate AWS lambda layer, requiring absolute imports. Although it could be achieved using a custom docker image for lambda, but I'd still prefer to be able to steer the working directory.

Am I missing something here? If not wanting to add additional path or import manipulations, is the best practice here really to modify PYTHONPATH?

Background

the subtleties of this question come from the desire to run locally an AWS Lambda based repository of microservices with some common code put on a lower layer.

Michel Müller
  • 5,535
  • 3
  • 31
  • 49
  • Does this answer your question? [Importing modules from parent folder](https://stackoverflow.com/questions/714063/importing-modules-from-parent-folder) – Paolo Feb 28 '23 at 16:50
  • @Paolo: I think it could be packaged into a separate answer, but it's not exactly the same question that I had. Mainly, the answers are the approaches I already outlined, with one more that I was missing: packaging up your commons into a library using a setup.py and importing it like a library. – Michel Müller Mar 01 '23 at 09:39

0 Answers0