Python API: edge neighborhood nodes retain visitors after leaving scope

未关闭
#2,542 1 条评论 0 个 reaction 已指派 1 人 在 GitHub 查看

维护者通常 1 天内回复

@klayoutmatthias 已经在做这个了。

开始于 2026年11月10日。

  • #2543 来自 @klayoutmatthias —— 未关闭

评估

这个 Issue 还没有评估数据。

描述

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
主要语言
C++
星标
1.2k
派生
305
平均合并
3 天 2 小时
30 天内合并 PR
11

环境准备

这个项目没有提供开发容器、Dockerfile 或贡献指南,环境需要你自己搭建:先看它的 README,通用步骤见我们的新手贡献指南。

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

KLayout/klayout 的其他 Issue

查看 KLayout/klayout 的全部 Issue

相似的 Issue

更多 C++ Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。