GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — ElementTree slice assignment with start greater than stop duplicates a child without owning its second reference · Issue #161689 · python/cpython

ElementTree slice assignment with start greater than stop duplicates a child without owning its second reference #161689

New issue
Copy link
New issue
Copy link
Open
Open
ElementTree slice assignment with start greater than stop duplicates a child without owning its second reference#161689
Copy link
Labels
interpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)topic-XMLtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error

Description

@Broyojo
Broyojo
opened on Nov 9, 2026
Issue body actions

Bug report

Assigning to a step-1 slice with start > stop should insert at start, as a list does. The C Element implementation shifts from stop but writes from start. This duplicates one child without incrementing its reference count and overwrites another child's slot without releasing its reference.

import sys
import xml.etree.ElementTree as ET
kids = [ET.Element('a%d' % i) for i in range(7)]
e = ET.Element('r')
e[:] = kids
before = sys.getrefcount(kids[2])
e[5:2] = [ET.Element('X')]
tags = [c.tag for c in e]
print(tags, 'refcount change of a2:', sys.getrefcount(kids[2]) - before)

Recorded on 3.15.2 and main:

['a0', 'a1', 'a2', 'a2', 'a3', 'X', 'a5', 'a6'] refcount change of a2: 0

Expected, also obtained with the pure-Python Element implementation:

['a0', 'a1', 'a2', 'a3', 'a4', 'X', 'a5', 'a6']

The duplicate a2 has no additional owned reference. Releasing the parent therefore decrements it twice, potentially freeing it while kids still holds it. The record confirms this lifetime error separately; the reproducer above shows the wrong slots and missing reference without adding an allocator-reuse demonstration.

Cause: Modules/_elementtree.c:1976-1977 uses PySlice_AdjustIndices without normalizing a backward empty slice. The insertion loop at :2026-2030 shifts from stop, whereas replacement at :2033-2037 starts at start. Normalize stop to start for a positive step with stop < start, as list slice assignment does. No reentrancy or threads are required.

CPython versions tested on:

3.15, CPython main branch

Operating systems tested on:

Linux


Found while building a Lean 4 model of CPython (https://broyojo.com/python-formalization/). AI tools (Claude and Codex) helped investigate the findings and prepare this report. The examples were rerun on CPython 3.15.2 and main, and the report received technical review. Record: textlibs-etree-slice-backward-dup

Linked PRs

  • gh-161689: Insert at start for a backward slice assignment to an Element #161736

Activity

  1. NekoAsakura
    added
    type-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
    interpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)
    topic-XML
    on Nov 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    interpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)topic-XMLtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      You are visitor 01402503 — GeezerVison does not store the pages you look up.
      Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.