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