@@ -1709,6 +1709,126 @@ def test_pickle_issue18997(self):
17091709 self .assertEqual (e2 [0 ].tag , 'dogs' )
17101710
17111711
1712+ class BadElementTest (ElementTestCase , unittest .TestCase ):
1713+ def test_extend_mutable_list (self ):
1714+ class X :
1715+ @property
1716+ def __class__ (self ):
1717+ L [:] = [ET .Element ('baz' )]
1718+ return ET .Element
1719+ L = [X ()]
1720+ e = ET .Element ('foo' )
1721+ try :
1722+ e .extend (L )
1723+ except TypeError :
1724+ pass
1725+
1726+ class Y (X , ET .Element ):
1727+ pass
1728+ L = [Y ('x' )]
1729+ e = ET .Element ('foo' )
1730+ e .extend (L )
1731+
1732+ def test_extend_mutable_list2 (self ):
1733+ class X :
1734+ @property
1735+ def __class__ (self ):
1736+ del L [:]
1737+ return ET .Element
1738+ L = [X (), ET .Element ('baz' )]
1739+ e = ET .Element ('foo' )
1740+ try :
1741+ e .extend (L )
1742+ except TypeError :
1743+ pass
1744+
1745+ class Y (X , ET .Element ):
1746+ pass
1747+ L = [Y ('bar' ), ET .Element ('baz' )]
1748+ e = ET .Element ('foo' )
1749+ e .extend (L )
1750+
1751+ def test_remove_with_mutating (self ):
1752+ class X (ET .Element ):
1753+ def __eq__ (self , o ):
1754+ del e [:]
1755+ return False
1756+ e = ET .Element ('foo' )
1757+ e .extend ([X ('bar' )])
1758+ self .assertRaises (ValueError , e .remove , ET .Element ('baz' ))
1759+
1760+ e = ET .Element ('foo' )
1761+ e .extend ([ET .Element ('bar' )])
1762+ self .assertRaises (ValueError , e .remove , X ('baz' ))
1763+
1764+
1765+ class MutatingElementPath (str ):
1766+ def __new__ (cls , elem , * args ):
1767+ self = str .__new__ (cls , * args )
1768+ self .elem = elem
1769+ return self
1770+ def __eq__ (self , o ):
1771+ del self .elem [:]
1772+ return True
1773+ MutatingElementPath .__hash__ = str .__hash__
1774+
1775+ class BadElementPath (str ):
1776+ def __eq__ (self , o ):
1777+ raise 1 / 0
1778+ BadElementPath .__hash__ = str .__hash__
1779+
1780+ class BadElementPathTest (ElementTestCase , unittest .TestCase ):
1781+ def setUp (self ):
1782+ super ().setUp ()
1783+ from xml .etree import ElementPath
1784+ self .path_cache = ElementPath ._cache
1785+ ElementPath ._cache = {}
1786+
1787+ def tearDown (self ):
1788+ from xml .etree import ElementPath
1789+ ElementPath ._cache = self .path_cache
1790+ super ().tearDown ()
1791+
1792+ def test_find_with_mutating (self ):
1793+ e = ET .Element ('foo' )
1794+ e .extend ([ET .Element ('bar' )])
1795+ e .find (MutatingElementPath (e , 'x' ))
1796+
1797+ def test_find_with_error (self ):
1798+ e = ET .Element ('foo' )
1799+ e .extend ([ET .Element ('bar' )])
1800+ try :
1801+ e .find (BadElementPath ('x' ))
1802+ except ZeroDivisionError :
1803+ pass
1804+
1805+ def test_findtext_with_mutating (self ):
1806+ e = ET .Element ('foo' )
1807+ e .extend ([ET .Element ('bar' )])
1808+ e .findtext (MutatingElementPath (e , 'x' ))
1809+
1810+ def test_findtext_with_error (self ):
1811+ e = ET .Element ('foo' )
1812+ e .extend ([ET .Element ('bar' )])
1813+ try :
1814+ e .findtext (BadElementPath ('x' ))
1815+ except ZeroDivisionError :
1816+ pass
1817+
1818+ def test_findall_with_mutating (self ):
1819+ e = ET .Element ('foo' )
1820+ e .extend ([ET .Element ('bar' )])
1821+ e .findall (MutatingElementPath (e , 'x' ))
1822+
1823+ def test_findall_with_error (self ):
1824+ e = ET .Element ('foo' )
1825+ e .extend ([ET .Element ('bar' )])
1826+ try :
1827+ e .findall (BadElementPath ('x' ))
1828+ except ZeroDivisionError :
1829+ pass
1830+
1831+
17121832class ElementTreeTypeTest (unittest .TestCase ):
17131833 def test_istype (self ):
17141834 self .assertIsInstance (ET .ParseError , type )
@@ -2556,6 +2676,8 @@ def test_main(module=None):
25562676 ModuleTest ,
25572677 ElementSlicingTest ,
25582678 BasicElementTest ,
2679+ BadElementTest ,
2680+ BadElementPathTest ,
25592681 ElementTreeTest ,
25602682 IOTest ,
25612683 ParseErrorTest ,
0 commit comments