Python API: edge neighborhood nodes retain visitors after leaving scope

Aperta
#2,542 1 commento 0 reazioni 1 assegnatario Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

@klayoutmatthias ci sta già lavorando.

Dal 10/11/2026.

  • #2543 di @klayoutmatthias — aperta

Valutazione

Questa issue non è ancora stata valutata.

Descrizione

bug

Creating CompoundRegionOperationNode.new_edge_neighborhood leaves its Python visitor alive after the node wrapper and all Python references to the visitor have been dropped. Repeated construction accumulates visitors and any data attached to them. Calling Region.complex_op is not needed to reproduce this.

Expected: once the node and visitor are no longer referenced, the visitor can be collected.

Minimal reproduction:

import gc
import weakref
from typing import List, Tuple
import klayout.db as kdb

class Visitor(kdb.EdgeNeighborhoodVisitor):
    def on_edge(self, layout: kdb.Layout, cell: kdb.Cell, edge: kdb.Edge, neighborhood: List):
        pass

def make() -> Tuple[weakref.ReferenceType, weakref.ReferenceType]:
    visitor = Visitor()
    node = kdb.CompoundRegionOperationNode.new_edge_neighborhood(
        children=[], visitor=visitor)
    return weakref.ref(visitor), weakref.ref(node)

references = [make() for _ in range(100)]
gc.collect()
print("Visitors alive:", sum(visitor() is not None for visitor, _ in references))
print("Node wrappers alive:", sum(node() is not None for _, node in references))

Actual: 100 visitors and zero node wrappers remain alive.

Controls:

  • Constructing and discarding visitors without constructing nodes leaves zero of 100 visitors alive
  • Creating nodes without executing them leaves 1, 10 and 100 visitors alive after 1, 10 and 100 calls
  • Executing complex_op on ordinary flat rectangular regions gives the same 1, 10 and 100 counts
  • The node-only and flat-region reproductions also retain all 100 visitors on Linux with Python 3.12.3

The reproduction has no extraction context, DeepShapeStore, callback instrumentation or retained strong-reference collection. Its observation list contains only weak references.

This is distinct from #2495, which concerned retained on_edge arguments and was fixed by #2501. Here no callback needs to run. In KPEX, each visitor refers to the extraction results, so retained visitors can keep completed extraction data alive when operations are repeated in one process.

The v0.30.13 source appears consistent with this lifetime observation:

Versions:

  • KLayout Python module 0.30.13, Python 3.14.6, macOS 26.6.2
  • Independent node-only and flat-region reproductions: KLayout Python module 0.30.13, Python 3.12.3, Linux
  • The KLayout executable is not involved
  • Source tag v0.30.13, commit 06b8ff4909ad1696c06c634183d8fd0eaa8a1b83
Lingua principale
C++
Stelle
1.2k
Fork
305
Merge medio
3g 2h
PR unite (30g)
11

Preparare l'ambiente

Questo progetto non fornisce container di sviluppo, Dockerfile né guida per i contributori, quindi l'ambiente è a tuo carico: parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di KLayout/klayout

Tutte le issue di KLayout/klayout

Issue simili

Altre issue su C++

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.