Installing packages from private pypi fails if password contains '@' character
So if I have login: someLogin password: Password@
then my pip.conf looks like:
[global]
extra-index-url = https://someLogin:Password@@nexus.privatepypy.com/repository/pypi/xxx
And this actually does not work. I have to type my password all the time.
Is there any workaround for this?
PS: Changing password is not a solution :-)
Maybe you need to percent scape it, as it is a URL.
>>> from urllib.parse import quote_plus
>>> quote_plus('Password@')
'Password%40'
For example in Mongo, to connect you can use:
>>> 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))
--- EDIT ---
I followed the code in pip to here:
And run the code manually, with both quoting and unquoting the password:
Unquoted:
>>> 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@')
Quoted:
>>> 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@')
As you can see it should work in both cases. As I could confirm pip unquotes the username and password, so it is better to quote them.
If it still doens't work I would check the pip version or file a bug.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.