Skip to content
This repository has been archived by the owner on Jul 22, 2021. It is now read-only.

Python 3.6 compatibility #14

Merged
merged 23 commits into from
Aug 10, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,5 @@ coverage.xml
# Sphinx documentation
docs/_build/


# IDE
.idea
2 changes: 0 additions & 2 deletions bin/csv2json

This file was deleted.

5 changes: 0 additions & 5 deletions bin/xls2json

This file was deleted.

19 changes: 12 additions & 7 deletions dsconfig/appending_dict/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from collections import defaultdict, Mapping

from .caseless import CaselessDictionary


Expand Down Expand Up @@ -32,7 +33,7 @@ def __init__(self, value={}, factory=None):
self.__dict__["_factory"] = factory
CaselessDictionary.__init__(self)
defaultdict.__init__(self, factory)
for k, v in value.items():
for k, v in list(value.items()):
self[k] = v

def __getitem__(self, key):
Expand All @@ -56,9 +57,11 @@ def __setattr__(self, key, value):
return self.__setitem__(key, value)

def to_dict(self):
"""Returns a ordinary dict version of itself"""
"""
Returns a ordinary dict version of itself
"""
result = {}
for key, value in self.items():
for key, value in list(self.items()):
if isinstance(value, SetterDict):
result[key] = value.to_dict()
else:
Expand All @@ -67,8 +70,10 @@ def to_dict(self):


def merge(d, u):
"Recursively 'merge' a Mapping into another"
for k, v in u.iteritems():
"""
Recursively 'merge' a Mapping into another
"""
for k, v in list(u.items()):
if isinstance(v, Mapping):
if k in d:
merge(d[k], v)
Expand All @@ -86,8 +91,8 @@ def list_of_strings(value):


class AppendingDict(SetterDict):

"""An extra weird SetterDict where assignment adds items instead of
"""
An extra weird SetterDict where assignment adds items instead of
overwriting. It also allows setting nested values using dicts (or
any Mapping). Scalar values are converted into lists of strings.

Expand Down
20 changes: 11 additions & 9 deletions dsconfig/appending_dict/caseless.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
"""A caseless dictionary implementation."""
"""
A caseless dictionary implementation.
"""

from collections import MutableMapping


class CaselessDictionary(MutableMapping):

"""
A dictionary-like object which ignores but preserves the case of strings.

Expand Down Expand Up @@ -44,8 +45,8 @@ class CaselessDictionary(MutableMapping):
def __init__(self, *args, **kwargs):
self.__dict__["_dict"] = {}
temp_dict = dict(*args, **kwargs)
for key, value in temp_dict.iteritems():
if isinstance(key, basestring):
for key, value in list(temp_dict.items()):
if isinstance(key, str):
key = CaselessString.make_caseless(key)
self._dict[key] = value

Expand All @@ -72,12 +73,13 @@ def keys(self):
return [str(k) for k in self._dict]

def items(self):
return zip(self.keys(), self.values())
return list(zip(list(self.keys()), list(self.values())))


class CaselessString(object):

"""A mixin to make a string subclass case-insensitive in dict lookups."""
"""
A mixin to make a string subclass case-insensitive in dict lookups.
"""

def __hash__(self):
return hash(self.lower())
Expand All @@ -90,7 +92,7 @@ def __cmp__(self, other):

@classmethod
def make_caseless(cls, string):
if isinstance(string, unicode):
if isinstance(string, str):
return CaselessUnicode(string)
return CaselessStr(string)

Expand All @@ -99,5 +101,5 @@ class CaselessStr(CaselessString, str):
pass


class CaselessUnicode(CaselessString, unicode):
class CaselessUnicode(CaselessString, str):
pass
47 changes: 25 additions & 22 deletions dsconfig/appending_dict/test_appendingdict.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,52 +31,52 @@ def test_init_tiny(self):
def test_init_flat(self):
FLAT_DICT = {"a": 1, "b": 2, "c": 3}
sd = SetterDict(FLAT_DICT)
self.assertDictEqual(sd, FLAT_DICT)
self.assertDictEqual(sd.to_dict(), FLAT_DICT)

def test_init_nested(self):
NESTED_DICT = {"a": {"b": 2}}
sd = SetterDict(NESTED_DICT)
self.assertDictEqual(sd, NESTED_DICT)
self.assertDictEqual(sd.to_dict(), NESTED_DICT)

def test_init_blended(self):
BLENDED_DICT = {"a": 1, "b": {"c": 3}}
sd = SetterDict(BLENDED_DICT)
self.assertDictEqual(sd, BLENDED_DICT)
self.assertDictEqual(sd.to_dict(), BLENDED_DICT)

def test_init_deep(self):
DEEP_DICT = {"a": {"b": {"c": {"d": 4}}}}
sd = SetterDict(DEEP_DICT)
self.assertDictEqual(sd, DEEP_DICT)
self.assertDictEqual(sd.to_dict(), DEEP_DICT)

def test_init_deep(self):
COMPLEX_DICT = {"a": {"b": {"c": {"d": 4}}}, "e": 5}
sd = SetterDict(COMPLEX_DICT)
self.assertDictEqual(sd, COMPLEX_DICT)
self.assertDictEqual(sd.to_dict(), COMPLEX_DICT)

def test_setting(self):
sd = SetterDict()
sd["foo"] = 1
self.assertDictEqual(sd, {"foo": 1})
self.assertDictEqual(sd.to_dict(), {"foo": 1})

def test_setting_nested(self):
sd = SetterDict()
sd["foo"]["bar"] = 2
self.assertDictEqual(sd, {"foo": {"bar": 2}})
self.assertDictEqual(sd.to_dict(), {"foo": {"bar": 2}})

def test_setting_nested_nonempty(self):
sd = SetterDict({"a": 1})
sd["foo"]["bar"] = 2
self.assertDictEqual(sd, {"a": 1, "foo": {"bar": 2}})
self.assertDictEqual(sd.to_dict(), {"a": 1, "foo": {"bar": 2}})

def test_setting_attr(self):
sd = SetterDict({"a": 1})
sd.a = 2
self.assertDictEqual(sd, {"a": 2})
self.assertDictEqual(sd.to_dict(), {"a": 2})

def test_setting_attr_deep(self):
sd = SetterDict()
sd.a.b.c = 4
self.assertDictEqual(sd, {"a": {"b": {"c": 4}}})
self.assertDictEqual(sd.to_dict(), {"a": {"b": {"c": 4}}})

def test_to_dict(self):
orig = {"a": {"b": ["3"], "c": {"d": ["4"]}, "e": ["1"]}}
Expand All @@ -95,53 +95,54 @@ def test_keeps_original_key_case(self):
sd.foo = 2
sd.baR = 3
sd.BAR = 4
self.assertListEqual(sd.keys(), ["FoO", "baR"])
self.assertListEqual(list(sd.keys()), ["FoO", "baR"])


class AppendingDictTestCase(unittest.TestCase):

def test_basic_appending(self):
ad = AppendingDict()
ad["a"] = 1
self.assertDictEqual(ad, {"a": ['1']})
self.assertDictEqual(ad.to_dict(), {"a": ['1']})
ad["a"] = 2
self.assertDictEqual(ad, {"a": ['1', '2']})
self.assertDictEqual(ad.to_dict(), {"a": ['1', '2']})

def test_deep_appending(self):
ad = AppendingDict()
ad["a"]["b"]["c"] = 1
ad["a"]["b"]["c"] = 2
print type(ad["a"]["b"])
self.assertDictEqual(ad, {"a": {"b": {"c": ['1', '2']}}})
print((type(ad["a"]["b"])))
self.assertDictEqual(ad.to_dict(), {"a": {"b": {"c": ['1', '2']}}})

def test_initial_setting_with_dict(self):
ad = AppendingDict()
ad.a = {"b": {"c": 1}}
self.assertDictEqual(ad, {"a": {"b": {"c": ["1"]}}})
self.assertDictEqual(ad.to_dict(), {"a": {"b": {"c": ["1"]}}})

def test_deep_setting_with_dict(self):
ad = AppendingDict()
ad.a.b.c = 1
ad.a = {"b": {"d": 2}}
self.assertDictEqual(ad, {"a": {"b": {"c": ['1'], "d": ['2']}}})
self.assertDictEqual(ad.to_dict(), {"a": {"b": {"c": ['1'], "d": ['2']}}})

def test_setting_with_sequence(self):
ad = AppendingDict()
ad.a = [1, "b"]
self.assertDictEqual(ad, {"a": ['1', 'b']})
self.assertDictEqual(ad.to_dict(), {"a": ['1', 'b']})

def test_setting_existing_key_with_sequence(self):
ad = AppendingDict()
ad.a = [1, "b"]
ad.a = [2, "c"]
self.assertDictEqual(ad, {"a": ['1', 'b', '2', 'c']})
self.assertDictEqual(ad.to_dict(), {"a": ['1', 'b', '2', 'c']})

def test_error_setting_existing_subtree_with_scalar(self):
ad = AppendingDict()
ad.a.b.c = 1

def set_subtree():
ad.a = 2

self.assertRaises(ValueError, set_subtree)

def test_setting_with_appendingdict(self):
Expand All @@ -150,18 +151,20 @@ def test_setting_with_appendingdict(self):
ad.a.e = 1
ad.a = ad2
self.assertDictEqual(
ad, {"a": {"b": ["3"], "c": {"d": ["4"]}, "e": ["1"]}})
ad.to_dict(), {"a": {"b": ["3"], "c": {"d": ["4"]}, "e": ["1"]}})

def test_updating_does_not_work(self):
"Have not yet implemented this"
"""
Have not yet implemented this
"""
ad = AppendingDict()
d = {"a": 1, "b": {"c": 3}}
self.assertRaises(NotImplementedError, ad.update(d))

def test_set_string_value(self):
ad = AppendingDict()
ad.a = "abc"
self.assertDictEqual(ad, {"a": ["abc"]})
self.assertDictEqual(ad.to_dict(), {"a": ["abc"]})

def test_to_dict(self):
orig = {"a": {"b": ["3"], "c": {"d": ["4"]}, "e": ["1"]}}
Expand Down
Loading