_quoters.py 1.1 KB

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