mirror of
https://github.com/python/cpython.git
synced 2025-10-01 04:42:10 +00:00
[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 e55aab9578
)
Co-authored-by: Victor Stinner <vstinner@python.org>
This commit is contained in:
parent
b3613815d4
commit
df64210ad0
2 changed files with 53 additions and 24 deletions
|
@ -1,13 +1,15 @@
|
||||||
# XXX TypeErrors on calling handlers, or on bad return values from a
|
# XXX TypeErrors on calling handlers, or on bad return values from a
|
||||||
# handler, are obscure and unhelpful.
|
# handler, are obscure and unhelpful.
|
||||||
|
|
||||||
from io import BytesIO
|
|
||||||
import os
|
import os
|
||||||
import platform
|
import platform
|
||||||
import sys
|
import sys
|
||||||
import sysconfig
|
import sysconfig
|
||||||
import unittest
|
import unittest
|
||||||
import traceback
|
import traceback
|
||||||
|
from io import BytesIO
|
||||||
|
from test import support
|
||||||
|
from test.support import os_helper
|
||||||
|
|
||||||
from xml.parsers import expat
|
from xml.parsers import expat
|
||||||
from xml.parsers.expat import errors
|
from xml.parsers.expat import errors
|
||||||
|
@ -441,37 +443,59 @@ class BufferTextTest(unittest.TestCase):
|
||||||
# Test handling of exception from callback:
|
# Test handling of exception from callback:
|
||||||
class HandlerExceptionTest(unittest.TestCase):
|
class HandlerExceptionTest(unittest.TestCase):
|
||||||
def StartElementHandler(self, name, attrs):
|
def StartElementHandler(self, name, attrs):
|
||||||
raise RuntimeError(name)
|
raise RuntimeError(f'StartElementHandler: <{name}>')
|
||||||
|
|
||||||
def check_traceback_entry(self, entry, filename, funcname):
|
def check_traceback_entry(self, entry, filename, funcname):
|
||||||
self.assertEqual(os.path.basename(entry[0]), filename)
|
self.assertEqual(os.path.basename(entry.filename), filename)
|
||||||
self.assertEqual(entry[2], funcname)
|
self.assertEqual(entry.name, funcname)
|
||||||
|
|
||||||
|
@support.cpython_only
|
||||||
def test_exception(self):
|
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 = expat.ParserCreate()
|
||||||
parser.StartElementHandler = self.StartElementHandler
|
parser.StartElementHandler = self.StartElementHandler
|
||||||
try:
|
try:
|
||||||
parser.Parse(b"<a><b><c/></b></a>", True)
|
parser.Parse(b"<a><b><c/></b></a>", True)
|
||||||
self.fail()
|
|
||||||
except RuntimeError as e:
|
self.fail("the parser did not raise RuntimeError")
|
||||||
self.assertEqual(e.args[0], 'a',
|
except RuntimeError as exc:
|
||||||
"Expected RuntimeError for element 'a', but" + \
|
self.assertEqual(exc.args[0], 'StartElementHandler: <a>', exc)
|
||||||
" found %r" % e.args[0])
|
entries = traceback.extract_tb(exc.__traceback__)
|
||||||
# Check that the traceback contains the relevant line in pyexpat.c
|
|
||||||
entries = traceback.extract_tb(e.__traceback__)
|
self.assertEqual(len(entries), 3, entries)
|
||||||
self.assertEqual(len(entries), 3)
|
self.check_traceback_entry(entries[0],
|
||||||
self.check_traceback_entry(entries[0],
|
"test_pyexpat.py", "_test_exception")
|
||||||
"test_pyexpat.py", "test_exception")
|
self.check_traceback_entry(entries[1],
|
||||||
self.check_traceback_entry(entries[1],
|
os.path.basename(PYEXPAT_C),
|
||||||
"pyexpat.c", "StartElement")
|
"StartElement")
|
||||||
self.check_traceback_entry(entries[2],
|
self.check_traceback_entry(entries[2],
|
||||||
"test_pyexpat.py", "StartElementHandler")
|
"test_pyexpat.py", "StartElementHandler")
|
||||||
if (sysconfig.is_python_build()
|
|
||||||
and not (sys.platform == 'win32' and platform.machine() == 'ARM')
|
# Check that the traceback contains the relevant line in
|
||||||
and not is_emscripten
|
# Modules/pyexpat.c. Skip the test if Modules/pyexpat.c is not
|
||||||
and not is_wasi
|
# available.
|
||||||
):
|
if have_source and os.path.exists(PYEXPAT_C):
|
||||||
self.assertIn('call_with_frame("StartElement"', entries[1][3])
|
self.assertIn('call_with_frame("StartElement"',
|
||||||
|
entries[1].line)
|
||||||
|
|
||||||
|
|
||||||
# Test Current* members:
|
# Test Current* members:
|
||||||
|
|
|
@ -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.
|
Loading…
Add table
Add a link
Reference in a new issue