Skip to content

Commit f313ba1

Browse files
committed
CP-45360: Make the output from Popen.communicate as strings rather than bytes
By default, all communication in python3 is in bytes and therefor the (stdout, stderr) will be bytes. Signed-off-by: Qin Zhang (张琴) <[email protected]>
1 parent 0c0f1cf commit f313ba1

File tree

1 file changed

+24
-23
lines changed

1 file changed

+24
-23
lines changed

XSConsoleUtils.py

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -49,35 +49,36 @@ def __init__(self, *inParams):
4949
self.stdout = []
5050
self.stderr = []
5151
self.called = False
52-
52+
5353
def _NewPipe(self, *inParams):
5454
if len(inParams) == 1 and isinstance(inParams, (list, tuple)):
5555
params = inParams[0]
5656
else:
5757
params = inParams
58-
58+
5959
self.pipe = subprocess.Popen(params,
6060
stdin=subprocess.PIPE,
6161
stdout=subprocess.PIPE,
6262
stderr=subprocess.PIPE,
63+
text=True,
6364
close_fds=True)
6465
self.called = False
65-
66+
6667
def Stdout(self):
6768
if not self.called:
6869
self.Call()
6970
return self.stdout
70-
71+
7172
def Stderr(self):
7273
if not self.called:
7374
self.Call()
7475
return self.stderr
75-
76+
7677
def AllOutput(self):
7778
if not self.called:
7879
self.Call()
7980
return self.stdout + self.stderr
80-
81+
8182
def Communicate(self, inInput = None):
8283
if self.called:
8384
raise Exception("ShellPipe called more than once")
@@ -88,19 +89,19 @@ def Communicate(self, inInput = None):
8889
stdout, stderr = self.pipe.communicate("\n".join(inInput))
8990
else:
9091
stdout, stderr = self.pipe.communicate(inInput)
91-
92+
9293
self.stdout += stdout.splitlines()
9394
self.stderr += stderr.splitlines()
9495
break
9596
except IOError as e:
9697
if e.errno != errno.EINTR: # Loop if EINTR
9798
raise
9899
# Other exceptions propagate to the caller
99-
100+
100101
def CallRC(self, inInput = None): # Raise exception or return the return code
101102
self.Communicate(inInput)
102103
return self.pipe.returncode
103-
104+
104105
def Call(self, inInput = None): # Raise exception on failure
105106
self.Communicate(inInput)
106107
if self.pipe.returncode != 0:
@@ -111,14 +112,14 @@ def Call(self, inInput = None): # Raise exception on failure
111112
else:
112113
raise Exception("Unknown failure")
113114
return self
114-
115+
115116
def Chain(self, *inParams):
116117
if not self.called:
117118
self.Call()
118119
self._NewPipe(*inParams)
119120
self.Call()
120121
return self
121-
122+
122123
def Pipe(self, *inParams):
123124
if not self.called:
124125
self.Call()
@@ -135,7 +136,7 @@ def MakeSafeParam(cls, inParam):
135136
if not re.match(r'[-A-Za-z0-9/._~:@]*$', inParam):
136137
raise Exception("Invalid characters in parameter '"+inParam+"'")
137138
return inParam
138-
139+
139140
@classmethod
140141
def WaitOnPipe(cls, inPipe):
141142
# Wait on a popen2 pipe, handling Interrupted System Call exceptions
@@ -154,7 +155,7 @@ class TimeUtils:
154155
@staticmethod
155156
def AlarmHandler(inSigNum, inStackFrame):
156157
raise TimeException("Operation timed out")
157-
158+
158159
@classmethod
159160
def TimeoutWrapper(cls, inCallable, inTimeout):
160161
oldHandler = signal.signal(signal.SIGALRM, TimeUtils.AlarmHandler)
@@ -164,11 +165,11 @@ def TimeoutWrapper(cls, inCallable, inTimeout):
164165
finally:
165166
signal.alarm(0)
166167
signal.signal(signal.SIGALRM, oldHandler)
167-
168+
168169
@classmethod
169170
def DurationString(cls, inSecs):
170171
secs = max(0, int(inSecs))
171-
172+
172173
hours = int(secs / 3600)
173174
secs -= hours * 3600
174175
mins = int(secs / 60)
@@ -178,15 +179,15 @@ def DurationString(cls, inSecs):
178179
else:
179180
retVal = "%d:%2.2d" % (mins, secs)
180181
return retVal
181-
182+
182183
@classmethod
183184
def DateTimeToSecs(cls, inDateTime):
184185
structTime = time.strptime(inDateTime.value, '%Y%m%dT%H:%M:%SZ')
185186
retVal = time.mktime(structTime)
186187
if retVal <= 3601.0: # Handle the effect of daylight savings on start of epoch
187188
retVal = 0.0
188189
return retVal
189-
190+
190191
class IPUtils:
191192
@classmethod
192193
def ValidateIP(cls, text):
@@ -199,7 +200,7 @@ def ValidateIP(cls, text):
199200
largest = max(largest, i)
200201
if largest == 0: return False
201202
return True
202-
203+
203204
@classmethod
204205
def ValidateNetmask(cls, text):
205206
rc = re.match("^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)$", text)
@@ -229,7 +230,7 @@ def AssertValidHostname(cls, inName):
229230
if not re.match(r'[0-9A-Za-z]([-0-9A-Za-z]{0,61}[0-9A-Za-z]|)$', inName):
230231
raise Exception(Lang('Invalid hostname'))
231232
return inName
232-
233+
233234
@classmethod
234235
def AssertValidNetworkName(cls, inName):
235236
# Also allow FQDN-style names
@@ -261,7 +262,7 @@ def AssertValidNFSPathName(cls, inName):
261262
for subName in splitNames[1:]:
262263
cls.AssertValidNFSDirectoryName(subName)
263264
return inName
264-
265+
265266
@classmethod
266267
def AssertValidCIFSPathName(cls, inName):
267268
splitNames = inName.split('\\')
@@ -277,7 +278,7 @@ def BinarySizeString(cls, inBytes, inInFix = None):
277278
else:
278279
inFix = FirstValue(inInFix, '')
279280
bytes = int(inBytes)
280-
281+
281282
if bytes is None or bytes < 0:
282283
retVal = Lang('<Unknown>')
283284
elif bytes >= 1073741824: # 1GiB
@@ -320,12 +321,12 @@ def DecimalSizeString(cls, inBytes, inPrefix = None):
320321
@classmethod
321322
def MemorySizeString(cls, inBytes):
322323
return cls.BinarySizeString(inBytes)
323-
324+
324325
@classmethod
325326
def SRSizeString(cls, inBytes):
326327
return cls.BinarySizeString(inBytes)
327328

328329
@classmethod
329330
def DiskSizeString(cls, inBytes):
330331
return cls.BinarySizeString(inBytes)+' ('+cls.DecimalSizeString(inBytes)+')'
331-
332+

0 commit comments

Comments
 (0)