如何强制 setup.py 包含 `__init__.py` 文件并使我的包可导入?

How do I force setup.py to include the `__init__.py` file and make my package importable?

我正在尝试让使用 pip 安装它的人可以导入我的 Python project。虽然它包含一个 __init__.py 并且在本地作为一个包工作,但我似乎误解了 setuptools 的工作原理。

我运行下面三个命令上传包。

python3 setup.py sdist bdist_wheel
python3 -m pip install  --upgrade twine
python3 -m twine upload dist/*

然后在另一台机器上,我运行 pip3 install smux.py。结果是我可以作为命令访问 smux.py,但是在尝试导入它时出现导入错误。

python3
Python 3.8.5 (default, Jul 28 2020, 12:59:40) 
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import smux
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'smux'

在 运行 执行上面的 setup.py 命令后,我检查了当前目录中的 smux.py.egg-info/SOURCES.txt 并发现它包含以下内容:

README.md
setup.py
smux.py
smux.py.egg-info/PKG-INFO
smux.py.egg-info/SOURCES.txt
smux.py.egg-info/dependency_links.txt
smux.py.egg-info/top_level.txt

文件 __init__.py 丢失。

如何将该文件放入包中,或修改设置调用以使 smux 可导入?

您的 setup 调用如下所示:

setup(
  name="smux.py",
  version='0.1.1',
  scripts=['smux.py'],
  author="Henry Qin",
  author_email="root@hq6.me",
  description="Simple tmux launcher that will take less than 2 minutes to learn and should work across all versions of tmux",
  long_description=long_description,
  platforms=["All platforms that tmux runs on."],
  license="MIT",
  url="https://github.com/hq6/smux"
)

使用 scripts 参数,您已经告诉 setuptools smux.py 是一个脚本,而不是一个模块。因此,它作为脚本而不是模块安装。

您的代码不需要 __init__.py,也不应该有。拥有 __init__.py 将无济于事。您需要告诉 setuptools 将您的文件安装为模块而不是脚本,并单独注册一个入口点,在 entry_points 参数中使用 console_scripts 条目:

setup(
    ...
    # no scripts= line
    py_modules=['smux'],
    entry_points={
        'console_scripts': ['smux=smux:main']
    }
)

然后当您的代码被安装时,smux 将是可导入的,并且将有一个 smux 脚本可从命令行调用 smux.main.

另一个答案是更符合犹太洁食和现代的答案,如果我没有根据名称 smux.py 遗留的脚本,我会使用它并将脚本命名为 smux。不幸的是,其他人已经包装 smux.py 并且破坏他们的脚本是不友好的。

这是我为避免循环依赖问题所做的工作,该问题是由于遗留脚本名称以 .py 结尾并与模块命名冲突而引起的。

我最终修改了 setup 调用,使其具有以下两项。

  py_modules=['smux'],
  scripts=['smux.py']

我的实验表明,这具有使模块可导入的预期效果,同时保留名称为 smux.py 的工作脚本。