Pipenv: Atualizando apenas uma dependência bloqueada

Criado em 24 out. 2017  ·  82Comentários  ·  Fonte: pypa/pipenv

Às vezes estou fazendo um PR e quero atualizar uma dependência específica, mas não quero lidar com atualizações de todas as minhas dependências (aiohttp, flake8, etc ...). Se alguma alteração significativa foi introduzida nessas dependências, quero lidar com isso em outro PR.

Pelo que eu sei, a única maneira de fazer isso seria fixar todas as dependências que não desejo atualizar no Pipfile. Mas acho que derrota o propósito do Pipenv em primeiro lugar :).

Portanto, minha solicitação de recurso seria capaz de fazer algo como:

$ pipenv lock --only my-awesome-dep

Isso geraria um Pipfile.lock com atualizações para apenas my-awesome-dep e suas dependências.

Provavelmente posso fazer um RP disso, mas gostaria de receber algum feedback primeiro.

Type

Comentários muito úteis

Concordo 100% - e irei um pouco mais adiante: este deve ser o padrão.

Ou seja, pipenv install foo nunca deve tocar em nada além de foo e suas dependências. E pipenv lock certamente nunca deve atualizar nada - deve apenas bloquear o que já está instalado.

AFAICT, é assim que npm , yarn , gem , etc. funcionam; não faz sentido ter um arquivo de bloqueio que não bloqueie realmente os pacotes, mas confia nos autores dos pacotes para não quebrar coisas em lançamentos de patches e, portanto, os atualiza sem serem solicitados. Eu posso ver o uso de permitir atualizações, mas isso deve ser opcional, já que é mais surpreendente do que não atualizá-los.

Peço desculpas se estou sequestrando esse problema para outra coisa, mas como isso está tão relacionado a um problema que eu estava prestes a criar, pensei em iniciar a conversa aqui. Sinta-se à vontade para me dizer que devo fazer um novo.

Todos 82 comentários

Isso também pode ser útil para pipenv install , pois às vezes desejo instalar uma nova dependência sem atualizar outras.

Há uma pequena coisa a se levar em consideração aqui: alterar uma única dependência pode alterar o conjunto geral de requisitos.
Ex: Atualizar foo de 1.0 para 2.0 pode exigir a atualização de bar para> = 2.0 (enquanto era <2.0 antes), e assim por diante.

Eu sei que no contexto do próprio pip-tools (do qual pipenv tira seu algoritmo de resolução de dependência), a execução da resolução de dependência só "atualizará" os pacotes necessários ao "travar novamente" se houver um arquivo de bloqueio existente. Ele faz isso verificando se os pinos existentes no arquivo de bloqueio são candidatos válidos primeiro ao selecionar o candidato na resolução. pipenv provavelmente poderia fazer o mesmo.

Eu acho que é uma ideia razoável. Caso contrário, se você quiser atualizar absolutamente apenas uma dependência, pipenv teria que ter um modo para bloquear se a mudança de uma dependência causar outras mudanças, ou então você perderia a garantia de um ambiente válido.

Eu espero que isso ajude!

Na verdade, foi isso que eu quis dizer com:

Isso geraria um Pipfile.lock com atualizações apenas para my-awesome-dep e suas dependências.

Concordo 100% - e irei um pouco mais adiante: este deve ser o padrão.

Ou seja, pipenv install foo nunca deve tocar em nada além de foo e suas dependências. E pipenv lock certamente nunca deve atualizar nada - deve apenas bloquear o que já está instalado.

AFAICT, é assim que npm , yarn , gem , etc. funcionam; não faz sentido ter um arquivo de bloqueio que não bloqueie realmente os pacotes, mas confia nos autores dos pacotes para não quebrar coisas em lançamentos de patches e, portanto, os atualiza sem serem solicitados. Eu posso ver o uso de permitir atualizações, mas isso deve ser opcional, já que é mais surpreendente do que não atualizá-los.

Peço desculpas se estou sequestrando esse problema para outra coisa, mas como isso está tão relacionado a um problema que eu estava prestes a criar, pensei em iniciar a conversa aqui. Sinta-se à vontade para me dizer que devo fazer um novo.

Também encontrei este problema relacionado: https://github.com/kennethreitz/pipenv/issues/418

Ser capaz de especificar pipenv install --upgrade-strategy=only-if-needed parece o que estou procurando, embora, é claro, como mencionei, acho que deve ser o padrão, já que está se tornando no pip 10. Mas ser capaz de especificá-lo de forma semi-permanente via env var seria algo, de qualquer maneira.

Eu ficaria surpreso se essa mudança quebrasse o fluxo de trabalho de alguém ( últimas palavras famosas ), já que é mais conservador do que --upgrade-strategy=eager .

Tentei contornar isso definindo export PIP_UPGRADE_STRATEGY=only-if-needed na minha configuração de shell. Isso não funciona, e pipenv lock exibe estes comportamentos surpreendentes:

  1. Ele "atualiza" pacotes que não precisam ser atualizados (mas ...)
  2. Na verdade, não atualiza as versões instaladas! ou seja, pip freeze e Pipfile.lock mostram versões diferentes!

Supondo que pipenv está delegando a pip para a instalação, e pip respeita suas configurações de variável de ambiente, mas pipenv lock não.

@ k4nar O que acontece agora que você considera indesejável? Porque se você atualizar uma dependência que tem requisitos em cascata, obviamente haverá consequências para outras dependências. Você está sugerindo algum tipo de lógica de resolução para determinar a versão mais atual de um pacote específico _no contexto do lockfile_ atual? Hesito em encorajar muitos hacks para resolver a lógica, que já é complicada e difícil de depurar.

@brettdh Acho que posso lançar alguma luz porque você tem a maioria das peças. pipenv lock não instala nada, e não afirma instalar. Ele apenas gera o arquivo de bloqueio de acordo com seu ambiente de host, versão python e um Pipfile . Se você manipular seu ambiente de alguma outra forma ou se usar pip diretamente / manipular configurações de pip fora de pipenv / não estiver usando pipenv run ou usando pip freeze dentro de um subshell pipenv, é muito fácil para um arquivo de bloqueio fora de sincronia de pip freeze . Os dois não estão realmente relacionados.

Para ser claro:

  1. Pipfile.lock é uma resolução de dependência estritamente fixada usando o resolvedor pip-tools baseado no usuário Pipfile
  2. Se você quiser manter alfinetes estritos de tudo enquanto atualiza apenas um pacote, acredito que você pode fazer isso fixando estritamente tudo em seu Pipfile exceto para o item que deseja atualizar (corrija-me se eu estiver errado @vphilippon)

Quanto ao seu lockfile e pip freeze discordando um do outro, eu precisaria saber mais informações, mas acredito que temos um problema aberto em relação ao nosso resolvedor de lockfile ao usar versões de python fora do sistema para resolver.

@techalchemy : Se eu tiver um Pipfile.lock com A, B e C em que B é uma dependência de A, gostaria de poder atualizar A e B sem atualizar C, ou C sem atualizar A e B.
Mais uma vez, é claro que posso fixar todas as minhas dependências e suas dependências no meu Pipfile para fazer isso, mas seria um fardo para manter (como a maioria de requirements.txt ).

Eu concordo com tudo o que @ k4nar escreveu. Claro, eu poderia apenas fixar
tudo em requirements.txt e não use pipenv. O objetivo do pipenv é
ter uma ferramenta que faz isso (e as coisas do virtualenv, é claro)
mais simples de gerenciar; ou seja, todos os pacotes são bloqueados por padrão para uma versão
que funciona, mas deve ser simples atualizar um seleto
poucos (sem atualizar outros inesperadamente).
Na quinta-feira, 26 de outubro de 2017 às 4:28 AM Yannick PÉROUX [email protected]
escrevi:

@techalchemy https://github.com/techalchemy : If I have a Pipfile.lock
com A, B e C, onde B é uma dependência de A, gostaria de poder
atualize A e B sem atualizar C, ou C sem atualizar A e B.
É claro que posso fixar todas as minhas dependências e suas dependências em meu
Pipfile para fazer isso, mas seria um fardo para manter (como
a maioria dos requisitos.txt são).

-
Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/kennethreitz/pipenv/issues/966#issuecomment-339591307 ,
ou silenciar o tópico
https://github.com/notifications/unsubscribe-auth/AAFlnqUOEKARiFD8kEk3GVczF3NXBdVOks5swEKcgaJpZM4QEf--
.

Hm, eu vejo o que vocês estão dizendo. A premissa de passar uma configuração para o pip não é o que me preocupa, é resolver com as ferramentas do pip que me preocupa. Como é esse comportamento agora?

@techalchemy Eu mencionei a diferença pip freeze como uma abreviação para "as versões de pacote que pipenv install instala diferem das versões de pacote que pipenv lock salva em Pipfile.lock ."

Verdade, isso só acontece quando eu mudei os argumentos padrão do pip por meio da variável de ambiente; Eu estava apenas apontando que era surpreendente que pipenv delegasse ao pip para instalação, mas não para bloqueio de versão; ou seja, em vez de bloquear o que está instalado, ele bloqueia o que acha que deve ser instalado, potencialmente com atualizações não solicitadas.

Você poderia esclarecer um pouco sua pergunta? Eu acho que "resolver com pip-tools" se refere ao que pipenv lock está fazendo, e a razão pela qual não é afetado quando eu defino os padrões do pip? E você poderia ser mais específico sobre o que entende por "este comportamento"?

@brettdh O mecanismo de bloqueio inclui uma noção de "resolução de dependência" que não existe em pip . É manejado por pip-tools (ou melhor, uma versão corrigida dele, integrada de forma especial por pipenv que trazem algumas diferenças com a ferramenta original). Resumindo, o mecanismo de bloqueio lê Pipfile e executa uma resolução de dependência completa para selecionar um conjunto completo de pacotes que atenderá a todas as restrições definidas pelos pacotes necessários e suas dependências .

@techalchemy

[...] é resolver com pip-tools que me preocupa.

Não tenho certeza de como aqueles --upgrade-strategy afetariam pip-tools , porque funciona em alguns componentes internos de baixo nível de pip . Tenho a sensação de que isso não daria o resultado esperado, pois essas opções levam em consideração o que está instalado, e não é isso que está sendo tratado naquele mecanismo. Mas temos outra abordagem para isso em pip-tools que pode ser feita aqui.

O comportamento "original" de pip-tools é que ele apenas atualiza o que é necessário no arquivo de bloqueio (em seu contexto, é o requirements.txt), mas isso foi "perdido" na maneira como o resolvedor foi integrado em pipenv . Deixe-me explicar o porquê.

Voltando ao meu currículo de como pip-tools funciona: https://github.com/kennethreitz/pipenv/issues/875#issuecomment -337717817
Lembra da parte "selecione um candidato"? Isso é feito consultando o objeto Repository .
Em pipenv , configuramos diretamente um PyPIRepository para Resolver , mas pip-tools faz outra coisa, ele usa um objeto LocalRequirementsRepository , que mantém os pinos existentes do requirements.txt existente anteriormente (se encontrado) e "substitutos" em PyPIRepository .

Portanto, em pip-tools , acontece o seguinte ao selecionar um candidato:

  1. Consulte LocalRequirementsRepository para um candidato que corresponda a foobar>=1.0,<2.0 .
  2. Verifique se um pino existente atende a esses requisitos:

    • Em caso afirmativo, devolva o distintivo como candidato.

    • Caso contrário, consulte proxied_repository ( PyPIRepository ) para o candidato.

  3. Use o candidato retornado

Efetivamente, isso significa que os pinos existentes recebem uma "prioridade" como candidato para tentar primeiro.

Mas em pipenv , atualmente, simplesmente:

  1. Consulte PyPIRepository (diretamente) para um candidato que corresponda a foobar>=1.0,<2.0 .
  2. Use o candidato retornado.

Então, acho que o mesmo comportamento para o bloqueio em pipenv poderia ser feito analisando o Pipfile.lock para obter os pinos existentes e usar um LocalRequirementsRepository , como pip-tools faz em seu comando pip-compile .

@vphilippon , você tem uma noção de quão difícil seria a implementação disso?

@techalchemy

  • Analisando Pipfile.lock para extrair os pinos existentes: Não olhei para isso. Depende de como as coisas estão estruturadas em pipenv . Precisamos de um conjunto de InstallRequirements que representa os pinos em Pipfile.lock .
  • Usando LocalRequirementsRepository : Bastante fácil: troque nosso PyPIRepository atual por um LocalRequirementsRepository .

Mas, enquanto estou examinando isso e seguindo os comentários de @brettdh , percebi algumas coisas:

  1. O comportamento padrão atual de pipenv install não corresponde ao comportamento pipenv lock . Fazer pipenv install requests sozinho não atualizará requests se uma nova versão for lançada (bem como pip install linha reta). No entanto, fazer pipenv lock atualizará Pipfile.lock com a versão mais recente de requests que corresponde ao especificador Pipfile e às restrições de dependência.
    Existem duas maneiras principais de ver isso:

    • A) O Pipfile.lock deve permanecer o mais estável possível por padrão, não mudando os pinos a menos que seja necessário, a fim de permanecer como o ambiente atual, e apenas mudar no caso de mudarmos o ambiente.

    • B) O Pipfile.lock deve obter as versões mais recentes que respeitem as restrições / dependências do ambiente para se beneficiar livremente das faixas abertas nas dependências Pipfile e lib, permitindo adquirir continuamente novas versões compatíveis em seu ambiente. Você pode então executar pipenv update para se beneficiar do novo bloqueio.

IMHO, I would align the default behavior, which would be to go with A) by default. Because right now, everytime a lock is performed (i.e. after each installation), new versions can come in, which make the lockfile *drive the update of the environment*, which seems weird. But, this is arguable of course. While in development, I might want to continuously update my requirements to no get stale, like with B), so that should also be easily doable.
  1. Mesmo se usarmos LocalRequirementsRepository para evitar a atualização dos pinos existentes corretos e acabar alinhando os comportamentos padrão, precisamos abordar o equivalente a --upgrade e --upgrade-strategy para a parte de bloqueio . Atualmente, definir alguma variável de ambiente (como PIP_UPGRADE e PIP_UPGRADE_STRATEGY ) afetará o comportamento de pipenv install , mas não afetará pipenv lock , pois não afeta o comportamento de pip-tools (eu confirmei isso, pois não tinha certeza no início).
    Caso contrário, não haverá maneira de atualizar o ambiente sem excluir o Pipfile.lock (parece desajeitado e "tudo ou nada") ou exigir uma versão mais recente (quero dizer, fazer um pipenv install requests>2.18.4 explícito, que requer que você saiba que uma nova versão foi lançada, e altera o especificador no próprio Pipfile , aumentando o limite inferior), o que está errado. Como o " pip-tools " original não difere para pip para lidar com isso (pois não está relacionado ao que está instalado atualmente), ele oferece uma opção para especificar as dependências a serem atualizadas no lockfile e simplesmente remova os pinos para esses pacotes (ou todos) da lista existing_pins, voltando a consultar o PyPI. Não tenho certeza de como podemos combinar a noção de "estratégia de atualização" com isso.

@techalchemy
Então, embora eu estivesse dizendo que era bastante fácil apenas "alinhar o comportamento padrão", agora percebo que isso causaria alguns problemas importantes ao ser capaz de atualizar os pacotes (como em: basta buscar a versão mais recente que corresponda às minhas restrições atuais) .

Se há algo obscuro, pergunte, muitas edições foram feitas ao escrever isso.

(Resolução de dependência não é fácil. Resolução de dependência boa e prática é ainda pior 😄)

@vphilippon é exatamente o que eu quis dizer. Manter as coisas que o pip instala em sincronia com as coisas que o pip-tools resolve não é trivial, a menos que você conduza o processo para trás, usando o lockfile resolvido para fazer a instalação. Tenho certeza de que foi por isso que as coisas foram projetadas do jeito que eram.

B) O Pipfile.lock deve obter as versões mais novas que respeitem as restrições / dependências do ambiente para se beneficiar livremente dos intervalos abertos nas dependências Pipfile e lib, permitindo adquirir continuamente novas versões compatíveis em seu ambiente. Você pode então executar pipenv update para se beneficiar do novo bloqueio.

Este fluxo de trabalho pode funcionar possivelmente com a configuração atual. Você pode usar pipenv lock para gerar um arquivo de bloqueio, mas pipenv update reinstalará todo o ambiente. Tenho certeza de que podemos usar um de nossos vários formatos de saída para resolver o gráfico de dependência (já temos um formato json como você sabe) e apenas reinstalar coisas que não estão alinhadas ao arquivo de bloqueio. Isso pode ser mais sensato, mas eu estaria curioso sobre a opinião de @erinxocon antes de tomar uma decisão

@vphilippon Concordo totalmente que A e B são fluxos de trabalho desejáveis ​​em diferentes situações. No entanto, algumas das suas frases em torno de B me confundiram um pouco, parecendo dizer que pipenv lock pode resultar em um arquivo de bloqueio que não corresponde ao ambiente - eu particularmente ouvi isso em que seria necessário "executar pipenv update para se beneficiar do novo bloqueio "- como se o bloqueio estivesse" à frente "do ambiente ao invés de combiná-lo.

Independentemente de você estar em um fluxo de trabalho A ou B, algumas coisas parecem constantes para mim, e acho que isso está de @techalchemy está dizendo também:

  • O resultado de pipenv lock deve ser sempre um arquivo de bloqueio que corresponda ao ambiente.
  • O resultado de pipenv install deve sempre ser um ambiente que corresponda ao lockfile.

Estou ignorando os detalhes de implementação, mas esse é o tipo de comportamento básico que espero de um gerenciador de pacotes com um recurso lockfile.

Executar pipenv update periodicamente permite que você fique no modo B enquanto quiser que tudo esteja fresco, e ter a capacidade de pipenv install --upgrade requests permitiria atualizações específicas de um pacote e suas dependências, sem afetar os pacotes que não precisam ser atualizados desnecessariamente.

Estou perdendo algum caso de uso? Posso pensar em otimizações para B - por exemplo, um sinalizador ou env var que diz a ele para sempre atualizar avidamente - mas acho que cobre o básico. Também sei que estou reformando um terreno que você já percorreu; é apenas útil para mim ter certeza de que entendi o que você está falando. :)

Algumas das suas frases em torno de B me confundiram um pouco, porém, parecendo dizer que o bloqueio pipenv pode resultar em um arquivo de bloqueio que não corresponde ao ambiente

@brettdh isto está correto - o pip-tools resolvedor que usamos para gerar Pipfile.lock não pede ao virtualenv uma lista de quais pacotes foram instalados. Em vez disso, ele compila uma lista de pacotes que atendem aos critérios especificados na lista de pinos de Pipfile . Como o resolvedor em si é executado usando o sistema ou a instalação externa de python / pipenv / pip-tools, estamos fazendo alguma merda suprema para convencê-lo a resolver pacotes com a mesma versão de python usada no virtualenv. A suposição seria que pip install resolveria as coisas de maneira semelhante, mas nem sempre é o caso, embora eu não tenha 100% de certeza disso. Mas sim, pipenv lock não é gerado com base no virtualenv, ele é gerado com base no Pipfile . É um arquivo de bloqueio de resolução de dependência, não um pino de estado do ambiente.

Como uma solução potencial para isso: algo que o próprio pip atualmente suporta, mas pip-compile não, é a noção de um arquivo de restrições.

Um arquivo de restrições difere de um arquivo de requisitos, pois diz " Se este componente estiver instalado, ele deve atender a esta restrição de versão". No entanto, se um pacote específico no arquivo de restrições não aparecer na árvore de dependências em nenhum lugar, ele não será adicionado ao conjunto de pacotes a serem instalados.

Este é o recurso que está faltando em pipenv , já que as entradas desejadas para a geração Pipfile.lock são:

  1. O conteúdo atualizado de Pipfile como um novo arquivo de entrada de requisitos
  2. O conjunto completo de dependências existentes de Pipfile.lock como um arquivo de restrições, excluindo os pacotes especificamente nomeados no comando atual

O suporte do arquivo de restrições no nível do resolvedor de ferramentas pip seria o suficiente para pipenv suportar um modo em que as tentativas de atualizações implícitas de dependências falhariam como uma violação de restrição, permitindo ao usuário decidir se deseja ou não adicionar esse pacote para o conjunto que está sendo atualizado.

atualmente não suportado, obrigado pelo feedback

@kennethreitz

Você quer dizer:

  1. Este comportamento deve ser alterado, mas não é uma prioridade no momento,
  2. Este comportamento deve ser adicionado como opcional, mas não é atualmente uma prioridade, ou
  3. Este comportamento não deve ser adicionado?

Isso é um inconveniente suficiente, dada a inconsistência com a forma como outros gerenciadores de pacotes de bloqueio semelhantes funcionam, que seria bom mantê-lo aberto como uma solicitação para PRs.

Se, em vez disso, for (3), e isso não será adicionado, então acho que vários de nós sobre o problema precisaremos ajustar nossos planos para nossa escolha de ferramentas de gerenciamento de pacotes Python.

Quer dizer, isso não é compatível no momento e agradeço o feedback.

Eu entendo que não é compatível. Você também está dizendo que não aceitaria os PRs alterando esse comportamento ou adicionando isso como uma opção?

Eu não faço ideia.

@ k4nar ainda está interessado em fazer uma RP para isso? Especificamente, algo como pipenv install --only <dep-to-update que evita que dependências não relacionadas sejam atualizadas. Visto que @kennethreitz parece desinteressado em discutir mais, parece-me que essa é a única maneira de descobrir se essa adição / mudança de comportamento seria aceitável (e, por extensão, se pessoas como @taion e eu podemos continuar usando pipenv).

Estou interessado, mas não tenho certeza de saber qual seria a melhor maneira de implementar isso. Existem muitos componentes em ação (pip, pip-tools, pipfile, pipenv ...) e provavelmente muitas soluções possíveis.

Por https://github.com/kennethreitz/pipenv/issues/966#issuecomment -339707418, deve ser relativamente simples. Essa lógica de resolução de dep é basicamente apenas de pip-tools. Eu estava planejando enviar um PR, mas não posso justificar gastar o trabalho se não estivermos dispostos a falar sobre como queremos que a API pareça antes de gastarmos tempo escrevendo o código.

No momento, estou procurando uma abordagem alternativa - como Pipfile é um padrão, as interações com ele não precisam passar pelo pipenv e gostaria de trabalhar em torno de algumas das outras semânticas estranhas aqui, como limpar virtualenvs existentes por https : //github.com/kennethreitz/pipenv/issues/997.

Desculpe comentar sobre um problema encerrado, mas gostaria de salientar que, no meu entendimento, usar pipenv em meus projetos atualmente requer um fluxo de trabalho como este:

pipenv install foo
vim Pipfile.lock  # Manually remove all the unwanted updates
git add && git commit && git push

Acho muito chato ter de comunicar isso aos membros da minha equipe. A alternativa parece ser fixar tudo em versões exatas em Pipfile , mas isso anula muito do propósito de usar pipenv em primeiro lugar.

IIUC, este comportamento é o equivalente a apt realizando um apt dist-upgrade implícito sempre que você executa apt install foo .

Isso é piorado pelo fato de que pipenv install atualiza coisas em Pipfile.lock , mas não instala as atualizações no virtualenv local. Se o desenvolvedor não examinar cuidadosamente a diferença de Pipfile.lock , eles ainda estão usando as versões mais antigas localmente, mas uma vez que compartilham o código, todos os outros ambientes veem as atualizações surpreendentes. As pessoas tendem a ignorar o diff de Pipfile.lock porque ele é considerado um arquivo gerado automaticamente.

Estou fortemente convencido de que "atualizar tudo para a versão mais recente permitida por Pipfile " deve ser uma operação solicitada explicitamente, separada de "instalar o foo".

deve ser corrigido no mestre

O comportamento ainda está presente, testei-o em pipenv 11.8.3 , @kennethreitz.

@ marius92mc O comentário "corrigido no mestre" refere-se às opções --selective-upgrade e --keep-outdated adicionadas em lançamentos recentes: https://docs.pipenv.org/#cmdoption -pipenv-install-keep - desatualizado

Isso permite que as pessoas que precisam ou desejam mais controle sobre exatamente quando as atualizações acontecem optem por esse comportamento, enquanto o comportamento padrão continua a respeitar o OWASP A9 e pressiona por atualizações ansiosas a cada oportunidade.

@ncoghlan Acho que uma coisa necessária (fácil de pedir, não tão fácil de fazer) é um FAQ sobre _como_ essas opções se comportam (pelo menos ainda é confuso para mim).

Por exemplo: Usar --selective-upgrade e --keep-outdated ainda fará com que bibliotecas desatualizadas em Pipfile.lock sejam atualizadas, se não estiverem diretamente relacionadas ao pacote "selecionado" a ser atualizado .

Parece que pode haver bugs de implementação, então.

O objetivo deles é deixar o pipfile.lock como está, exceto para a nova alteração.

Deixe-me saber se é útil fornecer um teste Pipfile + .lock.

Acho que você forneceu informações suficientes para que possamos investigar. Vou tentar fazer isso agora.

Na verdade, seu pipfile / lock seria ótimo, se contiver resultados desatualizados.

@ncoghlan , obrigado por fornecer os detalhes.
Tentei novamente com as opções mencionadas e o resultado parece ser o mesmo, ainda atualiza os outros pacotes também, alterando-os no arquivo Pipfile.lock .

Há alguma atualização sobre esse problema, @kennethreitz?

Desculpe pelas respostas lentas sobre isso. Ainda não descobrimos a causa raiz da regressão aqui (eu sei que pessoalmente estive lidando com uma migração de data center neste fim de semana, então estou meio lento), mas vamos resolver isso nos próximos dias.

As contribuições são bem-vindas como sempre!

Acho que está faltando um caso de uso que pode usar essa mesma mudança: quando estou desenvolvendo um aplicativo, geralmente preciso atualizar a versão de uma única dependência. As etapas que eu gostaria de seguir são:

  1. Atualize a restrição de versão para a dependência em setup.py
  2. Execute pipenv lock --selective-upgrade ; pipenv sync ou pipenv install --selective-upgrade "-e ."

@wichert Se Pipfile foi editado de uma forma que aumenta a versão mínima exigida além do que está no arquivo de bloqueio atual, então --keep-outdated já deve cobrir o que você precisa. --selective-upgrade é para o caso em que Pipfile não mudou, mas você deseja atualizar para uma nova versão fixada de qualquer maneira.

@ncoghlan Pipfile não mudou neste cenário, apenas setup.py alterando o requisito de versão mínima para uma dependência, normalmente para algo mais recente e atualmente em Pipfile.lock .

@wichert pipenv não captura alterações em seu setup.py automaticamente porque não são ferramentas de configuração. Você tem que executar pipenv lock se quiser que isso aconteça.

Qual é o status atual disso? Em 25 de março, alguém disse que achava que os problemas de implementação seriam resolvidos "nos próximos dias", e outros relatórios de bug foram fechados devido ao rastreamento aqui; mas a partir de 2018.7.1 ainda vejo o bug relatado por Simon Percivall (dependências indiretas são sempre atualizadas) e esse bug não foi discutido desde o relatório original. O problema ainda está sendo rastreado?

(Atualmente estou morando em uma cidade de segundo nível no Senegal, então minha Internet é terrível e seria uma virada de jogo não estourar meu limite de dados na atualização de dependências indiretas, se possível: P)

PS: Obrigado por fazer Pipenv, é incrível <3

Sim com certeza. Estamos reescrevendo o resolvedor para oferecer suporte a isso agora. Se isso acontecerá neste lançamento ou no próximo, ainda veremos

Não estou tão confiante com minha habilidade de codificação para estimar quando o resolvedor pousaria: p Sério, este é um projeto totalmente voluntário e não temos um mecanismo de prazo como você teria em ambientes comerciais (nem mesmo temos um chefe ou gerente de projeto ou o que quer que você tenha em sua empresa que decide quando uma coisa precisa ser feita). Se você deseja que algo seja feito no prazo que deseja, precisa fazer você mesmo ou, pelo menos, fornecer motivação real para que outros o façam.

@uranusjr FWIW, não vi nenhuma exigência de expediente no comentário de @benkuhn acima - apenas uma pergunta sobre onde as coisas estão; isto é, que trabalho foi feito, para que observadores externos possam fazer suas próprias estimativas / decisões.

Eu entendo que pipenv é um projeto voluntário e que não contribuintes não podem pedir que algo seja feito até uma data sem se inscrever para que isso aconteça. Eu me pergunto se há espaço para mais transparência no processo de desenvolvimento do projeto ou se simplesmente não estou procurando nos lugares certos. Normalmente a resposta é "se o problema não foi atualizado, não houve movimento" ou "olhe para esta solicitação de pull WIP", mas esse problema em particular parece ter desencadeado um esforço muito maior, então os pontos podem ser difíceis para conectar para aqueles não diretamente envolvidos.

Como sempre, muito obrigado a você e a todos que dedicam seu valioso tempo para o aprimoramento do pipenv. 👏

Com certeza, este não tem atividade ou um PR de trabalho em andamento porque é muito mais complicado do que isso. Estamos falando internamente principalmente sobre como queremos estruturar isso em relação ao projeto maior e trabalhar iterativamente para estabelecer uma abordagem que pode até começar a funcionar corretamente. Uma vez que possamos resolver isso, podemos construir uma lógica de resolução.

Nesse ínterim, a pilha do resolver no pipenv é super complicada e eu não ficaria confortável em pedir às pessoas que investissem muito esforço tentando desvendá-la para esse propósito. Mesmo o caso de uso mais simples aqui exigirá uma refatoração significativa. Ficaríamos felizes em revisar / discutir qualquer refatoração proposta se alguém estiver interessado em ajudar a resolver isso, mas as duas coisas estão intimamente ligadas.

Se alguém tem experiência em resolução de dependências e solução de problemas, certamente estaríamos interessados ​​em receber informações, mas ainda não há uma única ideia concreta. Já passamos por várias iterações que nunca planejamos levar adiante como mais do que uma prova de conceito. Nem todo código se torna um PR, e nem todas as decisões de organização de código acontecem no rastreador de problemas. Às vezes, conversamos sincronicamente e propomos e descartamos ideias em tempo real.

Algo que _continuarei_ a sugerir como um fluxo de trabalho alternativo que pode resolver isso é facilitar a fixação de uma versão específica no _Pipfile_ durante a instalação.

Eu acho que é um pouco surpreendente, mas não completamente irracional, que pipenv interprete foo = "*" como "Eu só preciso ter certeza de que _alguma_ versão do foo está instalada, o usuário não se importa qual". Para esse fim, ter algo como pipenv install --pin foo que resulta em foo = "==1.2.3" vez de foo = "*" no Pipfile (onde 1.2.3 é a versão atual mais recente de foo) parece que pode Socorro.

O problema com isso é que o comportamento de muitos pacotes pode mudar muito com base em suas dependências (por exemplo, a mesma versão do pylint pode fazer coisas totalmente diferentes dependendo da versão do astroid que está usando), e os pacotes não fixe seus próprios departamentos exatamente. Portanto, não acho que isso leve ninguém muito longe. : /

(Acabei de perceber que estou comentando sobre o problema errado. Desculpe pela bagunça, por favor, me ignore) 😞

Um caso de uso real com o qual tenho lutado por algumas horas: quero medir a cobertura de teste em um projeto Django 2.0. Mesmo pipenv install --keep-outdated --selective-upgrade --dev coverage insiste em atualizar o pacote Django não-dev para a versão 2.1, que por causa da quebra em outro lugar eu absolutamente não posso usar ainda. Realmente deve haver uma maneira de mudar o conjunto de pacotes instalados sem atualizar pacotes completamente não relacionados para versões possivelmente quebradas. A possibilidade de ruptura na versão mais recente sempre existirá.

Vou tentar a solução alternativa de @rfleschenberg , mas não sei se ter uma propriedade _meta hash presumivelmente incorreta quebrará alguma coisa.

@ l0b0 Se seu aplicativo realmente não consegue lidar com uma versão específica do Django, acho que faz sentido declarar essa restrição em seu Pipfile.

@AlecBenzer Isso soa como algo para setup.py para mim.

@wichert Isso também pode fazer sentido (na verdade, não estou totalmente certo em quais circunstâncias você gostaria de ter um setup.py e um Pipfile), mas se você tiver uma linha em seu Pipfile que diz:

Django = "*"

você está dizendo ao pipenv que deseja instalar _qualquer_ versão do Django. Se o que você realmente deseja fazer é instalar 2.0 ou inferior, diga-lhe que:

Django = "<=2.0.0"

Embora neste caso em particular o pipenv esteja atualizando o Django sem nenhuma razão real, pode ser que em algum momento você tente instalar um pacote que requer Django> 2.0.0, em cujo ponto pipenv o instalará alegremente se você não tiver informado que você precisa de <= 2.0.0.

Se o que você realmente quer fazer é instalar 2.0 ou inferior, diga a ele que

@AlecBenzer refletindo, agora me ocorre que é isso que o npm / yarn faz por padrão quando você instala um pacote; eles encontram a versão major.minor mais recente e especificam ^major.minor.0 em package.json, o que evita atualizações inesperadas de versão principal, mesmo quando uma atualização para a última é explicitamente solicitada. Eu me pergunto se Pipenv deveria fazer o mesmo - mas isso seria um problema separado.

Claro, seu arquivo de bloqueio também evita atualizações acidentais até mesmo de versões menores e de patch, que é o que está sendo solicitado aqui.

Acho que isso foi discutido acima e em outros lugares, mas há uma tensão / compensação no espaço de design entre npm / yarn e pipenv. Qualquer gerenciador de pacotes ostensivamente tem esses objetivos, com alguma prioridade relativa:

  • Facilite a instalação e atualização de pacotes
  • Torne difícil quebrar acidentalmente seu aplicativo com uma atualização de dependência errônea

O problema de fixar uma versão exata no Pipfile é que fica mais difícil atualizar os pacotes; é por isso que existem

O sinalizador --keep-outdated não parece estar funcionando conforme o esperado, conforme declarado quando o problema foi reaberto. Se esse comportamento deve ou não ser o padrão e como ele se alinha com outros gerenciadores de pacotes não é realmente a questão central aqui. Vamos consertar a coisa primeiro.

@brettdh

refletindo, agora me ocorre que é isso que o npm / yarn faz por padrão quando você instala um pacote; eles encontram a versão major.minor mais recente e especificam ^ major.minor.0 em package.json, o que evita atualizações inesperadas de versão principal, mesmo quando uma atualização para a última é explicitamente solicitada. Eu me pergunto se Pipenv deveria fazer o mesmo - mas isso seria um problema separado.

Sim, está na mesma linha do que eu estava tentando sugerir em https://github.com/pypa/pipenv/issues/966#issuecomment -408420493

Estou muito animado para saber que isso está sendo trabalhado!

Nesse ínterim, alguém tem uma solução alternativa sugerida que é menos trabalhosa e sujeita a erros do que executar pipenv lock e reverter manualmente as alterações de lockfile resultantes que eu não desejo aplicar?

@benkuhn Não que eu saiba - eu faço a mesma dança de travar e reverter o tempo todo.

Ah, ok, você pode, pelo menos às vezes, evitar a reversão manual:

  1. pipenv lock
  2. git commit -m "FIXME: revert"
  3. pipenv install packagename
  4. git commit -m 'Add dependency on packagename'
  5. git rebase -i
  6. Abandone o FIXME: revert commit

Infelizmente ainda é possível criar um Pipfile.lock inconsistente se o seu Pipfile.lock começar contendo uma versão de um pacote que é muito antigo para satisfazer os requisitos de packagename , mas talvez pipenv reclamará sobre isso se acontecer?

--keep-outdated parece manter sistematicamente desatualizado apenas as dependências explícitas que são especificadas (não fixadas) no Pipfile, enquanto todas as dependências implícitas são atualizadas.

Estou correto que não é possível atualizar / instalar dependência única usando pipenv==2018.7.1 sem atualizar outras dependências? Tentei diferentes combinações de --selective-upgrade e --keep-outdated sem sucesso.

Editar Pipfile.lock manualmente não é divertido ...

Igual a @ max-arnold, é meu primeiro dia usando a ferramenta em um projeto existente, e devo dizer que estou muito desapontado , antes de começar a usar, verifiquei o site de doc e a demonstração de vídeo, parecia impressionante para mim, e agora isto: no projeto real, trabalhar com pip ou pipenv é quase o mesmo, não vejo o ponto, como muitos outros disseram no tópico, se eu tiver um arquivo de bloqueio, porque você está atualizando minhas outras dependências se não há necessidade de atualizá-las.

Claro, ### se a atualização for obrigatória, não há problema em atualizar todas as dependências necessárias, mas apenas essas, não todas desatualizadas.

Além disso, as opções --selective-upgrade e --keep-outdated não são claras para o que são úteis, há outro problema destacando isso aqui # 1554, e ninguém é capaz de responder o que essas opções fazem, incrível.

Mas minha maior decepção é porque este pacote foi recomendado pela própria pip , que também não resolve esses problemas, mas pelo menos é muito minimalista e está geralmente incluído em qualquer ambiente (não adiciona dependências extras).

@mrsarm Obrigado por sua opinião. Desculpe, as coisas não funcionam para você. Não entendo de onde vem a decepção, entretanto. Ninguém está forçando Pipenv a ninguém; se não funcionar para você, não use. É assim que as recomendações funcionam.

Seu discurso também não tem nada particularmente relacionado a esse problema. Eu entendo que é necessário um pouco de autocontrole para não jogar lixo nas pessoas quando as coisas não acontecem do seu jeito, mas, por favor, mostre algum respeito e evite fazer isso.

@uranusjr não é lixo, é uma opinião, e às vezes não é uma opção, como no meu caso, onde alguém escolheu o pipenv para fazer um projeto onde comecei a trabalhar agora e tenho que lidar com isso.

Mas agora as coisas estão piorando, e o que vou dizer não é uma opinião, é um fato.

Depois de tentar adicionar uma dependência que acabei de dispensar para evitar lidar com esse problema (porque é uma dependência dev, então criei um segundo ambiente com pip e a antiga abordagem requirements-dev.txt , apenas com essa ferramenta), eu precisava adicionar outra dependência.

A nova dependência é PyYAML, digamos a versão mais recente. Se você instalá-lo em qualquer novo ambiente com pip , verá que a biblioteca não adiciona nenhuma dependência, portanto, apenas PyYAML é instalado, é tão simples nesses casos com Pip. Mas adicionando a dependência com Pipenv (porque um projeto que eu não criei é gerenciado com Pipenv) o mesmo problema aconteceu, apesar de PyYAML não ter nenhuma dependência e não estar instalado anteriormente no projeto (uma versão mais antiga), pipenv atualiza todas as minhas dependências no arquivo de bloqueio e no ambiente virtual, mas não quero atualizar as outras dependências, apenas um para adicionar um único novo módulo sem nenhuma dependência.

Então a conclusão (e novamente uma opinião, não um fato como o pipenv quebrou todas as minhas dependências) é que o Pipenv em vez de me ajudar a lidar com o gerenciamento de dependências, ele o transformou em um inferno.

Eu acompanho esse tópico há meses e acho que qualquer projeto real acabará por tropeçar nesse problema, porque o comportamento é inesperado, contra-intuitivo e, sim: perigoso.

Há cerca de um mês, experimentei uma alternativa mais abrangente a pipenv , poetry ; resolveu os problemas que _I_ precisava resolver:
1) gerenciamento de um conjunto de dependências (setup.py, setup.cfg, pip e pipfile -> pyproject.toml)
2) orientado para o futuro, compatível com versões anteriores (novamente pyproject.toml )
3) bastante sem opinião ( não, realmente não estou pedindo para instalar redis )
4) e a solução para o problema clássico do Pipenv: "Além disso, você deve dizer explicitamente a ele [pipenv] para não atualizar os pacotes bloqueados quando instalar novos. Este deve ser o padrão." [[1] (https://github.com/sdispater/poetry#what-about-pipenv)] [[2] (https://github.com/pypa/pipenv/issues/966#issuecomment-339117289)]

Eu ponderei compartilhar essas idéias sobre a questão de pipenv , mas como @uranusjr disse, "ninguém está forçando Pipenv a ninguém", e eu não estou forçando Poesia. Eu gosto, funciona bem e resolve meus problemas, mas estou apenas compartilhando uma solução alternativa e mais abrangente para o problema que estava tendo. Considere tudo isso como meus 2 centavos.

  • como isenção de responsabilidade, não sou membro da equipe de Poesia ou afiliado a ela.

ps Eu acho que a preocupação de Pipenv ser a solução "oficial" é devido às suas integrações de primeira classe - algo que você, @uranusjr , pode ver como uma recomendação simples - a indústria em geral está considerando-a como a "abordagem abençoada em andamento frente". Francamente, essa recomendação é mais confiável na comunidade do que certos PEPs que existem há mais de um ano.

Ninguém o está forçando a participar de nosso rastreador de problemas; se você não tiver um comentário produtivo, encontre um fórum que não seja para triagem de problemas.

Para usuários interessados ​​em experimentar o resolvedor alternativo que @uranusjr e eu estamos implementando há várias semanas, experimente https://github.com/sarugaku/passa, que gerará arquivos de bloqueio compatíveis. A poesia faz muitas coisas diferentes, mas também tem limitações e problemas em si, e temos uma divergência de filosofia de design sobre o escopo.

Este é um projeto que administramos em nosso tempo livre; se você quiser ver algo consertado ou tiver uma abordagem melhor, ficaremos felizes em aceitar contribuições. Se você está aqui simplesmente para nos dizer que arruinamos seu dia e seu projeto, pedirei apenas uma vez para ver você mesmo.

Não esquecemos ou ignoramos esse problema, temos uma implementação completa de uma correção no resolvedor com link acima. Tenha paciência, seja cortês ou encontre outro lugar para conversar. Para aqueles que têm esperado pacientemente por uma solução, experimente o resolvedor mencionado acima - estamos ansiosos para ver se ele atende às suas necessidades. Ele implementa backtracking e resolução adequados e não deve lidar com essa estratégia de atualização

Em um prazo mais curto, acho que podemos colocar um band-aid para isso em pipenv se não acabarmos cortando primeiro.

@dfee Não tenho certeza de que confundir as linhas entre aplicativos e bibliotecas seja a resposta correta para o gerenciamento de dependências, então não vejo a abordagem da poesia como uma vantagem. Eu não estava envolvido em nenhum dos seus problemas com o mecanismo de recomendação, mas nós o retiramos há algum tempo ...

@techalchemy

Não tenho certeza de que confundir as linhas entre aplicativos e bibliotecas seja a resposta correta para o gerenciamento de dependências, portanto, não vejo a abordagem da poesia como uma vantagem.

Porquê? Nunca entendi essa ideia de que você deve gerenciar as dependências de uma biblioteca e de um aplicativo de maneira diferente. A única diferença entre os dois é o arquivo de bloqueio que é necessário para um aplicativo garantir um ambiente reproduzível. Fora isso, é a mesma coisa. Este é o padrão na maioria das outras linguagens e Python parece a exceção aqui por algum motivo e isso é ruim do ponto de vista da experiência do usuário, pois está tornando as coisas mais complexas do que deveriam.

também tem limitações e problemas próprios

Quais? Estou realmente curioso sobre os problemas ou limitações que você encontrou ao usar a Poesia.

Minhas desculpas por ser tão rude. Agora, lendo meus comentários, percebo que apesar das informações que forneci e de algumas das minhas opções ainda serem válidas (IMHO), elas não foram apropriadas da forma como escrevi o que queria dizer.

Eu entendo que o rastreador de problemas é mais um lugar onde discutir bugs e melhorias, e discutir se isso é um bug ou um erro de design não está claro no tópico, mas, novamente, minhas desculpas.

Acho que há dois tópicos fortes aqui:

  • O pipenv deve atualizar todas as suas dependências desatualizadas onde você está tentando apenas instalar uma nova dependência: aquelas que não são necessárias para atualizar porque o novo pacote / versão que estamos tentando instalar pode funcionar com as dependências existentes, e mesmo as que não Há dependências do novo pacote que estamos tentando instalar? Talvez isso esteja fora do escopo deste tíquete, mas é um tópico muito importante para discutir.
  • Um desses parâmetros --keep-outdated --selective-upgrade nos permite evitar esses comportamentos? Não está claro o que essas opções fazem, há uma falta de documentação sobre elas, e mesmo na edição relacionada (# 1554) ninguém está respondendo a isso.

No caso de ser um bug em um desses parâmetros --keep-outdated --selective-upgrade , ainda estou pensando que não definir nenhum parâmetro resolve a atualização desnecessária das dependências como padrão é uma péssima ideia.

Para comparar com um cenário semelhante, imagine que você execute apt-get install vim apenas para instalar a ferramenta vim em seu sistema (e as dependências ou atualizações necessárias do vim, se aplicável), mas imagine também que nesta situação apt atualiza todas as outras dependências do seu sistema: python, o sistema QT, o kernel Linux ... e assim por diante. Não é que o apt não deva nos permitir atualizar outras dependências, mas há um comando claro para fazer isso: apt-get upgrade , enquanto apt-get install PACKAGE apenas instale / atualize PACKAGE e suas dependências.

@sdispater a distinção está no cerne de cada desacordo que já tivemos e é incrivelmente sutil, mas eu diria para você https://caremad.io/posts/2013/07/setup-vs-requirement/ ou um bom artigo para o caso de uso do elixir: http://blog.plataformatec.com.br/2016/07/understanding-deps-and-applications-in-your-mixfile/

pyproject.toml não é realmente compatível com metadados de definição de biblioteca - e nem um pouco por qualquer versão do pip que não implemente peps 517 e 518 (os quais ainda estão tendo os detalhes de implementação resolvidos) como um autoritário arquivo de declaração da biblioteca. setup.cfg existe para esse propósito (o sucessor real de setup.py ) e IMHO ambos devem realmente ser suportados. Uma biblioteca é publicada e destinada ao consumo com dependências abstratas para que possam jogar bem na sandbox com outras pessoas; os aplicativos geralmente são bestas grandes e complexas, às vezes com centenas de dependências diretas. Portanto, uma das nossas principais divergências é que, quando projetamos e construímos nossas ferramentas, levamos isso em consideração também

@mrsarm Para sua primeira pergunta, o comportamento da atualização foi intencional (e foi amplamente discutido na época, / cc @ncoghlan e relacionado a questões de segurança do OWASP). No segundo ponto, o comportamento não está implementado corretamente, é por isso que o problema ainda está aberto, o que nos levou a reescrever o resolvedor de apoio atrás do pipenv, que mencionei acima. Simplesmente não suportava esse comportamento. --selective-upgrade deve atualizar seletivamente apenas coisas que são dependências do novo pacote, enquanto --keep-outdated impediria qualquer coisa que satisfizesse as dependências exigidas por um novo pacote. Um pouco diferente, mas tenho quase certeza de que nenhum dos dois está funcionando corretamente agora.

pyproject.toml não é realmente compatível com metadados de definição de biblioteca - e nem um pouco por qualquer versão do pip que não implemente peps 517 e 518 (ambos os quais ainda estão tendo detalhes de implementação resolvidos) como um arquivo de declaração de biblioteca autorizado . O setup.cfg existe para esse propósito (o sucessor real do setup.py) e o IMHO ambos devem realmente ser suportados.

Bem, isso certamente está fora do tópico, mas é uma discussão importante, então não posso evitar.

Na verdade, não existe um padrão em torno de setup.cfg agora, além das convenções estabelecidas por distutils e ferramentas de configuração. pyproject.toml é absolutamente para metadados de biblioteca como o sucessor de setup.py ou a comunidade teria colocado requisitos de construção em setup.cfg .

pyproject.toml descreve como construir um projeto (PEP 518), e parte da construção descreve metadados. NÃO estou dizendo que pyproject.toml precisa de um local padrão para esses metadados, mas o PEP 518 usa esse arquivo para instalar uma ferramenta de compilação e, a partir daí, é muito razoável esperar que a ferramenta de compilação use a configuração declarativa de outro lugar no arquivo para determinar como construir o projeto.

De qualquer forma, voltando ao pipenv vs poesia - parece haver uma ideia flutuando de que os aplicativos não precisam de certos recursos que as bibliotecas obtêm, como pontos de entrada, e isso é simplesmente incorreto. Deve ser simples para um aplicativo ser um pacote python.

A única diferença verdadeira entre um aplicativo e uma biblioteca em minha experiência com python e com outros ecossistemas é se você está usando um lockfile ou não. Claro, há um terceiro caso em que você realmente quer apenas requirements.txt ou Pipfile e nenhum código real e isso parece ser tudo que o pipenv se concentrou até agora ( pipenv install -e . quedas nesta categoria, pois o pipenv ainda tem medo de tentar dar suporte aos metadados do pacote). Infelizmente, embora o design do pipenv seja mais limpo com esta abordagem, também é menos útil para a maioria dos aplicativos porque o PEP 518 decidiu punt sobre como instalar projetos no modo editável, então, para continuar usando o pipenv, ficaremos presos nas ferramentas de configuração. enquanto você não pode usar pyproject.toml para sair das ferramentas de configuração e ainda usar pipenv install -e . .

Na verdade, não existe um padrão em torno de setup.cfg agora, além das convenções estabelecidas por distutils e setuptools. pyproject.toml é absolutamente para metadados de biblioteca como o sucessor de setup.py ou a comunidade teria colocado requisitos de construção em setup.cfg.

Distutils faz parte da biblioteca padrão e setuptools é instalado com pip agora, então dizer que não existe um padrão é um pouco bobo. Sem mencionar que usa o padrão descrito no pep 345 para metadados, entre outros, e também pode ser usado para especificar requisitos de construção.

a comunidade teria colocado os requisitos de construção em setup.cfg.

Você quer dizer os autores estimulantes? Você pode perguntar a eles por que tomaram essa decisão, eles descrevem tudo com entusiasmo.

pyproject.toml descreve como construir um projeto (PEP 518), e parte da construção descreve metadados. NÃO estou dizendo que o pyproject.toml precisa de um local padrão para esses metadados, mas o PEP 518 usa esse arquivo para instalar uma ferramenta de compilação e, a partir daí, é razoável esperar que a ferramenta de compilação use a configuração declarativa de algum outro lugar no arquivo para determinar como construir o projeto.

Isso surgiu na lista de discussão recentemente - nada em nenhum lugar declarou um padrão em torno de pyproject.toml além de que será usado para declarar os requisitos do sistema de construção. Qualquer outra coisa é uma suposição; você pode chamar isso de "metadados de definição de biblioteca", mas não é. Tente apenas definir um sistema de construção sem informações adicionais sobre o seu projeto (ou seja, sem metadados compatíveis com pep-345) e carregue-o para pypi e me diga como foi.

De qualquer forma, voltando ao pipenv vs poesia - parece haver uma ideia flutuando de que os aplicativos não precisam de certos recursos que as bibliotecas obtêm, como pontos de entrada, e isso é simplesmente incorreto. Deve ser simples para um aplicativo ser um pacote python.

Quem está dizendo que os aplicativos não exigem pontos de entrada? Pipenv tem uma construção inteira para lidar com isso.

então, para continuar usando o pipenv, ficaremos presos no setuptools por um bom tempo, pois você não pode usar o pyproject.toml para sair do setuptools e ainda usar o pipenv install -e.

Não seguindo aqui ... não vamos deixar o pip vendido na versão 10 para sempre, estou literalmente descrevendo nosso novo resolvedor, e o instalador real apenas recorre ao pip diretamente ... como isso impede que as pessoas usem editáveis instala?

Isso apareceu na lista de discussão recentemente - nada em lugar nenhum declarou um padrão em torno de pyproject.toml

Correto, não é um "padrão", mas nesse mesmo tópico reconheça que, ao chamá-lo de pyproject.toml eles provavelmente pediram que as pessoas usassem esse arquivo para outras configurações / configurações relacionadas ao projeto.

Então, pela mesma lógica que você invocou aqui:

Distutils faz parte da biblioteca padrão e setuptools é instalado com pip agora, então dizer que não existe um padrão é um pouco bobo.

pyproject.toml é um padrão e a comunidade o adotou como o local padrão para colocar informações relacionadas ao sistema de compilação e outras partes de um projeto Python.

Não seguindo aqui ... não vamos deixar o pip vendido na versão 10 para sempre, estou literalmente descrevendo nosso novo resolvedor, e o instalador real apenas recorre ao pip diretamente ... como isso impede que as pessoas usem editáveis instala?

PEP 517 pontuado em instalações editáveis ​​... o que significa que não há uma maneira padrão de instalar um projeto em modo editável se você não estiver usando ferramentas de configuração (que tem um conceito conhecido como modo de desenvolvimento que instala o projeto em modo editável).

Distutils faz parte da biblioteca padrão e setuptools é instalado com pip agora, então dizer que não existe um padrão é um pouco bobo. Sem mencionar que usa o padrão descrito no pep 345 para metadados, entre outros, e também pode ser usado para especificar requisitos de construção.

Sim, é esperado que o sistema de compilação produza o arquivo PKG-INFO descrito no PEP 345. Este é um formato de transferência que vai em um sdist ou wheel e é gerado a partir de um setup.py/setup.cfg, não é uma substituição como como para os metadados voltados para o usuário. O uso de pyproject.toml PEP 518 é sobre o suporte de alternativas para distutils / setuptools como um sistema de construção, ninguém está tentando substituir os formatos sdist / wheel no momento. Esses sistemas de compilação substitutos precisam de um lugar para colocar seus metadados e, felizmente, o PEP 517 reservou o namespace tool. para esses sistemas fazerem isso. Não é uma suposição - tanto o flit quanto a poesia adotaram esse namespace para "metadados de definição de biblioteca".

Tente apenas definir um sistema de construção sem informações adicionais sobre o seu projeto (ou seja, sem metadados compatíveis com pep-345) e carregue-o para pypi e me diga como foi.

Que construtivo.

Quem está dizendo que os aplicativos não exigem pontos de entrada? Pipenv tem uma construção inteira para lidar com isso.

Onde está essa construção? Não consigo nem encontrar a palavra "entrada" em nenhuma página da documentação do pipenv em https://pipenv.readthedocs.io/en/latest/, então "uma construção inteira" parece muito improvável? Se você quer dizer instalações editáveis, então chegamos ao ponto que estava fazendo acima - com o pipenv decidindo se acoplar a pipenv install -e . como a única maneira de conectar e desenvolver um aplicativo como um pacote, para o futuro previsível suporte do pipenv aqui está acoplado a ferramentas de configuração. Acho que toda a controvérsia se reduz a este ponto e as pessoas (certamente eu) estão frustradas por agora podermos definir bibliotecas que não usam ferramentas de configuração, mas não podem desenvolver com pipenv. Para ficar bem claro, não é estritamente culpa do pipenv (PEP 518 decidiu interromper as instalações editáveis), mas sua recusa em reconhecer o problema tem sido frustrante no discurso, já que a poesia fornece uma alternativa que lida com esse problema de uma forma compatível com o formato pyproject.toml . Pipenv vive dizendo que a poesia toma decisões ruins, mas não tenta realmente fornecer um caminho a seguir.

https://pipenv.readthedocs.io/en/latest/advanced/#custom -script-shortcuts

Por favor, leia a documentação.

@bertjwregeer :

pyproject.toml é um padrão e a comunidade o adotou como o local padrão para colocar informações relacionadas ao sistema de compilação e outras partes de um projeto Python.

Ótimo, e estamos felizes em acomodar sdists e rodas construídas usando este sistema e até que haja um padrão para instalações editáveis, continuaremos usando o pip para construir sdists e rodas e lidar com a resolução de dependência dessa maneira. Por favor, leia minhas respostas na íntegra. Os autores e mantenedores do pip, dos peps em questão, e eu e @uranusjr somos muito bem versados ​​nas diferenças entre instalações editáveis ​​e as implicações de

Eu já disse que isso não é correto. Se você estiver realmente interessado na implementação e em ter uma conversa produtiva, ficarei feliz em ter isso. Se você está aqui simplesmente para dizer que não sabemos o que estamos fazendo, mas não estamos interessados ​​em saber primeiro o que estamos fazendo, este é o seu único aviso. Somos voluntários com tempo limitado e estou praticando uma política de tolerância zero para compromissos tóxicos. Não finjo que meu trabalho é perfeito e não finjo que pipenv é perfeito. Terei o maior prazer em contribuir com meu tempo e esforço para esse tipo de discussão; em troca, peço que sejam respeitosos, que se atem aos fatos e que aqueles que participam também estejam dispostos a aprender, ouvir e me ouvir. Se você está aqui apenas para palanque, terá que encontrar outra plataforma; este é um rastreador de problemas. Vou moderar conforme necessário.

Esta discussão está totalmente fora do assunto . Se alguém tiver algo construtivo a dizer sobre o assunto em questão, fique à vontade para continuar essa discussão. Se alguém tiver problemas ou perguntas sobre as implementações do nosso sistema de compilação, abra um novo problema. Se você tiver problemas com nossa documentação, aceitamos muitas solicitações de pull em torno da documentação e estamos cientes de que precisa ser corrigido. Por favor, adie toda essa discussão para novas questões para esses tópicos. E, por favor, observe: as mesmas regras ainda se aplicam - esta não é uma palestra, é um rastreador de problemas.

https://pipenv.readthedocs.io/en/latest/advanced/#custom -script-shortcuts
Por favor, leia a documentação.

Os pontos de entrada são um conceito mais geral do que apenas scripts de console e este link é completamente errado ao tratar dessas questões. <soapbox> Banir - você não é o único mantenedor de grandes projetos de código aberto aqui e nenhum de meus comentários foi um ataque pessoal a você ou ao projeto. As pessoas que comentam aqui estão fazendo isso porque querem usar o pipenv e apreciam muito o que ele faz. Meu comentário não foi a primeira postagem fora do tópico neste tópico, mas é o único marcado. Seus comentários sarcásticos, indicando que você acha que não sei do que estou falando, são embaraçosos e tóxicos.

No projeto que mantemos, podemos palestrar. E sim, o pip suportará todos os sistemas de compilação compatíveis que vocês dois parecem entender muito bem e produzirão metadados consumíveis, e como o pipenv usa o pip como ferramenta de apoio para conduzir seu processo de instalação, como eu descrevi, sim, o pipenv oferecerá suporte a todos os compatíveis ferramentas. Eu já disse isso.

Então, sim, por favor, leve sua toxicidade para outro lugar. Sua atitude não é bem-vinda aqui. Aviso final. Tentativas persistentes de incitar conflito não serão toleradas.

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