|
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