8

我已经使用 setuptools 一段时间了,最​​近使用 pip 为我的项目创建发行版,一切正常:“python setup.py sdist”、“python setup.py install”等命令按配置工作。现在我想使用 pip 安装为“可编辑”,以便在我对这个包进行维护时简化测试。所以我尝试了

cd \
pip install -e .\mypackage

这会将路径:c:\mypackage 添加到 C:\python27\Lib\site-packages\easy-install.pth。但是,在我的情况下这是错误的,因为 mypackage 的结构如下:

C:\mypackage 
    setup.py 
    src 
        mypackage 
            __init__.py
             ... 
    docs 
    tests

所以easy-install.pth 应该包含c:\mypackage\src,而不是c:\mypackage。我可以手动编辑 easy-install.pth 以将“\src”添加到添加的路径中,然后“import mypackage”成功,正如它应该的那样。如果我从 c:\mypackage 运行命令“python setup.py develop”,也会出现同样的问题,因此问题可能出在 setuptools 级别。

setup.py 有:

setup( 
     ... 
     packages = find_packages('src'), 
     package_dir = {'mypackage': 'src/mypackage'}, 
     ... 
)

(唯一的其他设置参数是作者、版本等文本项,由于与问题无关,因此未列出)。

我不想在easy-install.pth 中编辑路径。查看文档,看不到任何迹象表明将包源根目录放在与 setup.py 分开的文件夹中是一个问题。我做错了什么?

4

1 回答 1

9

我找到了答案。原来这是在 distutils 级别(pip 依赖于 setuptools,而 setuptools 又依赖于 distutils)。“分发 Python 模块”的第 2.1 节讨论了 package_dir 参数的使用,表明“[如果]你将所有 Python 源代码保存在 lib 下,那么“根包”中的模块(即根本不在任何包中)是在 lib 中, foo 包中的模块在 lib/foo, ",那么你应该使用

setup(
   ...
   packages = ['foo'],
   package_dir = {'': 'lib'},
   ...
)

从 OP 中可以看出,对我来说确实是这种情况,所以我改为如下:

setup(
   ...
   packages = ['mypackage'],
   package_dir = {'': 'src'},
   ...
)

这行得通。所以问题是为什么

   package_dir = {'': 'src'}

适用于发布和可编辑安装,而

   package_dir = {'mypackage': 'src/mypackage'}

适用于发行版,但不适用于可编辑安装。

答案是默认情况下,distutils(以及 setuptools 和 pip)期望分发的“根”是包含 setup.py 的文件夹:任何要安装在 site-packages 中的 *.py 和 package 文件夹都应该是那里; 如果他们在其他地方,则必须告知。这是通过在 package_dir 中有一个带有键 '' 的条目来完成的。由于我原来的 package_dir 没有这个,distutils 假设我的 dist 的根目录是包含 setup.py 的文件夹,这就是它指向可编辑安装的目录。发布安装运行良好,因为我所说的 package_dir 说 mypackage/ init .py 在 src/mypackage 中,它就是这样,所以对于“常规”分发来说一切正常。

于 2013-11-11T22:20:37.153 回答