diff --git a/.travis.yml b/.travis.yml index d81b6fa..4666146 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,19 +3,26 @@ arch: - amd64 - ppc64le python: - - "3.4" - "3.5" - "3.6" - "3.7" - "3.8" - "3.9" - "pypy3" -# Disable unsuported version pypy for ppc64le +# Disable unsupported version pypy for ppc64le jobs: exclude: - arch: ppc64le python: pypy3 +matrix: + include: + - python: 3.9 + install: + - pip install mypy + script: + - mypy --strict idna/ + install: - pip install . script: diff --git a/MANIFEST.in b/MANIFEST.in index 66a19d4..3d746f6 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,7 +1,6 @@ include *.rst include LICENSE.md include idna/py.typed -recursive-include idna *.pyi recursive-include tools * recursive-exclude tools *.pyc recursive-include tests * diff --git a/idna/__init__.py b/idna/__init__.py index 338e170..a40eeaf 100644 --- a/idna/__init__.py +++ b/idna/__init__.py @@ -12,7 +12,6 @@ check_nfc, decode, encode, - intranges_contain, ulabel, uts46_remap, valid_contextj, @@ -20,6 +19,7 @@ valid_label_length, valid_string_length, ) +from .intranges import intranges_contain __all__ = [ "IDNABidiError", diff --git a/idna/codec.py b/idna/codec.py index 30fe72f..080f22a 100644 --- a/idna/codec.py +++ b/idna/codec.py @@ -1,23 +1,24 @@ from .core import encode, decode, alabel, ulabel, IDNAError import codecs import re +from typing import Tuple, Optional _unicode_dots_re = re.compile('[\u002e\u3002\uff0e\uff61]') class Codec(codecs.Codec): def encode(self, data, errors='strict'): - + # type: (str, str) -> Tuple[bytes, int] if errors != 'strict': raise IDNAError('Unsupported error handling \"{}\"'.format(errors)) if not data: - return "", 0 + return b"", 0 return encode(data), len(data) def decode(self, data, errors='strict'): - + # type: (bytes, str) -> Tuple[str, int] if errors != 'strict': raise IDNAError('Unsupported error handling \"{}\"'.format(errors)) @@ -27,12 +28,13 @@ def decode(self, data, errors='strict'): return decode(data), len(data) class IncrementalEncoder(codecs.BufferedIncrementalEncoder): - def _buffer_encode(self, data, errors, final): + def _buffer_encode(self, data, errors, final): # type: ignore + # type: (str, str, bool) -> Tuple[str, int] if errors != 'strict': raise IDNAError('Unsupported error handling \"{}\"'.format(errors)) if not data: - return ('', 0) + return "", 0 labels = _unicode_dots_re.split(data) trailing_dot = '' @@ -55,12 +57,13 @@ def _buffer_encode(self, data, errors, final): size += len(label) # Join with U+002E - result = '.'.join(result) + trailing_dot + result_str = '.'.join(result) + trailing_dot # type: ignore size += len(trailing_dot) - return (result, size) + return result_str, size class IncrementalDecoder(codecs.BufferedIncrementalDecoder): - def _buffer_decode(self, data, errors, final): + def _buffer_decode(self, data, errors, final): # type: ignore + # type: (str, str, bool) -> Tuple[str, int] if errors != 'strict': raise IDNAError('Unsupported error handling \"{}\"'.format(errors)) @@ -87,22 +90,26 @@ def _buffer_decode(self, data, errors, final): size += 1 size += len(label) - result = '.'.join(result) + trailing_dot + result_str = '.'.join(result) + trailing_dot size += len(trailing_dot) - return (result, size) + return (result_str, size) class StreamWriter(Codec, codecs.StreamWriter): pass + class StreamReader(Codec, codecs.StreamReader): pass + def getregentry(): + # type: () -> codecs.CodecInfo + # Compatibility as a search_function for codecs.register() return codecs.CodecInfo( name='idna', - encode=Codec().encode, - decode=Codec().decode, + encode=Codec().encode, # type: ignore + decode=Codec().decode, # type: ignore incrementalencoder=IncrementalEncoder, incrementaldecoder=IncrementalDecoder, streamwriter=StreamWriter, diff --git a/idna/codec.pyi b/idna/codec.pyi deleted file mode 100644 index 3726afc..0000000 --- a/idna/codec.pyi +++ /dev/null @@ -1,27 +0,0 @@ -import codecs -from typing import Tuple - -class Codec(codecs.Codec): - def encode(self, data: str, errors: str = ...) -> Tuple[bytes, int]: ... - def decode(self, data: bytes, errors: str = ...) -> Tuple[str, int]: ... - -class IncrementalEncoder(codecs.BufferedIncrementalEncoder): - def _buffer_encode( # type: ignore - self, - data: str, - errors: str, - final: bool - ) -> Tuple[str, int]: ... - -class IncrementalDecoder(codecs.BufferedIncrementalDecoder): - def _buffer_decode( # type: ignore - self, - data: str, - errors: str, - final: bool - ) -> Tuple[str, int]: ... - -class StreamWriter(Codec, codecs.StreamWriter): ... -class StreamReader(Codec, codecs.StreamReader): ... - -def getregentry() -> codecs.CodecInfo: ... diff --git a/idna/compat.py b/idna/compat.py index 2e622d6..dc896c7 100644 --- a/idna/compat.py +++ b/idna/compat.py @@ -1,12 +1,16 @@ from .core import * from .codec import * +from typing import Any, Union def ToASCII(label): + # type: (str) -> bytes return encode(label) def ToUnicode(label): + # type: (Union[bytes, bytearray]) -> str return decode(label) def nameprep(s): + # type: (Any) -> None raise NotImplementedError('IDNA 2008 does not utilise nameprep protocol') diff --git a/idna/compat.pyi b/idna/compat.pyi deleted file mode 100644 index 44677a6..0000000 --- a/idna/compat.pyi +++ /dev/null @@ -1,5 +0,0 @@ -from typing import Any - -def ToASCII(label: str) -> bytes: ... -def ToUnicode(label: bytes) -> str: ... -def nameprep(s: Any) -> None: ... diff --git a/idna/core.py b/idna/core.py index 2c193d6..d605129 100644 --- a/idna/core.py +++ b/idna/core.py @@ -2,7 +2,7 @@ import bisect import unicodedata import re -import sys +from typing import Union, Optional from .intranges import intranges_contain _virama_combining_class = 9 @@ -30,6 +30,7 @@ class InvalidCodepointContext(IDNAError): def _combining_class(cp): + # type: (int) -> int v = unicodedata.combining(chr(cp)) if v == 0: if not unicodedata.name(chr(cp)): @@ -37,31 +38,34 @@ def _combining_class(cp): return v def _is_script(cp, script): + # type: (str, str) -> bool return intranges_contain(ord(cp), idnadata.scripts[script]) def _punycode(s): + # type: (str) -> bytes return s.encode('punycode') def _unot(s): + # type: (int) -> str return 'U+{:04X}'.format(s) def valid_label_length(label): - + # type: (Union[bytes, str]) -> bool if len(label) > 63: return False return True def valid_string_length(label, trailing_dot): - + # type: (Union[bytes, str], bool) -> bool if len(label) > (254 if trailing_dot else 253): return False return True def check_bidi(label, check_ltr=False): - + # type: (str, bool) -> bool # Bidi rules should only be applied if string contains RTL characters bidi_label = False for (idx, cp) in enumerate(label, 1): @@ -84,7 +88,7 @@ def check_bidi(label, check_ltr=False): raise IDNABidiError('First codepoint in label {} must be directionality L, R or AL'.format(repr(label))) valid_ending = False - number_type = False + number_type = None # type: Optional[str] for (idx, cp) in enumerate(label, 1): direction = unicodedata.bidirectional(cp) @@ -121,14 +125,14 @@ def check_bidi(label, check_ltr=False): def check_initial_combiner(label): - + # type: (str) -> bool if unicodedata.category(label[0])[0] == 'M': raise IDNAError('Label begins with an illegal combining character') return True def check_hyphen_ok(label): - + # type: (str) -> bool if label[2:4] == '--': raise IDNAError('Label has disallowed hyphens in 3rd and 4th position') if label[0] == '-' or label[-1] == '-': @@ -137,13 +141,13 @@ def check_hyphen_ok(label): def check_nfc(label): - + # type: (str) -> None if unicodedata.normalize('NFC', label) != label: raise IDNAError('Label must be in Normalization Form C') def valid_contextj(label, pos): - + # type: (str, int) -> bool cp_value = ord(label[pos]) if cp_value == 0x200c: @@ -187,7 +191,7 @@ def valid_contextj(label, pos): def valid_contexto(label, pos, exception=False): - + # type: (str, int, bool) -> bool cp_value = ord(label[pos]) if cp_value == 0x00b7: @@ -226,9 +230,11 @@ def valid_contexto(label, pos, exception=False): return False return True + return False -def check_label(label): +def check_label(label): + # type: (Union[str, bytes, bytearray]) -> None if isinstance(label, (bytes, bytearray)): label = label.decode('utf-8') if len(label) == 0: @@ -260,13 +266,13 @@ def check_label(label): def alabel(label): - + # type: (str) -> bytes try: - label = label.encode('ascii') - ulabel(label) - if not valid_label_length(label): + label_bytes = label.encode('ascii') + ulabel(label_bytes) + if not valid_label_length(label_bytes): raise IDNAError('Label too long') - return label + return label_bytes except UnicodeEncodeError: pass @@ -275,51 +281,57 @@ def alabel(label): label = str(label) check_label(label) - label = _punycode(label) - label = _alabel_prefix + label + label_bytes = _punycode(label) + label_bytes = _alabel_prefix + label_bytes - if not valid_label_length(label): + if not valid_label_length(label_bytes): raise IDNAError('Label too long') - return label + return label_bytes def ulabel(label): - + # type: (Union[str, bytes, bytearray]) -> str if not isinstance(label, (bytes, bytearray)): try: - label = label.encode('ascii') + label_bytes = label.encode('ascii') except UnicodeEncodeError: check_label(label) return label + else: + label_bytes = label - label = label.lower() - if label.startswith(_alabel_prefix): - label = label[len(_alabel_prefix):] - if not label: + label_bytes = label_bytes.lower() + if label_bytes.startswith(_alabel_prefix): + label_bytes = label_bytes[len(_alabel_prefix):] + if not label_bytes: raise IDNAError('Malformed A-label, no Punycode eligible content found') - if label.decode('ascii')[-1] == '-': + if label_bytes.decode('ascii')[-1] == '-': raise IDNAError('A-label must not end with a hyphen') else: - check_label(label) - return label.decode('ascii') + check_label(label_bytes) + return label_bytes.decode('ascii') - label = label.decode('punycode') + label = label_bytes.decode('punycode') check_label(label) return label def uts46_remap(domain, std3_rules=True, transitional=False): + # type: (str, bool, bool) -> str """Re-map the characters in the string according to UTS46 processing.""" from .uts46data import uts46data output = '' - try: - for pos, char in enumerate(domain): - code_point = ord(char) + + for pos, char in enumerate(domain): + code_point = ord(char) + try: uts46row = uts46data[code_point if code_point < 256 else bisect.bisect_left(uts46data, (code_point, 'Z')) - 1] status = uts46row[1] - replacement = uts46row[2] if len(uts46row) == 3 else None + replacement = None # type: Optional[str] + if len(uts46row) == 3: + replacement = uts46row[2] # type: ignore if (status == 'V' or (status == 'D' and not transitional) or (status == '3' and not std3_rules and replacement is None)): @@ -330,15 +342,16 @@ def uts46_remap(domain, std3_rules=True, transitional=False): output += replacement elif status != 'I': raise IndexError() - return unicodedata.normalize('NFC', output) - except IndexError: - raise InvalidCodepoint( - 'Codepoint {} not allowed at position {} in {}'.format( - _unot(code_point), pos + 1, repr(domain))) + except IndexError: + raise InvalidCodepoint( + 'Codepoint {} not allowed at position {} in {}'.format( + _unot(code_point), pos + 1, repr(domain))) + return unicodedata.normalize('NFC', output) -def encode(s, strict=False, uts46=False, std3_rules=False, transitional=False): +def encode(s, strict=False, uts46=False, std3_rules=False, transitional=False): + # type: (Union[str, bytes, bytearray], bool, bool, bool, bool) -> bytes if isinstance(s, (bytes, bytearray)): s = s.decode('ascii') if uts46: @@ -369,7 +382,7 @@ def encode(s, strict=False, uts46=False, std3_rules=False, transitional=False): def decode(s, strict=False, uts46=False, std3_rules=False): - + # type: (Union[str, bytes, bytearray], bool, bool, bool) -> str if isinstance(s, (bytes, bytearray)): s = s.decode('ascii') if uts46: diff --git a/idna/core.pyi b/idna/core.pyi deleted file mode 100644 index 5b8a4ac..0000000 --- a/idna/core.pyi +++ /dev/null @@ -1,39 +0,0 @@ -from typing import Union -from .intranges import intranges_contain as intranges_contain # noqa - -class IDNAError(UnicodeError): ... -class IDNABidiError(IDNAError): ... -class InvalidCodepoint(IDNAError): ... -class InvalidCodepointContext(IDNAError): ... - -def _combining_class(cp: int) -> int: ... -def _is_script(cp: str, script: str) -> bool: ... -def _punycode(s: str) -> bytes: ... -def _unot(s: int) -> str: ... -def valid_label_length(label: Union[str, bytes]) -> bool: ... -def valid_string_length(label: Union[str, bytes], trailing_dot: bool) -> bool: ... -def check_bidi(label: str, check_ltr: bool = ...) -> bool: ... -def check_initial_combiner(label: str) -> bool: ... -def check_hyphen_ok(label: str) -> bool: ... -def check_nfc(label: str) -> None: ... -def valid_contextj(label: str, pos: int) -> bool: ... -def valid_contexto(label: str, pos: int, exception: bool = False) -> bool: ... -def check_label(label: Union[str, bytes, bytearray]) -> None: ... -def alabel(label: str) -> bytes: ... -def ulabel(label: Union[str, bytes, bytearray]) -> str: ... -def uts46_remap( - domain: str, std3_rules: bool = ..., transitional: bool = ... -) -> str: ... -def encode( - s: Union[str, bytes, bytearray], - strict: bool = False, - uts46: bool = False, - std3_rules: bool = False, - transitional: bool = False, -) -> bytes: ... -def decode( - s: Union[str, bytes, bytearray], - strict: bool = ..., - uts46: bool = ..., - std3_rules: bool = ..., -) -> str: ... diff --git a/idna/idnadata.pyi b/idna/idnadata.pyi deleted file mode 100644 index 691249f..0000000 --- a/idna/idnadata.pyi +++ /dev/null @@ -1,6 +0,0 @@ -from typing import Dict, Tuple - -__version__: str -scripts: Dict[str, Tuple[int, ...]] -joining_types: Dict[int, int] -codepoint_classes: Dict[str, Tuple[int, ...]] diff --git a/idna/intranges.py b/idna/intranges.py index fa8a735..ee364a9 100644 --- a/idna/intranges.py +++ b/idna/intranges.py @@ -6,8 +6,10 @@ """ import bisect +from typing import List, Tuple def intranges_from_list(list_): + # type: (List[int]) -> Tuple[int, ...] """Represent a list of integers as a sequence of ranges: ((start_0, end_0), (start_1, end_1), ...), such that the original integers are exactly those x such that start_i <= x < end_i for some i. @@ -29,13 +31,16 @@ def intranges_from_list(list_): return tuple(ranges) def _encode_range(start, end): + # type: (int, int) -> int return (start << 32) | end def _decode_range(r): + # type: (int) -> Tuple[int, int] return (r >> 32), (r & ((1 << 32) - 1)) def intranges_contain(int_, ranges): + # type: (int, Tuple[int, ...]) -> bool """Determine if `int_` falls into one of the ranges in `ranges`.""" tuple_ = _encode_range(int_, 0) pos = bisect.bisect_left(ranges, tuple_) diff --git a/idna/intranges.pyi b/idna/intranges.pyi deleted file mode 100644 index cde4c23..0000000 --- a/idna/intranges.pyi +++ /dev/null @@ -1,6 +0,0 @@ -from typing import List, Tuple - -def intranges_from_list(list_: List[int]) -> Tuple[int, ...]: ... -def _encode_range(start: int, end: int) -> int: ... -def _decode_range(r: int) -> Tuple[int, int]: ... -def intranges_contain(int_: int, ranges: Tuple[int, ...]) -> bool: ... diff --git a/idna/package_data.pyi b/idna/package_data.pyi deleted file mode 100644 index bda5b5a..0000000 --- a/idna/package_data.pyi +++ /dev/null @@ -1 +0,0 @@ -__version__: str diff --git a/idna/uts46data.py b/idna/uts46data.py index 8ae36cb..f382ce3 100644 --- a/idna/uts46data.py +++ b/idna/uts46data.py @@ -1,10 +1,13 @@ # This file is automatically generated by tools/idna-data +from typing import List, Tuple, Union + """IDNA Mapping Table from UTS46.""" __version__ = '13.0.0' def _seg_0(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x0, '3'), (0x1, '3'), @@ -109,6 +112,7 @@ def _seg_0(): ] def _seg_1(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x64, 'V'), (0x65, 'V'), @@ -213,6 +217,7 @@ def _seg_1(): ] def _seg_2(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0xC8, 'M', 'è'), (0xC9, 'M', 'é'), @@ -317,6 +322,7 @@ def _seg_2(): ] def _seg_3(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x12C, 'M', 'ĭ'), (0x12D, 'V'), @@ -421,6 +427,7 @@ def _seg_3(): ] def _seg_4(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x194, 'M', 'ɣ'), (0x195, 'V'), @@ -525,6 +532,7 @@ def _seg_4(): ] def _seg_5(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x20D, 'V'), (0x20E, 'M', 'ȏ'), @@ -629,6 +637,7 @@ def _seg_5(): ] def _seg_6(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x378, 'X'), (0x37A, '3', ' ι'), @@ -733,6 +742,7 @@ def _seg_6(): ] def _seg_7(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x403, 'M', 'ѓ'), (0x404, 'M', 'є'), @@ -837,6 +847,7 @@ def _seg_7(): ] def _seg_8(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x49E, 'M', 'ҟ'), (0x49F, 'V'), @@ -941,6 +952,7 @@ def _seg_8(): ] def _seg_9(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x503, 'V'), (0x504, 'M', 'ԅ'), @@ -1045,6 +1057,7 @@ def _seg_9(): ] def _seg_10(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x675, 'M', 'اٴ'), (0x676, 'M', 'وٴ'), @@ -1149,6 +1162,7 @@ def _seg_10(): ] def _seg_11(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0xA5C, 'V'), (0xA5D, 'X'), @@ -1253,6 +1267,7 @@ def _seg_11(): ] def _seg_12(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0xC29, 'X'), (0xC2A, 'V'), @@ -1357,6 +1372,7 @@ def _seg_12(): ] def _seg_13(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0xEBE, 'X'), (0xEC0, 'V'), @@ -1461,6 +1477,7 @@ def _seg_13(): ] def _seg_14(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x1316, 'X'), (0x1318, 'V'), @@ -1565,6 +1582,7 @@ def _seg_14(): ] def _seg_15(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x1C80, 'M', 'в'), (0x1C81, 'M', 'д'), @@ -1669,6 +1687,7 @@ def _seg_15(): ] def _seg_16(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x1D53, 'M', 'ɔ'), (0x1D54, 'M', 'ᴖ'), @@ -1773,6 +1792,7 @@ def _seg_16(): ] def _seg_17(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x1E21, 'V'), (0x1E22, 'M', 'ḣ'), @@ -1877,6 +1897,7 @@ def _seg_17(): ] def _seg_18(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x1E85, 'V'), (0x1E86, 'M', 'ẇ'), @@ -1981,6 +2002,7 @@ def _seg_18(): ] def _seg_19(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x1EEE, 'M', 'ữ'), (0x1EEF, 'V'), @@ -2085,6 +2107,7 @@ def _seg_19(): ] def _seg_20(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x1F85, 'M', 'ἅι'), (0x1F86, 'M', 'ἆι'), @@ -2189,6 +2212,7 @@ def _seg_20(): ] def _seg_21(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x1FF4, 'M', 'ώι'), (0x1FF5, 'X'), @@ -2293,6 +2317,7 @@ def _seg_21(): ] def _seg_22(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x2102, 'M', 'c'), (0x2103, 'M', '°c'), @@ -2397,6 +2422,7 @@ def _seg_22(): ] def _seg_23(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x217A, 'M', 'xi'), (0x217B, 'M', 'xii'), @@ -2501,6 +2527,7 @@ def _seg_23(): ] def _seg_24(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x24BA, 'M', 'e'), (0x24BB, 'M', 'f'), @@ -2605,6 +2632,7 @@ def _seg_24(): ] def _seg_25(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x2C26, 'M', 'ⱖ'), (0x2C27, 'M', 'ⱗ'), @@ -2709,6 +2737,7 @@ def _seg_25(): ] def _seg_26(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x2CBF, 'V'), (0x2CC0, 'M', 'ⳁ'), @@ -2813,6 +2842,7 @@ def _seg_26(): ] def _seg_27(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x2F12, 'M', '力'), (0x2F13, 'M', '勹'), @@ -2917,6 +2947,7 @@ def _seg_27(): ] def _seg_28(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x2F76, 'M', '米'), (0x2F77, 'M', '糸'), @@ -3021,6 +3052,7 @@ def _seg_28(): ] def _seg_29(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x3003, 'V'), (0x3036, 'M', '〒'), @@ -3125,6 +3157,7 @@ def _seg_29(): ] def _seg_30(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x3181, 'M', 'ᅌ'), (0x3182, 'M', 'ᇱ'), @@ -3229,6 +3262,7 @@ def _seg_30(): ] def _seg_31(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x3243, '3', '(至)'), (0x3244, 'M', '問'), @@ -3333,6 +3367,7 @@ def _seg_31(): ] def _seg_32(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x32AE, 'M', '資'), (0x32AF, 'M', '協'), @@ -3437,6 +3472,7 @@ def _seg_32(): ] def _seg_33(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x3312, 'M', 'キュリー'), (0x3313, 'M', 'ギルダー'), @@ -3541,6 +3577,7 @@ def _seg_33(): ] def _seg_34(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x3376, 'M', 'pc'), (0x3377, 'M', 'dm'), @@ -3645,6 +3682,7 @@ def _seg_34(): ] def _seg_35(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x33DA, 'M', 'pr'), (0x33DB, 'M', 'sr'), @@ -3749,6 +3787,7 @@ def _seg_35(): ] def _seg_36(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0xA688, 'M', 'ꚉ'), (0xA689, 'V'), @@ -3853,6 +3892,7 @@ def _seg_36(): ] def _seg_37(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0xA76F, 'V'), (0xA770, 'M', 'ꝯ'), @@ -3957,6 +3997,7 @@ def _seg_37(): ] def _seg_38(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0xA9DA, 'X'), (0xA9DE, 'V'), @@ -4061,6 +4102,7 @@ def _seg_38(): ] def _seg_39(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0xABB4, 'M', 'Ꮴ'), (0xABB5, 'M', 'Ꮵ'), @@ -4165,6 +4207,7 @@ def _seg_39(): ] def _seg_40(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0xF94F, 'M', '累'), (0xF950, 'M', '縷'), @@ -4269,6 +4312,7 @@ def _seg_40(): ] def _seg_41(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0xF9B3, 'M', '靈'), (0xF9B4, 'M', '領'), @@ -4373,6 +4417,7 @@ def _seg_41(): ] def _seg_42(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0xFA19, 'M', '神'), (0xFA1A, 'M', '祥'), @@ -4477,6 +4522,7 @@ def _seg_42(): ] def _seg_43(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0xFA82, 'M', '廒'), (0xFA83, 'M', '廙'), @@ -4581,6 +4627,7 @@ def _seg_43(): ] def _seg_44(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0xFB17, 'M', 'մխ'), (0xFB18, 'X'), @@ -4685,6 +4732,7 @@ def _seg_44(): ] def _seg_45(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0xFBF4, 'M', 'ئۈ'), (0xFBF6, 'M', 'ئې'), @@ -4789,6 +4837,7 @@ def _seg_45(): ] def _seg_46(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0xFC60, '3', ' َّ'), (0xFC61, '3', ' ُّ'), @@ -4893,6 +4942,7 @@ def _seg_46(): ] def _seg_47(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0xFCC4, 'M', 'كج'), (0xFCC5, 'M', 'كح'), @@ -4997,6 +5047,7 @@ def _seg_47(): ] def _seg_48(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0xFD28, 'M', 'شم'), (0xFD29, 'M', 'شر'), @@ -5101,6 +5152,7 @@ def _seg_48(): ] def _seg_49(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0xFDAF, 'M', 'يجي'), (0xFDB0, 'M', 'يمي'), @@ -5205,6 +5257,7 @@ def _seg_49(): ] def _seg_50(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0xFE67, 'X'), (0xFE68, '3', '\\'), @@ -5309,6 +5362,7 @@ def _seg_50(): ] def _seg_51(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0xFF24, 'M', 'd'), (0xFF25, 'M', 'e'), @@ -5413,6 +5467,7 @@ def _seg_51(): ] def _seg_52(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0xFF88, 'M', 'ネ'), (0xFF89, 'M', 'ノ'), @@ -5517,6 +5572,7 @@ def _seg_52(): ] def _seg_53(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x10027, 'X'), (0x10028, 'V'), @@ -5621,6 +5677,7 @@ def _seg_53(): ] def _seg_54(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x104BF, 'M', '𐓧'), (0x104C0, 'M', '𐓨'), @@ -5725,6 +5782,7 @@ def _seg_54(): ] def _seg_55(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x10C00, 'V'), (0x10C49, 'X'), @@ -5829,6 +5887,7 @@ def _seg_55(): ] def _seg_56(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x11213, 'V'), (0x1123F, 'X'), @@ -5933,6 +5992,7 @@ def _seg_56(): ] def _seg_57(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x118B8, 'M', '𑣘'), (0x118B9, 'M', '𑣙'), @@ -6037,6 +6097,7 @@ def _seg_57(): ] def _seg_58(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x16A60, 'V'), (0x16A6A, 'X'), @@ -6141,6 +6202,7 @@ def _seg_58(): ] def _seg_59(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x1D173, 'X'), (0x1D17B, 'V'), @@ -6245,6 +6307,7 @@ def _seg_59(): ] def _seg_60(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x1D452, 'M', 'e'), (0x1D453, 'M', 'f'), @@ -6349,6 +6412,7 @@ def _seg_60(): ] def _seg_61(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x1D4B9, 'M', 'd'), (0x1D4BA, 'X'), @@ -6453,6 +6517,7 @@ def _seg_61(): ] def _seg_62(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x1D51E, 'M', 'a'), (0x1D51F, 'M', 'b'), @@ -6557,6 +6622,7 @@ def _seg_62(): ] def _seg_63(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x1D584, 'M', 'y'), (0x1D585, 'M', 'z'), @@ -6661,6 +6727,7 @@ def _seg_63(): ] def _seg_64(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x1D5E8, 'M', 'u'), (0x1D5E9, 'M', 'v'), @@ -6765,6 +6832,7 @@ def _seg_64(): ] def _seg_65(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x1D64C, 'M', 'q'), (0x1D64D, 'M', 'r'), @@ -6869,6 +6937,7 @@ def _seg_65(): ] def _seg_66(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x1D6B1, 'M', 'κ'), (0x1D6B2, 'M', 'λ'), @@ -6973,6 +7042,7 @@ def _seg_66(): ] def _seg_67(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x1D717, 'M', 'θ'), (0x1D718, 'M', 'κ'), @@ -7077,6 +7147,7 @@ def _seg_67(): ] def _seg_68(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x1D77C, 'M', 'ν'), (0x1D77D, 'M', 'ξ'), @@ -7181,6 +7252,7 @@ def _seg_68(): ] def _seg_69(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x1D7E4, 'M', '2'), (0x1D7E5, 'M', '3'), @@ -7285,6 +7357,7 @@ def _seg_69(): ] def _seg_70(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x1EC71, 'V'), (0x1ECB5, 'X'), @@ -7389,6 +7462,7 @@ def _seg_70(): ] def _seg_71(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x1EE6B, 'X'), (0x1EE6C, 'M', 'م'), @@ -7493,6 +7567,7 @@ def _seg_71(): ] def _seg_72(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x1F109, '3', '8,'), (0x1F10A, '3', '9,'), @@ -7597,6 +7672,7 @@ def _seg_72(): ] def _seg_73(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x1F224, 'M', '声'), (0x1F225, 'M', '吹'), @@ -7701,6 +7777,7 @@ def _seg_73(): ] def _seg_74(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x1FBFA, 'X'), (0x20000, 'V'), @@ -7805,6 +7882,7 @@ def _seg_74(): ] def _seg_75(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x2F85C, 'M', '夆'), (0x2F85D, 'M', '多'), @@ -7909,6 +7987,7 @@ def _seg_75(): ] def _seg_76(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x2F8C3, 'M', '摩'), (0x2F8C4, 'M', '摾'), @@ -8013,6 +8092,7 @@ def _seg_76(): ] def _seg_77(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x2F927, 'M', '𤠔'), (0x2F928, 'M', '獺'), @@ -8117,6 +8197,7 @@ def _seg_77(): ] def _seg_78(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x2F98E, 'M', '䑫'), (0x2F98F, 'M', '芑'), @@ -8221,6 +8302,7 @@ def _seg_78(): ] def _seg_79(): + # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x2F9F2, 'M', '䧦'), (0x2F9F3, 'M', '雃'), @@ -8353,4 +8435,4 @@ def _seg_79(): + _seg_77() + _seg_78() + _seg_79() -) +) # type: Tuple[Union[Tuple[int, str], Tuple[int, str, str]], ...] diff --git a/idna/uts46data.pyi b/idna/uts46data.pyi deleted file mode 100644 index 5937034..0000000 --- a/idna/uts46data.pyi +++ /dev/null @@ -1,4 +0,0 @@ -from typing import Tuple, Union - -__version__: str -uts46data: Tuple[Union[Tuple[int, str], Tuple[int, str, str]], ...] diff --git a/setup.py b/setup.py index d4c95ba..3ea5678 100644 --- a/setup.py +++ b/setup.py @@ -22,7 +22,7 @@ def main(): arguments = { 'name': 'idna', 'packages': ['idna'], - 'package_data': {'idna': ['py.typed', '*.pyi']}, + 'package_data': {'idna': ['py.typed']}, 'include_package_data': True, 'version': package_data['__version__'], 'description': 'Internationalized Domain Names in Applications (IDNA)', @@ -51,7 +51,7 @@ def main(): 'Topic :: Software Development :: Libraries :: Python Modules', 'Topic :: Utilities', ], - 'python_requires': '>=3.4', + 'python_requires': '>=3.5', 'test_suite': 'tests', } diff --git a/tools/idna-data b/tools/idna-data index 00c0f4e..dae8901 100755 --- a/tools/idna-data +++ b/tools/idna-data @@ -575,6 +575,7 @@ def uts46_libdata(ucdata): yield '# This file is automatically generated by tools/idna-data' yield '# vim: set fileencoding=utf-8 :\n' + yield 'from typing import List, Tuple, Union\n\n' yield '"""IDNA Mapping Table from UTS46."""\n\n' yield '__version__ = \'{}\''.format(ucdata.version) @@ -585,7 +586,7 @@ def uts46_libdata(ucdata): if idx % UTS46_SEGMENT_SIZE == 0: if idx != 0: yield ' ]\n' - yield 'def _seg_{}():\n return ['.format(idx // UTS46_SEGMENT_SIZE) + yield 'def _seg_{}():\n # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]]\n return ['.format(idx // UTS46_SEGMENT_SIZE) yield ' {},'.format(row) yield ' ]\n' @@ -593,7 +594,7 @@ def uts46_libdata(ucdata): yield ' _seg_0()' for i in range(1, idx // UTS46_SEGMENT_SIZE + 1): yield ' + _seg_{}()'.format(i) - yield ')' + yield ') # type: Tuple[Union[Tuple[int, str], Tuple[int, str, str]], ...]' def make_libdata(args, ucdata):