如何将 setup.py console_script 与本机命名空间包一起使用
How to use setup.py console_script with native namespace packages
我无法为使用 Python 命名空间包结构的 Python 包定义 console_scripts
。
我正在关注 Python 3.8.2 中的 Python packaging document. Specifically, I am using native namespace packaging 中概述的 Python 命名空间包。
我是这样创建我的项目的:
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 安装我的项目时,包安装成功。但是,当我从命令行调用 do-some-stuff
时,我得到 ModuleNotFoundError: No module named 'mypackage'
.
我还尝试将 console_scripts
修改为:
entry_points={
"console_scripts": {
"do-some-stuff = mynamespace.mypackage.__main__:main"
}
}
但是当我从命令行 运行 do-some-stuff
时,这也会给出 ModuleNotFoundError: No module named 'mynamespace.mypackage
。
我应该如何定义程序的入口点以正确指向包的 __main__:main
函数?非常感谢任何帮助。
可能的解决方法:
基于setuptools documentation,如果我将__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
我无法为使用 Python 命名空间包结构的 Python 包定义 console_scripts
。
我正在关注 Python 3.8.2 中的 Python packaging document. Specifically, I am using native namespace packaging 中概述的 Python 命名空间包。
我是这样创建我的项目的:
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 安装我的项目时,包安装成功。但是,当我从命令行调用 do-some-stuff
时,我得到 ModuleNotFoundError: No module named 'mypackage'
.
我还尝试将 console_scripts
修改为:
entry_points={
"console_scripts": {
"do-some-stuff = mynamespace.mypackage.__main__:main"
}
}
但是当我从命令行 运行 do-some-stuff
时,这也会给出 ModuleNotFoundError: No module named 'mynamespace.mypackage
。
我应该如何定义程序的入口点以正确指向包的 __main__:main
函数?非常感谢任何帮助。
可能的解决方法:
基于setuptools documentation,如果我将__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