Python 3.8 - 软件包发布损坏,但在本地安装时有效

Python 3.8 - Package release broken, but works when installed locally

好的,所以我正在开发我们在 Pypi 和 Anaconda 上发布的这个 python 包。在其中,我们有许多 python 个文件,其中包含 类。从历史上看,我使用过以下结构,没有问题。

repo/
    conda/
        conda_build_config.yaml
        meta.yaml
    setup.py
    src/
        A
            ClassA
        B
            ClassB
        ...
        __init__.py
            from .A import ClassA
            from .B import ClassB
            ...

我们进行 GitHub 发布,GitHub 动作为我们捆绑所有内容并发布到 PyPi 和 Condas。很简单。但是 类 的数量已经增长到平面层次结构没有意义的地步,我们想开始将它们分组为嵌套在各个组中的子包,如下所示:

repo/
    conda/
        conda_build_config.yaml
        meta.yaml
    setup.py
    package/
        Group1/
            A
                ClassA
            B
                ClassB
            __init__.py
                from .A import ClassA
                from .B import ClassB
        Group2/
            C
                ClassC
            D
                ClassD
            __init__.py
                from .C import ClassC
                from .D import ClassD
        ...
        __init__.py
            from .Group1 import ClassA
            from .Group1 import ClassB
            from .Group2 import ClassA
            from .Group2 import ClassB
            ...

奇怪的是:如果我 运行 pip install -e . 在本地测试它,这个新设置完全符合我的要求。但是,如果我将它发布到 PyPi,pip install package,然后 运行 import package,我会收到以下错误:

ModuleNotFoundError: No module named package.A

我尝试了几种不同的组织结构,以各种方式使用 init.py,以及我从其他相关问题中找到的所有建议和结构,但它似乎总是这样,当推送到 PyPi 时,作为本地安装起作用的东西不起作用。我在这里错过了什么?

---编辑---

除了接受的答案中描述的解决方案外,我还必须将我的 package/ 移到 src/ 中并将以下内容添加到我的 setup.py:

package_dir={"": "src"},
packages=find_packages(where="src"),

这确保所有子包都捆绑到包中。

我们可以尝试在您的 __init__.py 文件中添加 __all__ 变量。
例如在 Group1__init__.py 中,我们可以添加:

from .A import ClassA
from .B import ClassB

__all__ = [
    'ClassA',
    'ClassB'
]

并对其他文件夹中的另一个 __init__.py 应用相同的技巧。
这应该可以完成工作。