Hello community, here is the log from the commit of package python-biplist for openSUSE:Factory checked in at 2015-04-27 13:05:34 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-biplist (Old) and /work/SRC/openSUSE:Factory/.python-biplist.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-biplist" Changes: -------- --- /work/SRC/openSUSE:Factory/python-biplist/python-biplist.changes 2013-10-25 11:12:03.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.python-biplist.new/python-biplist.changes 2015-04-27 13:05:35.000000000 +0200 @@ -1,0 +2,16 @@ +Sun Apr 26 13:02:09 UTC 2015 - [email protected] + +- update to version 0.9: + * Fixes #5 ValueError: timestamp out of range for platform time_t + * Merged pull request #3 removing the `six` module while keeping + Python3 compatibility +- additional changes from version v0.8: + * Fixes #3 testFileRead fails using python 3.x along with several + other Python 3 compatibility issues. +- update project URL +- add fdupes as BuildRequires and call it after install +- set a minimum version to python 2.7 +- remove python-six from BuildRequires: now unneeded +- quiet the test run to avoid spamming the build log + +------------------------------------------------------------------- Old: ---- biplist-0.5.tar.gz New: ---- biplist-0.9.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-biplist.spec ++++++ --- /var/tmp/diff_new_pack.JUj3Nj/_old 2015-04-27 13:05:37.000000000 +0200 +++ /var/tmp/diff_new_pack.JUj3Nj/_new 2015-04-27 13:05:37.000000000 +0200 @@ -1,7 +1,7 @@ # # spec file for package python-biplist # -# Copyright (c) 2013 SUSE LINUX Products GmbH, Nuernberg, Germany. +# Copyright (c) 2015 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -17,19 +17,19 @@ Name: python-biplist -Version: 0.5 +Version: 0.9 Release: 0 -Url: https://github.com/wooster/biplist +Url: https://bitbucket.org/wooster/biplist Summary: A library for reading/writing binary plists License: BSD-3-Clause Group: Development/Languages/Python Source: http://pypi.python.org/packages/source/b/biplist/biplist-%{version}.tar.gz BuildRoot: %{_tmppath}/%{name}-%{version}-build +BuildRequires: fdupes BuildRequires: python-coverage -BuildRequires: python-devel +BuildRequires: python-devel >= 2.7 BuildRequires: python-nose BuildRequires: python-setuptools -BuildRequires: python-six %if 0%{?suse_version} && 0%{?suse_version} <= 1110 %{!?python_sitelib: %global python_sitelib %(python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")} %else @@ -51,9 +51,10 @@ %install python setup.py install --prefix=%{_prefix} --root=%{buildroot} +%fdupes %buildroot/%_prefix %check -python setup.py test +python setup.py -q test %files %defattr(-,root,root,-) ++++++ biplist-0.5.tar.gz -> biplist-0.9.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/biplist-0.5/PKG-INFO new/biplist-0.9/PKG-INFO --- old/biplist-0.5/PKG-INFO 2012-06-19 02:51:33.000000000 +0200 +++ new/biplist-0.9/PKG-INFO 2014-10-26 20:09:20.000000000 +0100 @@ -1,12 +1,12 @@ Metadata-Version: 1.1 Name: biplist -Version: 0.5 +Version: 0.9 Summary: biplist is a library for reading/writing binary plists. -Home-page: https://github.com/wooster/biplist +Home-page: https://bitbucket.org/wooster/biplist Author: Andrew Wooster Author-email: [email protected] License: BSD -Download-URL: https://github.com/wooster/biplist/downloads/biplist-0.5.tar.gz +Download-URL: https://bitbucket.org/wooster/biplist/downloads/biplist-0.9.tar.gz Description: `biplist` is a binary plist parser/generator for Python. Binary Property List (plist) files provide a faster and smaller serialization @@ -22,4 +22,3 @@ Classifier: Programming Language :: Python Classifier: Topic :: Software Development :: Libraries :: Python Modules Classifier: Topic :: Text Processing :: Markup -Requires: six diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/biplist-0.5/biplist/__init__.py new/biplist-0.9/biplist/__init__.py --- old/biplist-0.5/biplist/__init__.py 2012-06-19 02:37:05.000000000 +0200 +++ new/biplist-0.9/biplist/__init__.py 2014-10-26 20:03:11.000000000 +0100 @@ -46,22 +46,38 @@ import sys from collections import namedtuple -import calendar import datetime +import io import math import plistlib from struct import pack, unpack +from struct import error as struct_error import sys import time -import six +try: + unicode + unicodeEmpty = r'' +except NameError: + unicode = str + unicodeEmpty = '' +try: + long +except NameError: + long = int +try: + {}.iteritems + iteritems = lambda x: x.iteritems() +except AttributeError: + iteritems = lambda x: x.items() __all__ = [ 'Uid', 'Data', 'readPlist', 'writePlist', 'readPlistFromString', 'writePlistToString', 'InvalidPlistException', 'NotBinaryPlistException' ] -apple_reference_date_offset = 978307200 +# Apple uses Jan 1, 2001 as a base for all plist date/times. +apple_reference_date = datetime.datetime.utcfromtimestamp(978307200) class Uid(int): """Wrapper around integers for representing UID values. This @@ -69,7 +85,7 @@ def __repr__(self): return "Uid(%d)" % self -class Data(six.binary_type): +class Data(bytes): """Wrapper around str types for representing Data values.""" pass @@ -85,7 +101,7 @@ """Raises NotBinaryPlistException, InvalidPlistException""" didOpen = False result = None - if isinstance(pathOrFile, (six.binary_type, six.text_type)): + if isinstance(pathOrFile, (bytes, unicode)): pathOrFile = open(pathOrFile, 'rb') didOpen = True try: @@ -94,19 +110,33 @@ except NotBinaryPlistException as e: try: pathOrFile.seek(0) - result = plistlib.readPlist(pathOrFile) + result = None + if hasattr(plistlib, 'loads'): + contents = None + if isinstance(pathOrFile, (bytes, unicode)): + with open(pathOrFile, 'rb') as f: + contents = f.read() + else: + contents = pathOrFile.read() + result = plistlib.loads(contents) + else: + result = plistlib.readPlist(pathOrFile) result = wrapDataObject(result, for_binary=True) except Exception as e: raise InvalidPlistException(e) - if didOpen: - pathOrFile.close() + finally: + if didOpen: + pathOrFile.close() return result def wrapDataObject(o, for_binary=False): if isinstance(o, Data) and not for_binary: - o = plistlib.Data(o) - elif isinstance(o, plistlib.Data) and for_binary: - o = Data(o.data) + v = sys.version_info + if not (v[0] >= 3 and v[1] >= 4): + o = plistlib.Data(o) + elif isinstance(o, (bytes, plistlib.Data)) and for_binary: + if hasattr(o, 'data'): + o = Data(o.data) elif isinstance(o, tuple): o = wrapDataObject(list(o), for_binary) o = tuple(o) @@ -121,10 +151,17 @@ def writePlist(rootObject, pathOrFile, binary=True): if not binary: rootObject = wrapDataObject(rootObject, binary) - return plistlib.writePlist(rootObject, pathOrFile) + if hasattr(plistlib, "dump"): + if isinstance(pathOrFile, (bytes, unicode)): + with open(pathOrFile, 'wb') as f: + return plistlib.dump(rootObject, f) + else: + return plistlib.dump(rootObject, pathOrFile) + else: + return plistlib.writePlist(rootObject, pathOrFile) else: didOpen = False - if isinstance(pathOrFile, (six.binary_type, six.text_type)): + if isinstance(pathOrFile, (bytes, unicode)): pathOrFile = open(pathOrFile, 'wb') didOpen = True writer = PlistWriter(pathOrFile) @@ -134,25 +171,27 @@ return result def readPlistFromString(data): - return readPlist(six.BytesIO(data)) + return readPlist(io.BytesIO(data)) def writePlistToString(rootObject, binary=True): if not binary: rootObject = wrapDataObject(rootObject, binary) - if six.PY3: + if hasattr(plistlib, "dumps"): + return plistlib.dumps(rootObject) + elif hasattr(plistlib, "writePlistToBytes"): return plistlib.writePlistToBytes(rootObject) else: return plistlib.writePlistToString(rootObject) else: - io = six.BytesIO() - writer = PlistWriter(io) + ioObject = io.BytesIO() + writer = PlistWriter(ioObject) writer.writeRoot(rootObject) - return io.getvalue() + return ioObject.getvalue() def is_stream_binary_plist(stream): stream.seek(0) header = stream.read(7) - if header == six.b('bplist0'): + if header == b'bplist0': return True else: return False @@ -281,12 +320,12 @@ raise InvalidPlistException("Invalid object found: {format: %s, extra: %s}" % (bin(format), bin(extra))) return result - def readInteger(self, bytes): + def readInteger(self, byteSize): result = 0 original_offset = self.currentOffset - data = self.contents[self.currentOffset:self.currentOffset+bytes] - result = self.getSizedInteger(data, bytes) - self.currentOffset = original_offset + bytes + data = self.contents[self.currentOffset:self.currentOffset + byteSize] + result = self.getSizedInteger(data, byteSize, as_number=True) + self.currentOffset = original_offset + byteSize return result def readReal(self, length): @@ -350,9 +389,9 @@ return data.decode('utf_16_be') def readDate(self): - global apple_reference_date_offset result = unpack(">d", self.contents[self.currentOffset:self.currentOffset+8])[0] - result = datetime.datetime.utcfromtimestamp(result + apple_reference_date_offset) + # Use timedelta to workaround time_t size limitation on 32-bit python. + result = datetime.timedelta(seconds=result) + apple_reference_date self.currentOffset += 8 return result @@ -364,19 +403,32 @@ def readUid(self, length): return Uid(self.readInteger(length+1)) - def getSizedInteger(self, data, bytes): + def getSizedInteger(self, data, byteSize, as_number=False): + """Numbers of 8 bytes are signed integers when they refer to numbers, but unsigned otherwise.""" result = 0 # 1, 2, and 4 byte integers are unsigned - if bytes == 1: + if byteSize == 1: result = unpack('>B', data)[0] - elif bytes == 2: + elif byteSize == 2: result = unpack('>H', data)[0] - elif bytes == 4: + elif byteSize == 4: result = unpack('>L', data)[0] - elif bytes == 8: - result = unpack('>q', data)[0] + elif byteSize == 8: + if as_number: + result = unpack('>q', data)[0] + else: + result = unpack('>Q', data)[0] + elif byteSize <= 16: + # Handle odd-sized or integers larger than 8 bytes + # Don't naively go over 16 bytes, in order to prevent infinite loops. + result = 0 + if hasattr(int, 'from_bytes'): + result = int.from_bytes(data, 'big') + else: + for byte in data: + result = (result << 8) | unpack('>B', byte)[0] else: - raise InvalidPlistException("Encountered integer longer than 8 bytes.") + raise InvalidPlistException("Encountered integer longer than 16 bytes.") return result class HashableWrapper(object): @@ -391,8 +443,21 @@ def __repr__(self): return "<BoolWrapper: %s>" % self.value +class FloatWrapper(object): + _instances = {} + def __new__(klass, value): + # Ensure FloatWrapper(x) for a given float x is always the same object + wrapper = klass._instances.get(value) + if wrapper is None: + wrapper = object.__new__(klass) + wrapper.value = value + klass._instances[value] = wrapper + return wrapper + def __repr__(self): + return "<FloatWrapper: %s>" % self.value + class PlistWriter(object): - header = six.b('bplist00bybiplist1.0') + header = b'bplist00bybiplist1.0' file = None byteCounts = None trailer = None @@ -467,6 +532,8 @@ return self.wrappedTrue else: return self.wrappedFalse + elif isinstance(root, float): + return FloatWrapper(root) elif isinstance(root, set): n = set() for value in root: @@ -474,7 +541,7 @@ return HashableWrapper(n) elif isinstance(root, dict): n = {} - for key, value in six.iteritems(root): + for key, value in iteritems(root): n[self.wrapRoot(key)] = self.wrapRoot(value) return HashableWrapper(n) elif isinstance(root, list): @@ -497,7 +564,7 @@ raise InvalidPlistException('Dictionary keys cannot be null in plists.') elif isinstance(key, Data): raise InvalidPlistException('Data cannot be dictionary keys in plists.') - elif not isinstance(key, (six.binary_type, six.text_type)): + elif not isinstance(key, (bytes, unicode)): raise InvalidPlistException('Keys must be strings.') def proc_size(size): @@ -519,10 +586,10 @@ elif isinstance(obj, Uid): size = self.intSize(obj) self.incrementByteCount('uidBytes', incr=1+size) - elif isinstance(obj, six.integer_types): + elif isinstance(obj, (int, long)): size = self.intSize(obj) self.incrementByteCount('intBytes', incr=1+size) - elif isinstance(obj, (float)): + elif isinstance(obj, FloatWrapper): size = self.realSize(obj) self.incrementByteCount('realBytes', incr=1+size) elif isinstance(obj, datetime.datetime): @@ -530,7 +597,7 @@ elif isinstance(obj, Data): size = proc_size(len(obj)) self.incrementByteCount('dataBytes', incr=1+size) - elif isinstance(obj, (six.text_type, six.binary_type)): + elif isinstance(obj, (unicode, bytes)): size = proc_size(len(obj)) self.incrementByteCount('stringBytes', incr=1+size) elif isinstance(obj, HashableWrapper): @@ -549,7 +616,7 @@ elif isinstance(obj, dict): size = proc_size(len(obj)) self.incrementByteCount('dictBytes', incr=1+size) - for key, value in six.iteritems(obj): + for key, value in iteritems(obj): check_key(key) self.computeOffsets(key, asReference=True) self.computeOffsets(value, asReference=True) @@ -566,10 +633,10 @@ position = self.positionOfObjectReference(obj) if position is None: self.writtenReferences[obj] = len(self.writtenReferences) - output += self.binaryInt(len(self.writtenReferences) - 1, bytes=self.trailer.objectRefSize) + output += self.binaryInt(len(self.writtenReferences) - 1, byteSize=self.trailer.objectRefSize) return (True, output) else: - output += self.binaryInt(position, bytes=self.trailer.objectRefSize) + output += self.binaryInt(position, byteSize=self.trailer.objectRefSize) return (False, output) def writeObject(self, obj, output, setReferencePosition=False): @@ -578,7 +645,7 @@ object was written. """ def proc_variable_length(format, length): - result = six.b('') + result = b'' if length > 0b1110: result += pack('!B', (format << 4) | 0b1111) result = self.writeObject(length, result) @@ -586,9 +653,9 @@ result += pack('!B', (format << 4) | length) return result - if isinstance(obj, six.text_type) and obj == six.u(''): + if isinstance(obj, (str, unicode)) and obj == unicodeEmpty: # The Apple Plist decoder can't decode a zero length Unicode string. - obj = six.b('') + obj = b'' if setReferencePosition: self.referencePositions[obj] = len(output) @@ -604,31 +671,29 @@ size = self.intSize(obj) output += pack('!B', (0b1000 << 4) | size - 1) output += self.binaryInt(obj) - elif isinstance(obj, six.integer_types): - bytes = self.intSize(obj) - root = math.log(bytes, 2) + elif isinstance(obj, (int, long)): + byteSize = self.intSize(obj) + root = math.log(byteSize, 2) output += pack('!B', (0b0001 << 4) | int(root)) - output += self.binaryInt(obj) - elif isinstance(obj, float): + output += self.binaryInt(obj, as_number=True) + elif isinstance(obj, FloatWrapper): # just use doubles output += pack('!B', (0b0010 << 4) | 3) output += self.binaryReal(obj) elif isinstance(obj, datetime.datetime): - timestamp = calendar.timegm(obj.utctimetuple()) - timestamp -= apple_reference_date_offset + timestamp = (obj - apple_reference_date).total_seconds() output += pack('!B', 0b00110011) output += pack('!d', float(timestamp)) elif isinstance(obj, Data): output += proc_variable_length(0b0100, len(obj)) output += obj - elif isinstance(obj, six.text_type): - bytes = obj.encode('utf_16_be') - output += proc_variable_length(0b0110, len(bytes)//2) - output += bytes - elif isinstance(obj, six.binary_type): - bytes = obj - output += proc_variable_length(0b0101, len(bytes)) - output += bytes + elif isinstance(obj, unicode): + byteData = obj.encode('utf_16_be') + output += proc_variable_length(0b0110, len(byteData)//2) + output += byteData + elif isinstance(obj, bytes): + output += proc_variable_length(0b0101, len(obj)) + output += obj elif isinstance(obj, HashableWrapper): obj = obj.value if isinstance(obj, (set, list, tuple)): @@ -649,7 +714,7 @@ keys = [] values = [] objectsToWrite = [] - for key, value in six.iteritems(obj): + for key, value in iteritems(obj): keys.append(key) values.append(value) for key in keys: @@ -675,8 +740,8 @@ # goes into writtenReferences. This isn't an issue in Py2 # because u'' and b'' have the same hash; but it is in # Py3, where they don't. - if six.PY3 and obj == six.u(''): - obj = six.b('') + if bytes != str and obj == unicodeEmpty: + obj = b'' position = self.referencePositions.get(obj) if position is None: raise InvalidPlistException("Error while writing offsets table. Object not found. %s" % obj) @@ -686,23 +751,31 @@ def binaryReal(self, obj): # just use doubles - result = pack('>d', obj) + result = pack('>d', obj.value) return result - def binaryInt(self, obj, bytes=None): - result = six.b('') - if bytes is None: - bytes = self.intSize(obj) - if bytes == 1: + def binaryInt(self, obj, byteSize=None, as_number=False): + result = b'' + if byteSize is None: + byteSize = self.intSize(obj) + if byteSize == 1: result += pack('>B', obj) - elif bytes == 2: + elif byteSize == 2: result += pack('>H', obj) - elif bytes == 4: + elif byteSize == 4: result += pack('>L', obj) - elif bytes == 8: - result += pack('>q', obj) + elif byteSize == 8: + if as_number: + result += pack('>q', obj) + else: + result += pack('>Q', obj) + elif byteSize <= 16: + try: + result = pack('>Q', 0) + pack('>Q', obj) + except struct_error as e: + raise InvalidPlistException("Unable to pack integer %d: %s" % (obj, e)) else: - raise InvalidPlistException("Core Foundation can't handle integers with size greater than 8 bytes.") + raise InvalidPlistException("Core Foundation can't handle integers with size greater than 16 bytes.") return result def intSize(self, obj): @@ -719,8 +792,10 @@ return 4 # SIGNED # 0x7FFFFFFFFFFFFFFF is the max. - elif obj <= 0x7FFFFFFFFFFFFFFF: # 8 bytes + elif obj <= 0x7FFFFFFFFFFFFFFF: # 8 bytes signed return 8 + elif obj <= 0xffffffffffffffff: # 8 bytes unsigned + return 16 else: raise InvalidPlistException("Core Foundation can't handle integers with size greater than 8 bytes.") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/biplist-0.5/biplist.egg-info/PKG-INFO new/biplist-0.9/biplist.egg-info/PKG-INFO --- old/biplist-0.5/biplist.egg-info/PKG-INFO 2012-06-19 02:51:33.000000000 +0200 +++ new/biplist-0.9/biplist.egg-info/PKG-INFO 2014-10-26 20:09:20.000000000 +0100 @@ -1,12 +1,12 @@ Metadata-Version: 1.1 Name: biplist -Version: 0.5 +Version: 0.9 Summary: biplist is a library for reading/writing binary plists. -Home-page: https://github.com/wooster/biplist +Home-page: https://bitbucket.org/wooster/biplist Author: Andrew Wooster Author-email: [email protected] License: BSD -Download-URL: https://github.com/wooster/biplist/downloads/biplist-0.5.tar.gz +Download-URL: https://bitbucket.org/wooster/biplist/downloads/biplist-0.9.tar.gz Description: `biplist` is a binary plist parser/generator for Python. Binary Property List (plist) files provide a faster and smaller serialization @@ -22,4 +22,3 @@ Classifier: Programming Language :: Python Classifier: Topic :: Software Development :: Libraries :: Python Modules Classifier: Topic :: Text Processing :: Markup -Requires: six diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/biplist-0.5/biplist.egg-info/SOURCES.txt new/biplist-0.9/biplist.egg-info/SOURCES.txt --- old/biplist-0.5/biplist.egg-info/SOURCES.txt 2012-06-19 02:51:33.000000000 +0200 +++ new/biplist-0.9/biplist.egg-info/SOURCES.txt 2014-10-26 20:09:20.000000000 +0100 @@ -8,17 +8,18 @@ biplist.egg-info/SOURCES.txt biplist.egg-info/dependency_links.txt biplist.egg-info/not-zip-safe -biplist.egg-info/requires.txt biplist.egg-info/top_level.txt tests/test_invalid.py tests/test_utils.py tests/test_valid.py tests/test_write.py +tests/data/BFPersistentEventInfo.plist tests/data/array_only_binary.plist tests/data/bogus_file.plist tests/data/bool_only_binary.plist tests/data/dict_only_binary.plist tests/data/empty_file.plist +tests/data/large_int_limits.plist tests/data/nskeyedarchiver_example.plist tests/data/simple_binary.plist tests/data/small_real.plist diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/biplist-0.5/biplist.egg-info/requires.txt new/biplist-0.9/biplist.egg-info/requires.txt --- old/biplist-0.5/biplist.egg-info/requires.txt 2012-06-19 02:51:33.000000000 +0200 +++ new/biplist-0.9/biplist.egg-info/requires.txt 1970-01-01 01:00:00.000000000 +0100 @@ -1 +0,0 @@ -six \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/biplist-0.5/setup.py new/biplist-0.9/setup.py --- old/biplist-0.5/setup.py 2012-06-19 02:50:08.000000000 +0200 +++ new/biplist-0.9/setup.py 2014-10-26 20:04:50.000000000 +0100 @@ -19,14 +19,14 @@ author = 'Andrew Wooster' email = '[email protected]' -version = '0.5' +version = '0.9' desc = 'biplist is a library for reading/writing binary plists.' setup( name = 'biplist', version = version, - url = 'https://github.com/wooster/biplist', - download_url = 'https://github.com/wooster/biplist/downloads/biplist-0.5.tar.gz', + url = 'https://bitbucket.org/wooster/biplist', + download_url = 'https://bitbucket.org/wooster/biplist/downloads/biplist-0.9.tar.gz', license = 'BSD', description = desc, long_description = @@ -50,9 +50,9 @@ 'Programming Language :: Python', "Topic :: Software Development :: Libraries :: Python Modules", "Topic :: Text Processing :: Markup", - ], - setup_requires = ['nose', 'coverage'], + ], test_suite = 'nose.collector', - install_requires = ['six'], - requires = ['six'], + install_requires = [], + requires = [], + tests_require = ['nose', 'coverage'], ) Files old/biplist-0.5/tests/data/BFPersistentEventInfo.plist and new/biplist-0.9/tests/data/BFPersistentEventInfo.plist differ Files old/biplist-0.5/tests/data/large_int_limits.plist and new/biplist-0.9/tests/data/large_int_limits.plist differ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/biplist-0.5/tests/test_invalid.py new/biplist-0.9/tests/test_invalid.py --- old/biplist-0.5/tests/test_invalid.py 2012-06-19 02:37:05.000000000 +0200 +++ new/biplist-0.9/tests/test_invalid.py 2014-10-26 20:03:11.000000000 +0100 @@ -17,14 +17,14 @@ def testTooShort(self): try: - readPlistFromString(six.b("bplist0")) + readPlistFromString(b"bplist0") self.fail("Should not successfully read plist which is too short.") except InvalidPlistException as e: pass def testInvalid(self): try: - readPlistFromString(six.b("bplist0-------------------------------------")) + readPlistFromString(b"bplist0-------------------------------------") self.fail("Should not successfully read invalid plist.") except InvalidPlistException as e: pass diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/biplist-0.5/tests/test_utils.py new/biplist-0.9/tests/test_utils.py --- old/biplist-0.5/tests/test_utils.py 2012-06-19 02:37:05.000000000 +0200 +++ new/biplist-0.9/tests/test_utils.py 2014-10-26 20:03:11.000000000 +0100 @@ -1,7 +1,6 @@ import os import subprocess import sys -import six def data_path(path): return os.path.join(os.path.dirname(globals()["__file__"]), 'data', path) @@ -13,7 +12,8 @@ p = subprocess.Popen(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE) stdin, stdout = (p.stdin, p.stdout) output = stdout.read() - output = output.strip(six.b("\n")) + output = output.strip(b'\n') status = stdin.close() + stdout.close() p.wait() return p.returncode, output diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/biplist-0.5/tests/test_valid.py new/biplist-0.9/tests/test_valid.py --- old/biplist-0.5/tests/test_valid.py 2012-06-19 02:37:05.000000000 +0200 +++ new/biplist-0.9/tests/test_valid.py 2014-10-26 20:03:33.000000000 +0100 @@ -1,9 +1,17 @@ +# -*- coding: utf-8 -*- + from biplist import * import datetime import os from test_utils import * import unittest -import six + +try: + unicode + toUnicode = lambda x: x.decode('unicode-escape') +except NameError: + unicode = str + toUnicode = lambda x: x class TestValidPlistFile(unittest.TestCase): def setUp(self): @@ -11,14 +19,19 @@ def validateSimpleBinaryRoot(self, root): self.assertTrue(type(root) == dict, "Root should be dictionary.") - self.assertTrue(type(root[six.b('dateItem')]) == datetime.datetime, "date should be datetime") - self.assertEquals(root[six.b('dateItem')], datetime.datetime(2010, 8, 19, 22, 27, 30, 385449), "dates not equal" ) - self.assertEquals(root[six.b('numberItem')], -10000000000000000, "number not of expected value") - self.assertEquals(root[six.b('unicodeItem')], six.u('abc\u212cdef\u2133')) - self.assertEquals(root[six.b('stringItem')], six.b('Hi there')) - self.assertEquals(root[six.b('realItem')], 0.47) - self.assertEquals(root[six.b('boolItem')], True) - self.assertEquals(root[six.b('arrayItem')], [six.b('item0')]) + self.assertTrue(type(root[b'dateItem']) == datetime.datetime, "date should be datetime") + us = root[b'dateItem'].microsecond + if us == 385448: + # Python 3 doesn't round microseconds to the nearest value. + self.assertEqual(root[b'dateItem'], datetime.datetime(2010, 8, 19, 22, 27, 30, 385448), "dates not equal" ) + else: + self.assertEqual(root[b'dateItem'], datetime.datetime(2010, 8, 19, 22, 27, 30, 385449), "dates not equal" ) + self.assertEqual(root[b'numberItem'], -10000000000000000, "number not of expected value") + self.assertEqual(root[b'unicodeItem'], toUnicode('abc\u212cdef\u2133')) + self.assertEqual(root[b'stringItem'], b'Hi there') + self.assertEqual(root[b'realItem'], 0.47) + self.assertEqual(root[b'boolItem'], True) + self.assertEqual(root[b'arrayItem'], [b'item0']) def testFileRead(self): try: @@ -31,7 +44,7 @@ def testUnicodeRoot(self): result = readPlist(data_path('unicode_root.plist')) - self.assertEquals(result, six.u("Mirror's Edge\u2122 for iPad")) + self.assertEqual(result, toUnicode("Mirror's Edge\u2122 for iPad")) def testEmptyUnicodeRoot(self): # Porting note: this test was tricky; it was only passing in @@ -42,12 +55,22 @@ # 0b0101 (ASCII string), so the value being asserted against # appears to be what is wrong. result = readPlist(data_path('unicode_empty.plist')) - self.assertEquals(result, six.b("")) + self.assertEqual(result, b'') def testSmallReal(self): result = readPlist(data_path('small_real.plist')) - self.assertEquals(result, {six.b('4 byte real'):0.5}) + self.assertEqual(result, {b'4 byte real':0.5}) + def testLargeIntegers(self): + result = readPlist(data_path('large_int_limits.plist')) + self.assertEqual(result[b'Max 8 Byte Unsigned Integer'], 18446744073709551615) + self.assertEqual(result[b'Min 8 Byte Signed Integer'], -9223372036854775808) + self.assertEqual(result[b'Max 8 Byte Signed Integer'], 9223372036854775807) + + def testLargeDates(self): + result = readPlist(data_path("BFPersistentEventInfo.plist")) + self.assertEqual(result['lastShownRatePromptDate'], datetime.datetime(1, 12, 30, 0, 0, 0)) + def testKeyedArchiverPlist(self): """ Archive is created with class like this: @@ -63,15 +86,15 @@ ... """ result = readPlist(data_path('nskeyedarchiver_example.plist')) - self.assertEquals(result, {six.b('$version'): 100000, - six.b('$objects'): - [six.b('$null'), - {six.b('$class'): Uid(3), six.b('somekey'): Uid(2)}, - six.b('object value as string'), - {six.b('$classes'): [six.b('Archived'), six.b('NSObject')], six.b('$classname'): six.b('Archived')} + self.assertEqual(result, {b'$version': 100000, + b'$objects': + [b'$null', + {b'$class': Uid(3), b'somekey': Uid(2)}, + b'object value as string', + {b'$classes': [b'Archived', b'NSObject'], b'$classname': b'Archived'} ], - six.b('$top'): {six.b('root'): Uid(1)}, six.b('$archiver'): six.b('NSKeyedArchiver')}) - self.assertEquals("Uid(1)", repr(Uid(1))) + b'$top': {b'root': Uid(1)}, b'$archiver': b'NSKeyedArchiver'}) + self.assertEqual("Uid(1)", repr(Uid(1))) if __name__ == '__main__': unittest.main() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/biplist-0.5/tests/test_write.py new/biplist-0.9/tests/test_write.py --- old/biplist-0.5/tests/test_write.py 2012-06-19 02:37:05.000000000 +0200 +++ new/biplist-0.9/tests/test_write.py 2014-10-26 20:03:11.000000000 +0100 @@ -1,13 +1,18 @@ from biplist import * from biplist import PlistWriter import datetime +import io import os #from cStringIO import StringIO import subprocess import tempfile from test_utils import * import unittest -import six + +try: + unicode +except NameError: + unicode = str class TestWritePlist(unittest.TestCase): def setUp(self): @@ -19,7 +24,7 @@ plist = writePlistToString(root, binary=(not xml)) self.assertTrue(len(plist) > 0) readResult = readPlistFromString(plist) - self.assertEquals(readResult, (expected if expected is not None else root)) + self.assertEqual(readResult, (expected if expected is not None else root)) self.lintPlist(plist) def lintPlist(self, plistString): @@ -37,13 +42,13 @@ def testXMLPlistWithData(self): for binmode in (True, False): - binplist = writePlistToString({'data': Data(six.b('\x01\xac\xf0\xff'))}, binary=binmode) + binplist = writePlistToString({'data': Data(b'\x01\xac\xf0\xff')}, binary=binmode) plist = readPlistFromString(binplist) - self.assertTrue(isinstance(plist['data'], Data), \ + self.assertTrue(isinstance(plist['data'], (Data, bytes)), \ "unable to encode then decode Data into %s plist" % ("binary" if binmode else "XML")) def testConvertToXMLPlistWithData(self): - binplist = writePlistToString({'data': Data(six.b('\x01\xac\xf0\xff'))}) + binplist = writePlistToString({'data': Data(b'\x01\xac\xf0\xff')}) plist = readPlistFromString(binplist) xmlplist = writePlistToString(plist, binary=False) self.assertTrue(len(xmlplist) > 0, "unable to convert plist with Data from binary to XML") @@ -62,22 +67,28 @@ def testDictRoot(self): self.roundTrip({'a':1, 'B':'d'}) - def boolsAndIntegersHelper(self, cases): + def mixedNumericTypesHelper(self, cases): result = readPlistFromString(writePlistToString(cases)) for i in range(0, len(cases)): self.assertTrue(cases[i] == result[i]) - self.assertEquals(type(cases[i]), type(result[i]), "Type mismatch on %d: %s != %s" % (i, repr(cases[i]), repr(result[i]))) + self.assertEqual(type(cases[i]), type(result[i]), "Type mismatch on %d: %s != %s" % (i, repr(cases[i]), repr(result[i]))) def reprChecker(self, case): result = readPlistFromString(writePlistToString(case)) - self.assertEquals(repr(case), repr(result)) + self.assertEqual(repr(case), repr(result)) def testBoolsAndIntegersMixed(self): - self.boolsAndIntegersHelper([0, 1, True, False, None]) - self.boolsAndIntegersHelper([False, True, 0, 1, None]) - self.reprChecker({'1':[True, False, 1, 0], '0':[1, 2, 0, {'2':[1, 0, False]}]}) + self.mixedNumericTypesHelper([0, 1, True, False, None]) + self.mixedNumericTypesHelper([False, True, 0, 1, None]) + self.reprChecker({unicode('1'):[True, False, 1, 0], unicode('0'):[1, 2, 0, {unicode('2'):[1, 0, False]}]}) self.reprChecker([1, 1, 1, 1, 1, True, True, True, True]) + def testFloatsAndIntegersMixed(self): + self.mixedNumericTypesHelper([0, 1, 1.0, 0.0, None]) + self.mixedNumericTypesHelper([0.0, 1.0, 0, 1, None]) + self.reprChecker({unicode('1'):[1.0, 0.0, 1, 0], unicode('0'):[1, 2, 0, {unicode('2'):[1, 0, 0.0]}]}) + self.reprChecker([1, 1, 1, 1, 1, 1.0, 1.0, 1.0, 1.0]) + def testSetRoot(self): self.roundTrip(set((1, 2, 3))) @@ -93,8 +104,8 @@ result = writePlistToString({'aTuple':(1, 2.0, 'a'), 'dupTuple':('a', 'a', 'a', 'b', 'b')}) self.assertTrue(len(result) > 0) readResult = readPlistFromString(result) - self.assertEquals(readResult['aTuple'], [1, 2.0, 'a']) - self.assertEquals(readResult['dupTuple'], ['a', 'a', 'a', 'b', 'b']) + self.assertEqual(readResult['aTuple'], [1, 2.0, 'a']) + self.assertEqual(readResult['dupTuple'], ['a', 'a', 'a', 'b', 'b']) def testComplicated(self): root = {'preference':[1, 2, {'hi there':['a', 1, 2, {'yarrrr':123}]}]} @@ -102,9 +113,9 @@ self.roundTrip(root) def testString(self): - self.roundTrip(six.b('0')) - self.roundTrip(six.b('')) - self.roundTrip({six.b('a'):six.b('')}) + self.roundTrip(b'0') + self.roundTrip(b'') + self.roundTrip({b'a':b''}) def testLargeDict(self): d = {} @@ -124,7 +135,8 @@ path = '/var/tmp/test.plist' writePlist([1, 2, 3], path, binary=is_binary) self.assertTrue(os.path.exists(path)) - self.lintPlist(open(path, 'rb').read()) + with open(path, 'rb') as f: + self.lintPlist(f.read()) def testNone(self): self.roundTrip(None) @@ -138,7 +150,7 @@ except InvalidPlistException as e: pass try: - self.roundTrip({Data(six.b("hello world")):1}) + self.roundTrip({Data(b"hello world"):1}) self.fail("Data is not a valid key in Cocoa.") except InvalidPlistException as e: pass @@ -153,41 +165,45 @@ for edge in edges: cases = [edge, edge-1, edge+1, edge-2, edge+2, edge*2, edge/2] self.roundTrip(cases) - edges = [-pow(2, 7), pow(2, 7) - 1, -pow(2, 15), pow(2, 15) - 1, -pow(2, 31), pow(2, 31) - 1] + edges = [-pow(2, 7), pow(2, 7) - 1, + -pow(2, 15), pow(2, 15) - 1, + -pow(2, 31), pow(2, 31) - 1, + -pow(2, 63), pow(2, 64) - 1] self.roundTrip(edges) - io = six.BytesIO() - writer = PlistWriter(io) + ioBytes = io.BytesIO() + writer = PlistWriter(ioBytes) bytes = [(1, [pow(2, 7) - 1]), (2, [pow(2, 15) - 1]), (4, [pow(2, 31) - 1]), - (8, [-pow(2, 7), -pow(2, 15), -pow(2, 31), -pow(2, 63), pow(2, 63) - 1]) + (8, [-pow(2, 7), -pow(2, 15), -pow(2, 31), -pow(2, 63), pow(2, 63) - 1]), + (16, [pow(2, 64) - 1]) ] for bytelen, tests in bytes: for test in tests: got = writer.intSize(test) - self.assertEquals(bytelen, got, "Byte size is wrong. Expected %d, got %d" % (bytelen, got)) + self.assertEqual(bytelen, got, "Byte size is wrong. Expected %d, got %d" % (bytelen, got)) bytes_lists = [list(x) for x in bytes] self.roundTrip(bytes_lists) try: - self.roundTrip([0x8000000000000000, pow(2, 63)]) - self.fail("2^63 should be too large for Core Foundation to handle.") + self.roundTrip([0x10000000000000000, pow(2, 64)]) + self.fail("2^64 should be too large for Core Foundation to handle.") except InvalidPlistException as e: pass def testWriteData(self): - self.roundTrip(Data(six.b("woohoo"))) + self.roundTrip(Data(b"woohoo")) def testUnicode(self): - unicodeRoot = six.u("Mirror's Edge\u2122 for iPad") + unicodeRoot = unicode("Mirror's Edge\u2122 for iPad") writePlist(unicodeRoot, "/tmp/odd.plist") self.roundTrip(unicodeRoot) - unicodeStrings = [six.u("Mirror's Edge\u2122 for iPad"), six.u('Weightbot \u2014 Track your Weight in Style')] + unicodeStrings = [unicode("Mirror's Edge\u2122 for iPad"), unicode('Weightbot \u2014 Track your Weight in Style')] self.roundTrip(unicodeStrings) - self.roundTrip({six.u(""):six.u("")}, expected={six.b(''):six.b('')}) - self.roundTrip(six.u(""), expected=six.b('')) + self.roundTrip({unicode(""):unicode("")}, expected={b'':b''}) + self.roundTrip(unicode(""), expected=b'') def testUidWrite(self): self.roundTrip({'$version': 100000,
