(self)
| 175 | |
| 176 | @support.requires_resource('cpu') |
| 177 | def testAppendChildNoQuadraticComplexity(self): |
| 178 | impl = getDOMImplementation() |
| 179 | |
| 180 | def work(n): |
| 181 | doc = impl.createDocument(None, "some_tag", None) |
| 182 | element = doc.documentElement |
| 183 | total_calls = 0 |
| 184 | |
| 185 | # Count attribute accesses as a proxy for work done |
| 186 | def getattribute_counter(self, attr): |
| 187 | nonlocal total_calls |
| 188 | total_calls += 1 |
| 189 | return object.__getattribute__(self, attr) |
| 190 | |
| 191 | with support.swap_attr(Element, "__getattribute__", getattribute_counter): |
| 192 | for _ in range(n): |
| 193 | child = doc.createElement("child") |
| 194 | element.appendChild(child) |
| 195 | element = child |
| 196 | return total_calls |
| 197 | |
| 198 | # Doubling N should not ~quadruple the work. |
| 199 | w1 = work(1024) |
| 200 | w2 = work(2048) |
| 201 | w3 = work(4096) |
| 202 | |
| 203 | self.assertGreater(w1, 0) |
| 204 | r1 = w2 / w1 |
| 205 | r2 = w3 / w2 |
| 206 | self.assertLess( |
| 207 | max(r1, r2), 3.2, |
| 208 | msg=f"Possible quadratic behavior: work={w1,w2,w3} ratios={r1,r2}" |
| 209 | ) |
| 210 | |
| 211 | def testSetAttributeNodeWithoutOwnerDocument(self): |
| 212 | # regression test for gh-142754 |
nothing calls this directly
no test coverage detected