Like quote(), but accepts a bytes object rather than a str, and does not perform string-to-bytes encoding. It always returns an ASCII string. quote_from_bytes(b'abc def\x3f') -> 'abc%20def%3f'
(bs, safe='/')
| 974 | return _Quoter(safe).__getitem__ |
| 975 | |
| 976 | def quote_from_bytes(bs, safe='/'): |
| 977 | """Like quote(), but accepts a bytes object rather than a str, and does |
| 978 | not perform string-to-bytes encoding. It always returns an ASCII string. |
| 979 | quote_from_bytes(b'abc def\x3f') -> 'abc%20def%3f' |
| 980 | """ |
| 981 | if not isinstance(bs, (bytes, bytearray)): |
| 982 | raise TypeError("quote_from_bytes() expected bytes") |
| 983 | if not bs: |
| 984 | return '' |
| 985 | if isinstance(safe, str): |
| 986 | # Normalize 'safe' by converting to bytes and removing non-ASCII chars |
| 987 | safe = safe.encode('ascii', 'ignore') |
| 988 | else: |
| 989 | # List comprehensions are faster than generator expressions. |
| 990 | safe = bytes([c for c in safe if c < 128]) |
| 991 | if not bs.rstrip(_ALWAYS_SAFE_BYTES + safe): |
| 992 | return bs.decode() |
| 993 | quoter = _byte_quoter_factory(safe) |
| 994 | if (bs_len := len(bs)) < 200_000: |
| 995 | return ''.join(map(quoter, bs)) |
| 996 | else: |
| 997 | # This saves memory - https://github.com/python/cpython/issues/95865 |
| 998 | chunk_size = math.isqrt(bs_len) |
| 999 | chunks = [''.join(map(quoter, bs[i:i+chunk_size])) |
| 1000 | for i in range(0, bs_len, chunk_size)] |
| 1001 | return ''.join(chunks) |
| 1002 | |
| 1003 | def urlencode(query, doseq=False, safe='', encoding=None, errors=None, |
| 1004 | quote_via=quote_plus): |