.. versionadded:: 3.2
-.. function:: SubElement(parent, tag, attrib={}, **extra)
+.. function:: SubElement(parent, tag, /, attrib={}, **extra)
Subelement factory. This function creates an element instance, and appends
it to an existing element.
.. versionchanged:: 3.15
*attrib* can now be a :class:`frozendict`.
+ .. versionchanged:: next
+ *parent* and *tag* are now positional-only parameters.
+
.. function:: tostring(element, encoding="us-ascii", method="xml", *, \
xml_declaration=None, default_namespace=None, \
:noindex:
:no-index:
-.. class:: Element(tag, attrib={}, **extra)
+.. class:: Element(tag, /, attrib={}, **extra)
Element class. This class defines the Element interface, and provides a
reference implementation of this interface.
.. versionchanged:: 3.15
*attrib* can now be a :class:`frozendict`.
+ .. versionchanged:: next
+ *tag* is now a positional-only parameter.
+
.. attribute:: tag
self.serialize_check(element,
'<tag key="value"><subtag /><subtag /></tag>')
+ def test_positional_only_parameter(self):
+ # Test Element positional-only parameters (gh-144846).
+
+ # 'tag' is positional-only
+ with self.assertRaises(TypeError):
+ ET.Element(tag='fail')
+
+ # 'tag' and 'attrib' as kwarg/attribute names
+ e = ET.Element('e', attrib={'attrib': 'foo'}, tag='bar')
+ self.assertEqual(e.tag, 'e')
+ self.assertEqual(e.get('attrib'), 'foo')
+ self.assertEqual(e.get('tag'), 'bar')
+
def test_cdata(self):
# Test CDATA handling (etc).
self.assertEqual(ET.tostring(elem),
b'<test a=" " b=" " c="	 " d=" 		 " />')
+ def test_subelement_positional_only_parameter(self):
+ # Test SubElement positional-only parameters (gh-144270).
+ parent = ET.Element('parent')
+
+ # 'parent' and 'tag' are positional-only
+ with self.assertRaises(TypeError):
+ ET.SubElement(parent=parent, tag='fail')
+ with self.assertRaises(TypeError):
+ ET.SubElement(parent, tag='fail')
+
+ # 'attrib' can be passed as keyword
+ sub1 = ET.SubElement(parent, 'sub1', attrib={'key': 'value'})
+ self.assertEqual(sub1.get('key'), 'value')
+
+ # 'tag' and 'parent' as kwargs become XML attributes, not func params
+ sub2 = ET.SubElement(parent, 'sub2', attrib={'attrib': 'foo'},
+ tag='bar', parent='baz')
+ self.assertEqual(sub2.tag, 'sub2')
+ self.assertEqual(sub2.get('attrib'), 'foo')
+ self.assertEqual(sub2.get('tag'), 'bar')
+ self.assertEqual(sub2.get('parent'), 'baz')
+
def test_makeelement(self):
# Test makeelement handling.
"""
- def __init__(self, tag, attrib={}, **extra):
+ def __init__(self, tag, /, attrib={}, **extra):
if not isinstance(attrib, (dict, frozendict)):
raise TypeError("attrib must be dict or frozendict, not %s" % (
attrib.__class__.__name__,))
yield t
-def SubElement(parent, tag, attrib={}, **extra):
+def SubElement(parent, tag, /, attrib={}, **extra):
"""Subelement factory which creates an element instance, and appends it
to an existing parent.