_quoters.py 1.1 KB

123456789101112131415161718192021222324252627282930313233
  1. """Quoting and unquoting utilities for URL parts."""
  2. from typing import Union
  3. from urllib.parse import quote
  4. from ._quoting import _Quoter, _Unquoter
  5. QUOTER = _Quoter(requote=False)
  6. REQUOTER = _Quoter()
  7. PATH_QUOTER = _Quoter(safe="@:", protected="/+", requote=False)
  8. PATH_REQUOTER = _Quoter(safe="@:", protected="/+")
  9. QUERY_QUOTER = _Quoter(safe="?/:@", protected="=+&;", qs=True, requote=False)
  10. QUERY_REQUOTER = _Quoter(safe="?/:@", protected="=+&;", qs=True)
  11. QUERY_PART_QUOTER = _Quoter(safe="?/:@", qs=True, requote=False)
  12. FRAGMENT_QUOTER = _Quoter(safe="?/:@", requote=False)
  13. FRAGMENT_REQUOTER = _Quoter(safe="?/:@")
  14. UNQUOTER = _Unquoter()
  15. PATH_UNQUOTER = _Unquoter(unsafe="+")
  16. PATH_SAFE_UNQUOTER = _Unquoter(ignore="/%", unsafe="+")
  17. QS_UNQUOTER = _Unquoter(qs=True)
  18. UNQUOTER_PLUS = _Unquoter(plus=True) # to match urllib.parse.unquote_plus
  19. def human_quote(s: Union[str, None], unsafe: str) -> Union[str, None]:
  20. if not s:
  21. return s
  22. for c in "%" + unsafe:
  23. if c in s:
  24. s = s.replace(c, f"%{ord(c):02X}")
  25. if s.isprintable():
  26. return s
  27. return "".join(c if c.isprintable() else quote(c) for c in s)