Skip to content

Commit 77da8e5

Browse files
committed
docs: adding typing annotations in the whole project
1 parent 2ed91b2 commit 77da8e5

File tree

8 files changed

+85
-79
lines changed

8 files changed

+85
-79
lines changed

language_tool_python/__main__.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@
44
import locale
55
import re
66
import sys
7-
from importlib.metadata import version
7+
from importlib.metadata import version, PackageNotFoundError
88
import toml
9+
from typing import Any, Optional, Set, Union
910

1011
from .server import LanguageTool
1112
from .utils import LanguageToolError
@@ -17,7 +18,7 @@
1718
__version__ = toml.loads(f.read().decode('utf-8'))["project"]["version"]
1819

1920

20-
def parse_args():
21+
def parse_args() -> argparse.Namespace:
2122
parser = argparse.ArgumentParser(
2223
description=__doc__.strip() if __doc__ else None,
2324
prog='language_tool_python')
@@ -69,22 +70,22 @@ def parse_args():
6970

7071

7172
class RulesAction(argparse.Action):
72-
def __call__(self, parser, namespace, values, option_string=None):
73+
def __call__(self, parser: argparse.ArgumentParser, namespace: Any, values: Any, option_string: Optional[str] = None) -> str:
7374
getattr(namespace, self.dest).update(values)
7475

7576

76-
def get_rules(rules: str) -> set:
77+
def get_rules(rules: str) -> Set[str]:
7778
return {rule.upper() for rule in re.findall(r"[\w\-]+", rules)}
7879

7980

80-
def get_text(filename, encoding, ignore):
81+
def get_text(filename: Union[str, int], encoding: Optional[str], ignore: Optional[str]) -> str:
8182
with open(filename, encoding=encoding) as f:
8283
text = ''.join('\n' if (ignore and re.match(ignore, line)) else line
8384
for line in f.readlines())
8485
return text
8586

8687

87-
def main():
88+
def main() -> int:
8889
args = parse_args()
8990

9091
status = 0

language_tool_python/console_mode.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
"""Write to stdout without causing UnicodeEncodeError."""
33

44
import sys
5+
from typing import Any, Tuple
56

67

78
if (getattr(sys.stdout, 'errors', '') == 'strict' and
@@ -21,12 +22,12 @@
2122
0x201d: '"',
2223
}
2324

24-
def simplify(s):
25+
def simplify(s: str) -> str:
2526
s = s.translate(TRANSLIT_MAP)
2627
return ''.join([c for c in unicodedata.normalize('NFKD', s)
2728
if not unicodedata.combining(c)])
2829

29-
def simple_translit_error_handler(error):
30+
def simple_translit_error_handler(error: UnicodeEncodeError) -> Tuple[str, int]:
3031
if not isinstance(error, UnicodeEncodeError):
3132
raise error
3233
chunk = error.object[error.start:error.end]
@@ -40,20 +41,20 @@ class SimpleTranslitStreamFilter:
4041
"""Filter a stream through simple transliteration."""
4142
errors = 'simple_translit'
4243

43-
def __init__(self, target):
44+
def __init__(self, target: Any) -> None:
4445
self.target = target
4546

46-
def __getattr__(self, name):
47+
def __getattr__(self, name: str) -> Any:
4748
return getattr(self.target, name)
4849

49-
def write(self, s):
50+
def write(self, s: str) -> None:
5051
self.target.write(self.downgrade(s))
5152

52-
def writelines(self, lines):
53+
def writelines(self, lines: Any) -> None:
5354
self.target.writelines(
5455
[self.downgrade(line) for line in lines])
5556

56-
def downgrade(self, s):
57+
def downgrade(self, s: str) -> str:
5758
return (s.encode(self.target.encoding, self.errors)
5859
.decode(self.target.encoding))
5960

language_tool_python/download_lt.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
import sys
1111
import tempfile
1212
import tqdm
13-
from typing import Optional
13+
from typing import IO, Dict, Optional, Tuple
1414
import zipfile
1515

1616
from shutil import which
@@ -42,7 +42,7 @@
4242
r'^(?:java|openjdk) [version ]?(?P<major1>\d+)\.(?P<major2>\d+)',
4343
re.MULTILINE)
4444

45-
def parse_java_version(version_text):
45+
def parse_java_version(version_text: str) -> Tuple[int, int]:
4646
"""Return Java version (major1, major2).
4747
4848
>>> parse_java_version('''java version "1.6.0_65"
@@ -70,7 +70,7 @@ def parse_java_version(version_text):
7070
return (major1, major2)
7171

7272

73-
def confirm_java_compatibility():
73+
def confirm_java_compatibility() -> bool:
7474
""" Confirms Java major version >= 8. """
7575
java_path = which('java')
7676
if not java_path:
@@ -97,15 +97,15 @@ def confirm_java_compatibility():
9797
raise SystemError(f'Detected java {major_version}.{minor_version}. LanguageTool requires Java >= 8.')
9898

9999

100-
def get_common_prefix(z):
100+
def get_common_prefix(z: zipfile.ZipFile) -> Optional[str]:
101101
"""Get common directory in a zip file if any."""
102102
name_list = z.namelist()
103103
if name_list and all(n.startswith(name_list[0]) for n in name_list[1:]):
104104
return name_list[0]
105105
return None
106106

107107

108-
def http_get(url, out_file, proxies=None):
108+
def http_get(url: str, out_file: IO[bytes], proxies: Optional[Dict[str, str]] = None) -> None:
109109
""" Get contents of a URL and save to a file.
110110
"""
111111
req = requests.get(url, stream=True, proxies=proxies)
@@ -123,14 +123,14 @@ def http_get(url, out_file, proxies=None):
123123
progress.close()
124124

125125

126-
def unzip_file(temp_file, directory_to_extract_to):
126+
def unzip_file(temp_file: str, directory_to_extract_to: str) -> None:
127127
""" Unzips a .zip file to folder path. """
128128
logger.info(f'Unzipping {temp_file.name} to {directory_to_extract_to}.')
129129
with zipfile.ZipFile(temp_file.name, 'r') as zip_ref:
130130
zip_ref.extractall(directory_to_extract_to)
131131

132132

133-
def download_zip(url, directory):
133+
def download_zip(url: str, directory: str) -> None:
134134
""" Downloads and unzips zip file from `url` to `directory`. """
135135
# Download file.
136136
downloaded_file = tempfile.NamedTemporaryFile(suffix='.zip', delete=False)
@@ -145,7 +145,7 @@ def download_zip(url, directory):
145145
logger.info(f'Downloaded {url} to {directory}.')
146146

147147

148-
def download_lt(language_tool_version: Optional[str] = LTP_DOWNLOAD_VERSION):
148+
def download_lt(language_tool_version: Optional[str] = LTP_DOWNLOAD_VERSION) -> None:
149149
confirm_java_compatibility()
150150

151151
download_folder = get_language_tool_download_path()

language_tool_python/language_tag.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,30 @@
11
import re
2-
2+
from typing import Iterable, Any
33
from functools import total_ordering
44

55
@total_ordering
66
class LanguageTag:
77
"""Language tag supported by LanguageTool."""
88
_LANGUAGE_RE = re.compile(r"^([a-z]{2,3})(?:[_-]([a-z]{2}))?$", re.I)
99

10-
def __init__(self, tag, languages):
10+
def __init__(self, tag: str, languages: Iterable[str]) -> None:
1111
self.tag = tag
1212
self.languages = languages
1313
self.normalized_tag = self._normalize(tag)
1414

15-
def __eq__(self, other_tag):
15+
def __eq__(self, other: Any) -> bool:
1616
return self.normalized_tag == self._normalize(other_tag)
1717

18-
def __lt__(self, other_tag):
18+
def __lt__(self, other: Any) -> bool:
1919
return str(self) < self._normalize(other)
2020

21-
def __str__(self):
21+
def __str__(self) -> str:
2222
return self.normalized_tag
2323

24-
def __repr__(self):
24+
def __repr__(self) -> str:
2525
return f'<LanguageTag "{str(self)}">'
2626

27-
def _normalize(self, tag):
27+
def _normalize(self, tag: str) -> str:
2828
if not tag:
2929
raise ValueError('empty language tag')
3030
languages = {language.lower().replace('-', '_'): language

language_tool_python/match.py

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import unicodedata
22
from collections import OrderedDict
3+
from typing import Any, Dict, Iterator, OrderedDict as OrderedDictType
34
from functools import total_ordering
45

5-
def get_match_ordered_dict():
6+
def get_match_ordered_dict() -> OrderedDictType[str, type]:
67
slots = OrderedDict([
78
('ruleId', str),
89
('message', str),
@@ -32,7 +33,7 @@ def get_match_ordered_dict():
3233
}
3334
3435
"""
35-
def auto_type(obj):
36+
def auto_type(obj: Any) -> Any:
3637
try:
3738
return int(obj)
3839
except ValueError:
@@ -44,7 +45,7 @@ def auto_type(obj):
4445
@total_ordering
4546
class Match:
4647
"""Hold information about where a rule matches text."""
47-
def __init__(self, attrib):
48+
def __init__(self, attrib: Dict[str, Any]) -> None:
4849
# Process rule.
4950
attrib['category'] = attrib['rule']['category']['id']
5051
attrib['ruleId'] = attrib['rule']['id']
@@ -63,8 +64,8 @@ def __init__(self, attrib):
6364
for k, v in attrib.items():
6465
setattr(self, k, v)
6566

66-
def __repr__(self):
67-
def _ordered_dict_repr():
67+
def __repr__(self) -> str:
68+
def _ordered_dict_repr() -> str:
6869
slots = list(get_match_ordered_dict())
6970
slots += list(set(self.__dict__).difference(slots))
7071
attrs = [slot for slot in slots
@@ -73,7 +74,7 @@ def _ordered_dict_repr():
7374

7475
return f'{self.__class__.__name__}({_ordered_dict_repr()})'
7576

76-
def __str__(self):
77+
def __str__(self) -> str:
7778
ruleId = self.ruleId
7879
s = f'Offset {self.offset}, length {self.errorLength}, Rule ID: {ruleId}'
7980
if self.message:
@@ -84,7 +85,7 @@ def __str__(self):
8485
return s
8586

8687
@property
87-
def matchedText(self):
88+
def matchedText(self) -> str:
8889
""" Returns the text that garnered the error (without its surrounding context).
8990
"""
9091
return self.context[self.offsetInContext:self.offsetInContext+self.errorLength]
@@ -98,22 +99,22 @@ def select_replacement(self, index: int) -> None:
9899
raise ValueError(f'This Match\'s suggestions are numbered from 0 to {len(self.replacements) - 1}')
99100
self.replacements = [self.replacements[index]]
100101

101-
def __eq__(self, other):
102+
def __eq__(self, other: Any) -> bool:
102103
return list(self) == list(other)
103104

104-
def __lt__(self, other):
105+
def __lt__(self, other: Any) -> bool:
105106
return list(self) < list(other)
106107

107-
def __iter__(self):
108+
def __iter__(self) -> Iterator[Any]:
108109
return iter(getattr(self, attr) for attr in get_match_ordered_dict())
109110

110-
def __setattr__(self, key, value):
111+
def __setattr__(self, key: str, value: Any) -> None:
111112
try:
112113
value = get_match_ordered_dict()[key](value)
113114
except KeyError:
114115
return
115116
super().__setattr__(key, value)
116117

117-
def __getattr__(self, name):
118+
def __getattr__(self, name: str) -> Any:
118119
if name not in get_match_ordered_dict():
119120
raise AttributeError(f'{self.__class__.__name__!r} object has no attribute {name!r}')

0 commit comments

Comments
 (0)