From f02ea6225bc3b71bd5fe66224d199a6e3e23b14d Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sun, 1 Sep 2019 11:18:35 +0300 Subject: [PATCH] bpo-36543: Remove old-deprecated ElementTree features. (GH-12707) Remove methods Element.getchildren(), Element.getiterator() and ElementTree.getiterator() and the xml.etree.cElementTree module. --- Doc/library/xml.etree.elementtree.rst | 18 ------ Doc/whatsnew/3.9.rst | 6 ++ Lib/test/test_xml_etree.py | 60 ++++--------------- Lib/xml/etree/ElementTree.py | 31 ---------- .../2019-04-06-20-08-12.bpo-36543.RPjmUz.rst | 2 + Modules/_elementtree.c | 60 ------------------- Modules/clinic/_elementtree.c.h | 55 +---------------- 7 files changed, 19 insertions(+), 213 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2019-04-06-20-08-12.bpo-36543.RPjmUz.rst diff --git a/Doc/library/xml.etree.elementtree.rst b/Doc/library/xml.etree.elementtree.rst index 6047e6e29b9..1b4e2c9b142 100644 --- a/Doc/library/xml.etree.elementtree.rst +++ b/Doc/library/xml.etree.elementtree.rst @@ -873,18 +873,6 @@ Element Objects in the expression into the given namespace. - .. method:: getchildren() - - .. deprecated-removed:: 3.2 3.9 - Use ``list(elem)`` or iteration. - - - .. method:: getiterator(tag=None) - - .. deprecated-removed:: 3.2 3.9 - Use method :meth:`Element.iter` instead. - - .. method:: insert(index, subelement) Inserts *subelement* at the given position in this element. Raises @@ -1019,12 +1007,6 @@ ElementTree Objects Same as :meth:`Element.findtext`, starting at the root of the tree. - .. method:: getiterator(tag=None) - - .. deprecated-removed:: 3.2 3.9 - Use method :meth:`ElementTree.iter` instead. - - .. method:: getroot() Returns the root element for this tree. diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst index e20ae47462e..0a0b91670ca 100644 --- a/Doc/whatsnew/3.9.rst +++ b/Doc/whatsnew/3.9.rst @@ -207,6 +207,12 @@ Removed Use :meth:`~threading.Thread.is_alive()` instead. (Contributed by Dong-hee Na in :issue:`37804`.) +* Methods ``getchildren()`` and ``getiterator()`` in the + :mod:`~xml.etree.ElementTree` module have been removed. They were + deprecated in Python 3.2. Use functions :func:`list` and :func:`iter` + instead. The ``xml.etree.cElementTree`` module has been removed. + (Contributed by Serhiy Storchaka in :issue:`36543`.) + Porting to Python 3.9 ===================== diff --git a/Lib/test/test_xml_etree.py b/Lib/test/test_xml_etree.py index db06aceb146..87a6fa14646 100644 --- a/Lib/test/test_xml_etree.py +++ b/Lib/test/test_xml_etree.py @@ -242,7 +242,6 @@ class ElementTreeTest(unittest.TestCase): check_method(element.extend) check_method(element.insert) check_method(element.remove) - check_method(element.getchildren) check_method(element.find) check_method(element.iterfind) check_method(element.findall) @@ -254,7 +253,6 @@ class ElementTreeTest(unittest.TestCase): check_method(element.items) check_method(element.iter) check_method(element.itertext) - check_method(element.getiterator) # These methods return an iterable. See bug 6472. @@ -741,24 +739,20 @@ class ElementTreeTest(unittest.TestCase): ('end-ns', ''), ]) - # Element.getchildren() and ElementTree.getiterator() are deprecated. - @checkwarnings(("This method will be removed in future versions. " - "Use .+ instead.", - DeprecationWarning)) - def test_getchildren(self): - # Test Element.getchildren() + def test_children(self): + # Test Element children iteration with open(SIMPLE_XMLFILE, "rb") as f: tree = ET.parse(f) - self.assertEqual([summarize_list(elem.getchildren()) + self.assertEqual([summarize_list(elem) for elem in tree.getroot().iter()], [ ['element', 'element', 'empty-element'], [], [], [], ]) - self.assertEqual([summarize_list(elem.getchildren()) - for elem in tree.getiterator()], [ + self.assertEqual([summarize_list(elem) + for elem in tree.iter()], [ ['element', 'element', 'empty-element'], [], [], @@ -766,13 +760,13 @@ class ElementTreeTest(unittest.TestCase): ]) elem = ET.XML(SAMPLE_XML) - self.assertEqual(len(elem.getchildren()), 3) - self.assertEqual(len(elem[2].getchildren()), 1) - self.assertEqual(elem[:], elem.getchildren()) + self.assertEqual(len(list(elem)), 3) + self.assertEqual(len(list(elem[2])), 1) + self.assertEqual(elem[:], list(elem)) child1 = elem[0] child2 = elem[2] del elem[1:2] - self.assertEqual(len(elem.getchildren()), 2) + self.assertEqual(len(list(elem)), 2) self.assertEqual(child1, elem[0]) self.assertEqual(child2, elem[1]) elem[0:2] = [child2, child1] @@ -780,7 +774,7 @@ class ElementTreeTest(unittest.TestCase): self.assertEqual(child1, elem[1]) self.assertNotEqual(child1, elem[0]) elem.clear() - self.assertEqual(elem.getchildren(), []) + self.assertEqual(list(elem), []) def test_writestring(self): elem = ET.XML("text") @@ -2955,40 +2949,6 @@ class ElementIterTest(unittest.TestCase): self.assertEqual(self._ilist(doc), all_tags) self.assertEqual(self._ilist(doc, '*'), all_tags) - # Element.getiterator() is deprecated. - @checkwarnings(("This method will be removed in future versions. " - "Use .+ instead.", DeprecationWarning)) - def test_getiterator(self): - doc = ET.XML(''' - - - bedroom1 - bedroom2 - - nothing here - - - bedroom8 - - ''') - - self.assertEqual(summarize_list(doc.getiterator('room')), - ['room'] * 3) - self.assertEqual(summarize_list(doc.getiterator('house')), - ['house'] * 2) - - # test that getiterator also accepts 'tag' as a keyword arg - self.assertEqual( - summarize_list(doc.getiterator(tag='room')), - ['room'] * 3) - - # make sure both tag=None and tag='*' return all tags - all_tags = ['document', 'house', 'room', 'room', - 'shed', 'house', 'room'] - self.assertEqual(summarize_list(doc.getiterator()), all_tags) - self.assertEqual(summarize_list(doc.getiterator(None)), all_tags) - self.assertEqual(summarize_list(doc.getiterator('*')), all_tags) - def test_copy(self): a = ET.Element('a') it = a.iter() diff --git a/Lib/xml/etree/ElementTree.py b/Lib/xml/etree/ElementTree.py index 431ecd0dddf..beb2d68803a 100644 --- a/Lib/xml/etree/ElementTree.py +++ b/Lib/xml/etree/ElementTree.py @@ -273,19 +273,6 @@ class Element: # assert iselement(element) self._children.remove(subelement) - def getchildren(self): - """(Deprecated) Return all subelements. - - Elements are returned in document order. - - """ - warnings.warn( - "This method will be removed in future versions. " - "Use 'list(elem)' or iteration over elem instead.", - DeprecationWarning, stacklevel=2 - ) - return self._children - def find(self, path, namespaces=None): """Find first matching element by tag name or path. @@ -409,15 +396,6 @@ class Element: for e in self._children: yield from e.iter(tag) - # compatibility - def getiterator(self, tag=None): - warnings.warn( - "This method will be removed in future versions. " - "Use 'elem.iter()' or 'list(elem.iter())' instead.", - DeprecationWarning, stacklevel=2 - ) - return list(self.iter(tag)) - def itertext(self): """Create text iterator. @@ -617,15 +595,6 @@ class ElementTree: # assert self._root is not None return self._root.iter(tag) - # compatibility - def getiterator(self, tag=None): - warnings.warn( - "This method will be removed in future versions. " - "Use 'tree.iter()' or 'list(tree.iter())' instead.", - DeprecationWarning, stacklevel=2 - ) - return list(self.iter(tag)) - def find(self, path, namespaces=None): """Find first matching element by tag name or path. diff --git a/Misc/NEWS.d/next/Library/2019-04-06-20-08-12.bpo-36543.RPjmUz.rst b/Misc/NEWS.d/next/Library/2019-04-06-20-08-12.bpo-36543.RPjmUz.rst new file mode 100644 index 00000000000..1153de872bc --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-04-06-20-08-12.bpo-36543.RPjmUz.rst @@ -0,0 +1,2 @@ +Removed methods Element.getchildren(), Element.getiterator() and +ElementTree.getiterator() and the xml.etree.cElementTree module. diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c index 830ce8635ea..b88e8a1d6e9 100644 --- a/Modules/_elementtree.c +++ b/Modules/_elementtree.c @@ -1426,42 +1426,6 @@ _elementtree_Element_get_impl(ElementObject *self, PyObject *key, return value; } -/*[clinic input] -_elementtree.Element.getchildren - -[clinic start generated code]*/ - -static PyObject * -_elementtree_Element_getchildren_impl(ElementObject *self) -/*[clinic end generated code: output=e50ffe118637b14f input=0f754dfded150d5f]*/ -{ - Py_ssize_t i; - PyObject* list; - - if (PyErr_WarnEx(PyExc_DeprecationWarning, - "This method will be removed in future versions. " - "Use 'list(elem)' or iteration over elem instead.", - 1) < 0) { - return NULL; - } - - if (!self->extra) - return PyList_New(0); - - list = PyList_New(self->extra->length); - if (!list) - return NULL; - - for (i = 0; i < self->extra->length; i++) { - PyObject* item = self->extra->children[i]; - Py_INCREF(item); - PyList_SET_ITEM(list, i, item); - } - - return list; -} - - static PyObject * create_elementiter(ElementObject *self, PyObject *tag, int gettext); @@ -1492,27 +1456,6 @@ _elementtree_Element_iter_impl(ElementObject *self, PyObject *tag) } -/*[clinic input] -_elementtree.Element.getiterator - - tag: object = None - -[clinic start generated code]*/ - -static PyObject * -_elementtree_Element_getiterator_impl(ElementObject *self, PyObject *tag) -/*[clinic end generated code: output=cb69ff4a3742dfa1 input=500da1a03f7b9e28]*/ -{ - if (PyErr_WarnEx(PyExc_DeprecationWarning, - "This method will be removed in future versions. " - "Use 'tree.iter()' or 'list(tree.iter())' instead.", - 1) < 0) { - return NULL; - } - return _elementtree_Element_iter_impl(self, tag); -} - - /*[clinic input] _elementtree.Element.itertext @@ -4220,9 +4163,6 @@ static PyMethodDef element_methods[] = { _ELEMENTTREE_ELEMENT_ITERTEXT_METHODDEF _ELEMENTTREE_ELEMENT_ITERFIND_METHODDEF - _ELEMENTTREE_ELEMENT_GETITERATOR_METHODDEF - _ELEMENTTREE_ELEMENT_GETCHILDREN_METHODDEF - _ELEMENTTREE_ELEMENT_ITEMS_METHODDEF _ELEMENTTREE_ELEMENT_KEYS_METHODDEF diff --git a/Modules/clinic/_elementtree.c.h b/Modules/clinic/_elementtree.c.h index 324e549d486..a58ad737f85 100644 --- a/Modules/clinic/_elementtree.c.h +++ b/Modules/clinic/_elementtree.c.h @@ -355,23 +355,6 @@ exit: return return_value; } -PyDoc_STRVAR(_elementtree_Element_getchildren__doc__, -"getchildren($self, /)\n" -"--\n" -"\n"); - -#define _ELEMENTTREE_ELEMENT_GETCHILDREN_METHODDEF \ - {"getchildren", (PyCFunction)_elementtree_Element_getchildren, METH_NOARGS, _elementtree_Element_getchildren__doc__}, - -static PyObject * -_elementtree_Element_getchildren_impl(ElementObject *self); - -static PyObject * -_elementtree_Element_getchildren(ElementObject *self, PyObject *Py_UNUSED(ignored)) -{ - return _elementtree_Element_getchildren_impl(self); -} - PyDoc_STRVAR(_elementtree_Element_iter__doc__, "iter($self, /, tag=None)\n" "--\n" @@ -408,42 +391,6 @@ exit: return return_value; } -PyDoc_STRVAR(_elementtree_Element_getiterator__doc__, -"getiterator($self, /, tag=None)\n" -"--\n" -"\n"); - -#define _ELEMENTTREE_ELEMENT_GETITERATOR_METHODDEF \ - {"getiterator", (PyCFunction)(void(*)(void))_elementtree_Element_getiterator, METH_FASTCALL|METH_KEYWORDS, _elementtree_Element_getiterator__doc__}, - -static PyObject * -_elementtree_Element_getiterator_impl(ElementObject *self, PyObject *tag); - -static PyObject * -_elementtree_Element_getiterator(ElementObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"tag", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "getiterator", 0}; - PyObject *argsbuf[1]; - Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; - PyObject *tag = Py_None; - - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); - if (!args) { - goto exit; - } - if (!noptargs) { - goto skip_optional_pos; - } - tag = args[0]; -skip_optional_pos: - return_value = _elementtree_Element_getiterator_impl(self, tag); - -exit: - return return_value; -} - PyDoc_STRVAR(_elementtree_Element_itertext__doc__, "itertext($self, /)\n" "--\n" @@ -969,4 +916,4 @@ skip_optional: exit: return return_value; } -/*[clinic end generated code: output=50e0b1954c5f9e0f input=a9049054013a1b77]*/ +/*[clinic end generated code: output=f5dbf9b4a095d310 input=a9049054013a1b77]*/