pip install . 仅创建 dist-info 而不是包
- 2025-04-16 08:56:00
- admin 原创
- 13
问题描述:
我正在尝试创建一个要在本地安装的 Python 包pip install .
。包名称已列出,pip freeze
但import <package>
出现错误No module named <package>
。此外,site-packages 文件夹只包含一个 dist-info 文件夹。find_packages()
无法找到包。我遗漏了什么?
import io
import os
import sys
from shutil import rmtree
from setuptools import find_packages, setup, Command
# Package meta-data.
NAME = '<package>'
DESCRIPTION = 'description'
URL = ''
EMAIL = 'email'
AUTHOR = 'name'
# What packages are required for this module to be executed?
REQUIRED = [
# 'requests', 'maya', 'records',
]
# The rest you shouldn't have to touch too much :)
# ------------------------------------------------
# Except, perhaps the License and Trove Classifiers!
# If you do change the License, remember to change the Trove Classifier for that!
here = os.path.abspath(os.path.dirname(__file__))
# Where the magic happens:
setup(
name=NAME,
#version=about['__version__'],
description=DESCRIPTION,
# long_description=long_description,
author=AUTHOR,
author_email=EMAIL,
url=URL,
packages=find_packages(),
# If your package is a single module, use this instead of 'packages':
# py_modules=['mypackage'],
# entry_points={
# 'console_scripts': ['mycli=mymodule:cli'],
# },
install_requires=REQUIRED,
include_package_data=True,
license='MIT',
classifiers=[
# Trove classifiers
# Full list: https://pypi.python.org/pypi?%3Aaction=list_classifiers
'License :: OSI Approved :: MIT License',
'Programming Language :: Python',
'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: Implementation :: CPython',
'Programming Language :: Python :: Implementation :: PyPy'
],
)
解决方案 1:
由于这个问题已经很常见了,以下是安装后文件丢失时的诊断步骤。假设有一个示例项目,其结构如下:
root
├── spam
│ ├── __init__.py
│ ├── data.txt
│ ├── eggs.py
│ └── fizz
│ ├── __init__.py
│ └── buzz.py
├── bacon.py
└── setup.py
现在我运行pip install .
,检查包是否已安装:
$ pip list
Package Version
---------- -------
mypkg 0.1
pip 19.0.1
setuptools 40.6.3
wheel 0.32.3
但在已安装软件包的文件列表中看不到spam
、 nor spam/eggs.py
nor bacon.py
nor :spam/fizz/buzz.py
$ pip show -f mypkg
Name: mypkg
Version: 0.1
...
Files:
mypkg-0.1.dist-info/DESCRIPTION.rst
mypkg-0.1.dist-info/INSTALLER
mypkg-0.1.dist-info/METADATA
mypkg-0.1.dist-info/RECORD
mypkg-0.1.dist-info/WHEEL
mypkg-0.1.dist-info/metadata.json
mypkg-0.1.dist-info/top_level.txt
那么现在该怎么办?
通过检查车轮制造日志进行诊断
除非被告知不要这样做,pip
否则将始终尝试构建一个 wheel 文件并从中安装您的软件包。如果在详细模式下重新安装,我们可以检查 wheel 构建过程的日志。第一步是卸载软件包:
$ pip uninstall -y mypkg
...
然后再次安装它,但现在带有一个附加参数:
$ pip install . -vvv
...
现在如果我检查日志:
$ pip install . -vvv 2>&1 | grep 'adding'
adding 'mypkg-0.1.dist-info/METADATA'
adding 'mypkg-0.1.dist-info/WHEEL'
adding 'mypkg-0.1.dist-info/top_level.txt'
adding 'mypkg-0.1.dist-info/RECORD'
spam
我注意到目录或目录中的文件没有bacon.py
被提及。这意味着它们根本不包含在wheel文件中,因此无法被安装pip
。最常见的错误来源是:
缺少软件包:检查packages
参数
确认已将packages
参数传递给 setup 函数。检查是否已提及所有需要安装的软件包。如果仅提及父软件包,则不会自动收集子软件包!例如,在 setup 脚本中
from setuptools import setup
setup(
name='mypkg',
version='0.1',
packages=['spam']
)
spam
将会被安装,但不会安装,spam.fizz
因为它本身就是一个包,所以必须明确提及。修复方法:
from setuptools import setup
setup(
name='mypkg',
version='0.1',
packages=['spam', 'spam.fizz']
)
如果您有很多包,请使用以下方法setuptools.find_packages
来自动化该过程:
from setuptools import find_packages, setup
setup(
name='mypkg',
version='0.1',
packages=find_packages() # will return a list ['spam', 'spam.fizz']
)
如果您缺少某个模块:
缺少模块:检查py_modules
参数
bacon.py
在上面的例子中,由于它不属于任何包,安装后会丢失。我必须在单独的参数中提供它的模块名称py_modules
:
from setuptools import find_packages, setup
setup(
name='mypkg',
version='0.1',
packages=find_packages(),
py_modules=['bacon']
)
缺少数据文件:检查package_data
参数
我现在已经把所有源代码文件都准备好了,但该data.txt
文件仍然没有安装。位于包目录下的数据文件应该通过参数添加package_data
。修复上述安装脚本:
from setuptools import find_packages, setup
setup(
name='mypkg',
version='0.1',
packages=find_packages(),
package_data={'spam': ['data.txt']},
py_modules=['bacon']
)
不要试图使用该data_files
参数。将数据文件放在包下并进行配置package_data
。
修复安装脚本后,验证安装后包文件是否到位
如果我现在重新安装该软件包,我会注意到所有文件都已添加到轮子中:
$ pip install . -vvv | grep 'adding'
adding 'bacon.py'
adding 'spam/__init__.py'
adding 'spam/data.txt'
adding 'spam/eggs.py'
adding 'spam/fizz/__init__.py'
adding 'spam/fizz/buzz.py'
adding 'mypkg-0.1.dist-info/METADATA'
adding 'mypkg-0.1.dist-info/WHEEL'
adding 'mypkg-0.1.dist-info/top_level.txt'
adding 'mypkg-0.1.dist-info/RECORD'
它们也将显示在属于以下文件列表中mypkg
:
$ pip show -f mypkg
Name: mypkg
Version: 0.1
...
Files:
__pycache__/bacon.cpython-36.pyc
bacon.py
mypkg-0.1.dist-info/INSTALLER
mypkg-0.1.dist-info/METADATA
mypkg-0.1.dist-info/RECORD
mypkg-0.1.dist-info/WHEEL
mypkg-0.1.dist-info/top_level.txt
spam/__init__.py
spam/__pycache__/__init__.cpython-36.pyc
spam/__pycache__/eggs.cpython-36.pyc
spam/data.txt
spam/eggs.py
spam/fizz/__init__.py
spam/fizz/__pycache__/__init__.cpython-36.pyc
spam/fizz/__pycache__/buzz.cpython-36.pyc
spam/fizz/buzz.py
解决方案 2:
我遇到了同样的问题,更新setuptools
有所帮助:
python3 -m pip install --upgrade pip setuptools wheel
之后,重新安装该软件包,它应该可以正常工作:)
解决方案 3:
确保您的src
文件位于example_package_YOUR_USERNAME_HERE
(这是文档中使用的示例包名称) 中,而不是 中src
。错误地将文件放入 中src
可能会产生问题中描述的后果。
参考:https ://packaging.python.org/en/latest/tutorials/packaging-projects/
该包应按如下方式设置:
packaging_tutorial/
└── src/
└── example_package_YOUR_USERNAME_HERE/
├── __init__.py
└── example.py
解决方案 4:
对我来说,如果你这样做,我会发现有些奇怪的事情:
# Not in the setup.py directory
python /path/to/folder/setup.py bdist_wheel
当您安装轮子时,它只会在您的 site-packages 文件夹中安装 .dist-info 文件夹。
但是,如果你这样做:
cd /path/to/folder \n&& python setup.py bdist_wheel
该轮子将包含您的所有文件。
解决方案 5:
2024 年更新:建议使用pyproject.toml
而不是now。它由PEP 517和PEP 518setup.py
引入。你可以在这里找到这两种方法之间的区别
你需要做的就是确保__init__.py
模块的根目录和所有子目录都是空的。你还需要创建pyproject.toml
如下文件:
[build-system]
requires = ["setuptools"]
build-backend = "setuptools.build_meta"
[metadata]
name = "project"
version = "0.0.1"
[tool.setuptools.packages]
find = {} # Scan the project directory with the default parameters
[project]
name = "project"
version = "0.0.1"
authors = [
{ name="your_name", email="your_email" },
]
description = "Sample project "
readme = "README.md"
requires-python = ">=3.8"
很棒的文章解释了这里的设置
解决方案 6:
如果您使用的是 Windows 10 及更高版本,可以确保所有安装均正确无误的一种方法是点击左下角的“开始”,搜索 cmd.exe,然后右键单击“命令提示符”(确保选择“以管理员身份运行”)。输入“cd path to your Python 3.X installation
”。您可以在文件资源管理器中找到此路径(转到安装 Python 的文件夹),然后在顶部找到它。复制此路径,并将其放在我上面写的位置path to your Python 3.X installation
。完成后,按 Enter,输入“python -m pip install package
”(package
表示您要安装的软件包)。您的 Python 程序现在应该可以正常运行了。
解决方案 7:
我刚才遇到了这个问题,原因是我引用了旧的 pyproject.toml 文件中不存在的模块,而我之前已经把这个文件复制到了 [project.optional-dependencies] 目录下的新包中。所以,如果你安装时只生成了 dist-info 文件夹,但没有生成包的实际文件夹,请检查 pyproject.toml 文件夹是否有错误,尤其要确保 [project.optional-dependencies] 目录下没有列出任何你包中不存在的模块。
扫码咨询,免费领取项目管理大礼包!