6

My python app has a folder structure like this:

my_repo/
  src/
    main.py
    util/   <-- util is a git submodule
      src/
        torgle.py
      test/
        test_torgle.py
  test/
    test_main.py

Inside main.py, I can import stuff in my util submodule like this:

from util.src.torgle import Torgler

But src/ is just a way to keep things organized in my git submodule repo, and shouldn't really be a logical part of the package name inside the main repo. Is there some way I can skip the src part of the module import? I'd rather do this:

from util.torgle import Torgler

I.e. can I essentially alias util/src folder to the Python util package?

(Note that in my real case I have more deeply nested packages (util.x.y.z.torgle), so from util import torgle; torgle.Torgler(...) won't scale well. I'm specifically interested in from util.torgle import Torgler.)

Sasgorilla
  • 2,403
  • 2
  • 29
  • 56
  • Is there any reason why you build the Python app directly from the repositories, instead of, say, installing it and merging the repository directories in the process? – MisterMiyagi Mar 31 '20 at 13:30
  • @MisterMiyagi I'm no Python expert -- could you say more about what you mean by "installing it"? To clarify my situation, both `my_repo` and `util` are my own repositories; `util` is shared between several projects. So if there's a better way to manage that (and still allow me to import from `util` like `from util.torgle ...`), I'm definitely flexible. – Sasgorilla Apr 01 '20 at 17:11
  • Are you aware of ``setup.py`` or ``PYTHONPATH``? Basically you can merge your code into one single, installable package, or adjust how Python loads modules. – MisterMiyagi Apr 01 '20 at 18:21

2 Answers2

1

You can kind of do this by adding my_repo/src/util/__init__.py and adding the following line to it:

from .src import torgle

You'll then be able to do the following:

from util import torgle
torgle.Torgler(...)
Benjamin Rowell
  • 1,371
  • 8
  • 16
  • 5
    Works great, but unfortunately for just one level as shown here. In my real case I have more deeply nested packages (`util.x.y.z.torgle`), so I believe with this technique I would have to do `from util import x; x.y.z.torgle.Torgler(...)`, right? So I'm specifically interested in getting `from util.torgle import Torgler` to work. I've updated the question to clarify that. – Sasgorilla Mar 31 '20 at 13:29
1

My solution is based on an OS trick, while the one of Benjamin Rowell is python specific and very elegant. I suggest taking a look at it first.


The solution are the symbolic links

Explanation

Your situation should be the following:

Directory tree

Where the actual library is within useless_dir, but you want to access it directly.

If you want to import library.py from the main file, the standard way is:

from useful_dir.useless_dir.library import p_func

p_func()

Then, when you call main.py:

python3 main.py  # Hello World!

Here's the trick you are searching for:

1) Place yourself within the useful_dir folder: Useful directory

2) From within this directory create a symbolic link:

ln -s useless_dir/library.py any_name_for_the_library.py

3) Change accordingly the main content:

from useful_dir.any_name_for_the_library import p_func

p_func()

The end

Mattia Baldari
  • 567
  • 1
  • 5
  • 15