Skip to content

Commit 3207edc

Browse files
bpo-29209: Remove old-deprecated features in ElementTree.
Also make getchildren() and getiterator() emitting a DeprecationWarning instead of PendingDeprecationWarning.
1 parent 7ec8f28 commit 3207edc

7 files changed

Lines changed: 74 additions & 182 deletions

File tree

Doc/library/xml.etree.elementtree.rst

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -772,13 +772,13 @@ Element Objects
772772

773773
.. method:: getchildren()
774774

775-
.. deprecated:: 3.2
775+
.. deprecated-removed:: 3.2 3.9
776776
Use ``list(elem)`` or iteration.
777777

778778

779779
.. method:: getiterator(tag=None)
780780

781-
.. deprecated:: 3.2
781+
.. deprecated-removed:: 3.2 3.9
782782
Use method :meth:`Element.iter` instead.
783783

784784

@@ -888,7 +888,7 @@ ElementTree Objects
888888

889889
.. method:: getiterator(tag=None)
890890

891-
.. deprecated:: 3.2
891+
.. deprecated-removed:: 3.2 3.9
892892
Use method :meth:`ElementTree.iter` instead.
893893

894894

@@ -1050,20 +1050,20 @@ XMLParser Objects
10501050
^^^^^^^^^^^^^^^^^
10511051

10521052

1053-
.. class:: XMLParser(html=0, target=None, encoding=None)
1053+
.. class:: XMLParser(*, target=None, encoding=None)
10541054

10551055
This class is the low-level building block of the module. It uses
10561056
:mod:`xml.parsers.expat` for efficient, event-based parsing of XML. It can
10571057
be fed XML data incrementally with the :meth:`feed` method, and parsing
10581058
events are translated to a push API - by invoking callbacks on the *target*
10591059
object. If *target* is omitted, the standard :class:`TreeBuilder` is used.
1060-
The *html* argument was historically used for backwards compatibility and is
1061-
now deprecated. If *encoding* [1]_ is given, the value overrides the
1060+
If *encoding* [1]_ is given, the value overrides the
10621061
encoding specified in the XML file.
10631062

1064-
.. deprecated:: 3.4
1065-
The *html* argument. The remaining arguments should be passed via
1066-
keyword to prepare for the removal of the *html* argument.
1063+
.. versionchanged:: 3.8
1064+
Parameters are now :ref:`keyword-only <keyword-only_parameter>`.
1065+
The *html* argument no longer supported.
1066+
10671067

10681068
.. method:: close()
10691069

@@ -1072,13 +1072,6 @@ XMLParser Objects
10721072
this is the toplevel document element.
10731073

10741074

1075-
.. method:: doctype(name, pubid, system)
1076-
1077-
.. deprecated:: 3.2
1078-
Define the :meth:`TreeBuilder.doctype` method on a custom TreeBuilder
1079-
target.
1080-
1081-
10821075
.. method:: feed(data)
10831076

10841077
Feeds data to the parser. *data* is encoded data.

Doc/whatsnew/3.8.rst

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,11 @@ Build and C API Changes
106106
Deprecated
107107
==========
108108

109+
* Deprecated methods ``getchildren()`` and ``getiterator()`` in
110+
the :mod:`~xml.etree.ElementTree` module emit now a
111+
:exc:`DeprecationWarning` instead of :exc:`PendingDeprecationWarning`.
112+
They will be removed in 3.9.
113+
(Contributed by Serhiy Storchaka in :issue:`29209`.)
109114

110115

111116
Removed
@@ -115,6 +120,15 @@ Removed
115120
to help eliminate confusion as to what Python interpreter the ``pyvenv``
116121
script is tied to. (Contributed by Brett Cannon in :issue:`25427`.)
117122

123+
* The :class:`~xml.etree.ElementTree.XMLParser` constructor no longer accepts
124+
the *html* argument. It never had effect and was deprecated in Python 3.4.
125+
All other parameters are now :ref:`keyword-only <keyword-only_parameter>`.
126+
(Contributed by Serhiy Storchaka in :issue:`29209`.)
127+
128+
* Removed the ``doctype()`` method of :class:`~xml.etree.ElementTree.XMLParser`.
129+
(Contributed by Serhiy Storchaka in :issue:`29209`.)
130+
131+
118132

119133
Porting to Python 3.8
120134
=====================
@@ -146,6 +160,13 @@ Changes in the Python API
146160
a database if it does not exist.
147161
(Contributed by Serhiy Storchaka in :issue:`32749`.)
148162

163+
* The ``doctype()`` method defined in a subclass of
164+
:class:`~xml.etree.ElementTree.XMLParser` will no longer be called and will
165+
cause emitting a :exc:`RuntimeWarning` instead of a :exc:`DeprecationWarning`.
166+
Define the :meth:`doctype() <xml.etree.ElementTree.TreeBuilder.doctype>`
167+
method on a target for handling an XML doctype declaration.
168+
(Contributed by Serhiy Storchaka in :issue:`29209`.)
169+
149170

150171
CPython bytecode changes
151172
------------------------

Lib/test/test_xml_etree.py

Lines changed: 8 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -705,7 +705,7 @@ def comment(self, data):
705705
# Element.getchildren() and ElementTree.getiterator() are deprecated.
706706
@checkwarnings(("This method will be removed in future versions. "
707707
"Use .+ instead.",
708-
(DeprecationWarning, PendingDeprecationWarning)))
708+
DeprecationWarning))
709709
def test_getchildren(self):
710710
# Test Element.getchildren()
711711

@@ -2398,7 +2398,7 @@ def test_iter_by_tag(self):
23982398

23992399
# Element.getiterator() is deprecated.
24002400
@checkwarnings(("This method will be removed in future versions. "
2401-
"Use .+ instead.", PendingDeprecationWarning))
2401+
"Use .+ instead.", DeprecationWarning))
24022402
def test_getiterator(self):
24032403
doc = ET.XML('''
24042404
<document>
@@ -2604,14 +2604,6 @@ def _check_sample_element(self, e):
26042604
self.assertEqual(e[0].text, '22')
26052605

26062606
def test_constructor_args(self):
2607-
# Positional args. The first (html) is not supported, but should be
2608-
# nevertheless correctly accepted.
2609-
with self.assertWarnsRegex(DeprecationWarning, r'\bhtml\b'):
2610-
parser = ET.XMLParser(None, ET.TreeBuilder(), 'utf-8')
2611-
parser.feed(self.sample1)
2612-
self._check_sample_element(parser.close())
2613-
2614-
# Now as keyword args.
26152607
parser2 = ET.XMLParser(encoding='utf-8',
26162608
target=ET.TreeBuilder())
26172609
parser2.feed(self.sample1)
@@ -2625,13 +2617,6 @@ class MyParser(ET.XMLParser):
26252617
self._check_sample_element(parser.close())
26262618

26272619
def test_doctype_warning(self):
2628-
parser = ET.XMLParser()
2629-
with self.assertWarns(DeprecationWarning):
2630-
parser.doctype('html', '-//W3C//DTD XHTML 1.0 Transitional//EN',
2631-
'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd')
2632-
parser.feed('<html/>')
2633-
parser.close()
2634-
26352620
with warnings.catch_warnings():
26362621
warnings.simplefilter('error', DeprecationWarning)
26372622
parser = ET.XMLParser()
@@ -2641,21 +2626,20 @@ def test_doctype_warning(self):
26412626
def test_subclass_doctype(self):
26422627
_doctype = None
26432628
class MyParserWithDoctype(ET.XMLParser):
2644-
def doctype(self, name, pubid, system):
2629+
def doctype(self, *args, **kwargs):
26452630
nonlocal _doctype
2646-
_doctype = (name, pubid, system)
2631+
_doctype = (args, kwargs)
26472632

26482633
parser = MyParserWithDoctype()
2649-
with self.assertWarns(DeprecationWarning):
2634+
with self.assertWarnsRegex(RuntimeWarning, 'doctype'):
26502635
parser.feed(self.sample2)
26512636
parser.close()
2652-
self.assertEqual(_doctype,
2653-
('html', '-//W3C//DTD XHTML 1.0 Transitional//EN',
2654-
'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'))
2637+
self.assertIsNone(_doctype)
26552638

26562639
_doctype = _doctype2 = None
26572640
with warnings.catch_warnings():
26582641
warnings.simplefilter('error', DeprecationWarning)
2642+
warnings.simplefilter('error', RuntimeWarning)
26592643
class DoctypeParser:
26602644
def doctype(self, name, pubid, system):
26612645
nonlocal _doctype2
@@ -2673,6 +2657,7 @@ def test_inherited_doctype(self):
26732657
'''Ensure that ordinary usage is not deprecated (Issue 19176)'''
26742658
with warnings.catch_warnings():
26752659
warnings.simplefilter('error', DeprecationWarning)
2660+
warnings.simplefilter('error', RuntimeWarning)
26762661
class MyParserWithoutDoctype(ET.XMLParser):
26772662
pass
26782663
parser = MyParserWithoutDoctype()

Lib/xml/etree/ElementTree.py

Lines changed: 9 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -412,11 +412,10 @@ def iter(self, tag=None):
412412

413413
# compatibility
414414
def getiterator(self, tag=None):
415-
# Change for a DeprecationWarning in 1.4
416415
warnings.warn(
417416
"This method will be removed in future versions. "
418417
"Use 'elem.iter()' or 'list(elem.iter())' instead.",
419-
PendingDeprecationWarning, stacklevel=2
418+
DeprecationWarning, stacklevel=2
420419
)
421420
return list(self.iter(tag))
422421

@@ -622,11 +621,10 @@ def iter(self, tag=None):
622621

623622
# compatibility
624623
def getiterator(self, tag=None):
625-
# Change for a DeprecationWarning in 1.4
626624
warnings.warn(
627625
"This method will be removed in future versions. "
628626
"Use 'tree.iter()' or 'list(tree.iter())' instead.",
629-
PendingDeprecationWarning, stacklevel=2
627+
DeprecationWarning, stacklevel=2
630628
)
631629
return list(self.iter(tag))
632630

@@ -1431,25 +1429,19 @@ def end(self, tag):
14311429
self._tail = 1
14321430
return self._last
14331431

1434-
_sentinel = ['sentinel']
14351432

14361433
# also see ElementTree and TreeBuilder
14371434
class XMLParser:
14381435
"""Element structure builder for XML source data based on the expat parser.
14391436
1440-
*html* are predefined HTML entities (deprecated and not supported),
14411437
*target* is an optional target object which defaults to an instance of the
14421438
standard TreeBuilder class, *encoding* is an optional encoding string
14431439
which if given, overrides the encoding specified in the XML file:
14441440
http://www.iana.org/assignments/character-sets
14451441
14461442
"""
14471443

1448-
def __init__(self, html=_sentinel, target=None, encoding=None):
1449-
if html is not _sentinel:
1450-
warnings.warn(
1451-
"The html argument of XMLParser() is deprecated",
1452-
DeprecationWarning, stacklevel=2)
1444+
def __init__(self, *, target=None, encoding=None):
14531445
try:
14541446
from xml.parsers import expat
14551447
except ImportError:
@@ -1602,27 +1594,13 @@ def _default(self, text):
16021594
return
16031595
if hasattr(self.target, "doctype"):
16041596
self.target.doctype(name, pubid, system[1:-1])
1605-
elif self.doctype != self._XMLParser__doctype:
1606-
# warn about deprecated call
1607-
self._XMLParser__doctype(name, pubid, system[1:-1])
1608-
self.doctype(name, pubid, system[1:-1])
1609-
self._doctype = None
1610-
1611-
def doctype(self, name, pubid, system):
1612-
"""(Deprecated) Handle doctype declaration
1613-
1614-
*name* is the Doctype name, *pubid* is the public identifier,
1615-
and *system* is the system identifier.
1597+
elif hasattr(self, "doctype"):
1598+
warnings.warn(
1599+
"The doctype() method of XMLParser is ignored. "
1600+
"Define doctype() method on the TreeBuilder target.",
1601+
RuntimeWarning)
16161602

1617-
"""
1618-
warnings.warn(
1619-
"This method of XMLParser is deprecated. Define doctype() "
1620-
"method on the TreeBuilder target.",
1621-
DeprecationWarning,
1622-
)
1623-
1624-
# sentinel, if doctype is redefined in a subclass
1625-
__doctype = doctype
1603+
self._doctype = None
16261604

16271605
def feed(self, data):
16281606
"""Feed encoded data to parser."""
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
Removed the ``doctype()`` method and the *html* parameter of the constructor
2+
of :class:`~xml.etree.ElementTree.XMLParser`. The ``doctype()`` method
3+
defined in a subclass will no longer be called. Deprecated methods
4+
``getchildren()`` and ``getiterator()`` in the :mod:`~xml.etree.ElementTree`
5+
module emit now a :exc:`DeprecationWarning` instead of
6+
:exc:`PendingDeprecationWarning`.

0 commit comments

Comments
 (0)