forked from python/mypy
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdaemon.test
221 lines (210 loc) · 6.13 KB
/
daemon.test
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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
-- End-to-end test cases for the daemon (dmypy).
-- These are special because they run multiple shell commands.
[case testDaemonStartStop]
$ dmypy start -- --follow-imports=error
Daemon started
$ dmypy stop
Daemon stopped
[case testDaemonBasic]
$ dmypy start -- --follow-imports=error
Daemon started
$ dmypy check -- foo.py
$ dmypy recheck
$ dmypy stop
Daemon stopped
[file foo.py]
def f(): pass
[case testDaemonRun]
$ dmypy run -- foo.py --follow-imports=error
Daemon started
$ dmypy stop
Daemon stopped
[file foo.py]
def f(): pass
[case testDaemonRunRestart]
$ dmypy run -- foo.py --follow-imports=error
Daemon started
$ dmypy run -- foo.py --follow-imports=error
$ {python} -c "print('[mypy]')" >mypy.ini
$ {python} -c "print('disallow_untyped_defs = True')" >>mypy.ini
$ dmypy run -- foo.py --follow-imports=error
Restarting: configuration changed
Daemon stopped
Daemon started
foo.py:1: error: Function is missing a return type annotation
foo.py:1: note: Use "-> None" if function does not return a value
== Return code: 1
$ {python} -c "print('def f() -> None: pass')" >foo.py
$ dmypy run -- foo.py --follow-imports=error
$ dmypy stop
Daemon stopped
[file foo.py]
def f(): pass
[case testDaemonRunRestartPluginVersion]
$ dmypy run -- foo.py
Daemon started
$ {python} -c "print(' ')" >> plug.py
$ dmypy run -- foo.py
Restarting: plugins changed
Daemon stopped
Daemon started
$ dmypy stop
Daemon stopped
[file mypy.ini]
[[mypy]
follow_imports = error
plugins = plug.py
[file foo.py]
pass
[file plug.py]
from mypy.plugin import Plugin
class Dummy(Plugin): pass
def plugin(version): return Dummy
[case testDaemonStatusKillRestartRecheck]
$ dmypy status
No status file found
== Return code: 2
$ dmypy stop
No status file found
== Return code: 2
$ dmypy kill
No status file found
== Return code: 2
$ dmypy recheck
No status file found
== Return code: 2
$ dmypy start -- --follow-imports=error
Daemon started
$ dmypy status
Daemon is up and running
$ dmypy start
Daemon is still alive
== Return code: 2
$ dmypy restart -- --follow-imports=error
Daemon stopped
Daemon started
$ dmypy stop
Daemon stopped
$ dmypy status
No status file found
== Return code: 2
$ dmypy restart -- --follow-imports=error
Daemon started
$ dmypy recheck
Command 'recheck' is only valid after a 'check' command
== Return code: 2
$ dmypy kill
Daemon killed
$ dmypy status
Daemon has died
== Return code: 2
[case testDaemonRecheck]
$ dmypy start -- --follow-imports=error
Daemon started
$ dmypy check foo.py bar.py
$ dmypy recheck
$ dmypy recheck --update foo.py --remove bar.py sir_not_appearing_in_this_film.py
foo.py:1: error: Import of 'bar' ignored
foo.py:1: note: (Using --follow-imports=error, module not passed on command line)
== Return code: 1
$ dmypy recheck --update bar.py
$ dmypy recheck --update sir_not_appearing_in_this_film.py
$ dmypy recheck --update --remove
$ dmypy stop
Daemon stopped
[file foo.py]
import bar
[file bar.py]
pass
[case testDaemonTimeout]
$ dmypy start --timeout 1 -- --follow-imports=error
Daemon started
$ {python} -c "import time;time.sleep(1)"
$ dmypy status
No status file found
== Return code: 2
[case testDaemonRunNoTarget]
$ dmypy run -- --follow-imports=error
Daemon started
mypy-daemon: error: Missing target module, package, files, or command.
== Return code: 2
$ dmypy stop
Daemon stopped
-- this is carefully constructed to be able to break if the quickstart system lets
-- something through incorrectly. in particular, the files need to have the same size
[case testDaemonQuickstart]
$ {python} -c "print('x=1')" >foo.py
$ {python} -c "print('x=1')" >bar.py
$ mypy --local-partial-types --cache-fine-grained --follow-imports=error --no-sqlite-cache --python-version=3.6 -- foo.py bar.py
$ {python} -c "import shutil; shutil.copy('.mypy_cache/3.6/bar.meta.json', 'asdf.json')"
-- update bar's timestamp but don't change the file
$ {python} -c "import time;time.sleep(1)"
$ {python} -c "print('x=1')" >bar.py
$ dmypy run -- foo.py bar.py --follow-imports=error --use-fine-grained-cache --no-sqlite-cache --python-version=3.6
Daemon started
$ dmypy status --fswatcher-dump-file test.json
Daemon is up and running
$ dmypy stop
Daemon stopped
-- copy the original bar cache file back so that the mtime mismatches
$ {python} -c "import shutil; shutil.copy('asdf.json', '.mypy_cache/3.6/bar.meta.json')"
-- sleep guarantees timestamp changes
$ {python} -c "import time;time.sleep(1)"
$ {python} -c "print('lol')" >foo.py
$ dmypy run --log-file=log -- foo.py bar.py --follow-imports=error --use-fine-grained-cache --no-sqlite-cache --python-version=3.6 --quickstart-file test.json
Daemon started
foo.py:1: error: Name 'lol' is not defined
== Return code: 1
-- make sure no errors made it to the log file
$ {python} -c "import sys; sys.stdout.write(open('log').read())"
-- make sure the meta file didn't get updated. we use this as an imperfect proxy for
-- whether the source file got rehashed, which we don't want it to have been.
$ {python} -c "x = open('.mypy_cache/3.6/bar.meta.json').read(); y = open('asdf.json').read(); assert x == y"
[case testDaemonSuggest]
$ dmypy start --log-file log.txt -- --follow-imports=error
Daemon started
$ dmypy suggest foo:foo
Command 'suggest' is only valid after a 'check' command
== Return code: 2
$ dmypy check foo.py bar.py
$ dmypy suggest foo.bar
Unknown function foo.bar
== Return code: 2
$ dmypy suggest foo.var
Object foo.var is not a function
== Return code: 2
$ dmypy suggest foo.Foo.var
Unknown class foo.Foo
== Return code: 2
$ dmypy suggest foo.Bar.baz
Unknown method foo.Bar.baz
== Return code: 2
$ dmypy suggest foo.foo.baz
Object foo.foo is not a class
== Return code: 2
$ dmypy suggest --callsites foo.foo
bar.py:3: (str)
bar.py:4: (arg=str)
$ dmypy suggest foo.foo
(str) -> int
$ {python} -c "import shutil; shutil.copy('foo.py.2', 'foo.py')"
$ dmypy check foo.py bar.py
bar.py:3: error: Incompatible types in assignment (expression has type "int", variable has type "str")
== Return code: 1
[file foo.py]
def foo(arg):
return 12
class Bar:
def bar(self): pass
var = 0
[file foo.py.2]
def foo(arg: str) -> int:
return 12
class Bar:
def bar(self) -> None: pass
var = 0
[file bar.py]
from foo import foo
def bar() -> None:
x = foo('abc') # type: str
foo(arg='xyz')