Какая часть этого RFC вызывает такое безумие?
Это поведение правильно и соответствует с другими реализациями, как указано RFC3986 :
Сегмент пути, который содержит символ двоеточия (например, «this: that»), нельзя использовать в качестве первого сегмента ссылки относительного пути , так как он будет ошибочно принят за имя схемы. Такому сегменту должен предшествовать точечный сегмент (например, "./this:that"), чтобы сделать ссылку на относительный путь.
Это уже обсуждалось в другой записи :
Двоеточия разрешены в пути URI. Но вы должны быть осторожны, когда пишете относительные пути URI с двоеточием, так как это не разрешено при использовании так:
<a href="tag:sample">
В этом случае тег будет интерпретироваться как схема URI. Вместо этого вам нужно написать это так:
<a href="./tag:sample">
Использование urljoin
Функция urljoin
просто обрабатывает оба аргумента как URL (без какого-либо предположения). Требуется, чтобы их схемы были идентичными или вторая представляла относительный путь URI . В противном случае он возвращает только второй аргумент (хотя, ИМХО, это должно вызвать ошибку). Вы можете лучше понять логику, посмотрев на источник urljoin .
def urljoin(base, url, allow_fragments=True):
"""Join a base URL and a possibly relative URL to form an absolute
interpretation of the latter."""
...
bscheme, bnetloc, bpath, bparams, bquery, bfragment = \
urlparse(base, '', allow_fragments)
scheme, netloc, path, params, query, fragment = \
urlparse(url, bscheme, allow_fragments)
if scheme != bscheme or scheme not in uses_relative:
return _coerce_result(url)
Результаты процедуры синтаксического анализа urlparse
следующие:
>>> from urllib.parse import urlparse
>>> urlparse('123:abc')
ParseResult(scheme='123', netloc='', path='abc', params='', query='', fragment='')
>>> urlparse('abc:123')
ParseResult(scheme='', netloc='', path='abc:123', params='', query='', fragment='')
>>> urlparse('abc:a123')
ParseResult(scheme='abc', netloc='', path='a123', params='', query='', fragment='')