Python: Почему "~" теперь включено в набор зарезервированных символов в urllib.parse.quote()?
В последней документации для urllib
говорится:
Изменено в версии 3.7: Перемещено из RFC 2396 в RFC 3986 для цитирования строк URL. "~" теперь включен в набор зарезервированных символов.
Почему это так? В RFC 3986 ~
не является зарезервированным символом:
reserved = gen-delims / sub-delims
gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@"
sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
/ "*" / "+" / "," / ";" / "="
Явно в следующем разделе он включен как незаслуженный символ:
2,3. Незарезервированные персонажи
Символы, разрешенные в URI, но не имеющие зарезервированной цели, называются безоговорочными. К ним относятся прописные и строчные буквы, десятичные цифры, дефис, период, подчеркивание и тильда.
unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
Кроме того, в дальнейшем RFC заявляет, что (акцент мой):
Например, октет, соответствующий тильде ("~"), часто кодируется как "% 7E" более старыми реализациями обработки URI;
Таким образом, кажется, что 3.7 несовместимо: он утверждает поддержку нового RFC и одновременно регрессирует обработку ~
. (На самом деле, в более раннем RFC ~
также не зарезервировано и не " неразумно ")
Ответы
Ответ 1
Эта ошибка была отслежена и закрыта в https://bugs.python.org/issue16285
И действительно, самая последняя версия кода отражает изменения.
Ref https://github.com/python/cpython/blob/master/Lib/urllib/parse.py
_ALWAYS_SAFE = frozenset(b'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
b'abcdefghijklmnopqrstuvwxyz'
b'0123456789'
b'_.-~')