繁体   English   中英

如果密码包含“ @”字符,则无法从私人pypi安装软件包

[英]Installing packages from private pypi fails if password contains '@' character

如果密码包含“ @”字符,则无法从私人pypi安装软件包

因此,如果我登录:someLogin密码:Password @

然后我的pip.conf看起来像:

[global]
extra-index-url = https://someLogin:Password@@nexus.privatepypy.com/repository/pypi/xxx

这实际上是行不通的。 我必须一直输入密码。

有什么解决方法吗?

PS:更改密码不是解决方案:-)

也许您需要对其进行转义,因为它是一个URL。

>>> from urllib.parse import quote_plus
>>> quote_plus('Password@')
'Password%40'

例如,在Mongo中,可以使用以下方法进行连接:

http://api.mongodb.com/python/current/examples/authentication.html#percent-escaping-username-and-password

>>> from pymongo import MongoClient
>>> import urllib.parse
>>> username = urllib.parse.quote_plus('user')
>>> username
'user'
>>> password = urllib.parse.quote_plus('pass/word')
>>> password
'pass%2Fword'
>>> MongoClient('mongodb://%s:%s@127.0.0.1' % (username, password))

-编辑-

我按照此处的代码进行操作:

https://github.com/pypa/pip/blob/1ea3f89ff9f005c78413907b36e55b3e76092612/src/pip/_internal/download.py#L140

并手动运行代码,同时引用和取消引用密码:

非上市:

>>> from urllib import parse as urllib_parse
>>> url = 'https://someLogin:Password@@nexus.privatepypy.com/repository/pypi/xxx'

>>> parsed = urllib_parse.urlparse(url)
>>> parsed
ParseResult(scheme='https', netloc='someLogin:Password@@nexus.privatepypy.com', path='/repository/pypi/xxx', params='', query='', fragment='')

>>> netloc = parsed.netloc.rsplit("@", 1)[-1]
>>> netloc
'nexus.privatepypy.com'

>>> url = urllib_parse.urlunparse(parsed[:1] + (netloc,) + parsed[2:])
>>> url
'https://nexus.privatepypy.com/repository/pypi/xxx'

>>> def parse_credentials(netloc):
...    if "@" in netloc:
...        userinfo = netloc.rsplit("@", 1)[0]
...        if ":" in userinfo:
...            user, pwd = userinfo.split(":", 1)
...            return (urllib_parse.unquote(user), urllib_parse.unquote(pwd))
...        return urllib_parse.unquote(userinfo), None
...    return None, None

>>> username, password = parse_credentials(parsed.netloc)
>>> username, password
('someLogin', 'Password@')

引:

>>> url = 'https://{}:{}@nexus.privatepypy.com/repository/pypi/xxx'.format(
...     urllib_parse.quote_plus('someLogin'), 
...     urllib_parse.quote_plus('Password@'), 
... )
>>> url
'https://someLogin:Password%40@nexus.privatepypy.com/repository/pypi/xxx'

>>> parsed = urllib_parse.urlparse(url)
>>> parsed
ParseResult(scheme='https', netloc='someLogin:Password%40@nexus.privatepypy.com', path='/repository/pypi/xxx', params='', query='', fragment='')

>>> username, password = parse_credentials(parsed.netloc)
>>> username, password
('someLogin', 'Password@')

如您所见,它在两种情况下都应该起作用。 由于我可以确认pip取消了用户名和密码的引用,因此最好使用引号。

如果仍然无法使用,我会检查pip版本或提交错误。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM