-
Notifications
You must be signed in to change notification settings - Fork 22
Fix Python 3.6.0 #5
base: master
Are you sure you want to change the base?
Changes from all commits
5e3b735
532cf1f
ac28a99
954e4ba
f55514a
339e7f9
3e8b117
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,17 +18,65 @@ | |
|
||
import copy | ||
import platform | ||
import re | ||
import subprocess | ||
|
||
from .posix import get_mounts | ||
|
||
# platform.mac_ver()'s first tuple element encodes the OS X version, | ||
# such as 10.11.3. | ||
OSX_VERSION_STR = platform.mac_ver()[0] | ||
OSX_VERSION_MAJOR_INT, \ | ||
OSX_VERSION_MINOR_INT, \ | ||
OSX_VERSION_MICRO_INT = [int(part) for part in OSX_VERSION_STR.split('.')] | ||
|
||
OSX_VERSION_INFO = [int(part) for part in OSX_VERSION_STR.split('.')] | ||
OSX_VERSION_MAJOR_INT = OSX_VERSION_INFO[0] | ||
OSX_VERSION_MINOR_INT = OSX_VERSION_INFO[1] | ||
OSX_VERSION_MICRO_INT = 0 | ||
|
||
if len(OSX_VERSION_INFO) >= 3: | ||
OSX_VERSION_MICRO_INT = OSX_VERSION_INFO[2] | ||
|
||
|
||
sanitize_pattern = re.compile(r'^(\s*?\<string\>)(.*?)(\<\/string\>.*?)$') | ||
|
||
def _sanitize_xml(data): | ||
"""Takes an plist (xml) and checks <string> defintions for control characters. | ||
|
||
If a control character is found, the string is converted to hexidecimal. | ||
For ST-Link devices, this properly displays the serial number, which | ||
is eroneously encoded as binary data, which causes the plistlib XML parser | ||
to crash. | ||
|
||
Returns the same document, with any mis-encoded <string> values converted | ||
to ascii hex.""" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should follow the indentation style for other docstrings. |
||
output = [] | ||
|
||
data = data.decode('utf-8') | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You are mutating data at the caller here. You could just encode it ad the for loop itself. |
||
|
||
for i, line in enumerate(data.split('\n')): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No need to enumerate if you're not using the index. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can also use splitlines(). |
||
chunk = line | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Temporary assignment not necessary. |
||
match = re.match(sanitize_pattern, chunk) | ||
if match: | ||
start = match.group(1) | ||
middle = match.group(2) | ||
end = match.group(3) | ||
needs_patch = False | ||
# Inspect the line and see if it has invalid characters. | ||
byte_list = bytearray([ord(byte) for byte in middle]) | ||
for byte in byte_list: | ||
if byte < 32: | ||
needs_patch = True | ||
if needs_patch: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could this all be reduced to just
|
||
middle = ''.join(['%02X' % byte for byte in byte_list]) | ||
new_line = '{start}{middle}{end}'.format(start=start, | ||
middle=middle, | ||
end=end) | ||
output.append(new_line) | ||
else: | ||
output.append(line) | ||
else: | ||
output.append(line) | ||
output = '\n'.join([line for line in output]) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This can simply be:
|
||
|
||
return output.encode('utf-8') | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Isn't this redundant? |
||
|
||
def _ioreg_usb_devices(nodename=None): | ||
"""Returns a list of USB device tree from ioreg""" | ||
|
@@ -38,9 +86,17 @@ def _ioreg(nodename): | |
"""Run ioreg command on specific node name""" | ||
cmd = ['ioreg', '-a', '-l', '-r', '-n', nodename] | ||
output = subprocess.check_output(cmd) | ||
# ST-Link devices (and possibly others?) erroneously store binary data | ||
# in the <string> serial number, which causes plistlib to blow up. | ||
# This will convert that to hex and preserve contents otherwise. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please add this comment to the function definition. |
||
output = _sanitize_xml(output) | ||
plist_data = [] | ||
if output: | ||
return plistlib.readPlistFromString(output) | ||
return [] | ||
try: | ||
plist_data = plistlib.readPlistFromString(output) | ||
except AttributeError as e: | ||
plist_data = plistlib.loads(output) | ||
jeffherman marked this conversation as resolved.
Show resolved
Hide resolved
|
||
return plist_data | ||
|
||
if nodename is None: | ||
xhci = _ioreg('AppleUSBXHCI') | ||
|
@@ -97,7 +153,7 @@ def _disk_partition(node): | |
info = {} | ||
|
||
for child in node.get('IORegistryEntryChildren', []): | ||
for class_name, handler in ioclass_handlers.iteritems(): | ||
for class_name, handler in iter(ioclass_handlers.items()): | ||
jeffherman marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if child.get('IOObjectClass') == class_name: | ||
info.update(handler(child)) | ||
info.update(_extra_if_info(child)) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might be worth investigating doing all of this in an XML library. This function is assuming that
ioreg
will always return data in a specific format.