commit python-serpent for openSUSE:Leap:15.2
Hello community, here is the log from the commit of package python-serpent for openSUSE:Leap:15.2 checked in at 2020-04-30 18:51:43 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Leap:15.2/python-serpent (Old) and /work/SRC/openSUSE:Leap:15.2/.python-serpent.new.2738 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Package is "python-serpent" Thu Apr 30 18:51:43 2020 rev:6 rq:795769 version:1.30.2 Changes: -------- --- /work/SRC/openSUSE:Leap:15.2/python-serpent/python-serpent.changes 2020-03-02 13:22:40.622317202 +0100 +++ /work/SRC/openSUSE:Leap:15.2/.python-serpent.new.2738/python-serpent.changes 2020-04-30 18:51:44.364636362 +0200 @@ -1,0 +2,12 @@ +Wed Mar 18 13:31:41 UTC 2020 - pgajdos@suse.com + +- version update to 1.30.2 + * upstream does not support python 2 anymore + * no changelog found + +------------------------------------------------------------------- +Sat Mar 14 07:12:14 UTC 2020 - Tomáš Chvátal <tchvatal@suse.com> + +- Fix building without python2 + +------------------------------------------------------------------- Old: ---- serpent-1.28.tar.gz New: ---- serpent-1.30.2.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-serpent.spec ++++++ --- /var/tmp/diff_new_pack.lQYeQk/_old 2020-04-30 18:51:45.896639598 +0200 +++ /var/tmp/diff_new_pack.lQYeQk/_new 2020-04-30 18:51:45.896639598 +0200 @@ -1,7 +1,7 @@ # # spec file for package python-serpent # -# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2020 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -17,27 +17,23 @@ %{?!python_module:%define python_module() python-%{**} python3-%{**}} +%define skip_python2 1 Name: python-serpent -Version: 1.28 +Version: 1.30.2 Release: 0 Summary: Serialization based on astliteral_eval License: MIT -Group: Development/Languages/Python URL: https://github.com/irmen/Serpent Source: https://files.pythonhosted.org/packages/source/s/serpent/serpent-%{version}.tar.gz BuildRequires: %{python_module setuptools} BuildRequires: fdupes -BuildRequires: python-enum34 BuildRequires: python-rpm-macros +BuildArch: noarch # SECTION test requirements BuildRequires: %{python_module attrs} BuildRequires: %{python_module pytest} BuildRequires: %{python_module pytz} # /SECTION -BuildArch: noarch -%ifpython2 -Requires: python-enum34 -%endif %python_subpackages %description ++++++ serpent-1.28.tar.gz -> serpent-1.30.2.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/serpent-1.28/PKG-INFO new/serpent-1.30.2/PKG-INFO --- old/serpent-1.28/PKG-INFO 2019-03-10 17:33:49.000000000 +0100 +++ new/serpent-1.30.2/PKG-INFO 2020-02-01 10:36:38.472208500 +0100 @@ -1,8 +1,8 @@ -Metadata-Version: 1.1 +Metadata-Version: 1.2 Name: serpent -Version: 1.28 +Version: 1.30.2 Summary: Serialization based on ast.literal_eval -Home-page: UNKNOWN +Home-page: https://github.com/irmen/Serpent Author: Irmen de Jong Author-email: irmen@razorvine.net License: MIT @@ -21,7 +21,7 @@ **API** - - ``ser_bytes = serpent.dumps(obj, indent=False, set_literals=True, module_in_classname=False):`` # serialize obj tree to bytes + - ``ser_bytes = serpent.dumps(obj, indent=False, module_in_classname=False):`` # serialize obj tree to bytes - ``obj = serpent.loads(ser_bytes)`` # deserialize bytes back into object tree - You can use ``ast.literal_eval`` yourself to deserialize, but ``serpent.deserialize`` works around a few corner cases. See source for details. @@ -41,7 +41,7 @@ Serpent allows comments in the serialized data (because it is just Python source code). Serpent can't serialize object graphs (when an object refers to itself); it will then crash with a ValueError pointing out the problem. - Works with Python 2.7+ (including 3.x), IronPython 2.7+, Jython 2.7+. + Works with Python 3.5+ **FAQ** @@ -63,9 +63,7 @@ .. code:: python - # This demo script is written for Python 3.2+ # -*- coding: utf-8 -*- - from __future__ import print_function import ast import uuid import datetime @@ -107,7 +105,7 @@ assert data2==data - When you run this (with python 3.2+) it prints: + When you run this it prints: .. code:: python @@ -150,9 +148,9 @@ Classifier: Natural Language :: English Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python -Classifier: Programming Language :: Python :: 2.7 -Classifier: Programming Language :: Python :: 3.4 Classifier: Programming Language :: Python :: 3.5 Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 Classifier: Topic :: Software Development +Requires-Python: >=3.2 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/serpent-1.28/README.md new/serpent-1.30.2/README.md --- old/serpent-1.28/README.md 2018-08-16 09:49:54.000000000 +0200 +++ new/serpent-1.30.2/README.md 2020-01-25 15:33:28.000000000 +0100 @@ -24,7 +24,8 @@ PYTHON ------ -Package can be found on Pypi as 'serpent': https://pypi.python.org/pypi/serpent +Compatible with Python 3.5+ (use a serpent version before 1.30 for Python 2.7 support) +It can be found on Pypi as 'serpent': https://pypi.python.org/pypi/serpent Example usage can be found in ./tests/example.py @@ -47,31 +48,23 @@ SOME MORE DETAILS ----------------- -Compatible with Python 2.7+ (including 3.x), IronPython 2.7+, Jython 2.7+. - Serpent handles several special Python types to make life easier: - - str --> promoted to unicode (see below why this is) - - bytes, bytearrays, memoryview, buffer --> string, base-64 + - bytes, bytearrays, memoryview --> string, base-64 (you'll have to manually un-base64 them though. Can use serpent.tobytes function) - uuid.UUID, datetime.{datetime, date, time, timespan} --> appropriate string/number - decimal.Decimal --> string (to not lose precision) - - array.array typecode 'c'/'u' --> string/unicode + - array.array typecode 'u' --> string - array.array other typecode --> list - Exception --> dict with some fields of the exception (message, args) - collections module types --> mostly equivalent primitive types or dict - - enums --> the value of the enum (Python 3.4+ or enum34 library) + - enums --> the value of the enum - namedtuple --> treated as just a tuple - attr dataclasses and python 3.7 native dataclasses: treated as just a class, so will become a dict - - all other types --> dict with the ``__getstate__`` or ``vars()`` of the object, and a ``__class__`` element with the name of the class + - all other types --> dict with the ``__getstate__`` or ``vars()`` of the object, and a ``__class__`` element with the name of the class Notes: -All str will be promoted to unicode. This is done because it is the -default anyway for Python 3.x, and it solves the problem of the str/unicode -difference between different Python versions. Also it means the serialized -output doesn't have those problematic 'u' prefixes on strings. - The serializer is not thread-safe. Make sure you're not making changes to the object tree that is being serialized, and don't use the same serializer in different threads. @@ -80,19 +73,7 @@ contain comments. Serpent does not add comments by itself apart from the single header line. -Set literals are not supported on python <3.2 (``ast.literal_eval`` -limitation). If you need Python < 3.2 compatibility, you'll have to use -``set_literals=False`` when serializing. Since version 1.6 serpent chooses -this wisely for you by default, but you can still override it if needed. - Floats +inf and -inf are handled via a trick, Float 'nan' cannot be handled and is represented by the special value: ``{'__class__':'float','value':'nan'}`` We chose not to encode it as just the string 'NaN' because that could cause memory issues when used in multiplications. - -Jython's ast module cannot properly parse some literal reprs of unicode strings. -This is a known bug http://bugs.jython.org/issue2008 -It seems to work when your server is Python 2.x but safest is perhaps to make -sure your data to parse contains only ascii strings when dealing with Jython. -Serpent checks for possible problems and will raise an error if it finds one, -rather than continuing with string data that might be incorrect. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/serpent-1.28/serpent.egg-info/PKG-INFO new/serpent-1.30.2/serpent.egg-info/PKG-INFO --- old/serpent-1.28/serpent.egg-info/PKG-INFO 2019-03-10 17:33:49.000000000 +0100 +++ new/serpent-1.30.2/serpent.egg-info/PKG-INFO 2020-02-01 10:36:38.000000000 +0100 @@ -1,8 +1,8 @@ -Metadata-Version: 1.1 +Metadata-Version: 1.2 Name: serpent -Version: 1.28 +Version: 1.30.2 Summary: Serialization based on ast.literal_eval -Home-page: UNKNOWN +Home-page: https://github.com/irmen/Serpent Author: Irmen de Jong Author-email: irmen@razorvine.net License: MIT @@ -21,7 +21,7 @@ **API** - - ``ser_bytes = serpent.dumps(obj, indent=False, set_literals=True, module_in_classname=False):`` # serialize obj tree to bytes + - ``ser_bytes = serpent.dumps(obj, indent=False, module_in_classname=False):`` # serialize obj tree to bytes - ``obj = serpent.loads(ser_bytes)`` # deserialize bytes back into object tree - You can use ``ast.literal_eval`` yourself to deserialize, but ``serpent.deserialize`` works around a few corner cases. See source for details. @@ -41,7 +41,7 @@ Serpent allows comments in the serialized data (because it is just Python source code). Serpent can't serialize object graphs (when an object refers to itself); it will then crash with a ValueError pointing out the problem. - Works with Python 2.7+ (including 3.x), IronPython 2.7+, Jython 2.7+. + Works with Python 3.5+ **FAQ** @@ -63,9 +63,7 @@ .. code:: python - # This demo script is written for Python 3.2+ # -*- coding: utf-8 -*- - from __future__ import print_function import ast import uuid import datetime @@ -107,7 +105,7 @@ assert data2==data - When you run this (with python 3.2+) it prints: + When you run this it prints: .. code:: python @@ -150,9 +148,9 @@ Classifier: Natural Language :: English Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python -Classifier: Programming Language :: Python :: 2.7 -Classifier: Programming Language :: Python :: 3.4 Classifier: Programming Language :: Python :: 3.5 Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 Classifier: Topic :: Software Development +Requires-Python: >=3.2 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/serpent-1.28/serpent.py new/serpent-1.30.2/serpent.py --- old/serpent-1.28/serpent.py 2019-03-10 17:23:39.000000000 +0100 +++ new/serpent-1.30.2/serpent.py 2020-02-01 10:26:12.000000000 +0100 @@ -7,29 +7,23 @@ machines over the network for instance (because only 'safe' literals are encoded). -Compatible with Python 2.7+ (including 3.x), IronPython 2.7+, Jython 2.7+. +Compatible with Python 3.5+ Serpent handles several special Python types to make life easier: - - str --> promoted to unicode (see below why this is) - - bytes, bytearrays, memoryview, buffer --> string, base-64 + - bytes, bytearrays, memoryview --> string, base-64 (you'll have to manually un-base64 them though) - uuid.UUID, datetime.{datetime, date, time, timespan} --> appropriate string/number - decimal.Decimal --> string (to not lose precision) - - array.array typecode 'c'/'u' --> string/unicode + - array.array typecode 'u' --> string - array.array other typecode --> list - Exception --> dict with some fields of the exception (message, args) - collections module types --> mostly equivalent primitive types or dict - - enums --> the value of the enum (Python 3.4+ or enum34 library) + - enums --> the value of the enum - all other types --> dict with __getstate__ or vars() of the object Notes: -All str will be promoted to unicode. This is done because it is the -default anyway for Python 3.x, and it solves the problem of the str/unicode -difference between different Python versions. Also it means the serialized -output doesn't have those problematic 'u' prefixes on strings. - The serializer is not thread-safe. Make sure you're not making changes to the object tree that is being serialized, and don't use the same serializer in different threads. @@ -37,34 +31,18 @@ Because the serialized format is just valid Python source code, it can contain comments. -Set literals are not supported on python <3.2 (ast.literal_eval -limitation). If you need Python < 3.2 compatibility, you'll have to use -set_literals=False when serializing. Since version 1.6 serpent chooses -this wisely for you by default, but you can still override it if needed. - Floats +inf and -inf are handled via a trick, Float 'nan' cannot be handled and is represented by the special value: {'__class__':'float','value':'nan'} We chose not to encode it as just the string 'NaN' because that could cause memory issues when used in multiplications. -Jython's ast module cannot properly parse some literal reprs of unicode strings. -This is a known bug http://bugs.jython.org/issue2008 -It seems to work when your server is Python 2.x but safest is perhaps to make -sure your data to parse contains only ascii strings when dealing with Jython. -Serpent checks for possible problems and will raise an error if it finds one, -rather than continuing with string data that might be incorrect. - Copyright by Irmen de Jong (irmen@razorvine.net) Software license: "MIT software license". See http://opensource.org/licenses/MIT """ -from __future__ import print_function, division -import __future__ import ast import base64 import sys -import types -import os import gc import decimal import datetime @@ -74,65 +52,31 @@ import numbers import codecs import collections -if sys.version_info >= (3, 4): - from collections.abc import KeysView, ValuesView, ItemsView - import enum -else: - from collections import KeysView, ValuesView, ItemsView - try: - import enum - except ImportError: - enum = None +import enum +from collections.abc import KeysView, ValuesView, ItemsView -__version__ = "1.28" +__version__ = "1.30.2" __all__ = ["dump", "dumps", "load", "loads", "register_class", "unregister_class", "tobytes"] -can_use_set_literals = sys.version_info >= (3, 2) # check if we can use set literals - -def dumps(obj, indent=False, set_literals=can_use_set_literals, module_in_classname=False): +def dumps(obj, indent=False, module_in_classname=False): """Serialize object tree to bytes""" - return Serializer(indent, set_literals, module_in_classname).serialize(obj) + return Serializer(indent, module_in_classname).serialize(obj) -def dump(obj, file, indent=False, set_literals=can_use_set_literals, module_in_classname=False): +def dump(obj, file, indent=False, module_in_classname=False): """Serialize object tree to a file""" - file.write(dumps(obj, indent=indent, set_literals=set_literals, module_in_classname=module_in_classname)) + file.write(dumps(obj, indent=indent, module_in_classname=module_in_classname)) def loads(serialized_bytes): """Deserialize bytes back to object tree. Uses ast.literal_eval (safe).""" - if os.name == "java": - if type(serialized_bytes) is memoryview: - serialized_bytes = serialized_bytes.tobytes() - elif type(serialized_bytes) is buffer: - serialized_bytes = serialized_bytes[:] - serialized = serialized_bytes.decode("utf-8") - elif sys.platform == "cli": - if type(serialized_bytes) is memoryview: - serialized_bytes = serialized_bytes.tobytes() - serialized = codecs.decode(serialized_bytes, "utf-8") - else: - serialized = codecs.decode(serialized_bytes, "utf-8") + serialized = codecs.decode(serialized_bytes, "utf-8") if '\x00' in serialized: raise ValueError("The serpent data contains 0-bytes so it cannot be parsed by ast.literal_eval. Has it been corrupted?") - if sys.version_info < (3, 0): - # python 2.x: parse with unicode_literals (promotes all strings to unicode) - # note: this doesn't work on jython... see bug http://bugs.jython.org/issue2008 - # so we add a safety net, to avoid working with incorrectly processed unicode strings - serialized = compile(serialized, "<serpent>", mode="eval", flags=ast.PyCF_ONLY_AST | __future__.unicode_literals.compiler_flag) - if os.name == "java": - for node in ast.walk(serialized): - if isinstance(node, ast.Str): - if isinstance(node.s, str) and any(c for c in node.s if c > '\x7f'): - # In this case there is risk of incorrectly parsed unicode data. Play safe and crash. - raise ValueError("cannot properly parse unicode string with ast in Jython, see bug http://bugs.jython.org/issue2008" - " - use python 2.x server or convert strings to ascii yourself first") - node.s = node.s.decode("unicode-escape") try: - if os.name != "java" and sys.platform != "cli": - gc.disable() + gc.disable() return ast.literal_eval(serialized) finally: gc.enable() @@ -164,12 +108,12 @@ _special_classes_registry[KeysView] = _ser_DictView _special_classes_registry[ValuesView] = _ser_DictView _special_classes_registry[ItemsView] = _ser_DictView - if sys.version_info >= (2, 7): - _special_classes_registry[collections.OrderedDict] = _ser_OrderedDict - if enum is not None: - def _ser_Enum(obj, serializer, outputstream, indentlevel): - serializer._serialize(obj.value, outputstream, indentlevel) - _special_classes_registry[enum.Enum] = _ser_Enum + _special_classes_registry[collections.OrderedDict] = _ser_OrderedDict + + def _ser_Enum(obj, serializer, outputstream, indentlevel): + serializer._serialize(obj.value, outputstream, indentlevel) + + _special_classes_registry[enum.Enum] = _ser_Enum _reset_special_classes_registry() @@ -199,12 +143,7 @@ self.data = data def __getstate__(self): - if sys.platform == "cli": - b64 = base64.b64encode(str(self.data)) # weird IronPython bug? - elif (os.name == "java" or sys.version_info < (2, 7)) and type(self.data) is bytearray: - b64 = base64.b64encode(bytes(self.data)) # Jython bug http://bugs.jython.org/issue2011 - else: - b64 = base64.b64encode(self.data) + b64 = base64.b64encode(self.data) return { "data": b64 if type(b64) is str else b64.decode("ascii"), "encoding": "base64" @@ -222,45 +161,27 @@ def from_memoryview(data): return BytesWrapper(data.tobytes()) - @staticmethod - def from_buffer(data): - return BytesWrapper(data) - -_repr_types = set([ - str, - int, - bool, - type(None) -]) +_repr_types = {str, int, bool, type(None)} _translate_types = { bytes: BytesWrapper.from_bytes, bytearray: BytesWrapper.from_bytearray, collections.deque: list, + collections.UserDict: dict, + collections.UserList: list, + collections.UserString: str } -if sys.version_info >= (3, 0): - _translate_types.update({ - collections.UserDict: dict, - collections.UserList: list, - collections.UserString: str - }) - _bytes_types = [bytes, bytearray, memoryview] # do some dynamic changes to the types configuration if needed if bytes is str: del _translate_types[bytes] -if hasattr(types, "BufferType"): - _translate_types[types.BufferType] = BytesWrapper.from_buffer - _bytes_types.append(buffer) try: _translate_types[memoryview] = BytesWrapper.from_memoryview except NameError: pass -if sys.platform == "cli": - _repr_types.remove(str) # IronPython needs special str treatment, otherwise it treats unicode wrong _bytes_types = tuple(_bytes_types) @@ -290,16 +211,14 @@ """ dispatch = {} - def __init__(self, indent=False, set_literals=can_use_set_literals, module_in_classname=False): + def __init__(self, indent=False, module_in_classname=False): """ Initialize the serializer. indent=indent the output over multiple lines (default=false) - setLiterals=use set-literals or not (set to False if you need compatibility with Python < 3.2). Serpent chooses a sensible default for you. module_in_classname = include module prefix for class names or only use the class name itself """ self.indent = indent - self.set_literals = set_literals self.module_in_classname = module_in_classname self.serialized_obj_ids = set() self.special_classes_registry_copy = None @@ -308,17 +227,10 @@ def serialize(self, obj): """Serialize the object tree to bytes.""" self.special_classes_registry_copy = _special_classes_registry.copy() # make it thread safe - header = "# serpent utf-8 " - if self.set_literals: - header += "python3.2\n" # set-literals require python 3.2+ to deserialize (ast.literal_eval limitation) - else: - header += "python2.6\n" # don't change this, otherwise we can't read older serpent strings + header = "# serpent utf-8 python3.2\n" out = [header] - if os.name == "java" and type(obj) is buffer: - obj = bytearray(obj) try: - if os.name != "java" and sys.platform != "cli": - gc.disable() + gc.disable() self.serialized_obj_ids = set() self._serialize(obj, out, 0) finally: @@ -327,7 +239,7 @@ del self.serialized_obj_ids return "".join(out).encode("utf-8") - _shortcut_dispatch_types = frozenset([float, complex, tuple, list, dict, set, frozenset]) + _shortcut_dispatch_types = {float, complex, tuple, list, dict, set, frozenset} def _serialize(self, obj, out, level): if level > self.maximum_level: @@ -363,11 +275,6 @@ func = Serializer.ser_default_class func(self, obj, out, level) - def ser_builtins_str(self, str_obj, out, level): - # special case str, for IronPython where str==unicode and repr() yields undesired result - self.ser_builtins_unicode(str_obj, out, level) - dispatch[str] = ser_builtins_str - def ser_builtins_float(self, float_obj, out, level): if math.isnan(float_obj): # there's no literal expression for a float NaN... @@ -391,21 +298,6 @@ out.append("j)") dispatch[complex] = ser_builtins_complex - if sys.version_info < (3, 0): - # this method is used for python 2.x unicode (python 3.x doesn't use this) - def ser_builtins_unicode(self, unicode_obj, out, level): - z = repr(unicode_obj) - if z[0] == 'u': - z = z[1:] # get rid of the unicode 'u' prefix - out.append(z) - dispatch[unicode] = ser_builtins_unicode - - if sys.version_info < (3, 0): - def ser_builtins_long(self, long_obj, out, level): - # used with python 2.x - out.append(str(long_obj)) - dispatch[long] = ser_builtins_long - def ser_builtins_tuple(self, tuple_obj, out, level): append = out.append serialize = self._serialize @@ -460,9 +352,7 @@ def _check_hashable_type(self, t): if t not in (bool, bytes, str, tuple) and not issubclass(t, numbers.Number): - if enum is not None and issubclass(t, enum.Enum): - return - elif sys.version_info < (3, 0) and t is unicode: + if issubclass(t, enum.Enum): return raise TypeError("one of the keys in a dict or set is not of a primitive hashable type: " + str(t) + ". Use simple types as keys or use a list or tuple as container.") @@ -506,11 +396,6 @@ dispatch[dict] = ser_builtins_dict def ser_builtins_set(self, set_obj, out, level): - if not self.set_literals: - if self.indent: - set_obj = sorted(set_obj) - self._serialize(tuple(set_obj), out, level) # use a tuple instead of a set literal - return append = out.append serialize = self._serialize if self.indent and set_obj: @@ -558,14 +443,9 @@ out.append(repr(date_obj.isoformat())) dispatch[datetime.date] = ser_datetime_date - if os.name == "java" or sys.version_info < (2, 7): # jython bug http://bugs.jython.org/issue2010 - def ser_datetime_timedelta(self, timedelta_obj, out, level): - secs = ((timedelta_obj.days * 86400 + timedelta_obj.seconds) * 10 ** 6 + timedelta_obj.microseconds) / 10 ** 6 - out.append(repr(secs)) - else: - def ser_datetime_timedelta(self, timedelta_obj, out, level): - secs = timedelta_obj.total_seconds() - out.append(repr(secs)) + def ser_datetime_timedelta(self, timedelta_obj, out, level): + secs = timedelta_obj.total_seconds() + out.append(repr(secs)) dispatch[datetime.timedelta] = ser_datetime_timedelta def ser_datetime_time(self, time_obj, out, level): @@ -587,9 +467,7 @@ dispatch[BaseException] = ser_exception_class def ser_array_array(self, array_obj, out, level): - if array_obj.typecode == 'c': - self._serialize(array_obj.tostring(), out, level) - elif array_obj.typecode == 'u': + if array_obj.typecode == 'u': self._serialize(array_obj.tounicode(), out, level) else: self._serialize(array_obj.tolist(), out, level) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/serpent-1.28/setup.cfg new/serpent-1.30.2/setup.cfg --- old/serpent-1.28/setup.cfg 2019-03-10 17:33:49.000000000 +0100 +++ new/serpent-1.30.2/setup.cfg 2020-02-01 10:36:38.472208500 +0100 @@ -1,5 +1,5 @@ [wheel] -universal = 1 +universal = 0 [bdist_rpm] doc_files = LICENSE diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/serpent-1.28/setup.py new/serpent-1.30.2/setup.py --- old/serpent-1.28/setup.py 2019-03-08 23:02:46.000000000 +0100 +++ new/serpent-1.30.2/setup.py 2020-02-01 10:25:57.000000000 +0100 @@ -1,6 +1,5 @@ # -*- coding: utf-8 -*- # Serpent: ast.literal_eval() compatible object tree serialization. -# Copyright 2013, Irmen de Jong (irmen@razorvine.net) # Software license: "MIT software license". See http://opensource.org/licenses/MIT try: @@ -12,8 +11,15 @@ import unittest import re +import sys + serpent_version = re.search(r'^__version__\s*=\s*"(.+)"', open("serpent.py", "rt").read(), re.MULTILINE).groups()[0] +if sys.version_info < (3, 2): + raise RuntimeError("This version of serpent ({}) doesn't support this obsolete Python version {}.{}. " + "Either upgrade to a recent Python version or downgrade serpent to a version before 1.30" + .format(serpent_version, sys.version_info.major, sys.version_info.minor)) + def serpent_test_suite(): testloader = unittest.TestLoader() @@ -25,9 +31,11 @@ name='serpent', version=serpent_version, py_modules=["serpent"], + python_requires='>=3.2', license='MIT', author='Irmen de Jong', author_email='irmen@razorvine.net', + url='https://github.com/irmen/Serpent', description='Serialization based on ast.literal_eval', long_description=""" Serpent is a simple serialization library based on ast.literal_eval. @@ -44,7 +52,7 @@ **API** -- ``ser_bytes = serpent.dumps(obj, indent=False, set_literals=True, module_in_classname=False):`` # serialize obj tree to bytes +- ``ser_bytes = serpent.dumps(obj, indent=False, module_in_classname=False):`` # serialize obj tree to bytes - ``obj = serpent.loads(ser_bytes)`` # deserialize bytes back into object tree - You can use ``ast.literal_eval`` yourself to deserialize, but ``serpent.deserialize`` works around a few corner cases. See source for details. @@ -64,7 +72,7 @@ Serpent allows comments in the serialized data (because it is just Python source code). Serpent can't serialize object graphs (when an object refers to itself); it will then crash with a ValueError pointing out the problem. -Works with Python 2.7+ (including 3.x), IronPython 2.7+, Jython 2.7+. +Works with Python 3.5+ **FAQ** @@ -86,9 +94,7 @@ .. code:: python - # This demo script is written for Python 3.2+ # -*- coding: utf-8 -*- - from __future__ import print_function import ast import uuid import datetime @@ -130,7 +136,7 @@ assert data2==data -When you run this (with python 3.2+) it prints: +When you run this it prints: .. code:: python @@ -175,13 +181,11 @@ "Natural Language :: English", "Operating System :: OS Independent", "Programming Language :: Python", - "Programming Language :: Python :: 2.7", - "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", "Topic :: Software Development" ], - tests_require=['enum34; python_version < "3.4"'], test_suite="setup.serpent_test_suite" ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/serpent-1.28/tests/example.py new/serpent-1.30.2/tests/example.py --- old/serpent-1.28/tests/example.py 2018-08-16 09:49:54.000000000 +0200 +++ new/serpent-1.30.2/tests/example.py 2020-01-21 23:56:10.000000000 +0100 @@ -1,38 +1,37 @@ -from __future__ import print_function -import datetime -import serpent - - -class CustomClass(object): - def __init__(self, name, age): - self.name = name - self.age = age - - -def example(): - data = { - "tuple": (1, 2, 3), - "date": datetime.datetime.now(), - "set": set(['a', 'b', 'c']), - "class": CustomClass("Sally", 26) - } - - # serialize the object - ser = serpent.dumps(data, indent=True) - # print it to the screen, but usually you'd save the bytes to a file or transfer them over a network connection - print("Serialized data:") - print(ser.decode("UTF-8")) - - # deserialize the bytes and print the objects - obj = serpent.loads(ser) - print("Deserialized data:") - print("tuple:", obj["tuple"]) - print("date:", obj["date"]) - print("set:", obj["set"]) - clazz = obj["class"] - print("class attributes: type={0} name={1} age={2}".format( - clazz["__class__"], clazz["name"], clazz["age"])) - - -if __name__ == "__main__": - example() +import datetime +import serpent + + +class CustomClass(object): + def __init__(self, name, age): + self.name = name + self.age = age + + +def example(): + data = { + "tuple": (1, 2, 3), + "date": datetime.datetime.now(), + "set": {'a', 'b', 'c'}, + "class": CustomClass("Sally", 26) + } + + # serialize the object + ser = serpent.dumps(data, indent=True) + # print it to the screen, but usually you'd save the bytes to a file or transfer them over a network connection + print("Serialized data:") + print(ser.decode("UTF-8")) + + # deserialize the bytes and print the objects + obj = serpent.loads(ser) + print("Deserialized data:") + print("tuple:", obj["tuple"]) + print("date:", obj["date"]) + print("set:", obj["set"]) + clazz = obj["class"] + print("class attributes: type={0} name={1} age={2}".format( + clazz["__class__"], clazz["name"], clazz["age"])) + + +if __name__ == "__main__": + example() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/serpent-1.28/tests/performance.py new/serpent-1.30.2/tests/performance.py --- old/serpent-1.28/tests/performance.py 2018-08-16 09:49:54.000000000 +0200 +++ new/serpent-1.30.2/tests/performance.py 2020-01-21 23:45:44.000000000 +0100 @@ -3,7 +3,6 @@ Compares results based on size of the output, and time taken to (de)serialize. """ -from __future__ import print_function from timeit import default_timer as perf_timer import sys import datetime diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/serpent-1.28/tests/test_serpent.py new/serpent-1.30.2/tests/test_serpent.py --- old/serpent-1.28/tests/test_serpent.py 2019-03-08 22:58:27.000000000 +0100 +++ new/serpent-1.30.2/tests/test_serpent.py 2020-01-22 00:06:22.000000000 +0100 @@ -1,11 +1,7 @@ """ Serpent: ast.literal_eval() compatible object tree serialization. - -Copyright 2013, Irmen de Jong (irmen@razorvine.net) Software license: "MIT software license". See http://opensource.org/licenses/MIT """ -from __future__ import print_function, division -import __future__ import sys import ast import timeit @@ -19,33 +15,16 @@ import traceback import threading import time -import types import collections import enum import attr -if sys.version_info >= (3, 4): - from collections.abc import KeysView, ValuesView, ItemsView -else: - from collections import KeysView, ValuesView, ItemsView - -if sys.version_info < (2, 7): - import unittest2 as unittest -else: - import unittest - +import unittest +from collections.abc import KeysView, ValuesView, ItemsView import serpent -if sys.version_info >= (3, 0): - unicode = str - unichr = chr - - def strip_header(ser): - if sys.platform == "cli": - _, _, data = ser.partition("\n") - else: - _, _, data = ser.partition(b"\n") + _, _, data = ser.partition(b"\n") return data @@ -54,13 +33,12 @@ data = serpent.loads(b"555") self.assertEqual(555, data) - def test_deserialize_unichr(self): + def test_deserialize_chr(self): unicodestring = u"euro\u20ac" encoded = repr(unicodestring).encode("utf-8") data = serpent.loads(encoded) self.assertEqual(unicodestring, data) - @unittest.skipIf(sys.version_info < (3, 0), "Python 2.x ast can't parse complex") def test_weird_complex(self): c1 = complex(float('inf'), 4) ser = serpent.dumps(c1) @@ -77,10 +55,9 @@ v = serpent.loads(b"{'a':1, 'b':2, 'c':3,}") self.assertEqual({'a': 1, 'b': 2, 'c': 3}, v) - @unittest.skipIf(sys.version_info < (3, 2), "needs python 3.3+ to parse set literals") def test_trailing_comma_set(self): v = serpent.loads(b"{1,2,3,}") - self.assertEqual(set([1, 2, 3]), v) + self.assertEqual({1, 2, 3}, v) def test_unicode_escapes(self): v = serpent.loads(b"'\\u20ac'") @@ -95,9 +72,6 @@ self.assertEqual("text", serpent.loads(bytes_input)) self.assertEqual("text", serpent.loads(bytearray_input)) self.assertEqual("text", serpent.loads(memview_input)) - if sys.version_info < (3, 0): - buffer_input = buffer(bytes_input) - self.assertEqual("text", serpent.loads(buffer_input)) class TestBasics(unittest.TestCase): @@ -109,35 +83,19 @@ self.assertEqual(data, result, "must understand python 2.x repr form of unicode string") py3repr = b"# serpent utf-8 python3.2\n'hello\xe2\x82\xac'" try: - result = serpent.loads(py3repr) # jython fails this test. - if os.name != "java": - self.assertEqual(data, result, "must understand python 3.x repr form of unicode string") - except ValueError as x: - if os.name == "java": - self.assertIn("issue2008", str(x)) - else: - self.fail("non-jython must parse it correctly") + result = serpent.loads(py3repr) + self.assertEqual(data, result, "must understand python 3.x repr form of unicode string") + except ValueError: + self.fail("must parse it correctly") def test_header(self): - ser = serpent.dumps(None, set_literals=True) - if sys.platform == "cli": - header, _, rest = ser.partition("\n") - else: - self.assertTrue(type(ser) is bytes) - header, _, rest = ser.partition(b"\n") + ser = serpent.dumps(None) + header, _, rest = ser.partition(b"\n") hdr = "# serpent utf-8 python3.2".encode("utf-8") self.assertEqual(hdr, header) - ser = serpent.dumps(None, set_literals=False) - if sys.platform == "cli": - header, _, rest = ser.partition("\n") - else: - self.assertTrue(type(ser) is bytes) - header, _, rest = ser.partition(b"\n") - hdr = "# serpent utf-8 python2.6".encode("utf-8") # don't change the 2.6 here even though we don't support python 2.6 any longer - self.assertEqual(hdr, header) def test_comments(self): - ser = b"""# serpent utf-8 python2.7 + ser = b"""# serpent utf-8 python3.2 [ 1, 2, # some comments here 3, 4] # more here @@ -163,32 +121,32 @@ ser = serpent.dumps(obj) data = strip_header(ser) self.assertEqual(36, len(data)) - obj = set([3, 4, 2, 1, 6, 5]) + obj = {3, 4, 2, 1, 6, 5} ser = serpent.dumps(obj) data = strip_header(ser) self.assertEqual(13, len(data)) - ser = serpent.dumps(obj, indent=True, set_literals=True) + ser = serpent.dumps(obj, indent=True) data = strip_header(ser) self.assertEqual(b"{\n 1,\n 2,\n 3,\n 4,\n 5,\n 6\n}", data) # sorted - obj = set([3, "something"]) - ser = serpent.dumps(obj, indent=False, set_literals=True) + obj = {3, "something"} + ser = serpent.dumps(obj, indent=False) data = strip_header(ser) self.assertTrue(data == b"{3,'something'}" or data == b"{'something',3}") - ser = serpent.dumps(obj, indent=True, set_literals=True) + ser = serpent.dumps(obj, indent=True) data = strip_header(ser) self.assertTrue(data == b"{\n 3,\n 'something'\n}" or data == b"{\n 'something',\n 3\n}") obj = {3: "three", "something": 99} - ser = serpent.dumps(obj, indent=False, set_literals=True) + ser = serpent.dumps(obj, indent=False) data = strip_header(ser) self.assertTrue(data == b"{'something':99,3:'three'}" or data == b"{3:'three','something':99}") - ser = serpent.dumps(obj, indent=True, set_literals=True) + ser = serpent.dumps(obj, indent=True) data = strip_header(ser) self.assertTrue(data == b"{\n 'something': 99,\n 3: 'three'\n}" or data == b"{\n 3: 'three',\n 'something': 99\n}") obj = {3: "three", 4: "four", 5: "five", 2: "two", 1: "one"} - ser = serpent.dumps(obj, indent=True, set_literals=True) + ser = serpent.dumps(obj, indent=True) data = strip_header(ser) self.assertEqual(b"{\n 1: 'one',\n 2: 'two',\n 3: 'three',\n 4: 'four',\n 5: 'five'\n}", data) # sorted @@ -239,8 +197,8 @@ data = serpent.loads(ser) self.assertEqual(" ", data) - def test_nullbytesunicode(self): - line = unichr(0) + "null" + def test_nullbytesstr(self): + line = chr(0) + "null" ser = serpent.dumps(line) data = strip_header(ser) self.assertEqual(b"'\\x00null'", data, "must escape 0-byte") @@ -263,10 +221,9 @@ serpent.loads(bytearray(b"'contains no nullbyte'")) serpent.loads(memoryview(b"'contains no nullbyte'")) - @unittest.skipIf(os.name == "java", "jython can't parse unicode U's") def test_unicode_U(self): - u = "euro" + unichr(0x20ac)+"\U00022001" - self.assertTrue(type(u) is unicode) + u = "euro" + chr(0x20ac)+"\U00022001" + self.assertTrue(type(u) is str) ser = serpent.dumps(u) data = serpent.loads(ser) self.assertEqual(u, data) @@ -275,34 +232,22 @@ # this checks for all 0x0000-0xffff chars that they will be serialized # into a proper repr form and when processed back by ast.literal_parse directly # will get turned back into the chars 0x0000-0xffff again - # For Jython we take the range upto 0x4100 because after that it starts - # complaining about surrogates or "mark invalid" (an utf-8 parsing bug it seems) - highest_char = 0x4100 if os.name == "java" else 0xffff - all_chars = u"".join(unichr(c) for c in range(highest_char+1)) + highest_char = 0xffff + all_chars = u"".join(chr(c) for c in range(highest_char+1)) ser = serpent.dumps(all_chars) self.assertGreater(len(ser), len(all_chars)) ser = ser.decode("utf-8") - if sys.version_info < (3, 0): - ser = compile(ser, "<serpent>", mode="eval", flags=ast.PyCF_ONLY_AST | __future__.unicode_literals.compiler_flag) - if os.name == "java": - # The ast module in Jython will not have parsed this correctly into unicode literals. - # So we have to patch up the ast tree ourselves and decode Str nodes to unicode manually. - # (this is the same what Serpent does internally so we replicate it here) - # See http://bugs.jython.org/issue2008 - for node in ast.walk(ser): - if isinstance(node, ast.Str): - node.s = node.s.decode("unicode-escape") data = ast.literal_eval(ser) self.assertEqual(highest_char+1, len(data)) for i, c in enumerate(data): - if unichr(i) != c: + if chr(i) != c: self.fail("char different for "+str(i)) def test_unicode_quotes(self): - ser = serpent.dumps(unicode("quotes'\"")) + ser = serpent.dumps(str("quotes'\"")) data = strip_header(ser) self.assertEqual(b"'quotes\\'\"'", data) - ser = serpent.dumps(unicode("quotes2'")) + ser = serpent.dumps(str("quotes2'")) data = strip_header(ser) self.assertEqual(b"\"quotes2'\"", data) @@ -310,44 +255,22 @@ u = u"\x00\x01\x80\x81\xfe\xffabcdef\u20ac" utf_8_correct = repr(u).encode("utf-8") if utf_8_correct.startswith(b"u"): - utf_8_correct=utf_8_correct[1:] + utf_8_correct = utf_8_correct[1:] ser = serpent.dumps(u) d = strip_header(ser) self.assertEqual(utf_8_correct, d) - @unittest.skipIf(sys.version_info >= (3, 0), "py2 escaping tested") - def test_unicode_with_escapes_py2(self): - ser = serpent.dumps(unicode("\n")) - d = strip_header(ser) - self.assertEqual(b"'\\n'", d) - ser = serpent.dumps(unicode("\a")) - d = strip_header(ser) - self.assertEqual(b"'\\x07'", d) - - @unittest.skipIf(sys.version_info >= (3, 0), "py2 escaping tested") - def test_unicode_with_escapes_unichrs(self): - ser = serpent.dumps("\a"+unichr(0x20ac)) - d = strip_header(ser) - self.assertEqual(b"'\\x07\\u20ac'", d) - line = "'euro" + unichr(0x20ac) + "\nlastline\ttab\\@slash\a\b\f\n\r\t\v'" - ser = serpent.dumps(line) - d = strip_header(ser) - self.assertEqual(b"\"'euro\\u20ac\\nlastline\\ttab\\\\@slash\\x07\\x08\\x0c\\n\\r\\t\\x0b'\"", d) - data = serpent.loads(ser) - self.assertEqual(line, data) - - @unittest.skipIf(sys.version_info < (3, 0), "py3 escaping tested") def test_unicode_with_escapes_py3(self): - ser = serpent.dumps(unicode("\n")) + ser = serpent.dumps(str("\n")) d = strip_header(ser) self.assertEqual(b"'\\n'", d) - ser = serpent.dumps(unicode("\a")) + ser = serpent.dumps(str("\a")) d = strip_header(ser) self.assertEqual(b"'\\x07'", d) - ser = serpent.dumps("\a"+unichr(0x20ac)) + ser = serpent.dumps("\a"+chr(0x20ac)) d = strip_header(ser) self.assertEqual(b"'\\x07\xe2\x82\xac'", d) - line = "'euro" + unichr(0x20ac) + "\nlastline\ttab\\@slash\a\b\f\n\r\t\v'" + line = "'euro" + chr(0x20ac) + "\nlastline\ttab\\@slash\a\b\f\n\r\t\v'" ser = serpent.dumps(line) d = strip_header(ser) self.assertEqual(b"\"'euro\xe2\x82\xac\\nlastline\\ttab\\\\@slash\\x07\\x08\\x0c\\n\\r\\t\\x0b'\"", d) @@ -399,31 +322,23 @@ ser = serpent.dumps(mydict) data = strip_header(ser) self.assertEqual(69, len(data)) - if sys.version_info < (3, 0): - self.assertEqual(b"{", data[0]) - self.assertEqual(b"}", data[-1]) - else: - self.assertEqual(ord("{"), data[0]) - self.assertEqual(ord("}"), data[-1]) + self.assertEqual(ord("{"), data[0]) + self.assertEqual(ord("}"), data[-1]) ser = serpent.dumps(mydict, indent=True) data = strip_header(ser) self.assertEqual(86, len(data)) - if sys.version_info < (3, 0): - self.assertEqual(b"{", data[0]) - self.assertEqual(b"}", data[-1]) - else: - self.assertEqual(ord("{"), data[0]) - self.assertEqual(ord("}"), data[-1]) + self.assertEqual(ord("{"), data[0]) + self.assertEqual(ord("}"), data[-1]) - def test_dict_unicode(self): - data = {"key": unicode("value")} + def test_dict_str(self): + data = {"key": str("value")} ser = serpent.dumps(data) data2 = serpent.loads(ser) - self.assertEqual(unicode("value"), data2["key"]) - data = {unicode("key"): 123} + self.assertEqual(str("value"), data2["key"]) + data = {str("key"): 123} ser = serpent.dumps(data) data2 = serpent.loads(ser) - self.assertEqual(123, data2[unicode("key")]) + self.assertEqual(123, data2[str("key")]) def test_dict_iters(self): data = {"john": 22, "sophie": 34, "bob": 26} @@ -493,43 +408,31 @@ self.assertEqual(b"()", data) # test set-literals - myset = set([42, "Sally"]) - ser = serpent.dumps(myset, set_literals=True) + myset = {42, "Sally"} + ser = serpent.dumps(myset) data = strip_header(ser) self.assertTrue(data == b"{42,'Sally'}" or data == b"{'Sally',42}") - ser = serpent.dumps(myset, indent=True, set_literals=True) + ser = serpent.dumps(myset, indent=True) data = strip_header(ser) self.assertTrue(data == b"{\n 42,\n 'Sally'\n}" or data == b"{\n 'Sally',\n 42\n}") - - # test no set-literals - ser = serpent.dumps(myset, set_literals=False) - data = strip_header(ser) - self.assertTrue(data == b"(42,'Sally')" or data == b"('Sally',42)") # must output a tuple instead of a set-literal - # unicode elements - data = set([unicode("text1"), unicode("text2")]) + data = {str("text1"), str("text2")} ser = serpent.dumps(data) data2 = serpent.loads(ser) self.assertEqual(2, len(data2)) - self.assertIn(unicode("text1"), data2) - self.assertIn(unicode("text2"), data2) + self.assertIn(str("text1"), data2) + self.assertIn(str("text2"), data2) def test_bytes(self): - if sys.version_info >= (3, 0): - ser = serpent.dumps(bytes(b"abcdef")) - data = serpent.loads(ser) - self.assertEqual({'encoding': 'base64', 'data': 'YWJjZGVm'}, data) + ser = serpent.dumps(bytes(b"abcdef")) + data = serpent.loads(ser) + self.assertEqual({'encoding': 'base64', 'data': 'YWJjZGVm'}, data) ser = serpent.dumps(bytearray(b"abcdef")) data = serpent.loads(ser) self.assertEqual({'encoding': 'base64', 'data': 'YWJjZGVm'}, data) - if sys.version_info >= (2, 7): - ser = serpent.dumps(memoryview(b"abcdef")) - data = serpent.loads(ser) - self.assertEqual({'encoding': 'base64', 'data': 'YWJjZGVm'}, data) - if sys.version_info < (3, 0): - ser = serpent.dumps(buffer(b"abcdef")) - data = serpent.loads(ser) - self.assertEqual({'encoding': 'base64', 'data': 'YWJjZGVm'}, data) + ser = serpent.dumps(memoryview(b"abcdef")) + data = serpent.loads(ser) + self.assertEqual({'encoding': 'base64', 'data': 'YWJjZGVm'}, data) def test_exception(self): x = ZeroDivisionError("wrong") @@ -564,12 +467,8 @@ x = ZeroDivisionError("wrong") ser = serpent.dumps(x, module_in_classname=True) data = serpent.loads(ser) - if sys.version_info < (3, 0): - expected_classname = "exceptions.ZeroDivisionError" - else: - expected_classname = "builtins.ZeroDivisionError" self.assertEqual({ - '__class__': expected_classname, + '__class__': "builtins.ZeroDivisionError", '__exception__': True, 'args': ('wrong',), 'attributes': {} @@ -626,7 +525,6 @@ serpent.dumps({1: 1, 2: 1, 3: 1, pp: 1}) # can only serialize simple types as dict keys (hashable) self.assertTrue("hashable type" in str(x.exception)) - @unittest.skipIf(not serpent.can_use_set_literals, reason="no problem if serpent doesn't serializes set literals") def test_class_hashable_set_element_check(self): import pprint pp = pprint.PrettyPrinter(stream="dummy", width=42) @@ -644,28 +542,21 @@ BLUE = 3 data = serpent.dumps({"abc", Color.RED, Color.GREEN, Color.BLUE}) orig = serpent.loads(data) - if sys.version_info < (3, 4): - self.assertEqual([1, 2, 3, u"abc"], sorted(orig)) - else: - self.assertEqual({"abc", 1, 2, 3}, orig) + self.assertEqual({"abc", 1, 2, 3}, orig) data = serpent.dumps({"abc": 1, Color.RED: 1, Color.GREEN: 1, Color.BLUE: 1}) orig = serpent.loads(data) - if sys.version_info < (3, 4): - self.assertEqual({u"abc": 1, 1: 1, 2: 1, 3: 1}, orig) - else: - self.assertEqual({"abc": 1, 1: 1, 2: 1, 3: 1}, orig) + self.assertEqual({"abc": 1, 1: 1, 2: 1, 3: 1}, orig) def test_array(self): - ser = serpent.dumps(array.array('u', unicode("unicode"))) + ser = serpent.dumps(array.array('u', str("unicode"))) data = strip_header(ser) self.assertEqual(b"'unicode'", data) ser = serpent.dumps(array.array('i', [44, 45, 46])) data = strip_header(ser) self.assertEqual(b"[44,45,46]", data) - if sys.version_info < (3, 0): - ser = serpent.dumps(array.array('c', "normal")) - data = strip_header(ser) - self.assertEqual(b"'normal'", data) + ser = serpent.dumps(array.array('u', "normal")) + data = strip_header(ser) + self.assertEqual(b"'normal'", data) def test_time(self): ser = serpent.dumps(datetime.datetime(2013, 1, 20, 23, 59, 45, 999888)) @@ -707,7 +598,7 @@ serpent.loads(ser) tmpfn = tempfile.mktemp() with open(tmpfn, "wb") as outf: - serpent.dump([1, 2, 3], outf, indent=True, set_literals=True) + serpent.dump([1, 2, 3], outf, indent=True) with open(tmpfn, "rb") as inf: data = serpent.load(inf) self.assertEqual([1, 2, 3], data) @@ -719,7 +610,7 @@ ser = strip_header(serpent.dumps(values)) self.assertEqual(b"[1e30000,-1e30000,{'__class__':'float','value':'nan'},(1e30000+4.0j)]", ser) values2 = serpent.loads(ser) - self.assertEqual([float('inf'), float('-inf'), {'__class__':'float','value':'nan'}, (float('inf')+4j)], values2) + self.assertEqual([float('inf'), float('-inf'), {'__class__': 'float', 'value': 'nan'}, (float('inf')+4j)], values2) values2 = serpent.loads(b"[1e30000,-1e30000]") self.assertEqual([float('inf'), float('-inf')], values2) @@ -761,16 +652,10 @@ self.assertIs(obj, serpent.tobytes(obj)) obj = bytearray(b"test") self.assertIs(obj, serpent.tobytes(obj)) - if hasattr(types, "BufferType"): - obj = buffer(b"test") - self.assertIs(obj, serpent.tobytes(obj)) ser = {'data': 'dGVzdA==', 'encoding': 'base64'} out = serpent.tobytes(ser) self.assertEqual(b"test", out) - if sys.platform == 'cli': - self.assertIsInstance(out, str) # ironpython base64 decodes into str type.... - else: - self.assertIsInstance(out, bytes) + self.assertIsInstance(out, bytes) with self.assertRaises(TypeError): serpent.tobytes({'@@@data': 'dGVzdA==', 'encoding': 'base64'}) with self.assertRaises(TypeError): @@ -788,12 +673,12 @@ def setUp(self): self.data = { "str": "hello", - "unicode": unichr(0x20ac), # euro-character + "unicode": chr(0x20ac), # euro-character "numbers": [123456789012345678901234567890, 999.1234, decimal.Decimal("1.99999999999999999991")], "bytes": bytearray(100), "list": [1, 2, 3, 4, 5, 6, 7, 8, 1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9], "tuple": (1, 2, 3, 4, 5, 6, 7, 8), - "set": set([1, 2, 3, 4, 5, 6, 7, 8, 9]), + "set": {1, 2, 3, 4, 5, 6, 7, 8, 9}, "dict": dict((i, str(i) * 4) for i in range(10)), "exc": ZeroDivisionError("fault"), "dates": [ @@ -868,21 +753,21 @@ 2, 3 )""", ser) - data = set([1]) - ser = serpent.dumps(data, indent=True, set_literals=True).decode("utf-8") + data = {1} + ser = serpent.dumps(data, indent=True).decode("utf-8") _, _, ser = ser.partition("\n") self.assertEqual("""{ 1 }""", ser) data = {"one": 1} - ser = serpent.dumps(data, indent=True, set_literals=True).decode("utf-8") + ser = serpent.dumps(data, indent=True).decode("utf-8") _, _, ser = ser.partition("\n") self.assertEqual("""{ 'one': 1 }""", ser) - data = {"first": [1, 2, ("a", "b")], "second": {1: False}, "third": set([1, 2])} - ser = serpent.dumps(data, indent=True, set_literals=True).decode("utf-8") + data = {"first": [1, 2, ("a", "b")], "second": {1: False}, "third": {1, 2}} + ser = serpent.dumps(data, indent=True).decode("utf-8") _, _, ser = ser.partition("\n") self.assertEqual("""{ 'first': [ @@ -905,8 +790,6 @@ class TestFiledump(unittest.TestCase): def testFile(self): - if sys.version_info < (3, 2): - self.skipTest("testdatafile contains stuff that is not supported by ast.literal_eval on Python < 3.2") datafile = "testserpent.utf8.bin" if not os.path.exists(datafile): mypath = os.path.split(__file__)[0] @@ -1019,8 +902,7 @@ self.assertEqual(KeysView, classes.pop(0)) self.assertEqual(ValuesView, classes.pop(0)) self.assertEqual(ItemsView, classes.pop(0)) - if sys.version_info >= (2, 7): - self.assertEqual(collections.OrderedDict, classes.pop(0)) + self.assertEqual(collections.OrderedDict, classes.pop(0)) self.assertEqual(enum.Enum, classes.pop(0)) self.assertEqual(BaseClass, classes.pop(0)) self.assertEqual(SubClass, classes.pop(0)) @@ -1164,7 +1046,6 @@ class TestCollections(unittest.TestCase): - @unittest.skipIf(sys.version_info < (2, 7), "collections.OrderedDict is python 2.7+") def testOrderedDict(self): o = collections.OrderedDict() o['apple'] = 1 @@ -1180,21 +1061,7 @@ d = serpent.dumps(p) p2 = serpent.loads(d) self.assertEqual((11, 22), p2) - # the checks below are valid if named tuples are not serialized by the normal tuple serializer: - # if sys.version_info < (2, 7) or sys.platform == "cli": - # # named tuple serialization is unfortunately broken on python <2.7 or ironpython; it leaves out the actual values - # self.assertEqual({"__class__": "Point"}, p2) - # elif os.name == "java": - # # named tuple serialization is unfortunately broken on jython; it forgets about the order - # self.assertEqual({"__class__": "Point", "x": 11, "y": 22}, p2) - # elif sys.version_info >= (3, 3) or ((2, 7) <= sys.version_info < (3, 0)): - # # only these versions got it 100% right! - # self.assertEqual({"__class__": "Point", "items": [('x', 11), ('y', 22)]}, p2) - # else: - # # other versions forget about the order.... - # self.assertEqual({"__class__": "Point", "x": 11, "y": 22}, p2) - @unittest.skipIf(sys.version_info < (2, 7), "collections.Counter is python 2.7+") def testCounter(self): c = collections.Counter("even") d = serpent.dumps(c) @@ -1207,7 +1074,6 @@ obj2 = serpent.loads(d) self.assertEqual([1, 2, 3], obj2) - @unittest.skipIf(sys.version_info < (3, 3), "ChainMap is python 3.3+") def testChainMap(self): c = collections.ChainMap({"a": 1}, {"b": 2}, {"c": 3}) d = serpent.dumps(c) @@ -1222,7 +1088,6 @@ dd2 = serpent.loads(d) self.assertEqual({'a': 1, 'b': 2}, dd2) - @unittest.skipIf(sys.version_info < (3, 0), "collections.UserDict is python 3.0+") def testUserDict(self): obj = collections.UserDict() obj['a'] = 1 @@ -1231,14 +1096,12 @@ obj2 = serpent.loads(d) self.assertEqual({'a': 1, 'b': 2}, obj2) - @unittest.skipIf(sys.version_info < (3, 0), "collections.UserList is python 3.0+") def testUserList(self): obj = collections.UserList([1, 2, 3]) d = serpent.dumps(obj) obj2 = serpent.loads(d) self.assertEqual([1, 2, 3], obj2) - @unittest.skipIf(sys.version_info < (3, 0), "collections.UserString is python 3.0+") def testUserString(self): obj = collections.UserString("test") d = serpent.dumps(obj) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/serpent-1.28/tests/test_unicode.py new/serpent-1.30.2/tests/test_unicode.py --- old/serpent-1.28/tests/test_unicode.py 2018-08-16 09:49:54.000000000 +0200 +++ new/serpent-1.30.2/tests/test_unicode.py 2020-01-21 23:45:38.000000000 +0100 @@ -1,11 +1,7 @@ -from __future__ import print_function import sys import serpent import platform -if sys.version_info>=(3,0): - unichr = chr - teststrings = [ u"", u"abc", @@ -13,9 +9,9 @@ u"\x00\x01\x80\x81\xfe\xff\u20ac\u4444\u0240slashu:\\uend.\\u20ac(no euro!)\\U00022001bigone" ] -large = u"".join(unichr(i) for i in range(256)) +large = u"".join(chr(i) for i in range(256)) teststrings.append(large) -large = u"".join(unichr(i) for i in range(0x20ac+1)) +large = u"".join(chr(i) for i in range(0x20ac+1)) teststrings.append(large) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/serpent-1.28/tests/test_unicode_parse.py new/serpent-1.30.2/tests/test_unicode_parse.py --- old/serpent-1.28/tests/test_unicode_parse.py 2018-08-16 09:49:54.000000000 +0200 +++ new/serpent-1.30.2/tests/test_unicode_parse.py 2020-01-21 23:46:41.000000000 +0100 @@ -1,4 +1,3 @@ -from __future__ import print_function import os import io import re diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/serpent-1.28/tox.ini new/serpent-1.30.2/tox.ini --- old/serpent-1.28/tox.ini 2018-08-16 09:49:54.000000000 +0200 +++ new/serpent-1.30.2/tox.ini 2020-01-22 00:00:04.000000000 +0100 @@ -1,18 +1,13 @@ -[tox] -envlist=py27,py34,py35,py36,py37,pypy,pypy3 - -[testenv] -deps= - pytz - enum34; python_version<"3.4" - attrs -changedir={toxinidir}/tests -commands=python -E -Wall -tt -bb test_serpent.py - -[testenv:py26] -deps=unittest2 - pytz - -[testenv:pypy3] -commands=python -E -Wall -bb test_serpent.py -# pypy3 doesn't like the -tt option +[tox] +envlist=py35,py36,py37,py38,pypy3 + +[testenv] +deps= + pytz + attrs +changedir={toxinidir}/tests +commands=python -E -Wall -tt -bb test_serpent.py + +[testenv:pypy3] +commands=python -E -Wall -bb test_serpent.py +# pypy3 doesn't like the -tt option
participants (1)
-
root