是否可以使用pip一次性升级所有Python包?
注意:官方问题跟踪器上对此有一个功能请求。
是否可以使用pip一次性升级所有Python包?
注意:官方问题跟踪器上对此有一个功能请求。
当前回答
以下Windows cmd代码段执行以下操作:
将pip升级到最新版本。升级所有过时的软件包。对于正在升级的每个包,检查requirements.txt中的任何版本说明符。
@echo off
Setlocal EnableDelayedExpansion
rem https://stackoverflow.com/questions/2720014/
echo Upgrading pip...
python -m pip install --upgrade pip
echo.
echo Upgrading packages...
set upgrade_count=0
pip list --outdated > pip-upgrade-outdated.txt
for /F "skip=2 tokens=1,3 delims= " %%i in (pip-upgrade-outdated.txt) do (
echo ^>%%i
set package=%%i
set latest=%%j
set requirements=!package!
rem for each outdated package check for any version requirements:
set dotest=1
for /F %%r in (.\python\requirements.txt) do (
if !dotest!==1 (
call :substr "%%r" !package! _substr
rem check if a given line refers to a package we are about to upgrade:
if "%%r" NEQ !_substr! (
rem check if the line contains more than just a package name:
if "%%r" NEQ "!package!" (
rem set requirements to the contents of the line:
echo requirements: %%r, latest: !latest!
set requirements=%%r
)
rem stop testing after the first instance found,
rem prevents from mistakenly matching "py" with "pylint", "numpy" etc.
rem requirements.txt must be structured with shorter names going first
set dotest=0
)
)
)
rem pip install !requirements!
pip install --upgrade !requirements!
set /a "upgrade_count+=1"
echo.
)
if !upgrade_count!==0 (
echo All packages are up to date.
) else (
type pip-upgrade-outdated.txt
)
if "%1" neq "-silent" (
echo.
set /p temp="> Press Enter to exit..."
)
exit /b
:substr
rem string substition done in a separate subroutine -
rem allows expand both variables in the substring syntax.
rem replaces str_search with an empty string.
rem returns the result in the 3rd parameter, passed by reference from the caller.
set str_source=%1
set str_search=%2
set str_result=!str_source:%str_search%=!
set "%~3=!str_result!"
rem echo !str_source!, !str_search!, !str_result!
exit /b
其他回答
如果你在macOS上,
确保已安装Homebrew安装jq以读取您将要生成的JSON
brew install jq
更新pip3列表生成的过时包列表中的每个项目--过时
pip3 install --upgrade `pip3 list --outdated --format json | jq '.[] | .name' | awk -F'"' '{print $2}'`
您可以使用以下Python代码。与pip冻结不同,这不会打印警告和FIXME错误。对于管道<10.0.1
import pip
from subprocess import call
packages = [dist.project_name for dist in pip.get_installed_distributions()]
call("pip install --upgrade " + ' '.join(packages), shell=True)
对于pip>=10.0.1
import pkg_resources
from subprocess import call
packages = [dist.project_name for dist in pkg_resources.working_set]
call("pip install --upgrade " + ' '.join(packages), shell=True)
从…起https://github.com/cakebread/yolk:
$ pip install -U `yolk -U | awk '{print $1}' | uniq`
然而,你需要先得到蛋黄:
$ sudo pip install -U yolk
更稳健的解决方案
对于pip3,请使用以下命令:
pip3 freeze --local |sed -rn 's/^([^=# \t\\][^ \t=]*)=.*/echo; echo Processing \1 ...; pip3 install -U \1/p' |sh
对于pip,只需删除3s即可:
pip freeze --local |sed -rn 's/^([^=# \t\\][^ \t=]*)=.*/echo; echo Processing \1 ...; pip install -U \1/p' |sh
OS X奇数
截至2017年7月,OS X附带了一个非常旧的sed版本(已有十几年历史)。要获得扩展正则表达式,请在上面的解决方案中使用-E而不是-r。
使用流行解决方案解决问题
这个解决方案经过了精心设计和测试1,而即使是最流行的解决方案也存在问题。
由于pip命令行特性的变化而导致的可移植性问题由于常见的pip或pip3子进程故障导致xargs崩溃来自原始xargs输出的拥挤日志记录依赖Python到OS桥,同时可能升级它3
上面的命令使用最简单和最可移植的pip语法,并结合sed和sh来完全解决这些问题。sed操作的详细信息可以使用注释的版本2进行详细检查。
细节
[1] 在Linux 4.8.16-200.fc24.x86_64集群中测试并定期使用,并在其他五种Linux/Unix版本上测试。它还可以在Windows 10上安装的Cygwin64上运行。需要在iOS上进行测试。
[2] 为了更清楚地看到命令的解剖结构,这与上面的pip3命令完全等价,并带有注释:
# Match lines from pip's local package list output
# that meet the following three criteria and pass the
# package name to the replacement string in group 1.
# (a) Do not start with invalid characters
# (b) Follow the rule of no white space in the package names
# (c) Immediately follow the package name with an equal sign
sed="s/^([^=# \t\\][^ \t=]*)=.*"
# Separate the output of package upgrades with a blank line
sed="$sed/echo"
# Indicate what package is being processed
sed="$sed; echo Processing \1 ..."
# Perform the upgrade using just the valid package name
sed="$sed; pip3 install -U \1"
# Output the commands
sed="$sed/p"
# Stream edit the list as above
# and pass the commands to a shell
pip3 freeze --local | sed -rn "$sed" | sh
[3] 升级也用于升级Python或PIP组件的Python或PIP组件可能会导致死锁或包数据库损坏。
通过拉取请求发送给pip人员;同时使用我写的这个pip库解决方案:
from pip import get_installed_distributions
from pip.commands import install
install_cmd = install.InstallCommand()
options, args = install_cmd.parse_args([package.project_name
for package in
get_installed_distributions()])
options.upgrade = True
install_cmd.run(options, args) # Chuck this in a try/except and print as wanted