|
1 | 1 | # XXX TypeErrors on calling handlers, or on bad return values from a |
2 | 2 | # handler, are obscure and unhelpful. |
3 | 3 |
|
4 | | -fromioimportBytesIO |
5 | 4 | importos |
6 | 5 | importplatform |
7 | 6 | importsys |
8 | 7 | importsysconfig |
9 | 8 | importunittest |
10 | 9 | importtraceback |
| 10 | +fromioimportBytesIO |
| 11 | +fromtestimportsupport |
| 12 | +fromtest.supportimportos_helper |
11 | 13 |
|
12 | 14 | fromxml.parsersimportexpat |
13 | 15 | fromxml.parsers.expatimporterrors |
@@ -441,37 +443,59 @@ def test7(self): |
441 | 443 | # Test handling of exception from callback: |
442 | 444 | classHandlerExceptionTest(unittest.TestCase): |
443 | 445 | defStartElementHandler(self,name,attrs): |
444 | | -raiseRuntimeError(name) |
| 446 | +raiseRuntimeError(f'StartElementHandler: <{name}>') |
445 | 447 |
|
446 | 448 | defcheck_traceback_entry(self,entry,filename,funcname): |
447 | | -self.assertEqual(os.path.basename(entry[0]),filename) |
448 | | -self.assertEqual(entry[2],funcname) |
| 449 | +self.assertEqual(os.path.basename(entry.filename),filename) |
| 450 | +self.assertEqual(entry.name,funcname) |
449 | 451 |
|
| 452 | +@support.cpython_only |
450 | 453 | deftest_exception(self): |
| 454 | +# gh-66652: test _PyTraceback_Add() used by pyexpat.c to inject frames |
| 455 | + |
| 456 | +# Change the current directory to the Python source code directory |
| 457 | +# if it is available. |
| 458 | +src_dir=sysconfig.get_config_var('abs_builddir') |
| 459 | +ifsrc_dir: |
| 460 | +have_source=os.path.isdir(src_dir) |
| 461 | +else: |
| 462 | +have_source=False |
| 463 | +ifhave_source: |
| 464 | +withos_helper.change_cwd(src_dir): |
| 465 | +self._test_exception(have_source) |
| 466 | +else: |
| 467 | +self._test_exception(have_source) |
| 468 | + |
| 469 | +def_test_exception(self,have_source): |
| 470 | +# Use path relative to the current directory which should be the Python |
| 471 | +# source code directory (if it is available). |
| 472 | +PYEXPAT_C=os.path.join('Modules','pyexpat.c') |
| 473 | + |
451 | 474 | parser=expat.ParserCreate() |
452 | 475 | parser.StartElementHandler=self.StartElementHandler |
453 | 476 | try: |
454 | 477 | parser.Parse(b"<a><b><c/></b></a>",True) |
455 | | -self.fail() |
456 | | -exceptRuntimeErrorase: |
457 | | -self.assertEqual(e.args[0],'a', |
458 | | -"Expected RuntimeError for element 'a', but"+ \ |
459 | | -" found %r"%e.args[0]) |
460 | | -# Check that the traceback contains the relevant line in pyexpat.c |
461 | | -entries=traceback.extract_tb(e.__traceback__) |
462 | | -self.assertEqual(len(entries),3) |
463 | | -self.check_traceback_entry(entries[0], |
464 | | -"test_pyexpat.py","test_exception") |
465 | | -self.check_traceback_entry(entries[1], |
466 | | -"pyexpat.c","StartElement") |
467 | | -self.check_traceback_entry(entries[2], |
468 | | -"test_pyexpat.py","StartElementHandler") |
469 | | -if (sysconfig.is_python_build() |
470 | | -andnot (sys.platform=='win32'andplatform.machine()=='ARM') |
471 | | -andnotis_emscripten |
472 | | -andnotis_wasi |
473 | | - ): |
474 | | -self.assertIn('call_with_frame("StartElement"',entries[1][3]) |
| 478 | + |
| 479 | +self.fail("the parser did not raise RuntimeError") |
| 480 | +exceptRuntimeErrorasexc: |
| 481 | +self.assertEqual(exc.args[0],'StartElementHandler: <a>',exc) |
| 482 | +entries=traceback.extract_tb(exc.__traceback__) |
| 483 | + |
| 484 | +self.assertEqual(len(entries),3,entries) |
| 485 | +self.check_traceback_entry(entries[0], |
| 486 | +"test_pyexpat.py","_test_exception") |
| 487 | +self.check_traceback_entry(entries[1], |
| 488 | +os.path.basename(PYEXPAT_C), |
| 489 | +"StartElement") |
| 490 | +self.check_traceback_entry(entries[2], |
| 491 | +"test_pyexpat.py","StartElementHandler") |
| 492 | + |
| 493 | +# Check that the traceback contains the relevant line in |
| 494 | +# Modules/pyexpat.c. Skip the test if Modules/pyexpat.c is not |
| 495 | +# available. |
| 496 | +ifhave_sourceandos.path.exists(PYEXPAT_C): |
| 497 | +self.assertIn('call_with_frame("StartElement"', |
| 498 | +entries[1].line) |
475 | 499 |
|
476 | 500 |
|
477 | 501 | # Test Current* members: |
|