Skip to content

Validate native py::print delegation with comprehensive tests - #6122

Closed
rwgk wants to merge 3 commits into
pybind:masterfrom
rwgk:pybind11_print_delegate_to_native_plus_6120_tests
Closed

Validate native py::print delegation with comprehensive tests#6122
rwgk wants to merge 3 commits into
pybind:masterfrom
rwgk:pybind11_print_delegate_to_native_plus_6120_tests

Conversation

@rwgk

@rwgk rwgk commented Aug 2, 2026

Copy link
Copy Markdown
Collaborator

Description

This is a companion experiment to #6121 and an alternative to #6120. It uses the same production change as #6121: delegate py::print to Python's current print callable instead of maintaining a separate implementation.

This branch temporarily adds the comprehensive behavior tests developed around #6120, adapted where necessary to compare runtime-owned behavior with the active runtime's native print. The purpose of this PR is to run the full CI matrix and confirm our expectations across supported interpreters and platforms, including argument and keyword handling, stream and flush behavior, exception propagation, and interpreter/subinterpreter shutdown.

If that validation succeeds, the plan is not to retain this comprehensive test suite in the final change. We will trim the tests in #6121 back to the aspects owned by pybind11: proving that py::print resolves the current print callable, forwards its arguments and keywords unchanged, and propagates failures. Details of native print behavior should remain the Python runtime's responsibility rather than being frozen in pybind11's tests.

This follows up on the original delegation suggestion in #6120.

Local validation

  • Full regular CPython 3.14.4 test suite
  • Full free-threaded CPython 3.14.4 test suite
  • Pre-commit checks

Documentation changes are deliberately left out of this experimental validation PR.

@rwgk

rwgk commented Aug 2, 2026

Copy link
Copy Markdown
Collaborator Author

Result of the comprehensive CI validation experiment

PR #6122 intentionally carried much broader test coverage than is planned for the final change in #6121. Its purpose was to combine the native-print delegation with the comprehensive behavioral tests developed around #6120, then exercise that combination across the full CI matrix before simplifying the tests.

The final result is 73 passing checks, two skipped CI checks, and three failing PyPy 3.11 jobs. No failure points to a problem in the production implementation.

The three failures—on Ubuntu, macOS, and Windows—all come from the same assertion in test_print_missing_stdout. After deleting sys.stdout, CPython's native print raises RuntimeError, while PyPy's native print raises AttributeError. The test unnecessarily required the native exception to be RuntimeError, and therefore failed before it reached the comparison with py::print.

This is useful evidence rather than a delegation failure: it identifies exactly the kind of runtime-owned behavior that pybind11 should not duplicate or freeze in its tests. All other print coverage passed in the same PyPy jobs, including the direct test that replaces the current built-in print callable and verifies delegation.

Across the rest of the matrix, the comprehensive tests exercised argument and keyword handling, file=None and redirected streams, separator and terminator validation, ordinary and pathological unknown keywords, flush truthiness and error propagation, stream call ordering, unavailable sys module state, and interpreter/subinterpreter shutdown. The matrix covered CPython 3.9 through development versions, free-threaded builds, GraalPy, PyPy, multiple operating systems, compilers, architectures, and C++ standards. The format, clang-tidy, packaging, documentation, wheel, and external checks also passed.

The experiment therefore supports the simpler final shape for #6121:

  • delegate each py::print call to the current print callable in Python's built-ins;
  • test only that pybind11 performs a fresh lookup, forwards positional and keyword arguments unchanged, ignores the callable's return value as required by the void API, and propagates its exception unchanged;
  • leave formatting, stream behavior, keyword validation, flushing, diagnostics, and shutdown details to the active Python runtime.

In other words, #6122 provided the broad validation scaffolding; #6121 can now keep the implementation and tests deliberately small without relying on untested assumptions.

@rwgk

rwgk commented Aug 2, 2026

Copy link
Copy Markdown
Collaborator Author

This experimental PR has served its purpose. Closing.

@rwgk rwgk closed this Aug 2, 2026
@rwgk
rwgk deleted the pybind11_print_delegate_to_native_plus_6120_tests branch August 3, 2026 05:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant