简单的脚本可以在问题的末尾再现错误。
这也是作为https://github.com/pypa/pip/issues/10810上的一个bug提交的
对于如下结构的pkg:
.
├── setup.py
└── src
└── my_pkg
├── __init__.py
└── main.py
像这样的setup.py:
from setuptools import setup, find_packages
setup(
name='test-pkg',
packages=find_packages('src'),
package_dir={
'my_pkg': 'src/my_pkg',
},
)
创建一个轮子并安装它的允许我导入"my_pkg",但是使用安装软件包却不能。为什么??
安装转轮允许导入"my_pkg“,而通过"-e”安装只允许导入"src“,这违背了目的,因为"src”不是包dir。
python -c "import my_pkg"
Traceback (most recent call last):
File "<string>", line 1, in <module>
ModuleNotFoundError: No module named 'my_pkg'
pip版本: 21.3.1 (最新)
概括地说:
工作:
pip install .
python setup.py bdist_wheel && pip install dist/*whl
不起作用:
pip install -e .
python setup.py develop
(这是pip install -e
运行的程序,但我想确保在过渡过程中没有丢失任何东西)奥普西..。
但是,对于.-info格式,基本位置是包含. egg __的目录,因此它是必须添加到sys.path中的目录,才能使鸡蛋变得重要。(请注意,这意味着将包安装到sys.path目录中的“正常”安装就足以使其成为一个“鸡蛋”,如果它旁边安装了一个.egg文件或目录。)
我不完全确定这意味着我完蛋了,但有可能。有办法绕过这件事吗?
错误复制脚本:
#!/bin/bash
set -e
mkdir -p reproduce_pip_install_e_bug/src/my_pkg
cd reproduce_pip_install_e_bug
touch src/my_pkg/__init__.py
echo "
from setuptools import setup, find_packages
setup(
name='test-pkg',
packages=find_packages('src'),
package_dir={
'my_pkg': 'src/my_pkg',
},
)
" > setup.py
virtualenv -p python3.6 good_venv > /dev/null && . good_venv/bin/activate && pip install . -vvv &> .good_installation.log && python -c "import my_pkg"
echo this was successful, however, next command will break
virtualenv -p python3.6 bad_venv > /dev/null && . bad_venv/bin/activate && pip install -e . -vvv &> .bad_installation.log && python -c "import my_pkg"
发布于 2022-01-21 04:37:42
==解决方案==
PYTHONPATH
去营救!
运行export PYTHONPATH=<abspath_to_src>
可以避免这个问题。但是,在本例中,sys.path
与sys.path
of pip install .
不同--它们都有src的路径,但pip install -e .
也有根目录的路径--允许导入它,这是不应该发生的。
发布于 2022-01-22 08:52:56
为了在setuptools中使用所谓的src
_-布局,setup.py应该如下所示:
from setuptools import setup, find_packages
setup(
name='test-pkg',
packages=find_packages('src'),
package_dir={
'': 'src',
},
)
package_dir
应该得到一个空字符串作为键。
在setuptools的“废弃”文档中对此作了某种解释。
此字典的键是包名,空包名表示根包。这些值是相对于分发根目录的目录名。在这种情况下,当您说
packages = ['foo']
时,您保证文件lib/foo/__init__.py
是存在的。
-- dir#列表-整包
...and类似于最新版本的文档,但在某种程度上可以将内容拼凑在一起:
https://stackoverflow.com/questions/70777486
复制相似问题