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 - [email protected]
+
+- 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 <[email protected]>
+
+- 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: [email protected]
 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: [email protected]
 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 ([email protected])
 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 ([email protected])
 # 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='[email protected]',
+    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 ([email protected])
 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


Reply via email to