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 |
|---|---|---|
| @@ -2680,10 +2680,28 @@ class Y(X, ET.Element): | ||
| e = ET.Element('foo') | ||
| e.extend(L) | ||
| def test_remove_with_clear_child(self): | ||
| class X(ET.Element): | ||
| def __eq__(self, o): | ||
| del e[:] | ||
| return False | ||
| # The pure Python implementation raises a ValueError but the C | ||
| # implementation raises a RuntimeError (like OrderedDict does). | ||
| exc_type = ValueError if ET is pyET else RuntimeError | ||
| e = ET.Element('foo') | ||
| e.extend([X('bar')]) | ||
| self.assertRaises(exc_type, e.remove, ET.Element('baz')) | ||
| e = ET.Element('foo') | ||
| e.extend([ET.Element('bar')]) | ||
| self.assertRaises(exc_type, e.remove, X('baz')) | ||
| def test_remove_with_clear_children(self): | ||
| # See: https://github.com/python/cpython/issues/126033 | ||
| classX(ET.Element): | ||
| def __eq__(self, o): | ||
| root.clear() | ||
picnixz marked this conversation as resolved. OutdatedShow resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
| return False | ||
| @@ -2692,39 +2710,36 @@ def __eq__(self, o): | ||
| # implementation raises a RuntimeError (like OrderedDict does). | ||
| exc_type = ValueError if ET is pyET else RuntimeError | ||
| for foo_type, rem_type in [(X, ET.Element), (ET.Element, X)]: | ||
picnixz marked this conversation as resolved. OutdatedShow resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
| with self.subTest(foo_type=foo_type, rem_type=rem_type): | ||
| root = ET.Element('.') | ||
| root.extend([foo_type('foo'), rem_type('bar')]) | ||
| self.assertRaises(exc_type, root.remove, rem_type('baz')) | ||
| def test_remove_with_mutate_root(self): | ||
| # See: https://github.com/python/cpython/issues/126033 | ||
| first_element = ET.Element('foo') | ||
| class X(ET.Element): | ||
| def __eq__(self, o): | ||
| # Remove the first element so that the list size changes. | ||
| # This causes an infinite recursion error in the Python | ||
| # implementation, but we do not really care about it. | ||
| # | ||
| # Depending on whether the first element is or is not | ||
| root.remove(first_element) | ||
| return False | ||
| # The pure Python implementation raises a ValueError but the C | ||
| # implementation raises a RuntimeError (like OrderedDict does). | ||
| exc_type = ValueError if ET is pyET else RuntimeError | ||
| for bar_type, rem_type in [(X, ET.Element), (ET.Element, X), (X, X)]: | ||
picnixz marked this conversation as resolved. OutdatedShow resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
| with self.subTest(bar_type=bar_type, rem_type=rem_type): | ||
| root = ET.Element('.') | ||
| root.extend([first_element, bar_type('bar')]) | ||
| self.assertRaises(exc_type, root.remove, rem_type('baz')) | ||
| @support.infinite_recursion(25) | ||
| def test_recursive_repr(self): | ||
Uh oh!
There was an error while loading.Please reload this page.