]> jfr.im git - dlqueue.git/blob - venv/lib/python3.11/site-packages/pip/_vendor/idna/codec.py
init: venv aand flask
[dlqueue.git] / venv / lib / python3.11 / site-packages / pip / _vendor / idna / codec.py
1 from .core import encode, decode, alabel, ulabel, IDNAError
2 import codecs
3 import re
4 from typing import Tuple, Optional
5
6 _unicode_dots_re = re.compile('[\u002e\u3002\uff0e\uff61]')
7
8 class Codec(codecs.Codec):
9
10 def encode(self, data: str, errors: str = 'strict') -> Tuple[bytes, int]:
11 if errors != 'strict':
12 raise IDNAError('Unsupported error handling \"{}\"'.format(errors))
13
14 if not data:
15 return b"", 0
16
17 return encode(data), len(data)
18
19 def decode(self, data: bytes, errors: str = 'strict') -> Tuple[str, int]:
20 if errors != 'strict':
21 raise IDNAError('Unsupported error handling \"{}\"'.format(errors))
22
23 if not data:
24 return '', 0
25
26 return decode(data), len(data)
27
28 class IncrementalEncoder(codecs.BufferedIncrementalEncoder):
29 def _buffer_encode(self, data: str, errors: str, final: bool) -> Tuple[str, int]: # type: ignore
30 if errors != 'strict':
31 raise IDNAError('Unsupported error handling \"{}\"'.format(errors))
32
33 if not data:
34 return "", 0
35
36 labels = _unicode_dots_re.split(data)
37 trailing_dot = ''
38 if labels:
39 if not labels[-1]:
40 trailing_dot = '.'
41 del labels[-1]
42 elif not final:
43 # Keep potentially unfinished label until the next call
44 del labels[-1]
45 if labels:
46 trailing_dot = '.'
47
48 result = []
49 size = 0
50 for label in labels:
51 result.append(alabel(label))
52 if size:
53 size += 1
54 size += len(label)
55
56 # Join with U+002E
57 result_str = '.'.join(result) + trailing_dot # type: ignore
58 size += len(trailing_dot)
59 return result_str, size
60
61 class IncrementalDecoder(codecs.BufferedIncrementalDecoder):
62 def _buffer_decode(self, data: str, errors: str, final: bool) -> Tuple[str, int]: # type: ignore
63 if errors != 'strict':
64 raise IDNAError('Unsupported error handling \"{}\"'.format(errors))
65
66 if not data:
67 return ('', 0)
68
69 labels = _unicode_dots_re.split(data)
70 trailing_dot = ''
71 if labels:
72 if not labels[-1]:
73 trailing_dot = '.'
74 del labels[-1]
75 elif not final:
76 # Keep potentially unfinished label until the next call
77 del labels[-1]
78 if labels:
79 trailing_dot = '.'
80
81 result = []
82 size = 0
83 for label in labels:
84 result.append(ulabel(label))
85 if size:
86 size += 1
87 size += len(label)
88
89 result_str = '.'.join(result) + trailing_dot
90 size += len(trailing_dot)
91 return (result_str, size)
92
93
94 class StreamWriter(Codec, codecs.StreamWriter):
95 pass
96
97
98 class StreamReader(Codec, codecs.StreamReader):
99 pass
100
101
102 def getregentry() -> codecs.CodecInfo:
103 # Compatibility as a search_function for codecs.register()
104 return codecs.CodecInfo(
105 name='idna',
106 encode=Codec().encode, # type: ignore
107 decode=Codec().decode, # type: ignore
108 incrementalencoder=IncrementalEncoder,
109 incrementaldecoder=IncrementalDecoder,
110 streamwriter=StreamWriter,
111 streamreader=StreamReader,
112 )