1+ from contextlib import contextmanager
2+ import os
3+ import tempfile
4+ import time
5+
16from SublimeLinter .lint import PythonLinter
27from SublimeLinter .lint .linter import TransientError
38
@@ -22,6 +27,62 @@ class Pydocstyle(PythonLinter):
2227 '--ignore-decorators=' : ''
2328 }
2429
30+ def tmpfile (self , cmd , code , suffix = None ):
31+ filename = (
32+ self .context .get ('file_name' )
33+ or "{}{}" .format (
34+ self .context ['canonical_filename' ][1 :- 1 ],
35+ suffix or self .get_tempfile_suffix ()
36+ )
37+ )
38+ with self ._make_temp_file (filename , code ) as temp_filename :
39+ self .context ['file_on_disk' ] = self .filename
40+ self .context ['temp_file' ] = temp_filename
41+ cmd = self .finalize_cmd (
42+ cmd , self .context , at_value = temp_filename , auto_append = True )
43+ return self ._communicate (cmd )
44+
45+ @contextmanager
46+ def _make_temp_file (self , filename , code ):
47+ folder_prefix = "{}-" .format (self .plugin_name )
48+ with tempfile .TemporaryDirectory (prefix = folder_prefix ) as tmp_dir_name :
49+ temp_filename = os .path .join (tmp_dir_name , filename )
50+ with open (temp_filename , "w+b" ) as file :
51+ file .write (bytes (code , "utf-8" ))
52+
53+ try :
54+ yield temp_filename
55+ finally :
56+ self ._retry (
57+ 3 ,
58+ "removing '{}'" .format (temp_filename ),
59+ lambda : os .unlink (temp_filename )
60+ )
61+
62+ def _retry (self , times , tag , fn ):
63+ for i in range (times ):
64+ try :
65+ fn ()
66+ except Exception :
67+ if i < times - 1 :
68+ self .logger .info (
69+ "{} failed: "
70+ "will retry after sleeping for {} second(s)"
71+ .format (tag , 2 ** i )
72+ )
73+ time .sleep (2 ** i )
74+ else :
75+ self .logger .warning ("{} failed" .format (tag ))
76+ raise
77+ else :
78+ if i > 0 :
79+ self .logger .info ("{} succeeded after {} retry" .format (tag , i ))
80+ break
81+
82+ @property
83+ def plugin_name (self ):
84+ return self .__class__ .__module__ .split ("." , 1 )[0 ]
85+
2586 def on_stderr (self , stderr ):
2687 # For a doc style tester, parse errors can be treated 'transient',
2788 # for the benefit, that we do not re-draw, but keep the errors from
0 commit comments