Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion src/pydash/chaining/all_funcs.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -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]":
Expand Down
9 changes: 6 additions & 3 deletions src/pydash/collections.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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:]
Expand Down
9 changes: 6 additions & 3 deletions tests/test_collections.py
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand All @@ -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])
Expand Down