Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes15kdownloads
codec.py160 linesDownload Raw Back to idna
1import codecs2from typing import Any, Optional, Tuple3 4from .core import IDNAError, _unicode_dots_re, alabel, decode, encode, ulabel5 6 7class Codec(codecs.Codec):8    """Stateless IDNA 2008 codec.9 10    Implements the :class:`codecs.Codec` protocol so that the whole-domain11    encoder (:func:`idna.encode`) and decoder (:func:`idna.decode`) are12    accessible through the standard codec machinery as ``"idna2008"``.13 14    Only the ``"strict"`` error handler is supported; any other handler15    raises :exc:`~idna.IDNAError`.16    """17 18    def encode(self, data: str, errors: str = "strict") -> Tuple[bytes, int]:  # ty: ignore[invalid-method-override]19        if errors != "strict":20            raise IDNAError(f'Unsupported error handling "{errors}"')21 22        if not data:23            return b"", 024 25        return encode(data), len(data)26 27    def decode(self, data: bytes, errors: str = "strict") -> Tuple[str, int]:  # ty: ignore[invalid-method-override]28        if errors != "strict":29            raise IDNAError(f'Unsupported error handling "{errors}"')30 31        if not data:32            return "", 033 34        return decode(data), len(data)35 36 37class IncrementalEncoder(codecs.BufferedIncrementalEncoder):38    """Incremental IDNA 2008 encoder.39 40    Buffers a partial trailing label across calls until either the next41    label separator is seen or ``final=True``, so that streamed input is42    encoded one whole label at a time. Any of the four Unicode label43    separators (``U+002E``, ``U+3002``, ``U+FF0E``, ``U+FF61``) ends a44    label; the result always uses ``U+002E`` as the separator.45 46    Only the ``"strict"`` error handler is supported.47    """48 49    def _buffer_encode(self, data: str, errors: str, final: bool) -> Tuple[bytes, int]:  # ty: ignore[invalid-method-override]50        if errors != "strict":51            raise IDNAError(f'Unsupported error handling "{errors}"')52 53        if not data:54            return b"", 055 56        labels = _unicode_dots_re.split(data)57        trailing_dot = b""58        if labels:59            if not labels[-1]:60                trailing_dot = b"."61                del labels[-1]62            elif not final:63                # Keep potentially unfinished label until the next call64                del labels[-1]65                if labels:66                    trailing_dot = b"."67 68        result = []69        size = 070        for label in labels:71            result.append(alabel(label))72            if size:73                size += 174            size += len(label)75 76        # Join with U+002E77        result_bytes = b".".join(result) + trailing_dot78        size += len(trailing_dot)79        return result_bytes, size80 81 82class IncrementalDecoder(codecs.BufferedIncrementalDecoder):83    """Incremental IDNA 2008 decoder.84 85    Buffers a partial trailing label across calls until either the next86    label separator is seen or ``final=True``, so that streamed input is87    decoded one whole label at a time.88 89    Only the ``"strict"`` error handler is supported.90    """91 92    def _buffer_decode(self, data: Any, errors: str, final: bool) -> Tuple[str, int]:  # ty: ignore[invalid-method-override]93        if errors != "strict":94            raise IDNAError(f'Unsupported error handling "{errors}"')95 96        if not data:97            return ("", 0)98 99        if not isinstance(data, str):100            data = str(data, "ascii")101 102        labels = _unicode_dots_re.split(data)103        trailing_dot = ""104        if labels:105            if not labels[-1]:106                trailing_dot = "."107                del labels[-1]108            elif not final:109                # Keep potentially unfinished label until the next call110                del labels[-1]111                if labels:112                    trailing_dot = "."113 114        result = []115        size = 0116        for label in labels:117            result.append(ulabel(label))118            if size:119                size += 1120            size += len(label)121 122        result_str = ".".join(result) + trailing_dot123        size += len(trailing_dot)124        return (result_str, size)125 126 127class StreamWriter(Codec, codecs.StreamWriter):128    pass129 130 131class StreamReader(Codec, codecs.StreamReader):132    pass133 134 135def search_function(name: str) -> Optional[codecs.CodecInfo]:136    """Codec search function registered with :mod:`codecs`.137 138    Returns a :class:`codecs.CodecInfo` for the ``"idna2008"`` codec name139    so that ``str.encode("idna2008")`` and ``bytes.decode("idna2008")``140    invoke the IDNA 2008 codec defined in this module.141 142    :param name: The codec name being looked up.143    :returns: A :class:`codecs.CodecInfo` instance if ``name`` is144        ``"idna2008"``, otherwise ``None``.145    """146    if name != "idna2008":147        return None148    return codecs.CodecInfo(149        name=name,150        encode=Codec().encode,151        decode=Codec().decode,  # type: ignore152        incrementalencoder=IncrementalEncoder,153        incrementaldecoder=IncrementalDecoder,154        streamwriter=StreamWriter,155        streamreader=StreamReader,156    )157 158 159codecs.register(search_function)160 
codekingpro/portable-devtools · Team Ai