|
1 | 1 | import codecs |
2 | 2 | import sys |
3 | 3 | from collections.abc import Callable |
4 | | -from typing import Any |
5 | | -from typing_extensions import TypeAlias |
| 4 | +from typing import overload |
| 5 | +from typing_extensions import Literal, TypeAlias |
6 | 6 |
|
7 | 7 | # This type is not exposed; it is defined in unicodeobject.c |
8 | 8 | class _EncodingMap: |
9 | 9 | def size(self) -> int: ... |
10 | 10 |
|
11 | 11 | _MapT: TypeAlias = dict[int, int] | _EncodingMap |
12 | | -_Handler: TypeAlias = Callable[[Exception], tuple[str, int]] |
| 12 | +_Handler: TypeAlias = Callable[[UnicodeError], tuple[str | bytes, int]] |
| 13 | +_SearchFunction: TypeAlias = Callable[[str], codecs.CodecInfo | None] |
| 14 | + |
| 15 | +def register(__search_function: _SearchFunction) -> None: ... |
| 16 | + |
| 17 | +if sys.version_info >= (3, 10): |
| 18 | + def unregister(__search_function: _SearchFunction) -> None: ... |
13 | 19 |
|
14 | | -def register(__search_function: Callable[[str], Any]) -> None: ... |
15 | 20 | def register_error(__errors: str, __handler: _Handler) -> None: ... |
16 | | -def lookup(__encoding: str) -> codecs.CodecInfo: ... |
17 | 21 | def lookup_error(__name: str) -> _Handler: ... |
18 | | -def decode(obj: Any, encoding: str = ..., errors: str | None = ...) -> Any: ... |
19 | | -def encode(obj: Any, encoding: str = ..., errors: str | None = ...) -> Any: ... |
| 22 | + |
| 23 | +# The type ignore on `encode` and `decode` is to avoid issues with overlapping overloads, for more details, see #300 |
| 24 | +# https://docs.python.org/3/library/codecs.html#binary-transforms |
| 25 | +_BytesToBytesEncoding: TypeAlias = Literal[ |
| 26 | + "base64", |
| 27 | + "base_64", |
| 28 | + "base64_codec", |
| 29 | + "bz2", |
| 30 | + "bz2_codec", |
| 31 | + "hex", |
| 32 | + "hex_codec", |
| 33 | + "quopri", |
| 34 | + "quotedprintable", |
| 35 | + "quoted_printable", |
| 36 | + "quopri_codec", |
| 37 | + "uu", |
| 38 | + "uu_codec", |
| 39 | + "zip", |
| 40 | + "zlib", |
| 41 | + "zlib_codec", |
| 42 | +] |
| 43 | +# https://docs.python.org/3/library/codecs.html#text-transforms |
| 44 | +_StrToStrEncoding: TypeAlias = Literal["rot13", "rot_13"] |
| 45 | + |
| 46 | +@overload |
| 47 | +def encode(obj: bytes, encoding: _BytesToBytesEncoding, errors: str = ...) -> bytes: ... |
| 48 | +@overload |
| 49 | +def encode(obj: str, encoding: _StrToStrEncoding, errors: str = ...) -> str: ... # type: ignore[misc] |
| 50 | +@overload |
| 51 | +def encode(obj: str, encoding: str = ..., errors: str = ...) -> bytes: ... |
| 52 | +@overload |
| 53 | +def decode(obj: bytes, encoding: _BytesToBytesEncoding, errors: str = ...) -> bytes: ... # type: ignore[misc] |
| 54 | +@overload |
| 55 | +def decode(obj: str, encoding: _StrToStrEncoding, errors: str = ...) -> str: ... |
| 56 | + |
| 57 | +# these are documented as text encodings but in practice they also accept str as input |
| 58 | +@overload |
| 59 | +def decode( |
| 60 | + obj: str, encoding: Literal["unicode_escape", "unicode-escape", "raw_unicode_escape", "raw-unicode-escape"], errors: str = ... |
| 61 | +) -> str: ... |
| 62 | + |
| 63 | +# hex is officially documented as a bytes to bytes encoding, but it appears to also work with str |
| 64 | +@overload |
| 65 | +def decode(obj: str, encoding: Literal["hex", "hex_codec"], errors: str = ...) -> bytes: ... |
| 66 | +@overload |
| 67 | +def decode(obj: bytes, encoding: str = ..., errors: str = ...) -> str: ... |
| 68 | +def lookup(__encoding: str) -> codecs.CodecInfo: ... |
20 | 69 | def charmap_build(__map: str) -> _MapT: ... |
21 | 70 | def ascii_decode(__data: bytes, __errors: str | None = ...) -> tuple[str, int]: ... |
22 | 71 | def ascii_encode(__str: str, __errors: str | None = ...) -> tuple[bytes, int]: ... |
|
0 commit comments