Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork33.7k
gh-126033: fix a crash inxml.etree.ElementTree.Element.remove when concurrent mutations happen#126124
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
gh-126033: fix a crash inxml.etree.ElementTree.Element.remove when concurrent mutations happen#126124
Changes from1 commit
abc121c4efa5174ca3cf0a1950d19b6f55900a7a7e59ade8f7fc9932e30756df2b5bb19f7351770f2aad756b1eb4b74caffd29203e7033b64d3cdd7883e8d2220b6697f26430e8d84c83a43c0fbc52c04f4a4dae09a9fa9f5d352f2b47468dc576abce66ac704cb600a0c2324File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading.Please reload this page.
Jump to
Uh oh!
There was an error while loading.Please reload this page.
Diff view
Diff view
- Loading branch information
Uh oh!
There was an error while loading.Please reload this page.
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -2643,10 +2643,6 @@ def test_pickle_issue18997(self): | ||
| class BadElementTest(ElementTestCase, unittest.TestCase): | ||
| def test_extend_mutable_list(self): | ||
| class X: | ||
| @property | ||
| @@ -2695,80 +2691,84 @@ def test_remove_with_clear(self): | ||
| E = ET.Element | ||
| def test_remove(root, target, raises): | ||
picnixz marked this conversation as resolved. OutdatedShow resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
| if raises: | ||
| self.assertRaises(ValueError, root.remove, target) | ||
| else: | ||
| root.remove(target) | ||
| self.assertNotIn(target, root) | ||
picnixz marked this conversation as resolved. OutdatedShow resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
| for raises in [True, False]: | ||
| class X(E): | ||
| def __eq__(self, o): | ||
| del root[:] | ||
| return not raises | ||
| class Y(E): | ||
| def __eq__(self, o): | ||
| root.clear() | ||
| return not raises | ||
| for etype, rem_type in [(E, X), (X, E), (E, Y), (Y, E)]: | ||
| with self.subTest( | ||
| etype=etype, rem_type=rem_type, raises=raises, | ||
| ): | ||
| with self.subTest("single child"): | ||
| root = E('.') | ||
picnixz marked this conversation as resolved. OutdatedShow resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
| root.append(etype('one')) | ||
| test_remove(root, rem_type('baz'), raises) | ||
| with self.subTest("with children"): | ||
| root = E('.') | ||
| root.extend([etype('one'), rem_type('two')]) | ||
| test_remove(root, rem_type('baz'), raises) | ||
| def test_remove_with_mutate_root_1(self): | ||
| # See: https://github.com/python/cpython/issues/126033 | ||
| E = ET.Element | ||
| class X(E): | ||
| def __eq__(self, o): | ||
| del root[0] | ||
| return False | ||
| for etype, rem_type in [(E, X), (X, E)]: | ||
| with self.subTest('missing', etype=etype, rem_type=rem_type): | ||
| root = E('.') | ||
| root.extend([E('one'), etype('two')]) | ||
| to_remove = rem_type('baz') | ||
| self.assertRaises(ValueError, root.remove, to_remove) | ||
| with self.subTest('existing', etype=etype, rem_type=rem_type): | ||
| root = E('.') | ||
| root.extend([E('one'), etype('same')]) | ||
| to_remove = rem_type('same') | ||
| self.assertRaises(ValueError, root.remove, to_remove) | ||
| def test_remove_with_mutate_root_2(self): | ||
| # See: https://github.com/python/cpython/issues/126033 | ||
| E = ET.Element | ||
| class X(E): | ||
| def __eq__(self, o): | ||
| del root[0] | ||
| return True | ||
| for etype, rem_type in [(E, X), (X, E)]: | ||
| with self.subTest('missing', etype=etype, rem_type=rem_type): | ||
| root = E('.') | ||
| root.extend([E('one'),etype('two')]) | ||
| to_remove = rem_type('baz') | ||
| root.remove(to_remove) | ||
| with self.subTest('existing', etype=etype, rem_type=rem_type): | ||
| root = E('.') | ||
| root.extend([E('one'), etype('same')]) | ||
| to_remove = rem_type('same') | ||
| root.remove(to_remove) | ||
| @support.infinite_recursion(25) | ||
| def test_recursive_repr(self): | ||
Uh oh!
There was an error while loading.Please reload this page.