(string: bytes | bytearray | str)
| 673 | return bytes(_unquote_impl(string)) |
| 674 | |
| 675 | def _unquote_impl(string: bytes | bytearray | str) -> bytes | bytearray: |
| 676 | # Note: strings are encoded as UTF-8. This is only an issue if it contains |
| 677 | # unescaped non-ASCII characters, which URIs should not. |
| 678 | if not string: |
| 679 | # Is it a string-like object? |
| 680 | string.split |
| 681 | return b'' |
| 682 | if isinstance(string, str): |
| 683 | string = string.encode('utf-8') |
| 684 | bits = string.split(b'%') |
| 685 | if len(bits) == 1: |
| 686 | return string |
| 687 | res = bytearray(bits[0]) |
| 688 | append = res.extend |
| 689 | # Delay the initialization of the table to not waste memory |
| 690 | # if the function is never called |
| 691 | global _hextobyte |
| 692 | if _hextobyte is None: |
| 693 | _hextobyte = {(a + b).encode(): bytes.fromhex(a + b) |
| 694 | for a in _hexdig for b in _hexdig} |
| 695 | for item in bits[1:]: |
| 696 | try: |
| 697 | append(_hextobyte[item[:2]]) |
| 698 | append(item[2:]) |
| 699 | except KeyError: |
| 700 | append(b'%') |
| 701 | append(item) |
| 702 | return res |
| 703 | |
| 704 | _asciire = re.compile('([\x00-\x7f]+)') |
| 705 |
no test coverage detected