繁体   English   中英

如何将 setup.py console_script 与本机命名空间包一起使用

[英]How to use setup.py console_script with native namespace packages

我无法为使用console_scripts命名空间包结构的 Python package 定义控制台脚本。

我遵循Python 打包文档中概述的 Python 命名空间包。 具体来说,我在 Python 3.8.2 中使用原生命名空间包装

我这样创建了我的项目:

src
└── main
   └── python
      └── mynamespace-mypackage
         ├── mynamespace
         │  └── mypackage
         │     ├── __init__.py
         │     ├── __main__.py
         │     ├── module_a.py
         │     └── module_b.py
         └── setup.py

setup.py中,我写:


#!/usr/bin/env python3

from setuptools import setup, find_namespace_packages

PACKAGE = "mynamespace-mypackage"
VERSION = "0.1a"

setup(
    name=PACKAGE,
    version=VERSION,
    packages=find_namespace_packages(include=["mynamespace.*"]),
    description="My fancy package",
    entry_points={
        "console_scripts": {
            "do-some-stuff = mypackage.__main__:main"
        }
    }
)

当我通过调用pip install -e src/main/python/mynamespace-mypackage使用 pip 安装我的项目时,package 安装成功。 但是,当我从命令行调用do-some-stuff时,我得到ModuleNotFoundError: No module named 'mypackage'

我还尝试将console_scripts修改为:


    entry_points={
        "console_scripts": {
            "do-some-stuff = mynamespace.mypackage.__main__:main"
        }
    }

但这也会给出ModuleNotFoundError: No module named 'mynamespace.mypackage当我从命令行运行do-some-stuff时。

我应该如何定义我的程序的入口点以正确指向我的 package 的__main__:main function? 任何帮助深表感谢。

潜在的解决方法:

根据setuptools 文档,如果我将__init__.py添加到mynamespace目录,内容如下

__import__("pkg_resources").declare_namespace(__name__)

并通过添加namespace_packages=["mynamespace"]修改setup.py ,入口点起作用。 我可以确认这解决了我的问题。 但是,我认为这并不理想。 Python 打包文档明确指出,在使用原生打包时,我不应将任何__init__.py添加到命名空间目录中。

一个最小的可重现示例:

src/main/python/mynamespace-mypackage/mynamespace/mypackage/__init__.py :

#!/usr/bin/env python3

from .module_a import Hello
from .module_b import GoodBye

__all__ = ["Hello", "GoodBye"]

src/main/python/mynamespace-mypackage/mynamespace/mypackage/__main__.py :

#!/usr/bin/env python3

from . import Hello, GoodBye

def main() -> None:
    h = Hello()
    h.say_hi()
    g = GoodBye()
    g.say_bye()

if __name__ == "__main__":
    main()

src/main/python/mynamespace-mypackage/mynamespace/mypackage/module_a.py :

#!/usr/bin/env python3


class Hello:
    def say_hi(self) -> None:
        print("Hello!")

src/main/python/mynamespace-mypackage/mynamespace/mypackage/module_b.py :

#!/usr/bin/env python3


class GoodBye:
    def say_bye(self) -> None:
        print("Good Bye!")

事实证明,这个问题是一个过时的setuptools库。 我正在使用setuptools-41.2.0 我升级到setuptools-46.1.3 ,现在我的最小示例按预期工作。 不需要解决方法。

pip install -U setuptools

即使使用setuptools-52.0.0 ,使用pkgutil-style 命名空间包是我让它工作的唯一方法

src/main/python/mynamespace-mypackage/mynamespace/__init__.py

__path__ = __import__("pkgutil").extend_path(__path__, __name__)

并将命名空间添加到setup.py中的包:

packages=["mynamespace", "mynamespace.mypackage"])

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM