1 year ago

#371425

test-img

peguerosdc

How to import from subpackage (without exposing) when building using setuptools?

I am packaging a personal Python project and uploading it to pypi. It has the following structure:

root
├── package
│   ├── __init__.py
│   ├── foo.py
│   └── subpackage
│       ├── bar.py
│       └── __init__.py
├── setup.py
└── test.py

Now, foo.py has a function called public_function that depends on bar.py:bar_function , so I am structuring my code as:

# package/foo.py
from package.subpackage import bar_function

def public_function():
    return bar_function()
# package/subpackage/__init__.py
from .bar import bar_function

My goal is to let people call public_function while hiding all its dependencies like this:

import package
package.bar_function()

So package/__init__.py looks like:

from .bar import bar_function

This is working correctly when importing from test.py, but when building using setuptools, things start getting weird.

After checking these similar questions (one, two and three) these are the two approaches I have tried, but don't work as I want:

Approach 1

As I don't want to expose subpackage, I tried:

# package/setup.py
from setuptools import setup
setup(
    name='package',
    packages=['package']
)

But when I do import package (after uploading to pypi and running pip install package), I get the following error:

File /venv/lib/python3.8/site-packages/package/foo.py:1
----> 1 from package.subpackage import bar_function
ImportError: cannot import name 'bar_function' from 'package.subpackage' (unknown location)

(I also tried with a relative import from .subpackage ... but didn't work)

Approach 2

As it looked like the subpackages are not making it to the build, I tried:

# package/setup.py
from setuptools import setup, find_packages
setup(
    name='package',
    packages=find_packages()
)

Which doesn't yield the error anymore, but now I end up exposing everything else (i.e I can do import foo and import subpackage) which I don't want.

What should be the right way to set up my package? Is it even possible to achieve what I want in Python?

python

setuptools

pypi

setup.py

python-packaging

0 Answers

Your Answer

Accepted video resources