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

Commit

Permalink
Merge pull request #14 from wkitka/feature/1-python36
Browse files Browse the repository at this point in the history
done! Python 3.6 compatibility
  • Loading branch information
bamartos authored Aug 10, 2020
2 parents 77ea047 + cc2874f commit a31f67a
Show file tree
Hide file tree
Showing 36 changed files with 2,130 additions and 2,228 deletions.
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

0 comments on commit a31f67a

Please sign in to comment.