xrange() was removed from Python on 1/1/2020

Also simplify by defining basestring and unicode in Python 3

Python porting best practice [___use feature detection instead of version detection___](https://docs.python.org/3/howto/pyporting.html#use-feature-detection-instead-of-version-detection).

Bare exceptions: https://realpython.com/the-most-diabolical-python-antipattern

__basestring__ and __unicode__ was removed in Python 3 because all str are Unicode utf-8.
This commit is contained in:
Christian Clauss 2020-04-13 10:44:05 +02:00 committed by GitHub
parent 26fda46c01
commit 49e07bcb2f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -10,10 +10,17 @@ if sys.version_info < (3,0):
# has issues with Unicode strings
from StringIO import StringIO
try:
basestring # Python 2
unicode
except NameError:
basestring = str # Python 3
unicode = str
try:
FMT_XML = plistlib.FMT_XML
FMT_BINARY = plistlib.FMT_BINARY
except:
except AttributeError:
FMT_XML = "FMT_XML"
FMT_BINARY = "FMT_BINARY"
@ -22,33 +29,27 @@ except:
### ###
def _check_py3():
return True if sys.version_info >= (3, 0) else False
return sys.version_info >= (3, 0)
def _is_binary(fp):
if isinstance(fp, _get_inst()):
if isinstance(fp, basestring):
return fp.startswith(b"bplist00")
header = fp.read(32)
fp.seek(0)
return header[:8] == b'bplist00'
def _get_inst():
if _check_py3():
return (str)
else:
return (str, unicode)
### ###
# Deprecated Functions - Remapped #
### ###
def readPlist(pathOrFile):
if not isinstance(pathOrFile, _get_inst()):
if not isinstance(pathOrFile, basestring):
return load(pathOrFile)
with open(pathOrFile, "rb") as f:
return load(f)
def writePlist(value, pathOrFile):
if not isinstance(pathOrFile, _get_inst()):
if not isinstance(pathOrFile, basestring):
return dump(value, pathOrFile, fmt=FMT_XML, sort_keys=True, skipkeys=False)
with open(pathOrFile, "wb") as f:
return dump(value, f, fmt=FMT_XML, sort_keys=True, skipkeys=False)
@ -107,7 +108,7 @@ def load(fp, fmt=None, use_builtin_types=None, dict_type=dict):
if isinstance(fp, unicode):
# Encode unicode -> string; use utf-8 for safety
fp = fp.encode("utf-8")
if isinstance(fp,_get_inst()):
if isinstance(fp, basestring):
# It's a string - let's wrap it up
fp = StringIO(fp)
# Parse it
@ -119,7 +120,7 @@ def load(fp, fmt=None, use_builtin_types=None, dict_type=dict):
return p.parse(fp)
def loads(value, fmt=None, use_builtin_types=None, dict_type=dict):
if _check_py3() and isinstance(value, _get_inst()):
if _check_py3() and isinstance(value, basestring):
# If it's a string - encode it
value = value.encode()
return load(BytesIO(value),fmt=fmt,use_builtin_types=use_builtin_types,dict_type=dict_type)
@ -137,7 +138,7 @@ def dump(value, fp, fmt=FMT_XML, sort_keys=True, skipkeys=False):
writer.beginElement("dict")
items = sorted(d.items()) if sort_keys else d.items()
for key, value in items:
if not isinstance(key, (str,unicode)):
if not isinstance(key, basestring):
if skipkeys:
continue
raise TypeError("keys must be strings")
@ -273,7 +274,7 @@ class _BinaryPlistParser:
elif tokenH == 0x10: # int
result = 0
for k in xrange((2 << tokenL) - 1):
for k in range((2 << tokenL) - 1):
result = (result << 8) + ord(self._fp.read(1))
# result = int.from_bytes(self._fp.read(1 << tokenL),
# 'big', signed=tokenL >= 3)
@ -441,7 +442,7 @@ class _BinaryPlistWriter (object):
items = sorted(items)
for k, v in items:
if not isinstance(k, (str,unicode)):
if not isinstance(k, basestring):
if self._skipkeys:
continue
raise TypeError("keys must be strings")
@ -521,7 +522,7 @@ class _BinaryPlistWriter (object):
self._write_size(0x40, len(value.data))
self._fp.write(value.data)
elif isinstance(value, (str,unicode)):
elif isinstance(value, basestring):
try:
t = value.encode('ascii')
self._write_size(0x50, len(value))
@ -549,7 +550,7 @@ class _BinaryPlistWriter (object):
rootItems = value.items()
for k, v in rootItems:
if not isinstance(k, (str,unicode)):
if not isinstance(k, basestring):
if self._skipkeys:
continue
raise TypeError("keys must be strings")