这个问题是校长的结果 需求说明的解决方案:
python django pip update problems: how to get compatible versions?
我尝试在服务器之间同步python需求 和当地的发展系统。两者都是Ubuntu 16.04。, 所以这应该是一个问题。 服务器给我一个需求文件(在pip-installation django之后,如另一个quwtion中所述)。
但是在本地计算机上安装需求会产生一些错误, 像这样:
Could not find a version that satisfies the requirement python-
apt==1.1.0b1 (from -r requirements.txt (line 3)) (from versions: 0.0.0,
0.7.8) No matching distribution found for python-apt==1.1.0b1 (from -r
requirements.txt
有没有办法确保在类似系统上满足要求 没有因版本不兼容而导致的错误 (或者因为改变性地解决了不相容问题)?
我需要虚拟环境来解决这个问题吗? 甚至是pipenv? 或者有一个简单直接的方法来拥有两个系统 兼容的python和包环境?
答案 0 :(得分:3)
此特定模块(python-apt
)是only available on PyPi with version 0.7.8
。但是,此版本似乎是一个错误!
python-apt
has stated the following的开发人员和Debian软件包维护者之一:
Aargh,不再是整个PyPI。从未有人正式 在这里上传了
python-apt
。它与APT紧密结合,并且 除通过发行外,不应以任何其他方式发行 Debian软件包。没有,而且从来没有对PyPi的支持。我可以 说我绝对不愿意在那里重复工作。 Source: Debian "Deity" Mailing List 2016-11-22 msg#00094
您可以从apt安装
python-apt
,我们没有在python-apt
上提供pip
。最近,我控制了pypi条目,需要对其进行处理。尽管(python-apt
和apt版本xy需要匹配),但我不愿意在发行版之外提供python-apt
,所以我宁愿放弃它,所以人们会停下来询问过时的版本。 Source: python-apt#1883451
因此,至少对于这种依赖关系,当通过pip
+ PyPi原生解决python依赖关系时,我们似乎不走运。幸运的是,上游项目托管在salsa.debian.org
GitLab实例上,并且pip
现在支持git+
个SCM url,以及其他选项。
通常,有许多解决此依赖性的解决方案。您要解决的问题是:
>= 2.0.0
2.x
/ Semantic Versioning pip-module-name
+ version constraint
的“抽象”依赖
pip
的参数,使用特定的virtualenv
进行安装等来覆盖这些内容。sha1 / sha256 / sha**
,以确保确切的位置和文件的完整性。pip
setup.py
样式解析通过install_requires = [...]
安装依赖项? (图书馆)pip install -r requirements.txt
安装依赖项? (应用程序)setup.py
指定PyPi的库依赖项requirements.txt
指定应用程序的依赖项.deb
,.rpm
,.apk
等)
因此,大多数情况下,我们可以看到所有与 所需特异性 有关的问题,这些问题在哪里以及如何解决和安装这些依赖项。这里没有“一刀切”的解决方案...有优缺点,只有许多不同的解决方案可以满足以下需求:
more specific <---------------------> less specific
reliable compatibility reliable installability
less testing permutations more (possibly un-vetted) testing permutations
limited platform support more platform support (when more permutations are well tested)
dependable known configurations less dependable known configurations
less platform tolerant more tolerant and agnostic of platforms
more OS native less OS native
解决python-apt
软件包问题的一种方法是使用git+
中的requirements.txt
URL功能。这对于使用GitLab的python-apt
上游版本进行开发非常有用。为了进一步将安装与系统OS提供的python-apt
版本隔离开,可能需要virtualenv
或pip install --user
。例如:
requirements.txt
:
--index-url https://pypi.python.org/simple/
-e git+https://salsa.debian.org/apt-team/python-apt.git#egg=python-apt
-e .
此示例项目可用于包含setup.py
的示例项目:
[...SNIP...] # Boilerplate stuff here
setup(
#[...SNIP...] # Other setup() args here
platforms=['linux'],
# Reference:
# - https://github.com/pypa/interoperability-peps/pull/30/files#r184839487
# sudo apt install python3-apt apt-rdepends apt
# os_requires=[
# ['python3-apt', type='packagename', target='run', os='ubuntu'],
# ['apt-rdepends', type='packagename', target='run', os='ubuntu'],
# ['apt', type='packagename', target='run', os='ubuntu']
# ['libapt-pkg-dev', type='packagename', target='build', os='ubuntu']
# ]
# Build-deps for apt-python via git SCM: sudo apt install libapt-pkg-dev
python_requires='>=3.5',
install_requires=[
'python-apt (>= 2.0)',
# rest of your dependencies here
#[... SNIP ...]
],
package_dir={'': 'lib'},
scripts=_glob('bin/*'),
#[...SNIP...]
)
注意:os_requires
isn't actually supported yet, but is proposed for a PEP
。将来这可能会有助于软件包的外部依赖关系。在不通过PyPi / pip
分发python模块,而是仅通过OS上的apt
/ .deb
软件包提供python模块的情况下,这将很有帮助。
设置virtualenv
或根据需要使用pip3 install --user
,然后继续。
运行git+
时,使用pip3 install -r requirements.txt
需求功能会导致以下结果:
$ pip3 install -r requirements.txt
Looking in indexes: https://pypi.python.org/simple/
Obtaining file:///../example-project (from -r requirements.txt (line 4))
Obtaining python-apt from git+https://salsa.debian.org/apt-team/python-apt.git#egg=python-apt (from -r requirements.txt (line 3))
Updating ./example-project-venv/src/python-apt clone
Running command git fetch -q --tags
Running command git reset --hard -q c97d4159beae2f9cd42d55d3dff9c37f5c69aa44
ERROR: example-project 0.0.1 has requirement python-apt>=2.0, but you'll have python-apt 0.0.0 which is incompatible.
Installing collected packages: python-apt, example-project
Running setup.py develop for python-apt
Running setup.py develop for example-project
Successfully installed example-project python-apt
注意:您可能想先为setup.py
安装运行时和build / python-apt
依赖项:
# Runtime deps (e.g.: Ubuntu 20.04 needs python3-apt, <20.04 needs python-apt):
sudo apt install python3-apt apt
# python-apt pip install deps (also for setup.py / development)
sudo apt install libapt-pkg-dev
dependency_links
(注意:可能已弃用)如果您正在开发库类型模块,并且还希望使用GitLab作为python-apt
的源代码,则可能需要考虑将setup.py
中的using dependency_links
在git+
中提供http(s)
或requirements.txt
的tarball发布URL。这有助于将“应用程序” python项目与“库” Python模块项目区分开。这完全取决于项目的安装过程。 (例如:您要pip install -r requirements.txt
,还是pip install example-module
或python[3] setup.py {sdist,bdist,bdist_rpm, etc...}
。为分叉版本python-apt
指定自定义URL也可能会有所帮助。 ,此方法 可能很快就会被弃用 (如果在pip
的新版本中尚未部分淘汰),您可能希望考虑其他选择,以便将来-证明您的依赖性规范,例如PEP 508或pip install --find-links ...
。
此外,"application" vs "library" distinction以及“抽象”与“具体”依赖项的概念也很重要。快速摘要可能是:
抽象和具体之间的这种区别是重要的。它是 是什么使PyPI镜像基础架构能够正常工作。是什么 允许公司托管自己的私有软件包索引。甚至 是什么使您能够派生一个库来修复错误或添加功能,以及 用你自己的叉子。因为抽象依赖关系是名称和 可选的版本说明符,您可以从PyPI或从 Crate.io,或从您自己的文件系统。您可以派生一个库,更改 代码,只要它具有正确的名称和版本说明符 该库将愉快地继续使用它。
Setuptools具有类似于Go示例的功能。叫做 依赖关系链接,看起来像这样:
setup( # ... dependency_links = [ "http://packages.example.com/snapshots/", "http://example2.com/p/bar-1.0.tar.gz", ], ) ``` This “feature” of setuptools removes the abstractness of its dependencies and hardcodes an exact url from which you can fetch the dependency from. Now very similarly to Go if we want to modify packages, or simply fetch them from a different server we’ll need to go in and edit each package in the dependency chain in order to update the dependency_links.
对于此python-apt
示例,我们可以使用类似的方法来锁定v2.0.0
上的“具体依赖项”:
setup(
# [...SNIP...]
dependency_links = [
"https://salsa.debian.org/apt-team/python-apt/-/archive/2.0.0/python-apt-2.0.0.tar.gz#egg=python-apt"
],
# [...SNIP...]
) `
注意:此“错误功能”为briefly removed,然后在指定私有软件包依赖项URL时为brought back赋予了some usefulness。但是,目前pip --process-dependency-links
标志已被弃用,因此其作用可能仅限于Python 2 + pip
的旧版本。
Newer versions of pip
now have URL support for PEP 508 syntax。这可能是使用复杂语法指定具体和抽象依赖关系的最可靠的方法(有关详细信息,请参见PEP 508)。现在可以通过多种方式指定软件包,包括自定义URL。
例如,使用可选的python-apt
校验和将v2.0.0
锁定到sha256
:
setup(
# [...SNIP...]
install_requires=[
'python-apt@https://salsa.debian.org/apt-team/python-apt/-/archive/2.0.0/python-apt-2.0.0.tar.gz#sha256=1ddbd3eb7cbc1ded7e0e8a2dd75219f0c59c7e062c6e6bfd5c8ff6f656c59a4e',
# [...SNIP...]
],
# [...SNIP...]
)
requirements.txt
:
--index-url https://pypi.python.org/simple/
-e .
然后,pip install -r requirements.txt
仍然可以正常运行,没有任何额外的标志:
$ ./example-project-venv/bin/python3 ./example-project-venv/bin/pip3 install -r requirements.txt
Looking in indexes: https://pypi.python.org/simple/
Obtaining file://./src/pub/example-project (from -r requirements.txt (line 4))
Requirement already satisfied: graph-tools>=1.5 in ./example-project-venv/lib/python3.8/site-packages (from example-project==0.0.1->-r requirements.txt (line 4)) (1.5)
Collecting python-apt@ https://salsa.debian.org/apt-team/python-apt/-/archive/2.0.0/python-apt-2.0.0.tar.gz#sha256=1ddbd3eb7cbc1ded7e0e8a2dd75219f0c59c7e062c6e6bfd5c8ff6f656c59a4e
Using cached https://salsa.debian.org/apt-team/python-apt/-/archive/2.0.0/python-apt-2.0.0.tar.gz (458 kB)
Building wheels for collected packages: python-apt
Building wheel for python-apt (setup.py) ... done
Created wheel for python-apt: filename=python_apt-0.0.0-cp38-cp38-linux_x86_64.whl size=2040980 sha256=79eeb0d1bb9e3c9785acb68f164a3f72a5777539137d180e9ded7558d2547a49
Stored in directory: ~/.cache/pip/wheels/c4/09/b5/36fc8c9a1ebe8786620db922f1495da200dce187ee7c618993
Successfully built python-apt
Installing collected packages: python-apt, example-project
Attempting uninstall: example-project
Found existing installation: example-project 0.0.1
Uninstalling example-project-0.0.1:
Successfully uninstalled example-project-0.0.1
Running setup.py develop for example-project
Successfully installed example-project python-apt-0.0.0
pip install --find-links ...
安装锁定到特定版本的“具体依赖项”的另一种替代方法是使用已发布的tarball文件将--find-links
传递到pip install
。在给定发布URL的情况下,此方法可能有助于显式安装特定版本。例如,使用python-apt
v2.0.0
:
$ ./example-project-venv/bin/python3 ./example-project-venv/bin/pip3 install --find-links 'https://salsa.debian.org/apt-team/python-apt/-/archive/2.0.0/python-apt-2.0.0.tar.gz' -r requirements.txt
Looking in indexes: https://pypi.python.org/simple/
Looking in links: https://salsa.debian.org/apt-team/python-apt/-/archive/2.0.0/python-apt-2.0.0.tar.gz
Obtaining file://./example-project (from -r requirements.txt (line 4))
Requirement already satisfied: graph-tools>=1.5 in ./example-project-venv/lib/python3.8/site-packages (from example-project==0.0.1->-r requirements.txt (line 4)) (1.5)
Collecting python-apt>=2.0
Downloading https://salsa.debian.org/apt-team/python-apt/-/archive/2.0.0/python-apt-2.0.0.tar.gz (458 kB)
|████████████████████████████████| 458 kB 614 kB/s
WARNING: Requested python-apt>=2.0 from https://salsa.debian.org/apt-team/python-apt/-/archive/2.0.0/python-apt-2.0.0.tar.gz (from example-project==0.0.1->-r requirements.txt (line 4)), but installing version 0.0.0
Building wheels for collected packages: python-apt
Building wheel for python-apt (setup.py) ... done
Created wheel for python-apt: filename=python_apt-0.0.0-cp38-cp38-linux_x86_64.whl size=2040783 sha256=d0a8f88c04f202e948b9855837140517d9b2bd3cef72e626221614552a476780
Stored in directory: ~/.cache/pip/wheels/8a/07/e9/b3c3328bac08c030a5b1e754e01e327b62fd26f9baedf07c15
Successfully built python-apt
ERROR: example-project 0.0.1 has requirement python-apt>=2.0, but you'll have python-apt 0.0.0 which is incompatible.
Installing collected packages: python-apt, example-project
Attempting uninstall: python-apt
Found existing installation: python-apt 0.0.0
Uninstalling python-apt-0.0.0:
Successfully uninstalled python-apt-0.0.0
Attempting uninstall: example-project
Found existing installation: example-project 0.0.1
Uninstalling example-project-0.0.1:
Successfully uninstalled example-project-0.0.1
Running setup.py develop for example-project
Successfully installed example-project python-apt-0.0.0
在Debian和Ubuntu上,您会在不同的发行版本上看到两个.deb
软件包:python3-apt
和python-apt
(对于Python2)。
These packages are managed由APT软件包管理器安装,因此安装在系统位置:/usr/lib/python3/dist-packages
或/usr/lib/python2.7/dist-packages
分别用于Python3和Python2.7。
此dist-packages
路径和其他Python打包约定为explained well in this post:
系统已将Python软件包安装在每个Python版本的全局
dist-packages
目录中,并创建了符号链接:/usr/lib/python2.7/dist-packages/numpy /usr/lib/python3/dist-packages/numpy ls -ls /usr/include/numpy #-> ../lib/python2.7/dist-packages/numpy/core/include/numpy ls -l /usr/include/python2.7/numpy #->../../lib/python2.7/dist-packages/numpy/core/include/numpy ls -l /usr/include/python3.5/numpy #-> ../../lib/python3/dist-packages/numpy/core/include/numpy
请注意
dist-packages
而不是site-packages
的良好用法,应将其保留给系统Python。
因此,如果您要使用python3-apt
的基本OS系统级别版本,则需要确保此路径位于sys.path
或PYTHONPATH
上因此import apt
将起作用。而如果您想使用site-packages
位置或virtualenv
位置,则这些位置必须存在于sys.path / PYTHONPATH
上。
不幸的是,as mentioned before还没有一种正式的方法来声明对提供特定版本python模块的OS软件包的依赖。但是,只要您管理python
运行时环境的import
路径,就应该能够使用dist-packages
目录中的OS软件包中的正确版本。
答案 1 :(得分:0)
事实上,python-apt
的最新版本是0.7.8 https://pypi.org/project/python-apt/
如果您100%确定它是相同的包,请尝试在requirements.txt文件中更改它。
另一方面,您可以尝试查看本地python-apt
的位置。
import apt
print(apt.__file__) # or print(apt.__path__)
然后,去那里手动检查那个python-apt
包是什么。