Pip: `pip install -U` atualiza dependências já satisfeitas

Criado em 9 jun. 2011  ·  23Comentários  ·  Fonte: pypa/pip

Se eu pip install -U foo , espero que a versão mais recente de foo seja instalada e as dependências de foo sejam reinstaladas apenas se ainda não estiverem satisfeitas. Mas, na verdade, todas as dependências são reinstaladas, mesmo se eu já tiver versões idênticas instaladas:


$ pip install -U django-supervisor
Downloading/unpacking django-supervisor
  Downloading django-supervisor-0.2.0.tar.gz
  Running setup.py egg_info for package django-supervisor
Downloading/unpacking supervisor (from django-supervisor)
  Downloading supervisor-3.0a10.tar.gz (438Kb): 438Kb downloaded
  Running setup.py egg_info for package supervisor
    no previously-included directories found matching 'docs/*.pyc'
    no previously-included directories found matching 'docs/.build'
Downloading/unpacking meld3>=0.6.5 (from supervisor->django-supervisor)
  Downloading meld3-0.6.7.tar.gz
  Running setup.py egg_info for package meld3
Installing collected packages: django-supervisor, supervisor, meld3
  Found existing installation: django-supervisor 0.1.1
    Uninstalling django-supervisor:
      Successfully uninstalled django-supervisor
  Running setup.py install for django-supervisor
  Found existing installation: supervisor 3.0a10
    Uninstalling supervisor:
      Successfully uninstalled supervisor
  Running setup.py install for supervisor
    no previously-included directories found matching 'docs/*.pyc'
    no previously-included directories found matching 'docs/.build'
    Skipping installation of /usr/local/ejucovy/django/lib/python2.6/site-packages/supervisor/__init__.py (namespace package)
    Installing /usr/local/ejucovy/django/lib/python2.6/site-packages/supervisor-3.0a10-py2.6-nspkg.pth
    Installing echo_supervisord_conf script to /usr/local/ejucovy/django/bin
    Installing pidproxy script to /usr/local/ejucovy/django/bin
    Installing supervisorctl script to /usr/local/ejucovy/django/bin
    Installing supervisord script to /usr/local/ejucovy/django/bin
  Found existing installation: meld3 0.6.7
    Uninstalling meld3:
      Successfully uninstalled meld3
  Running setup.py install for meld3
Successfully installed django-supervisor supervisor meld3
Cleaning up...

Minhas "instalações existentes" de supervisor-3.0a10 e meld3-0.6.7 são ambas "desinstaladas com sucesso" e, em seguida, versões idênticas são instaladas.

upgrade auto-locked bug

Comentários muito úteis

Não acho que seja uma duplicata do # 49. Eu li o # 49 dizendo que install -U foo não deve reinstalar _ foo si_ se já estiver na versão mais recente - o que é diferente de se deve ou não reinstalar foo dependências já satisfeitas de.

Esta distinção é importante para bibliotecas difíceis de construir que têm lançamentos frequentes, mas APIs razoavelmente estáveis ​​- na maior parte, uma instalação é boa o suficiente - eu só gostaria de reinstalá-la se minhas dependências começarem a usar recursos mais novos daqueles dependências aninhadas (ou seja, se o requisito não for mais satisfeito) - por exemplo:

  • foo 0.1 depende de lxml>=2.3.0
  • foo 0.2 é lançado e depende de lxml>=2.3.0 (mesma dependência)
  • lxml 2.4.0 foi lançado

Se eu já instalei foo 0.1 e lxml 2.3.0 e I pip install -U foo , não gostaria que ele instale lxml 2.4.0 . Ele só deve instalar lxml 2.4.0 quando foo começar a depender de lxml>=2.4.0 .

Todos 23 comentários

Na minha opinião, é um comportamento conhecido, não sei se é realmente um bug - acho que easy_install tem o mesmo comportamento.

Eu gostaria de ver as opiniões dos outros.

PS: Houve uma pergunta no StackOverflow relacionada a isso: http://stackoverflow.com/questions/5937756/why-is-pip-looking-for-download-cache-if-the-same-exact-package-is -já-instalar

Relacionado ao problema # 49

É um bug e é uma duplicata do # 49.

Não acho que seja uma duplicata do # 49. Eu li o # 49 dizendo que install -U foo não deve reinstalar _ foo si_ se já estiver na versão mais recente - o que é diferente de se deve ou não reinstalar foo dependências já satisfeitas de.

Esta distinção é importante para bibliotecas difíceis de construir que têm lançamentos frequentes, mas APIs razoavelmente estáveis ​​- na maior parte, uma instalação é boa o suficiente - eu só gostaria de reinstalá-la se minhas dependências começarem a usar recursos mais novos daqueles dependências aninhadas (ou seja, se o requisito não for mais satisfeito) - por exemplo:

  • foo 0.1 depende de lxml>=2.3.0
  • foo 0.2 é lançado e depende de lxml>=2.3.0 (mesma dependência)
  • lxml 2.4.0 foi lançado

Se eu já instalei foo 0.1 e lxml 2.3.0 e I pip install -U foo , não gostaria que ele instale lxml 2.4.0 . Ele só deve instalar lxml 2.4.0 quando foo começar a depender de lxml>=2.4.0 .

Ah, sim, isso é um pouco diferente. Mesmo se o nº 49 for corrigido, haverá algum código adicional necessário para atingir o comportamento que você deseja quando a dependência não estiver em sua versão mais recente, mas ainda atender aos requisitos de dependência.

Acho que se fizéssemos essa mudança, algumas pessoas achariam surpreendente. Posso ver porque é desejável em certos casos - mas também posso ver casos em que o comportamento atual (menos # 49) é preferível. Então, estou em cima do muro.

Uma opção de linha de comando extra seria apropriada? pip install foo --upgrade vs pip install foo --upgrade-recursive ? (Ou --upgrade-nonrecursive se preservar o comportamento atual de compatibilidade reversa for importante)

tornar as atualizações não recursivas por padrão forneceria consistência com outros gerenciadores de pacotes, como APT e Portage. e acho que há uma boa razão para tal comportamento, que evita efeitos colaterais indesejados - se eu quiser atualizar um pacote P, gostaria de inserir um comando nas linhas de upgrade P , não upgrade P --but-not-other-things .

por outro lado, acho que um comando "atualizar tudo" (consulte # 59) deve ser recursivo por padrão, uma vez que "todos" deve realmente significar "todos" por padrão. neste caso, o comportamento não recursivo significaria "atualizar todos os pacotes instalados diretamente, mas não quaisquer dependências que não foram instaladas diretamente" (como emerge --update @world do Portage sem --deep ).

Um problema relacionado é que se o pacote que está sendo atualizado depender de outro pacote que já está instalado, mas indisponível em um repositório, o Pip irá falhar e não poderá atualizar o pacote solicitado, apesar de suas dependências serem atendidas.

Isso parece acontecer com -I e também com -U.

Como -I significa --ignore-installed e tem como objetivo fazer o pip operar como se nada estivesse instalado no momento, reinstalar tudo é o comportamento correto para -I . Portanto, o comportamento aqui é apenas um bug para -U , não para -I .

easy_install não tem o mesmo comportamento. easy_install não irá reinstalar dependências se já forem atendidas.

este não é um recurso ou comportamento, é um bug.

isso também é realmente irritante - testar a distribuição PIP de um pacote de estrutura ou atualizar um único complemento de estrutura significa precisar reinstalar toda a estrutura e todas as suas dependências. esses downloads e instalações desnecessários são uma perda de tempo e recursos.

para aqueles que querem apenas uma maneira de fazer isso _agora_, sem alterar o comportamento / código para "-U"

Acho que isso dá o resultado desejado, certo?

atualizar apenas os requisitos de nível superior:

  • pip install -U --no-deps REQS // atualiza apenas o nível superior
  • pip install REQS // esta segunda passagem irá instalar quaisquer _novas_ dependências da atualização

Para o caso mais simples, isso é suficiente, mas não acho que funcione para um arquivo requirements.txt, ou se houver dependências que tenham atualizações para seus install_requires. Temos um script complicado que faz uma comparação de nosso requirements.txt e mais ou menos faz o que você descreve, mas não lida com a profundidade de atualização> 1.

O que complica as coisas até certo ponto é que muitos pacotes django comentam ou removem suas linhas install_requires por causa desse bug; caso contrário, eles acabam com alguma versão alfa do django instalada (essa tem sido nossa experiência, e eu vi isso nos problemas do github de muitos pacotes proeminentes do django.

Ei @fdintino , eu

para o caso em que um requisito de nível superior tem uma nova dependência "install_requires", é por isso que mencionei o comando 2nd pass para instalá-los.

para o caso em que há "dependências que têm atualizações para seus install_requires", não tenho certeza se segui você até aí. você apenas descobriria e gostaria de agir sobre isso, se quisesse fazer uma atualização recursiva completa, certo?

Somente se você não atender mais aos requisitos. Então, por exemplo, se eu atualizei django-sentry, e django-sentry exigiu django-celery>=2.5.4,django-celery<3.0 onde anteriormente exigia django-celery>=2.5.3,django-celery<3.0 (talvez por causa de uma correção de bug ou um novo recurso), e eu atualmente tenho django-celery==2.5.3 , então eu esperaria que ele atualizasse o django-celery para satisfazer o requisito, como meu patch o faz. No entanto, se eu tivesse django-celery==2.5.4 , não esperaria que ele atualizasse o aipo. No caso do aipo não é grande coisa, mas quando os pacotes têm Django>1.2,Django<=1.4 , e os projetos são freqüentemente escritos para o Django 1.2, 1.3 ou 1.4, uma atualização inesperada do django pode ser uma grande dor de cabeça.

obrigado @fdintino . Eu sigo agora. você não deseja cortar todo o comportamento recursivo (que fará as atualizações necessárias para cumprir os requisitos), apenas deseja interromper as atualizações "forçadas" recursivas.

aliás, seu comentário foi cortado devido à formatação. pode querer consertar isso para outros.

Publiquei um resumo que analisa a obtenção do comportamento desejado usando os 2 comandos em sequência mencionados acima.
Não que isso invalide o desejo por esse tíquete ou a atração, mas foi útil para mim confirmar como
ele funciona atualmente e o que é possível atualmente.
(dica: no exemplo, "b" é o paralelo ao django que foi mencionado como uma preocupação)

https://gist.github.com/3088149

comentário apreciado na essência, se este não for o cenário.

Percebo que está aberto há muito tempo.

Descobri que minha versão do pip agora tem a opção de fazer

pip install --upgrade --upgrade-strategy=only-if-needed package

Este parece ser o comportamento desejado, embora bastante prolixo. Pessoalmente, acho que teria sido ótimo se esse fosse o padrão, mas talvez seja tarde demais para mudar agora.

Se for tarde demais para alterar o padrão, então acho que isso pode ser fechado?

Em https://github.com/pypa/pip/issues/3871#issuecomment -247789343 mencionei o que acredito ser a forma como iremos avançar nisso, reproduzindo aqui:

Circulando de volta para isso agora. Aqui está o que acho que devemos fazer:

  1. Adicione --upgrade-strategy = [eager / non-eager] no pip vX, que é eager padrão, e permite que as pessoas optem pela estratégia não-ansiosa. Isso nos permitirá fazer alguns testes do mundo real com as pessoas, sem forçar uma mudança em todos de uma vez.
  2. Depois de abordar qualquer feedback de 1., mude o padrão de --upgrade-strategy para non-eager no pip vX + 1. Isso nos dará muito uso no mundo real, ao forçar uma mudança em todos, mas dá uma saída de emergência para as pessoas que, por qualquer motivo, são prejudicadas pela mudança.
  3. Depois de responder a qualquer feedback de 2., observe a suspensão de --upgrade-strategy no pip vx + 2 (a ser removido de acordo com nossa política de suspensão de uso normal).

Isso terá um tempo de espera maior antes que não ansioso seja o padrão, mas nos permite colocá-lo em fases mais devagar para ter certeza de que não há nenhum caso de uso que saia do controle. Idealmente, acho que queremos nos livrar da bandeira --upgrade-strategy . Esse tipo de sinalizador parece estar apenas pedindo problemas com coisas quebrando, porque essencialmente exige que duplicemos nosso teste de atualização para testar totalmente as coisas. Eu realmente acho que é uma boa bandeira para adicionar agora, para permitir a entrada gradual e lidar com quaisquer quebras.

Ok, parece bom, vou aguardar a conclusão da etapa 2. Parece que o outro problema é uma duplicata, mas já fechado.

@xavfernandez @dstufft Isso pode ser fechado ou vamos esperar até as opções padrão?

Provavelmente vamos esperar até que as mudanças padrão.

Fechando, visto que # 4500 foi mesclado

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