Pip: URLs de índice contendo "@" sem escape no nome de usuário causam o erro "Falha ao analisar" no pip 19.2

Criado em 23 jul. 2019  ·  66Comentários  ·  Fonte: pypa/pip

Meio Ambiente

  • versão pip: 19.2
  • Versão Python: 3.6.8
  • SO: ubuntu 18.04

Descrição
Depois de atualizar para pip-19.2 de pip-19.1.1, instalar pacotes com --extra-index-url não funciona e eu obtenho:

ERRO: Não foi possível encontrar uma versão que satisfaça o requisito package_name (das versões: nenhuma)
ERRO: Nenhuma distribuição correspondente encontrada para package_name

voltar para 19.1.1 funciona bem

finder auto-locked bug

Comentários muito úteis

+1
Sim. Aconteceu conosco também.

Todos 66 comentários

+1
Sim. Aconteceu conosco também.

Também temos problemas com pip-19.2 ao usar url de índice específico:

Looking in indexes: https://<email.com>:****@<artifactory_host>/artifactory/api/pypi/pypi-virtual/simple
Collecting setuptools
ERROR: Could not install packages due to an EnvironmentError: Failed to parse: https://<email.com>:[secure]@<artifactory_host>/artifactory/api/pypi/pypi-virtual/simple/setuptools/

Está funcionando bem com pip-19.1.1. Isso poderia estar relacionado?

@TTRh acabou de ver o mesmo e abriu # 6776. Não tenho certeza se deve ser tratado no mesmo problema.

@bomri , você pode executar novamente com --verbose e fornecer a saída?

Tivemos o mesmo problema com um caractere especial em nossa senha.

Oi pessoal! Obrigado por registrar este problema e concordar aqui.

Seria melhor que, se você estiver enfrentando esse problema, use as reações do GitHub na primeira postagem e se inscreva neste problema. Dessa forma, podemos evitar comentários "eu também", que realmente não agregam muito valor à discussão.

Isso tornará mais fácil para os mantenedores discutirem como resolver este problema, neste problema em si e fornecer atualizações para vocês mais facilmente. 🙃

@chrahunt rodando com --verbose eu obtenho 404 no pypi.org como esperado (já que o pacote não existe lá) mas do meu próprio servidor pypi eu obtenho:

Erro 403 do cliente: proibido para url: ...

talvez esteja relacionado a caracteres especiais no id do token como @brainerazer mencionado

Isso também nos mordeu. Não tenho certeza se este problema está relacionado aos @brainerazer vinculados por urllib3 . Nosso problema aparece ao tentar baixar um pacote .zip lançado do GitHub com um token de acesso. Portanto, coisas como pip install https://<my-access-token>@github.com/myorganization/myprivaterepo/archive/myrelease.zip#egg=mypackage não funcionam mais com o pip 19.2 (funciona para 19.1.1 como alguém já mencionou).

Criei um repositório privado vazio, com uma versão vazia para testar isso. A saída para pip install -vvv ... pode ser encontrada aqui:

O problema / diferença pode ser observado em torno de Starting new HTTPS connection (1): github.com:443 .

Talvez @cjerdonek saiba mais sobre essas coisas do que eu.

Também executei uma sessão git bisect para este problema e apontou para este commit: https://github.com/pypa/pip/commit/eeb74aeb29~~ c63ee61027fe

Minha opinião: o comportamento atual é mais tecnicamente correto e as pessoas deveriam começar a usar o novo suporte de chaveiro para essas coisas.

Ao mesmo tempo, definitivamente não é bom que isso tenha quebrado fluxos de trabalho razoáveis ​​existentes. Acho que se alguém descobrir como reintroduzir o comportamento legado aqui, seria ótimo.

Com base na política de depreciação documentada do pip, não precisamos ter um ciclo de depreciação para tais comportamentos não documentados. Mesmo assim, devemos fazer um ciclo de depreciação, alertando os usuários para mudar para a sintaxe ou ferramenta mais "correta" aqui, antes de descartar o suporte e mudar para uma mensagem de erro mais agradável.


Não tenho certeza se a bissecção encontrou o commit certo aqui, mas mesmo assim, obrigado por fazer isso!

@pradyunsg , talvez eu não tenha entendido ... você pode me indicar o "comportamento atual" necessário?
Se precisarmos refatorar a maneira como usamos repositórios de terceiros (em nosso caso gemfury.com), tudo bem. Só não entendo qual deve ser a sintaxe certa :)

Não tenho certeza se a bissecção encontrou o commit certo aqui, mas mesmo assim, obrigado por fazer isso!

você está totalmente certo. Corrigi meu script de teste e agora aponta para c63ee61027fe, o que faz mais sentido agora, eu acho

Tendo o mesmo problema

pip install --user --index-url https://[email protected]:[email protected]/foo/api/pypi/PyPi-dev/simple -v em-generate-config 
Created temporary directory: /tmp/pip-ephem-wheel-cache-1q06a68y 
Created temporary directory: /tmp/pip-req-tracker-1igksn7z 
Created requirements tracker '/tmp/pip-req-tracker-1igksn7z' 
Created temporary directory: /tmp/pip-install-six90fkc 
Looking in indexes: https://rnc_build%40foo.com:****@foo.jfrog.io/foo/api/pypi/PyPi-dev/simple 
Collecting em-generate-config 
  1 location(s) to search for versions of em-generate-config: 
  * https://rnc_build%40foo.com:****@bar.jfrog.io/foo/api/pypi/PyPi-dev/simple/em-generate-config/ 
  Getting page https://rnc_build%40foo.com:****@bar.jfrog.io/foo/api/pypi/PyPi-dev/simple/em-generate-config/ 
ERROR: Could not install packages due to an EnvironmentError. 
Traceback (most recent call last): 
  File "/usr/local/lib/python3.7/site-packages/pip/_vendor/requests/models.py", line 379, in prepare_url 
    scheme, auth, host, port, path, query, fragment = parse_url(url) 
  File "/usr/local/lib/python3.7/site-packages/pip/_vendor/urllib3/util/url.py", line 234, in parse_url 
    raise LocationParseError(url) 
pip._vendor.urllib3.exceptions.LocationParseError: Failed to parse: https://[email protected]:[email protected]/foo/api/pypi/PyPi-dev/simple/em-generate-config/

você pode me indicar o "comportamento atual" necessário?

Opa. Sim. (É por isso que eu precisava de uma soneca)

O problema aqui é que as partes de um URL devem ser ... codificados por url.

Assim, o @ no e-mail usado, como nome de usuário, deve ser %40 . O seguinte não é de fato um URL válido com base no RFC que define essas coisas:

https://[email protected]:[email protected]/pypi

A maneira correta de representar essas informações seria:

https://awesome%40pradyunsg.me:[email protected]/pypi

Se alguém tiver um problema com isso ... Eles provavelmente deveriam conversar com as pessoas que escreveram esse RFC. É mencionado no problema urllib relacionado mais adiante neste tópico.

À parte: @markuszoeller apontou a solução alternativa em um problema diferente que foi fechado como uma duplicata deste.


O que acho que estou sugerindo nesse comentário ... é que o pip pode detectar quando o usuário usa tais URLs inválidos (uma vez que aceitava isso no passado), avisa o usuário e funciona como 19.1.1 - depois de alguns vez, o aviso e a solução alternativa seriam removidos.

Se vocês acharem que é necessário depois dessa quebra, avise-nos.

Ficarei mais do que feliz em simplesmente pular o trabalho adicional se não for útil para as pessoas afetadas por ele - não há sentido em fazer coisas que não são úteis para os usuários finais. 🙃

Corrigi meu script de teste e agora aponta para c63ee61, o que faz mais sentido agora, eu acho

De fato. Eu posso ver por que não estávamos detectando esses usos antes - pip estava fazendo um processamento "caseiro" das informações de autenticação do URL de índice, o que obviamente não considerava essa entrada inválida. O que mudou é que agora estamos usando uma função de utilitário urllib para obter partes da URL, que é mais rígida e compatível com RFC.

pip estava fazendo um processamento "caseiro" das informações de autenticação do URL de índice, o que obviamente não considerava essa entrada inválida. O que mudou é que agora estamos usando uma função de utilitário urllib3 para obter partes da URL, que é mais rígida e compatível com RFC.

certo, agora entendi, obrigado @pradyunsg. Para aqueles que estão assistindo em casa;) como uma correção, pode-se passar https://<my-access-token>:@github.com/myorganization/myprivaterepo/archive/myrelease.zip#egg=mypackage (observe o : após o token de acesso), o que torna o URL mais compatível com RFC (não é?) E o pip instala com prazer o pacote.

EDITAR:
ou (melhor ainda) https://:<my-access-token>@github.com/...

torna o URL mais compatível com RFC (não é?)

Nenhuma pista. Não sou um especialista no assunto.

Tudo o que eu disse acima é basicamente um palpite bem informado que fiz olhando todos os trechos de código relevantes no meu telefone ... porque meu laptop está muito longe da cama. 🙃

https: //: @ github.com / myorganization / myprivaterepo /

Observando a última coisa que direi aqui com base em (apenas) intuição + memória, parece que o pip requer incorretamente a presença de ambos os componentes de nome de usuário / senha.

Se for esse o caso, é quase certo que seja um bug, embora seja separado.

Tentei o último comentário do @slafs e parece estar funcionando bem para mim.
Adicionar ":" após o token funciona, enquanto adicioná-lo antes do token não

Adicionar ":" após o token funciona, enquanto adicioná-lo antes do token não

certo, não sei por que funciona para mim (ou seja, com pip), mas agora vejo que um simples curl -L não fará o download do pacote se : estiver antes do token.

Se for esse o caso, é quase certo que seja um bug, embora seja separado.

sim, agora estou inclinado a acreditar que não ter : na seção de autenticação da URL também está totalmente certo. Quero dizer, curl não reclama. Nem urllib3 :

>>> import urllib3
>>> urllib3.__version__
'1.25.3'
>>> urllib3.util.parse_url('http://user<strong i="16">@host</strong>')
Url(scheme='http', auth='user', host='host', port=None, path=None, query=None, fragment=None)

Acho que vou registrar um problema sobre isso.

Acho que vou registrar um problema sobre isso.

Por favor faça. :)

Para as pessoas que já passaram um tempo examinando isso, você pode vincular à linha de código que está fazendo a análise em discussão?

@cjerdonek Não tenho certeza se tenho uma linha exata para você. Olhando rapidamente para c63ee61027fe7dea, posso dizer que https://github.com/pypa/pip/blob/81040b5d0644460a46a360d67c451c03bbbb03ab/src/pip/_internal/download.py#L333 -L335 parece suspeito para mim. Especialmente em comparação com a versão anterior desse arquivo: https://github.com/pypa/pip/blob/e34769861ec5ed8aa5ce23670e111fe8db446c39/pip/download.py#L91 -L96

oh, desculpe @cjerdonek , você provavelmente está perguntando sobre o problema com @ não codificado. Eu estava me referindo ao meu problema com o token de autenticação.

Além disso, acho que devemos estar abertos à possibilidade de haver duas questões aqui. Neste comentário (segunda resposta à postagem original), há um erro de análise nos logs (evidentemente vindo de urllib3 com base no texto "Falha ao analisar"):

ERROR: Não foi possível instalar pacotes devido a um EnvironmentError: Falha ao analisar: https://<email.com>:[secure]@<artifactory_host>/artifactory/api/pypi/pypi-virtual/simple/setuptools/

Mas na postagem original, um erro "Nenhuma distribuição correspondente encontrada para nome_do_pacote" foi relatado sem um erro "Falha ao analisar" nos logs (a menos que isso estivesse presente nos logs, mas simplesmente não incluído no relatório).

Seria bom saber o rastreamento de pilha no ponto do primeiro erro acima.

Hmm ... Parece que minha intuição não estava exatamente correta. Hah!

@cjerdonek Eu estava me referindo à análise acontecendo em MultiDomainBasicAuth .__ call__, mas vejo agora que ele estava de fato usando os utilitários de análise do urllib. A coisa estranha que me desconcertou foi a concatenação, mas acho que está ... tudo bem?

ISTM agora que a condição que @slafs apontou pode ser a causa raiz disso - alterando-a para or vez de and , e tendo or "" na chamada , deve corrigir o problema auth-needs-2-parts, bem como este relatório, eu acho.

Aqui está o traceback completo quando reproduzi o erro "Falha ao analisar" com um extra-index-url criado (acredito que o modo verboso faz com que o traceback seja exibido):

$ pip install twine --extra-index-url https://[email protected]:[email protected]/simple/ -vvv
...
  Getting page https://foo%40example.com:****@github.com/simple/twine/
ERROR: Could not install packages due to an EnvironmentError.
Traceback (most recent call last):
  File "/.../pip/src/pip/_vendor/requests/models.py", line 379, in prepare_url
    scheme, auth, host, port, path, query, fragment = parse_url(url)
  File "/.../pip/src/pip/_vendor/urllib3/util/url.py", line 234, in parse_url
    raise LocationParseError(url)
pip._vendor.urllib3.exceptions.LocationParseError: Failed to parse: https://[email protected]:[email protected]/simple/twine/

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/.../pip/src/pip/_internal/commands/install.py", line 345, in run
    resolver.resolve(requirement_set)
  File "/.../pip/src/pip/_internal/legacy_resolve.py", line 196, in resolve
    self._resolve_one(requirement_set, req)
  File "/.../pip/src/pip/_internal/legacy_resolve.py", line 359, in _resolve_one
    abstract_dist = self._get_abstract_dist_for(req_to_install)
  File "/.../pip/src/pip/_internal/legacy_resolve.py", line 307, in _get_abstract_dist_for
    self.require_hashes
  File "/.../pip/src/pip/_internal/operations/prepare.py", line 134, in prepare_linked_requirement
    req.populate_link(finder, upgrade_allowed, require_hashes)
  File "/.../pip/src/pip/_internal/req/req_install.py", line 211, in populate_link
    self.link = finder.find_requirement(self, upgrade)
  File "/.../pip/src/pip/_internal/index.py", line 1201, in find_requirement
    req.name, specifier=req.specifier, hashes=hashes,
  File "/.../pip/src/pip/_internal/index.py", line 1183, in find_candidates
    candidates = self.find_all_candidates(project_name)
  File "/.../pip/src/pip/_internal/index.py", line 1128, in find_all_candidates
    for page in self._get_pages(url_locations, project_name):
  File "/.../pip/src/pip/_internal/index.py", line 1282, in _get_pages
    page = _get_html_page(location, session=self.session)
  File "/.../pip/src/pip/_internal/index.py", line 234, in _get_html_page
    resp = _get_html_response(url, session=session)
  File "/.../pip/src/pip/_internal/index.py", line 182, in _get_html_response
    "Cache-Control": "max-age=0",
  File "/.../pip/src/pip/_vendor/requests/sessions.py", line 546, in get
    return self.request('GET', url, **kwargs)
  File "/.../pip/src/pip/_internal/download.py", line 610, in request
    return super(PipSession, self).request(method, url, *args, **kwargs)
  File "/.../pip/src/pip/_vendor/requests/sessions.py", line 519, in request
    prep = self.prepare_request(req)
  File "/.../pip/src/pip/_vendor/requests/sessions.py", line 462, in prepare_request
    hooks=merge_hooks(request.hooks, self.hooks),
  File "/.../pip/src/pip/_vendor/requests/models.py", line 313, in prepare
    self.prepare_url(url, params)
  File "/.../pip/src/pip/_vendor/requests/models.py", line 381, in prepare_url
    raise InvalidURL(*e.args)
pip._vendor.requests.exceptions.InvalidURL: Failed to parse: https://[email protected]:[email protected]/simple/twine/

Curiosamente, como você pode ver na primeira mensagem de registro acima:

Obtendo a página https: //foo%40example.com : * *@github.com/simple/twine/

nosso próprio código de registro consegue citar o caractere no nome de usuário que, se fosse citado na solicitação real, eu acredito que resolveria (um dos) problemas. Essa cotação para registro acontece em redact_netloc() : https://github.com/pypa/pip/blob/81040b5d0644460a46a360d67c451c03bbbb03ab/src/pip/_internal/utils/misc.py#L1109 -L1122

heh, sobre esse último, também descobri que pip nem sempre edita a senha. Se você alterar as credenciais para "válidas", depois de fazer pip install você obterá, por exemplo,

$ pip install https://foo:[email protected]/slafs
Collecting https://foo:****@github.com/slafs
  Downloading https://foo:[email protected]/slafs
...

😅

@ pypa / pip-committers Portanto, para o erro causado pela análise de URL mais estrita introduzida pela atualização do fornecedor urllib3 v1.25 (PR original https://github.com/urllib3/urllib3/pull/1487 com problema subsequente https: //github.com/urllib3/urllib3/issues/1640), queremos manter as coisas como estão e exigir que os usuários citem as coisas corretamente (não parece que urllib3 mudará) ou queremos "consertar" a URL fornecida pelo usuário fazendo algo como o que é feito em redact_netloc() acima? Voltar à lógica anterior sem corrigir a URL fornecida pelo usuário significaria reverter a atualização do fornecedor do urllib3, o que não tenho certeza se gostaríamos de fazer.

heh, sobre esse último, também descobri que pip nem sempre edita a senha.

Você pode arquivar isso como um problema separado. pip não tem uma maneira "global" de fazer isso agora. Acredito que existam alguns casos semelhantes como esse como problemas de pip.

queremos manter as coisas como estão e exigir que os usuários citem as coisas corretamente

Se os usuários que entraram com esse problema disserem que citar @ é complexo para eles, eu diria que vamos adicionar uma solução alternativa para o urllib3.

Não sou fã da ideia de trabalhar em torno do urllib3, embora já tenha sugerido isso antes.

Eu concordo - eu prefiro não "consertar" o URL, é provável que seja um código frágil que teríamos que manter, mas se citar @ for complexo para os usuários realmente afetados por esse problema, devemos fazer o que pode aliviar sua dor.

Eu estaria inclinado a tornar qualquer solução temporária, porém, e iniciar um processo de descontinuação de URLs não compatíveis (dando aos usuários tempo para resolver isso, mas não mantendo a solução alternativa indefinidamente).

Pelo que vale a pena, parece que os uploads de fio não funcionam se você usar um nome de usuário com %40 vez de @ . Portanto, no meu caso, tenho uma credencial de nome de usuário PyPI armazenada em meu mecanismo de armazenamento secreto. Se eu atualizar esse nome de usuário para foo%40bar.com , minhas instalações de pip funcionarão, no entanto, meu upload de cordão (que usa a mesma credencial) falhará:

twine upload --verbose --repository-url https://mypypi.com -u foo%40bar.com -p <redacted> dist/my-package-*
Uploading distributions to https://mypypi.com
Uploading my-package-1.2.3.tar.gz

100% 166k/166k [00:00<00:00, 430kB/s]  
Content received from server:
<html>
 <head>
  <title>401 Unauthorized</title>
 </head>
 <body>
  <h1>401 Unauthorized</h1>
  This server could not verify that you are authorized to access the document you requested.  Either you supplied the wrong credentials (e.g., bad password), or your browser does not understand how to supply the credentials required.<br/><br/>

Estou testemunhando um problema separado, mas semelhante, em que --extra-index-url falha se houver qualquer tipo de autorização. Não apenas sendo escapado por @.

Usando:
python 3.7.4
pip 19.2.1

  1. Remover a autorização e tornar o pacote público em nosso repositório privado nos permite baixá-lo
  2. Claro, fazer o downgrade para o pip 19.1.1 também resolve o problema
pip3 install package --extra-index-url https://[email protected]/pypi -vvv

Traceback:

Created temporary directory: /private/var/folders/rb/rg18vqd16lxg47cm1kvgh3yh0000gn/T/pip-ephem-wheel-cache-dkqjnspg
Created temporary directory: /private/var/folders/rb/rg18vqd16lxg47cm1kvgh3yh0000gn/T/pip-req-tracker-_5f9p1zv
Created requirements tracker '/private/var/folders/rb/rg18vqd16lxg47cm1kvgh3yh0000gn/T/pip-req-tracker-_5f9p1zv'
Created temporary directory: /private/var/folders/rb/rg18vqd16lxg47cm1kvgh3yh0000gn/T/pip-install-ajhlm6xm
Looking in indexes: https://pypi.org/simple, https://[email protected]/pypi
Collecting package
  2 location(s) to search for versions of package:
  * https://pypi.org/simple/package/
  * https://[email protected]/pypi/package/
  Getting page https://pypi.org/simple/package/
  Found index url https://pypi.org/simple
  Looking up "https://pypi.org/simple/package/" in the cache
  Request header has "max_age" as 0, cache bypassed
  Starting new HTTPS connection (1): pypi.org:443
  https://pypi.org:443 "GET /simple/package/ HTTP/1.1" 404 13
  Status code 404 not in (200, 203, 300, 301)
  Could not fetch URL https://pypi.org/simple/package/: 404 Client Error: Not Found for url: https://pypi.org/simple/package/ - skipping
  Getting page https://[email protected]/pypi/package/
  Found index url https://private-repo.io/pypi
  Looking up "https://private-repo.io/pypi/package/" in the cache
  Request header has "max_age" as 0, cache bypassed
  Starting new HTTPS connection (1): private-repo.io:443
  https://private-repo.io:443 "GET /pypi/package/ HTTP/1.1" 404 10
  Status code 404 not in (200, 203, 300, 301)
  Could not fetch URL https://[email protected]/pypi/package/: 404 Client Error: Not Found for url: https://private-repo.io/pypi/package/ - skipping
  Given no hashes to check 0 links for project 'package': discarding no candidates
  ERROR: Could not find a version that satisfies the requirement package (from versions: none)
Cleaning up...
Removed build tracker '/private/var/folders/rb/rg18vqd16lxg47cm1kvgh3yh0000gn/T/pip-req-tracker-_5f9p1zv'
ERROR: No matching distribution found for package
Exception information:
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/pip/_internal/cli/base_command.py", line 188, in main
    status = self.run(options, args)
  File "/usr/local/lib/python3.7/site-packages/pip/_internal/commands/install.py", line 345, in run
    resolver.resolve(requirement_set)
  File "/usr/local/lib/python3.7/site-packages/pip/_internal/legacy_resolve.py", line 196, in resolve
    self._resolve_one(requirement_set, req)
  File "/usr/local/lib/python3.7/site-packages/pip/_internal/legacy_resolve.py", line 359, in _resolve_one
    abstract_dist = self._get_abstract_dist_for(req_to_install)
  File "/usr/local/lib/python3.7/site-packages/pip/_internal/legacy_resolve.py", line 307, in _get_abstract_dist_for
    self.require_hashes
  File "/usr/local/lib/python3.7/site-packages/pip/_internal/operations/prepare.py", line 134, in prepare_linked_requirement
    req.populate_link(finder, upgrade_allowed, require_hashes)
  File "/usr/local/lib/python3.7/site-packages/pip/_internal/req/req_install.py", line 211, in populate_link
    self.link = finder.find_requirement(self, upgrade)
  File "/usr/local/lib/python3.7/site-packages/pip/_internal/index.py", line 1228, in find_requirement
    'No matching distribution found for %s' % req
pip._internal.exceptions.DistributionNotFound: No matching distribution found for package

@bmckalla você tentou com https://:[email protected] vez disso? consulte: https://github.com/pypa/pip/issues/6775#issuecomment -514272956

@TTRh

Tendo o mesmo problema, mas acho que : deve ir atrás do token. Pelo menos, essa é uma solução alternativa que funciona para mim agora: https://token:@private-repo.io

@TTRh @jgspiro Colocando : depois que o token funcionou, obrigado!

Pelo que vale a pena, parece que os uploads de twine não funcionam se você usar um nome de usuário com% 40 em vez de @.

@leviable ~ Eu recomendaria registrar um problema no rastreador do twine se ainda não houver um link para este problema. ~ Olhando mais de perto a sua postagem original, quando você passa um nome de usuário para o twine, você não está fazendo isso como parte de uma URL, mas sim como um valor autônomo -u <username> , então a cotação de URL não funcionará nesse contexto. Você precisará fazer algum processamento extra no nome de usuário para usar a mesma configuração para ambos (veja, por exemplo, o comentário após este para obter ideias).

apenas FYI, url quote the password funciona para nós.

password='passwordwith@$$!!'
encoded=$(python3 -c 'from urllib.parse import quote;print(quote("'${password}'"))')
export PIP_EXTRA_INDEX_URL='https://username:'${encoded}'@nexus.hostname.com/repository/pypi-all/simple'
pip install your_package

@TTRh

Tendo o mesmo problema, mas acho que : deve ir atrás do token. Pelo menos, essa é uma solução alternativa que funciona para mim agora: https://token:@private-repo.io

Isso é considerado um bug ou comportamento pretendido (não salvar credencial quando não há : com token)?

Algumas modificações em download.py aqui parecem resolver o problema.

É um bug que ainda precisa ser corrigido, eu acredito.

Pousei no mesmo patch que https://github.com/booleand/pip/commit/9761f46520b94c027b0e6732223e391088f745a5#diff -34481ab2fefef95e8820a46e86004ae7

@booleand você gostaria de enviar um patch?

@pradyunsg Sim estou

@booleand seria ótimo se você registrasse um PR. :)

obrigado @pradyunsg. entrou com um PR # 6795

Seguindo https://github.com/pypa/pip/issues/6775#issuecomment -514284653, abri # 6796 para a autenticação "um elemento" no URL do pacote.

Obrigado @slafs. Nesse caso, acho que podemos fechar este.

Que tal documentar esse caso nos documentos (inclusive com um exemplo), já que parece comum e pode enganar as pessoas?

@cjerdonek , adicionou # 6797 para rastrear essa ação.

Publiquei um PR (# 6818), que corrige os nossos problemas de manipulação de URL (este e # 6796).

Eu apreciaria se o pessoal deste tópico pudesse dar uma olhada no # 6818 e me dizer se funciona.


Para instalar o pip desse branch em seu ambiente local, execute:

pip install https://github.com/pradyunsg/pip/archive/fix/URL-authentication-handling.zip

Eu não acho que RP resolve esse problema? Achei que esse problema fosse sobre nomes de usuário que incluem um @ quando uma senha está presente (não tem a ver com Nenhum / não-nenhum), e o outro problema é sobre a ausência de senha. Mas não vejo o primeiro entre os casos de teste. (Seria necessário haver dois símbolos @ sem escape nos casos de teste.) Além disso, achei que corrigir o anterior significaria que teríamos que “consertar” / reescrever a URL, o que não vejo sendo feito no PR.

Não vejo o primeiro entre os casos de teste

Ah sim. Que pena, omiti o teste para isso. Eu fui em frente e adicionei esse caso ao conjunto de testes - executá-lo localmente confirma que extraiu o endereço de email corretamente.

"http://[email protected]:[email protected]/path" -> ("http://example.com/path", "[email protected]", "password")

Achei que consertar o anterior significaria que teríamos que “consertar” / reescrever a URL, o que não vejo sendo feito no PR.

Ah sim. Eu também inicialmente.

No entanto, olhei para a diferença de solicitações e fornecedores de urllib3 e não vi nada em um caminho de código que nos afetou diretamente aqui. Decidi tentar ver se reverter para as alterações da estrutura original funcionava e parece que funcionou.

Meu entendimento agora é que isso tem algo a ver com o tratamento padrão de solicitações de URLs que contêm informações de autenticação e (de alguma forma) estamos contornando esses problemas em nossa subclasse Session .

Meu entendimento agora é que isso tem algo a ver com o tratamento padrão de URLs que contêm informações de autenticação e (de alguma forma) estamos contornando esses problemas em nossa subclasse de Sessão.

Não, se você olhar meu comentário acima, onde incluí o rastreamento para este problema, você verá que passamos o URL original: https://github.com/pypa/pip/issues/6775#issuecomment -514313192
E o seu PR não "corrige" / reescreve o URL original, de modo que eu não esperaria que esse comportamento mudasse em seu PR.

Só para ter certeza, tentei repetir aquele comando em seu PR e confirmei que o mesmo erro ainda acontece.

Aqui está meu comentário acima, onde falo sobre uma abordagem para corrigir o problema atual: https://github.com/pypa/pip/issues/6775#issuecomment -514322734

Certo, faz sentido para mim. Acho que estava misturando problemas na minha cabeça.

Que tal documentar esse caso nos documentos (inclusive com um exemplo), já que parece comum e pode enganar as pessoas?

Também faria sentido abortar nessa situação e imprimir um aviso se houver um "@" sem escape no URL. É provavelmente mais detectável do que a documentação e mais amigável do que tê-lo na documentação.


Resumindo o estado de coisas no pip 19.2, para meu eu estúpido:

  • A autenticação com apenas um token (ou seja, nome de usuário, sem senha) foi interrompida - a lógica atual do pip assume que ambas as partes estariam presentes. É para isso que serve o # 6796.
  • A autenticação com um nome de usuário que não é codificado por URL não funciona mais - o pip 19.2 falha com um traceback, o pip 19.1.1 aceita tais URLs. A origem desse problema é que o urllib3 se tornou mais rígido na análise de tais URLs.

Olá, estamos enfrentando o mesmo problema com o pip 18.1, urllib3 (1.24.1) e Python2.7, mas na seção de senha.
https://pypi.org/simple --extra-index-url http://user:password@@124.4.56:8086 --trusted-host 124.4.56
https://pypi.org/project/urllib3/ não lista nenhuma alteração relacionada à especificação RFC 3986 acima. Também @cjerdonek @pradyunsg, você poderia recomendar versões estáveis ​​de ambos os pacotes para que possamos instalá-los.

Lançado o pip 19.2.2 contendo uma correção para os tokens que precisam de : .

Para pessoas que enfrentam problemas com @ em suas senhas, o caminho sugerido é escapar de @ nas URLs.

Edit: Não parece estar relacionado ao '%', pois mudei minha senha para "password" e obtive o mesmo resultado.


Outra torção nisso: minha antiga senha gerada (costumava) terminar em "%".

Na versão 19.2.2

Substituindo % por %25 ou deixando-o sozinho, vejo o mesmo erro:

(Supondo que minha senha fosse: password% )

ERROR: Exception:
Traceback (most recent call last):
  File "/Library/Python/2.7/site-packages/pip/_internal/cli/base_command.py", line 188, in main
    status = self.run(options, args)
  File "/Library/Python/2.7/site-packages/pip/_internal/commands/install.py", line 345, in run
    resolver.resolve(requirement_set)
  File "/Library/Python/2.7/site-packages/pip/_internal/legacy_resolve.py", line 196, in resolve
    self._resolve_one(requirement_set, req)
  File "/Library/Python/2.7/site-packages/pip/_internal/legacy_resolve.py", line 359, in _resolve_one
    abstract_dist = self._get_abstract_dist_for(req_to_install)
  File "/Library/Python/2.7/site-packages/pip/_internal/legacy_resolve.py", line 307, in _get_abstract_dist_for
    self.require_hashes
  File "/Library/Python/2.7/site-packages/pip/_internal/operations/prepare.py", line 134, in prepare_linked_requirement
    req.populate_link(finder, upgrade_allowed, require_hashes)
  File "/Library/Python/2.7/site-packages/pip/_internal/req/req_install.py", line 211, in populate_link
    self.link = finder.find_requirement(self, upgrade)
  File "/Library/Python/2.7/site-packages/pip/_internal/index.py", line 1201, in find_requirement
    req.name, specifier=req.specifier, hashes=hashes,
  File "/Library/Python/2.7/site-packages/pip/_internal/index.py", line 1183, in find_candidates
    candidates = self.find_all_candidates(project_name)
  File "/Library/Python/2.7/site-packages/pip/_internal/index.py", line 1111, in find_all_candidates
    if self._validate_secure_origin(logger, link)
  File "/Library/Python/2.7/site-packages/pip/_internal/index.py", line 998, in _validate_secure_origin
    origin = (parsed.scheme, parsed.hostname, parsed.port)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urlparse.py", line 113, in port
    port = int(port, 10)
ValueError: invalid literal for int() with base 10: 'password%%40mydomain.com'

ou

ValueError: invalid literal for int() with base 10: 'password%25%40mydomain.com'

Você pode tentar codificar apenas a parte da credencial do URL - por exemplo, password%[email protected] ?

Mudar para password%[email protected] me permite prosseguir.

Não há nada mais acionável aqui. Para encerrar, vou resumir esse problema e fazer uma frase de chamariz.

O que aconteceu?

pip 19.2 agora requer que as credenciais sejam citadas no URL. Assim, caracteres como @ e % precisam ser citados no URL (como %40 e %25 ).

Assim, os seguintes index-urls não funcionarão mais:

https://[email protected]:[email protected]/
https://user:password%@mydomain.com/

Os equivalentes que funcionam são:

https://pradyunsg%40email.com:[email protected]/
https://user:password%[email protected]/

Por quê?

pip (e solicitações) usam urllib3 para muitas das manipulações de URL subjacentes. O urllib3 introduziu uma análise de URL mais rígida na versão para a qual o pip foi atualizado em 19.2. Como essa rigidez só foi "detectada" após o lançamento, os desenvolvedores de pip decidiram não contornar a análise mais rígida. Os fluxos de trabalho dos usuários afetados já haviam sido interrompidos e nenhum indicou que seria particularmente difícil para eles citarem suas credenciais corretamente.

Como você pode ajudar?

Os desenvolvedores do pip não querem interromper os fluxos de trabalho de seus usuários. No entanto, isso é difícil porque o pip é um projeto mantido inteiramente por voluntários, com uma base de código legada que dificulta a integração de contribuidores adicionais.

Há uma falta substancial de tempo do desenvolvedor no pip, especialmente devido ao impacto que as mudanças nele podem ter sobre os usuários. Para nos ajudar a evitar problemas como esse e fazer melhorias mais substanciais no pip, considere financiar melhorias no Python Packaging. Financiar tais projetos relacionados ao pip permitiria aos mantenedores atuais trabalhar no pip por mais tempo e trazer especialistas adicionais (especialistas em UX, gerentes de projeto, redatores técnicos, etc.) para tornar o pip melhor.

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