python - 点安装。仅创建 dist-info 而不是包
问题描述
我正在尝试制作一个我想在pip install .
本地安装的python包。包名列在其中,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'
],
)
解决方案
由于该问题已变得非常流行,因此以下是安装后丢失文件时要执行的诊断步骤。想象有一个具有以下结构的示例项目:
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
,也spam/eggs.py
看不到,也看不到:bacon.py
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 文件并从中安装您的包。如果在详细模式下重新安装,我们可以检查轮子构建过程的日志。第一步是卸载包:
$ pip uninstall -y mypkg
...
然后再次安装它,但现在有一个额外的参数:
$ pip install . -vvv
...
现在,如果我检查日志:
$ pip install . -vvv | 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
在任何地方提及。这意味着它们根本没有包含在轮文件中,因此没有安装pip
。最常见的错误来源是:
缺少包:检查packages
参数
验证您已将packages
参数传递给 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
推荐阅读
- ruby-on-rails - “rake routes”导致语法错误:time_zone.rb 循环参数参考 - 现在
- elasticsearch - 弹性搜索 - 根据日期重新索引数百万条记录
- arrays - Bash:计算关联数组中的键总数?
- python - 在 python 中的 sklearn 中保存 EllipticEnvelope 模型
- python - Python 无法启动新线程多处理
- python - python中列表的深拷贝
- ios - AWS S3 文件上传在带有 Ionic 的 iOS 中给出 NetworkingError
- python - 使用 numpy 结构比较两个数组可能更快的代码
- xml - 带有命名空间的 XML 文件不使用 XSLT 加载
- java - 获取“”侧的原始字符串