Skip to content

Fix UniqueList membership after indexed replacement - #51

Merged
wolph merged 1 commit into
wolph:developfrom
shkyyy18:fix/unique-list-indexed-membership
Oct 2, 2026
Merged

wolph merged 1 commit into
wolph:developfrom
shkyyy18:fix/unique-list-indexed-membership

Conversation

@shkyyy18

@shkyyy18 shkyyy18 commented Oct 1, 2026

Copy link
Copy Markdown

Bug

Replacing an indexed UniqueList element leaves the removed value in its membership set:

values = UniqueList(1, 2)
values[0] = 3
assert values == [3, 2]
1 in values  # currently True
values.append(1)  # silently ignored; raises with on_duplicate="raise"

An out-of-range replacement also adds the new value to the set before list.__setitem__ raises IndexError. Future valid appends are then incorrectly treated as duplicates.

Change

Read the existing item first to validate the index, perform the indexed replacement, and only then remove the old value and add the new value to the membership set. Existing duplicate policies and same-value assignments are preserved. This patch is deliberately limited to indexed assignment; it does not change slice assignment or other list mutators.

Add regression tests for positive/negative indices in both duplicate modes, failed out-of-range replacements, and same-value controls, plus a changelog entry.

Validation

Python 3.12 on Windows:

  • New cases before the fix: 8 failed, 2 passed.
  • Full suite after: 113 passed, 1 failed, with 100% branch coverage. The failure is the existing timing-sensitive test_aio_generator_timeout_detector_decorator_clean_exit (i == 3 instead of 4); unmodified baseline is 103 passed, 1 failed with the same failure, also reproduced in isolation.
  • Excluding only that baseline test: 113 passed, 1 deselected, 100% branch coverage.
  • Ruff lint, formatting of both changed Python files, mypy, basedpyright, pyrefly and codespell: passed. Repository formatting was also checked against LF Git contents to avoid this checkout's CRLF-only differences.
  • Full Python/platform matrix and docs build were not run. No changes to the unrelated timing test or project configuration.

AI assistance was used to identify, implement, and test this fix. Tests use synthetic lists only.

@wolph

wolph commented Oct 2, 2026

Copy link
Copy Markdown
Owner

Thank you for the fix and the thorough tests!

While reviewing it I found that slice assignment, extend, pop, remove and clear had the same problem, so I've built on top of your commit in #52 to cover those as well. I'm working on a new release with both, should be out soon :)

@wolph
wolph merged commit 4d90688 into wolph:develop Oct 2, 2026
@wolph

wolph commented Oct 2, 2026

Copy link
Copy Markdown
Owner

I've created a new release (v4.1.0) which includes your fix, thanks again for the help :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants