1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352
|
From aca3528d1f1b8ed88e54cbbf2fbfaa0621985224 Mon Sep 17 00:00:00 2001
From: Victor Stinner <vstinner@python.org>
Date: Mon, 20 Jan 2020 14:29:54 +0100
Subject: [PATCH] Update to Python 3.9
* Fix SyntaxWarning: "is not" with a literal. Did you mean "!="?
* Add py3_array_frombytes() and py3_array_tobytes() to pyipmi.utils.
frombytes() and tostring() methods of array.array have been removed
from Python 3.9.
* Python 3.9 normalizes the encoding name "bcd+" to "bcd".
* Replace b'...' with br'...' in two regular expressions.
* Add _PY3 private constant to pyipmi.utils.
---
pyipmi/fields.py | 5 +++--
pyipmi/hpm.py | 10 +++++----
pyipmi/interfaces/ipmb.py | 10 ++++-----
pyipmi/interfaces/ipmitool.py | 10 ++++-----
pyipmi/interfaces/rmcp.py | 4 ++--
pyipmi/lan.py | 2 +-
pyipmi/sdr.py | 8 +++----
pyipmi/utils.py | 39 +++++++++++++++++++++++++++--------
tests/interfaces/test_rmcp.py | 3 ++-
9 files changed, 58 insertions(+), 33 deletions(-)
diff --git a/pyipmi/fields.py b/pyipmi/fields.py
index 7f2e734..4068262 100644
--- a/pyipmi/fields.py
+++ b/pyipmi/fields.py
@@ -5,6 +5,7 @@
import array
from .errors import DecodingError
+from .utils import py3_array_tobytes
class VersionField(object):
@@ -38,10 +39,10 @@ class VersionField(object):
"""`data` is array.array"""
self.major = data[0]
- if data[1] is 0xff:
+ if data[1] == 0xff:
self.minor = data[1]
elif data[1] <= 0x99:
- self.minor = int(data[1:2].tostring().decode('bcd+'))
+ self.minor = int(py3_array_tobytes(data[1:2]).decode('bcd+'))
else:
raise DecodingError()
diff --git a/pyipmi/hpm.py b/pyipmi/hpm.py
index d7cb9da..5de95f4 100644
--- a/pyipmi/hpm.py
+++ b/pyipmi/hpm.py
@@ -29,7 +29,7 @@ from .errors import CompletionCodeError, HpmError, IpmiTimeoutError
from .msgs import create_request_by_name
from .msgs import constants
from .utils import check_completion_code, bcd_search, chunks
-from .utils import py3dec_unic_bytes_fix, bytes2 as bytes
+from .utils import py3dec_unic_bytes_fix, bytes2 as bytes, py3_array_tobytes
from .state import State
from .fields import VersionField
@@ -203,7 +203,7 @@ class Hpm(object):
try:
status = self.get_upgrade_status()
if status.command_in_progress is not expected_cmd \
- and status.command_in_progress is not 0x34:
+ and status.command_in_progress != 0x34:
pass
if status.last_completion_code \
== CC_LONG_DURATION_CMD_IN_PROGRESS:
@@ -474,9 +474,11 @@ class ComponentPropertyCurrentVersion(ComponentProperty):
class ComponentPropertyDescriptionString(ComponentProperty):
def _from_rsp_data(self, data):
- self.description = py3dec_unic_bytes_fix(array('B', data).tostring())
+ descr = py3_array_tobytes(array('B', data))
+ descr = py3dec_unic_bytes_fix(descr)
# strip '\x00'
- self.description = self.description.replace('\0', '')
+ descr = descr.replace('\0', '')
+ self.description = descr
class ComponentPropertyRollbackVersion(ComponentProperty):
diff --git a/pyipmi/interfaces/ipmb.py b/pyipmi/interfaces/ipmb.py
index 8acf96f..5d4d06a 100644
--- a/pyipmi/interfaces/ipmb.py
+++ b/pyipmi/interfaces/ipmb.py
@@ -20,6 +20,7 @@ from ..logger import log
from ..msgs import (create_message, create_request_by_name,
encode_message, decode_message, constants)
from ..utils import check_completion_code
+from ..utils import py3_array_tobytes, py3_array_frombytes
def checksum(data):
@@ -62,7 +63,7 @@ class IpmbHeaderReq(IpmbHeader):
data.append(self.rq_sa)
data.append(self.rq_seq << 2 | self.rq_lun)
data.append(self.cmd_id)
- return data.tostring()
+ return py3_array_tobytes(data)
def decode(self):
raise NotImplementedError()
@@ -93,14 +94,13 @@ def encode_ipmb_msg(header, data):
Returns the message as bytestring.
"""
msg = array('B')
-
- msg.fromstring(header.encode())
+ py3_array_frombytes(msg, header.encode())
if data is not None:
a = array('B')
- a.fromstring(data)
+ py3_array_frombytes(a, data)
msg.extend(a)
msg.append(checksum(msg[3:]))
- return msg.tostring()
+ return py3_array_tobytes(msg)
def encode_send_message(payload, rq_sa, rs_sa, channel, seq, tracking=1):
diff --git a/pyipmi/interfaces/ipmitool.py b/pyipmi/interfaces/ipmitool.py
index 8d6d97f..80532e8 100644
--- a/pyipmi/interfaces/ipmitool.py
+++ b/pyipmi/interfaces/ipmitool.py
@@ -25,7 +25,7 @@ from ..errors import IpmiTimeoutError
from ..logger import log
from ..msgs import encode_message, decode_message, create_message
from ..msgs.constants import CC_OK
-from ..utils import py3dec_unic_bytes_fix, ByteBuffer
+from ..utils import py3dec_unic_bytes_fix, ByteBuffer, py3_array_tobytes
class Ipmitool(object):
@@ -49,9 +49,9 @@ class Ipmitool(object):
interface_type)
self.re_completion_code = re.compile(
- b"Unable to send RAW command \(.*rsp=(0x[0-9a-f]+)\)")
+ br"Unable to send RAW command \(.*rsp=(0x[0-9a-f]+)\)")
self.re_timeout = re.compile(
- b"Unable to send RAW command \(.*cmd=0x[0-9a-f]+\)")
+ br"Unable to send RAW command \(.*cmd=0x[0-9a-f]+\)")
self._session = None
@@ -135,7 +135,7 @@ class Ipmitool(object):
log().debug('IPMI RX: {:s}'.format(
''.join('%02x ' % b for b in array('B', data))))
- return data.tostring()
+ return py3_array_tobytes(data)
def send_and_receive(self, req):
log().debug('IPMI Request [%s]', req)
@@ -144,7 +144,7 @@ class Ipmitool(object):
req_data.push_string(encode_message(req))
rsp_data = self.send_and_receive_raw(req.target, req.lun, req.netfn,
- req_data.tostring())
+ py3_array_tobytes(req_data))
rsp = create_message(req.netfn + 1, req.cmdid, req.group_extension)
decode_message(rsp, rsp_data)
diff --git a/pyipmi/interfaces/rmcp.py b/pyipmi/interfaces/rmcp.py
index d6e35be..ff7a95e 100644
--- a/pyipmi/interfaces/rmcp.py
+++ b/pyipmi/interfaces/rmcp.py
@@ -32,7 +32,7 @@ from ..logger import log
from ..interfaces.ipmb import (IpmbHeaderReq, encode_ipmb_msg,
encode_bridged_message, decode_bridged_message,
rx_filter)
-from ..utils import check_completion_code
+from ..utils import check_completion_code, py3_array_tobytes
CLASS_NORMAL_MSG = 0x00
@@ -262,7 +262,7 @@ class IpmiMsg(object):
else:
raise NotSupportedError('authentication type %s' % auth_type)
- pdu += array('B', [data_len]).tostring()
+ pdu += py3_array_tobytes(array('B', [data_len]))
if sdu is not None:
pdu += sdu
diff --git a/pyipmi/lan.py b/pyipmi/lan.py
index 0a2b04b..bff61de 100644
--- a/pyipmi/lan.py
+++ b/pyipmi/lan.py
@@ -58,7 +58,7 @@ class Lan(object):
revision_only=0):
req = create_request_by_name('GetLanConfigurationParameters')
req.command.get_parameter_revision_only = revision_only
- if revision_only is not 1:
+ if revision_only != 1:
req.command.channel_number = channel
req.parameter_selector = parameter_selector
req.set_selector = set_selector
diff --git a/pyipmi/sdr.py b/pyipmi/sdr.py
index d5ede24..b079f99 100644
--- a/pyipmi/sdr.py
+++ b/pyipmi/sdr.py
@@ -374,13 +374,13 @@ class SdrFullSensorRecord(SdrCommon):
elif capabilities & THRESHOLD_MASK == THRESHOLD_IS_FIXED:
self.capabilities.append('threshold_fixed')
# sensor event message control support
- if (capabilities & 0x03) is 0:
+ if (capabilities & 0x03) == 0:
pass
- if (capabilities & 0x03) is 1:
+ if (capabilities & 0x03) == 1:
pass
- if (capabilities & 0x03) is 2:
+ if (capabilities & 0x03) == 2:
pass
- if (capabilities & 0x03) is 3:
+ if (capabilities & 0x03) == 3:
pass
def _from_data(self, data):
diff --git a/pyipmi/utils.py b/pyipmi/utils.py
index bba9db3..04ff91b 100644
--- a/pyipmi/utils.py
+++ b/pyipmi/utils.py
@@ -21,27 +21,44 @@ from .msgs import constants
from .errors import DecodingError, CompletionCodeError
+_PY3 = (sys.version_info >= (3,))
+
+
def py3enc_unic_bytes_fix(dat):
# python 3 unicode fix
- if isinstance(dat, str) and int(sys.version[0]) > 2:
+ if isinstance(dat, str) and _PY3:
dat = dat.encode('raw_unicode_escape')
return dat
def py3dec_unic_bytes_fix(dat):
# python 3 unicode fix
- if int(sys.version[0]) > 2:
+ if _PY3:
return dat.decode('raw_unicode_escape')
return dat
def bytes2(dat, enc):
# python 2-3 workaround
- if int(sys.version[0]) > 2:
+ if _PY3:
return bytes(dat, enc)
return dat
+def py3_array_frombytes(msg, data):
+ if _PY3:
+ return msg.frombytes(data)
+ else:
+ return msg.fromstring(data)
+
+
+def py3_array_tobytes(msg):
+ if _PY3:
+ return msg.tobytes()
+ else:
+ return msg.tostring()
+
+
def check_completion_code(cc):
if cc != constants.CC_OK:
raise CompletionCodeError(cc)
@@ -74,12 +91,15 @@ class ByteBuffer(object):
return value
def push_string(self, value):
- self.array.fromstring(value)
+ if _PY3 and isinstance(value, str):
+ # Encode Unicode to UTF-8
+ value = value.encode()
+ py3_array_frombytes(self.array, value)
def pop_string(self, length):
string = self.array[0:length]
del self.array[0:length]
- return string.tostring()
+ return py3_array_tobytes(string)
# return py3dec_unic_bytes_fix(string.tostring())
def pop_slice(self, length):
@@ -91,7 +111,7 @@ class ByteBuffer(object):
return c
def tostring(self):
- return self.array.tostring()
+ return py3_array_tobytes(self.array)
def extend(self, data):
self.array.extend(data)
@@ -123,7 +143,7 @@ def bcd_decode(encoded_input):
chars = list()
try:
for data in encoded_input:
- if int(sys.version[0]) == 2:
+ if not _PY3:
data = ord(data)
chars.append(BCD_MAP[data >> 4 & 0xf] + BCD_MAP[data & 0xf])
return (''.join(chars), len(encoded_input) * 2)
@@ -132,12 +152,13 @@ def bcd_decode(encoded_input):
def bcd_search(name):
- if name != 'bcd+':
+ # Python 3.9 normalizes 'bcd+' as 'bcd_'
+ if name not in ('bcd+', 'bcd'):
return None
return codecs.CodecInfo(name='bcd+', encode=bcd_encode, decode=bcd_decode)
def is_string(string):
- if sys.version_info[0] >= 3:
+ if _PY3:
return isinstance(string, str)
return isinstance(string, basestring)
diff --git a/tests/interfaces/test_rmcp.py b/tests/interfaces/test_rmcp.py
index 44772e0..c2a41d6 100644
--- a/tests/interfaces/test_rmcp.py
+++ b/tests/interfaces/test_rmcp.py
@@ -10,6 +10,7 @@ from pyipmi import Target
from pyipmi.session import Session
from pyipmi.interfaces.rmcp import (AsfMsg, AsfPing, AsfPong, IpmiMsg,
Rmcp, RmcpMsg)
+from pyipmi.utils import py3_array_tobytes
class TestRmcpMsg:
@@ -83,7 +84,7 @@ class TestIpmiMsg:
eq_(psw, b'admin\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
def test_ipmimsg_pack_with_data(self):
- data = array.array('B', (1, 2, 3, 4)).tostring()
+ data = py3_array_tobytes(array.array('B', (1, 2, 3, 4)))
m = IpmiMsg()
pdu = m.pack(data)
eq_(pdu, b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x01\x02\x03\x04')
--
2.25.1
|