diff --git a/backport_fix_xml_tree_assert_error.patch b/backport_fix_xml_tree_assert_error.patch
new file mode 100644
index 0000000000000000000000000000000000000000..853a647160ce9eca298ba50183d3b7c67d543ef1
--- /dev/null
+++ b/backport_fix_xml_tree_assert_error.patch
@@ -0,0 +1,77 @@
+diff --git a/Lib/test/test_xml_etree.py b/Lib/test/test_xml_etree.py
+index 142ce2c..a8d5c2d 100644
+--- a/Lib/test/test_xml_etree.py
++++ b/Lib/test/test_xml_etree.py
+@@ -14,6 +14,8 @@ import locale
+ import operator
+ import os
+ import pickle
++import pyexpat
++import subprocess
+ import sys
+ import textwrap
+ import types
+@@ -96,6 +98,11 @@ ENTITY_XML = """\
+ &entity;
+ """
+
++macro_to_find = 'XML_SetReparseDeferralEnabled'
++header_file = '/usr/include/expat.h'
++result = subprocess.run(['grep', '-q', macro_to_find, header_file], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
++fails_with_expat = (unittest.expectedFailure if result.returncode == 0 else lambda test: test)
++
+ EXTERNAL_ENTITY_XML = """\
+
+@@ -1410,27 +1417,38 @@ class XMLPullParserTest(unittest.TestCase):
+ with self.assertRaises(StopIteration):
+ next(it)
+
+- def test_simple_xml_with_ns(self):
++ def test_simple_xml(self, chunk_size=None):
+ parser = ET.XMLPullParser()
+ self.assert_event_tags(parser, [])
+- self._feed(parser, "\n")
+- self.assert_event_tags(parser, [])
+- self._feed(parser, "\n")
++ self._feed(parser, "\n", chunk_size)
+ self.assert_event_tags(parser, [])
+- self._feed(parser, "text\n text\n")
+- self.assert_event_tags(parser, [('end', '{namespace}element')])
+- self._feed(parser, "texttail\n")
+- self._feed(parser, "\n")
++ self._feed(parser, ">\n", chunk_size)
++ self.assert_event_tags(parser, [('end', 'element')])
++ self._feed(parser, "texttail\n", chunk_size)
++ self._feed(parser, "\n", chunk_size)
+ self.assert_event_tags(parser, [
+- ('end', '{namespace}element'),
+- ('end', '{namespace}empty-element'),
++ ('end', 'element'),
++ ('end', 'empty-element'),
+ ])
+- self._feed(parser, "\n")
+- self.assert_event_tags(parser, [('end', '{namespace}root')])
++ self._feed(parser, "\n", chunk_size)
++ self.assert_event_tags(parser, [('end', 'root')])
+ self.assertIsNone(parser.close())
+
++ @fails_with_expat
++ def test_simple_xml_chunk_1(self):
++ self.test_simple_xml(chunk_size=1)
++
++ @fails_with_expat
++ def test_simple_xml_chunk_5(self):
++ self.test_simple_xml(chunk_size=5)
++
++ def test_simple_xml_chunk_22(self):
++ self.test_simple_xml(chunk_size=22)
++
+ def test_ns_events(self):
+ parser = ET.XMLPullParser(events=('start-ns', 'end-ns'))
+ self._feed(parser, "\n")
diff --git a/python3.spec b/python3.spec
index 885e744107b160ea317ec4c0511e47c82f16e559..15787504b57260db8201b0e4d1de6903e2291304 100644
--- a/python3.spec
+++ b/python3.spec
@@ -117,6 +117,7 @@ Patch6023: backport-3.9-bpo-37013-Fix-the-error-handling-in-socket.if_in.patch
Patch6024: backport-3.9-gh-91133-tempfile.TemporaryDirectory-fix-symlink.patch
Patch6025: backport-3.9-gh-109858-Protect-zipfile-from-quoted-overlap-zi.patch
Patch6026: backport-3.9-gh-113659-Skip-hidden-.pth-files-GH-113660-GH-11.patch
+Patch6027: backport_fix_xml_tree_assert_error.patch
Patch9000: add-the-sm3-method-for-obtaining-the-salt-value.patch
Patch9001: python3-Add-sw64-architecture.patch
@@ -232,6 +233,7 @@ rm -r Modules/expat
%patch6024 -p1
%patch6025 -p1
%patch6026 -p1
+%patch6027 -p1
%patch9000 -p1
%patch9001 -p1
@@ -859,6 +861,12 @@ export BEP_GTDLIST="$BEP_GTDLIST_TMP"
%{_mandir}/*/*
%changelog
+* Web May 22 2024 xinsheng - 3.9.9-31
+- Type:bugfix
+- CVE:NA
+- SUG:NA
+- DESC:fix xml tree assert error
+
* Web Mar 23 2024 xinsheng - 3.9.9-30
- Type:bugfix
- CVE:NA