使用setuptools构建时如何从子包导入(不暴露)?

发布于 2025-01-18 15:11:49 字数 2381 浏览 3 评论 0原文

我正在打包一个个人Python项目并将其上传到pypi。它具有以下结构:

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

现在, foo.py 有一个名为 public_function 的函数,它依赖于 bar.py:bar_function ,所以我正在构建我的代码为:

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

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

我的目标是让人们调用 public_function 同时隐藏其所有依赖项,如下所示:

import package
package.bar_function()

因此 package/__init__.py 看起来像:

from .bar import bar_function

测试.py,但是当使用 setuptools 构建时,事情开始变得奇怪。

检查这些类似的问题后(​​一个两个)这是我尝试过的两种方法,但不起作用想要:

方法1

由于我不想暴露subpackage,所以我尝试了:

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

但是当我import package时(上传到pypi并运行pip install之后)包),我收到以下错误:(

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)

我也尝试使用相对导入 from .subpackage ... 但没有工作)

方法 2

因为看起来子包不是使它进入构建,我尝试:

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

这不再产生错误,但现在我最终暴露了其他所有内容(即我可以执行 import fooimport subpackage )这是我不想要的。

设置我的套餐的正确方法应该是什么?是否有可能在 Python 中实现我想要的目标?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文