-
Notifications
You must be signed in to change notification settings - Fork 158
/
Copy pathtest_annotations.py
122 lines (101 loc) · 3.87 KB
/
test_annotations.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import json
import logging
import os
# noinspection PyCompatibility
from dataclasses import dataclass
from io import StringIO
from typing import Any, Dict, List, NewType, Optional, Tuple, Union
from mypy.main import main as mypy_main
import pytest
from dataclasses_json import DataClassJsonMixin, CatchAll
@dataclass
class User(DataClassJsonMixin):
id: str
name: str = "John"
ca: CatchAll = None
Filename = NewType('Filename', str)
LineNumber = NewType('LineNumber', int)
ErrorLevel = NewType('ErrorLevel', str)
ErrorMessage = NewType('ErrorMessage', str)
class TestAnnotations:
u: User = User('ax9ssFxH')
j: str = u.to_json()
u2: User = User.from_json(j)
u2a: User = User.from_json(j.encode())
jMany = [{"id": "115412", "name": "Peter"},
{"id": "atxXxGhg", "name": "Parker"}]
sch = User.schema()
users1: List[User] = sch.loads(json.dumps(jMany), many=True)
n: str = users1[1].name
users2: List[User] = sch.load(jMany, many=True) # type: ignore
u3: User = sch.load(jMany[1])
j2: Dict[str, Any] = sch.dump(u)
j3: List[Dict[str, Any]] = sch.dump([u2, u3], many=True)
j4: str = sch.dumps(u2)
j4_dict: Dict[str, Any] = json.loads(j4)
u4a: User = User.from_json(j4)
u4b: User = User.from_dict(j4_dict)
def filter_errors(self, errors: List[str]) -> List[str]:
real_errors: List[str] = list()
current_file = __file__
current_path = os.path.split(current_file)
for line in errors:
line = line.strip()
if (not line):
continue
fn, lno, lvl, msg = self.parse_trace_line(line)
if (fn is not None):
_path = os.path.split(fn)
if (_path[-1] != current_path[-1]):
continue
real_errors.append(line)
return real_errors
def parse_trace_line(self, line: str) -> \
Tuple[Optional[Filename], Optional[LineNumber], Optional[
ErrorLevel], ErrorMessage]:
# Define variables
file_name: Union[str, Filename, None]
line_no: Union[str, LineNumber, None]
level: Union[str, ErrorLevel, None]
msg: Union[str, ErrorMessage, None]
where, sep, msg = line.partition(': ')
if (sep):
file_name, sep, line_no = where.rpartition(':')
file_name = Filename(file_name)
if (sep):
line_no = LineNumber(int(line_no))
else:
line_no = None
level, sep, msg = msg.partition(': ')
if (sep):
level = ErrorLevel(level)
else:
msg = level
level = None
else:
# Otherwise we get 'Found 1 error in 1 file (checked 1 source file)' as an error
# due to a mypy error in a different file
file_name = Filename("") if line.startswith("Found") else None
line_no = None
level = None
msg = line
msg = ErrorMessage(msg)
return file_name, line_no, level, msg
@pytest.mark.skip(reason="mypy_main signature changed")
def test_type_hints(self):
text_io = StringIO('')
try:
# mypy.main uses sys.stdout for printing
# We override it to catch error messages
mypy_main(args=[__file__], stdout=text_io, stderr=text_io, clean_exit=True)
except SystemExit:
# mypy.main could return errors found inside other files.
# filter_errors() will filter out all errors outside this file.
errors = text_io.getvalue().splitlines()
errors = self.filter_errors(errors)
else:
errors = None
# To prevent large errors raise error out of try/except
if (errors):
logging.error('\n'.join(errors))
raise AssertionError("Type annotations check failed")