Pip: Adicionar os comandos "upgrade" e "upgrade-all"

Criado em 15 mar. 2011  ·  251Comentários  ·  Fonte: pypa/pip

(Atualizado para refletir a realidade em abril de 2020)

Este problema foi inicialmente definido para alterar o comportamento de pip install --upgrade , adicionando um novo comando upgrade com um comportamento diferente ao atualizar pacotes. O padrão recursivo "ansioso" mais antigo causou pesar para muitos (# 304) No entanto, após muita discussão sobre isso, a abordagem adotada foi adicionar o sinalizador --upgrade-strategy . A bandeira inicialmente tinha um padrão de "ansioso", que foi alterado para um padrão melhor em # 4500.

O problema de rastreamento para a funcionalidade "atualizar todos os pacotes" é # 4551.

upgrade auto-locked enhancement

Comentários muito úteis

Você vai implementar isso nos próximos 10 anos?

Todos 251 comentários

"upgrade" é um apelido trivial para "install --upgrade". Precisa pensar um pouco mais
sobre "atualizar tudo"; por um lado, presumo que apenas atualizaria pacotes
dentro de sys.prefix? (ou seja, se você estiver dentro de um virtualenv, ele não tentaria
atualizar pacotes globais). Isso seria um motivo para mudar
UninstallPathSet.can_uninstall () para uma função com nome mais genérico (ou
método de InstallRequirement), de modo que fornece "posso tocar nisto?" genérico.
decisões.


Original Comment By: Carl Meyer

Só para constar, acho que parece uma boa ideia, dada a capacidade de
desinstale antes de atualizar. Embora eu prefira uma opção --all para
upgrade vez de um próprio comando upgrade-all .

Por questão de can_uninstall (), eu concordo .. isso provavelmente é útil ter
globalmente de qualquer maneira.


Original Comment By: Jannis Leidel

Eu não sou totalmente contrário a atualizar como um alias para instalar --upgrade. Mas
parece um pouco trivial.

upgrade-all requer que você descubra o que é "atualizável". Provavelmente um
pré-requisito é que ele viva em/lib/pythonX.Y/site-packages
(simplesmente em sys.prefix não é suficiente).

Se permitirmos algo como "importação zip" (para trazer um pacote do pai
ambiente em um ambiente virtualenv), então provavelmente os pacotes nesse
ambiente pai não deve ser atualizado, mas não está 100% claro que é o que
o usuário espera.

Tentei desinstalar um pacote editável com "pip uninstall" e
razoavelmente oferecido para remover o .egg-link e atualizar o easy-install.pth. Mas isso
não poderia ter atualizado razoavelmente o pacote, então can_uninstall é um pouco
diferente de can_upgrade.


Original Comment By: Ian Bicking

Sim, você está certo que can_uninstall e can_upgrade são diferentes.

Eu pensaria que se tivéssemos "pip import" ainda não quereríamos atualizar
pacotes globais importados; mas (junto com os editáveis) pode valer a pena "não
atualizando este "aviso para o console.


Original Comment By: Carl Meyer

1 para este bug


Original Comment By: smyrman

O problema nº 167 foi marcado como uma duplicata deste problema.


Original Comment By: Carl Meyer

1

(echo pip; pip freeze | awk 'BEGIN{FS="=="}{print $1}') | xargs sudo pip

instalar -U

Isso deve atualizar todos os pacotes instalados (incluindo o próprio pip). Se
você o executa no virtualenv, provavelmente não precisa usar o sudo.

Claro que há alto risco de falha - se atualizar um dos pacotes
falhar, todo o processo irá falhar (é semelhante a port upgrade outdated em
MacPorts).


Original Comment By: Tomasz Elendt

+1 para atualização --todos

Por que no momento todos os recursos de gerenciamento de módulo Python têm que ser uma merda? Porque nao
um fornece o comando simples upgrade + upgrade --all?


Original Comment By: Anonymous

Eu não me importaria de tentar uma implementação, mas primeiro algumas perguntas.

É consenso geral que um novo comando "upgrade" que suporte um '--all'
opção ser adicionada ao pip?

Executar a atualização do pip deve afetar apenas o ambiente em que está sendo executado.
execute a partir de um virtualenv então apenas os pacotes locais para esse env serão atualizados;
o mesmo para não virtuais


Original Comment By: Kelsey Hightower

Kelsey: da minha leitura da discussão acima, não vejo nenhum real
oposição a ele. Acho que é um ótimo complemento de se fazer. O caso principal é
instalações VCS editáveis ​​- como sugeriu Ian, acho que um comando de "atualização"
não deve tocar neles. Definir o que "upgrade" significa no contexto de todos os
possibilidades editáveis ​​(incluindo repositórios locais editáveis ​​instalados que não têm
origem) seria quase impossível, eu acho, e mesmo se algum meio de trabalho
definição poderia ser colocada junto, isso só aumentaria a manutenção
carga dos já frágeis back-ends do VCS. Mas para não editáveis ​​- vá para
isto!


Original Comment By: Carl Meyer

Carl: Legal, vou começar e atualizar este tíquete com os resultados.


Original Comment By: Kelsey Hightower

Enquanto trabalhava no comando de atualização, surgiram as seguintes questões:

  • Quais métodos o pip upgrade deve suportar para especificar quais pacotes devem ser
    melhoria? Devemos oferecer suporte a um arquivo de requisitos?
  • Como o pip upgrade deve lidar com os pacotes que ainda não estão instalados?
    Devemos instalar pacotes ausentes?
casos de uso de atualização pip e como lidar com eles:
# pip upgrade some_installed_package

Try and locate a package that satisfies the requirement. If the

requisito não for satisfeito, atualize para a versão solicitada. Isso inclui
atualizando para uma versão mais antiga.

# pip upgrade --all

Locate all installed packages (non-editables) and update them to a new

versão, se disponível.

# pip upgrade some_other_package

Warning: some_other_package not installed, use pip install

algum_outro_pacote.

Meus objetivos são manter o comando de atualização realmente simples. Você pode atualizar
pacotes não editáveis ​​específicos para uma versão nova ou mais antiga; ou você pode atualizar
todos os pacotes não editáveis ​​para uma versão mais recente.

Pensamentos?


Original Comment By: Kelsey Hightower

Eu acho que "pip upgrade" deve ser um apelido exato para "pip install --upgrade" como
funciona agora. Isso implica que sim, ele instala os pacotes solicitados se eles
não estão instalados e, sim, ele aceita arquivos de requisitos com -r. Seu deveria
ser factível com quase nenhum código novo.

Atualizar - tudo exigirá algum código para encontrar a lista de
pacotes atualizáveis ​​instalados; então deve apenas passar essa lista para instalar
--atualizar, como acima.


Original Comment By: Carl Meyer

Carl, obrigado pela resposta. Eu praticamente tomei o caminho que você tem
descrito. Mais tarde hoje, devo poder postar alguns exemplos de execução.


Original Comment By: Kelsey Hightower

Concluí a maior parte do código, restava apenas um pouco de polimento antes de postá-lo
para revisão.

FAÇAM:

  • Testes
  • Arquivo de requisitos de filtro; adicionar não editáveis ​​à lista de pacotes para
    melhoria.
Executando pip usando o comando de atualização
# pip upgrade --all

All packages up-to-date


# pip upgrade --all -v

Packages installed at latest version:

  pip: 0.8.2 (latest)

  distribute: 0.6.14 (latest)

  Python: 2.7.1 (latest)

  wsgiref: 0.1.2 (latest)

All packages up-to-date


# pip upgrade PyYAML

Package updates available:

  PyYAML: N/A (installed) 3.09 (latest)

Downloading/unpacking PyYAML

  Downloading PyYAML-3.09.tar.gz (238Kb): 238Kb downloaded

....

Successfully installed PyYAML

Cleaning up...


# pip upgrade --all -v

Packages installed at latest version:

  pip: 0.8.2 (latest)

  distribute: 0.6.14 (latest)

  PyYAML: 3.09 (latest)

  Python: 2.7.1 (latest)

  wsgiref: 0.1.2 (latest)

All packages up-to-date


# pip upgrade PyYAML==3.08

Downloading/unpacking PyYAML==3.08

....

Successfully installed PyYAML

Cleaning up...


# pip upgrade --all -v

Packages installed at latest version:

  pip: 0.8.2 (latest)

  distribute: 0.6.14 (latest)

  Python: 2.7.1 (latest)

  wsgiref: 0.1.2 (latest)

Package updates available:

  PyYAML: 3.08 (installed) 3.09 (latest)

Downloading/unpacking PyYAML

...

Successfully installed PyYAML

Cleaning up...

  Removing temporary dir /root/upgrade_env/build...

Original Comment By: Kelsey Hightower

Último conjunto de perguntas (espero):

  • O pip upgrade deve analisar o arquivo de requisitos e filtrar
    editáveis? E quanto aos requisitos de URL?

Para cada item não editável no arquivo de requisitos, gostaria de verificar o
índices para uma versão posterior. Para fazer isso, eu precisaria reunir o
informações do pacote de cada linha no arquivo de requisitos.

Todas as dicas são bem-vindas (atualmente olhando em pip.req.parse_requirements )

  • O pip upgrade deve pesquisar os índices para uma versão posterior para instalar?
    (Isso é o que estou fazendo agora). Se não, como o comando de atualização deve determinar
    se houver uma atualização?

No momento, estou apenas adicionando pacotes à lista de atualização quando:

  • O pacote não está instalado
  • Uma atualização está disponível (versão posterior dos índices), e nenhum
    versão foi solicitada
  • A versão solicitada é diferente da instalada (falta de versão
    Combine).
  • Estou adiando o arquivo de requisitos para o comando de instalação até que eu filtre
    os requisitos não editáveis.

Original Comment By: Kelsey Hightower

Carl, depois de reler sua postagem, parece que estou fazendo mais do que
requeridos. Vou carregar meu branch para que você possa dar uma olhada. Posso ter ido
ao mar verificando PyPi para uma versão posterior.


Original Comment By: Kelsey Hightower

Carl, depois de reler sua postagem, parece que estou fazendo mais do que
requeridos. Vou carregar meu branch para que você possa dar uma olhada. Posso ter ido
ao mar verificando PyPi para uma versão posterior.


Original Comment By: Kelsey Hightower

Sim, parece que você está fazendo mais do que o necessário. Pip install
--upgrade faz tudo o que você já está discutindo (verificando se há novos
versões, etc); toda a "atualização pip" deve ser como uma passagem de duas linhas
tudo para pip install --upgrade.

O único código real a ser escrito aqui é o código para "atualizar - todos" para obter
a lista completa de pacotes atualizáveis ​​instalados no ambiente.


Original Comment By: Carl Meyer

Sim, eu sabia. Bem, eu aprendi muito. Mesmo que não seja necessário para isso
tarefa, gosto da capacidade de mostrar o que está instalado e disponível durante o
processo de atualização (veja a execução de teste acima).

Vou refazer o fator e limpar as coisas. Mudanças atuais na minha bifurcação no
ramificação do comando de atualização.

https://bitbucket.org/khightower/pip/changeset/2bdc202b446c


Original Comment By: Kelsey Hightower

Eu eliminei o comando de atualização de acordo com as sugestões de Carl (eu fui para longe
em primeiro lugar). Não tenho certeza se gostei dos resultados, mas faz a instalação do espelho--atualizar em funcionalidade.

Parece que o pip tenta baixar e reinstalar o pacote mesmo quando o
pacote já está instalado e atualizado. Pior ainda com upgrade--all , o pip reinstala tudo, incluindo o próprio pip. É assim que pip
a atualização deve funcionar? Se sim, estou quase terminando :)

Executando o comando de atualização do pip
# pip upgrade Mako


Downloading/unpacking Mako

  Running setup.py egg_info for package Mako


    warning: no files found matching '*.jpg' under directory 'doc'

    warning: no files found matching '*.sty' under directory 'doc'

    warning: no files found matching 'autohandler' under directory 'doc'

    warning: no files found matching '*.xml' under directory 'examples'

    warning: no files found matching '*.mako' under directory 'examples'

    warning: no files found matching '*.dat' under directory 'test'

    warning: no files found matching 'ez_setup.py'

Downloading/unpacking MarkupSafe>=0.9.2 (from Mako)

  Running setup.py egg_info for package MarkupSafe


Installing collected packages: Mako, MarkupSafe

  Found existing installation: Mako 0.3.6

    Uninstalling Mako:

      Successfully uninstalled Mako

  Running setup.py install for Mako

    changing mode of build/scripts-2.7/mako-render from 644 to 755


    warning: no files found matching '*.jpg' under directory 'doc'

    warning: no files found matching '*.sty' under directory 'doc'

    warning: no files found matching 'autohandler' under directory 'doc'

    warning: no files found matching '*.xml' under directory 'examples'

    warning: no files found matching '*.mako' under directory 'examples'

    warning: no files found matching '*.dat' under directory 'test'

    warning: no files found matching 'ez_setup.py'

    changing mode of /root/upgrade_env/bin/mako-render to 755

  Found existing installation: MarkupSafe 0.11

    Uninstalling MarkupSafe:

      Successfully uninstalled MarkupSafe

  Running setup.py install for MarkupSafe


    building 'markupsafe._speedups' extension

    gcc -pthread -fno-strict-aliasing -g -O2 -DNDEBUG -g -fwrapv -O3 -Wall

-Wstrict-prototypes -fPIC -I / opt / OpenPython-2.7.1 / include / python2.7 -c
markupsafe / _speedups.c -o build / temp.linux-x86_64-2.7 / markupsafe / _speedups.o

    gcc -pthread -shared

build / temp.linux-x86_64-2.7 / markupsafe / _speedups.o -o
build / lib.linux-x86_64-2.7 / markupsafe / _speedups.so

Successfully installed Mako MarkupSafe

Cleaning up...

Original Comment By: Kelsey Hightower

Kelsey - Sim, existem alguns bugs com install --upgrade; em particular você
identificou # 13 , que baixa e reinstala até mesmo pacotes que
já estão atualizados. A solução não é fazer algo diferente
com o novo comando de atualização, é para consertar o bug em install --upgrade.

Com upgrade --all, parece razoável para mim que o pip se atualize
também, se houver uma atualização disponível. (Pessoalmente, nunca vou usar o upgrade
--todos, então eu não sei que comportamento as pessoas que usarão isso gostariam de ver com ele
aqui). Obviamente, seria melhor se comportarmos se # 13 fosse corrigido.


Original Comment By: Carl Meyer

Obrigado Carl, vou encerrar isso e começar a olhar para o # 13


Original Comment By: Kelsey Hightower

Se alguém tiver tempo, reveja meu branch de comando de atualização. Enquanto isso
Vou trabalhar em testes de unidade que tentam não duplicar os existentes para o
comando de instalação.

https://bitbucket.org/khightower/pip/src/fa7b2a6d2bf1/pip/commands/upgrade.py


Original Comment By: Kelsey Hightower

@vababiy : eu tentei seu comando de atualização, mas parece não funcionar corretamente ... Então eu fiz um:

https://github.com/pypa/pip/pull/313
https://github.com/jedie/pip/commit/7a31d70dabe0e809184fe1b5280c5a7ccf420dd5

@jedie, acho que você quis direcionar seu comentário para @khightower. @vbabiy migrou seu comentário para aqui, mas não escreveu o comando de atualização.

+1

@kelseyhightower Algum progresso?

+1

+1!

+1

+1

Por favor, pare de comentar sobre o problema com apenas um "+1". Estamos cientes de que o recurso é desejado, mas enviar spam para nossa caixa de entrada não ajuda.

Em vez disso, ficaria emocionado em ver um comentário "patch pronto!" ;)

+1

Alguma atualização? Existe algum plano para adicionar isso, já tem 3 anos ..

+1

Eu pensei que isso já estava mesclado. Posso tirar o pó da minha habilidade de python e tentar novamente.

Esse recurso será incluído no 1.5? Não consigo encontrar nenhuma referência a ele na documentação 1.5 ...

+1

Qual é a situação deste problema?

Está bloqueado por # 988

Se for realmente importante para você, existem soluções alternativas para atualizar todos os pacotes; Eu criei um script para fazer isso em paralelo (https://github.com/ariccio/update-pip-packages), e há muitas outras implementações em outros lugares na Internet.

Este problema tem duas partes. upgrade-all pode estar bloqueado por gh-988, mas não vejo como upgrade está bloqueado. pip upgrade pode ser um apelido simples para pip install -U --no-deps . Isso resolveria um dos principais problemas de usar install_requires em arquivos setup.py. Isso não pode ser feito em breve?

pip upgrade pode ser um apelido simples para pip install -U --no-deps

da descrição:

pip upgrade seria como pip install --upgrade exceto que não seria recursivo por padrão (e ofereceria uma opção --recursive ). Seu comportamento padrão recursivo atual causou pesar para muitos (# 304). Para saber como fazer atualizações não recursivas agora, veja aqui

isso não é pip install -U --no-deps

“Não recursivo” neste contexto não significa simplesmente –no-deps . Uma atualização não recursiva atualizará as dependências, mas apenas se necessário para atender aos requisitos principais.

@qwcode obrigado pelo esclarecimento. Então não é isso que me importa. Por que você chamaria isso de "não recursivo", ainda é recursivo, mas apenas um pouco mais inteligente / diferente?

Fiquei com a impressão, a partir da discussão em gh-571, que realmente não recursivo era o padrão desejado. Isso certamente faria sentido e evitaria a necessidade de sempre escrever códigos como https://github.com/scipy/scipy/commit/8e7ee0c4b3c16.

em # 571, "não recursivo" não é --no-deps é o recursivo "mais inteligente / diferente" como você diz.
observe o teste test_upgrade_with_needed_recursive_upgrades() daquele PR.

sem travar os termos, há 3 coisas:

  1. a "atualização mais inteligente / diferente", ou seja, o tipo que ocorre no pacote do sistema operacional que também pode implicar em atualizar as dependências (mas apenas se elas realmente _precisar_ de atualização).
  2. o que o pip faz agora, que é atualizar todas as dependências, independentemente da necessidade ou resolução de conflitos.
  3. --no-deps

algumas maneiras possíveis de distinguir # 1 e # 2

  1. "não recursivo" vs "recursivo"
  2. "normal" vs "recursivo"
  3. "apenas se necessário recursivo" vs "faça-o independentemente recursivo"

Estou aberto a usar os melhores termos ... mas não tenho certeza de quais são.

Acho que estou gostando dessa frase "recursiva apenas se necessário". talvez eu deva usar isso aqui na documentação:

Eu gosto disso também. Se você descrever as três opções juntas como

a. non-recursive
b. only if needed recursive
c. recursive (or "do it regardless recursive")

isso seria claro.

Então você deseja escolher bons padrões. Tanto para upgrade quanto install -U , (a) ou (b) podem fazer sentido. Eu prefiro fortemente (a), mas (b) também faz sentido, visto que é isso que o pacote do sistema operacional faz.

(c) não faz sentido como padrão, portanto, reconsidere sua decisão de não alterar install -U .

Para esclarecer por que eu prefiro fortemente (a): um usuário desavisado querendo (b) e recebendo (a) terá que ler uma mensagem dizendo "non-recursive upgrade can't satisfy all dependencies, please use only-if-needed recursive" , o que não é grande coisa. Se o padrão fosse (b), esse usuário desavisado pode acabar com uma atualização ou até mesmo com a falha na instalação de um pacote que ele realmente não queria tocar. Isso pode levar horas ou até dias para se recuperar.

(c) não faz sentido como padrão, portanto, reconsidere sua decisão de não alterar o install -U

a razão para deixar install -U sozinho é apenas por razões de compatibilidade e, posteriormente, para descontinuá-lo.

Se o padrão for (b), esse usuário desavisado pode acabar com uma atualização
ou mesmo uma instalação quebrada de um pacote que ele realmente não queria tocar

se um usuário deseja que as atualizações de dependência necessárias não sejam realizadas, ele deve solicitar especificamente por isso usando --no-deps . não há nenhuma maneira em minha mente que poderia ser o padrão. esse comportamento causaria mais danos do que o que você está considerando (que é o caso mais discrepante). Repetidamente, os usuários ficavam sem as atualizações de dependência de que precisavam.

Suspender install -U parece bom.

Eu concordo que (b) é mais comum do que (a). Mesmo que fosse 100 vezes mais comum, o que não é o caso, eu acho, mais danos não é verdade. Ler uma mensagem de erro clara antes de iniciar a instalação é muito melhor do que, por exemplo, um erro de compilação na metade, que imho (a) ainda é o melhor padrão.

Confiar em --no-deps pode ser bom para usuários muito experientes, mas os novos usuários só aprenderão sobre isso depois que algo der errado.

Enfim, parece que não vou conseguir te convencer. Então, de volta ao manual

try:
   import dependency
except ImportError:
    install_requires.append('dependency')
else:
    if dependency.version < 'x.y.z':
        raise ValueError('Please upgrade dependency to x.y.z')

isto é.

@qwcode obrigado pela explicação detalhada. Espero que isso avance em um futuro próximo - apenas se necessário, a recursiva seria uma grande melhoria em relação ao comportamento atual.

Passando novamente muitas horas esta semana discutindo por que não usamos install_requires , estou adicionando: +1: para nos afastarmos do comportamento atual.

Há alguma atualização sobre esse problema?

Temos agora 2015 e ainda preciso copiar de pip freeze --local | grep -v '^\-e' | cut -d = -f 1 | xargs -n1 pip install -U stackoverflow

Sim, essencialmente todo o progresso está relacionado a esse problema.

pip_upgrade_github

O GitHub faz um bom trabalho de referência cruzada de coisas. Todos esses são clicáveis! (Tenho certeza que você sabe disso?)

Sim, com certeza, mas não entendi porque esse recurso "simples" tem tanto atraso.

Qual é a razão para isto?

Am 16.04.2015 um 05:28 schrieb Alexander Riccio [email protected] :

Sim, essencialmente todo o progresso está relacionado a esse problema.

O GitHub faz um bom trabalho de referência cruzada de coisas. Todos esses são clicáveis! (Tenho certeza que você sabe disso?)

-
Responda a este e-mail diretamente ou visualize-o no GitHub.

quanto a pip upgrade-all , o consenso parece ser esperar pelo trabalho relacionado ao # 988 antes de lançar qualquer comando novo e brilhante que ainda apresenta falhas e pode ser perigoso para o ambiente de trabalho. Uma versão simples de upgrade-all que não resolve adequadamente os requisitos pode facilmente quebrar os pacotes existentes

+1

O que você está fazendo ao longo de 4 anos?

+1

+1

+1

@muhasturk Atualmente, esperando ... https://github.com/pypa/pip/issues/59#issuecomment -93646462

+1

+1

+1

+1

+1

+1

+1

+1

+1

+1

+1 ... desculpe pelo spam, mas executar pip freeze --local | grep -v '^\-e' | cut -d = -f 1 | xargs -n1 pip install -U dói!

+1

Caso alguém esteja interessado em trabalhar nisso, acho que os comentários acima são um tanto confusos - AFAICT o status real é que pip upgrade-all está atualmente bloqueado pela necessidade de um sistema de resolução de dependência adequado, mas pip upgrade pode ser implementado a qualquer momento. Se alguém quiser trabalhar nessa parte, seria extremamente incrível :-).

(Veja também o tópico que começa aqui e a resposta de @dstufft aqui e comente aqui concordando com a avaliação acima.)

aqui está outra discussão da lista pypa-dev de um ano atrás (que concorda que pip upgrade FOO pode ser feito agora) https://groups.google.com/forum/#!searchin/pypa -dev / pip $ 20 atualizar / pypa-dev / vVLmo1PevTg / oBkHCPBLb9YJ

Obrigado @qwcode! Também acabei de ver a nova descrição em https://pip.pypa.io/en/latest/user_guide/#only -if-needed-recursive-upgrade, que é útil.

+1

Se não estou errado:

Se xxx não estiver instalado:

  • pip upgrade xxx seria equivalente a pip install xxx
  • pip upgrade xxx --recursive seria o equivalente a pip install xxx --upgrade

Se xxx estiver instalado:

  • pip upgrade xxx --recursive ainda seria o equivalente a pip install xxx --upgrade (por design)
  • mas atualmente não há equivalente para pip upgrade xxx , isso poderia ser pip install xxx --upgrade-only-if-needed/--upgrade-lazy

Não está claro qual é o valor agregado de um novo comando sobre a adição de uma nova opção a pip install ?

Não está claro qual é o valor agregado de um novo comando sobre a adição de uma nova opção a pip install ?

O comportamento padrão de pip install -U é inaceitável para muitos projetos. Veja meu comentário acima (https://github.com/pypa/pip/issues/59#issuecomment-52434862). E aqui está uma explicação mais longa: http://article.gmane.org/gmane.comp.python.distutils.devel/24218

Se for inaceitável, então eu acho que você planeja mudar o uso de pip install --upgrade para pip upgrade?
Por que você não poderia, em vez disso, alterar o uso atual de instalação do pip - atualizar para instalação do pip - apenas de atualização necessária?
O que um novo comando oferece que uma nova opção não pode?

É tudo pavimentação de caminhos de vacas. Não é com o uso pessoal de

De fato. As pessoas não leem documentos. De fato, consertaremos todos os documentos de instalação que pudermos encontrar, mas assim que um usuário vir -U ou --upgrade é isso que ele usará. A chance de que as pessoas usem --no-deps ou --only-as-needed ou qualquer outra coisa antes de serem seriamente mordidas por ele é remota.

Por que você não poderia, em vez disso, alterar o uso atual de instalação do pip - atualizar para instalação do pip - apenas de atualização necessária?

E para ser claro: evitamos pip install --upgrade agora _e_ não use install_requires por causa disso. Isso é muito ruim.

Acho que há um pequeno mal-entendido aqui - IIUC @xavfernandez concorda em adicionar a funcionalidade de atualização não recursiva, a pergunta é por que a IU para essa funcionalidade tem que ser como um novo comando de nível superior em vez de uma nova opção para pip install .

@xavfernandez : Observe que atualmente há uma discussão acontecendo em # 3194 sobre qual seria a interface do usuário mais clara para esta funcionalidade.

(E pip install -U será descontinuado e removido, então isso responde à pergunta sobre como os usuários saberão que não deve usá-lo :-).)

Eu acho que há um pequeno mal-entendido aqui

Tenho certeza de que não existe. E sim, estamos apenas debatendo a interface do usuário. Mas isso é importante.

Sim, apenas debatendo a IU e concordo que é importante. Mas o que vejo é que, uma vez que a atualização do pip for lançada, não haverá razão para continuar usando a instalação do pip ...
E a IU para instalar qualquer pacote se tornará "pip upgrade foo"

não haverá razão para continuar usando pip install

qual é um problema por quê? O problema (pelo menos para @qwcode nos comentários acima) em alterar pip install --upgrade para o comportamento correto está quebrando a compatibilidade com versões anteriores. Portanto, pip upgrade é a maneira de evitar essa quebra _e_ obter o padrão correto.

@rgommers : para ser justo, nós _teremos_ um número diferente de zero de perguntas confusas sobre por que você me disse para executar pip upgrade foo quando eu nem mesmo tinha foo instalado, não não funciona (argumentar para frente e para trás até que eles realmente tentem executar o comando em vez de presumir que ele não funcionará e fingir que o executaram)

Em # 3194, fiz o comentário de que talvez o caminho certo a seguir seja apenas remover --upgrade de pip install , fazer pip install sempre fazer uma atualização dos itens explicitamente nomeados e padrão para uma estratégia de atualização mínima para dependências com um sinalizador --recursive para obter o comportamento atual na atualização.

Acho que concordo que, com o # 3194, o UX padrão se tornará pip upgrade foo vez de pip install [-U] foo . O único problema que tenho com isso é que acho meio confuso ter os dois comandos e, dado que acho que pip upgrade seria o "certo" para as pessoas usarem, acho que é péssimo ter o óbvio nome seja o nome errado.

Estou com enxaqueca, então posso simplesmente não estar pensando totalmente correto, mas estou com vontade de descobrir como lidar com o caminho da reprovação para essa sugestão pode ser o caminho certo a seguir.

Bem, eu não vou argumentar que compat com versões anteriores é importante aqui. Sempre fui a favor de mudar o comportamento de pip install --upgrade . É o mais limpo e o custo parece pequeno. Mas me pareceu que foi vetado por @qwcode , então pip upgrade foi a segunda melhor opção (e já foi aprovado pelos desenvolvedores pip há um ano).

Se agora queremos voltar a alterar os padrões / comportamento de pip install , ótimo.

@dstufft que faz total sentido para mim - a dor de cabeça não pode ser tão ruim :)

Uma vez que concordamos em descontinuar o --upgrade, podemos mantê-lo e adicionar duas opções para instalar o pip: --upgrade-only-needed e --upgrade-eager, o segundo sendo um apelido para o obsoleto --upgrade

@xavfernandez Forçar decisões sobre os usuários é meio ruim, eu acho. A menos que eu entenda as questões bastante sutis, não tenho certeza se realmente saberia se quisesse --upgrade-only-needed e --upgrade-eager .

@xavfernandez então você está propondo que na situação final o comando seria pip install --upgrade-only-needed ? Parece feio.

Seria muito melhor ter algo que mapeie para o equivalente da versão semântica fixada disponível em, por exemplo, hex ou Cargo . Isso certamente precisaria de ajustes no contexto do Python, uma vez que (a) as versões PEP 440 não fazem e não podem mapear precisamente para versões semânticas e (b) a comunidade Python em geral não necessariamente corta para versões semânticas em seus lançamentos, mesmo dentro PEP 440.

No entanto, algo nesse sentido seria muito útil, assim como a noção de fixar uma versão específica.

Dadas as restrições, no curto prazo, uma opção viável pode estar fazendo algo análogo aos comandos upgrade e upgrade --all do homebrew, onde o último simplesmente vai em frente com a atualização de tudo (potencialmente com um aviso na primeira vez )

No longo prazo, entretanto, seria extremamente útil criar convenções compartilhadas sobre o que as versões significam na comunidade de empacotamento Python, e construir pip suporte para isso poderia ser uma grande parte disso.

O caminho de migração óbvio seria:

pip versão X:

  • adicionar opções pip install --eager , pip install --no-eager , onde --eager significa que para requisitos sem restrição de versão anexada, tentamos instalar a versão mais recente, mesmo se já houver alguma versão instalada, e --no-eager significa que estamos satisfeitos se alguma versão for instalada
  • também adicione a opção pip install --eager-recursive com a semântica -U atual
  • --no-eager permanece o padrão
  • se nenhuma dessas opções for especificada e pip install for aprovado em um requisito sem número de versão anexado e esse requisito já for satisfeito, em seguida, produzirá um aviso dizendo que não atualizamos seu pacote, mas no futuro nós o faremos, então você deve usar --no-eager se quiser manter o comportamento atual
  • adicione um aviso de descontinuação a pip install -U referindo pessoas a pip install --eager-recursive

pip versão Y:

  • mude o padrão de pip install para --eager

pip versão Z:

  • remover pip install -U

Fiz versões diferentes de Y e Z porque estou ansioso por --eager então talvez pudéssemos fazer essa mudança em um cronograma mais agressivo, mantendo pip install -U por perto por um tempo, já que muita documentação já se refere a ele, e não causa nenhum dano. Mas obviamente Y = Z é uma opção :-)

@chriskrycho : Tudo isso parece ótimo para se ter, mas esta discussão é sobre como lidar com a situação em que o usuário está explicitamente tentando solicitar uma atualização para a versão mais recente de um pacote, que é uma situação que normalmente já acontece hoje e não temos uma boa resposta para. Não sei se há um bug aberto solicitando suporte de fixação, mas se não, talvez você deva iniciar um?

Absolutamente; meu ponto (que agora reconheço que falhei totalmente em tornar explícito!) foi simplesmente observar que qualquer solução adotada aqui não deve entrar em conflito com esse tipo de abordagem no futuro.

Qual é o caminho normal de suspensão de uso do pip? Baseado em tempo / versão? Por quanto tempo algo precisa ser descontinuado antes de ser removido?

A propósito, acho que "ansioso" é uma palavra que os usuários não vão entender. recursivo / recursivo somente quando necessário / sempre recursivo é muito mais claro.

Normalmente fazemos um ciclo de depreciação de duas versões.

Versões principais, presumo? As versões secundárias são muito rápidas (7.0 -> 7.1 era um mês). Normalmente, meio ano entre as versões principais, portanto, 1 ano de avisos de suspensão de uso?

Sim, desculpe. Versões principais. Se suspendermos o uso de algo em 8.x, será um aviso amarelo para o restante de 8.x, um aviso vermelho para todos os de 9.x e removido em 10.x.

Obrigado.

Copiando comentário @dstufft 's de https://github.com/pypa/pip/pull/3194#issuecomment -152357835 aqui, porque é o melhor resumo da situação:

Acho que o tl; dr é que eu acho totalmente que precisamos corrigir o comportamento "padrão", só precisamos definir a implementação específica para corrigi-lo:

  1. Mantenha o UX be pip install --upgrade e mude o padrão.
  2. Mova o UX para atualizar o pip com o padrão "correto" e adicione um sinalizador --recursive.
  3. Mova o UX para instalar pip, remova --upgrade e adicione um sinalizador --recursive.

Meu 2c:

(1) tem um bom UX, pode ser feito agora
(2) UX um pouco pior (ambos install e upgrade ), pode ser feito agora
(3) segundo melhor UX, a alteração de pip install pode ser feita agora, a remoção de --upgrade só será feita em 10.0 (obsoleto em 8.0 e 9.0).

Não vejo por que o problema de compatibilidade reversa (que deve ser menor de qualquer maneira) para (1) seria pior do que para (3). Portanto, (1) parece o melhor. Se o bw compat for uma preocupação real, escolha (2).

Enfim, hora de encerrar a noite.

Eu acho que a diferença entre (3) e (1) se resume a se nós pensamos que instalar ou atualizar é a operação mais comum que as pessoas desejam - se sim, então torná-lo um comando curto como em (3) é provavelmente o melhor. De qualquer forma, não é um grande problema.

A propósito, acho que "ansioso" é uma palavra que os usuários não vão entender. recursivo / recursivo somente quando necessário / sempre recursivo é muito mais claro.

Não estou nem um pouco preso à grafia "ansioso", mas recursivo simplesmente não faz sentido como a palavra principal para ativar e desativar atualizações. Eu acho que poderíamos usar --upgrade-non-recursive (futuro padrão), --upgrade-recursive , --upgrade-none ou algo assim, mas ainda assim enfatiza o confuso comportamento recursivo (eu não teria ideia do que --upgrade-non-recursive significava se eu já não estivesse familiarizado com o estranho comportamento recursivo da opção -U legada), e --upgrade-none enganosamente parece que fará com que nenhum pacote seja atualizado, mesmo se necessário para preservar a si mesmo. consistência.

Se formos por esse caminho, não me importo muito com o período de grafia, já que a opção que a maioria das pessoas deseja seria apenas o padrão e as opções de atualização recursiva e sem atualização seriam ambas coisas especiais raramente usadas que a maioria dos usuários poderia ignorar.

--upgrade-non-recursive (padrão futuro) ...

claro que isso é confuso. mas você está ignorando a opção mais simples, que é não fornecer essa opção. porque se for idêntico ao comportamento padrão, por que você precisaria dele?

Acho que a diferença entre (3) e (1) se resume a se pensamos que instalar ou atualizar é a operação mais comum que as pessoas desejam

Eu esperaria "instalar". Pelo menos eu sei que só atualizo pacotes que uso intensamente de propósito, mas cada vez que vejo algo interessante / útil, fica apenas pip install pkgname distância.

(não que eu seja um usuário típico, então minha expectativa pode estar errada)

Acho que seria a favor de:

  • Nenhum novo pip upgrade que seria um alias para pip install
  • pip install (sem --upgrade* opção) o comportamento não muda
  • pip install --some_name tentaria apenas atualizar os pacotes especificados na linha de comando e não suas dependências
  • pip install --some_other_name para manter o antigo --upgrade comportamento disponível

E então existem duas opções:

  • não precisamos / queremos um caminho de descontinuação, então --some_name pode ser --upgrade e --some_other_name pode ser o que parecer melhor
  • precisamos de um caminho de descontinuação, então --upgrade no pip8 dará um aviso dizendo que está descontinuado e devemos usar --some_other_name para manter o comportamento antigo ou mudar para um --some_name mais seguro para atualizar apenas os pacotes especificados e suas dependências apenas se necessário.

Neste segundo caso, --some_name não pode ser --upgrade . Portanto, temos que encontrar dois novos nomes de opções para --some_name e --some_other_name

Parece-me que a "melhor" solução óbvia é manter pip install como o comando e alterar o comportamento de --upgrade para não atualizar as dependências. O único problema real é a compatibilidade com versões anteriores, mas tivemos _algumas_ usuários argumentando que dependem do comportamento atual?

Pessoalmente, estou inclinado para a visão "vá em frente e vá em frente com a compatibilidade com versões anteriores". Eu poderia argumentar que o comportamento atual é na verdade um bug, e essa mudança seria uma correção de bug. Mas acho que em algum momento precisamos ser capazes de dizer que alcançamos um bom ponto e que vamos ter uma visão muito mais rígida sobre a compatibilidade com versões anteriores. Não acho que chegamos a esse ponto ainda, mas podemos precisar começar a informar a comunidade o que achamos que ainda precisa ser feito para chegarmos a esse ponto.

Ainda existe (IMO) a necessidade de algum tipo de comando pip install --upgrade :all: para atualizar todos os pacotes instalados. Mas essa é uma nova funcionalidade, então não é relevante aqui.

O comportamento atual _é_ útil, particularmente para projetos como Pyramid, que não são um único projeto, mas na verdade são uma coleção de projetos. Seria útil poder fazer algo como pip install --upgrade-recursive Pyramid para atualizar o Pyramid e todas as suas dependências para a versão mais recente. Remover a coisa recursiva toda junto significa que eu tenho que rastrear manualmente todas as dependências e fazer pip install --upgrade Pyramid dep1 dep2 dep3 dep4 (com a árvore de dependências inteira) ou eu preciso fazer um pip install --upgrade :all: hipotético e possivelmente atualizar mais coisas do que eu realmente quero atualizar. Em # 3194, pelo menos um usuário mencionou que gostaria que o comportamento atual estivesse disponível por meio de um sinalizador, pois é útil em alguns casos.

Existe alguma razão (além da compatibilidade com versões anteriores) para não torná-lo tão pip install implicitamente faz uma atualização "mínima"? Estou tentando descobrir em que situação eu realmente gostaria que ele apenas fosse instalado e não uma atualização (IOW, uma em que a versão mais recente está bem se eu ainda não a tiver instalado, mas não se eu tiver instalado) e estou tendo um problema para encontrar um caso em que gostaria do comportamento atual.

Eu gosto da ideia de um _novo_ pip upgrade [--recursive] comando como em # 3194 (e descontinuando install --upgrade )

Estou preocupado com quaisquer escolhas que quebrem a compatibilidade ou tenham depreciações complexas ou que sobrecarreguem um pip install já pesado com mais opções ou complexidade. Além disso, estou pessoalmente atraído por um comando de "atualização", que por padrão, apenas atualiza de forma semelhante ao funcionamento das ferramentas da distro. "install" instala e "atualiza" upgrades ...

Estou inclinado para a visão "vá em frente e vá em frente com a compatibilidade com versões anteriores"

Eu não sou:) pelo menos para uma lógica central como essa.

faça com que a instalação do pip faça implicitamente uma atualização "mínima"

para mim, considerando que isso parece um fracasso, certo? considere o número de quebras de compilação automatizadas que podem ocorrer. também, as pessoas ficam presas em um modelo conceitual em um certo ponto sobre o que pip install é ... e isso forçaria a recarga de um novo modelo mental. as pessoas não gostam disso.

@qwcode Não sei, não acho que seria bom. O principal problema com pip upgrade é remover a maneira como as pessoas dizem "dê-me a última versão deste independentemente de estar instalado ou não" ou você tem dois comandos que fazem quase inteiramente a mesma coisa ( pip install e pip upgrade ). Pode haver alguma quebra no curto prazo, mas estou um pouco preocupado com o modelo mental real de pip upgrade porque posso ver as pessoas simplesmente espalhando substituindo suas instruções de instalação de pip install foo para pip upgrade foo (mas por que estou atualizando algo que ainda não instalei ?!).

Er, acho que ficaria bem, quero dizer.

ampla distribuição substituindo suas instruções de instalação pip install foo para pip upgrade foo

entendido, é por isso que acho que upgrade deveria apenas atualizar. quanto ao "bosta" --fill-in-missing , não estou preso a isso, então não me considere que eu tenho que ter isso, mas veja abaixo.

"dê-me a versão mais recente, independentemente de estar instalado ou não"

  • se eu não tiver FOO , então eu pip install FOO e obtenho a versão mais recente.
  • se eu tenho FOO , então pip upgrade FOO e obtenho a versão mais recente.

Acho que estamos falando de 2 casos:

  1. Não sei se tenho FOO e quero que o comando _one_ obtenha o FOO mais recente, quer o tenha ou não.
  2. Quero que o comando _one_ obtenha o último de FOO e BAR . Tenho FOO instalado, mas não BAR .

Devemos aos usuários _um_ o comando por eles? Eu prefiro simplicidade e clareza nos comandos a dar atalhos às pessoas. Mas se os usuários exigirem, é aí que algo como --fill-in-missing entra.

Além disso, estou pessoalmente atraído por um comando de "atualização", que por padrão, apenas atualiza de forma semelhante ao funcionamento das ferramentas da distro. "install" instala e "atualiza" upgrades ...

Ponto de esclarecimento: acabei de verificar como funcionam três ferramentas populares de distro e AFAICT (em parte, isso é baseado em páginas de manual b / c eu não uso todas elas):

  • apt:

    • apt install <pkg> executa uma "atualização" - atualiza ou instala dependendo se já está instalado ou não.

    • apt upgrade atualiza todos os pacotes instalados

    • apt upgrade <pkg> não existe, a única maneira de atualizar um único pacote é apt install <pkg> (que também aceita vários tipos de especificadores de versão)

  • yum:

    • yum install <pkg> executa um "upstall"

    • yum upgrade atualiza todos os pacotes instalados

    • yum upgrade <pkg> atualiza uma lista especificada de pacotes. Não sei o que acontece se eles ainda não estiverem instalados.

  • cerveja caseira:

    • brew install <pkg> executa um "upstall"

    • brew upgrade atualiza todos os pacotes

    • brew upgrade <pkg> atualiza uma lista especificada de pacotes. Não sei o que acontece se eles ainda não estiverem instalados.

Portanto, usar a instalação para atualizações é o que as ferramentas da distro fazem :-). Não significa que temos que fazer isso também; apenas um ponto de dados.

Não sei se tenho FOO e quero um comando para obter o FOO mais recente, quer o tenha ou não.

Acho que o caso de uso mais obviamente atraente para isso está na documentação. Exemplo: os documentos do django que vinculei em outro tópico que instruem as pessoas a executar pip install -U <some package> . Você não quer dizer às pessoas para "executar pip install <pkg> exceto se você já tiver instalado, execute pip upgrade <pkg> " porque isso é muito confuso para iniciantes, mas se install não t atualizar então apenas dizer às pessoas para executarem pip install <pkg> também vai criar confusão, onde as pessoas começam a trabalhar em seu tutorial com uma versão antiga instalada e então não têm ideia de por que as coisas não funcionam direito e culpam você por isso. Portanto, você definitivamente precisa de um único comando "upstall", e precisa ser simples e óbvio para incluir nos documentos.

Acompanhamento do comportamento do Homebrew para comparação: brew upgrade falhará se você tentar instalar um pacote não instalado:

$ brew upgrade git
Error: No such file or directory - /usr/local/Cellar/git

Além disso, o comportamento atual de brew upgrade está mudando (veja a discussão aqui ); em uma versão futura, ele passará a exigir --all para atualizar todos os pacotes instalados.

Ponto de esclarecimento

Eu sabia que alguém iria perceber isso. :)
Quase respondi a mim mesmo. Eu estava focado em atualizações.

yum atualização[...] não sei o que acontece se ainda não estiverem instalados.

não faz nada

yum installexecuta um "upstall"

verdadeiro, mas o comportamento padrão é solicitar a confirmação, o que o pip não tem.

os documentos do django que vinculei no outro tópico

para ser claro, eles não eram os documentos reais do Django. os documentos do Django dizem pip install Django (https://docs.djangoproject.com/en/1.8/topics/install/)

na verdade, acho que é uma coisa ruim, dada a maneira -U funciona atualmente, fazer com que as pessoas adquiram o hábito de usar install -U .

no seu exemplo vinculado, era para redis que não tem nenhuma dependência, eu acho, então está tudo bem neste caso.

vai criar confusão onde as pessoas começam a trabalhar com o seu tutorial
com uma versão antiga [...] Então você definitivamente precisa de um único comando "upstall"

IDK, Não é tão óbvio para mim que os tutoriais devam dizer às pessoas para atualizar em geral. Se alguém está fazendo um tutorial para o FOO e já tem o FOO instalado, talvez não deva "upstall" cegamente ... talvez uma atualização danifique o ambiente existente.

Acho que os tutoriais deveriam dizer às pessoas para "upstall" (ótimo termo!) Porque um bom número deles são escritos pelos próprios projetos e quando as pessoas vão para ver os tutoriais, raramente olham primeiro para ver qual é a versão existente do FOO. instalaram, em vez disso, eles tendem a consultar quaisquer que sejam os documentos mais recentes.

Também concordo que a maneira -U funciona atualmente é um péssimo hábito fazer com que as pessoas tenham o hábito de usá-lo indiscriminadamente, mas a principal coisa que acho é com o comportamento proposto, não acho que seja um mau hábito , mas sim uma coisa boa a fazer. Se você precisa garantir que uma versão específica está instalada, então você já deve estar usando == e podemos adicionar um sinalizador para transformar o "upstall" padrão de volta em uma "instalação" simples para pessoas que precisam ter certeza de que a versão atualmente instalada OU a versão mais recente está instalada (embora eu ainda não consiga imaginar um cenário em que isso seja realmente o que alguém deseja).

Acho que os tutoriais deveriam dizer às pessoas para "upstall"

Mais uma vez, porém, em que ambiente eles estão, onde obviamente não há problema em atualizar? Se for um ambiente python de sistema de distribuição, certamente não. Se for algum outro ambiente, eles foram feitos para um aplicativo, então um upstall pode ser prejudicial. se for um ambiente que eles criaram apenas para o tutorial, não será necessário fazer upgrade.

um ponto-chave aqui é que o PyPI não é um repositório "com curadoria", como os repositórios de distro são. você pode ter certeza de que um "upstall" está seguro de um repositório de distribuição padrão ... você não sabe disso com o PyPI. Cada atualização é, de certa forma, uma aposta. "instalar", como é, é conservador.

tenha em mente que fazer pip install agir como um "upstall" sem consertar # 988 irá quebrar as coisas.

considere onde A e B estão instalados e A requer B<2 . Agora vou executar o novo pip install B , que atualiza B para v3 ou qualquer outra coisa (devido a não considerar as restrições instaladas), e agora meu ambiente está quebrado.

para pessoas que precisam ter certeza de que a versão instalada atualmente OU a versão mais recente está instalada (embora eu ainda não consiga imaginar um cenário em que isso seja realmente o que alguém deseja).

É trivial criar tais cenários. Exemplo (infelizmente não inventado): atualmente statsmodels está quebrado pelo último pandas (0.17.0). Eu sou um usuário de ambos. Eu tenho um monte de versões do Python instaladas e venvs por aí. Portanto, sei que, para qualquer Python / venv, gostaria de instalar pandas apenas se ainda não estiver lá. Se for, provavelmente terei também statsmodels e então "upstall" o quebrará.

@rgommers Hmm, então você tem certeza de que não tem um pandas 0.17.0 em um ambiente virtual em lugar nenhum? Acho que poderia acontecer, embora eu provavelmente explicaria isso fazendo pip install pandas!=0.17.0 ou pip install pandas<0.17 mas acho que não é totalmente irracional confiar no que você já instalou.

Hmm, então você tem certeza absoluta de que não tem um pandas 0.17.0 em um ambiente virtual em qualquer lugar?

Não foi isso que eu disse. Eu tenho um venv com pandas 0.17.0, apenas um em que não tenho modelos de estatísticas. pip install pandas<0.17 fará o trabalho, mas não me ocorreu usar isso (principalmente porque eu não precisava, o comando install atual funciona para esse propósito).

De qualquer forma, não tenho muita preferência a favor ou contra upstall. Eu só queria apontar um cenário realista quando você disse que não poderia imaginar um.

+1

Esta discussão parece ter estagnado sem chegar a uma conclusão. Qualquer opção na mesa é uma grande melhoria no status atual. Parece que todos os prós e contras relevantes foram considerados; há apenas uma diferença de opinião sobre a importância relativa da compatibilidade retroativa versus a API ideal. Talvez os desenvolvedores do pip possam tentar finalizar uma decisão?

@rgommers eles provavelmente tomaram a decisão? https://pip.pypa.io/en/stable/user_guide/#only -if-needed-recursive-upgrade

@rgommers eles provavelmente tomaram a decisão? https://pip.pypa.io/en/stable/user_guide/#only -if-needed-recursive-upgrade

@ Liso77 obrigado, mas não - é realmente a discussão neste tópico que precisa ser finalizada. Essa documentação que você vinculou apenas aponta para trás aqui.

@rgommers do link que postei acima, li que os desenvolvedores farão o comando de atualização. E não planeje adicionar a opção "somente se necessário" para instalar o comando porque eles não criaram um termo para esta opção e usam apenas a descrição entre aspas. Então, do seu comentário (ou do dstuff) em 30 de outubro - é: _2. Mova o UX para atualizar o pip com o padrão "certo" ..._ (aliás, eu prefiro isso)
Tenho certeza que você estava pensando mais sobre este assunto e vê coisas mais sutis que eu vejo. Então, por favor, escreva o que (se você acha que algo) ainda está aberto. Se você quis dizer que pode ser bom que os desenvolvedores escrevam aqui explicitamente sua decisão e, eventualmente, fechem este problema - eu concordo.

Por falar nisso. situação poderia ser muito menos problemática se tivéssemos algo como

pip freeze > checkpoint.txt
pip checkout checkpoint.txt

o que poderia garantir a reversão da instalação para qualquer "ponto de verificação". (pip install -r não é bom nesse momento) Estava pensando em adicionar essa proposta em uma nova edição, mas tenho certeza que tenho que estudar e analisar mais para trazer uma proposta realmente útil. Vejo que há muitas ressalvas, mas realmente gosto de ter a possibilidade de

pip checkout git+https://github.com/somebody_trusted/pip_distro4ubuntu<strong i="12">@bleeding_egde_branch</strong>
#or
pip checkout git+https://github.com/somebody_trusted/pip_distro4ubuntu<strong i="13">@stable</strong>

Quer dizer, isso poderia resolver (com a ajuda de alguém_confiável (ou comunidade com muitos testes de unidade)) algo como o problema de pandas e modelos de estatísticas que você descreveu acima.

(útil para ver neste tópico também é: https://pypi.python.org/pypi/peep)

@ Liso77 é simples: a discussão sobre esse assunto ainda não acabou. Há um PR esperando com o comando upgrade implementado (gh-3194), mas os desenvolvedores pip (pelo menos qwcode e @dstufft , e provavelmente também @xavfernandez e @pfmoore) precisam decidir se é isso que eles querem ou, em vez disso, desejam alterar o comportamento de pip install . Até que isso aconteça, nada será alterado.

+1

Portanto, parece que a introdução do novo comando de atualização foi acordada e o último debate ainda não resolvido é se deve ou não haver um comando "upstall" e, em caso afirmativo, qual comando principal (instalar ou atualizar) deve obtê-lo como uma opção ou padrão .

Jogando minhas opiniões pessoais:

Acho que ter um comando único à prova de falhas para atualização "vale a pena", _se apenas_ para os casos em que você deseja verificar programaticamente se um ambiente está atualizado por algum motivo. Por que "programaticamente"? Porque não é interativo, ou seja, não há usuário para reagir a um erro, aviso ou outra mensagem apontando-o para o comando brother ou sister porque um pacote existe ou não existe.
Opcionalmente, um prompt pode ser adicionado perguntando ao usuário se ele deseja atualizar ou instalar, em vez de apenas reclamar.

Dito isso, este comando "upstall" não deve ser o padrão de nenhum dos comandos (instalar / atualizar) e, portanto, exigir que uma opção seja chamada. Isso adiciona clareza aos verbos "instalar" e "atualizar" semanticamente definidos e, em minha opinião, todos os gerenciadores de pacotes que instalam por padrão em um deles estão fazendo isso errado. Solicitar ação (como yum parece fazer) está certo.

Isso nos deixa com upgrade --install (menor que --install-missing ) e install --upgrade . Semanticamente, "atualize para o mais recente [e instale se não existir]" e "instale o mais recente [ou atualize para o mais recente se já existir]". Não há muita diferença aqui imo. install --upgrade é a versão já existente e seria reconhecível, mas incompatível com versões anteriores.
Aqui está outro para a combinação: Um novo comando chamado install-upgrade (ou upstall ?), Onde nem instalar nem atualizar tem a opção de "também fazer o outro", mas um novo comando é introduzido com semântica clara em uma posição importante: o próprio nome do comando. Essa seria minha preferência.

TL; DR : Apresente upgrade e upgrade-install , desative install --upgrade . Todas as funcionalidades com semântica clara.
Adicione mensagens ou, opcionalmente, prompts para instalar e atualizar comandos se suas operações falharem devido a um pacote já existente ou não.

Fiz isso de novo manualmente esta manhã. Há alguma notícia sobre este pedido de recurso?

+1

+1

+1

Todos, por favor, usem a reação de polegar para cima no OP e parem de enviar spam para a caixa de entrada de todos.

uma vez que o pip tem um modelo de controle de qualidade diferente das distribuições do Linux, tenho quase certeza de que um comando de atualização aleatória de todos é apenas uma falha em construção

pypi não tem banco de dados de versões de pacote e compatibilidade que seja realmente verificada e testada,
então, ao contrário de uma distribuição com QA, pypi praticamente não tem QA próprio e depende totalmente dos projetos enviados para ela (que variam em qualidade)

com os atuais conjuntos de restrições, estou convencido de que é mais uma maldição do que uma bênção
e se alguém se perguntar por que as distribuições estão tão desatualizadas, o controle de qualidade leva tempo e esforço reais ^^

Todos, por favor, usem a reação de polegar para cima no OP e parem de enviar spam para a caixa de entrada de todos.

Observe que, na verdade, não precisamos de _qualquer_ tipo de resposta do tipo "Eu gostaria disso" das pessoas. Estamos cientes de que as pessoas querem isso, o que está faltando é alguém disposto a desenvolver uma solução que atenda a todas as várias preocupações e problemas que já foram levantados e que inevitavelmente surgirão durante uma revisão de RP.

Portanto, pessoalmente, agradeceria se as pessoas evitassem fazer ping neste problema, a menos que tenham um código em funcionamento que pelo menos ofereça um ponto de partida para a implementação - e estejam dispostas a segui-lo até a implementação.

Caso contrário, vamos fazer isso quando pudermos. Eu pessoalmente enfrento esse problema regularmente e sou um desenvolvedor de pip core, então posso garantir que se algum dia eu tiver tempo suficiente para trabalhar nisso, eu o farei. Nesse ínterim, "algum progresso?" comentários tendem a simplesmente me desmotivar porque, na maioria das vezes, parecem pessoas exigindo o direito de ditar como passo meu tempo de hobby ...

um ponto de partida para a implementação

Achei que fosse esse o propósito de https://github.com/pypa/pip/pull/3194? A partir daí, a discussão mudou para várias alternativas de nomenclatura e comportamento de comandos sem um consenso dos desenvolvedores principais. Isso ajudaria a implementar várias dessas alternativas? Ou https://github.com/pypa/pip/pull/3194 só precisa de uma atualização?

@sfriesel Você perdeu "e está disposto a seguir adiante". Parece que a pessoa que fez aquele RP ficou sem tempo ou sem interesse (um problema comum). A próxima etapa é provavelmente para o OP ou outra pessoa que deseja assumir a propriedade do PR, escrever um resumo do estilo PEP da posição atual, quais são as várias questões pendentes, o que ele está sugerindo como resolução para essas várias questões e uma chamada para comentários para reiniciar a discussão. Se o debate for muito grande para o github, talvez ele precise levar seu documento para distutils-sig para obter mais informações. Se ele não conseguir decidir sobre uma resolução com a qual está satisfeito para as várias questões, ou não conseguir obter consenso do debate, então sim, # 3194 provavelmente está morto (até que outra pessoa pegue o problema novamente, momento em que eu esperaria que eles incorporassem todo o trabalho realizado em seu novo PR).

Bem mais de 50% do trabalho em uma proposta como esta é "gerenciamento" (documentar propostas, gerenciar discussões, obter consenso). Não é necessariamente o bit que as pessoas gostam de fazer, mas com uma base de código amplamente usada como pip, é uma parte essencial. (E sim, isso é um problema - é muito mais agradável dizer "Eu escrevo código como um hobby" do que "Eu faço gerenciamento de projetos como um hobby" :-))

@pfmoore Concordo totalmente.

A quantidade de propostas e quantidade de discussões, espalhadas por vários locais, relacionadas a esse assunto ao longo dos anos torna extremamente difícil abordar esse assunto e obter uma imagem clara em um curto espaço de tempo .


@RonnyPfannschmidt

pypi não tem banco de dados de versões de pacote

É verdade. Esta é a informação fornecida pelos pacotes em tempo de execução (do setup.py) e adiciona um pouco mais de complexidade ao processo de resolução das dependências. Além disso, devido ao comportamento da lógica atual, alguns pacotes (mesmo os proeminentes como o scipy) não listam uma dependência (como o numpy) se estiver instalada para evitar a recompilação desnecessária.

Isso seria resolvido pelo PEP 426 , entre outras coisas mas não sei qual é o estado desse PEP.

@pfmoore

Observe que, na verdade, não precisamos de qualquer tipo de resposta "Eu gostaria disso" das pessoas

É apenas tentador dizer +1 ou levantar o polegar para anunciar que você gostaria que isso acontecesse. Faz com que a pessoa sinta que acrescentou algo a este problema, que contribuiu para ele. Não estou dizendo que os desenvolvedores de pip precisam ser motivados ou persuadidos, só que todo mundo quer dizer isso. E...

Eu apreciaria se as pessoas evitassem fazer ping neste problema, a menos que tenham um código funcionando

Colocar um polegar para cima não vai dar a ninguém notificações / e-mails (irritantes) e ainda podemos ver o número de pessoas que mostraram interesse. Acho que ninguém deveria se importar com isso, mas posso estar errado.

Colocar um polegar para cima não vai dar a ninguém notificações / e-mails (irritantes) e ainda podemos ver o número de pessoas que mostraram interesse. Acho que ninguém deveria se importar com isso, mas posso estar errado.

Ah, eu não tinha percebido que fazer isso evitava as notificações. Sim, essa é uma boa ideia.

A próxima etapa é provavelmente para o OP ou outra pessoa que deseja assumir a propriedade do PR, escrever um resumo do estilo PEP da posição atual, quais são as várias questões pendentes, o que ele está sugerindo como resolução para essas várias questões e uma chamada para comentários para reiniciar a discussão.

Pelo que vale a pena, eu estava escrevendo anteriormente sobre isso e a resolução de dependências, no estilo PEP. Vou dividi-lo e atualizá-lo agora, adicionando todas as coisas que foram propostas nos últimos meses. Vou postar aquele para o comando de atualização como um Gist quando estiver pronto (cerca de 2 dias?) E vincular a ele a partir daqui.

Não estou disposto a assumir a propriedade do PR ainda. Pretendo ajudar a reacender as discussões e chegar a um projeto final que possa ser implementado. Se alguma coisa ao meu redor correr conforme o planejado, devo ser capaz de seguir até a implementação, mas não quero me comprometer com isso ainda.

/ cc @qwcode @dstufft @pfmoore @xavfernandez

Aqui está o link para meu artigo: https://gist.github.com/pradyunsg/a5abeac4af90fbdc54bb266c32c0d2d8

Inicialmente, apenas vinculei a vários lugares (~ 30 links) para o leitor consultar e tentei copiar e editar para caber em todos os tópicos de comentários. O documento era bem longo e minhas opiniões escaparam. Acabei começando do zero. É mais curto agora e não é opinativo. Ainda o marquei como WIP.

Se houver algum problema nisso, por favor, comente sobre a essência. Farei as correções assim que puder.

AVISO: _LIGHTLY_ COMENTÁRIO LONGO À FRENTE


Gosto da ideia de corrigir o comportamento existente de --upgrade . Há alguma preocupação com relação a isso além da compatibilidade com versões anteriores? Adicionar um comando upgrade não parece uma boa ideia, devido à alta sobreposição entre instalação e atualização.

FWIW, git fez algo semelhante ao que estamos discutindo sobre --upgrade , mudando o comportamento padrão de git push em 2014. link

Se houver interesse em mudar o comportamento de pip install --upgrade , aqui está uma proposta de propagação (chame de P1) para essa discussão:

  • Iniciando a próxima versão principal (9.0), pip install --upgrade imprime um aviso:

`` `
PipDeprecationWarning: pip irá parar de atualizar as dependências para o seu mais recente
versão incondicionalmente por padrão a partir da versão 11.0.

Para manter o comportamento atual após as mudanças de comportamento padrão, para
o comando de instalação passa --upgrade-strategy eager .

Para começar a usar o novo comportamento imediatamente, use o comando de instalação
passe --upgrade-strategy non-eager .

Para silenciar esta mensagem,.

Para mais detalhes, leia.
`` `

O link da página de documentação fornece uma visão geral rápida da mudança e seus efeitos. Em seguida, abordaria a pergunta mais comum: "O que devo fazer?" e "Qual estratégia de atualização devo usar?" da maneira mais direta razoável.

  • A mensagem poderia ser limpa.
  • A opção pode ser até 2 sinalizadores, --upgrade-eager e --upgrade-non-eager ou algo assim. Isso é bicicleta, ou seja, última etapa.

    • A menos que algo drástico aconteça, na versão 11.0, pip install --upgrade muda o comportamento para não ser ansioso ao atualizar dependências.

Edit: Eu coloquei um ciclo de 3 versões principais para a mudança, apenas para dar mais tempo para as pessoas fazerem a troca. Pode ser desnecessário. Talvez, uma versão principal imprimindo avisos e a próxima fazendo a alteração seja o suficiente?

@dstufft teve uma ideia semelhante (a mesma?).


Se um comando de atualização é o caminho a seguir, aqui está uma proposta de propagação para reiniciar essa discussão (chame de P2, se quiser):

  1. pip upgrade copia a maioria das opções e comportamentos de pip install .
  2. --dry-run bandeira install e upgrade que imprimem o que o pip tentará se realmente for executado.
  3. pip install <out_of_date_pkg> não muda o comportamento.
  4. pip upgrade <not_installed_pkg> falharia.
  5. pip upgrade <up_to_date_pkg> não faria nada, diga por que não fez nada e sairia com um código de saída zero.
  6. pip upgrade <out_of_date_pkg> executaria uma atualização recursiva não rápida.

    • : white_check_mark: Padrão para atualização recursiva não antecipada

  7. pip upgrade --eager package se comportaria como os pip install --upgrade .

    • : white_check_mark: Permitir adesão ao comportamento atual

  8. pip install --upgrade imprimiria um RemovedInPip10Warning .
    Porque seria removido.

Além disso, quais são suas opiniões sobre:

  1. Tornando o comando de atualização interativo? (algo como o que o apt-get faz)

    • fazendo pip install <pkg> se comportar como o ieupstall de instalação do gerenciador de pacotes do sistema operacional?

  2. Tendo --only-binary por padrão no novo comando de atualização?

    • Se estiver tudo bem, que tal adicionar --only-source e --no-source no comando de atualização?

  3. Adicionando uma opção para "reter" a atualização de um pacote? IMO, este é um requisito para upgrade-all .
  4. Faz sentido distinguir entre esses casos, ou seja, exigem CLI diferente?

    • instalar: não instalado -> atualizado

    • atualização: desatualizado -> atualizado

    • upstall: {not-installed, out-of-date} -> up-to-date

Eu não propus nada sobre "instalar como upstall" porque não tenho nenhuma opinião sobre isso. É consistente com os gerenciadores de pacotes no nível do sistema operacional, mas seria uma mudança importante. Não tenho certeza de quão útil seria ou como seria o comportamento exato e a interface ...

Talvez dormir sobre isso possa ajudar.

Pessoalmente, não vejo muito valor em manter a consistência com um comportamento com o qual poucas pessoas, se é que alguma, estão satisfeitas. Eu me pergunto se ter um para Python 2 (abrangendo estabilidade) e outro para Python 3 (abrangendo mudanças) seria melhor ou pior.

@ekevoo

Eu me pergunto se ter um para Python 2 (abrangendo estabilidade) e outro para Python 3 (abrangendo mudanças) seria melhor ou pior.

Um, isso está fora do assunto. Dois, se você fizer isso, acabará havendo divergência. Isso vai afastar as pessoas que atualmente usam o Python 2, porque (com sorte) chegará ao fim do dia um dia e eles terão que mudar para o Python 3, tendo que se adaptar para uma ferramenta de comportamento diferente. Assim, pip não deve fazer divergência (e não fará, IMO). Seria melhor mantê-los juntos em uma única ferramenta, então.

OTOH, vejo o que você pensa sobre o quanto a compatibilidade com versões anteriores é aceitável ...

Um aviso no pip 9, mais opções adicionais para ajustar o comportamento de pip install --upgrade , --eager/non-eager (ou algum outro nome) parece bom para mim.

Ressalto. Outra notificação para todos.

@pfmoore @dstufft @qwcode Não quero ser intrometido, mas você poderia

OK, então meus comentários:

Sobre os dois caminhos a seguir, não tenho opinião. Escolha aquela que você achar que é a melhor opção, implemente e veremos como funciona a partir daí.

Re suas perguntas adicionais:

  1. Estou -1 em tornar o comando interativo. A menos que haja um problema específico sobre o qual o usuário precise tomar uma decisão, ao longo das linhas de "esta consequência do que você pediu é algo que você claramente desconhecia e pode ser um problema - você deseja continuar", então é só ruído inútil. Sou contra os prompts do tipo "você tem certeza" em geral. Se você tiver uma proposta específica para um prompt que acha que vale a pena adicionar, sinta-se à vontade para perguntar novamente com os detalhes incluídos.
  2. Não devemos fazer atualizações diferentes de instalações, portanto, não a --only-binary por padrão. Para meu uso pessoal, provavelmente sempre irei querer pip upgrade --only-binary na primeira instância, mas _quero_ que seja explícito.
  3. Não tenho certeza do que você quer dizer sobre "reter" atualizações. Por favor, esclareça. Mas, como uma resposta geral, eu diria que não se preocupe em primeiro lugar, vamos manter o PR inicial livre de "extras opcionais" - eles podem ser adicionados mais tarde.
  4. Não é esse o principal tópico de debate nas várias discussões deste recurso? Para começar, isso não afeta a questão básica de install --upgrade vs upgrade ? Não me lembro de ter havido uma resolução para essa questão, então estou um pouco surpreso que você espere uma resposta "simples" para esta? Certamente não tenho uma boa resposta.

(A propósito, não tenho acesso fácil à essência, então, se houver algum conteúdo lá que não esteja em seu resumo, foi esquecido).

Eu sei que é um trabalho difícil escrever um PR, e desmotivador que pareça atolar em debates e perguntas, mas no final das contas, acho que alguém vai ter que escrever um e colocá-lo lá fora como "esta é a solução Eu proponho - algum comentário? "

Não devemos fazer atualizações diferentes de instalações [recorte]. Provavelmente, sempre desejarei pip upgrade --only-binary na primeira instância, mas quero que seja explícito.

Se você provavelmente sempre quer algo, deve ser o padrão 1 . Mas acho que manter a consistência entre install e um possível comando upgrade é uma boa ideia.

Não tenho certeza do que você quer dizer sobre "reter" atualizações.

Vou deixar isso de lado até chegarmos ao ponto de falar sobre como adicionar a funcionalidade de atualização completa.

nota para mim mesmo: apt-mark concepts for pip

Estou -1 em tornar o comando interativo. A menos que haja um problema específico sobre o qual o usuário precisa tomar uma decisão

Idem.

Não é esse o principal tópico de debate nas várias discussões deste recurso?

Exatamente por isso que queria saber o que vocês pensam.

Não me lembro de ter havido uma resolução para essa questão, então estou um pouco surpreso que você espere uma resposta "simples" para esta?

Não espero uma resposta "simples" ainda. Espero que cheguemos a uma resposta, de preferência simples, por meio de discussão.

A propósito, não tenho acesso fácil à essência, então, se houver algum conteúdo lá que não esteja no seu resumo, perdi, desculpe

Mais do que um resumo, é um acompanhamento do write-up. Por favor, leia assim que puder.

Escolha aquela que você achar que é a melhor opção, implemente e veremos como funciona a partir daí.
[recorte]
Eu acho que alguém vai ter que escrever um [PR], e publicá-lo como "esta é a solução que eu proponho - algum comentário?"

Eu estava pensando ao longo das linhas de "vamos descobrir exatamente o que queremos primeiro" e, em seguida, prosseguir e implementar isso.


1 a menos que destrua o mundo de outra pessoa

Não devemos fazer atualizações diferentes de instalações [recorte]. Provavelmente sempre desejarei atualização pip - apenas binário na primeira instância, mas quero que seja explícito.
Se você provavelmente sempre quer algo, deve ser o padrão. Mas acho que manter a consistência durante a instalação e um possível comando de atualização é uma boa ideia.

Se _todo mundo_ provavelmente sempre quer algo, isso (talvez) deveria ser o padrão. Mas eu estava apenas comentando sobre minhas próprias preferências. Sinceramente, não tenho ideia se --only-binary é o que a maioria das pessoas deseja (provavelmente depende se estamos falando de longo ou curto prazo).

Há uma grande diferença entre binários (rodas), fontes que podem ser construídas em qualquer lugar (normalmente Python puro) e fontes que precisam de um compilador ou outros pré-requisitos externos. Infelizmente, pip não consegue distinguir os dois últimos, e isso torna --only-binary menos útil (principalmente como padrão).

E eu valorizo ​​a consistência entre os comandos sobre os padrões "faça o que quero dizer", o que, novamente, pode ser apenas minha preferência pessoal.

Mais do que um resumo, é um acompanhamento do write-up. Por favor, leia assim que puder.

Eu li isso, não acrescentou muito que eu não soubesse (visto que acompanhei os vários tópicos sobre isso), então meus comentários permanecem. Mas é um bom resumo da situação, então obrigado por escrevê-lo.

Não devemos fazer atualizações diferentes de instalações [recorte]. Provavelmente sempre desejarei atualização pip - apenas binário na primeira instância, mas quero que seja explícito.

Se você provavelmente sempre quer algo, deve ser o padrão. Mas acho que manter a consistência durante a instalação e um possível comando de atualização é uma boa ideia.

Se _todo mundo_ provavelmente sempre quer algo, isso (talvez) deveria ser o padrão. Mas eu estava apenas comentando sobre minhas próprias preferências.

Esclarecimento: O "você" em meu comentário se referia aos usuários finais (plural), sendo @pfmoore um nesse caso específico. Eu realmente deveria ter usado alguma outra palavra.

Algumas reflexões sobre estratégias de upgrade. Opinião pessoal, tudo isso, claro :-)

Suponha que eu faça pip upgrade foo

  1. Se eu não tiver foo instalado no momento, espero um erro. Para mim, "instalar" e "atualizar" são duas atividades separadas que não desejo mescladas.
  2. Se não houver versão disponível mais recente do que a instalada atualmente (veja abaixo re --only-binary ), espero uma notificação informando que não há nada a fazer.
  3. Caso contrário, espero que foo seja atualizado para a versão mais recente. Isso é o que eu pedi, então deve acontecer.

    • Não estou convencido de que adicionar restrições faça sentido. O que pip upgrade foo>1.0 significaria se eu tivesse 1.1 instalado, mas 1.2 está disponível? Não é uma atualização se deixar 1.1 lá, mas se for atualizado para 1.2, é o mesmo que pip upgrade foo . Possivelmente você poderia atribuir significado a algo como pip upgrade foo<2.0 mas, IMO, isso seria um caso muito incomum e não vale a pena a complexidade. Portanto, vamos supor que pip upgrade apenas pegue uma lista de nomes de pacotes (em oposição aos requisitos).

    • Da mesma forma, não sei como interpretar pip upgrade <path_to_archive/wheel> . Vamos supor que não seja permitido na primeira instância.

  4. Posso ou não permitir que o pip tente construir a partir da fonte (isso deve ser uma decisão do usuário, já que pip não pode dizer se a construção a partir da fonte vai funcionar, e não tem capacidade para tentar novamente com uma versão diferente se um a compilação do código-fonte falha). Portanto, --only-binary deve ser uma opção do usuário e, se especificado, significa que o pip deve ignorar a distribuição do código-fonte ao determinar "o que está disponível". (Podemos, é claro, usar como padrão apenas binários e ter uma opção --allow-source , mas de qualquer forma upgrade deve corresponder a install neste aspecto).

OK, então isso é tratado com os pacotes especificados explicitamente. Duvido que haja algo controverso aí (exceto talvez pelas partes que eu digo que devemos omitir até mais tarde). Agora nas dependências.

  • A regra principal em minha mente é que nunca devemos fazer nada com as dependências, a menos que estejamos _atualmente_ atualizando o pacote especificado pelo usuário. Então esse é o ponto de partida. Se o destino não for atualizado, nem mesmo olhe para as dependências. Sempre.
  • Minha opinião seria que _todas_ as dependências devem ser tratadas da mesma maneira - se são dependências diretas ou indiretas do pacote especificado pelo usuário, é irrelevante. Não acho isso controverso.
  • Uma suposição fundamental aqui deve ser que o usuário não sabe o que é a lista de dependências. Afinal, o objetivo de ter dependências implícitas é para que o usuário _não_ tenha que gerenciá-las. Portanto, qualquer solução que precise que o usuário saiba explicitamente sobre uma dependência é falha, na minha opinião (a menos que um comando falhe com uma mensagem sobre uma dependência específica, caso em que o usuário pode executar novamente com essa dependência especificada em uma opção - mas devemos procurar trabalhar pela primeira vez em tantos casos quanto possível, então isso não deve ser visto como a norma).
  • Eu diria que, por padrão, a abordagem deve ser apenas atualizar as dependências que _têm_ que ser atualizadas para satisfazer as novas restrições. Há um problema desagradável à espreita aqui, pois as restrições podem mudar dependendo do que for atualizado. Mas se fazemos uma solução completa para esse problema ou simplesmente tentamos alguma solução de "melhor esforço" não é tão importante (duvido que gráficos de dependência complexos com restrições conflitantes sejam comuns na vida real). O ponto importante é o princípio de que não atualizamos nada que o usuário não tenha solicitado, a menos que seja necessário.
  • Ter um sinalizador dizendo "atualize tudo para a versão mais recente" pode ser útil (para compatibilidade com versões anteriores, pelo menos). Ainda melhor seria ter ferramentas (provavelmente externas ao pip) que analisam e relatam as opções de atualização. Então, os usuários podem decidir por si próprios. Mas eu não sei se eu mesmo veria a necessidade de qualquer uma dessas opções.
  • Em vez de uma opção de "atualização antecipada", é muito mais provável que eu deseje um comando upgrade-all (ou upgrade --all se quisermos manter um único comando). Deve ser semanticamente idêntico a upgrade com todos os pacotes instalados listados na linha de comando. Uma vez que estou fazendo atualizações cegas de pacotes (normalmente posso não saber ou ter documentado a árvore de dependências de meus pacotes), provavelmente só quero "tudo". Ainda mais se eu usar ambientes virtuais para isolar as coisas.
  • A pergunta --only-binary aparece novamente aqui. Certamente, se o usuário especificar --only-binary para a atualização principal, as dependências devem ser assumidas como implicando --only-binary . Mas mesmo se o usuário permitir instalações de origem ao atualizar o pacote principal, a introdução do risco de falha envolvida em fazer uma atualização de origem de uma dependência parece irracional. Portanto, sugiro que devemos sempre considerar binários para atualizar dependências, a menos que o usuário permita explicitamente o código-fonte. Isso implicaria na necessidade de uma opção --allow-source dep1,dep2,... . Espero que esta proposta seja controversa, mas considere um pacote Python puro foo que é distribuído apenas na forma de código-fonte, que depende do numpy. Temos foo 1.0 dependendo de numpy> = 1,10 e foo 2.0 dependendo de numpy> = 1,11. O usuário tem foo 1.0 e deseja atualizar. Eles não têm meios para construir entorpecentes. Eles têm que permitir atualizações de código para foo, mas não querem perder tempo tentando construir o numpy 1.11 (ou pior ainda, construí-lo pode funcionar, mas dá uma construção não otimizada, que quebra o sistema). Eles podem, é claro, especificar --only-binary numpy mas podem nem estar cientes de que foo depende de numpy.

É sobre isso. Para mim, os requisitos são bastante claros (e honestamente, não acho que sejam particularmente controversos se ignorarmos os problemas de implementação). No entanto, a implementação é o assassino aqui (basicamente o exposto acima exige uma abordagem de solucionador SAT completa, conforme discutido anteriormente). Os compromissos que estamos dispostos a fazer, porque implementar um solucionador SAT é muito difícil, é onde provavelmente ocorrerão os debates.

Pelo que eu sei, os seguintes serão os desafios de implementação:

  1. Um solucionador SAT completo é difícil. Não sei o suficiente para entender quais alternativas são mais simples e como elas diferem de um solucionador SAT. (Bem, a atualização antecipada é, creio eu, simples o suficiente - é por isso que é o que fazemos no momento). Especificamente, quando chegarmos a uma situação em que atualizamos algo que o simples princípio "não atualize nada que você não precisa" diz que não deveria ter sido atualizado.
  2. Eu encostei tudo, menos as restrições de dependência mais básicas. Uma vez que nos envolvemos em limites superiores de versões, ou listas de versões permitidas, as coisas ficam feias. Mas, realisticamente, esses casos são provavelmente muito raros (adoraria que alguém fizesse pesquisas sobre as informações reais de dependência do PyPI - posso tentar fazer isso, mas duvido que consiga tempo).
  3. Quando temos vários alvos - pip upgrade a b c - tratamos isso como 3 ações separadas, "atualizar a", depois "atualizar b" e depois "atualizar c", ou mesclamos os 3 em um único "combinado" ação de alguma forma (note que porque eu proponho tratar dependências diferentes dos alvos, isso _não_ é o mesmo que pip upgrade dummy onde dummy depende de a, bec e assumimos que o dummy foi atualizado).

Se alguém quiser contestar qualquer um dos comentários ou afirmações acima, ótimo. A maior parte disso é apenas minha opinião, e eu honestamente não trabalho em ambientes complexos - meu uso provavelmente será principalmente sobre como manter uma instalação de sistema e alguns ambientes virtuais no Windows (portanto, debates sobre instalações binárias versus instalações de origem são importantes para mim, mas gráficos de dependência complexos nem tanto). Quanto mais casos de uso pudermos comparar nossas suposições, melhor.

Portanto, atualmente temos duas operações, pip install e pip install --upgrade . No entanto, acho que ambas as coisas fazem algo que ninguém realmente deseja que aconteça na vida real.

Por pip install , temos esse tipo de comportamento estranho onde você pode obter a versão mais recente (ou não!) Com base no que já está instalado em seu sistema. Acho que esse tipo de esquisitice torna o pip mais difícil de usar e não acho que faça muito sentido (em qual situação você se importaria em não atualizar, mas ainda deseja instalar o mais recente, se ainda não tiver isto?). Acho que o fato desse comando ter esse comportamento estranho talvez-mais-talvez-não é a razão pela qual vemos muitas pessoas buscando pip install ---upgrade como seu comando principal, em vez de pip install .

No entanto, pip install --upgrade não é muito melhor, embora forneça um comportamento consistente, é excessivamente ansioso e se estende a uma atualização completa de _tudo_ que o usuário pode nem estar ciente que estará implicado em seus pip install --upgrade comando

O que eu acho que devemos fazer aqui, é descobrir um caminho para fazer `pip install ... more consistent. In that I mean pip install deve sempre acabar tendo a última versão aceitável (especificadores dados e sinalizadores de modificador como - only-binary ``) independentemente do que foi instalado anteriormente.

Eu acho que dar a este comando algum tipo de comportamento --eager ou --recursive ou --upgrade-all-the-things seria bom.

Não acho que um comando pip upgrade que leva uma lista de pacotes seja algo que devamos fazer. Acho que se adicionarmos esse comando, ele deve ser usado para simplesmente atualizar tudo instalado para as versões mais recentes (levando em conta as informações da cadeia de dependências, bem como modificadores como --only-binary ).

Huh? Portanto, pip install foo nem sempre falha se foo estiver instalado? Isso parece errado para mim, eu esperaria apenas dizer "já instalado".

Não gosto da ideia de pip install ser "instalar ou atualizar". Melhor ser explícito e tudo isso.

No momento pip install foo nunca "falha" com base em se algo está instalado ou não, ele simplesmente não fará nada e dirá que o X já está instalado. Minha afirmação é que o comportamento não é muito útil. "Afirmar que alguma versão, qualquer versão que esteja instalada" não parece ser um comportamento útil para mim. Também não corresponde a outros gerenciadores de pacotes que estou acostumado a gostar de apt-get ou algo assim.

OK, posso ver que o comportamento não é útil (embora pessoalmente ache aceitar silenciosamente "já instalado" como bastante inócuo). Mas eu prefiro ver a instalação de um pacote já instalado falhar, em vez de fazer com que ele seja atualizado.

O que você esperaria que pip install foo-1.0-none-any.whl fizesse se o foo 2.0 já estivesse instalado? Fazer downgrade? Silenciosamente, não faz nada? Prefiro ver um erro simples e simples de "já instalado" do que um conjunto complexo de regras que duvido que as pessoas se lembrem na prática.

Não tenho muita experiência com gerenciadores de pacotes Linux, então não posso comentar sobre as semelhanças (ou não) com pip. Mas não acho que esperaria que apt-get install foo atualizasse, então, se você diz que sim, só posso responder que também acho isso estranho.

"Afirmar que alguma versão, qualquer versão que esteja instalada" não parece ser um comportamento útil para mim.

Uma rápida pergunta lateral sobre isso: Que tal "Assegurar que esta versão específica está instalada"?

Esqueça, temos esse comportamento hoje.

@pfmoore :

O que você espera que o pip install foo-1.0-none-any.whl faça se o foo 2.0 já estiver instalado? Fazer downgrade? Silenciosamente, não faz nada? Prefiro ver um erro simples e simples de "já instalado" do que um conjunto complexo de regras que duvido que as pessoas se lembrem na prática.

Huh, as expectativas são coisas surpreendentes. Eu diria que _obviamente_ neste caso, o pip deve fazer o downgrade. O usuário disse de forma completamente explícita que deseja que o pip instale esta roda em particular, portanto, o pip deve instalar essa roda em particular. Não há nada de complexo nisso. Mas o caso do "caminho / arquivo de distribuição é fornecido explicitamente" é # 536 - provavelmente devemos manter esta discussão focada mais no que acontece se o usuário disser "pip install foo", que vai para o índice do pacote e encontra um foo 2.0, quando o foo 1.0 já está instalado.

Eu concordo plenamente com a posição de Donald aqui. Se começarmos com a pergunta "o que pip install fazer?", Então posso ver como alguém pode argumentar que, bem, diz 'instalar' no nome, então deve apenas instalar coisas, nunca atualizá-las ( bem, exceto quando houver alguma restrição). Mas se começarmos com a pergunta "quais operações os usuários querem?", Então um comando que pode instalar a última, ou pode deixar você com uma versão antiga, é realmente estranho e contra-intuitivo. Afirmo que em 99% dos casos em que os usuários digitam pip install x , é porque eles (a) não têm certeza se está instalado ou sabem que não está, E (b) querem ter certeza de que eles instale-o porque eles estão prestes a começar a usá-lo pela primeira vez. (Se não fosse a primeira vez, eles saberiam que estava instalado, portanto, não executariam pip install .) Nessa situação, fornecer a versão mais recente é a coisa certa a fazer.

@nchammas :

Que tal "Assegurar que esta versão específica está instalada"? Isso me parece útil, ter um comando de instalação idempotente.

Para "versão específica" há pip install x==<version> .

Também posso imaginar que, para alguns tipos de uso de script / programático, pode ser útil ter um comando pip require x que tenha a mesma semântica de instalar um pacote com Dist-Requires: x , ou seja, garante que alguns versão está instalada, mas sem garantias sobre o quê. Mas este seria um comando de nível inferior não destinado a usuários finais.

Uma maneira de pensar sobre a diferença entre eles: se x não estiver instalado, então pip require x pode instalar alguma versão antiga aleatória. (E , diabos, talvez devesse, para forçar as pessoas a serem robustas contra isso .) Mas ninguém jamais aceitaria pip install x instalar alguma versão antiga aleatória.

(Este é um experimento de pensamento, na verdade não estou defendendo que Dist-Requires: x ou pip require x em um ambiente sem x deve escolher uma versão antiga aleatória de x para instalar.)

Bem, eu acho que há também um outro caso em que os usuários digitam pip install x , que é quando eles já sabem que está instalado, mas estão acostumados com sistemas com o comportamento de estilo Debian em que install sempre atualiza . Obviamente, esses usuários também querem que ele atualize :-).

Prefiro não adicionar um comando pip upgrade .

os usuários do pip já têm algumas expectativas em relação ao comportamento do pip.
O principal ponto problemático vem do comportamento padrão de pip instal --upgrade , então vamos nos concentrar nisso.

Um aviso no pip 9, além de opções adicionais para ajustar o comportamento de pip install --upgrade , (--eager / non-eager) seguido no pip 10 por uma mudança em seu comportamento padrão parece simples o suficiente, deve remover a dor principal origem e não quebra o modelo mental dos usuários do pip.

Sim, estou definitivamente tentando abordar isso a partir de "quais operações um usuário deseja fazer" versus "quais operações o comando X deve fazer". Estou então realizando esta operação de alto nível que _choque_ os usuários desejam fazer e tentando mapeá-la para um único comando nomeado (por mais explícito que seja, pip install-the-latest-version`` não é muito amigável) .

Obviamente, tudo isso é muito confuso, mas posso dizer que 99% das vezes o que faço é pip install -U <whatever> porque isso corresponde melhor ao que espero de um instalador, dado o que está disponível atualmente. Também vejo em vários scripts de automação pessoas usando pip install -U . É também o que outros gerenciadores de pacotes populares para idiomas fazem por padrão, como o npm. Nos casos em que vejo pessoas não usando -U , é por causa da natureza recursiva do mesmo, não porque eles não querem a versão mais recente das coisas instaladas.

os usuários do pip já têm algumas expectativas em relação ao comportamento do pip.

TBH, porém, a principal expectativa que tenho sobre o pip como um usuário é que em cerca de 50% das invocações ele fará algo surpreendente e obviamente errado. E eu não sou o único - ver, por exemplo @glyph 's palestra na PyCon na semana passada, onde ele observou que pip é grande, exceto que todos os padrões são quebrados e requerem desquebrar-me bandeiras. Esta não é uma crítica aos desenvolvedores do pip, eu entendo que você / todos nós estamos trabalhando sob um conjunto complexo de restrições, e não é um argumento que devemos apenas quebrar as coisas quer queira ou não, só por quebrá-las - pip tem muitas peças e muitas delas estão bem! Mas dado o estado geral dos padrões do pop, eu _realmente_ não estou convencido por argumentos da forma "pip sempre fez X, portanto pip deve sempre fazer X". Se você quiser defender que o pip install se recuse a atualizar, isso é legal, mas eu prefiro ver esse argumento baseado nos méritos reais, não apenas na inércia.

Sim, certamente concordo com @njsmith e @glyph aqui. Temos uma série de comportamentos inadimplentes inadequados, e acho que parte do progresso deve ser descobrir como podemos nos livrar deles e lidar com essas mudanças significativas para mover as coisas em direção a padrões melhores.

Essa mudança específica pode não ser uma delas, mas acho que é.

Sim, estou definitivamente tentando abordar isso a partir de "quais operações um usuário deseja fazer" versus "quais operações o comando X deve fazer". Estou, então, pegando essa operação de alto nível que acho que os usuários desejam fazer e tentando mapeá-la para um único comando nomeado (por mais explícito que seja, pip install-the-latest-version`` não é muito amigável) .

OK. Suponha que eu esteja disposto a me considerar convencido (um pouco) sobre isso. No entanto, se presumirmos que essa é a coisa certa a fazer, e quanto às dependências? Estou 100% convencido de que "tentar instalar o numpy da fonte" quase sempre não é o que se espera. Portanto, só instalamos o numpy das rodas, a menos que o usuário mencione explicitamente o numpy. Por agora, considere isso como um dado adquirido e, em seguida, suponha que temos a situação que descrevi anteriormente.

  • O usuário tem foo 1.0 e numpy 1.10 instalado, foo 1.0 depende de numpy> = 1.10
  • PyPI tem foo 2.0 disponível, depende de numpy> = 1.11. Não há rodas 1.11 entorpecidas.

O que pip install foo faz? Presumivelmente, deixe o usuário em 1.0, já que é uma instalação funcional? Mas deve ser bem-sucedido (já que o foo está instalado) ou falhar (já que não foi possível instalar a versão mais recente)? No primeiro caso, como o usuário descobre que seu sistema está desatualizado? Se for o último, como o usuário dirá "Eu só quero ter certeza de que foo está lá"? OK, o usuário pode fazer pip list --outdated , ver que foo 2.0 existe e fazer pip install foo (a propósito, isso ainda me parece totalmente estranho, tenho foo, mas sei que há uma nova versão, então Eu faço a instalação do pip ??? Deixa pra lá ...) E teve sucesso, mas o 1.0 continua instalado?

Um dos motivos pelos quais prefiro dois comandos é que a intenção do usuário é completamente clara, de modo que casos extremos como esse podem ser tratados corretamente porque conhecemos a expectativa do usuário.

Talvez tudo isso seja óbvio se você estiver acostumado com o apt-get. Mas posso dizer com certeza que não está claro para alguém como eu quem não é.

Se você quiser defender que o pip install se recuse a atualizar, isso é legal, mas eu prefiro ver esse argumento baseado nos méritos reais, não apenas na inércia.

Meu argumento é mais explícito do que implícito. Definitivamente _não_ em "sempre fizemos assim". Não tenho nenhum problema com a ideia de que talvez os usuários do apt estejam acostumados a "instalar", o que significa "possivelmente atualizar". Eu realmente não tenho certeza de que outros usuários estariam.

Um pensamento - o apt tem um "pacote já existe - atualização?" mensagem? Eu poderia imaginar a instalação como atualização sendo menos surpreendente para mim se fosse "instalar ou perguntar se eu deveria atualizar" ... Claro, pip não se comporta interativamente dessa forma no momento, embora obviamente, fazê-lo é uma opção.

Essa é uma questão interessante-- Outros gerenciadores de pacotes geralmente contornam isso por não ter pacotes binários, então é _sempre_ pelo código-fonte, ou por basicamente lidar apenas com pacotes binários então é _sempre_ binário. Estamos em uma espécie de meio estranho que torna tudo mais difícil.

Dado isso, acho que por padrão por agora, devemos puxar para baixo o pacote fonte 1.11 numpy e tentar instalá-lo, mas se eles especificaram --only-binary , então nosso resolvedor hipotético (que precisamos desesperadamente, SAT ou back tracking ou qualquer outra coisa) veria que foo-2.0 não é uma instalação resolvível e então voltará a instalar foo-1.0 . Este não é um bom padrão, principalmente para usuários do Windows, onde a compilação é _muito_ mais difícil, mas acho que reflete a realidade de hoje.

Dito isso, uma coisa que eu realmente quero fazer é começar a tentar empurrar as coisas em direção a um mundo onde possamos mudar o comportamento do pip novamente para que, por padrão, possamos ser apenas binários e exigir ativação para versões de código-fonte, mas eu não pense que ainda estamos em um lugar em que podemos fazer isso.

@pfmoore : Eu acho que a questão de instalações binárias versus instalações de origem é um tanto ortogonal? Parece-me que as mesmas perguntas surgem para um comando pip upgrade dedicado, então, embora sejam problemas reais que precisamos resolver, dividir atualização e instalação apenas move os problemas ao invés de simplificá-los? Além disso, no caso particular do numpy, agora enviamos rodas para basicamente todas as plataformas para as quais nos preocupamos em oferecer suporte :-).

Mas aqui está como eu sugeriria lidar com esses problemas para pip install foo (especificamente este comando - não estou falando sobre pip install foo==whatever ou pip install ./foo-*.whl ou pip install bar where bar tem Requires-Dist: foo ):

1) Consulte o índice para encontrar a versão candidata mais recente de foo ; chame isso de $LATEST . Se não houver nenhuma versão candidata, haverá um erro.

2) Se $LATEST já estiver instalado, termine com sucesso.

3) Verifique se existe uma distribuição de $LATEST que pode ser instalada no ambiente atual. (Exemplos de motivos pelos quais pode não haver: há apenas rodas, mas não sdist, e as rodas não correspondem ao ambiente atual. Não há nenhuma roda correspondente e há um sdist, mas o usuário passou --binary-only :all: . Não há nenhuma roda correspondente e há um sdist, mas o sdist tem uma sinalização dizendo "Eu só trabalho em python 3" e o usuário está executando python 2 - o pessoal do ipython / jupyter provavelmente propor isso como um novo recurso em breve, b / c eles querem descartar o suporte a python 2 para novos lançamentos em janeiro, embora ainda forneçam um LTS compatível com python-2.)

4) Se $LATEST _não_ tem uma distribuição viável: emita um aviso para dizer ao usuário que uma versão mais recente está disponível, mas não para o seu ambiente, de preferência com uma dica do que eles precisam fazer se realmente fizerem deseja a nova versão (por exemplo, "ipython 6.0.1 está disponível, mas requer python> = 3.4, e você tem o python 2.7 - considere atualizar o python" ou "numpy 1.12 está disponível, mas não há binário para ppc64 e você tem construção desabilitada da fonte - considere --allow-source numpy ). Em seguida, remova $LATEST da lista de versões candidatas e vá para a etapa 1.

5) Se $LATEST _têm_ uma distribuição viável, tente instalar esta distribuição.

6) Se a instalação falhar (por exemplo, b / c é um sdist e não há compilador), então o erro será eliminado. Caso contrário, termine com sucesso.

@njsmith binary-only é um tanto ortogonal, de acordo, mas IMO, se estamos tentando projetar comandos que "fazem o que o usuário espera", é fundamental acertar ao mesmo tempo.

@dstufft o problema com "instalar numpy a menos que o usuário diga --binary-only foi explicado no exemplo em minha postagem épica anterior - (1) diga que foo está disponível apenas na forma de código-fonte, e (2) o usuário não pode (e de fato não deveria precisar) saber que foo depende de numpy. Então o usuário não pode dizer --only-binary :all: e não tem ideia de que precisa de --only-binary numpy até que _após_ uma (longa) compilação falhou. Ou (possivelmente pior ainda) uma compilação bem-sucedida que deixa o usuário com um numpy não otimizado (atualmente, o numpy compila fora da caixa no Windows, mas fornece uma compilação não otimizada).

Concordo totalmente que, a longo prazo, devemos usar como padrão apenas binário, mas não estamos nem perto disso ainda (no mínimo, isso deve implicar que praticamente todo pacote Python puro está disponível como uma roda).

@pradyunsg Como você pode ver, ainda há muitos problemas não resolvidos aqui. Você ainda está interessado em levar isso adiante? Estou relutante em iniciar outro longo debate se ele simplesmente parar de novo ...

@pradyunsg Como você pode ver, ainda há muitos problemas não resolvidos aqui. Você ainda está interessado em levar isso adiante? Estou relutante em iniciar outro longo debate se ele simplesmente parar de novo ...

Eu esperava que houvesse. Estou interessado em levar isso adiante. Vamos fazer isso! :sorriso:

Sugiro coletar uma lista com tudo o que um _usuário_ deseja que o pip faça e, em seguida, propor soluções para cada um deles até que todos (ou uma quantidade suficiente) sejam resolvidos por um comando pip (com opções / padrões) ou possam ser tratados com "nenhuma ação".

Para começar, aqui está uma lista provavelmente incompleta:

  1. Um usuário deseja instalar um pacote que ainda não está instalado.
  2. Um usuário tenta instalar um pacote que já está instalado.
  3. Um usuário deseja atualizar um pacote que está instalado.
  4. Um usuário tenta atualizar um pacote que não está instalado.
  5. Um usuário deseja garantir que possui a versão mais recente de um pacote instalado, quer já tenha sido instalado ou não.
  6. Um usuário geralmente não deseja que todas as dependências sejam atualizadas e, em vez disso, que apenas sejam satisfeitas.
  7. Um usuário deseja atualizar / instalar um pacote, mas não deseja compilá-lo a partir do código-fonte (nem o pacote nem suas dependências). Provavelmente mais provável do que:
  8. Um usuário deseja atualizar / instalar a partir da fonte.

Minhas propostas pessoais para isso, como usuário:

1) e 7) pip install foo deve tentar resolver para a versão mais recente disponível (considerando as dependências) e instalá-la. O algoritmo seria o de @njsmith .
2) pip install foo → mostrar um aviso de que foo já está instalado e propor o uso de pip upgrade foo
3) & 7) pip upgrade foo tenta instalar a última versão disponível de foo, novamente seguindo o algoritmo de @njsmith . Se uma versão mais recente não puder ser instalada porque não está disponível para a plataforma e não há sdist ou o usuário não deseja compilar a partir do código-fonte, mostre isso. É bem-sucedido em qualquer um dos casos e só falha se a própria instalação falhar.
4) pip upgrade foo falhará se o pacote não for instalado.
5) pip install-uprade foo ou pip install foo --ensure-latest ou pip install foo --upgrade (basicamente o mesmo que atualmente, exceto não ansioso).
7) Todas as operações devem ser não antecipadas e um sinalizador --eager estaria disponível para obter a funcionalidade antiga de install --upgrade . Se uma dependência ainda não estiver instalada, instale a mais recente. Se já estiver satisfeito, não faça nada. Se não estiver satisfeito, instale a versão mais recente ainda satisfatória (para requisitos de limite superior).
8) pip upgrade foo --allow-source ou pip upgrade foo --allow-source numpy , se foo depender de lançamentos numpy não binários. Edit: Não sei se isso seria aplicável, veja o comentário abaixo.

Sinta-se à vontade para ampliar a lista e postar suas próprias propostas.

@pfmoore Não tenho certeza de qual é a alternativa? O estado do mundo hoje é que as rodas estão ganhando terreno, mas não estão nem perto de serem onipresentes, então não tenho certeza se realmente vejo uma boa opção que não permite lançamentos de código-fonte por padrão agora.

@dstufft minha proposta era permitir o código fonte para pacotes explicitamente nomeados, mas o padrão era apenas binários para dependências. Dessa forma, o usuário não obtém etapas de construção "surpresa". É um compromisso, com certeza, mas reflete o que eu (tenho que) fazer manualmente no momento.

@FichteFoll Acima de tudo, meu principal caso de uso é para um recurso de "atualizar tudo". Procure tudo o que está instalado atualmente e, se houver versões mais recentes disponíveis, atualize-as.

Os pacotes que instalei normalmente não têm nada além de dependências "> =" (e a maioria nem tem isso), então não há nada complexo aqui. Basta pegar a versão mais recente. Minha maior restrição é que existem alguns pacotes que não posso construir (numpy, scipy, lxml, pyyaml, matplotlib, pyqt), então só quero binários para eles. Provavelmente posso colocar --only-binary <these> no meu pip.ini (ou pelo menos espero poder ...)

Secundário: Instale o pacote XXX (versão mais recente), mais qualquer uma de suas dependências que eu ainda não tenha. Não atualize dependências que eu já possuo se elas satisfizerem as restrições do novo pacote. Sempre sei que não tenho XXX no momento.

Terciário: Atualizar um único pacote XXX que eu (sei que) instalei. Não altere nenhum outro pacote, a menos que seja necessário para manter as restrições de dependência (e mesmo isso é teórico - nunca encontrei essa situação na vida real, então não sei qual seria a melhor resolução para mim). Minha intenção é sempre "atualizar para a versão mais recente". Nunca encontrei uma situação em que isso quebrasse dependências de pacotes já instalados. Se foi, eu _penso_ que gostaria de receber um aviso de que não recebi a versão mais recente (e por quê), além de uma atualização para a versão mais recente que seja aceitável. Em minha mente, essa situação atualmente se traduz em pip install -U embora o comportamento das dependências não seja o que desejo. No entanto, o principal motivo pelo qual eu faria isso é a falta atual de um "upgrade all" adequado (ou para lidar com casos em que um novo comando "upgrade all" não funcionou como eu queria).

Toda a discussão sobre dependências e restrições é, em minha experiência, quase inteiramente teórica. Atualmente, tenho 160 pacotes instalados em meu sistema Python (uma mistura de módulos científicos, de análise de dados, web e programação geral). 100 deles não têm requisitos. Para o restante, nenhum tem nada mais complexo do que uma lista de pacotes - nenhuma restrição de versão ou nada mais complexo do que Requires: six, dask, pillow, networkx . A lista mais longa de dependências tinha 9 itens.

@pfmoore Isso não vai quebrar muitas coisas? Uma lista rápida de coisas que posso pensar de início e que sei que são pacotes muito populares depende de:

  • SQLAlchemy (opcionalmente requer um compilador; caso contrário, usará Python puro).
  • PyYAML (opcionalmente requer um compilador; caso contrário, usará Python puro).
  • Markupsafe (opcionalmente requer um compilador; caso contrário, usará Python puro).
  • PyCrypto (sempre requer um compilador)
  • pycparser (nunca requer um compilador)
  • httpplib2 (nunca requer um compilador)
  • anyjson (nunca requer um compilador)
  • zope.interface (opcionalmente requer um compilador; caso contrário, usará Pure Python).
  • docopt (nunca requer um compilador)
  • Mako (nunca requer um compilador)
  • é perigoso (nunca requer um compilador)
  • amqp (nunca requer um compilador)
  • orderdict (nunca requer um compilador)

e assim por diante, você pode ver uma longa lista dos pacotes mais populares e se eles têm rodas em http://pythonwheels.com/.

@pfmoore

Procure tudo o que está instalado atualmente e, se houver versões mais recentes disponíveis, atualize-as.

Eu obtive este comando a partir de alguma pergunta do SO há algum tempo que estou usando atualmente para isso. É abaixo do ideal, mas funciona para a maioria dos meus pacotes, exceto um. (Ele usa o iniciador py porque estou no Windows.)

pip list -o | cut -d " " -f 1 | xargs -n1 py -m pip install -U

Agora, o único problema que tenho com isso é o pacote flake8, que tem estes requisitos:

Requires-Dist: pyflakes (>=0.8.1,<1.1)
Requires-Dist: pep8 (>=1.5.7,!=1.6.0,!=1.6.1,!=1.6.2)
Requires-Dist: mccabe (>=0.2.1,<0.5)

Especificamente, o pyflakes é um problema, pois tem uma versão mais recente disponível e é atualizado com o comando acima, fazendo com que o flake8 falhe em qualquer coisa (já que verifica a versão).
Portanto, isso é realmente algo que precisa ser considerado e eu também gostaria de ter a funcionalidade de atualização completa adequada (sem quebrar os requisitos!).

@dstufft por quê? Se foo depender de pyyaml ​​e eu pedir para atualizar foo, pyyaml ​​não será atualizado (sem novos binários), mas foo ainda pode ser atualizado, pois ainda há o pyyaml ​​original presente.

Para novas dependências (ou na instalação onde uma dependência não está sempre presente) você deve instalar, então se não houver binário, você obtém o código-fonte. Eu pessoalmente consideraria "escolher uma versão mais antiga com binário em vez de uma versão mais recente com código-fonte", mas isso está ficando perigosamente perto de padronizar para --binary-only qual concordo que não estamos prontos.

Hmm, talvez o problema que eu tenho seja realmente com a opção --only-binary , que é muito grosseira. Se tivéssemos uma opção --prefer-binary , que dizia "use apenas binários, a menos que isso signifique que não haja candidatos, caso em que tente novamente permitindo a fonte", suspeito que muitas das minhas preocupações de que uma atualização excessivamente ansiosa resultaria em quebra pode ser aliviado. O que, como @njsmith sugeriu, significa que as distinções binárias / fonte que estou focando podem muito bem ser ortogonais a este tíquete (embora mudasse minha posição para "não há solução satisfatória para meus requisitos sem algo melhor do que --only-binary estando disponível "...).

Especificamente, os flocos de neve são um problema

OK, então essa não é uma situação que eu tenho (como eu disse, não tenho nada com dependências tão complexas instaladas). Não tenho problemas em refinar "atualizar tudo" para atualizar as coisas para "a versão mais recente que não resulta em quebras", mas AIUI que precisa da abordagem de "solucionador de SAT" para encontrar a solução correta. No entanto, esse é um problema de implementação - o design deve sempre fornecer resultados corretos.

@pfmoore Acho que uma bandeira --prefer-binary pode ser uma boa opção, independentemente do resultado deste tíquete. Provavelmente empacotado com um aviso quando isso acaba não instalando a versão mais recente que de outra forma teria sido instalada.

@FicheFoll : Não acho que tentar recuperar toda a interface do usuário a partir dos primeiros princípios vai ser muito produtivo. Há uma parte do problema definida de forma relativamente clara que está no tópico desta questão em particular, e se tentarmos expandir o escopo para tudo de uma vez, então ele simplesmente travará novamente.

Nesse tópico, parece que o ponto principal da diferença é este: suponha que um usuário tenha o modelo mental de que pip install foo serve apenas para fazer a transição de coisas desinstaladas para instaladas e que eles entendam que foo já está instalado. Afirmo que um usuário com este modelo mental _nunca digitará pip install foo _. Portanto, quando algum usuário _faz_ digita pip install foo quando foo já está instalado, podemos concluir que o modelo mental dele não é como o seu (2). _Ou_ a primeira parte está errada: eles sabem que foo está instalado e esperam que o pip seja atualizado como alguns outros gerenciadores de pacotes populares, _ou_, a segunda parte está errada: eles não sabem que foo está instalado , nesse caso eles esperam que install deixe com a versão mais recente (porque é isso que o install faz quando os pacotes não estão instalados e eles acham que este pacote não está instalado).

Só para constar, uma das razões pelas quais não gosto de pip install ... apenas passar de desinstalado para instalado e pip upgrade ... apenas passar de instalado para algo mais novo instalado é porque eu encontro o usuário experiência muito ruim. Software que sabe o que você queria fazer, mas em vez de fazer isso, ele diz para você invocar algum comando diferente é incrivelmente frustrante.

$ pip install foobar
I'm sorry, but foobar is already installed, you want to run ``pip upgrade foobar``
$ pip upgrade foobar
...

Não faria nada por mim, exceto me irritar, mesmo que seja tecnicamente "correto".

O outro lado disso, se você disser "ok, se pip install foobar já tiver foobar instalado, então agiremos como se ele não estivesse instalado, e se você fizer pip upgrade foobar então nós vai agir como se já estivesse instalado, acabamos com dois comandos que fazem basicamente a mesma coisa, exceto com _talvez_ algumas pequenas diferenças em exatamente como as coisas são processadas, o que me diz que eles pertencem a um comando singular com alguns --options para lidar com os casos extremos. Eu acho que isso é melhor porque significa que os usuários não precisam tentar fazer uma escolha entre o que eles querem desde o início, há um comando para instalar as coisas e para a maioria dos usuários que irão geralmente fazem a coisa certa. Se algum usuário em um cenário específico exigir algumas escolhas de sua parte, ele terá que pagar o custo de fazer algumas escolhas sobre quais --flags usar.

OK. Considere-me convencido. Eu fiz algumas pesquisas, e até mesmo os instaladores do Windows que estou (supostamente :-)) familiarizados com a instalação como atualização (se você instalar algo como o VirtualBox, diz "você já tem uma versão anterior instalada, não é? deseja atualizar? ") O Powershell tem o pacote de instalação, que não diz nada específico, mas não há pacote de atualização. Etc. Então eu acho que apenas ter o único comando "instalar" é a norma.

O que, claro, significa que, a menos que alguém queira discutir, tecnicamente este PR pode simplesmente ser encerrado como "não vai ser implementado". Mas ainda é um lugar tão bom quanto qualquer outro para discutir _como_ queremos remodelar o comando de instalação, eu acho.

OTOH, talvez fechemos isso como rejeitado, e alguém abre um novo problema, com uma proposta concreta de como eles sugerem que o comando de instalação deve ser modificado. Pode pelo menos fornecer um ponto de partida mais claro para as discussões.

Uma pergunta. Alguém acha que ainda estamos em um ponto em que alguém poderia montar uma proposta completa de comportamento a partir de todas as sugestões aqui e em outros lugares? Cobrindo como as dependências são tratadas, o que acontece com as restrições (e quando elas entram em conflito), binário versus fonte, como oferecemos suporte ao cenário "atualizar tudo", etc? Meu sentimento pessoal é que precisamos de alguém para tomar essa decisão, para dar um ponto de referência à discussão, ou poderíamos apenas debater os detalhes para sempre. Eu provavelmente poderia fazer isso, mas é improvável que seja capaz de implementar o que proponho (por exemplo, eu proporia uma abordagem de "resolução de dependência ideal", que implica um solver SAT AIUI). Portanto, seria melhor para alguém que está disposto a implementar sua proposta se apresentar (e lidar com o debate inevitável e o desequilíbrio :-)).

Ainda estou preocupado com algumas das implicações nos pontos apresentados aqui, mas não tenho certeza se tenho energia para debatê-los até que haja uma possibilidade real de uma implementação.

Concordo plenamente com @dstufft 's mais recente https://github.com/pypa/pip/issues/59#issuecomment -224341218
É por isso que (mais uma vez) eu defenderia a solução simples de --eager / --non-eager options.

Também concordo com o comentário de @dstufft , conforme observado (optamos por um único comando install e nenhum comando update ).

No entanto, não tenho certeza do que --eager / --non-eager envolve. Acho que --non-eager significa não atualizar nada que não precise ser atualizado (ou porque o usuário especificou explicitamente ou porque é muito antigo para satisfazer o novo conjunto de dependências). --eager significa então atualizar cada dependência para a versão mais recente possível, seja necessário ou não? Qual seria o padrão? (Eu argumentaria por --non-eager )

E uma pergunta - isso encorajaria os pacotes científicos a declarar corretamente suas dependências? Isso tem que ser uma consideração importante.

Ponto de bicicleta. Os nomes de opções --eager e --non-eager são intuitivos. Acho que precisamos de melhores condições. Talvez algo explícito como --upgrade-dependencies .

Este PR também sugere um comando upgrade-all , que é o principal caso de uso para mim. Você está dizendo que rejeitamos esse comando ou simplesmente que não tem uma opinião sobre ele?

Meu entendimento do que --eager e -non-eager significam corresponde ao que @pfmoore acabou de dizer (sejam as dependências somente se necessário ou sempre instaladas), e eu concordo que --non-eager devem ser o padrão. Eu também concordo que o nome é meio ruim, embora eu não tenha uma solução melhor que não seja um bocado cheio. Talvez --[no-]recursive ou algo assim, não sei.

Acho que algo como um comando upgrade-all pode ser uma boa adição (desde que tenha certeza de não violar os especificadores de versão de nada). Eu provavelmente apenas chamaria isso de upgrade e não precisaria de argumentos para restringir em que opera.

tl; dr
Discussão por upgrade-all-packages - fique aqui.
Discussão para prefer-binário - Sobre para # 3785
Discussão para instalar como atualização - Sobre para # 3786


Se tivéssemos uma opção --prefer-binary, que dizia "usar apenas binários, a menos que isso signifique que não há candidatos, nesse caso tente novamente permitindo o código-fonte"

Essa é uma boa ideia. Embora relacionado a esse problema, acho que ele merece seu próprio problema. (o comentário de @dstufft me faz pensar que há interesse em prosseguir). Tomei a liberdade de abrir o número 3785 para uma discussão mais aprofundada sobre isso.

Meu entendimento do que --eager e -non-eager significa corresponde ao que @pfmoore acabou de dizer (se as dependências são apenas-se-necessárias ou sempre instaladas)

A atualização rápida instalaria as versões mais recentes permitidas de todas as (sub) dependências.

Os nomes das opções --eager e --non-eager não são intuitivos.

Eu concordo. Gosto da ideia de colocar o comportamento por trás de uma única bandeira.
--upgrade-strategy=eager/non-eager

É complicado também, mas transmite a intenção de forma mais explícita. É muito prolixo? Pode ser.

Eu acho que a retirada de bicicletas é melhor feita depois de finalizar a semântica.

Alguém acha que ainda estamos em um ponto em que alguém poderia montar uma proposta completa de comportamento a partir de todas as sugestões aqui e em outros lugares?

Eu penso que sim. Precisamos, pelo menos, estabelecer alguns fatos básicos com os quais concordamos. Eu estou nisso.

OTOH, talvez fechemos isso como rejeitado, e alguém abre um novo problema, com uma proposta concreta de como eles sugerem que o comando de instalação deve ser modificado. Pode pelo menos fornecer um ponto de partida mais claro para as discussões.

Acho que devemos deixar esse assunto em aberto por enquanto, porque ele propõe um upgrade-all . Você já observou que a atualização não está acontecendo. Abri # 3786 para uma discussão mais aprofundada sobre o comando instalar como atualização.

Ainda estou preocupado com algumas das implicações nos pontos apresentados aqui, mas não tenho certeza se tenho energia para debatê-los até que haja uma possibilidade real de uma implementação.

Estou disposto a levar isso adiante até a implementação. Definitivamente, não quero desperdiçar o esforço de todos para chegar a um consenso sobre isso.

Acho que todos concordam que seria muito bom ter um comando 'atualizar o mundo', mas o IIUC está bloqueado enquanto esperamos o funcionamento do resolvedor. Nesse ínterim, postei uma proposta mais concreta para atualizações de pacote único na nova edição dedicada de @pradyunsg para essa discussão.

Acho que todos concordam que seria muito bom ter um comando 'atualizar o mundo', mas o IIUC está bloqueado enquanto esperamos o funcionamento do resolvedor.

Na verdade, este problema agora está bloqueado corretamente por # 988. Mencionar o número do problema para vincular os dois problemas.

Eu quase esqueci...

Não tenho certeza do que você quer dizer sobre "reter" atualizações. Por favor, esclareça.

Agora que esse problema é exclusivamente para atualização, devo esclarecer.

Pode haver algumas situações em que pode ser útil evitar uma atualização de um determinado pacote quando executamos upgrade-all. O específico que tenho em mente é ... Se o pkg estiver instalado e eu não quiser me preocupar em reconfigurar uma potencial versão mais nova, então, quero evitar que o pip atualize esse pacote específico ao executar 'atualizar o mundo'. Basicamente, estou atrasando a atualização do pacote.

Uma sinalização que leva uma lista de pacotes separados por vírgulas para evitar uma atualização seria suficiente.

Adicionar isso assim que um solucionador SAT aparecer deve ser fácil. São apenas algumas cláusulas extras do IIUC. (Sim, também estou aprimorando os solucionadores de SAT)

Não sei se isso é algo comum ou algo que alguém deseja. Mas, eu não acho que isso se originou na minha cabeça. Alguém deve ter mencionado isso em algum tópico em algum lugar.

Ah, entendo. Isso faz sentido e parece uma coisa razoável de se desejar.

Solicitação rápida: alguém poderia adicionar à descrição uma pequena nota informando que o comando de atualização não acontecerá? Possivelmente, se você quiser, escreva um pequeno resumo de por que isso também acontece.

_vai dormir_

Dois bons recursos que o apt tem (e eu acho que outros gerenciadores de pacotes de sistema maduros como dnf têm recursos semelhantes):

  • Marcar um pacote como "retido", que é um sinalizador persistente anexado ao pacote e faz com que ele seja ignorado pelos comandos upgrade-the-world. Freqüentemente definido em pacotes que você teve que fazer downgrade ou patch local.
  • Rastreamento de quais pacotes foram explicitamente solicitados pelo usuário, contra quais pacotes foram instalados apenas implicitamente para cumprir as restrições de dependência. Estes últimos podem ser removidos por um upgrade-the-world se eles deixarem de ser dependentes.

Ambos podem ser vistos como casos especiais do que fazem os gerenciadores de pacotes de ambiente de projeto mais recentes, como npm e cargo, em que distinguem entre algum tipo de arquivo de "requisitos" orientado para humanos e um arquivo de "bloqueio" totalmente especificado. Um pacote mantido explicitamente é como um pacote que possui uma restrição de versão especificada por humanos, e um pacote explicitamente instalado é aquele que está listado no arquivo editável por humanos.

Idem. Se estamos adicionando 'atualizar o mundo', precisamos adicionar a capacidade de marcar pacotes (como held / user-installed e talvez mais) para adicionar informações para determinar melhor um curso de ação para as atualizações. Vejo isso como um requisito, não como algo bom de se ter.

Na verdade eu gosto da técnica usada pelo Cargo e gosta. O uso de arquivos e não de alguma forma de metadados ocultos por trás de um comando cli torna muito mais fácil de entender, gerenciar e também possível criar um ambiente reproduzível.

Eu ficaria realmente feliz se visse alguma forma de pyproject.lock ...

200º comentário. Uau. :risonho:

Adicionando referência a # 654 para "marcar" os pacotes dos quais falamos.

Você pode explicar o que a carga faz? Onde você veria o arquivo pyproject.lock sendo armazenado na máquina do usuário?

O arquivo de bloqueio do Rust's Cargo é armazenado na raiz do projeto, para registrar a versão das dependências atualmente instaladas. A confirmação desse arquivo para o git permite que você compartilhe um conjunto consistente de versões de dependência com outros desenvolvedores e CI. O Composer do PHP tem um arquivo de bloqueio semelhante, Composer.lock.

Eu sempre assumi que 'pip freeze' e 'pip install -r' do pip deviam fazer algo semelhante, e foi uma pena que o formato do arquivo de bloqueio fosse facilmente legível / gravável por humanos e as pessoas optassem por editá-lo diretamente. O requirements.txt não foi originalmente concebido como um arquivo de bloqueio?

@triplepoint Obrigado pela explicação. Isso realmente soa mais como um arquivo de requisitos. Mas os arquivos de requisitos são opcionais, baseados na versão e por projeto. A marcação (pelo que entendi) deve ser feita por ambiente (virtualenv ou instalação do sistema) e deve simplesmente dizer "não atualize automaticamente o pacote X" (mas permita a atualização manual se o usuário solicitar explicitamente uma atualização desse pacote pelo nome).

Para ajudar a desemaranhar as discussões sobre upgrade-all e "comportamento de atualização", aqui estão os comentários de @rbtcollins e @ncoghlan na discussão na lista deste último sobre um solucionador SAT não ser necessário para uma primeira implementação de upgrade-all :

Robert:

Percebo que o consenso sobre o tíquete é que está bloqueado, mas não
realmente concordo.

Sim, você não pode fazer isso _certo_ sem um resolvedor completo, mas você pode fazer
uma aproximação que seria muito melhor do que nada (apenas estreite
os especificadores fornecidos em todos os requisitos). Isso é na verdade
razoável quando você está lidando com um conjunto de versões consideradas boas
(com o qual a instalação não lida).

Usuario:

"yum upgrade" funcionou bem o suficiente por anos sem um solucionador SAT adequado, e o conjunto de pacotes em uma instalação típica do Linux é muito maior do que em um ambiente virtual típico (embora a distro curadoria reduza a probabilidade de requisitos conflitantes surgirem no primeiro Lugar, colocar).

Dito isso, reexecutar pip-compile e, em seguida, fazer um pip-sync já é um equivalente funcional de uma operação de upgrade-all (como destruir e recriar um venv), então concordo que não há necessidade de acoplar a questão de suportar upgrades em massa em pip de linha de base com a mudança do comportamento de atualização de componentes nomeados.

IMO, pip upgrade-all é de longe a proposta mais importante na mesa de todas as várias discussões de "funcionalidade de atualização". Ter "atualizar tudo" seria uma maneira óbvia de manter seu sistema atualizado, tornando as questões sobre atualizações não ansiosas que deixam as coisas em níveis anteriores muito menos urgentes, além de preencher uma lacuna que existe atualmente.

Embora um solucionador completo seja bom, não vejo razão para que o ponto de partida para pip upgrade-all não seja que ele faça o que pip install -U <list every package that's installed here> faz. Isso é o que eu esperava como usuário e, na maioria dos casos, ele faz exatamente o que é necessário. Os complexos casos de canto em torno de requisitos conflitantes podem ser tratados em primeira instância por referência ao acima. Se isso não for suficiente, podemos examinar a modificação do comportamento de install -U para resolvê-lo, ou criar um caso especial do comando update-all , ou até mesmo implementar um solucionador completo nesse ponto.

Você vai implementar isso nos próximos 10 anos?

FWIW, voltarei a visitar este fim de semana.


@magicgoose disse:
Você vai implementar isso nos próximos 10 anos?

@pfmoore disse isso melhor do que eu:

Estamos cientes de que as pessoas querem isso, o que está faltando é alguém disposto a desenvolver uma solução que atenda a todas as várias preocupações e problemas que já foram levantados e que inevitavelmente surgirão durante uma revisão de RP.

Portanto, pessoalmente, agradeceria se as pessoas evitassem fazer ping neste problema, a menos que tenham um código em funcionamento que pelo menos ofereça um ponto de partida para a implementação - e estejam dispostas a segui-lo até a implementação.

opinião inteiramente pessoal

eu acho que pela própria natureza do pip (que é instalar pacotes de um repo que não tem QA global como, digamos, debian, redhat ou ubuntu)
Eu acho que é necessário e / ou aceitável abster-se completamente de implementar e atualizar todas as funcionalidades,

já que garantimos sempre um estado obtido conhecido de um conjunto instalável de pacotes python

@RonnyPfannschmidt IMO é perfeitamente razoável para os usuários do pip proibir explicitamente o uso de um comando update-all, se isso se adequar aos seus requisitos / fluxo de trabalho. Mas nem todos os usuários do pip têm os mesmos requisitos rígidos que essas pessoas. Para usuários com necessidades mais relaxadas, um comando update-all é útil e sua falta torna significativamente mais difícil para eles manterem seus sistemas "atualizados". Portanto, acho que é razoável que o pip forneça esse comando. É nosso trabalho fornecer as ferramentas de que as pessoas precisam, não impor políticas específicas sobre como os usuários escolhem usar essas ferramentas.

@pfmoore minha experiência pessoal em apenas atualizar todos os pacotes em um ambiente é que isso quebra as coisas muito regularmente ^^

usuários que precisam de uma atualização tranquila, tudo soa como se você estivesse se referindo a usuários finais normais (que deveriam apenas usar uma distribuição normal do Linux, por exemplo)

Se atualizar tudo é problemático ou não, depende muito _muito_ de quantas dependências você tem e de quão disciplinados eles são sobre a manutenção da API. Ele também pode ser usado em conjunto com um repositório privado com curadoria para obter controle sobre quais atualizações realmente acontecem, ao invés de ter que configurar cuidadosamente quais comandos de atualização você executa em cada ambiente virtual.

@RonnyPfannschmidt Os usuários do Windows ainda superam os usuários do Linux ~ 18 para 1, e eles não têm nada comparável a uma comunidade de gerenciamento de pacotes de distro para se apoiar neste ponto (embora a tecnologia central esteja lá em versões recentes, as comunidades de embalagem e curadoria não são). Isso significa que eles dependem muito mais de ferramentas de nível de usuário, como pip e conda, para compensar.

Estamos cientes de que as pessoas querem isso, o que está faltando é alguém disposto a desenvolver uma solução que atenda a todas as várias preocupações e problemas que já foram levantados e que inevitavelmente surgirão durante uma revisão de RP.

@pfmoore você está ciente de que esses comentários podem denegrir os esforços dos colaboradores? É assim que parece para mim. Não tenho certeza se você acompanhou toda a história desse problema, mas, neste caso específico, você está muito errado. O problema é muito mais com a equipe de desenvolvimento do pip do que com qualquer contribuidor.

Resumo aproximado de apenas uma parte dele (PR gh-3194):

  1. Há uma decisão documentada de que um comando upgrade é bem-vindo (na lista de discussão pip, bem como nos documentos e no GitHub).
  2. Em seguida, uma chamada de um desenvolvedor proeminente ( @njsmith neste caso)
  3. Um novo contribuidor aparece, implementa tudo, aborda todos os comentários das revisões rapidamente. PR pronto para fusão.
  4. O contribuidor principal muda de ideia sobre querer upgrade .
  5. Seguem-se discussões muito longas, sem conclusão.
  6. O Colaborador desiste e desaparece (a maioria das pessoas faria isso, essas coisas são frustrantes).

E isso foi antes mesmo de @pradyunsg aparecer, que está mostrando uma persistência notável.

Em um projeto que funciona bem, os desenvolvedores principais que realmente se preocupam com o problema organizam um hangout rápido e tomam algum tipo de decisão. Ou delegue uma ou duas pessoas para trabalhar nisso o suficiente para chegar a essa conclusão. Ou, pelo menos, peça desculpas e agradeça ao apresentador de RP, em vez de culpá-lo por "não seguir adiante".

Eu sei que você tem a melhor das intenções, mas por favor, seja um pouco mais cuidadoso com esse tipo de comentário.

Acho perfeitamente razoável que os requisitos e as opiniões mudem durante a discussão, especialmente para uma questão espinhosa como esta, em que não existe uma resposta certa. Parte de conseguir que um patch seja colocado em qualquer base de código é acompanhar as mudanças que são eliminadas como parte da revisão e discussão em torno de qualquer mudança. Algumas mudanças são mínimas e têm menos delas, algumas têm mais. Não há nada de errado em uma pessoa decidir que não quer lidar com isso e desistir (cada barreira para adicionar uma mudança causará uma certa desistência, incluindo testes, documentação, etc).

Esta mudança em particular é particularmente desagradável porque está mudando o comportamento padrão do uso primário do pip. Isso é difícil e assustador e seria um péssimo serviço para nossos usuários se nos apressássemos e não discutíssemos tudo antes de nos comprometermos com uma direção ou outra. Esse comando é usado de 10 a 100 milhões de vezes por mês. Essa não é uma mudança pequena e fácil e não serão as pessoas que estão lidando com esse problema que terão que lidar com a reação violenta que surge ao fazer qualquer mudança.

A pessoa que implantou o PR antes, agradeceu o seu tempo, mas é verdade que eles não seguiram até o fim. Como os devs principais aqui _nosso_ tempo é limitado, somos voluntários ou espalhados por muitos projetos e participamos e deixamos de participar. Existem muitos problemas diferentes que requerem atenção e este é apenas um deles. Paul afirmou simplesmente que fazer ping neste problema não é útil (o que não é) e que se alguém quiser, precisará esperar que alguém (incluindo um dos desenvolvedores principais) decida colocar um esforço considerável para mudar o comportamento padrão de milhões ou fazer isso eles próprios.

Estamos cientes de que as pessoas querem isso, o que está faltando é alguém disposto a desenvolver uma solução que atenda a todas as várias preocupações e problemas que já foram levantados e que inevitavelmente surgirão durante uma revisão de RP.

@pfmoore você está ciente de que esses comentários podem denegrir os esforços dos colaboradores? É assim que parece para mim. Não tenho certeza se você acompanhou toda a história desse problema, mas, neste caso específico, você está muito errado.

@rgommers Sério? Esse comentário foi de meses atrás e foi citado fora do contexto aqui (mas, francamente, não tenho nenhum problema em @pradyunsg citá-lo em resposta ao comentário inútil e sarcástico que ele estava respondendo). Eu sugeriria que, se você tivesse revisado toda a história, teria visto meu comentário no contexto, momento em que, esperançosamente, você teria entendido o que eu estava tentando dizer.

Se eu fosse tão "deslocado", então você poderia ter dito isso em maio, na época em que eu disse isso, ao invés de mexer com isso agora, fora do contexto.

Se ofendi alguém, peço desculpas, não era essa a minha intenção. Honestamente, estou tão frustrado quanto qualquer outra pessoa que este problema esteja se mostrando tão difícil de se chegar a um design que seja aceitável para todos. Em meus comentários, estou tentando encontrar um equilíbrio - por um lado, realmente aprecio as contribuições que as pessoas fazem, mas, por outro lado, acho importante deixar claro para as pessoas que, em um assunto como este, o a codificação é, francamente, o mínimo de trabalho necessário. Muitas vezes, os contribuidores não apreciam esse fato, e é aí que obtemos PRs incompletos, onde as pessoas ficam frustradas com o trabalho necessário para persuadir as pessoas de que seu projeto está OK e / ou retrabalhar a mudança, possivelmente de maneiras que não Eu realmente gosto, de levar em consideração as opiniões de outras pessoas (muitas vezes conflitantes e inconsistentes!). Prefiro que eles entrem no processo com uma compreensão do que está envolvido, em vez de chegarem com expectativas irreais e, como resultado, tendo uma experiência ruim.

Todos os envolvidos nas discussões sobre este assunto dedicaram _muito_ ao debate sobre os prós e os contras de várias abordagens. Não creio que haja ninguém feliz com o tempo que está demorando. Pessoalmente, a falta de um comando upgrade-all (apenas uma parte da mudança, e provavelmente não será aquele que será implementado primeiro) me atinge regularmente. Ocasionalmente (honestamente, é muito mais do que apenas "ocasionalmente") recebemos pessoas (geralmente pessoas que não contribuíram de fato para a discussão ou o código) comentando "isso é importante, por que você ainda não implementou?" Francamente, é difícil manter a calma e _não_ gritar com essas pessoas.

Em um projeto que funciona bem, os desenvolvedores principais que realmente se preocupam com o problema

Você percebe que este comentário pode ser interpretado como dizendo que os desenvolvedores do pip não se importam em consertar isso (e por implicação sobre o pip)? Todos corremos o risco de formular as coisas de uma forma que pode ofender as pessoas. Tenho certeza de que você não quis dizer isso como uma crítica aos desenvolvedores do pip, por favor, suponha que eu também não estou tentando ofender ninguém.

organizaria um encontro rápido e tomaria algum tipo de decisão.

Ficaria surpreso se algo assim funcionasse aqui, mas estou aberto para tentar. Não tenho certeza de quem se envolveria ou como faríamos isso, mas com certeza, se ajuda e alguém quer tentar essa abordagem. Eu diria que, como essa mudança tem um grande potencial para afetar os usuários do pip, qualquer decisão tomada em um canal privado como este provavelmente deve ser escrita como uma proposta e publicada para comentários gerais - e eu suspeito que isso simplesmente acionaria mais uma rodada dos mesmos debates que estamos tendo.

Ou delegue uma ou duas pessoas para trabalhar nisso o suficiente para chegar a essa conclusão.

Então você está dizendo que uma decisão tão grande deve ser tomada unilateralmente por algumas pessoas? Talvez essa seja a única maneira de obtermos uma resolução, mas não é realmente como as decisões são feitas no pip (ao contrário do Python, não temos um BDFL com autoridade de tomada de decisão executiva). Você pode alegar que isso não nos torna um "projeto que funcione bem", se quiser, essa não é minha opinião, mas podemos discordar disso se quiser.

Ou, pelo menos, peça desculpas e agradeça ao apresentador de RP,

Não tenho certeza do que devemos nos desculpar, mas se ajudar, então ficarei feliz em me desculpar - pelo fato de ninguém ter dado a ele uma compreensão clara de como seria um trabalho difícil para concluir esta proposta, ou ajudou-o a administrar o debate e guiar os participantes a um consenso. Mas para ser justo, acho que ninguém _outro_ envolvido sabia na época que esse seria o caso, então acho que é principalmente retrospectiva falando aqui.

Ele certamente tem o meu agradecimento. É bastante fácil dizer "nem é preciso dizer", mas não deveria - os projetos de código aberto não agradecem os contribuidores o suficiente, e isso é um problema. Já que estou falando sobre o assunto, gostaria de agradecer a _todos_ que contribuíram para este debate - e estou falando sério aqui - pois sei por experiência própria como isso pode ser exaustivo. Mas especialmente para @pradyunsg por ser a vítima atual de todas as discussões intermináveis ​​e mudanças de direção. Obrigado por não desistir! (Ainda!!)

em vez de culpá-lo por "não seguir adiante".

Bem, eu não acho que haja qualquer culpa (embora seja difícil saber se ele se sentiu culpado, já que ele não está mais por perto). Mas é verdade que seu PR original não foi administrado até a conclusão. Isso é apenas um fato, no entanto. Espero que ninguém esteja sugerindo que os colaboradores têm o direito de ter seus PRs aceitos _simplesmente porque os enviaram_. Nem todos os PRs são aceitáveis ​​quando apresentados pela primeira vez, eles precisam ser revisados ​​e atualizados e, às vezes, mesmo depois de todo o trabalho, eles _ainda_ não são aceitáveis. Desculpe, mas é a vida.

[Se pareço duro na declaração acima, peço desculpas (de novo!). Mas muito do meu tempo de lazer é gasto lendo e lidando com reclamações que eu (ou projetos nos quais estou envolvido) de alguma forma não fiz o suficiente. E é um ciclo vicioso - eu perco a motivação para trabalhar com código aberto nas minhas horas vagas devido ao incômodo, o que, claro, significa que ainda menos é feito. Enquanto tento ser educado, às vezes não é fácil]

Não pretendo dizer mais nada sobre essa meta-discussão sobre como o PR está sendo gerenciado. Passei uma hora esta noite trabalhando nessa resposta, para tentar evitar dizer qualquer coisa que possa ofender alguém (e aposto que falhei :-(). E eu poderia ter passado muito melhor esse tempo - com minha família, relaxando, ou fazer algo mais produtivo.

Então, posso sugerir que voltemos a tentar ajudar @pradyunsg a encontrar um PR com o qual todos possamos ficar felizes, e deixar de lado as meta-discussões infrutíferas?

Então, posso sugerir que voltemos a tentar ajudar @pradyunsg a encontrar um PR com o qual todos possamos ficar felizes, e deixar de lado as meta-discussões infrutíferas?

Sim por favor. :inocente:

Oh, eu esqueci.

@rgommers disse:
E isso foi antes mesmo de @pradyunsg aparecer, que está mostrando uma persistência notável.

Vou tomar isso como um complemento ... Obrigado.

@pfmoore disse:
especialmente para @pradyunsg por ser a vítima atual de todas as discussões intermináveis ​​e mudanças de direção. Obrigado por não desistir!

De nada.

(Ainda!!)

Eu realmente espero que não chegue a esse estado. Será uma situação muito ruim se isso acontecer, IMO. (Eu sou arrogante assim)

Escrevi o seguinte enquanto estava revisando a história e pensei que poderia muito bem colocá-lo aqui, para referência futura, e deixar que outros me corrigissem apenas no caso.

  • Decidi trabalhar nisso depois de perceber como seria a grande razão não técnica: técnica (é muito maior do que eu _realmente_ pensava conservadoramente) e perceber que já houve uma tentativa malsucedida nisso.
  • Escrevi sobre a situação, porque estava entediado e precisava saber o que aconteceu de qualquer maneira.

    • Provavelmente gastei mais tempo (e espaço aqui?) Nisso do que o necessário, mas pelo menos eu tive uma boa visão geral do problema para mim (e todos os outros?).

  • Fiquei muito animado depois de escrevê-lo. : smiley: Mostrou para o mundo!
  • Iniciou uma (longa !!!) discussão sobre a implementação de um comando de atualização.

    • Algumas ideias iniciais úteis surgiram nas discussões. Novos números foram criados para o mesmo.

  • A discussão leva à ideia de mudar o comportamento de instalação para upstall, o que faria atualizações não ansiosas por padrão e removeria uma parte da funcionalidade fornecida por --target option - 3 coisas.

    • Foi aqui que cometemos um erro - agrupar as 3 mudanças (razoavelmente) independentes e que seriam implementadas como uma só, porque ninguém percebeu esta parte.

  • Eu implementei o mesmo. Uma vez que as 3 mudanças foram agrupadas, todas elas travaram quando não havia consenso sobre a mudança do comportamento de instalação para upstall, a mudança potencialmente controversa.
  • A falta de consenso deu início a uma longa discussão que chegou ao ponto em que as pessoas estavam desistindo da discussão e eu acho que quase se esgotaram.

    • Algumas das premissas anteriores foram quebradas e foi decidido que faríamos uma alteração de interrupção mínima primeiro.

  • Fiquei sem tempo para trabalhar nisso, então criei alguns novos problemas para que outra pessoa possa trabalhar com eles de forma independente e, de preferência, não cometer o mesmo erro que cometemos aqui.
  • Paralisado.
  • Estou de volta! Tentarei fazer a mudança para atualizações não ansiosas por padrão até 25 de setembro.

Sim, vamos nos concentrar em consertar pip install --upgrade e deixar todo o resto de fora por enquanto. Esse é um requisito para qualquer outro trabalho de qualquer maneira.

@pfmoore @dstufft obrigado pelas respostas atenciosas. Não tive a intenção de ofender ninguém, então peço desculpas se foi assim que entendi.

Não vou responder a tudo, porque ninguém está procurando uma discussão longa aqui.

você poderia ter dito isso em maio, na época em que eu disse isso,

Fiquei longe do Github por 2 meses, mas me incomodou quando vi esse comentário pela primeira vez.

Então você está dizendo que uma decisão tão grande deve ser tomada unilateralmente por algumas pessoas?

Todas as opções na mesa são muito melhores do que o status quo. E depois de 5,5 anos e muitas centenas de comentários espalhados por vários problemas / RPs aqui e na lista de e-mails, não tenho certeza de que mais comentários vão resolver isso. Espero que seja resolvido, mas se isso travar novamente, então definitivamente sim - indique uma ou duas pessoas e faça uma escolha.

Não tenho certeza do que devemos nos desculpar, mas se ajudar, então ficarei feliz em me desculpar - pelo fato de ninguém ter dado a ele uma compreensão clara de como seria um trabalho difícil para concluir esta proposta, ou ajudou-o a administrar o debate e guiar os participantes a um consenso.

Eu quis dizer o último. Às vezes eu mudo de ideia sobre uma decisão para um de meus projetos, isso acontece. Então me sinto responsável por deixar clara a nova direção. E peço desculpas se não tenho tempo para lidar com as consequências dessa mudança (leva apenas 30 segundos ...).

Mas é verdade que seu PR original não foi administrado até a conclusão. Isso é apenas um fato, no entanto.

Isso é uma visão, não um fato. Em minha opinião, o PR foi concluído - tudo o que faltou fazer foi apertar o botão verde ou rejeitá-lo. Ele fez tudo o que eu esperava de um contribuidor.

Percebi depois de sua resposta que as expectativas que os desenvolvedores do pip têm em relação aos contribuidores e desenvolvedores principais são muito diferentes de praticamente qualquer outro projeto com o qual estou familiarizado. Espero que os desenvolvedores principais orientem os novos colaboradores, os encorajem, forneçam feedback quando necessário e os ajudem a resolver problemas controversos (para os quais a maioria dos colaboradores não tem as habilidades nem o interesse, e aqueles que muitas vezes acabam se tornando os desenvolvedores principais) se precisava. Você está dizendo aos novos contribuidores: _ "você tem que nos administrar. Podemos mudar de idéia, discordar uns dos outros ou perder o interesse - é seu trabalho administrar isso" _. Talvez essa seja a natureza desse projeto e tem que ser assim, não sei.

Já que estou falando sobre o assunto, gostaria de agradecer a todos que contribuíram para este debate

Acordado. Obrigado a todos que contribuíram.

  • e estou falando sério aqui - como eu sei por experiência própria como isso pode ser exaustivo.

É desgastante. Pessoalmente, fico aqui e no distutils-sig porque é importante para o ecossistema Python e os usuários dos meus pacotes, mas os dois lugares não me fornecem exatamente energia positiva.

Apenas no caso de ter escapado do radar - # 3972: sorria:

Você está dizendo aos novos contribuidores: "você tem que nos gerenciar. Podemos mudar de ideia, discordar uns dos outros ou perder o interesse - é seu trabalho gerenciar isso". Talvez essa seja a natureza desse projeto e tem que ser assim, não sei.

Eu disse que não continuaria com isso, mas esse ponto me atingiu. Não é assim que me sinto em relação à nossa abordagem, mas agora que você colocou dessa forma, vejo que pode ser visto dessa forma. Para ser honesto, "podemos mudar de ideia, discordar uns dos outros ou perder o interesse" é verdade - afinal somos todos apenas pessoas com outros compromissos também - mas não considero isso como algo que um novo colaborador deve fazer "gerir". Em vez disso, é apenas uma realidade de lidar com as pessoas, mas se fazer muito disso parece despejar o problema para novos contribuidores, está errado.

Obrigado por apontar isso - vou tentar manter isso em mente e evitar dar essa impressão no futuro.

Acho que muito do problema realmente se resume ao fato de que somos muito insuficientes, o que acaba tornando difícil acompanhar e acompanhar tudo. Existem mais contribuidores em potencial do que nós, então é fácil se sentir sobrecarregado quando há várias pessoas tentando fazer alterações ao mesmo tempo. Mudanças maiores, ou mudanças onde não há um consenso claro, tendem a ser as mais difíceis de lidar, então são as que tendem a sofrer mais :(

O triste estado das coisas é que, embora eu ache que todos gostaríamos de estar aqui para ajudar a orientar todos os colaboradores durante o processo, simplesmente não temos mão de obra. Isso tende a ter um ciclo um pouco viscoso também, porque não temos mão de obra para fazer isso, não encontramos prontamente novas pessoas que parecem ter realmente começado a entender a mentalidade por trás de como o pip opera e que aprenderam o suficiente (porque não estamos lá para ensiná-los) para dar a eles direitos de commit para pip. Isso significa que estamos constantemente com falta de pessoal e lutando apenas para manter nossas cabeças acima da água (pelo menos, é assim que eu me sinto. Constantes 70-90 horas por semana são muito difíceis para uma pessoa: /).

@pradyunsg Rever # 3972 está na minha lista TODO, só não acertei ainda.

@pradyunsg Rever # 3972 está na minha lista TODO, só não acertei ainda.

Obrigado!

Isso significa que estamos constantemente com falta de pessoal e lutando apenas para manter nossas cabeças acima da água (pelo menos, é assim que eu me sinto. Constantes 70-90 horas por semana são muito difíceis para uma pessoa: /).

Isso é difícil. Numpy e Scipy estavam nessa situação quando comecei a trabalhar nisso. Não tem graça. Agradeço tudo o que você está fazendo.

Este problema agora é muito antigo e muito antigo, muitas coisas foram discutidas, muitas coisas aconteceram e este problema quase atingiu um sinal / ruído baixo. É difícil ver o que tudo aconteceu.

FWIW, o motivo pelo qual upgrade estava nas cartas era o fato de que install --upgrade tinha um default quebrado. Já que estamos um passo mais perto de consertar isso, acho melhor termos um novo problema para isso.

Sugiro que este problema seja encerrado por causa do acima e novos problemas sejam criados para tudo o que aqui é visto como não resolvido. Eu posso ver 2 coisas:

  • Mude a estratégia de atualização padrão para only-if-needed .
  • Adicione a funcionalidade "atualizar o mundo" que depende do # 988.

Em 15/09/16, Nick Coghlan [email protected] escreveu:

@RonnyPfannschmidt Os usuários do Windows ainda superam os usuários do Linux ~ 18 para 1, e
eles não têm nada comparável a uma comunidade de gerenciamento de pacotes de distribuição
recorrer a este ponto (embora a tecnologia principal esteja lá recentemente
versões, as comunidades de embalagem e curadoria não). Isso significa que eles são
muito mais dependente de ferramentas de nível de usuário como pip e conda para pegar o
folga.

Então não é
atualização conda --todos
bom o bastante?

@ Liso77
Bem, não. Não é.

Conda e pip são ferramentas com objetivos diferentes. Esta é uma ótima leitura sobre este tópico. O terceiro ponto é o mais relevante.


Se a discussão para atualizar tudo voltar à superfície (espero que em uma nova edição), meu voto é para soletrá-la da seguinte maneira:

pip install --upgrade :all:

pip install --upgrade :all: é extremamente estranho. Vamos nos ater à semântica POSIX, que basicamente todo mundo está fazendo hoje em dia: pip install --upgrade --all

Que tal apenas pip install --upgrade sem nenhum nome de pacote ou especificador? Tão fácil de executar acidentalmente?

pip-tools faz assim por pip-compile -P .

Talvez devêssemos trocar de bicicleta assim que tivermos algum tipo de trabalho
implementação ... :)

No domingo, 12 de fevereiro de 2017, 20:55 FichteFoll [email protected] escreveu:

Que tal apenas pip install --upgrade sem quaisquer nomes de pacote ou
especificadores? Tão fácil de executar acidentalmente?

-
Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/pypa/pip/issues/59#issuecomment-279225595 ou mudo
o segmento
https://github.com/notifications/unsubscribe-auth/ADH7SfnSBflH8rK3nFLw1hvYBaovjbcGks5rbyRUgaJpZM4AJ4Py
.

Que tal uma versão de pip list --outdated que produz sua lista em um formato que pode ser diretamente (ou seja, sem sed , cut , etc.) ingerido por pip install --upgrade (por exemplo, pip list --outdated --format install | xargs pip install --upgrade ou algo semelhante com crostas)?

seja qual for a sintaxe usada, o mais importante é a introdução deste comando, é inacreditável que ainda está faltando

enquanto isso eu sugiro que você experimente
https://github.com/jgonggrijp/pip-review
com pip-review --local --interactive pergunte a você pacote por pacote se deseja atualizar, não muito bom, mas melhor do que nada

@ SMH17 É totalmente crível que ainda esteja faltando, já que não há exatamente nenhum fornecedor comercial de Python fornecendo formalmente tempo de desenvolvimento financiado para trabalhar nas melhorias de usabilidade de pacotes Python em nome de seus clientes.

Portanto, se você gostaria de ver a situação melhorar, é provável que a coisa mais útil que você possa fazer pessoalmente seja encorajar seu fornecedor de suporte Python a investir tempo de desenvolvedor no aprimoramento das ferramentas que você usa, ou se você não tiver um fornecedor de suporte ainda, incentive seu empregador a pagar um.

Como uma parte adicional do contexto em relação à falta de urgência em torno deste problema, vale a pena ter em mente que as recomendações gerais são para

  • mantenha suas definições de ambiente de trabalho sob controle de origem para melhorar a reprodutibilidade em outros sistemas (usando algo como https://github.com/jazzband/pip-tools ou https://github.com/kennethreitz/pipenv para manter essas definições atualizadas )
  • visam atualizar rotineiramente para novas versões de dependências, a fim de minimizar as janelas de exposição a vulnerabilidades de segurança desconhecidas ou não divulgadas

Isso não significa que os comandos propostos aqui não sejam úteis, eles apenas são nitidamente menos valiosos se o ambiente de trabalho atual já estiver sendo mantido por pip-compile + pip-sync ou pipenv lock + pipenv install .

Seria valioso atualizar a descrição original, pois acho que foram feitas algumas alterações em pip install desde a atualização feita por @qwcode.

Olá a todos.

Eu quebrei algumas das dependências do meu pacote Python por causa do seguinte comando:

pip install --upgrade packageName atualizou pacotes recursivamente.

Por que não mudar o comportamento padrão da opção --upgrade , que é desinstalar e reinstalar SOMENTE o pacote fornecido na linha de comando?

Que tal agora ?

@sebma Acho que o comportamento padrão não deve ser alterado. Talvez você possa tentar usar o sinalizador -no-dependencies na próxima vez. Deve funcionar: +1:

@sebma , @aaossa , quero que vocês dois saibam que já está praticamente decidido que a estratégia de atualização padrão mudará no futuro (ref: https://github.com/pypa/pip/issues/3871# issuecomment-247789343). O recurso necessário (ou seja, o argumento --upgrade-strategy ) foi adicionado em https://github.com/pypa/pip/pull/3972.

Como @pradyunsg mencionou anteriormente , esse problema é uma espécie de sobra. A primeira parte já está resolvida (veja meu primeiro parágrafo) e a segunda parte é a única razão pela qual este pacote ainda está aberto, ao que parece. Não sei se um problema separado "atualizar tudo" foi criado desde então.

Lancei um ótimo atualizador interativo para o arquivo de requisitos: https://github.com/simion/pip-upgrader

Mude a estratégia de atualização padrão para apenas se necessário.

4500 fez isso.

Adicione a funcionalidade "atualizar o mundo" que depende do # 988.

4551 para discussão sobre este assunto.


Abordando os pontos levantados na postagem principal atual:

pip upgrade seria como pip install --upgrade, exceto que não seria recursivo por padrão (e ofereceria uma opção --recursive). Seu comportamento padrão recursivo atual causou pesar para muitos (# 304). Para saber como fazer atualizações não recursivas agora, veja aqui.

Foi decidido não adicionar um comando de atualização ou fazer pip install atualizar pacotes já instalados. pip agora tem atualizações não recursivas por padrão, com o comportamento recursivo disponível por trás de --upgrade-strategy eager .

pip upgrade-all atualizaria todos os pacotes instalados.

4551 existe e seria bom ter uma nova discussão sobre isso; quando # 988 estiver pronto.


@dstufft @xavfernandez @pfmoore Algum de vocês acha que este problema deveria ser

Editar (18-05-2017): Pontuação + texto menor adicionado

Parece razoável.

Olá a todos,
Eu fiz um script / gist simples que faz o trabalho.

https://gist.github.com/serafeimgr/b4ca5d0de63950cc5349d4802d22f3f0

Por que não simplesmente fazer isso?

pip install --upgrade $(pip list --outdated | awk '{print $1}' | tr '\n' ' ')

Porque não é tão fácil na realidade, já que você pode instalar versões que não satisfaçam algumas das dependências de outros pacotes.

Com base e graças à essência de @serafeimgr , escrevi uma ferramenta de linha de comando possivelmente útil, pip_upgrade_outdated ; fonte no github . Feedback bem-vindo.

(Veja também este problema : Sim, a execução paralela é particularmente perigosa e, sim, isso pode quebrar as coisas. No entanto, muitas pessoas executam algo assim manualmente o tempo todo, por isso podem achar útil.)

Obrigado por dedicar seu tempo para criar uma solução completa.
Mesmo que minha recomendação seja encontrar uma maneira de empurrar esse recurso para pip.

Acho que pipenv & pipfile vai substituir pip / requirements.txt de qualquer maneira.
Talvez @kennethreitz saiba mais sobre o roadmap e o recurso --upgrade all.

@qoheniac | tr ... é redundante.

Este tópico foi bloqueado automaticamente, pois não houve nenhuma atividade recente depois que ele foi fechado. Abra um novo problema para bugs relacionados.

Esta página foi útil?
0 / 5 - 0 avaliações