問題描述
我正在嘗試制作一個我想在本地使用 pip install .
安裝的 python 包.包名稱在 pip freeze
中列出,但 import <package>
會導致錯誤 No module named <package>
.此外,site-packages 文件夾僅包含 dist-info 文件夾.find_packages()
能夠找到包.我錯過了什么?
I am trying to make a python package which I want to install using pip install .
locally. The package name is listed in pip freeze
but import <package>
results in an error No module named <package>
. Also the site-packages folder does only contain a dist-info folder. find_packages()
is able to find packages. What am I missing?
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'
],
)
推薦答案
由于這個問題已經變得非常流行,這里是安裝后丟失文件時的診斷步驟.想象有一個具有以下結構的示例項目:
Since the question has become quite popular, here are the diagnosis steps to go through when you're missing files after installation. Imagine having an example project with the following structure:
root
├── spam
│ ├── __init__.py
│ ├── data.txt
│ ├── eggs.py
│ └── fizz
│ ├── __init__.py
│ └── buzz.py
├── bacon.py
└── setup.py
現在我運行 pip install .
,檢查包是否已安裝:
Now I run pip install .
, check that the package is installed:
$ 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
在屬于已安裝包的文件列表中:
but see neither spam
, nor spam/eggs.py
nor bacon.py
nor spam/fizz/buzz.py
in the list of files belonging to the installed package:
$ 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 文件并從中安裝您的包.如果在詳細模式下重新安裝,我們可以檢查輪子構建過程的日志.第一步是卸載包:
Unless told not to do so, pip
will always try to build a wheel file and install your package from it. We can inspect the log for the wheel build process if reinstalling in the verbose mode. First step is to uninstall the package:
$ pip uninstall -y mypkg
...
然后再次安裝它,但現在有一個額外的參數:
then install it again, but now with an additional argument:
$ 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
安裝.最常見的錯誤來源是:
I notice that no files from the spam
directory or bacon.py
are mentioned anywhere. This means they were simply not included in the wheel file and hence not installed by pip
. The most common error sources are:
驗證您已將 packages
參數傳遞給 setup 函數.檢查您是否提到了應該安裝的所有包.如果只提到父包,子包不會被自動收集!例如,在設置腳本中
Verify you have passed the packages
argument to the setup function. Check that you have mentioned all of the packages that should be installed. Subpackages will not be collected automatically if only the parent package is mentioned! For example, in the setup script
from setuptools import setup
setup(
name='mypkg',
version='0.1',
packages=['spam']
)
spam
將被安裝,而不是 spam.fizz
因為它本身就是一個包,必須明確提及.修復它:
spam
will be installed, but not spam.fizz
because it is a package itself and must be mentioned explicitly. Fixing it:
from setuptools import setup
setup(
name='mypkg',
version='0.1',
packages=['spam', 'spam.fizz']
)
如果您有很多包,請使用 setuptools.find_packages
自動執行該過程:
If you have lots of packages, use setuptools.find_packages
to automate the process:
from setuptools import find_packages, setup
setup(
name='mypkg',
version='0.1',
packages=find_packages() # will return a list ['spam', 'spam.fizz']
)
如果您缺少模塊:
在上面的例子中,我會在安裝后丟失 bacon.py
,因為它不屬于任何包.我必須在單獨的參數 py_modules
中提供其模塊名稱:
In the above examples, I will be missing bacon.py
after installation since it doesn't belong to any package. I have to provide its module name in the separate argument 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
參數添加位于包目錄下的數據文件.修復上述設置腳本:
Missing data files: check the package_data
argument
I have all the source code files in place now, but the data.txt
file is still not installed. Data files located under package directories should be added via the package_data
argument. Fixing the above setup script:
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
.
Don't be tempted to use the data_files
argument. Place the data files under a package and configure package_data
instead.
如果我現在重新安裝軟件包,我會注意到所有文件都添加到了輪子中:
If I now reinstall the package, I will notice all of the files are added to the wheel:
$ 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
的文件列表中可見:
They will also be visible in the list of files belonging to 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
這篇關于點安裝.僅創建 dist-info 而不是包的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!