【发布时间】:2017-12-21 17:10:20
【问题描述】:
情况
这是一个示例包的结构:
$ tree Foo/
Foo/
├── setup.py
└── src
├── bar.py
└── __init__.py
包的名称应为foo,但包的源文件放在src 文件夹中。
文件的内容是:
setup.py:
from setuptools import setup
setup(
name='foo',
version='1',
packages=['foo'],
package_dir={'foo': 'src'}
)
__init__.py:
from .bar import bar
print(bar)
bar.py:
bar = 1
问题
当pip install Foo 一切都很好,我可以按照我的期望使用这个包:
>>> import foo
1
但是,当我以可编辑模式 (pip install -e Foo) 安装包时,它不起作用:
>>> import foo
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: No module named 'foo'
我现在可以导入src:
>>> import src
1
使用-e 开关安装创建了一个site-packages/foo.egg-link 文件,其内容如下:
<path-to>/Foo
.
在Foo中创建了对应的foo.egg-info目录:
$ tree Foo/foo.egg-info/
Foo/foo.egg-info/
├── dependency_links.txt
├── PKG-INFO
├── SOURCES.txt
└── top_level.txt
SOURCES.txt 文件包含:
$ cat Foo/foo.egg-info/PKG-INFO
foo.egg-info/PKG-INFO
foo.egg-info/SOURCES.txt
foo.egg-info/dependency_links.txt
foo.egg-info/top_level.txt
src/__init__.py
src/bar.py
还有top_level.txt:
$ cat Foo/foo.egg-info/top_level.txt
foo
因此,在导入过程中,Python 似乎忽略了 Foo/foo.egg-info/ 中显示的信息,而是仅扫描 Foo/ 以查找名为 foo 的包(未找到)。
问题
我如何准备一个使用单独的源文件夹(其名称与包名称不同)的包,以便我可以在可编辑模式下安装它并仍然像正常安装一样使用它(即import <package-name> 应该例如在任何情况下都可以工作)。
【问题讨论】:
-
出于好奇,为什么包目录首先命名为
src? -
@Grimmy 诚然,我通常遵循在包之后命名源根目录的约定(在此示例中为
foo),这在技术上解决了上述问题。但是我发现distutils/setuptools支持源目录的自定义名称,所以我想知道这与在可编辑模式下安装的效果如何。因此,这个问题更像是“好奇的相关性”。
标签: python pip packages setuptools distutils