diff --git a/README.rst b/README.rst index a770f2d..3211c0f 100644 --- a/README.rst +++ b/README.rst @@ -89,21 +89,21 @@ In this example we can be sure that only int will be passed, in production you s .. code-block:: python ->>> def callback(data): ->>> return data + 10 # add 10 to every taco prize + >>> def callback(data): + >>> return data + 10 # add 10 to every taco prize The alter-version only works for scalar input (one dict), if you need to adress a list of dicts, you have to manually iterate over those and pass them to nested_update one by one .. code-block:: python ->>> out =[] ->>> for elem in document: ->>> altered_document = nested_alter(elem,"taco", callback) ->>> out.append(altered_document) + >>> out =[] + >>> for elem in document: + >>> altered_document = nested_alter(elem,"taco", callback) + >>> out.append(altered_document) ->>> print(out) -[ { 'taco' : 52 } , { 'salsa' : [ { 'burrito' : { 'taco' : 79 } } ] } ] + >>> print(out) + [ { 'taco' : 52 } , { 'salsa' : [ { 'burrito' : { 'taco' : 79 } } ] } ] >>> from nested_lookup import get_all_keys diff --git a/nested_lookup/__init__.py b/nested_lookup/__init__.py index c1a964a..224d6b7 100644 --- a/nested_lookup/__init__.py +++ b/nested_lookup/__init__.py @@ -1,3 +1,7 @@ -from .nested_lookup import nested_lookup, get_all_keys, get_occurrence_of_key,\ - get_occurrence_of_value +from .nested_lookup import ( + nested_lookup, + get_all_keys, + get_occurrence_of_key, + get_occurrence_of_value, +) from .lookup_api import nested_update, nested_delete, nested_alter diff --git a/nested_lookup/lookup_api.py b/nested_lookup/lookup_api.py index 322be96..2fd561b 100644 --- a/nested_lookup/lookup_api.py +++ b/nested_lookup/lookup_api.py @@ -31,9 +31,7 @@ def _nested_delete(document, key): return document -def nested_update( - document, key, value, in_place=False, treat_as_element=True -): +def nested_update(document, key, value, in_place=False, treat_as_element=True): """ Method to update a key->value pair in a nested document Args: @@ -61,8 +59,9 @@ def nested_update( # from the scalar value # check the length of the list and provide it to _nested_update if not treat_as_element and not isinstance(value, list): - raise Exception('You need to pass value as list if you opt for' + - 'this feature') + raise Exception( + "You need to pass value as list if you opt for" + "this feature" + ) elif treat_as_element: value = [value] @@ -70,13 +69,10 @@ def nested_update( if not in_place: document = copy.deepcopy(document) - return _nested_update(document=document, key=key, value=value, - val_len=val_len) + return _nested_update(document=document, key=key, value=value, val_len=val_len) -def _nested_update( - document, key, value, val_len, run=0 -): +def _nested_update(document, key, value, val_len, run=0): """ Method to update a key->value pair in a nested document Args: @@ -95,8 +91,9 @@ def _nested_update( """ if isinstance(document, list): for list_items in document: - _nested_update(document=list_items, key=key, value=value, - val_len=val_len, run=run) + _nested_update( + document=list_items, key=key, value=value, val_len=val_len, run=run + ) elif isinstance(document, dict): if document.get(key): # check if a value with the coresponding index exists and @@ -109,14 +106,20 @@ def _nested_update( document[key] = val run = run + 1 for dict_key, dict_value in iteritems(document): - _nested_update(document=dict_value, key=key, value=value, - val_len=val_len, run=run) + _nested_update( + document=dict_value, key=key, value=value, val_len=val_len, run=run + ) return document def nested_alter( - document, key, callback_function=None, function_parameters=None, - conversion_function=None, wild_alter=False, in_place=True + document, + key, + callback_function=None, + function_parameters=None, + conversion_function=None, + wild_alter=False, + in_place=True, ): """ Method to alter all values of the occurences of the key "key". @@ -155,17 +158,20 @@ def nested_alter( if not in_place: document = copy.deepcopy(document) - return _nested_alter(document=document, keys=key, - callback_function=callback_function, - function_parameters=function_parameters, - conversion_function=conversion_function, - wild_alter=wild_alter, - in_place=in_place, key_len=key_len) + return _nested_alter( + document=document, + keys=key, + callback_function=callback_function, + function_parameters=function_parameters, + conversion_function=conversion_function, + wild_alter=wild_alter, + in_place=in_place, + key_len=key_len, + ) def _call_callback( - value_list, callback_function, function_parameters, - conversion_function + value_list, callback_function, function_parameters, conversion_function ): """ internal helper to call the callback function @@ -188,8 +194,14 @@ def _call_callback( def _nested_alter( - document, keys, callback_function, function_parameters, - conversion_function, wild_alter, in_place, key_len + document, + keys, + callback_function, + function_parameters, + conversion_function, + wild_alter, + in_place, + key_len, ): """ """ @@ -201,17 +213,15 @@ def _nested_alter( # iterate over all given keys in the list for key in keys: # try to find the key: - findings = nested_lookup( - key, document, with_keys=True, wild=wild_alter - ) + findings = nested_lookup(key, document, with_keys=True, wild=wild_alter) for k, v in findings.items(): - trans_val = _call_callback(v, callback_function, - function_parameters, - conversion_function) + trans_val = _call_callback( + v, callback_function, function_parameters, conversion_function + ) # use the transformed value and apply the update to the key # (dont treat the lists as elements here) - document = nested_update(document, k, trans_val, - in_place=in_place, - treat_as_element=False) + document = nested_update( + document, k, trans_val, in_place=in_place, treat_as_element=False + ) return document diff --git a/nested_lookup/nested_lookup.py b/nested_lookup/nested_lookup.py index 0ae066d..f61d66e 100644 --- a/nested_lookup/nested_lookup.py +++ b/nested_lookup/nested_lookup.py @@ -7,9 +7,7 @@ def nested_lookup(key, document, wild=False, with_keys=False): """Lookup a key in a nested document, return a list of values""" if with_keys: d = defaultdict(list) - for k, v in _nested_lookup( - key, document, wild=wild, with_keys=with_keys - ): + for k, v in _nested_lookup(key, document, wild=wild, with_keys=with_keys): d[k].append(v) return d return list(_nested_lookup(key, document, wild=wild, with_keys=with_keys)) @@ -19,9 +17,7 @@ def _nested_lookup(key, document, wild=False, with_keys=False): """Lookup a key in a nested document, yield a value""" if isinstance(document, list): for d in document: - for result in _nested_lookup( - key, d, wild=wild, with_keys=with_keys - ): + for result in _nested_lookup(key, d, wild=wild, with_keys=with_keys): yield result if isinstance(document, dict): @@ -32,9 +28,7 @@ def _nested_lookup(key, document, wild=False, with_keys=False): else: yield v if isinstance(v, dict): - for result in _nested_lookup( - key, v, wild=wild, with_keys=with_keys - ): + for result in _nested_lookup(key, v, wild=wild, with_keys=with_keys): yield result elif isinstance(v, list): for d in v: @@ -78,7 +72,7 @@ def get_occurrence_of_key(dictionary, key): Return: Number of occurrence (Integer) """ - return _get_occurrence(dictionary=dictionary, item='key', keyword=key) + return _get_occurrence(dictionary=dictionary, item="key", keyword=key) def get_occurrence_of_value(dictionary, value): @@ -91,7 +85,7 @@ def get_occurrence_of_value(dictionary, value): Return: Number of occurrence (Integer) """ - return _get_occurrence(dictionary=dictionary, item='value', keyword=value) + return _get_occurrence(dictionary=dictionary, item="value", keyword=value) def _get_occurrence(dictionary, item, keyword): @@ -108,7 +102,7 @@ def _get_occurrence(dictionary, item, keyword): occurrence = [0] def recrusion(dictionary): - if item == 'key': + if item == "key": if dictionary.get(keyword) is not None: occurrence[0] += 1 elif keyword in list(dictionary.values()): @@ -118,10 +112,10 @@ def _get_occurrence(dictionary, item, keyword): recrusion(dictionary=value) elif isinstance(value, list): for list_items in value: - if hasattr(list_items, 'items'): + if hasattr(list_items, "items"): recrusion(dictionary=list_items) elif list_items == keyword: - occurrence[0] += 1 if item == 'value' else 0 + occurrence[0] += 1 if item == "value" else 0 recrusion(dictionary=dictionary) return occurrence[0] diff --git a/setup.py b/setup.py index 4804530..9d53994 100644 --- a/setup.py +++ b/setup.py @@ -1,54 +1,50 @@ # installation: pip install nested-lookup -from setuptools import ( - setup, - find_packages, -) +from setuptools import setup, find_packages # get list of requirement strings from requirements.txt def remove_whitespace(x): - return ''.join(x.split()) + return "".join(x.split()) def sanitize(x): - return not x.startswith('#') and x != '' + return not x.startswith("#") and x != "" -with open('requirements.txt', 'r') as f: +with open("requirements.txt", "r") as f: requires = filter(sanitize, map(remove_whitespace, f.readlines())) setup( - name='nested-lookup', - version='0.2.15', - description='Python functions for working with deeply nested documents (lists and dicts) ', - keywords='nested document dictionary dict list lookup schema json xml yaml', - long_description=open('README.rst').read(), - - author='Russell Ballestrini', - author_email='russell@ballestrini.net', - url='https://github.com/russellballestrini/nested-lookup', - - platforms=['All'], - license='Public Domain', - + name="nested-lookup", + version="0.2.15", + description="Python functions for working with deeply nested documents (lists and dicts) ", + keywords="nested document dictionary dict list lookup schema json xml yaml", + long_description=open("README.rst").read(), + author="Russell Ballestrini", + author_email="russell@ballestrini.net", + url="https://github.com/russellballestrini/nested-lookup", + platforms=["All"], + license="Public Domain", packages=find_packages(), include_package_data=True, - install_requires=requires, - classifiers=[ # Specify the Python versions you support here. In particular, ensure # that you indicate whether you support Python 2, Python 3 or both. - 'Programming Language :: Python :: 2.6', - 'Programming Language :: Python :: 2.7', - 'Programming Language :: Python :: 3.5', - 'Programming Language :: Python :: 3.6', - 'Programming Language :: Python :: 3.7', + "Programming Language :: Python :: 2.6", + "Programming Language :: Python :: 2.7", + "Programming Language :: Python :: 3.5", + "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", ], ) # setup keyword args: http://peak.telecommunity.com/DevCenter/setuptools +# build package: +# pip install twine +# python setup.py sdist + # built and uploaded to pypi with this: # python setup.py sdist bdist_egg register upload diff --git a/test_lookup_api.py b/test_lookup_api.py index ad751a1..09066e9 100644 --- a/test_lookup_api.py +++ b/test_lookup_api.py @@ -8,52 +8,53 @@ class BaseLookUpApi(TestCase): def setUp(self): self.sample_data1 = { "build_version": { - "model_name": 'MacBook Pro', + "model_name": "MacBook Pro", "build_version": { - "processor_name": 'Intel Core i7', - "processor_speed": '2.7 GHz', + "processor_name": "Intel Core i7", + "processor_speed": "2.7 GHz", "core_details": { - "build_version": '4', - "l2_cache(per_core)": '256 KB' - } + "build_version": "4", + "l2_cache(per_core)": "256 KB", + }, }, - "number_of_cores": '4', - "memory": '256 KB' + "number_of_cores": "4", + "memory": "256 KB", }, - "os_details": { - "product_version": '10.13.6', - "build_version": '17G65' - }, - "name": 'Test', - "date": 'YYYY-MM-DD HH:MM:SS' + "os_details": {"product_version": "10.13.6", "build_version": "17G65"}, + "name": "Test", + "date": "YYYY-MM-DD HH:MM:SS", } self.sample_data2 = { "hardware_details": { - "model_name": 'MacBook Pro', + "model_name": "MacBook Pro", "processor_details": [ - { - "processor_name": 'Intel Core i7', - "processor_speed": '2.7 GHz' - }, - { - "total_number_of_cores": '4', - "l2_cache(per_core)": '256 KB' - } + {"processor_name": "Intel Core i7", "processor_speed": "2.7 GHz"}, + {"total_number_of_cores": "4", "l2_cache(per_core)": "256 KB"}, ], - "total_number_of_cores": '5', - "memory": '16 GB' + "total_number_of_cores": "5", + "memory": "16 GB", } } self.sample_data3 = { - "values": [{ - "checks": [{ - "monitoring_zones": - ["mzdfw", "mzfra", "mzhkg", "mziad", - "mzlon", "mzord", "mzsyd"] - }] - }] + "values": [ + { + "checks": [ + { + "monitoring_zones": [ + "mzdfw", + "mzfra", + "mzhkg", + "mziad", + "mzlon", + "mzord", + "mzsyd", + ] + } + ] + } + ] } self.sample_data4 = { @@ -70,26 +71,23 @@ class BaseLookUpApi(TestCase): "brutto": 58.76, "netto": 58.76, "zahlungsrhythmus": "MONATLICH", - "plz": 86899 + "plz": 86899, }, "beginn": 1512082800000, "lebenslang": "True", "ueberschussverwendung": { "ueberschussverwendung": "2", - "indexoption": "3" + "indexoption": "3", }, "deckung": [ { "typ": "2", "art": "1", - "leistung": { - "value": 7500242424.0, - "einheit": "2" - }, - "leistungsRhythmus": "1" + "leistung": {"value": 7500242424.0, "einheit": "2"}, + "leistungsRhythmus": "1", } ], - "zuschlagNachlass": [] + "zuschlagNachlass": [], }, { "typ": "1", @@ -97,79 +95,69 @@ class BaseLookUpApi(TestCase): "endalter": 85, "brutto": 0.6, "netto": 0.6, - "zahlungsrhythmus": "1" + "zahlungsrhythmus": "1", }, - "zuschlagNachlass": [] - } - ] + "zuschlagNachlass": [], + }, + ], } class TestNestedDelete(BaseLookUpApi): def test_sample_data1(self): result = { - "os_details": { - "product_version": '10.13.6' - }, - "name": 'Test', - "date": 'YYYY-MM-DD HH:MM:SS' + "os_details": {"product_version": "10.13.6"}, + "name": "Test", + "date": "YYYY-MM-DD HH:MM:SS", } - self.assertEqual( - result, nested_delete(self.sample_data1, 'build_version') - ) + self.assertEqual(result, nested_delete(self.sample_data1, "build_version")) def test_sample_data2(self): result = { "hardware_details": { - "model_name": 'MacBook Pro', - "total_number_of_cores": '5', - "memory": '16 GB' + "model_name": "MacBook Pro", + "total_number_of_cores": "5", + "memory": "16 GB", } } - self.assertEqual( - result, nested_delete(self.sample_data2, 'processor_details') - ) + self.assertEqual(result, nested_delete(self.sample_data2, "processor_details")) def test_sample_data3(self): result = {"values": [{"checks": [{}]}]} - self.assertEqual( - result, nested_delete(self.sample_data3, 'monitoring_zones') - ) + self.assertEqual(result, nested_delete(self.sample_data3, "monitoring_zones")) class TestNestedUpdate(BaseLookUpApi): - def test_sample_data1(self): result = { "build_version": "Test1", - "os_details": { - "product_version": '10.13.6', - "build_version": 'Test1' - }, - "name": 'Test', - "date": 'YYYY-MM-DD HH:MM:SS' + "os_details": {"product_version": "10.13.6", "build_version": "Test1"}, + "name": "Test", + "date": "YYYY-MM-DD HH:MM:SS", } self.assertEqual( - result, nested_update(self.sample_data1, 'build_version', 'Test1') + result, nested_update(self.sample_data1, "build_version", "Test1") ) def test_sample_data1_list_input_treat_list_as_element_true(self): result = { "build_version": ["Test5", "Test6", "Test7"], "os_details": { - "product_version": '10.13.6', - "build_version": ["Test5", "Test6", "Test7"] + "product_version": "10.13.6", + "build_version": ["Test5", "Test6", "Test7"], }, - "name": 'Test', - "date": 'YYYY-MM-DD HH:MM:SS' + "name": "Test", + "date": "YYYY-MM-DD HH:MM:SS", } self.assertEqual( - result, nested_update( + result, + nested_update( self.sample_data1, - 'build_version', + "build_version", ["Test5", "Test6", "Test7"], - treat_as_element=True) + treat_as_element=True, + ), ) def test_nested_update_in_place_false(self): @@ -177,8 +165,9 @@ class TestNestedUpdate(BaseLookUpApi): ested_update should mutate and return a copy of the original document """ before_id = id(self.sample_data1) - result = nested_update(self.sample_data1, 'build_version', 'Test2', - in_place=False) + result = nested_update( + self.sample_data1, "build_version", "Test2", in_place=False + ) after_id = id(result) # the object ids should _not_ match. self.assertNotEqual(before_id, after_id) @@ -189,7 +178,8 @@ class TestNestedUpdate(BaseLookUpApi): """ before_id = id(self.sample_data1) result = nested_update( - self.sample_data1, 'build_version', 'Test2', in_place=True) + self.sample_data1, "build_version", "Test2", in_place=True + ) after_id = id(result) # the object ids should match. self.assertEqual(before_id, after_id) @@ -205,7 +195,8 @@ class TestNestedUpdate(BaseLookUpApi): updated_findings.append(elem + 300) # update those instances with the altered results doc_updated = nested_update( - doc, "plz", updated_findings, treat_as_element=False) + doc, "plz", updated_findings, treat_as_element=False + ) elem1 = doc_updated["plz"] # 85269 # 87199 elem2 = doc_updated["vertragsteile"][0]["beitragsDaten"]["plz"] @@ -223,8 +214,8 @@ class TestNestedUpdate(BaseLookUpApi): updated_findings.append(elem + 300) # update those instances with the altered results doc_updated = nested_update( - doc, "plz", updated_findings, in_place=False, - treat_as_element=False) + doc, "plz", updated_findings, in_place=False, treat_as_element=False + ) elem1 = doc_updated["plz"] elem2 = doc_updated["vertragsteile"][0]["beitragsDaten"]["plz"] self.assertEqual(elem1, 82569) @@ -236,7 +227,8 @@ class TestNestedUpdate(BaseLookUpApi): list_input = [1, 2, 3, 4, 5] # update those instances with the altered results doc_updated = nested_update( - doc, "plz", list_input, in_place=False, treat_as_element=False) + doc, "plz", list_input, in_place=False, treat_as_element=False + ) elem1 = doc_updated["plz"] elem2 = doc_updated["vertragsteile"][0]["beitragsDaten"]["plz"] # should not work without specifying "treat_list_as_element = True" @@ -250,7 +242,8 @@ class TestNestedUpdate(BaseLookUpApi): list_input = [1, 2, 3, 4, 5] # update those instances with the altered results doc_updated = nested_update( - doc, "plz", list_input, in_place=False, treat_as_element=True) + doc, "plz", list_input, in_place=False, treat_as_element=True + ) elem1 = doc_updated["plz"] elem2 = doc_updated["vertragsteile"][0]["beitragsDaten"]["plz"] # should not work without specifying "treat_list_as_element = True" @@ -264,7 +257,8 @@ class TestNestedUpdate(BaseLookUpApi): list_input = [1, 2, 3, 4, 5] # update those instances with the altered results doc_updated = nested_update( - doc, "plz", list_input, in_place=True, treat_as_element=False) + doc, "plz", list_input, in_place=True, treat_as_element=False + ) elem1 = doc_updated["plz"] elem2 = doc_updated["vertragsteile"][0]["beitragsDaten"]["plz"] # should not work without specifying "treat_list_as_element = True" @@ -278,7 +272,8 @@ class TestNestedUpdate(BaseLookUpApi): list_input = [1, 2, 3, 4, 5] # update those instances with the altered results doc_updated = nested_update( - doc, "plz", list_input, in_place=True, treat_as_element=True) + doc, "plz", list_input, in_place=True, treat_as_element=True + ) elem1 = doc_updated["plz"] elem2 = doc_updated["vertragsteile"][0]["beitragsDaten"]["plz"] # should not work without specifying "treat_list_as_element = True" @@ -291,8 +286,7 @@ class TestNestedUpdate(BaseLookUpApi): nested_delete should mutate and return a copy of the original document """ before_id = id(self.sample_data1) - result = nested_delete( - self.sample_data1, 'build_version', in_place=False) + result = nested_delete(self.sample_data1, "build_version", in_place=False) after_id = id(result) # the object ids should _not_ match. self.assertNotEqual(before_id, after_id) @@ -300,28 +294,24 @@ class TestNestedUpdate(BaseLookUpApi): def test_nested_delete_in_place_true(self): """nested_delete should mutate and return the original document""" before_id = id(self.sample_data1) - result = nested_delete( - self.sample_data1, 'build_version', in_place=True) + result = nested_delete(self.sample_data1, "build_version", in_place=True) after_id = id(result) # the object ids should match. self.assertEqual(before_id, after_id) def test_nested_update_taco_for_example(self): - document = [ - {'taco': 42}, - {'salsa': [{'burrito': {'taco': 69}}]} - ] + document = [{"taco": 42}, {"salsa": [{"burrito": {"taco": 69}}]}] updated_document = nested_update( - document, "taco", [100, 200], treat_as_element=False) + document, "taco", [100, 200], treat_as_element=False + ) self.assertEqual(updated_document[0]["taco"], 100) # The multi-update version only works for scalar input, # if you need to adress a list of dicts, you have to # manually iterate over those and pass them to nested_update # one by one - self.assertNotEqual( - updated_document[1]["salsa"][0]["burrito"]["taco"], 200) + self.assertNotEqual(updated_document[1]["salsa"][0]["burrito"]["taco"], 200) def test_nested_update_raise_error(self): doc = self.sample_data4 @@ -330,53 +320,42 @@ class TestNestedUpdate(BaseLookUpApi): # update those instances with the altered results self.assertRaises( Exception, - nested_update, doc, "plz", list_input, - in_place=True, treat_as_element=False + nested_update, + doc, + "plz", + list_input, + in_place=True, + treat_as_element=False, ) def test_sample_data2(self): result = { "hardware_details": { - "model_name": 'MacBook Pro', - "processor_details": { - 'test_key1': 'test_value1' - }, - "total_number_of_cores": '5', - "memory": '16 GB' + "model_name": "MacBook Pro", + "processor_details": {"test_key1": "test_value1"}, + "total_number_of_cores": "5", + "memory": "16 GB", } } self.assertEqual( - result, nested_update( - self.sample_data2, 'processor_details', - {'test_key1': 'test_value1'} - ) + result, + nested_update( + self.sample_data2, "processor_details", {"test_key1": "test_value1"} + ), ) def test_sample_data3(self): - result = { - "values": [{ - "checks": { - 'key1': ['value1'], - 'key2': 'value2' - } - }] - } + result = {"values": [{"checks": {"key1": ["value1"], "key2": "value2"}}]} self.assertEqual( - result, nested_update( - self.sample_data3, 'checks', - { - 'key1': ['value1'], - 'key2': 'value2' - } - ) + result, + nested_update( + self.sample_data3, "checks", {"key1": ["value1"], "key2": "value2"} + ), ) def test_sample_data4(self): result = { - "modelversion": { - 'key1': ['value1'], - 'key2': 'value2' - }, + "modelversion": {"key1": ["value1"], "key2": "value2"}, "vorgangsID": "1", "versorgungsvorschlagDatum": 1510558834978, "eingangsdatum": 1510558834978, @@ -389,26 +368,23 @@ class TestNestedUpdate(BaseLookUpApi): "brutto": 58.76, "netto": 58.76, "zahlungsrhythmus": "MONATLICH", - "plz": 86899 + "plz": 86899, }, "beginn": 1512082800000, "lebenslang": "True", "ueberschussverwendung": { "ueberschussverwendung": "2", - "indexoption": "3" + "indexoption": "3", }, "deckung": [ { "typ": "2", "art": "1", - "leistung": { - "value": 7500242424.0, - "einheit": "2" - }, - "leistungsRhythmus": "1" + "leistung": {"value": 7500242424.0, "einheit": "2"}, + "leistungsRhythmus": "1", } ], - "zuschlagNachlass": [] + "zuschlagNachlass": [], }, { "typ": "1", @@ -416,25 +392,23 @@ class TestNestedUpdate(BaseLookUpApi): "endalter": 85, "brutto": 0.6, "netto": 0.6, - "zahlungsrhythmus": "1" + "zahlungsrhythmus": "1", }, - "zuschlagNachlass": [] - } - ] + "zuschlagNachlass": [], + }, + ], } self.assertEqual( - result, nested_update( - self.sample_data4, 'modelversion', - { - 'key1': ['value1'], - 'key2': 'value2' - } - ) + result, + nested_update( + self.sample_data4, + "modelversion", + {"key1": ["value1"], "key2": "value2"}, + ), ) class TestNestedAlter(BaseLookUpApi): - def test_nested_alter_in_place_true(self): # callback functions @@ -442,7 +416,8 @@ class TestNestedAlter(BaseLookUpApi): return str(data) + "###" doc_updated = nested_alter( - self.sample_data4, "vorgangsID", callback, in_place=True) + self.sample_data4, "vorgangsID", callback, in_place=True + ) vorgangsid = doc_updated["vorgangsID"] @@ -455,7 +430,8 @@ class TestNestedAlter(BaseLookUpApi): return str(data) + "###" doc_updated = nested_alter( - self.sample_data4, "vorgangsID", callback, in_place=False) + self.sample_data4, "vorgangsID", callback, in_place=False + ) vorgangsid = doc_updated["vorgangsID"] @@ -470,7 +446,8 @@ class TestNestedAlter(BaseLookUpApi): return str(data) + "###" doc_updated = nested_alter( - self.sample_data4, ["plz", "vorgangsID"], callback, in_place=True) + self.sample_data4, ["plz", "vorgangsID"], callback, in_place=True + ) plz1 = doc_updated["plz"] plz2 = doc_updated["vertragsteile"][0]["beitragsDaten"]["plz"] @@ -488,12 +465,13 @@ class TestNestedAlter(BaseLookUpApi): def callback(data, str1, str2): return str(data) + str1 + str2 - doc_updated = nested_alter(self.sample_data4, [ - "plz", "vorgangsID"], - callback, - function_parameters=["abc", "def"], - in_place=True - ) + doc_updated = nested_alter( + self.sample_data4, + ["plz", "vorgangsID"], + callback, + function_parameters=["abc", "def"], + in_place=True, + ) plz1 = doc_updated["plz"] plz2 = doc_updated["vertragsteile"][0]["beitragsDaten"]["plz"] @@ -511,12 +489,13 @@ class TestNestedAlter(BaseLookUpApi): def callback(data, str1, str2): return str(data) + str1 + str2 - doc_updated = nested_alter(self.sample_data4, [ - "plz", "vorgangsID"], - callback, - function_parameters=["abc", "def"], - in_place=False - ) + doc_updated = nested_alter( + self.sample_data4, + ["plz", "vorgangsID"], + callback, + function_parameters=["abc", "def"], + in_place=False, + ) plz1 = doc_updated["plz"] plz2 = doc_updated["vertragsteile"][0]["beitragsDaten"]["plz"] @@ -535,7 +514,8 @@ class TestNestedAlter(BaseLookUpApi): return str(data) + "###" doc_updated = nested_alter( - self.sample_data4, ["plz", "vorgangsID"], callback, in_place=False) + self.sample_data4, ["plz", "vorgangsID"], callback, in_place=False + ) plz1 = doc_updated["plz"] plz2 = doc_updated["vertragsteile"][0]["beitragsDaten"]["plz"] @@ -548,10 +528,7 @@ class TestNestedAlter(BaseLookUpApi): self.assertEqual(vorgangsid, "1###") def test_nested_alter_taco_for_example(self): - documents = [ - {'taco': 42}, - {'salsa': [{'burrito': {'taco': 69}}]} - ] + documents = [{"taco": 42}, {"salsa": [{"burrito": {"taco": 69}}]}] # write a callback function which processes a scalar value. # Be aware about the possible types which can be passed to @@ -591,26 +568,23 @@ class TestNestedAlter(BaseLookUpApi): "brutto": 58.76, "netto": 58.76, "zahlungsrhythmus": "MONATLICH", - "plz": 86900 + "plz": 86900, }, "beginn": 1512082800000, "lebenslang": "True", "ueberschussverwendung": { "ueberschussverwendung": "2", - "indexoption": "3" + "indexoption": "3", }, "deckung": [ { "typ": "2", "art": "1", - "leistung": { - "value": 7500242424.0, - "einheit": "2" - }, - "leistungsRhythmus": "1" + "leistung": {"value": 7500242424.0, "einheit": "2"}, + "leistungsRhythmus": "1", } ], - "zuschlagNachlass": [] + "zuschlagNachlass": [], }, { "typ": "1", @@ -618,11 +592,11 @@ class TestNestedAlter(BaseLookUpApi): "endalter": 85, "brutto": 0.6, "netto": 0.6, - "zahlungsrhythmus": "1" + "zahlungsrhythmus": "1", }, - "zuschlagNachlass": [] - } - ] + "zuschlagNachlass": [], + }, + ], } # add +1 to all plz @@ -630,6 +604,4 @@ class TestNestedAlter(BaseLookUpApi): return data + 1 self.maxDiff = None - self.assertEqual( - result, nested_alter(self.sample_data4, 'plz', callback) - ) + self.assertEqual(result, nested_alter(self.sample_data4, "plz", callback)) diff --git a/test_nested_lookup.py b/test_nested_lookup.py index 718a795..7a8b8e1 100644 --- a/test_nested_lookup.py +++ b/test_nested_lookup.py @@ -1,11 +1,14 @@ from unittest import TestCase -from nested_lookup import nested_lookup, get_all_keys, get_occurrence_of_key,\ - get_occurrence_of_value +from nested_lookup import ( + nested_lookup, + get_all_keys, + get_occurrence_of_key, + get_occurrence_of_value, +) class TestNestedLookup(TestCase): - def setUp(self): self.subject_dict = {"a": 1, "b": {"d": 100}, "c": {"d": 200}} self.subject_dict2 = { @@ -25,18 +28,15 @@ class TestNestedLookup(TestCase): "processor_speed": "2.7 GHz", "core_details": { "build_version": "4", - "l2_cache(per_core)": "256 KB" - } + "l2_cache(per_core)": "256 KB", + }, }, "number_of_cores": "4", "memory": "256 KB", }, - "os_details": { - "product_version": "10.13.6", - "build_version": "17G65" - }, + "os_details": {"product_version": "10.13.6", "build_version": "17G65"}, "name": "Test", - "date": "YYYY-MM-DD HH:MM:SS" + "date": "YYYY-MM-DD HH:MM:SS", } def test_nested_lookup(self): @@ -68,8 +68,7 @@ class TestNestedLookup(TestCase): self.assertSetEqual({100, 200}, set(results)) def test_wild_nested_lookup(self): - results = nested_lookup( - key="mail", document=self.subject_dict2, wild=True) + results = nested_lookup(key="mail", document=self.subject_dict2, wild=True) self.assertEqual(4, len(results)) self.assertIn("test1@example.com", results) self.assertIn("test2@example.com", results) @@ -83,9 +82,8 @@ class TestNestedLookup(TestCase): self.assertIn("email_address", matches) self.assertIn("secondary_email", matches) self.assertIn("EMAIL_RECOVERY", matches) - self.assertSetEqual({ - "test1@example.com", "test4@example.com"}, - set(matches["email_address"]) + self.assertSetEqual( + {"test1@example.com", "test4@example.com"}, set(matches["email_address"]) ) self.assertIn("test2@example.com", matches["secondary_email"]) @@ -96,39 +94,30 @@ class TestNestedLookup(TestCase): self.assertSetEqual({100, 200}, set(matches["d"])) def test_after_key_is_found(self): - result = nested_lookup( - key='build_version', document=self.subject_dict3 - ) + result = nested_lookup(key="build_version", document=self.subject_dict3) self.assertEqual(4, len(result)) - self.assertIn('4', result) - self.assertIn('17G65', result) + self.assertIn("4", result) + self.assertIn("17G65", result) match1 = { - 'processor_name': 'Intel Core i7', - 'processor_speed': '2.7 GHz', - 'core_details': { - 'build_version': '4', - 'l2_cache(per_core)': '256 KB' - } + "processor_name": "Intel Core i7", + "processor_speed": "2.7 GHz", + "core_details": {"build_version": "4", "l2_cache(per_core)": "256 KB"}, } self.assertIn(match1, result) match2 = { - 'build_version': { - 'processor_name': 'Intel Core i7', - 'processor_speed': '2.7 GHz', - 'core_details': { - 'build_version': '4', - 'l2_cache(per_core)': '256 KB' - } + "build_version": { + "processor_name": "Intel Core i7", + "processor_speed": "2.7 GHz", + "core_details": {"build_version": "4", "l2_cache(per_core)": "256 KB"}, }, - 'memory': '256 KB', - 'model_name': 'MacBook Pro', - 'number_of_cores': '4' + "memory": "256 KB", + "model_name": "MacBook Pro", + "number_of_cores": "4", } self.assertIn(match2, result) class TestGetAllKeys(TestCase): - def setUp(self): self.sample1 = { "hardware_details": { @@ -144,9 +133,7 @@ class TestGetAllKeys(TestCase): "total_number_of_cores": "4", "memory": "16 GB", }, - "os_details": { - "product_version": "10.13.6", "build_version": "17G65" - }, + "os_details": {"product_version": "10.13.6", "build_version": "17G65"}, "name": "Test", "date": "YYYY-MM-DD HH:MM:SS", } @@ -171,38 +158,46 @@ class TestGetAllKeys(TestCase): "hardware_details": { "model_name": "MacBook Pro", "processor_details": [ - { - "processor_name": "Intel Core i7", - "processor_speed": "2.7 GHz" - }, - { - "total_numberof_cores": "4", - "l2_cache(per_core)": "256 KB" - }, + {"processor_name": "Intel Core i7", "processor_speed": "2.7 GHz"}, + {"total_numberof_cores": "4", "l2_cache(per_core)": "256 KB"}, ], "total_number_of_cores": "4", "memory": "16 GB", } } self.sample4 = { - "values": [{ - "checks": [{ - "monitoring_zones": - ["mzdfw", "mzfra", "mzhkg", "mziad", - "mzlon", "mzord", "mzsyd"] - }] - }] + "values": [ + { + "checks": [ + { + "monitoring_zones": [ + "mzdfw", + "mzfra", + "mzhkg", + "mziad", + "mzlon", + "mzord", + "mzsyd", + ] + } + ] + } + ] } - self.sample5 = [{ - "listings": [{ - "name": "title", - "postcode": "postcode", - "full_address": "fulladdress", - "city": "city", - "lat": "latitude", - "lng": "longitude" - }] - }] + self.sample5 = [ + { + "listings": [ + { + "name": "title", + "postcode": "postcode", + "full_address": "fulladdress", + "city": "city", + "lat": "latitude", + "lng": "longitude", + } + ] + } + ] def test_sample_data1(self): result = get_all_keys(self.sample1) @@ -244,11 +239,7 @@ class TestGetAllKeys(TestCase): def test_sample_data4(self): result = get_all_keys(self.sample4) self.assertEqual(3, len(result)) - keys_to_verify = [ - "values", - "checks", - "monitoring_zones" - ] + keys_to_verify = ["values", "checks", "monitoring_zones"] for key in keys_to_verify: self.assertIn(key, result) @@ -256,8 +247,13 @@ class TestGetAllKeys(TestCase): result = get_all_keys(self.sample5) self.assertEqual(7, len(result)) keys_to_verify = [ - 'listings', 'name', 'postcode', 'full_address', 'city', - 'lat', 'lng' + "listings", + "name", + "postcode", + "full_address", + "city", + "lat", + "lng", ] for key in keys_to_verify: self.assertIn(key, result) @@ -273,30 +269,29 @@ class TestGetOccurrence(TestCase): "processor_speed": "2.7 GHz", "core_details": { "build_version": "4", - "l2_cache(per_core)": "256 KB" - } + "l2_cache(per_core)": "256 KB", + }, }, "number_of_cores": "4", "memory": "256 KB", }, - "os_details": { - "product_version": "10.13.6", - "build_version": "17G65" - }, + "os_details": {"product_version": "10.13.6", "build_version": "17G65"}, "name": "Test", - "date": "YYYY-MM-DD HH:MM:SS" + "date": "YYYY-MM-DD HH:MM:SS", } self.sample2 = { "hardware_details": { "model_name": "MacBook Pro", - "processor_details": [{ - "processor_name": "4", - "processor_speed": "2.7 GHz", - "core_details": { - "total_numberof_cores": "4", - "l2_cache(per_core)": "256 KB" + "processor_details": [ + { + "processor_name": "4", + "processor_speed": "2.7 GHz", + "core_details": { + "total_numberof_cores": "4", + "l2_cache(per_core)": "256 KB", + }, } - }], + ], "total_number_of_cores": "4", "memory": "16 GB", } @@ -305,73 +300,76 @@ class TestGetOccurrence(TestCase): "hardware_details": { "model_name": "MacBook Pro", "processor_details": [ - { - "total_number_of_cores": "4", - "processor_speed": "2.7 GHz", - }, - { - "total_number_of_cores": "4", - "l2_cache(per_core)": "256 KB" - } + {"total_number_of_cores": "4", "processor_speed": "2.7 GHz"}, + {"total_number_of_cores": "4", "l2_cache(per_core)": "256 KB"}, ], "total_number_of_cores": "4", "memory": "16 GB", } } self.sample4 = { - "values": [{ - "checks": [{ - "monitoring_zones": - ["mzdfw", "mzfra", "mzhkg", "mziad", - "mzlon", "mzord", "mzsyd"] - }] - }] + "values": [ + { + "checks": [ + { + "monitoring_zones": [ + "mzdfw", + "mzfra", + "mzhkg", + "mziad", + "mzlon", + "mzord", + "mzsyd", + ] + } + ] + } + ] } self.sample5 = { "hardware_details": { - "model_name": 'MacBook Pro', + "model_name": "MacBook Pro", "total_number_of_cores": 0, - "memory": False + "memory": False, } } def test_sample_data1(self): - result = get_occurrence_of_key(self.sample1, 'build_version') + result = get_occurrence_of_key(self.sample1, "build_version") self.assertEqual(4, result) - result = get_occurrence_of_value(self.sample1, '256 KB') + result = get_occurrence_of_value(self.sample1, "256 KB") self.assertEqual(2, result) def test_sample_data2(self): - result = get_occurrence_of_key(self.sample2, 'core_details') + result = get_occurrence_of_key(self.sample2, "core_details") self.assertEqual(1, result) - result = get_occurrence_of_value(self.sample2, '4') + result = get_occurrence_of_value(self.sample2, "4") self.assertEqual(3, result) def test_sample_data3(self): - result = get_occurrence_of_key(self.sample3, 'total_number_of_cores') + result = get_occurrence_of_key(self.sample3, "total_number_of_cores") self.assertEqual(3, result) - result = get_occurrence_of_value(self.sample3, '4') + result = get_occurrence_of_value(self.sample3, "4") self.assertEqual(3, result) def test_sample_data4(self): - result = get_occurrence_of_key(self.sample4, 'checks') + result = get_occurrence_of_key(self.sample4, "checks") self.assertEqual(1, result) - result = get_occurrence_of_value(self.sample4, 'mziad') + result = get_occurrence_of_value(self.sample4, "mziad") self.assertEqual(1, result) # Add one more value in key "monitoring_zones" and verify - self.sample4['values'][0]['checks'][0]['monitoring_zones'].append( - 'mziad') - self.assertEqual(2, get_occurrence_of_value(self.sample4, 'mziad')) + self.sample4["values"][0]["checks"][0]["monitoring_zones"].append("mziad") + self.assertEqual(2, get_occurrence_of_value(self.sample4, "mziad")) def test_sample_data5(self): self.assertEqual( - 1, get_occurrence_of_key(self.sample5, 'total_number_of_cores') + 1, get_occurrence_of_key(self.sample5, "total_number_of_cores") ) - self.assertEqual(1, get_occurrence_of_key(self.sample5, 'memory')) + self.assertEqual(1, get_occurrence_of_key(self.sample5, "memory")) # Add key 'memory' and verify - self.sample5['memory'] = 0 - self.assertEqual(2, get_occurrence_of_key(self.sample5, 'memory')) + self.sample5["memory"] = 0 + self.assertEqual(2, get_occurrence_of_key(self.sample5, "memory")) if __name__ == "__main__":