summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>2023-09-12 14:03:47 (GMT)
committerGitHub <noreply@github.com>2023-09-12 14:03:47 (GMT)
commitdf64210ad0d65e82449bbff2c5125764d49e5073 (patch)
tree49f658e7397bcaecba314628315547cf7048ea25
parentb3613815d4550a611e67a9c97f616c97124b6495 (diff)
downloadcpython-df64210ad0d65e82449bbff2c5125764d49e5073.zip
cpython-df64210ad0d65e82449bbff2c5125764d49e5073.tar.gz
cpython-df64210ad0d65e82449bbff2c5125764d49e5073.tar.bz2
[3.12] gh-109230: test_pyexpat no longer depends on the current directory (GH-109233) (#109241)
gh-109230: test_pyexpat no longer depends on the current directory (GH-109233) Fix test_pyexpat.test_exception(): it can now be run from a directory different than Python source code directory. Before, the test failed in this case. Skip the test if Modules/pyexpat.c source is not available. Skip also the test on Python implementations other than CPython. (cherry picked from commit e55aab95786e0e9fb36a9a1122d2d0fb3d2403cd) Co-authored-by: Victor Stinner <vstinner@python.org>
-rw-r--r--Lib/test/test_pyexpat.py72
-rw-r--r--Misc/NEWS.d/next/Tests/2023-09-10-19-59-57.gh-issue-109230.SRNLFQ.rst5
2 files changed, 53 insertions, 24 deletions
diff --git a/Lib/test/test_pyexpat.py b/Lib/test/test_pyexpat.py
index 863c119..95698c0 100644
--- a/Lib/test/test_pyexpat.py
+++ b/Lib/test/test_pyexpat.py
@@ -1,13 +1,15 @@
# XXX TypeErrors on calling handlers, or on bad return values from a
# handler, are obscure and unhelpful.
-from io import BytesIO
import os
import platform
import sys
import sysconfig
import unittest
import traceback
+from io import BytesIO
+from test import support
+from test.support import os_helper
from xml.parsers import expat
from xml.parsers.expat import errors
@@ -441,37 +443,59 @@ class BufferTextTest(unittest.TestCase):
# Test handling of exception from callback:
class HandlerExceptionTest(unittest.TestCase):
def StartElementHandler(self, name, attrs):
- raise RuntimeError(name)
+ raise RuntimeError(f'StartElementHandler: <{name}>')
def check_traceback_entry(self, entry, filename, funcname):
- self.assertEqual(os.path.basename(entry[0]), filename)
- self.assertEqual(entry[2], funcname)
+ self.assertEqual(os.path.basename(entry.filename), filename)
+ self.assertEqual(entry.name, funcname)
+ @support.cpython_only
def test_exception(self):
+ # gh-66652: test _PyTraceback_Add() used by pyexpat.c to inject frames
+
+ # Change the current directory to the Python source code directory
+ # if it is available.
+ src_dir = sysconfig.get_config_var('abs_builddir')
+ if src_dir:
+ have_source = os.path.isdir(src_dir)
+ else:
+ have_source = False
+ if have_source:
+ with os_helper.change_cwd(src_dir):
+ self._test_exception(have_source)
+ else:
+ self._test_exception(have_source)
+
+ def _test_exception(self, have_source):
+ # Use path relative to the current directory which should be the Python
+ # source code directory (if it is available).
+ PYEXPAT_C = os.path.join('Modules', 'pyexpat.c')
+
parser = expat.ParserCreate()
parser.StartElementHandler = self.StartElementHandler
try:
parser.Parse(b"<a><b><c/></b></a>", True)
- self.fail()
- except RuntimeError as e:
- self.assertEqual(e.args[0], 'a',
- "Expected RuntimeError for element 'a', but" + \
- " found %r" % e.args[0])
- # Check that the traceback contains the relevant line in pyexpat.c
- entries = traceback.extract_tb(e.__traceback__)
- self.assertEqual(len(entries), 3)
- self.check_traceback_entry(entries[0],
- "test_pyexpat.py", "test_exception")
- self.check_traceback_entry(entries[1],
- "pyexpat.c", "StartElement")
- self.check_traceback_entry(entries[2],
- "test_pyexpat.py", "StartElementHandler")
- if (sysconfig.is_python_build()
- and not (sys.platform == 'win32' and platform.machine() == 'ARM')
- and not is_emscripten
- and not is_wasi
- ):
- self.assertIn('call_with_frame("StartElement"', entries[1][3])
+
+ self.fail("the parser did not raise RuntimeError")
+ except RuntimeError as exc:
+ self.assertEqual(exc.args[0], 'StartElementHandler: <a>', exc)
+ entries = traceback.extract_tb(exc.__traceback__)
+
+ self.assertEqual(len(entries), 3, entries)
+ self.check_traceback_entry(entries[0],
+ "test_pyexpat.py", "_test_exception")
+ self.check_traceback_entry(entries[1],
+ os.path.basename(PYEXPAT_C),
+ "StartElement")
+ self.check_traceback_entry(entries[2],
+ "test_pyexpat.py", "StartElementHandler")
+
+ # Check that the traceback contains the relevant line in
+ # Modules/pyexpat.c. Skip the test if Modules/pyexpat.c is not
+ # available.
+ if have_source and os.path.exists(PYEXPAT_C):
+ self.assertIn('call_with_frame("StartElement"',
+ entries[1].line)
# Test Current* members:
diff --git a/Misc/NEWS.d/next/Tests/2023-09-10-19-59-57.gh-issue-109230.SRNLFQ.rst b/Misc/NEWS.d/next/Tests/2023-09-10-19-59-57.gh-issue-109230.SRNLFQ.rst
new file mode 100644
index 0000000..18e1e85
--- /dev/null
+++ b/Misc/NEWS.d/next/Tests/2023-09-10-19-59-57.gh-issue-109230.SRNLFQ.rst
@@ -0,0 +1,5 @@
+Fix ``test_pyexpat.test_exception()``: it can now be run from a directory
+different than Python source code directory. Before, the test failed in this
+case. Skip the test if Modules/pyexpat.c source is not available. Skip also
+the test on Python implementations other than CPython. Patch by Victor
+Stinner.