2121__author__ = "Orsiris de Jong"
2222__copyright__ = "Copyright (C) 2015-2025 Orsiris de Jong for NetInvent"
2323__licence__ = "BSD 3 Clause"
24- __version__ = "1.7.2 "
25- __build__ = "2025031001 "
24+ __version__ = "1.8.0-dev "
25+ __build__ = "2025031301 "
2626__compat__ = "python2.7+"
2727
2828import io
3838# Avoid checking os type numerous times
3939os_name = os .name
4040
41+
42+ # Don't bother with an ImportError since we need command_runner to work without dependencies
4143try :
4244 import psutil
43- except ImportError :
44- # Don't bother with an error since we need command_runner to work without dependencies
45- pass
46- try :
4745 # Also make sure we directly import priority classes so we can reuse them
4846 if os_name == "nt" :
4947 from psutil import (
50- ABOVE_NORMAL_PRIORITY_CLASS ,
51- BELOW_NORMAL_PRIORITY_CLASS ,
48+ # ABOVE_NORMAL_PRIORITY_CLASS,
49+ # BELOW_NORMAL_PRIORITY_CLASS,
5250 HIGH_PRIORITY_CLASS ,
5351 IDLE_PRIORITY_CLASS ,
5452 NORMAL_PRIORITY_CLASS ,
5553 REALTIME_PRIORITY_CLASS ,
5654 )
57- from psutil import IOPRIO_HIGH , IOPRIO_NORMAL , IOPRIO_LOW , IOPRIO_VERYLOW
55+ from psutil import (
56+ IOPRIO_HIGH ,
57+ IOPRIO_NORMAL ,
58+ IOPRIO_LOW ,
59+ )
5860 else :
5961 from psutil import (
6062 IOPRIO_CLASS_BE ,
6163 IOPRIO_CLASS_IDLE ,
62- IOPRIO_CLASS_NONE ,
64+ # IOPRIO_CLASS_NONE,
6365 IOPRIO_CLASS_RT ,
6466 )
6567except (ImportError , AttributeError ):
66- pass
68+ if os_name == "nt" :
69+ BELOW_NORMAL_PRIORITY_CLASS = 16384
70+ HIGH_PRIORITY_CLASS = 128
71+ NORMAL_PRIORITY_CLASS = 32
72+ REALTIME_PRIORITY_CLASS = 256
73+ IDLE_PRIORITY_CLASS = 64
74+ IOPRIO_HIGH = 3
75+ IOPRIO_NORMAL = 2
76+ IOPRIO_LOW = 1
77+ else :
78+ IOPRIO_CLASS_IDLE = 3
79+ IOPRIO_CLASS_BE = 2
80+ IOPRIO_CLASS_RT = 1
81+
82+
83+ # Python 2.7 does not have priorities defined in subprocess module, but psutil has
84+ # Since Windows and Linux use different possible values, let's simplify things by
85+ # allowing 4 process priorities: low, normal, high, rt
86+ # and 3 process io priorities: low, normal, high
87+ # For IO, rt == high
88+ if os_name == "nt" :
89+ PRIORITIES = {
90+ "process" : {
91+ "low" : IDLE_PRIORITY_CLASS ,
92+ "normal" : NORMAL_PRIORITY_CLASS ,
93+ "high" : HIGH_PRIORITY_CLASS ,
94+ "rt" : REALTIME_PRIORITY_CLASS ,
95+ },
96+ "io" : {
97+ "low" : IOPRIO_LOW ,
98+ "normal" : IOPRIO_NORMAL ,
99+ "high" : IOPRIO_HIGH ,
100+ },
101+ }
102+ else :
103+ PRIORITIES = {
104+ "process" : {
105+ "low" : 15 ,
106+ "normal" : 0 ,
107+ "high" : - 15 ,
108+ "rt" : - 20 ,
109+ },
110+ "io" : {
111+ "low" : IOPRIO_CLASS_IDLE ,
112+ "normal" : IOPRIO_CLASS_BE ,
113+ "high" : IOPRIO_CLASS_RT ,
114+ },
115+ }
116+
117+
67118try :
68119 import signal
69120except ImportError :
@@ -263,8 +314,8 @@ def _set_priority(
263314 priority_type , # type: str
264315):
265316 """
266- Set process and / or io priorities
267- Since Windows and Linux use different possible values, let's simplify things by allowing 3 prioriy types
317+ Set process and / or io prioritie
318+ let's simplify things by allowing 3 priority types
268319 """
269320 priority = priority .lower ()
270321
@@ -279,34 +330,15 @@ def _set_priority(
279330 if priority_type == "io" and priority not in ["low" , "normal" , "high" ]:
280331 raise ValueError ("Bogus {} priority given: {}" .format (priority_type , priority ))
281332
282- if os_name == "nt" :
283- priorities = {
284- "process" : {
285- "low" : BELOW_NORMAL_PRIORITY_CLASS ,
286- "normal" : NORMAL_PRIORITY_CLASS ,
287- "high" : HIGH_PRIORITY_CLASS ,
288- },
289- "io" : {"low" : IOPRIO_LOW , "normal" : IOPRIO_NORMAL , "high" : IOPRIO_HIGH },
290- }
291- else :
292- priorities = {
293- "process" : {"low" : 15 , "normal" : 0 , "high" : - 15 },
294- "io" : {
295- "low" : IOPRIO_CLASS_IDLE ,
296- "normal" : IOPRIO_CLASS_BE ,
297- "high" : IOPRIO_CLASS_RT ,
298- },
299- }
300-
301333 if priority_type == "process" :
302334 # Allow direct priority nice settings under linux
303335 if isinstance (priority , int ):
304336 _priority = priority
305337 else :
306- _priority = priorities [priority_type ][priority ]
338+ _priority = PRIORITIES [priority_type ][priority ]
307339 psutil .Process (pid ).nice (_priority )
308340 elif priority_type == "io" :
309- psutil .Process (pid ).ionice (priorities [priority_type ][priority ])
341+ psutil .Process (pid ).ionice (PRIORITIES [priority_type ][priority ])
310342 else :
311343 raise ValueError ("Bogus priority type given." )
312344
@@ -961,9 +993,22 @@ def _monitor_process(
961993
962994 # Python >= 3.3 has SubProcessError(TimeoutExpired) class
963995 # Python >= 3.6 has encoding & error arguments
996+ # Python >= 3.7 has creationflags argument
964997 # universal_newlines=True makes netstat command fail under windows
965998 # timeout does not work under Python 2.7 with subprocess32 < 3.5
966999 # decoder may be cp437 or unicode_escape for dos commands or utf-8 for powershell
1000+
1001+ process_prio = 0
1002+ if priority :
1003+ if isinstance (priority , int ) and os_name != "nt" and - 20 <= priority <= 20 :
1004+ raise ValueError ("Bogus process priority int given: {}" .format (priority ))
1005+ else :
1006+ process_prio = PRIORITIES ["process" ][priority .lower ()]
1007+ if os_name == "nt" and sys .version_info >= (3 , 7 ):
1008+ kwargs ["creationflags" ] = kwargs .pop ("creationflags" , 0 ) | process_prio
1009+ else :
1010+ kwargs ["preexec_fn" ] = lambda : os .nice (process_prio )
1011+
9671012 # Disabling pylint error for the same reason as above
9681013 # pylint: disable=E1123
9691014 if sys .version_info >= (3 , 6 ):
@@ -995,8 +1040,8 @@ def _monitor_process(
9951040 ** kwargs
9961041 )
9971042
998- # Set process priority if given
999- if priority :
1043+ # Set process priority if not set earlier by creationflags or preexec_fn
1044+ if priority and sys . version_info < ( 3 , 7 ) and os_name == "nt" :
10001045 try :
10011046 try :
10021047 set_priority (process .pid , priority )
@@ -1236,3 +1281,6 @@ def deferred_command(command, defer_time=300):
12361281 stderr = None ,
12371282 close_fds = True ,
12381283 )
1284+
1285+
1286+ command_runner ("ping 127.0.0.1 -n 100" , live_output = True , priority = "low" )
0 commit comments