|
13 | 13 | import subprocess |
14 | 14 | from pathlib import Path |
15 | 15 | import logging |
| 16 | +from mypy import api as mypy_api |
16 | 17 | from pylsp import hookimpl |
17 | 18 | from pylsp.workspace import Document, Workspace |
18 | 19 | from pylsp.config.config import Config |
19 | 20 | from typing import Optional, Dict, Any, IO, List |
20 | 21 | import atexit |
21 | 22 | import collections |
22 | 23 | import warnings |
| 24 | +import shutil |
23 | 25 |
|
24 | 26 | line_pattern: str = r"((?:^[a-z]:)?[^:]+):(?:(\d+):)?(?:(\d+):)? (\w+): (.*)" |
25 | 27 |
|
@@ -189,33 +191,64 @@ def pylsp_lint( |
189 | 191 | if not dmypy: |
190 | 192 | args.extend(["--incremental", "--follow-imports", "silent"]) |
191 | 193 |
|
192 | | - log.info("executing mypy args = %s", args) |
193 | | - completed_process = subprocess.run( |
194 | | - ["mypy", *args], stdout=subprocess.PIPE, stderr=subprocess.PIPE |
195 | | - ) |
196 | | - report = completed_process.stdout.decode() |
197 | | - errors = completed_process.stderr.decode() |
| 194 | + if shutil.which("mypy"): |
| 195 | + # mypy exists on path |
| 196 | + # -> use mypy on path |
| 197 | + log.info("executing mypy args = %s on path", args) |
| 198 | + completed_process = subprocess.run( |
| 199 | + ["mypy", *args], stdout=subprocess.PIPE, stderr=subprocess.PIPE |
| 200 | + ) |
| 201 | + report = completed_process.stdout.decode() |
| 202 | + errors = completed_process.stderr.decode() |
| 203 | + else: |
| 204 | + # mypy does not exist on path, but must exist in the env pylsp-mypy is installed in |
| 205 | + # -> use mypy via api |
| 206 | + log.info("executing mypy args = %s via api", args) |
| 207 | + report, errors, _ = mypy_api.run(args) |
198 | 208 | else: |
199 | 209 | # If dmypy daemon is non-responsive calls to run will block. |
200 | 210 | # Check daemon status, if non-zero daemon is dead or hung. |
201 | 211 | # If daemon is hung, kill will reset |
202 | 212 | # If daemon is dead/absent, kill will no-op. |
203 | 213 | # In either case, reset to fresh state |
204 | | - completed_process = subprocess.run(["dmypy", *args], stderr=subprocess.PIPE) |
205 | | - _err = completed_process.stderr.decode() |
206 | | - _status = completed_process.returncode |
207 | | - if _status != 0: |
208 | | - log.info("restarting dmypy from status: %s message: %s", _status, _err.strip()) |
209 | | - subprocess.run(["dmypy", "kill"]) |
| 214 | + if shutil.which("dmypy"): |
| 215 | + # dmypy exists on path |
| 216 | + # -> use mypy on path |
| 217 | + completed_process = subprocess.run(["dmypy", *args], stderr=subprocess.PIPE) |
| 218 | + _err = completed_process.stderr.decode() |
| 219 | + _status = completed_process.returncode |
| 220 | + if _status != 0: |
| 221 | + log.info( |
| 222 | + "restarting dmypy from status: %s message: %s via path", _status, _err.strip() |
| 223 | + ) |
| 224 | + subprocess.run(["dmypy", "kill"]) |
| 225 | + else: |
| 226 | + # dmypy does not exist on path, but must exist in the env pylsp-mypy is installed in |
| 227 | + # -> use dmypy via api |
| 228 | + _, _err, _status = mypy_api.run_dmypy(["status"]) |
| 229 | + if _status != 0: |
| 230 | + log.info( |
| 231 | + "restarting dmypy from status: %s message: %s via api", _status, _err.strip() |
| 232 | + ) |
| 233 | + mypy_api.run_dmypy(["kill"]) |
210 | 234 |
|
211 | 235 | # run to use existing daemon or restart if required |
212 | 236 | args = ["run", "--"] + args |
213 | | - log.info("dmypy run args = %s", args) |
214 | | - completed_process = subprocess.run( |
215 | | - ["dmypy", *args], stdout=subprocess.PIPE, stderr=subprocess.PIPE |
216 | | - ) |
217 | | - report = completed_process.stdout.decode() |
218 | | - errors = completed_process.stderr.decode() |
| 237 | + |
| 238 | + if shutil.which("dmypy"): |
| 239 | + # dmypy exists on path |
| 240 | + # -> use mypy on path |
| 241 | + log.info("dmypy run args = %s via path", args) |
| 242 | + completed_process = subprocess.run( |
| 243 | + ["dmypy", *args], stdout=subprocess.PIPE, stderr=subprocess.PIPE |
| 244 | + ) |
| 245 | + report = completed_process.stdout.decode() |
| 246 | + errors = completed_process.stderr.decode() |
| 247 | + else: |
| 248 | + # dmypy does not exist on path, but must exist in the env pylsp-mypy is installed in |
| 249 | + # -> use dmypy via api |
| 250 | + log.info("dmypy run args = %s via api", args) |
| 251 | + report, errors, _ = mypy_api.run_dmypy(args) |
219 | 252 |
|
220 | 253 | log.debug("report:\n%s", report) |
221 | 254 | log.debug("errors:\n%s", errors) |
|
0 commit comments