Pip: Em direção ao PEP 518

Criado em 21 out. 2017  ·  101Comentários  ·  Fonte: pypa/pip

Estou AWOL neste fim de semana, mas pelo que entendi, precisa haver uma discussão sobre o PEP 518 e sua implementação no pip.

Abri este problema, porque não consegui localizar onde a discussão estava acontecendo, se é que está. Além disso, tê-lo em um lugar que não seja pypa-dev/distutils-sig seria legal?

auto-locked maintenance

Comentários muito úteis

Você precisa de instalações de pip separadas para serem executadas dentro de um subprocesso geralmente, por causa de caches em lugares como pkg_resources eu acredito (embora eu possa estar errado lá).

Isso não significa que você precisa chamar pip , no entanto, você pode criar uma API que serialize dados via CLI e chame python -c "from pip._internals import coolapithing; coolapithing(sys.stdin.read())" e leia mais dados em stdout. Seria possível transformar a solução recursiva de pip chamando pips chamando pips chamando pips transformando-a em uma pilha usando essa API (já que toda recursão também pode ser descrita como uma pilha), você basicamente estaria criando uma API privada que é chamado como um processo.

Ainda estou pensando em ler este tópico (tinha um monte de pratos girando ultimamente!), mas uma coisa: não temos realmente um cronograma de lançamento, lançamos quando estiver pronto, não em alguma data prevista. Às vezes temos uma ideia geral de quando gostaríamos de lançar, mas isso nunca é definitivo.

Todos 101 comentários

4799 é onde muito do debate está acontecendo. Foi principalmente motivado por:

  1. Eu entendi que o único bloqueador pendente para o suporte ao PEP 518 era # 4764 (via https://github.com/pypa/pip/pull/4144#issuecomment-302711736)
  2. Então o número 4799 apareceu e eu olhei para ver se conseguia entender todo o trabalho em andamento que o @xoviat estava fazendo.
  3. No decorrer disso, o #4647 apareceu como um bloqueador de lançamento dizendo que o suporte ao PEP 518 estava quebrado.

Enquanto eu tentava descobrir o que @xoviat estava dizendo em #4799, ficou óbvio que tínhamos alguns problemas em torno da construção recursiva de ambientes de construção (X precisa de Y para construir e Y precisa de Z, ...), embora eu ' Ainda não estou claro se esses são bugs de implementação, problemas de design mais profundos ou casos de canto desagradáveis ​​que podemos adiar sem muitos problemas.

Pessoalmente, estou no ponto em que estou fora da minha profundidade. Não entendo a implementação do @xoviat para julgar se é necessário ou se ainda precisamos mesclar o #4764 e corrigir o #4647 para estar pronto. Nem sei o quão fácil será corrigir o #4647 ( @xoviat parece estar dizendo que precisamos mesclar o #4799 para corrigir o #4647, mas isso traz seus próprios problemas).

Estou sem tempo e energia para levar a discussão adiante neste fim de semana, então vou desistir neste momento (pelo menos por um tempo). Para mim, o ponto-chave é que queremos um nível aceitável de suporte PEP 518 para o pip 10. Gostaria que alguém me desse uma ideia se estamos quase lá ou se estamos a semanas de distância, para que eu pode evitar que as pessoas fiquem empolgadas que o pip 10 está chegando apenas para dizer que não será até o ano novo ...

Obrigado por um resumo muito útil @pfmoore.

@ncoghlan @dstufft @xoviat Podemos trazer a discussão aqui? Fazer isso em um PR fechado parece estranho para mim. ._.

Coisa certa.

@pradyunsg Eu sei que você não tem tempo para isso. Mas você teve mais sucesso em obter aprovação de relações públicas do que eu, então, se você quiser, ficarei feliz em orientá-lo sobre a implementação atual, como ela funciona e os possíveis problemas que ela apresenta. Vou explicar como resolvi alguns (mas não todos) desses problemas e minhas ideias para uma correção completa (o que, novamente, posso fazer após o PEP 517, se não for feito). Eu honestamente não me importo com quem faz o trabalho, desde que seja feito.

Na verdade, você está AWOL, então deixe-me escrever um resumo:

pip tem uma hierarquia de objetos, como é comum na maioria dos projetos Python. Tudo começa com o comando, que cria novas referências a objetos, que criam novas referências a objetos inferiores. É como uma árvore.

Vou definir o "escopo" de um objeto como uma espécie de vida. É a duração que um objeto existe. Neste momento, o escopo do PEP 518 em pip é o WheelBuilder . O ambiente PEP 518 é configurado para bdist_wheel , então bdist_wheel é executado nesse ambiente e, em seguida, o ambiente é desmontado.

Então qual é o problema com isso? O problema é que o escopo do ambiente PEP 518 precisa ser igual ou maior que o escopo de todas as chamadas para setup.py . Mais especificamente, ele precisa encapsular um objeto que existe durante as chamadas setup.py . Esse objeto é Requirement .

A primeira decisão óbvia que você encontrará é: o que deve ter uma referência a BuildEnvironment , e o Requirement é um bom lugar como qualquer outro. Na verdade, é o melhor lugar IMHO para colocar a referência porque setup.py é chamado se e somente se Requirement existir.

O próximo problema que você pode encontrar é este: como instalamos os requisitos BuildEnvironment ? Poderíamos apenas desembolsar pip . E essa é a decisão que foi tomada pelo implementador original. Mas há um problema com isso: pip não tem como saber quantas chamadas de shell está fazendo porque cada pip poderia chamar a si mesmo novamente. Na verdade, um pacote mal-intencionado com dependências circulares pode travar o computador de alguém se pip gerar muitos processos.

Outro problema é que chamada de shell devemos fazer? Na verdade, é mais complicado do que você imagina, porque obter os parâmetros da linha de comando é francamente um PITA em que você precisa fazer essa chamada. Portanto, você pode ter problemas para passar os parâmetros originais que o usuário passou para o filho. A solução usada pelo implementador original envolveu o uso do finder , mas acho que você conhece o problema com isso.

Desembolsar um filho seu sem algum tipo de classe de gerenciador que pode matar filhos quando o usuário pressiona ctrl + C não é apenas errado, é malicioso, especialmente quando você não sabe quantos processos você gerou. Eu pessoalmente não sei se as crianças morrem na implementação atual (isso pode ser FUD), mas se não morrerem, a implementação atual IMHO está errada (além de outras preocupações).

Algumas soluções possíveis para esse problema são as seguintes:

  1. Se você deseja obter o PEP 518, sua melhor aposta é provavelmente algum tipo de arquivo de bloqueio que permite apenas até 10 bloqueios ou mais para garantir que o pip não esteja se multiplicando infinitamente. Então você pode simplesmente passar os requisitos exatos para o filho junto com os argumentos da linha de comando.

  2. Uma solução adequada, que eu gostaria de implementar após o PEP 517, é ter uma classe BuildEnvironmentManager inicializada diretamente no comando install . o BuildEnvironmentManager teria uma referência a todos os objetos lá ( RequirementPreparer , WheelBuilder , etc.), e teria um único método: get_build_environment(requirement_set) . Você poderia então implementar um método em RequirementPreparer que é algo como set_build_environment_manager , que pode ser usado para obter ambientes de compilação. O BuildEnvironmentManager pode até detectar vários usos do mesmo ambiente (mais comumente ['setuptools', 'wheel'] ) e fornecer o mesmo ambiente se for necessário várias vezes para que você não precise criá-lo ( muito comum inicialmente com projetos sem pyproject.toml ). Idealmente, também haveria algum design OOP para tentar remover as referências circulares (não triviais).

@xoviat Embora possa não cobrir o caso de malícia deliberada, estou certo em pensar que um cache de compilação (que foi usado mesmo quando --no-binary :all: foi especificado) com a capacidade de rastrear não apenas compilações concluídas, mas também em -progress, seriam suficientes para garantir que os ciclos de dependência de compilação terminassem? Esta seria uma variante de sua primeira sugestão (um limite de processo cruzado no número de invocações de pip simultâneas), mas reformulada como:

  1. Apenas um processo em uma máquina pode construir o mesmo pacote ao mesmo tempo
  2. Há um "id de compilação" de nível superior que o pip passa para qualquer subcompilação que ele gera (por exemplo, o PID do processo de nível superior combinado com o nome do pacote que está sendo construído)
  3. Se o cache de compilação indicar que algo está sendo compilado por um ID de compilação diferente , aguarde a conclusão dessa compilação
  4. Se o cache de compilação indicar que algo já está sendo compilado para o mesmo ID de compilação, saia com um erro relatando a dependência circular e indicando que --binary <name> será necessário para que a compilação funcione

pip também precisaria implementar a sugestão de @pfmoore de isentar setuptools & wheel da lógica padrão de precisar de setuptools e wheel como dependências de compilação, caso contrário, a injeção de dependência de compilação implícita acionaria inerentemente a lógica de detecção de dependência circular.

Usar o disco para evitar ter que descobrir problemas de design OOP não é uma má ideia. Isso é como uma opção intermediária entre implementar o PEP 518 completamente corretamente e apenas hackear algo juntos.

Ele também interagiria bem com ambientes conteinerizados e chroots em geral, já que poderíamos usar ferramentas de nível de sistema operacional para manter diferentes compilações de nível Python isoladas umas das outras, então o pip precisaria descobrir como garantir seus próprios subprocessos cooperar uns com os outros.

@xoviat obrigado pelo resumo acima. Como eu disse, cheguei ao limite da minha compreensão do código nesta área, e sua explicação me ajudou enormemente.

Na verdade, eu não tinha olhado para o código do #4144 antes. Acabei de fazer e não quero que seja frete.

implementando PEP 518 completamente corretamente e apenas hackeando algo juntos.

Sinceramente, acho que se resume a isso. Implementar o PEP 518 completa e corretamente é uma tarefa que atrasaria/poderia atrasar o pip 10 um bit (justo) se formos por esse caminho.

Eu acho que um meio-termo seguro aqui seria exigir que as dependências de construção estivessem disponíveis como rodas. Dessa forma, podemos evitar o problema de recursão, pois as dependências de compilação (e todas as suas dependências) não precisariam ser construídas por meio desse processo.

Como isso soa?

É restrito, mas acho que uma primeira implementação restrita é melhor do que uma primeira implementação do tipo você pode atirar no próprio pé se não tiver cuidado.

Implementar o PEP 518 completa e corretamente é uma tarefa que atrasaria/poderia atrasar o pip 10 um bit (justo) se formos por esse caminho.

Obrigado por confirmar isso - esse era o meu medo.

No entanto, agora estou confuso, pois pensei que pelo menos o PEP 518 parcial já estava no mestre. Especificamente, como eu entendo, # 4647 demonstra um bug no suporte PEP 518 no master - então claramente já temos algo , pois o que quer que seja não está correto ...

Então temos que fazer algo, e parece que as opções são:

  1. Retire tudo o que temos para suporte PEP 518 no momento.
  2. Arrume o que temos e envie suporte parcial.
  3. Implemente o PEP 518 totalmente antes de liberar o pip 10.

Como você diz (3) significa um longo atraso antes do pip 10 e temos outras correções que eu realmente gostaria de ver lançadas (as correções de Unicode são uma das quais estamos regularmente resolvendo problemas). Então eu não estou interessado nisso. Você não mencionou (1), e não tenho certeza se é porque você pensou que não tínhamos suporte PEP 518 em vigor, ou se você assumiu que recuar não era uma opção. Pessoalmente, não gosto da ideia - é um retrocesso e envia uma mensagem bastante negativa sobre o próprio PEP, se for tão difícil de implementar corretamente. Mas acho que devemos ser explícitos quanto a rejeitá-la.

Sua proposta para (2), de enviarmos uma versão do PEP 518 que suporte apenas rodas como dependências de compilação (ainda precisaríamos corrigir #4647, pois a demonstração disso usa uma dependência de compilação que é uma roda) parece razoável , no sentido de que é prático para nós implementarmos. Minha principal ressalva é que não faço ideia de quão problemática seria essa restrição para as pessoas que desejam usar o PEP 518.

Então, acho que estamos presos em tudo o que fazemos, mas o suporte parcial cobrindo apenas rodas como dependências de compilação é a melhor opção de um lote ruim :-(

Os autores do PEP (em https://github.com/pypa/pip/pull/4799#issuecomment-338331267 e https://github.com/pypa/pip/pull/4799#issuecomment-338332575 em resposta à minha pergunta em https://github.com/pypa/pip/pull/4799#issuecomment-338325354) foram bem definidos que o suporte completo ao PEP exigia a construção de quaisquer dependências de compilação, portanto, deve ser apenas um paliativo.

Mas não sou eu que vou implementar isso, então fico feliz em seguir o julgamento de quem o fizer. Uma coisa que fiz foi criar #4803 e marcá-lo como um bloqueador de lançamento, como um lembrete de que devemos documentar como nos desviamos da especificação, se necessário.

(E fora do tópico para este problema, mas posso sugerir que tenhamos cuidado para não cometer os mesmos erros quando começarmos a implementar o PEP 517? Vamos nos certificar de que entendemos todas as implicações da implementação antes de nos aprofundarmos na codificação - meu instinto é que o PEP 517 será um problema de projeto ainda mais complexo do que o PEP 518...)

Estou mais familiarizado com distros quando se trata da perspectiva "construir tudo da fonte", e definitivamente separamos o processo de "inicializar o buildroot" daquele de compilações de pacotes regulares. A inicialização automática completa da fonte é difícil , pois você acaba tendo que fazer coisas como inicializar seu compilador C.

Portanto, para pip, acho razoável dizer que as dependências de compilação sempre serão instaláveis ​​a partir de arquivos wheel. O refinamento que você pode introduzir após a versão 10.x é ter um cache de compilação diferente do cache de roda normal, de modo que os usuários do cache possam ter certeza de que todas as rodas foram construídas em um ambiente controlado, em vez de baixadas do PyPI ou outro servidor de indexação.

Pessoalmente, não gosto da ideia - é um retrocesso e envia uma mensagem bastante negativa sobre o próprio PEP, se for tão difícil de implementar corretamente.

Não necessariamente concordo com isso. É difícil implementar corretamente para pip. Mas o pip, conforme declarado no PEP, é um dos únicos front-ends que as pessoas usarão. Acho que é nosso trabalho como implementadores de linguagem, e pip é realmente uma linguagem que as pessoas usam para empacotar seus projetos python, para tornar o mais simples possível criar um sistema de compilação sem ter que pensar em todos esses problemas difíceis. Para eles, deve funcionar perfeitamente porque fizemos o trabalho duro.

Eu acho que um meio-termo seguro aqui seria exigir que as dependências de construção estivessem disponíveis como rodas.

Na verdade, é exatamente isso que o #4799 faz. Se você quiser, posso restaurar esse branch e você pode bifurcá-lo e enviá-lo como um PR.

Duas coisas no lado da implementação das coisas de (2) ainda permanecem - como @xoviat apontou acima:

  1. descobrir como criar o subprocesso (argumentos et al)
    Acho que deve ser factível.

  2. quais versões do pacote devem ser instaladas.
    Isso provavelmente deve ser feito no mesmo processo pai, embora eu não tenha certeza de como exatamente isso aconteceria, pois o código do resolvedor atual ainda está entrelaçado com o código em pip._internal.operations.prepare . Vou analisar isso em algum momento desta semana.

Não tenho certeza de quem teria tempo para fazer isso.


ele envia uma mensagem bastante negativa sobre o próprio PEP, se for tão difícil de implementar corretamente.

Provavelmente não é difícil de implementar corretamente. É só que com a forma como a base de código do pip é hoje, não é trivial implementar no pip - há coisas que acontecem em lugares estranhos e acho que se isso for limpo, seria bastante trivial.

Você não mencionou (1), e não tenho certeza se é porque você pensou que não tínhamos suporte PEP 518 em vigor, ou se você assumiu que recuar não era uma opção.

Eu assumi que voltar atrás não é uma opção.

Agora que penso nisso - quão importante é enviar o PEP 518 no pip 10? Eu sinto que se puder ser adiado para o próximo grande lançamento, isso seria (além de ser o caminho mais fácil para essa situação) ser direto e ambos 517 + 518 poderiam chegar em um grande lançamento. Isso parece limpo o suficiente para que eu não seja o único a dizer que esse não é o caminho a seguir.

@dstufft @xavfernandez pensamentos?


A ideia de @ncoghlan de um cache de compilação parece uma boa ideia para mim, embora não tenha certeza de entender todas as implicações disso.


Se você quiser, posso restaurar esse branch e você pode bifurcá-lo e enviá-lo como um PR.

Provavelmente não terei tempo e, mesmo que tenha, posso não estar reutilizando nenhum commit existente. Mas restaurar esse ramo não pode doer. :)

Minha principal ressalva é que não faço ideia de quão problemática seria essa restrição para as pessoas que desejam usar o PEP 518.

Tivemos essa discussão exata, exceto que você provavelmente nem sabia. Essa situação é a situação X. Chamar egg_info antes que o ambiente de compilação seja configurado é a situação Y (#4799).

Mas não sou eu que vou implementar isso, então fico feliz em seguir o julgamento de quem o fizer.

Acho que isso significa que o número 4799 está de volta à mesa, então? Desde que passe em todos os testes e faça o que afirma fazer?

Aargh, esses X e Y voltam para me assombrar novamente :wink: Sim, estou dizendo que não tenho noção das probabilidades relativas dos 2 casos. Eu entendo que você está dizendo que os requisitos de construção que não são rodas são raros o suficiente para que possamos ignorar esse caso. Assim como um voto de "está tudo bem" e um voto de "não sei" entre nós, basicamente. Não estou tentando bloquear essa opção, apenas dizendo onde estão os limites da minha intuição, é tudo.

@xoviat Tenho algumas perguntas. Seria incrível se você respondesse antes de fazer um novo PR. :)

  • Como você vai determinar quais pacotes serão instalados?
  • Você vai restringir a dependências de compilação somente binárias?

Eu trabalhei com muitos projetos científicos, então pode ser que eu seja tendencioso. Mas posso citar uma lista de projetos com dependências de construção de rodas e realmente não consigo pensar em um projeto com dependências de origem. Talvez eu esteja errado.

@rgommers você ficaria bem com o PEP 518 suportando apenas dependências de compilação disponíveis como rodas se estivesse no próximo pip?

Como você vai determinar quais pacotes serão instalados?

O subprocesso obtém a lista de requisitos exatamente conforme especificado. Dessa forma, ele passa pelo resolvedor.

Você vai restringir a dependências de compilação somente binárias?

Sim, é por isso que o teste falhou. A dependência de compilação no teste não é uma roda.

Agora que penso nisso - quão importante é enviar o PEP 518 no pip 10? Eu sinto que se puder ser adiado para o próximo grande lançamento, isso seria (além de ser o caminho mais fácil para essa situação) ser direto e ambos 517 + 518 poderiam chegar em um grande lançamento. Isso parece limpo o suficiente para que eu não seja o único a dizer que esse não é o caminho a seguir.

Qual é a nossa opinião se vamos conseguir alguém com tempo para fazer PEPs 517 e 518 para o pip 11? Não estou otimista. Parece-me que ambos são grandes pedaços de trabalho, e também temos o trabalho de resolução em andamento. Embora eu não seja a favor de segurar o pip 10 por mais tempo do que o necessário, estou igualmente desconfortável em deixar todos os nossos principais planos de recursos à deriva enquanto lançamos uma série de lançamentos essencialmente menores.

Dito de outra forma, dizer "vamos lançar o pip 10" provocou um ressurgimento da atividade no trabalho do PEP 518. Se removermos isso do pip 10, eu vou me concentrar em preparar as coisas para o lançamento, e suspeito que é provável que o PEP 518 perca força novamente. O que é colocar as coisas em atividade novamente? @xoviat está trabalhando na implementação, mas ele teve problemas para tentar fazer com que qualquer um de nós entendesse os problemas com os quais ele está lutando até agora. Eu não quero deixá-lo trabalhando sem feedback novamente.

O que poderíamos fazer é lançar um "pip 9.1" com apenas as correções incrementais que temos prontas e reservar o número da versão "pip 10" para implementação de (pelo menos um dos) 3 grandes recursos que estão no pipeline. Mas se fizermos isso, eu gostaria de tentar[1] me comprometer com um lançamento do pip 10 no primeiro trimestre de 2018. Eu ficaria bem com isso como uma abordagem. Mas alguém tem uma ideia do que estaria envolvido em apoiar o suporte parcial que atualmente temos no master? Ou documentar o que temos e quais são suas limitações (para que as pessoas não tentem usá-lo assumindo que está completo, encontrem bugs e levantem problemas aos quais temos que responder com "esse recurso ainda não está completo, desculpe, mas espere pelo pip 10")? Estamos apenas trocando um grande pedaço de trabalho por um diferente?

[1] Na medida em que podemos nos comprometer com qualquer coisa com recursos voluntários extremamente limitados, como tudo o que temos disponível.

Eu trabalhei com muitos projetos científicos, então pode ser que eu seja tendencioso

Obrigado, às vezes é difícil conhecer o passado das pessoas. Se você está familiarizado com os projetos científicos, isso alivia muito minhas preocupações.

O que poderíamos fazer é lançar um "pip 9.1" com apenas as correções incrementais que temos prontas e reservar o número da versão "pip 10" para implementação de (pelo menos um dos) 3 grandes recursos que estão no pipeline.

Eu realmente gosto disso. +1 para um pip 9.1.0 em vez de pip 10.0.0

Eu gostaria de tentar[1] me comprometer com um lançamento do pip 10 no primeiro trimestre de 2018. Eu ficaria bem com isso como uma abordagem.

Eu tive uma onda cerebral muito interessante - pip completa 10 anos em 12 de outubro de 2018. Essa seria a data perfeita para fazer um lançamento do pip 10.0.0. É uma linha do tempo completamente diferente. Não estou dizendo que devemos adiar os recursos da baleia branca até então, mas uma parte de mim realmente quer que essa coisa de número de versão e idade coincida também.

Suspeito que seja provável que o PEP 518 perca força novamente.

Farei o que puder para que não aconteça. Espero que a @xoviat também esteja disposta. :)

alguém tem uma ideia do que estaria envolvido em retirar o suporte parcial que temos atualmente no master?

Não me importo de dar uma olhada nisso amanhã. Como @dstufft foi o revisado em #4144, acho que sua opinião sobre isso seria valiosa.

Nota - eu não gostaria de fazer nada tão drástico quanto retirar as coisas sem o acordo de @dstufft e @xavfernandez - então vamos ver o que eles têm a dizer também.

@dstufft não tem tempo suficiente durante o dia. Ele também tem que se certificar de que o armazém não caia.

vamos ver o que eles têm a dizer também.

Sim por favor. :)

De uma perspectiva de UX: combater de forma abrangente o ataque "trusting trust" é realmente doloroso [1], e você encontrará muitas pessoas que dizem que "I compile tudo da fonte" não estão realmente fazendo isso - em algum lugar em seu processo lá será uma etapa de bootstrap onde eles confiam em um binário fornecido por outra pessoa (por exemplo, o ambiente de execução e a cadeia de ferramentas de compilação de seu provedor de sistema operacional), ou então de uma geração anterior de sua própria plataforma (por exemplo, os buildroots para novas versões do Fedora e O RHEL é propagado a partir de versões anteriores do Fedora e do RHEL, eles não começam completamente do zero). Mesmo uma distribuição Linux baseada em fonte como o Gentoo começa com um instalador para fornecer um ambiente de compilação funcional com um kernel Linux, compilador C, drivers de hardware, etc.

Então eu acho que é totalmente razoável para o pip 10 dizer que --no-binary :all: só se aplica a dependências de tempo de execução, não para construir dependências. Se as pessoas querem construir explicitamente seu buildroot a partir da fonte, eles ainda podem - é só que o pip 10 não o automatizará implicitamente para eles devido aos problemas inerentes de bootstrapping recursivo envolvidos em permitir compilações de fonte implícitas para suas dependências de compilação.

Para permitir que as pessoas indiquem que esperam que o ambiente de compilação seja totalmente pré-configurado, seria razoável adicionar uma opção --no-implicit-builddeps separada para que a instalação falhe imediatamente se a inicialização binária implícita for necessária como parte de uma compilação de origem . Dessa forma, as pessoas que tentam garantir que tudo seja compilado a partir da fonte (incluindo as dependências de compilação) podem fazer o equivalente a:

pip install --no-binary :all: --no-implicit-builddeps -r build-requirements.txt
pip install --no-binary :all: --no-implicit-builddeps -r requirements.txt

E defina quantos grupos de instalação distintos forem necessários para chegar a um ponto em que o primeiro não precise de nada além de CPython e quaisquer cadeias de ferramentas de compilação não Python pré-instaladas.

Um futuro complemento potencial para esse conceito seria permitir que as pessoas digam --buildenv <path> para especificar um ambiente de compilação pré-configurado para usar em qualquer compilação de origem necessária, em vez de fazer cada compilação em um ambiente isolado. No entanto, eu não tentaria colocar isso no pip 10 - sugiro limitar 10.x ao caminho feliz de "dependências de compilação binária são permitidas" e a opção alternativa de "falhar na compilação se for necessária uma dependência de compilação binária e ainda não está disponível no interpretador atualmente em execução".

[1] https://www.schneier.com/blog/archives/2006/01/countering_trus.html

Eu pensei em outra opção, que parece razoável e não exigiria muita refatoração: essencialmente usando multi-threading para colocar o thread principal em espera enquanto o ambiente de compilação é configurado. A ideia é mais ou menos assim: em install.py , você teria um BuildEnvironmentManager :

class BuildEnvironmentManager(Thread):
    '''Has references to literally everything (cache, resolver, etc.)'''
    def run(self):
        while True:
            requirement_list, future = self.build_environment_queue.get()

            # install the requirements using all of the things
            # that we have

            # then put the build environment in the future
            future.put(BuildEnvironment())

Você teria então outro arquivo (eu uso backend.py porque não está cheio o suficiente e provavelmente poderia usar mais coisas nele, e está na extremidade inferior da árvore):

class Future(Queue):
    pass

class BuildEnvironmentQueue(object):
    def __init__(self):
        self._queue = Queue()

    def request_build_environment(self, requirement_list):
        f = Future()
        self._queue.put((requirement_list, f))
        return f.get()

    def get():
        return self._queue.get()

E em operações/prepare.py:

# This call will put the thread to sleep until we have a build environment
# with the requirements installed
self.build_environment_queue.request_build_environment(requirement_list)

Isso tem a vantagem de exigir refatoração mínima, ter um BuildEnvironmentManager serializado (para que os ambientes de compilação possam ser otimizados e você saiba exatamente quais solicitações foram feitas em um único objeto) e mantendo tudo contido em um processo (para que o o pior cenário é um impasse). Claro, o log precisaria ser desabilitado para os outros threads, mas isso não é um grande problema.

Respondendo minha própria pergunta sobre a abordagem baseada em queue.Queue: é melhor evitar depender de concurrent.futures, pois usar isso exigiria a venda https://pypi.org/project/futures/ no Python 2.7.

Sem conhecer bem a base de código pip , a noção de consolidar o gerenciamento do ambiente de compilação em um único lugar ainda parece uma opção atraente.

concurrent.futures não é necessário para essa abordagem. Future é apenas um wrapper mais descritivo.

Apenas primitivo necessário é uma fila: https://docs.python.org/2/library/queue.html

Acho que podemos mover essas linhas para o BuildEnvironmentManager .

Eu trabalhei com muitos projetos científicos, então pode ser que eu seja tendencioso. Mas posso citar uma lista de projetos com dependências de construção de rodas e realmente não consigo pensar em um projeto com dependências de origem. Talvez eu esteja errado.

Bem, por um lado, há todos os sistemas operacionais que não são [Windows, macOS, Linux], IIRC que não são cobertos por manylinux1 .

@rgommers você ficaria bem com o PEP 518 suportando apenas dependências de compilação disponíveis como rodas se estivesse no próximo pip?

Não é minha decisão, mas ficaria feliz com qualquer passo adiante aqui. O suporte PEP 518 é opcional de qualquer maneira, então só funciona quando as rodas estão disponíveis (cobre > 90% dos casos, eu diria) no pip 10 ainda é uma melhoria significativa.

Observe que mesmo as plataformas que não permitem rodas no PyPI ainda terão um cache de roda local, o que significa que, mesmo que o pip não possa inicializar implicitamente as coisas, ele ainda poderá imprimi-las e dizer "obtenha essas dependências de compilação instaladas de alguma forma , e então isso funcionará".

Mas alguém tem uma ideia do que estaria envolvido em apoiar o suporte parcial que atualmente temos no master?

Eu olhei para isso; não parece ser muito difícil. Ficarei feliz em fazer um PR se decidirmos seguir este caminho.

+1 para um pip 9.1.0 em vez de pip 10.0.0

Finalmente consegui tempo para ler corretamente o tópico distutils-sig e ver PRs e discussões relevantes (#4351, #4144, #4799 e muitos outros). Agora acho que desde que anunciamos o pip 10; isso é o que devemos fazer, com o suporte parcial PEP 518 -- não 9.1.0.

este número de versão e coisa de idade para coincidir

Desapontamento. :(

@ncoghlan Talvez este comentário tenha escapado do radar -- https://github.com/pypa/pip/pull/4799#issuecomment -338416543

Caso isso não aconteça, seria bom se você pudesse explicar por que não funcionaria, porque eu meio que entendo esse tipo de configuração e estou definitivamente aberto a aprender mais sobre isso. :)

@pradyunsg Acho que isso funcionaria principalmente, pois é uma implementação específica da ideia do cache de compilação. O único aspecto que ele não cobre são os loops de dependência de compilação, pois está faltando uma maneira de detectar "Acabei de ser solicitado a construir algo que já estou tentando construir".

Observe que o pip não precisa resolver magicamente os loops de dependência - ele só precisa detectá-los e falhar assim que detectar um, em vez de realmente entrar em um loop infinito.

ele não cobre loops de dependência de compilação,

Isso não ocorreria com dependências de compilação somente binárias?

@pradyunsg O comentário vinculado era sobre uma maneira de permitir compilações de origem para dependências de compilação, o que significa que as dependências circulares se tornam uma preocupação potencial. Se estivermos exigindo dependências binárias, então pip pode apenas contar com o wheel cache existente por enquanto.

Ah, certo. Obrigado! :)

Sou a favor de um pip 10 com uma implementação parcial de PEP 518 limitada apenas a dependências de compilação binária (ou já disponível no cache pip wheel) se isso for tudo o que conseguirmos incluir.

Eu não li o tópico inteiro ainda, mas eu só quero apontar que um efeito colateral de limitar as dependências de compilação binária será que é impossível ter uma dependência C em suas dependências de compilação em muitos casos. Sim, temos rodas binárias no Windows, macOS e algumas versões do Linux, mas não em:

  • Qualquer Linux que não use glibc (o Alpine Linux dentro do Docker é um dos mais populares).
  • Qualquer sistema operacional *nix que não seja Linux, como FreeBSD etc.

Isso significaria que qualquer projeto baseado em CFFI, por exemplo, não seria capaz de usar o PEP 518 ou seria desinstalável nessas plataformas.

Isso já pode ter sido levantado! Vou ler este tópico mais tarde.

@dstufft Isso mesmo. Mas o que estamos propondo é que usar o pip cache é uma opção. Então você pode apenas pip wheel ou pip install suas dependências de compilação primeiro e então elas serão armazenadas no cache.

Isso já pode ter sido levantado!

Não. :)

Isso significaria que qualquer projeto baseado em CFFI, por exemplo, não seria capaz de usar o PEP 518 ou seria desinstalável nessas plataformas.

De fato. :-(

A maneira de contornar isso na minha cabeça seria que poderíamos ativar o comportamento do PEP 518 - se houver um arquivo pyproject.toml , usaremos o ambiente de isolamento + compilação, caso contrário, voltaremos ao comportamento atual de usar setup.py .

Vou ler este tópico mais tarde.

Por favor faça. :)

Eu fiz exatamente o mesmo comentário que Donald; meu entendimento deste segmento é que somente binário é temporário porque não há tempo para implementá-lo para o pip 10. Correto?

Se foi proposto como uma decisão permanente, então -1 é claro.

Eu fiz exatamente o mesmo comentário que Donald; meu entendimento deste segmento é que somente binário é temporário porque não há tempo para implementá-lo para o pip 10. Correto?

Está correto. pip deve suportar dependências de fonte, mas estamos com pouca mão de obra.

A maneira de contornar isso na minha cabeça seria que poderíamos tornar o comportamento PEP 518 opt-in -- se houver um arquivo pyproject.toml, usaremos o ambiente de isolamento + compilação, caso contrário, voltaremos ao comportamento atual de usar setup.py.

Reli este comentário e vou discordar aqui. O suporte ao PEP 518 não deve ser opcional (por motivos de implementação relacionados ao PEP 517) IMHO, mas os projetos não devem se tornar desinstaláveis ​​nessas plataformas.

Mais especificamente, o projeto específico que você está instalando não deve determinar se você obtém o PEP 518. Isso deve ser determinado se suas dependências de compilação estão disponíveis como rodas ou no cache. Além disso, também podemos tornar o suporte PEP 518 obrigatório para essas plataformas se apenas enviarmos uma mensagem como a seguinte:

Error: build dependency X is not in the pip cache. Run "pip install X" before installing Y.

Resumindo minha própria perspectiva:

  1. Eu vejo o "Sem suporte de compilação implícito para dependências de compilação" como uma limitação temporária no pip 10 para tornar certas classes de problema (por exemplo, loops de dependência de compilação) impossíveis de encontrar na primeira iteração lançada do recurso. As iterações futuras do suporte de back-end de compilação conectável podem permitir compilações de código-fonte implícitas para dependências de compilação, ao mesmo tempo em que implementam medidas adequadas para evitar os novos problemas que surgem quando você permite isso.
  2. Emitir o comando python -m pip wheel X Y Z relevante em uma mensagem de erro sem realmente executar a compilação implicitamente é uma solução adequada por enquanto, pois garante que o pip não possa inadvertidamente fazer um fork bomb em uma máquina.
  3. Compilações isoladas provavelmente não devem ser o padrão ainda, a menos que a roda específica que está sendo construída tenha um arquivo pyproject.toml , ou compilações isoladas sejam explicitamente solicitadas na linha de comando. Este é um problema de compatibilidade com versões anteriores, pois os projetos existentes esperam o comportamento não isolado. Uma vez que as compilações isoladas estejam disponíveis para uma ou duas versões, e quaisquer problemas de usabilidade com elas tenham sido resolvidos, elas podem se tornar o padrão em geral (talvez com uma opção de linha de comando para especificar um ambiente de compilação específico a ser usado em vez de gerar implicitamente uns)

@ncoghlan Só para avisar: nenhum isolamento de compilação padrão significa que não há PEP 517 (pelo menos com minha abordagem) porque apenas a versão mais recente do setuptools o suporta (precisamos instalar um setuptools mais recente, independentemente do que está na pessoa computador). Praticamente, acho que isso pode atrasar o PEP 517 em pelo menos um ano, porque aumentará drasticamente a quantidade de esforço necessária para implementá-lo (exigindo o código PEP 517 e não-PEP 517).

Este é um problema de compatibilidade com versões anteriores, pois os projetos existentes esperam o comportamento não isolado.

A maioria das pessoas tem scripts CI que executam pip install X e depois executam pip install Y . Esses projetos precisariam adicionar um pypproject.toml . Mas adicionar um pyproject.toml não dá muito trabalho, e podemos adicionar um sinalizador de linha de comando para desabilitar o isolamento de compilação, se necessário.

Devemos pelo menos cuspir um aviso se um projeto não tiver pyproject.toml no pip 10 (que parece não ter suporte para PEP 517 de qualquer maneira).

@xoviat "Não daria muito trabalho para ajustar" não é como a compatibilidade com versões anteriores funciona. Se fosse, o pip teria mudado para --user como o modelo de instalação padrão não-venv agora :)

No que diz respeito ao PEP 517, você não pode depender do PEP 517 como um editor de pacotes sem adicionar um arquivo pyproject.toml , então tudo bem se os projetos setup.py -somente não receberem suporte ao PEP 517 por padrão.

Você estaria bem em cuspir um aviso?

Eu veria isso como um problema se uma compilação que atualmente funciona bem começasse a emitir um aviso apenas porque o pip foi atualizado, mesmo que nem o projeto em si nem nenhuma de suas dependências tivessem mudado.

O PEP 518 e o 517 foram deliberadamente projetados para causar interrupção zero em projetos existentes, onde todos os editores envolvidos continuaram confiando apenas em ferramentas de configuração.

Faz sentido para pip ter como objetivo consolidar de volta a um único caminho de compilação PEP 518 mesmo para projetos baseados em setuptools, mas o momento para isso é depois que compilações isoladas viram uma ou duas versões de uso prático, não na primeira versão que os suporta.

Eu fiz exatamente o mesmo comentário que Donald; meu entendimento deste segmento é que somente binário é temporário porque não há tempo para implementá-lo para o pip 10. Correto?

Sim. Exatamente.


Faz sentido para o pip ter como objetivo consolidar de volta a um único caminho de compilação PEP 518, mesmo para projetos baseados em setuptools, mas o momento para isso é depois que compilações isoladas viram uma ou duas versões de uso prático, não na primeira versão que apoia-los em tudo.

+1

Acho que devemos tentar remover o caminho antigo, como 2 grandes lançamentos. Quando o pip chega ao suporte PEP 518 completo e adequado; devemos descontinuar a lógica de compilação antiga e removê-la de acordo com a política de descontinuação padrão.

Concordo com o resumo do Nick e...

porque aumentará drasticamente a quantidade de esforço necessária para implementá-lo

Não. Não acho que a implementação do PEP 518 desta forma tenha grandes obstáculos; Fiz um breve comentário em https://github.com/pypa/pip/pull/4799#issuecomment -339219397 sobre como isso poderia ser implementado no pip.


O que queremos fazer é proporcionar às pessoas uma transição limpa do antigo para o novo. Assim, precisamos manter a lógica de instalação atual do pip 9 inalterada - o que basicamente suportaria tudo o que fazemos atualmente da maneira exata que fazemos.

Colocar um arquivo pyproject.toml no arquivo significa que o pacote está optando pelo padrão mais recente e está disposto a testar o suporte para o novo comportamento - passando pelo ambiente de compilação com isolamento e compilação somente binária -dependências (por enquanto).

Não. Não acho que a implementação do PEP 518 desta forma tenha grandes obstáculos;

Discutindo PEP 517 aqui. Desculpe pela confusão.

Teríamos que executar os testes duas vezes para verificar os dois caminhos de código. Ah bem PEP 517 é provavelmente adiado.

OMI,

  1. Avisar se um projeto não tem pyproject.toml parece uma péssima ideia. Afinal, 99% dos projetos no PyPI atualmente não têm pyproject.toml , e não podemos enviar spam aos usuários finais com avisos sobre os quais eles não podem fazer nada (além de relatar o problema ao(s) projeto(s) ). Estou esquecendo de algo?
  2. Não acredito que o isolamento de compilação tenha sido mencionado no PEP 518. É um recurso adicional que o pip deseja incluir há algum tempo, mas não está vinculado ao suporte ao PEP 518, exceto pelo fato coincidente de que o mesmo PR implementado ambos (AFAIR). Portanto, se o isolamento de construção é o que está nos causando problemas aqui, estou bem em ter apenas o PEP 518 inicialmente e adicionar o isolamento como uma fase 2. No entanto, deixarei essa decisão para as pessoas que estão implementando as coisas.

Estou esquecendo de algo?

Não.

Estou bem em ter apenas PEP 518 inicialmente e adicionar isolamento como uma fase 2.

Acho que devemos fazer o PEP 518 e construir o isolamento juntos, já que é uma boa maneira de fazer com que as pessoas mudem para construções isoladas.

Embora nem o PEP 518 nem o PEP 517 exijam compilações isoladas, o PEP 517 os recomenda por boas razões: https://www.python.org/dev/peps/pep-0517/#recommendations -for-build-frontends-non-normative

Sem um cache de artefato binário local, ambientes de compilação isolados são impraticáveis, mas uma vez que você tenha um desses (como pip agora), eles são muito mais viáveis, pois:

  1. Na maioria das instalações, você nem precisará fazer uma compilação de origem em primeiro lugar
  2. Quando você precisar fazer uma compilação de origem, geralmente estará configurando o ambiente de compilação a partir do cache

Ao mesmo tempo, ambientes de compilação isolados exigem um pouco mais de trabalho dos editores, pois significam que metadados com erros quebrarão as próprias compilações do editor de uma maneira que exige que eles digam explicitamente "Minhas dependências de compilação não estão totalmente declaradas" para fazer uma construção.

Portanto, ter compilações baseadas pyproject.toml isoladas desde o início fornece um ponto de troca natural, já que todo o PEP é sobre fornecer uma maneira de declarar de forma clara e consistente as dependências de compilação separadamente das dependências de tempo de execução. Isso significa que as pessoas que estão mudando de setup.py provavelmente estão fazendo isso porque se preocupam em fazer esse tipo de coisa, enquanto as pessoas que chegam frescas para novos projetos vão apenas tratá-lo como outro aro que as ferramentas de embalagem os obrigam a pular Através dos.

Então, apenas algumas coisas que eu quero confirmar antes de começar a escrever o código:

  • O suporte PEP 517 não é um bloqueador para pip 10
  • PEP 518 no pip 10

    • opt-in por pyproject.toml

    • suporta apenas dependências de compilação somente binárias

    • construções isoladas

O PEP 517 não pode ser um bloqueador para o pip 10 porque ainda não está pronto e não há um caminho claro a seguir neste momento (há um caminho a seguir, mas não está claro).

Eu tenho um comentário e uma pergunta em resposta ao comentário de @xoviat aqui resumindo os desafios de implementação, bem como depois de ler este tópico rapidamente.

Primeiro, em relação à questão da recursão de coisas possivelmente explodindo, em geral qualquer função recursiva pode ser "traduzida" para uma iterativa. Eu estou querendo saber se essa abordagem poderia ajudar aqui, fornecendo mais controle.

Segundo, o que o desembolso compra em vez de chamar uma função pip de dentro do Python? Existe algum motivo para uma função de API interna não poder ser criada / refatorada que faria o que o shelling está tentando alcançar? Isso deve fornecer mais flexibilidade ao chamar a chamada (em comparação com os parâmetros da CLI). Isso também pode fornecer mais controle, permitindo que se gerencie mais facilmente o estado do processo geral.

Existe algum motivo para uma função de API interna não poder ser criada / refatorada que faria o que o shelling está tentando alcançar?

Segundo, o que o desembolso compra em vez de chamar uma função pip de dentro do Python?

Ele compra tempo que atualmente não temos. pip já está atrasado em relação ao cronograma de lançamento.

Primeiro, em relação à questão da recursão de coisas possivelmente explodindo, em geral qualquer função recursiva pode ser "traduzida" para uma iterativa.

Não sou anti-recursão. Eu sou anti processo-recursão. Eu acho que está tudo bem se você quiser usar 100% da CPU (bem, seria 20% em Python), mas no final das contas o usuário precisa ser capaz de abrir o gerenciador de tarefas e matar o máximo de 15 processos que estão lá. Para mim, uma situação que poderia causar uma explosão de processo é inaceitável.

Isso não responde à pergunta de por que ele ganha tempo, no entanto. O que torna difícil criar uma função de API interna que faça a mesma coisa?

De qualquer forma, se o shell resolver algum problema em particular, uma possibilidade de tornar essa abordagem mais fácil pode ser expor temporariamente um comando CLI privado/interno que facilita a passagem de qualquer informação necessária (por exemplo, pode até ser um objeto Python serializado , etc).

Isso não responde à pergunta de por que ele ganha tempo, no entanto. O que torna difícil criar uma função de API interna que faça a mesma coisa?

Se você acha que é fácil, vá em frente. Não estou dizendo isso com sarcasmo: por favor, vá em frente, porque vai resolver todos os problemas.

Eu não acho que seja fácil. Estou fazendo a pergunta para entender por que é difícil. (Suponho que você tenha pensado nisso desde que disse que economizaria tempo.)

Você precisa de instalações de pip separadas para serem executadas dentro de um subprocesso geralmente, por causa de caches em lugares como pkg_resources eu acredito (embora eu possa estar errado lá).

Isso não significa que você precisa chamar pip , no entanto, você pode criar uma API que serialize dados via CLI e chame python -c "from pip._internals import coolapithing; coolapithing(sys.stdin.read())" e leia mais dados em stdout. Seria possível transformar a solução recursiva de pip chamando pips chamando pips chamando pips transformando-a em uma pilha usando essa API (já que toda recursão também pode ser descrita como uma pilha), você basicamente estaria criando uma API privada que é chamado como um processo.

Ainda estou pensando em ler este tópico (tinha um monte de pratos girando ultimamente!), mas uma coisa: não temos realmente um cronograma de lançamento, lançamos quando estiver pronto, não em alguma data prevista. Às vezes temos uma ideia geral de quando gostaríamos de lançar, mas isso nunca é definitivo.

Em última análise, embora o Python tenha uma profundidade máxima de recursão para garantir que as coisas não saiam do controle. Nós precisaríamos implementar isso se fôssemos com essa abordagem.

Sim, uma abordagem baseada em pilha torna bastante eficiente ir bem fundo (muito mais profundo do que qualquer coisa além de um loop de dependência, por exemplo, poderíamos ter algo que depende literalmente de todos os pacotes e ainda ficar bem), o principal fazer é detectar loops.

Uma maneira bastante ingênua e fácil de fazer a detecção de loop é simplesmente colocar um limite superior no número de itens na pilha e dizer que se você atingir esse limite, certamente deve estar em uma situação de loop e errar. As desvantagens disso são, é claro, que os loops não são detectados o mais cedo possível e pacotes com cadeias de dependência de compilação mais profundas, então o limite simplesmente não funciona.

A opção geralmente melhor (já que se você usar uma abordagem baseada em pilha, poderá acessar toda a pilha) é simplesmente percorrer a pilha e verificar se o item que estamos tentando instalar já está na pilha em algum lugar e se está break out e erro porque atingimos um loop (esse erro pode ser apresentado ao usuário final ou pode borbulhar para o resolvedor eventualmente para tentar uma versão diferente - embora isso o torne muito mais lento).

E para responder diretamente à pergunta de @cjerdonek : em princípio, isso não é difícil, o que está dificultando as coisas são algumas suposições arquitetônicas incorporadas na maneira pip atualmente funciona que não são mais verdadeiras em um mundo onde cada fonte compila obtém seu próprio ambiente de compilação isolado, em vez de apenas ser executado diretamente no ambiente de instalação.

Isso significa que a maneira mais fácil de reutilizar a lógica de gerenciamento de dependência existente do pip sem tropeçar nessas limitações arquiteturais internas e sem arriscar quebrar o código em funcionamento atualmente é executar outra instância de pip em um subprocesso. Isso é bom, exceto pela consequência de que a falha em detectar e sair dos loops de dependência pode causar uma bomba no sistema que está executando a compilação.

Eu gosto da ideia do @dstufft de converter para uma abordagem iterativa/baseada em pilha e desembolsar para uma função pip interna usando o padrão python -c "from pip._internals import coolapithing; coolapithing(sys.stdin.read())" . Isso parece mais simples com base na discussão, além de robusto.

Acho que o primeiro passo para isso seria reduzir a abordagem recursiva direta a uma única função recursiva do Python com a entrada e saída esperadas (pelo menos esboçando-a) e, em seguida, isso poderia ser traduzido / convertido para a abordagem iterativa. E sim, você pode manter um set de chamadas visitadas para evitar loops, o que parece ser um dos aspectos mais fáceis de resolver.

Analisei/pensei um pouco mais sobre como converter a abordagem recursiva em uma iterativa. O trabalho parcial do @xoviat no PEP 518 (PR # 4799) me ajudou a encontrar o ponto de recursão (com o qual alguns de vocês provavelmente já estão familiarizados). Está no comentário do código dele:

# TODO: Use single process with recursion handling

onde então invoca pip install ... .

Minha ideia é que parece que isso talvez possa ser resolvido por uma variante de pip install (para as dependências de compilação) com algo como a seguinte alteração:

  • Se a instalação não exigir nenhuma subinstalação, faça a instalação.
  • Caso contrário, retorne com uma lista (possivelmente parcial) das subinstalações necessárias (por exemplo, gravando as informações em um arquivo acordado se gravar em stdout ainda não funcionar).

Dessa forma, o processo raiz de nível superior pode gerar progressivamente uma árvore das dependências de construção. E pode processar as folhas à medida que são encontradas. À medida que as folhas são processadas, os nós que anteriormente não eram folhas se tornarão folhas e assim por diante. Com esta implementação, em qualquer ponto haverá apenas no máximo uma instalação de pip acontecendo em um subprocesso.

Uma pequena variação do que sugeri acima é que o comando pip / chamada de subprocesso necessária pode retornar / emitir uma lista das invocações de subinstalação que uma instalação candidata exigiria (um pip get-subinstalls ou simplesmente pip subinstalls comando). A única diferença para o que sugeri acima é que esse comando seria limitado a informações de relatório. Na verdade, não faria a instalação. Portanto, implementá-lo poderia ser mais simples / mais fácil de testar.

@cjerdonek Não vejo nenhum problema com essa ideia. Mas, em última análise, alguém precisa implementá-lo (acho que @pradyunsg ia trabalhar em algo neste fim de semana?) e, como sempre, mais dificuldades podem ser descobertas.

Algo surgiu. Se alguém quiser pegar isso, eu não tenho
questões. :)

Também gosto da ideia do @dstufft .

Em Dom, 29 de outubro de 2017, 08:47 xoviat, [email protected] escreveu:

@cjerdonek https://github.com/cjerdonek Não vejo nenhum problema com
essa ideia. Mas, em última análise, alguém precisa implementá-lo (acho que
@pradyunsg https://github.com/pradyunsg ia trabalhar em algo
este fim de semana?) e como sempre mais dificuldades podem ser descobertas.


Você está recebendo isso porque foi mencionado.

Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/pypa/pip/issues/4802#issuecomment-340234567 ou silenciar
o segmento
https://github.com/notifications/unsubscribe-auth/ADH7SYImpWgJGg-DzQRcO_9hHfE6ZxEAks5sw-5RgaJpZM4QBdSg
.

Voltando a isso, queremos seguir em frente com a abordagem pilha + invocação interna sugerida por @dstufft?

/ping @ncoghlan @pfmoore @xavfernandez

Sim por favor. Qualquer coisa para levar isso adiante.

Existe alguém que possa resumir onde estamos com o PEP 517 e o PEP 518 em relação a um lançamento do pip 10? Especificamente:

  1. O mestre está atualmente em um estado liberável? A última vez que ouvi, o suporte ao PEP 518 foi interrompido (há pelo menos um problema de bloqueador de lançamento aberto relacionado ao PEP 518 - #4647).
  2. É provável que tenhamos uma implementação PEP 517 e/ou PEP 518 em funcionamento em uma escala de tempo que torne razoável atrasar o pip 10 até que estejam disponíveis?
  3. Supondo que consertamos as coisas em (1), queremos fazer um lançamento do pip 10 sem o PEP 517/518? Produzimos um e-mail de alerta sobre o lançamento, para que as pessoas saibam que está chegando. E há algumas correções razoavelmente significativas (por exemplo, correções de codificação para o Windows) que seria bom lançar.

Meu sentimento é que estamos esperando os bloqueadores de lançamento, mas não estamos perto o suficiente do suporte PEP 517/518 para bloquear o pip 10 neles. Mas acho que ninguém está trabalhando no #4647, exceto como parte da implementação do PEP 518.

Uma opção alternativa seria documentar as limitações do suporte PEP 518 atual e fazer o downgrade #4647 de um bloqueador de lançamento. Eu não sei o suficiente sobre os casos de uso para saber se isso é viável.

Acabei de ver esta discussão - desculpas pela implementação inicial incompleta que pode funcionar como uma bomba de fork, e obrigado a todos vocês que dedicaram um tempo para entendê-la e apresentar ideias melhores.

FWIW, acho que restringi-lo à instalação de rodas para requisitos de construção seria um compromisso aceitável para a primeira versão.

Isso também me lembra que eu provavelmente deveria consertar as coisas para que o flit não seja um requisito de construção por si só.

desculpas pela implementação inicial incompleta que pode funcionar como uma bomba de garfo,

Nenhum pedido de desculpas necessário. Como eu disse, você não pode prever esses problemas na primeira tentativa. Mesmo sabendo o que sabemos agora, atrasar o PR teria apenas adiado essas discussões.

O mestre está atualmente em um estado liberável?

IIUC, pode bombardear um sistema a partir de agora; isso é correto? Se sim, acho que não.

É provável que tenhamos uma implementação PEP 517 e/ou PEP 518 em funcionamento em uma escala de tempo que torne razoável atrasar o pip 10 até que estejam disponíveis?

Eu acho que a solução fácil (de curto prazo) seria apenas restringir as rodas para dependências de compilação. Vou tentar dar uma olhada nisso na próxima semana. Se isso não se concretizar, tudo bem se removermos o suporte PEP 518 atual do mestre e cortarmos um 10.0.0 disso.

Acho que ninguém está trabalhando no #4647, exceto como parte da implementação do PEP 518.

Eu acho que você quer dizer, implementação completa do PEP 518 com dependências de compilação de origem permitidas?

Ah, e sobre # 4647 -- a descrição de @xoviat acima diz, consertar isso levaria a mudança/mudança de código e propriedade/visibilidade de objetos (especificamente BuildEnvironment ), o que não é trivial.

Eu acho que restringi-lo às rodas deve ser tão simples quanto alterar esta linha:

https://github.com/pypa/pip/blob/fc6b2c192088737f81259b6446f627f20ce46443/src/pip/_internal/wheel.py#L696

para:

finder.format_control = FormatControl(set(), set([':all:']))

No segundo campo há um conjunto de pacotes a serem encontrados apenas como binários, com um caso especial para ':all:' para significar todos os pacotes.

sim. Mas isso por si só não resolveria #4647. Além disso, nenhum deste código vai
através de um resolvedor.

No sábado, 2 de dezembro de 2017 às 01:23 Thomas Kluyver [email protected] escreveu:

Eu acho que restringi-lo às rodas deve ser tão simples quanto mudar isso
linha:

https://github.com/pypa/pip/blob/fc6b2c192088737f81259b6446f627f20ce46443/src/pip/_internal/wheel.py#L696

para:

finder.format_control = FormatControl(set(), set([':all:'])))

No segundo campo há um conjunto de pacotes para encontrar apenas como binários, com
um caso especial para ':all:' significar todos os pacotes.


Você está recebendo isso porque foi mencionado.

Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/pypa/pip/issues/4802#issuecomment-348598368 ou silenciar
o segmento
https://github.com/notifications/unsubscribe-auth/ADH7SUi0QMS3rr5Iba90XWZmFweGmqeBks5s8FlEgaJpZM4QBdSg
.

Certo, há um monte de outras coisas erradas com ele. Mas isso deve impedi-lo de bombardeio, que eu acho que é a preocupação mais premente.

Se alguém quiser assumir meu PR original ("corrigir os problemas do PEP 518"),
não deve ser muito difícil alterá-lo para que o isolamento de compilação não seja
habilitado sem um pyproject.toml. O motivo original que não foi mesclado
foi que ele abandonou o suporte para instalar dependências da fonte com
PEP 518. No entanto, agora que as pessoas estão começando a perceber que o PEP 518 pode
não estar no pip 10, eles podem ser mais receptivos a aceitar esse PR. eu
pessoalmente, não tenho tempo para defendê-lo, mas isso não deve impedir os outros
de levá-lo adiante, pois apenas algumas linhas de mudanças serão necessárias
(além de x falhar no teste PEP 518).

Na verdade, contra meu melhor julgamento, estou disposto a implementar o PEP 517 e o 518 em breve se os desenvolvedores do pip concordarem com minhas condições:

  1. As dependências serão apenas de rodas inicialmente
  2. pip terá um backend de compilação interno inicialmente, mesmo que eventualmente seja removido

Não tenho problemas com 1; Não tenho preferência por 2.

Em Dom, 3 de dezembro de 2017 às 02:36 xoviat [email protected] escreveu:

Na verdade, contra meu melhor julgamento, estou disposto a implementar tanto o PEP
517 e 518 em breve se os desenvolvedores do pip concordarem com minhas condições:

  1. As dependências serão apenas de rodas inicialmente
  2. pip terá um backend de compilação interno inicialmente, mesmo que
    acabará por ser removido


Você está recebendo isso porque foi mencionado.

Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/pypa/pip/issues/4802#issuecomment-348720096 ou silenciar
o segmento
https://github.com/notifications/unsubscribe-auth/ADH7ST6riptZkYMap5Z5SstRf-VmE7eAks5s8bu5gaJpZM4QBdSg
.

Para sua informação, as condições não são arbitrárias, mas existem para possibilitar a implementação inicial. @pfmoore está bem com isso?

Não estou particularmente confortável com o tom da oferta "contra meu melhor julgamento... concordo com minhas condições". Não vou me opor se os outros desenvolvedores do pip estiverem felizes em aceitar esta oferta, mas pessoalmente não tenho tempo no momento para reiniciar todo o debate sobre os detalhes da implementação. Basicamente, vou adiar para @dstufft e @xavfernandez sobre isso ( @pradyunsg já deu suas opiniões).

O tom da oferta é do jeito que está porque os métodos de implementação foram fechados devido a divergências fundamentais sobre como seria uma implementação inicial. Prefiro concordar com os princípios agora do que recair em outro debate de implementação.

Vou apenas afirmar que também não estou super confortável com o tom, é
apenas, não tenho tempo ou energia para explicar por que esse tom foi usado
etc. Mesma razão para a resposta concisa do meu lado.

Talvez também valha a pena afirmar, eu sou legal com dependências de compilação apenas binárias em
a primeira implementação, não a longo prazo. Isso não se aplica a
dependências de tempo de execução (já que isso também surgiu em outro
discussão).

No domingo, 3 de dezembro de 2017, 23:37 xoviat, [email protected] escreveu:

O tom da oferta é do jeito que está porque os métodos de
implementação foram encerrados devido a divergências fundamentais sobre o que
uma implementação inicial seria semelhante. Eu prefiro concordar com o
princípios agora do que se transformam em outro debate de implementação.


Você está recebendo isso porque foi mencionado.

Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/pypa/pip/issues/4802#issuecomment-348802032 ou silenciar
o segmento
https://github.com/notifications/unsubscribe-auth/ADH7ScUh-BveonoTxZ5FkkeSynFvoLb8ks5s8uNRgaJpZM4QBdSg
.

Honestamente, provavelmente não é um uso eficaz do tempo de ninguém discutir mais o tom da postagem, pois não é relevante incluir esses recursos no pip 10. No entanto, preciso de uma garantia de que minhas condições são aceitáveis ​​para mesclar de @pfmoore ( que indicou que não pode fazer tal garantia, o que é aceitável, já que ninguém é pago por seu tempo aqui), @dstufft ou @xavfernandez.

Novamente, as condições não são minha opinião pessoal, mas são orientadas pela implementação. Se eu relaxar essas condições, não posso prometer uma implementação, então não faz sentido perder tempo preparando um PR e as pessoas lerem as diferenças e perguntarem "oh, por que essa linha está aqui?" e então "oh, então isso não é mesclável?" porque houve uma falha de comunicação sobre qual era exatamente o propósito do PR.

Concordo com o tom. Meu ponto é simplesmente que eu não vou mesclar a mudança [1], então minha visão não é tão importante aqui.

[1] Obviamente, estou dizendo isso sem ter visto a implementação, então espero que fique claro que meus motivos não têm a ver com preocupações com a qualidade do código - é sobre não ter tempo para garantir que eu entenda o código bem o suficiente para estar disposto a fundir, basicamente.

@xoviat Quais são seus planos de implementação em relação à abordagem iterativa versus recursiva que discutimos acima?

Além disso, para esclarecer, você está dizendo que primeiro concluirá uma implementação parcial do PEP 517 e 518 que pode ser mesclada, seguida por uma implementação completa que pode ser mesclada? Ou você está dizendo que fará apenas a implementação parcial, ou está dizendo que fará uma implementação completa, passando por estágios anteriores que não serão necessariamente mescláveis? (Estou parcialmente tentando entender melhor o que você quer dizer com "inicialmente" e "eventualmente" em seu comentário .)

A primeira condição elimina todo o problema de recursão.

Além disso, para esclarecer, você está dizendo que primeiro concluirá uma implementação parcial do PEP 517 e 518 que pode ser mesclada, seguida por uma implementação completa que pode ser mesclada?

O que estou dizendo é que estarei completando uma implementação parcial que funcionará para 95% dos casos de uso; especificamente no caso em que as dependências têm rodas (muito comuns agora) e você está em uma plataforma manylinux/windows/OSX (grande maioria dos usuários).

Não é uma implementação completa. Mas a maneira como você obtém PRs não-combináveis ​​é tentar fazer a abordagem "tudo ou nada", onde você cumpre o padrão ou não.

Tenha em mente que uma implementação completa exigirá a classificação de alguns problemas bastante desagradáveis ​​que precisarão de um PR separado (como ter um PR com mais de 100 comentários geralmente significa que o código não é bem revisado). [1]

[1] https://github.com/btc1/bitcoin/pull/11#issuecomment -313843216

Vou encerrar este problema agora - temos suporte preliminar para PEP 518 no pip 10, que suporta apenas rodas como dependências de compilação. Vou abrir um novo tópico para discussão sobre suporte completo e outro para suporte PEP 517 (citando daqui como relevante).

Obrigado @ncoghlan @rgommers @cjerdonek por seus insights e ajuda aqui. Obrigado @takluyver pela implementação inicial do PEP 518. Obrigado @xoviat (que é @ghost agora) por toda a ajuda na implementação dessas mudanças. Obrigado @benoit-pierre por sua ajuda para melhorar o suporte atual.

PS: 100º comentário! :tada:

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

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