Skip to content

test_subparser_inherits_reparse_deferral fails when compiled against expat < 2.6.0 #155485

Description

@hroncok

Bug report

Bug description:

test_subparser_inherits_reparse_deferral, added in 7d76013, fails when CPython is compiled against expat < 2.6.0:

test_subparser_inherits_reparse_deferral (test.test_pyexpat.ParentParserLifetimeTest.test_subparser_inherits_reparse_deferral) ... FAIL
======================================================================
FAIL: test_subparser_inherits_reparse_deferral (test.test_pyexpat.ParentParserLifetimeTest.test_subparser_inherits_reparse_deferral)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/builddir/build/BUILD/Python-3.13.15/Lib/test/test_pyexpat.py", line 960, in test_subparser_inherits_reparse_deferral
    self.assertEqual(subparser.GetReparseDeferralEnabled(), enabled)
    ~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: False != True
----------------------------------------------------------------------

With XML_COMBINED_VERSION < 20600, SetReparseDeferralEnabled is a complete no-op -- both the expat call and the cache update are inside #if XML_COMBINED_VERSION >= 20600. The cache stays at its initial value of false, which the subparser copies and GetReparseDeferralEnabled returns. The test's enabled=True iteration then asserts False == True.

This is consistent with the documented behavior: GetReparseDeferralEnabled says "always returns false with Expat <2.6.0".

I belive a simple fix for the test failure would be a version-based skip:

@unittest.skipIf(expat.version_info < (2, 6, 0),
                 "requires Expat >= 2.6.0")
def test_subparser_inherits_reparse_deferral(self):
    ...

However, the runtime expat version can differ from the compile-time one. Since the behavior is gated by the compile-time XML_COMBINED_VERSION check, it's more robust to test the compile-time default directly (similar to GH-144739 / 45e9343):

@unittest.skipIf(not expat.ParserCreate().GetReparseDeferralEnabled(),
                 "requires Python compiled with Expat >= 2.6.0")
def test_subparser_inherits_reparse_deferral(self):
    ...

A freshly created parser's GetReparseDeferralEnabled() reflects which #if branch was compiled -- True with expat >= 2.6.0, False otherwise.

Would that be an acceptable change?

Disclosure: I used LLM (Claude Opus 4.6) to analyze the cause of the test failure we see in EPEL 9.

CPython versions tested on:

3.13, CPython main branch

This has been reproduced on 3.13.15 with RHEL 9 expat 2.5.0 (which actually backported XML_SetReparseDeferralEnabled without XML_GetReparseDeferralEnabled but the buildttime version #if makes that irrelevant anyway). Based on the presence of the same code in the main branch, I assume this is also the same for newer Python versions.

Operating systems tested on:

Linux

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Labels

    testsTests in the Lib/test dirtopic-XMLtype-bugAn unexpected behavior, bug, or error

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions