diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 8a03f4a..5951549 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,6 +6,7 @@ Changelog Unreleased ---------- +- Search values in generic mappings with ``includes`` and respect the start offset. - Support ``range`` objects in ``index_of``, including when a start index is supplied. - Merge nested mutable mappings in place instead of replacing their existing contents, including ``UserDict`` and ``ChainMap``, and apply deep defaults and customizers to their entries. diff --git a/src/pydash/chaining/all_funcs.pyi b/src/pydash/chaining/all_funcs.pyi index de08c49..9779b06 100644 --- a/src/pydash/chaining/all_funcs.pyi +++ b/src/pydash/chaining/all_funcs.pyi @@ -1099,7 +1099,7 @@ class AllFuncs: return self._wrap(pyd.group_by)(iteratee) def includes( - self: "Chain[t.Union[t.Sequence[t.Any], t.Dict[t.Any, t.Any]]]", + self: "Chain[t.Union[t.Sequence[t.Any], t.Mapping[t.Any, t.Any]]]", target: t.Any, from_index: int = 0, ) -> "Chain[bool]": diff --git a/src/pydash/collections.py b/src/pydash/collections.py index 9ac27aa..a0355a6 100644 --- a/src/pydash/collections.py +++ b/src/pydash/collections.py @@ -885,11 +885,14 @@ def group_by(collection, iteratee=None): def includes( - collection: t.Union[t.Sequence[t.Any], t.Dict[t.Any, t.Any]], target: t.Any, from_index: int = 0 + collection: t.Union[t.Sequence[t.Any], t.Mapping[t.Any, t.Any]], + target: t.Any, + from_index: int = 0, ) -> bool: """ Checks if a given value is present in a collection. If `from_index` is negative, it is used as - the offset from the end of the collection. + the offset from the end of the collection. For mappings, the search and offset apply to values + in iteration order. Args: collection: Collection to iterate over. @@ -915,7 +918,7 @@ def includes( ``include``. """ collection_values: t.Container[t.Any] - if isinstance(collection, dict): + if isinstance(collection, Mapping): collection_values = list(collection.values())[from_index:] else: collection_values = collection[from_index:] diff --git a/tests/test_collections.py b/tests/test_collections.py index 09a182e..410c245 100644 --- a/tests/test_collections.py +++ b/tests/test_collections.py @@ -1319,9 +1319,11 @@ def test_order_by_mapping_values(mapping_type, orders): assert dict(collection) == source +@parametrize("factory", [dict, UserDict, MappingProxyType]) @parametrize( "target,offset,expected", [ + ("a", 0, False), (1, 1, False), (2, 1, True), (3, 3, False), @@ -1331,10 +1333,11 @@ def test_order_by_mapping_values(mapping_type, orders): (1, 10, False), ], ) -def test_includes_dictionary_offset(target, offset, expected): +def test_includes_mapping_offset(factory, target, offset, expected): source = {"a": 1, "b": 2, "c": 3} - assert _.includes(source, target, from_index=offset) is expected - assert source == {"a": 1, "b": 2, "c": 3} + mapping = factory(source) + assert _.includes(mapping, target, from_index=offset) is expected + assert dict(mapping) == {"a": 1, "b": 2, "c": 3} @parametrize("factory", [dict, UserDict, MappingProxyType])