diff --git a/src/pydash/arrays.py b/src/pydash/arrays.py index 15fda4b..f87e38b 100644 --- a/src/pydash/arrays.py +++ b/src/pydash/arrays.py @@ -531,13 +531,18 @@ def fill( .. versionadded:: 3.1.0 """ - if end is None: - end = len(array) - else: - end = min(end, len(array)) + length = len(array) - # Use this style of assignment so that `array` is mutated. - array[:] = array[:start] + [value] * len(array[start:end]) + array[end:] # type: ignore + if end is None: + end = length + + # Normalize to ``[0, length]``, negatives as slicing does, and fill in + # place so the length stays fixed. + start = max(length + start, 0) if start < 0 else min(start, length) + end = max(length + end, 0) if end < 0 else min(end, length) + + for index in range(start, end): + array[index] = value # type: ignore return array # type: ignore diff --git a/tests/test_arrays.py b/tests/test_arrays.py index ff4d668..dedd309 100644 --- a/tests/test_arrays.py +++ b/tests/test_arrays.py @@ -158,6 +158,14 @@ def test_duplicates(case, expected): (([1, 2, 3, 4, 5], 0, 0, 5), [0, 0, 0, 0, 0]), (([1, 2, 3, 4, 5], 0, 0, 8), [0, 0, 0, 0, 0]), (([1, 2, 3, 4, 5], 0, 0, -1), [0, 0, 0, 0, 5]), + # start after end must be a no-op and must not grow the array. + (([1, 2, 3, 4], "x", 4, 1), [1, 2, 3, 4]), + (([1, 2, 3, 4, 5], 0, 3, 2), [1, 2, 3, 4, 5]), + # negative start supported the same way slicing does. + (([1, 2, 3, 4, 5], 0, -2), [1, 2, 3, 0, 0]), + (([1, 2, 3, 4, 5], 0, -2, -1), [1, 2, 3, 0, 5]), + # reversed negative span is a no-op, not an array-growing overlap. + (([1, 2, 3], "x", -1, -2), [1, 2, 3]), ], ) def test_fill(case, expected):