mapz
Advanced tools
+26
-25
@@ -0,1 +1,9 @@ | ||
| """Mapz. | ||
| Hierarchy of methods: | ||
| get | ||
| """ | ||
| from mapz import methods, modifiers | ||
@@ -42,9 +50,4 @@ | ||
| key_sep: str = ".", | ||
| key_modificator: methods.SplitkeyModificatorCallable = lambda key, parts: parts, | ||
| val_visitor: methods.TraverseVisitorCallable = lambda k, v, **kwargs: ( | ||
| k, | ||
| v, | ||
| ), | ||
| merge_method: str = "recursive", | ||
| merge_inverse: bool = False, | ||
| strategy: methods.Strategy = methods.Strategy.Deep, | ||
| inverse: bool = False, | ||
| ) -> Dict[Hashable, Any]: | ||
@@ -55,8 +58,6 @@ return methods.set( | ||
| val=val, | ||
| key_prefix=key_prefix, | ||
| key_sep=key_sep, | ||
| key_modificator=key_modificator, | ||
| val_visitor=val_visitor, | ||
| merge_method=merge_method, | ||
| merge_inverse=merge_inverse, | ||
| prefix=key_prefix, | ||
| sep=key_sep, | ||
| strategy=strategy, | ||
| inverse=inverse, | ||
| mapping_type=Mapz, | ||
@@ -68,3 +69,3 @@ ) | ||
| mapping: Mapping[Hashable, Any], | ||
| method: str = "recursive", | ||
| strategy: methods.Strategy = methods.Strategy.Deep, | ||
| ) -> Dict[Hashable, Any]: | ||
@@ -83,3 +84,3 @@ # Intentionally incompatible with 'update' method of dict and MutableMapping. | ||
| other=mapping, | ||
| method=method, | ||
| strategy=strategy, | ||
| ) | ||
@@ -92,3 +93,3 @@ | ||
| key_sep: str = "__", | ||
| merge_method: str = "recursive", | ||
| strategy: methods.Strategy = methods.Strategy.Deep, | ||
| merge_inverse: bool = False, | ||
@@ -99,6 +100,6 @@ ) -> Dict[Hashable, Any]: | ||
| *mapping, | ||
| key_prefix=key_prefix, | ||
| key_sep=key_sep, | ||
| merge_method=merge_method, | ||
| merge_inverse=merge_inverse, | ||
| prefix=key_prefix, | ||
| sep=key_sep, | ||
| strategy=strategy, | ||
| inverse=merge_inverse, | ||
| mapping_type=Mapz, | ||
@@ -112,3 +113,3 @@ ) | ||
| key_sep: str = "__", | ||
| merge_method: str = "recursive", | ||
| strategy: methods.Strategy = methods.Strategy.Deep, | ||
| ) -> Dict[Hashable, Any]: | ||
@@ -118,6 +119,6 @@ return methods.merge( | ||
| *mapping, | ||
| key_prefix=key_prefix, | ||
| key_sep=key_sep, | ||
| merge_method=merge_method, | ||
| merge_inverse=True, | ||
| prefix=key_prefix, | ||
| sep=key_sep, | ||
| strategy=strategy, | ||
| inverse=True, | ||
| mapping_type=Mapz, | ||
@@ -124,0 +125,0 @@ ) |
@@ -7,3 +7,3 @@ from .get import get as get, getsert as getsert | ||
| ) | ||
| from .update import update as update | ||
| from .update import update as update, Strategy as Strategy | ||
| from .copy import copy as copy, deepcopy as deepcopy | ||
@@ -10,0 +10,0 @@ from .splitkey import ( |
| from .set import set as zset | ||
| from .update import Strategy | ||
@@ -17,6 +18,6 @@ from typing import ( | ||
| *other: Mapping[Hashable, Any], | ||
| key_prefix: str = "", | ||
| key_sep: str = "__", | ||
| merge_method: str = "recursive", | ||
| merge_inverse: bool = False, | ||
| prefix: str = "", | ||
| sep: str = "__", | ||
| strategy: Strategy = Strategy.Deep, | ||
| inverse: bool = False, | ||
| mapping_type: Type[Dict[Hashable, Any]] = dict, | ||
@@ -39,6 +40,6 @@ ) -> Dict[Hashable, Any]: | ||
| v, | ||
| key_prefix=key_prefix, | ||
| key_sep=key_sep, | ||
| merge_method=merge_method, | ||
| merge_inverse=merge_inverse, | ||
| prefix=prefix, | ||
| sep=sep, | ||
| strategy=strategy, | ||
| inverse=inverse, | ||
| mapping_type=mapping_type, | ||
@@ -45,0 +46,0 @@ ) |
+10
-17
@@ -5,3 +5,3 @@ from typing import Dict, Hashable, Any, Type | ||
| from .traverse import traverse, TraverseVisitorCallable | ||
| from .update import update | ||
| from .update import update, Strategy | ||
@@ -13,18 +13,11 @@ | ||
| val: Any, | ||
| key_prefix: str = "", | ||
| key_sep: str = ".", | ||
| key_modificator: SplitkeyModificatorCallable = lambda key, parts: parts, | ||
| val_visitor: TraverseVisitorCallable = lambda k, v, **kwargs: ( | ||
| k, | ||
| v, | ||
| ), | ||
| merge_method: str = "recursive", | ||
| merge_inverse: bool = False, | ||
| prefix: str = "", | ||
| sep: str = ".", | ||
| strategy: Strategy = Strategy.Deep, | ||
| inverse: bool = False, | ||
| mapping_type: Type[Dict[Hashable, Any]] = dict, | ||
| ) -> Dict[Hashable, Any]: | ||
| key_parts = splitkey( | ||
| key, prefix=key_prefix, sep=key_sep, modificator=key_modificator | ||
| ) | ||
| value = traverse(val, val_visitor, mapping_type=mapping_type) | ||
| key_parts = splitkey(key, prefix=prefix, sep=sep) | ||
| value = traverse(arg=val, mapping_type=mapping_type) | ||
@@ -39,8 +32,8 @@ # Build dict in reverse order from list of key parts and the value | ||
| if merge_inverse: | ||
| update(result, mapping, method=merge_method) | ||
| if inverse: | ||
| update(result, mapping, strategy=strategy) | ||
| mapping.clear() | ||
| update(mapping, result, method=merge_method) | ||
| update(mapping, result, strategy=strategy) | ||
| return mapping |
| from typing import Any, Dict, Hashable, Mapping | ||
| from types import MappingProxyType | ||
| from enum import Enum | ||
| class Strategy(Enum): | ||
| Deep = 1 | ||
| Shallow = 2 | ||
| def update( | ||
| mapping: Dict[Hashable, Any], | ||
| other: Mapping[Hashable, Any], | ||
| method: str = "recursive", | ||
| strategy: Strategy = Strategy.Deep, | ||
| ) -> Dict[Hashable, Any]: | ||
@@ -15,3 +22,3 @@ | ||
| if ( | ||
| method == "recursive" | ||
| strategy is Strategy.Deep | ||
| and key in mapping | ||
@@ -26,3 +33,3 @@ and isinstance(dict.__getitem__(mapping, key), Mapping) | ||
| MappingProxyType(other).__getitem__(key), | ||
| method=method, | ||
| strategy=strategy, | ||
| ) | ||
@@ -29,0 +36,0 @@ |
@@ -1,2 +0,1 @@ | ||
| from attr import dataclass | ||
| from mapz.methods.merge import merge | ||
@@ -8,3 +7,3 @@ | ||
| @pytest.fixture | ||
| def data_map(): | ||
| def data(): | ||
| return {"name": "Boris", "data": {"songs": ["Du Hast", "Du Hast - Live"]}} | ||
@@ -14,11 +13,11 @@ | ||
| @pytest.fixture | ||
| def merger(): | ||
| def mergein(): | ||
| return {"name": "Duhast", "parental": "Vyacheslavovich"} | ||
| def test_merge(data_map, merger): | ||
| def test_merge(data, mergein): | ||
| merged = merge(data_map, merger) | ||
| merged = merge(data, mergein) | ||
| assert merged["name"] == "Duhast" | ||
| assert merged["parental"] == "Vyacheslavovich" |
@@ -23,2 +23,2 @@ """""" | ||
| assert zset(data, "name", "Duhast", merge_inverse=True)["name"] == "Boris" | ||
| assert zset(data, "name", "Duhast", inverse=True)["name"] == "Boris" |
@@ -1,32 +0,61 @@ | ||
| from mapz.methods.update import update | ||
| """Test update method. | ||
| Update performs recursive/shallow update of one dictionary | ||
| with another. | ||
| def test_overwrite(): | ||
| TODO: test updating "brothers" with list instead of dict. | ||
| """ | ||
| dest = {"name": "Duhast", True: False} | ||
| from mapz.methods.update import update, Strategy | ||
| assert update(dest, {"parental": "Vyacheslavovich"}, "overwrite") == { | ||
| import pytest | ||
| @pytest.fixture | ||
| def data(): | ||
| """Provide shared data structure.""" | ||
| return { | ||
| "name": "Duhast", | ||
| "parental": "Vyacheslavovich", | ||
| True: False, | ||
| "brothers": {"Kris": 36, "Mike": 29}, | ||
| } | ||
| assert update(dest, {True: True}, "overwrite") == { | ||
| "name": "Duhast", | ||
| "parental": "Vyacheslavovich", | ||
| True: True, | ||
| } | ||
| def test_shallow(data): | ||
| """Test shallow update.""" | ||
| def test_recursive(): | ||
| # With shallow strategy "parental" key will get seccussfully added to | ||
| # the dest mapping. | ||
| update(data, {"parental": "Vyacheslavovich"}, Strategy.Shallow) | ||
| assert data["name"] == "Duhast" | ||
| assert data["parental"] == "Vyacheslavovich" | ||
| dest = {"person": {"name": "Duhast"}} | ||
| # With shallow strategy "True" get gets successfully overwritten. | ||
| update(data, {True: True}, Strategy.Shallow) | ||
| assert data[True] is True | ||
| assert update(dest, {"person": {"parental": "Vyacheslavovich"}}) == { | ||
| "person": {"name": "Duhast", "parental": "Vyacheslavovich"} | ||
| } | ||
| # However, deeper and nested values are not explored, being instead | ||
| # overwritten in their entirety. | ||
| # As you can see below, whole content of "brothers" key was overwritten | ||
| # instead of updating only "Kris"'s age. | ||
| update(data, {"brothers": {"Kris": 48}}, Strategy.Shallow) | ||
| assert data["brothers"] == {"Kris": 48} | ||
| def test_deep(data): | ||
| """Test deep update.""" | ||
| # Unlike shallow strategy, default update strategy - deep - will | ||
| # recursively look into nested objects to update them properly. | ||
| update(data, {"brothers": {"Kris": 48}}) | ||
| assert data["brothers"] == {"Kris": 48, "Mike": 29} | ||
| def test_update_wrong_args(): | ||
| """Test update with wrong arguments.""" | ||
| # You cannot update None with True. And that would be an error in | ||
| # mypy but "update" is coded in a way to return given object, so | ||
| # it returns initial None. | ||
| assert update(None, True) is None | ||
@@ -38,2 +67,2 @@ | ||
| assert update(True, {1: 2}) == True | ||
| assert update(True, {1: 2}) is True |
@@ -132,3 +132,2 @@ from mapz.mapz import Mapz | ||
| assert m.databases.db1.host == "localhost" | ||
@@ -135,0 +134,0 @@ m.databases.db1.host = "172.31.0.4" |
+1
-1
| Metadata-Version: 2.1 | ||
| Name: mapz | ||
| Version: 1.1.21 | ||
| Version: 1.1.22 | ||
| Summary: Extension of dict features | ||
@@ -5,0 +5,0 @@ Home-page: https://github.com/ilexconf/mapz |
+1
-1
| [tool.poetry] | ||
| name = "mapz" | ||
| version = "1.1.21" | ||
| version = "1.1.22" | ||
| description = "Extension of dict features" | ||
@@ -5,0 +5,0 @@ authors = ["vduseev <vagiz@duseev.com>"] |
+1
-1
@@ -17,3 +17,3 @@ # -*- coding: utf-8 -*- | ||
| 'name': 'mapz', | ||
| 'version': '1.1.21', | ||
| 'version': '1.1.22', | ||
| 'description': 'Extension of dict features', | ||
@@ -20,0 +20,0 @@ 'long_description': '# MapZ\n\n<h2>Extension of standard `dict` capabilities.</h2>\n\n<p>\n <a href="https://github.com/ilexconf/mapz/actions"><img alt="GitHub Workflow Status" src="https://img.shields.io/github/workflow/status/ilexconf/mapz/release?logo=github"></a>\n <a href="https://codecov.io/gh/ilexconf/mapz/"><img alt="Codecov" src="https://img.shields.io/codecov/c/github/ilexconf/mapz?logo=codecov"></a>\n <a href="https://pypi.org/project/mapz/"><img alt="PyPI" src="https://img.shields.io/pypi/v/mapz?color=blue&logo=pypi"></a>\n</p>\n', |
Alert delta unavailable
Currently unable to show alert delta for PyPI packages.
51351
1.26%1389
1.24%