From be1eafb7b9d23d871015455a4bad0aff3980a497 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Piotr=20Ma=C5=9Blanka?= <piotr.maslanka@henrietta.com.pl>
Date: Fri, 27 Aug 2021 19:55:08 +0200
Subject: [PATCH] added is_subset, v2.17.20

---
 CHANGELOG.md                            |  2 ++
 docs/coding/transforms.rst              |  2 ++
 satella/__init__.py                     |  2 +-
 satella/coding/transforms/__init__.py   |  3 ++-
 satella/coding/transforms/predicates.py | 18 ++++++++++++++++++
 tests/test_coding/test_transforms.py    |  9 ++++++++-
 6 files changed, 33 insertions(+), 3 deletions(-)
 create mode 100644 satella/coding/transforms/predicates.py

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2830c801..a9b10366 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1 +1,3 @@
 # v2.17.20
+
+* added is_subset
diff --git a/docs/coding/transforms.rst b/docs/coding/transforms.rst
index dbb63f8b..702c54c1 100644
--- a/docs/coding/transforms.rst
+++ b/docs/coding/transforms.rst
@@ -1,6 +1,8 @@
 Rudimentary data transforms and algorithms
 ==========================================
 
+.. autofunction:: satella.coding.transforms.is_subset
+
 .. autoclass:: satella.coding.transforms.merge_list
 
 .. autofunction:: satella.coding.transforms.hashables_to_int
diff --git a/satella/__init__.py b/satella/__init__.py
index 44f81345..ace31da4 100644
--- a/satella/__init__.py
+++ b/satella/__init__.py
@@ -1 +1 @@
-__version__ = '2.17.20a2'
+__version__ = '2.17.20'
diff --git a/satella/coding/transforms/__init__.py b/satella/coding/transforms/__init__.py
index 5dd08e5a..4104511e 100644
--- a/satella/coding/transforms/__init__.py
+++ b/satella/coding/transforms/__init__.py
@@ -11,11 +11,12 @@ from .percentile import percentile
 from .base64 import b64encode
 from .interpol import linear_interpolate
 from .words import hashables_to_int
+from .predicates import is_subset
 
 __all__ = ['stringify', 'split_shuffle_and_join', 'one_tuple', 'none_if_false',
            'merge_series', 'pad_to_multiple_of_length', 'clip', 'hashables_to_int',
            'jsonify', 'intify', 'percentile', 'b64encode', 'linear_interpolate',
-           'merge_list']
+           'merge_list', 'is_subset']
 
 from satella.coding.typing import T, NoArgCallable, Appendable, Number, Predicate
 
diff --git a/satella/coding/transforms/predicates.py b/satella/coding/transforms/predicates.py
new file mode 100644
index 00000000..994dbfa2
--- /dev/null
+++ b/satella/coding/transforms/predicates.py
@@ -0,0 +1,18 @@
+import typing as tp
+
+
+def is_subset(subset: tp.Dict, superset: tp.Dict) -> bool:
+    """
+    Does superset contain all keys of subset, and are their values equal?
+
+    :param subset: the set that contains all the keys
+    :param superset: the set that is to contain all the keys in subset, and their values
+        have to be equal
+    :return: does the condition hold?
+    """
+    for k, v in subset:
+        if k not in superset:
+            return False
+        if v != superset[k]:
+            return False
+    return True
diff --git a/tests/test_coding/test_transforms.py b/tests/test_coding/test_transforms.py
index cd0dd3c6..202767ab 100644
--- a/tests/test_coding/test_transforms.py
+++ b/tests/test_coding/test_transforms.py
@@ -5,11 +5,18 @@ import base64
 
 from satella.coding.transforms import stringify, split_shuffle_and_join, one_tuple, \
     merge_series, pad_to_multiple_of_length, clip, b64encode, linear_interpolate, \
-    hashables_to_int, none_if_false, merge_list
+    hashables_to_int, none_if_false, merge_list, is_subset
 
 
 class TestTransforms(unittest.TestCase):
 
+    def test_is_subset(self):
+        self.assertTrue(is_subset({}, {}))
+        self.assertTrue(is_subset({}, {1: 2}))
+        self.assertFalse(is_subset({2: 3}, {1: 2}))
+        self.assertFalse(is_subset({1: 3}, {1: 2}))
+        self.assertTrue(is_subset({1: 2}, {1: 2}))
+
     def test_merge_list(self):
         a = [(1, 1), (2, 2), (3, 3)]
         b = [(1, 2), (3, 2), (4, 4)]
-- 
GitLab