diff options
-rw-r--r-- | Doc/library/xml.etree.elementtree.rst | 9 | ||||
-rw-r--r-- | Doc/whatsnew/3.12.rst | 8 | ||||
-rw-r--r-- | Lib/test/test_xml_etree.py | 20 | ||||
-rw-r--r-- | Lib/xml/etree/ElementTree.py | 5 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Library/2022-02-05-12-01-58.bpo-38941.8IhvyG.rst | 4 | ||||
-rw-r--r-- | Modules/_elementtree.c | 18 |
6 files changed, 59 insertions, 5 deletions
diff --git a/Doc/library/xml.etree.elementtree.rst b/Doc/library/xml.etree.elementtree.rst index 876de29..f9290f5 100644 --- a/Doc/library/xml.etree.elementtree.rst +++ b/Doc/library/xml.etree.elementtree.rst @@ -1045,9 +1045,9 @@ Element Objects :meth:`~object.__getitem__`, :meth:`~object.__setitem__`, :meth:`~object.__len__`. - Caution: Elements with no subelements will test as ``False``. This behavior - will change in future versions. Use specific ``len(elem)`` or ``elem is - None`` test instead. :: + Caution: Elements with no subelements will test as ``False``. Testing the + truth value of an Element is deprecated and will raise an exception in + Python 3.14. Use specific ``len(elem)`` or ``elem is None`` test instead.:: element = root.find('foo') @@ -1057,6 +1057,9 @@ Element Objects if element is None: print("element not found") + .. versionchanged:: 3.12 + Testing the truth value of an Element emits :exc:`DeprecationWarning`. + Prior to Python 3.8, the serialisation order of the XML attributes of elements was artificially made predictable by sorting the attributes by their name. Based on the now guaranteed ordering of dicts, this arbitrary diff --git a/Doc/whatsnew/3.12.rst b/Doc/whatsnew/3.12.rst index 164cd89..3cab897 100644 --- a/Doc/whatsnew/3.12.rst +++ b/Doc/whatsnew/3.12.rst @@ -425,6 +425,11 @@ Deprecated is no current event loop set and it decides to create one. (Contributed by Serhiy Storchaka and Guido van Rossum in :gh:`100160`.) +* The :mod:`xml.etree.ElementTree` module now emits :exc:`DeprecationWarning` + when testing the truth value of an :class:`xml.etree.ElementTree.Element`. + Before, the Python implementation emitted :exc:`FutureWarning`, and the C + implementation emitted nothing. + Pending Removal in Python 3.13 ------------------------------ @@ -487,6 +492,9 @@ Pending Removal in Python 3.14 * ``__package__`` and ``__cached__`` will cease to be set or taken into consideration by the import system (:gh:`97879`). +* Testing the truth value of an :class:`xml.etree.ElementTree.Element` + is deprecated and will raise an exception in Python 3.14. + Pending Removal in Future Versions ---------------------------------- diff --git a/Lib/test/test_xml_etree.py b/Lib/test/test_xml_etree.py index ee3154e..ca5bb56 100644 --- a/Lib/test/test_xml_etree.py +++ b/Lib/test/test_xml_etree.py @@ -3957,6 +3957,25 @@ class NoAcceleratorTest(unittest.TestCase): self.assertIsInstance(pyET.Element.__init__, types.FunctionType) self.assertIsInstance(pyET.XMLParser.__init__, types.FunctionType) +# -------------------------------------------------------------------- + +class BoolTest(unittest.TestCase): + def test_warning(self): + e = ET.fromstring('<a style="new"></a>') + msg = ( + r"Testing an element's truth value will raise an exception in " + r"future versions. " + r"Use specific 'len\(elem\)' or 'elem is not None' test instead.") + with self.assertWarnsRegex(DeprecationWarning, msg): + result = bool(e) + # Emulate prior behavior for now + self.assertIs(result, False) + + # Element with children + ET.SubElement(e, 'b') + with self.assertWarnsRegex(DeprecationWarning, msg): + new_result = bool(e) + self.assertIs(new_result, True) # -------------------------------------------------------------------- @@ -4223,6 +4242,7 @@ def test_main(module=None): XMLPullParserTest, BugsTest, KeywordArgsTest, + BoolTest, C14NTest, ] diff --git a/Lib/xml/etree/ElementTree.py b/Lib/xml/etree/ElementTree.py index df5d519..42574ee 100644 --- a/Lib/xml/etree/ElementTree.py +++ b/Lib/xml/etree/ElementTree.py @@ -200,9 +200,10 @@ class Element: def __bool__(self): warnings.warn( - "The behavior of this method will change in future versions. " + "Testing an element's truth value will raise an exception in " + "future versions. " "Use specific 'len(elem)' or 'elem is not None' test instead.", - FutureWarning, stacklevel=2 + DeprecationWarning, stacklevel=2 ) return len(self._children) != 0 # emulate old behaviour, for now diff --git a/Misc/NEWS.d/next/Library/2022-02-05-12-01-58.bpo-38941.8IhvyG.rst b/Misc/NEWS.d/next/Library/2022-02-05-12-01-58.bpo-38941.8IhvyG.rst new file mode 100644 index 0000000..5f99604 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-02-05-12-01-58.bpo-38941.8IhvyG.rst @@ -0,0 +1,4 @@ +The :mod:`xml.etree.ElementTree` module now emits :exc:`DeprecationWarning` +when testing the truth value of an :class:`xml.etree.ElementTree.Element`. +Before, the Python implementation emitted :exc:`FutureWarning`, and the C +implementation emitted nothing. diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c index 3be098a..df1ebc3 100644 --- a/Modules/_elementtree.c +++ b/Modules/_elementtree.c @@ -1449,6 +1449,23 @@ element_getitem(PyObject* self_, Py_ssize_t index) return Py_NewRef(self->extra->children[index]); } +static int +element_bool(PyObject* self_) +{ + ElementObject* self = (ElementObject*) self_; + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Testing an element's truth value will raise an exception " + "in future versions. Use specific 'len(elem)' or " + "'elem is not None' test instead.", + 1) < 0) { + return -1; + }; + if (self->extra ? self->extra->length : 0) { + return 1; + } + return 0; +} + /*[clinic input] _elementtree.Element.insert @@ -4156,6 +4173,7 @@ static PyType_Slot element_slots[] = { {Py_sq_length, element_length}, {Py_sq_item, element_getitem}, {Py_sq_ass_item, element_setitem}, + {Py_nb_bool, element_bool}, {Py_mp_length, element_length}, {Py_mp_subscript, element_subscr}, {Py_mp_ass_subscript, element_ass_subscr}, |