【问题标题】:pip install . creates only the dist-info not the package点安装。只创建 dist-info 而不是包
【发布时间】:2018-11-08 03:52:42
【问题描述】:

我正在尝试制作一个我想在本地使用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'
    ],

)

【问题讨论】:

  • 运行pip uninstall -y pkgname &amp;&amp; pip install -v .并检查构建日志是否处理了源文件(查找包含copying file &lt;filename&gt;adding &lt;filename&gt;的行)。如果文件已添加,请运行 pip show -f pkgname 并将两个命令的输出添加到问题中。
  • 非常感谢。这让我意识到我给setup.py 指定了一个与目录名称不同的包名称。
  • 我遇到了同样的问题,直到我意识到这是一个愚蠢的错误:我在项目仍在复制到新位置时开始了轮子构建过程。这样,它不包含任何 python 代码。所有使用不同设置安装轮子的尝试都注定会失败,因为轮子实际上不包含任何要安装的可用代码文件。
  • hoefling,您能否根据您的评论输入更完整的答案?我不知道如何检查构建日志,也不确定您希望我们添加什么到pip show

标签: python pip package setuptools setup.py


【解决方案1】:

对我来说,如果你这样做,我会注意到一些奇怪的事情:

# Not in the setup.py directory
python /path/to/folder/setup.py bdist_wheel

当你安装轮子时,它只会在你的站点包文件夹中安装 .dist-info 文件夹。

但是,如果你这样做:

cd /path/to/folder \
&& python setup.py bdist_wheel

轮盘将包含您的所有文件。

【讨论】:

  • 在 python 3.9 的 windows 上这对我也有用 py setup.py bdist_wheel
【解决方案2】:

由于该问题已变得非常流行,因此以下是安装后丢失文件时要执行的诊断步骤。想象有一个具有以下结构的示例项目:

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

【讨论】:

  • 在 Linux 上,我已经完成了以上所有操作。安装工作正常,但从 IPython 笔记本 import &lt;packagename&gt; 失败,但 !pip freeze | grep &lt;packagename&gt; 列出了它。在导入包之前还有什么需要做的吗?
  • 我应该补充一点,我很好奇为什么import mypkg 失败了。
  • 您是在尝试导入分发名称(设置脚本中name 参数下的内容)还是包名称之一(packages 参数下的内容)?您无法导入分发名称。总的来说,这是一个与这个无关的问题,我建议改为问另一个问题。
  • 优秀的答案!谢谢。
  • 另一个常见的错误来源:每个包都必须有一个 __init__.py 文件,以便 setuptools 找到它。如果您习惯于使用开发安装 (-e),很容易忘记这一点,而这并不需要。
【解决方案3】:

如果您使用的是 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 程序现在应该可以完美运行了。

【讨论】:

  • 我希望这能解决你的问题,你能提供一个更具体的例子吗?
猜你喜欢
  • 2019-04-21
  • 2019-10-22
  • 1970-01-01
  • 1970-01-01
  • 2018-02-06
  • 1970-01-01
  • 2016-10-30
  • 2014-01-24
  • 1970-01-01
相关资源
最近更新 更多