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

Commit

Permalink
Add some utility methods
Browse files Browse the repository at this point in the history
  • Loading branch information
wichert committed Nov 16, 2007
1 parent 706a8db commit b2dc1d0
Show file tree
Hide file tree
Showing 2 changed files with 111 additions and 0 deletions.
75 changes: 75 additions & 0 deletions bicop/tests/testUtils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import copy
from unittest import TestCase
from bicop.utils import same_type
from bicop.utils import merge

class base:
pass

class child(base):
pass

class SameTypeTests(TestCase):
def testTwoStrings(self):
self.assertEqual(same_type("", ""), True)

def testTwoDifferentTypes(self):
self.assertEqual(same_type("", 1), False)

def testSubClass(self):
self.assertEqual(same_type(base(), child()), True)
self.assertEqual(same_type(child(), base()), True)


class MergeTests(TestCase):
def testMergeToSelf(self):
one=dict(one=1)
original=one.copy()
merge(one, one)
self.assertEqual(one, original)

def testVarEntryOverlapping(self):
one=dict(one=1)
two=dict(two=2)
merge(one, two)
self.assertEqual(one, dict(one=1, two=2))
self.assertEqual(two, dict(two=2))

def testListEntryOverlapping(self):
one=dict(one=1)
two=dict(two=[1,2,3])
merge(one, two)
self.assertEqual(one, dict(one=1, two=[1,2,3]))
self.assertEqual(two, dict(two=[1,2,3]))
self.failUnless(one["two"] is two["two"])

def testOverrideEntry(self):
one=dict(one=1)
two=dict(one=2)
merge(one, two, True)
self.assertEqual(one, dict(one=2))
self.assertEqual(two, dict(one=2))

def testOverrideList(self):
one=dict(one=[1,2])
two=dict(one=[3,4])
merge(one, two, True)
self.assertEqual(one, dict(one=[3,4]))

def testOverrideTypeMismatch(self):
one=dict(one=1)
two=dict(one=[3,4])
self.assertRaises(ValueError, merge, one, two, True)

def testOverrideAllowedTypeMismatch(self):
one=dict(one=1)
two=dict(one=[3,4])
merge(one, two, True, False)
self.assertEqual(one, dict(one=[3,4]))

def testDeepMerge(self):
one=dict(people=dict(john="male"))
two=dict(people=dict(jane="female"))
merge(one, two)
self.assertEqual(one, dict(people=dict(john="male", jane="female")))

36 changes: 36 additions & 0 deletions bicop/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
def same_type(one, two):
"""Check if two things have the same type."""

return isinstance(one, type(two))

def merge(one, two, overwrite=False, typecheck=True):
"""Merge data from another configuration space into this one.
There are two merge methods: overwriting and adding. With the overwrite
method any existing values will be replaced. In adding mode only
non-existing keys will be added. If the typecheck flag is set an exception
will be thrown if a value has a different type in the a different type than
the original.
Please note that where possible this will merge data from two to one
*without copying*.
"""
if one is two:
return

if typecheck and not same_type(one, two):
raise ValuError, "Type mismatch"

for (key,value) in two.items():
if key not in one:
one[key]=value

if typecheck and not same_type(one[key], value):
raise ValueError, "Type mismatch"
if isinstance(value, dict):
merge(one[key], two[key], overwrite, typecheck)
elif not overwrite:
continue
else:
one[key]=two[key]

0 comments on commit b2dc1d0

Please sign in to comment.