Skip to content

Commit

Permalink
support for enum34 backport library for enums in older python versions
Browse files Browse the repository at this point in the history
  • Loading branch information
irmen committed Jul 24, 2018
1 parent 4187c93 commit 2692bd5
Show file tree
Hide file tree
Showing 6 changed files with 32 additions and 21 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Expand Up @@ -4,7 +4,7 @@
*.so

# Packages
*.egg
*.egg[s]
*.egg-info
dist
build
Expand Down
5 changes: 3 additions & 2 deletions .travis.yml
Expand Up @@ -14,8 +14,9 @@ dist: trusty

# Installation installs dependencies
install:
- pip install pytz
- pip install .
- pip install --user pytz
- pip install --user enum34;python_version<"3.4"
- pip install --user .

script:
- if [[ $TRAVIS_PYTHON_VERSION != pypy* ]]; then cd tests && python -E -Wall -tt -bb test_serpent.py; fi
Expand Down
14 changes: 8 additions & 6 deletions serpent.py
Expand Up @@ -76,11 +76,16 @@
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


__version__ = "1.25"
__version__ = "1.26"
__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
Expand Down Expand Up @@ -161,9 +166,7 @@ def _reset_special_classes_registry():
_special_classes_registry[ItemsView] = _ser_DictView
if sys.version_info >= (2, 7):
_special_classes_registry[collections.OrderedDict] = _ser_OrderedDict
if sys.version_info >= (3, 4):
import enum

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
Expand Down Expand Up @@ -457,8 +460,7 @@ def ser_builtins_list(self, list_obj, out, level):

def _check_hashable_type(self, t):
if t not in (bool, bytes, str, tuple) and not issubclass(t, numbers.Number):
if sys.version_info >= (3, 4):
import enum
if enum is not None:
if issubclass(t, enum.Enum):
return
elif sys.version_info < (3, 0) and t is unicode:
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Expand Up @@ -173,5 +173,5 @@ def __init__(self):
"Programming Language :: Python :: 3.7",
"Topic :: Software Development"
],

tests_require=['enum34; python_version < "3.4"']
)
26 changes: 16 additions & 10 deletions tests/test_serpent.py
Expand Up @@ -21,6 +21,7 @@
import time
import types
import collections
import enum
if sys.version_info >= (3, 4):
from collections.abc import KeysView, ValuesView, ItemsView
else:
Expand Down Expand Up @@ -617,19 +618,23 @@ def test_class_hashable_set_element_check(self):
serpent.dumps({1, 2, 3, pp}) # can only serialize simple typles as set elements (hashable)
self.assertTrue("hashable type" in str(x.exception))

@unittest.skipIf(sys.version_info < (3, 4), reason="python 3.4 introduced enums")
def test_enum_hashable(self):
import enum
class Color(enum.Enum):
RED = 1
GREEN = 2
BLUE = 3
data = serpent.dumps({"abc", Color.RED, Color.GREEN, Color.BLUE})
orig = serpent.loads(data)
self.assertEqual({"abc", 1, 2, 3}, orig)
if sys.version_info < (3, 4):
self.assertEqual([1, 2, 3, u"abc"], sorted(orig))
else:
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)
self.assertEqual({"abc": 1, 1: 1, 2: 1, 3: 1}, orig)
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)

def test_array(self):
ser = serpent.dumps(array.array('u', unicode("unicode")))
Expand Down Expand Up @@ -714,16 +719,19 @@ def test_float_precision(self):
v = serpent.loads(serpent.dumps((-98765432123456.12345678987656e+44 -665544332211.9998877665544e+33j)))
self.assertEqual((-98765432123456.12345678987656e+44 -665544332211.9998877665544e+33j), v)

@unittest.skipIf(sys.version_info < (3, 4), "needs python 3.4 to test enum type")
def test_enums(self):
import enum
class Animal(enum.Enum):
BEE = 1
CAT = 2
DOG = 3
v = serpent.loads(serpent.dumps(Animal.CAT))
self.assertEqual(2, v)
Animal2 = enum.Enum("Animals2", "BEE CAT DOG HORSE RABBIT")
class Animal2(enum.Enum):
BEE = 1
CAT = 2
DOG = 3
HORSE = 4
RABBIT = 5
v = serpent.loads(serpent.dumps(Animal2.HORSE))
self.assertEqual(4, v)

Expand Down Expand Up @@ -990,9 +998,7 @@ def testRegisterOrderPreserving(self):
self.assertEqual(ItemsView, classes.pop(0))
if sys.version_info >= (2, 7):
self.assertEqual(collections.OrderedDict, classes.pop(0))
if sys.version_info >= (3, 4):
import enum
self.assertEqual(enum.Enum, classes.pop(0))
self.assertEqual(enum.Enum, classes.pop(0))
self.assertEqual(BaseClass, classes.pop(0))
self.assertEqual(SubClass, classes.pop(0))
self.assertEqual(0, len(classes))
Expand Down
4 changes: 3 additions & 1 deletion tox.ini
Expand Up @@ -2,7 +2,9 @@
envlist=py27,py34,py35,py36,py37,pypy,pypy3

[testenv]
deps=pytz
deps=
pytz
enum34; python_version<"3.4"
changedir={toxinidir}/tests
commands=python -E -Wall -tt -bb test_serpent.py

Expand Down

0 comments on commit 2692bd5

Please sign in to comment.