1010import tempfile
1111import os
1212import os .path
13+ from pathlib import Path
1314import logging
1415from mypy import api as mypy_api
1516from pylsp import hookimpl
2425log = logging .getLogger (__name__ )
2526
2627# A mapping from workspace path to config file path
27- mypyConfigFileMap : Dict [str , Optional [str ]] = dict ()
28+ mypyConfigFileMap : Dict [str , Optional [str ]] = {}
2829
2930tmpFile : Optional [IO [str ]] = None
3031
3334# so store a cache of last diagnostics for each file a-la the pylint plugin,
3435# so we can return some potentially-stale diagnostics.
3536# https://github.com/python-lsp/python-lsp-server/blob/v1.0.1/pylsp/plugins/pylint_lint.py#L55-L62
36- last_diagnostics : Dict [str , List ] = collections .defaultdict (list )
37+ last_diagnostics : Dict [str , List [ Dict [ str , Any ]] ] = collections .defaultdict (list )
3738
3839
39- def parse_line (
40- line : str , document : Optional [Document ] = None
41- ) -> Optional [Dict [str , Any ]]:
40+ def parse_line (line : str , document : Optional [Document ] = None ) -> Optional [Dict [str , Any ]]:
4241 """
4342 Return a language-server diagnostic from a line of the Mypy error report.
4443
@@ -66,9 +65,7 @@ def parse_line(
6665 # results from other files can be included, but we cannot return
6766 # them.
6867 if document and document .path and not document .path .endswith (file_path ):
69- log .warning (
70- "discarding result for %s against %s" , file_path , document .path
71- )
68+ log .warning ("discarding result for %s against %s" , file_path , document .path )
7269 return None
7370
7471 lineno = int (linenoStr or 1 ) - 1 # 0-based line number
@@ -91,9 +88,7 @@ def parse_line(
9188 # can make a good guess by highlighting the word that Mypy flagged
9289 word = document .word_at_position (diag ["range" ]["start" ])
9390 if word :
94- diag ["range" ]["end" ]["character" ] = diag ["range" ]["start" ][
95- "character"
96- ] + len (word )
91+ diag ["range" ]["end" ]["character" ] = diag ["range" ]["start" ]["character" ] + len (word )
9792
9893 return diag
9994 return None
@@ -124,6 +119,21 @@ def pylsp_lint(
124119
125120 """
126121 settings = config .plugin_settings ("pylsp_mypy" )
122+ oldSettings1 = config .plugin_settings ("mypy-ls" )
123+ if oldSettings1 != {}:
124+ raise DeprecationWarning (
125+ "Your configuration uses the namespace mypy-ls, this should be changed to pylsp_mypy"
126+ )
127+ oldSettings2 = config .plugin_settings ("mypy_ls" )
128+ if oldSettings2 != {}:
129+ raise DeprecationWarning (
130+ "Your configuration uses the namespace mypy_ls, this should be changed to pylsp_mypy"
131+ )
132+ if settings == {}:
133+ settings = oldSettings1
134+ if settings == {}:
135+ settings = oldSettings2
136+
127137 log .info (
128138 "lint settings = %s document.path = %s is_saved = %s" ,
129139 settings ,
@@ -181,9 +191,7 @@ def pylsp_lint(
181191 # In either case, reset to fresh state
182192 _ , _err , _status = mypy_api .run_dmypy (["status" ])
183193 if _status != 0 :
184- log .info (
185- "restarting dmypy from status: %s message: %s" , _status , _err .strip ()
186- )
194+ log .info ("restarting dmypy from status: %s message: %s" , _status , _err .strip ())
187195 mypy_api .run_dmypy (["kill" ])
188196
189197 # run to use existing daemon or restart if required
@@ -242,19 +250,15 @@ def init(workspace: str) -> Dict[str, str]:
242250 The plugin config dict.
243251
244252 """
245- # On windows the path contains \\ on linux it contains / all the code works with /
246253 log .info ("init workspace = %s" , workspace )
247- workspace = workspace .replace ("\\ " , "/" )
248254
249255 configuration = {}
250- path = findConfigFile (workspace , "pylsp-mypy.cfg" )
256+ path = findConfigFile (workspace , [ "pylsp-mypy.cfg" , "mypy-ls.cfg" , "mypy_ls.cfg" ] )
251257 if path :
252258 with open (path ) as file :
253259 configuration = eval (file .read ())
254260
255- mypyConfigFile = findConfigFile (workspace , "mypy.ini" )
256- if not mypyConfigFile :
257- mypyConfigFile = findConfigFile (workspace , ".mypy.ini" )
261+ mypyConfigFile = findConfigFile (workspace , ["mypy.ini" , ".mypy.ini" ])
258262 mypyConfigFileMap [workspace ] = mypyConfigFile
259263
260264 if ("enabled" not in configuration or configuration ["enabled" ]) and (
@@ -268,7 +272,7 @@ def init(workspace: str) -> Dict[str, str]:
268272 return configuration
269273
270274
271- def findConfigFile (path : str , name : str ) -> Optional [str ]:
275+ def findConfigFile (path : str , names : List [ str ] ) -> Optional [str ]:
272276 """
273277 Search for a config file.
274278
@@ -279,24 +283,28 @@ def findConfigFile(path: str, name: str) -> Optional[str]:
279283 ----------
280284 path : str
281285 The path where the search starts.
282- name : str
283- The file to be found.
286+ names : List[ str]
287+ The file to be found (or alternative names) .
284288
285289 Returns
286290 -------
287291 Optional[str]
288292 The path where the file has been found or None if no matching file has been found.
289293
290294 """
291- while True :
292- p = f"{ path } /{ name } "
293- if os .path .isfile (p ):
294- return p
295- else :
296- loc = path .rfind ("/" )
297- if loc == - 1 :
298- return None
299- path = path [:loc ]
295+ start = Path (path ).joinpath (names [0 ]) # the join causes the parents to include path
296+ for parent in start .parents :
297+ for name in names :
298+ file = parent .joinpath (name )
299+ if file .is_file ():
300+ if file .name in ["mypy-ls.cfg" , "mypy_ls.cfg" ]:
301+ raise DeprecationWarning (
302+ f"{ str (file )} : { file .name } is no longer supported, you should rename your "
303+ "config file to pylsp-mypy.cfg"
304+ )
305+ return str (file )
306+
307+ return None
300308
301309
302310@atexit .register
0 commit comments