python
runtime_error
ai_generated
true
ERROR: tearDown (tests.test_foo.TestFoo) ... Traceback (最近一次调用最后): File "...", 第 N 行, 在 tearDown 中 self.conn.close() AttributeError: 'NoneType' 对象没有属性 'close'
ERROR: tearDown (tests.test_foo.TestFoo) ... Traceback (most recent call last): File "...", line N, in tearDown self.conn.close() AttributeError: 'NoneType' object has no attribute 'close'
ID: python/unittest-teardown-exception-masks-test
80%修复率
88%置信度
0证据数
2024-04-25首次发现
版本兼容性
| 版本 | 状态 | 引入 | 弃用 | 备注 |
|---|---|---|---|---|
| 3.11 | active | — | — | — |
| 3.12 | active | — | — | — |
根因分析
tearDown 引用了 setUp 未能赋值的属性(例如 setUp 抛出异常或被跳过),导致清理逻辑作用于未初始化的值。
English
tearDown references an attribute that setUp failed to assign (e.g., because setUp raised or was skipped), so the cleanup runs against an uninitialized value.
解决方案
-
94% 成功率
def tearDown(self): conn = getattr(self, 'conn', None) if conn is not None: conn.close() super().tearDown() -
96% 成功率
def setUp(self): self.conn = connect() self.addCleanup(self.conn.close) # addCleanup runs only if the resource was created
无效尝试
常见但无效的做法:
-
70% 失败
Silences the error but leaks resources (open sockets, temp files) and hides genuine teardown bugs, causing cascading failures in later tests.
-
80% 失败
addCleanup still calls the same code path; if the attribute is None the same AttributeError is raised, now reported as a cleanup error.