Skip to content

gh-156743: Document deque.index bound resolution change in 3.14.6 - #157784

Open
MannXo wants to merge 1 commit into
python:mainfrom
MannXo:docs/156743-deque-index-bounds
Open

MannXo wants to merge 1 commit into
python:mainfrom
MannXo:docs/156743-deque-index-bounds

Conversation

@MannXo

@MannXo MannXo commented Sep 19, 2026

Copy link
Copy Markdown
Contributor

deque.index() changed how it resolves start and stop when a bound's
__index__ method mutates the deque. The change is user visible and is not
mentioned in the NEWS entry for gh-150750, which describes only the
free-threading race. gh-156743 reports it.

Before the change, Argument Clinic assigned stop its default of
Py_SIZE(deque) before _PyEval_SliceIndexNotNone converted start, so a
start that mutated the deque during conversion left stop holding the old
length while start was resolved against the new one. stop now defaults to
PY_SSIZE_T_MAX and deque_index_impl reads the length once, after both
converters have run, so the two bounds always agree.

Using the reproducer from the issue:

from collections import deque

d = deque([1, 2, 3])

class Grow:
    def __index__(self):
        d.extend([2, 2, 2])
        return -1

d.index(2, Grow())

3.14.5 and earlier raise ValueError. 3.14.6 and later return 5, which is
also what list.index returns for the equivalent list. The new behaviour takes
a single length snapshot and is self-consistent, so it reads as intended and
only the documentation was missing.

This adds a versionchanged note to deque.index. Documentation only, so no
NEWS entry.

One correction to the issue

The issue reports the change as landing in 3.14.7. It landed in 3.14.6.

The versions tested in the issue were 3.14.0, 3.14.2, 3.14.4 and 3.14.7, which
brackets the change but skips 3.14.6. The note therefore says 3.14.6.

@read-the-docs-community

Copy link
Copy Markdown

Documentation build overview

📚 cpython-previews | 🛠️ Build #34649417 | 📁 Comparing 1ce504f against main (1d0f1ad)

  🔍 Preview build  

1 file changed
± library/collections.html

@picnixz

picnixz commented Sep 19, 2026

Copy link
Copy Markdown
Member

This kind of changes is not worth documenting. Mutating a container while doing other things is not safe. The fix was just there to prevent crashes I believe.

@MannXo

MannXo commented Sep 20, 2026

Copy link
Copy Markdown
Contributor Author

Fair, and the fix was for the crash rather than for this. I opened it because JelleZijlstra asked for the note on the issue, after the reporter said he hit it porting pydantic/monty to an alternate implementation rather than fuzzing:

Agree we should document the behavior change.

If the call is not to document it, I will close this, and #156743 wants closing too rather than staying open with a docs label on 3.14, 3.15 and 3.16.

Either way, one correction. The change landed in 3.14.6, not 3.14.7. The clinic default for stop is Py_SIZE(deque) at v3.14.5 and PY_SSIZE_T_MAX at v3.14.6, and the NEWS entry for gh-150750 is in Misc/NEWS.d/3.14.6.rst. The reporter tested 3.14.4 and 3.14.7 and skipped 3.14.6.

@picnixz

picnixz commented Sep 20, 2026

Copy link
Copy Markdown
Member

Mmj let me think about it a bit more. I can see why it can help but I do not consider that anything python impmementations should bother about (they can raise whatever they want). It is, IMO, a garbage-in/garbage out situation but let me think for a few days.

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

Labels

awaiting review docs Documentation in the Doc dir skip news

Projects

Status: Todo

Development

Successfully merging this pull request may close these issues.

2 participants