I'm trying to inject a basic-authentication into an url by split-inject-join:
url = urllib.parse.urlsplit(url)
new_url = url._replace(username=user, password=password)
But I'm surprised about the behavior of the SplitResult
I get from the urllib.parse.urlsplit
method:
>>> v = urlsplit('http://a.b/c/d')
>>> v.username is None and v.password is None # None, but accessible
True
>>> v._replace(scheme='ftp') # beautiful! Just like expected.
SplitResult(scheme='ftp', netloc='a.b', path='/c/d', query='', fragment='')
# however...
>>> v._replace(scheme='ftp', username='u', password='p')
...ValueError: Got unexpected field names: ['username', 'password']
It seems as if the None
fields in this SplitResult
can not be replaced. This is odd, since the documentation claims it to be a named tuple.
When I do the equivalent with a self-constructed named tuple, it appears that the 'None' fields can be replaced without problem.
>>> T = namedtuple("T", ("a", "b", "c"))
>>> t = T(a=1, b=2, c=None)
>>> t
T(a=1, b=2, c=None)
>>> t._replace(c=3)
T(a=1, b=2, c=3)
But the same exception can be triggered by replacing an unexisting field.
>>> t._replace(d=4) # should raise, please
...ValueError: Got unexpected field names: ['d']
# I was expecting an AttributeError, but hey...
However, in this case, the unexpected field is really not accessible:
>>> t.d is None
...AttributeError: 'T' object has no attribute 'd'
Any idea what makes the SplitResult
different?