Skip to content

fix(py_loader): handle TYPE_THROWABLE to prevent fatal errors in Python 3.14+#717

Draft
k5602 wants to merge 4 commits intometacall:developfrom
k5602:mac_py
Draft

fix(py_loader): handle TYPE_THROWABLE to prevent fatal errors in Python 3.14+#717
k5602 wants to merge 4 commits intometacall:developfrom
k5602:mac_py

Conversation

@k5602
Copy link
Copy Markdown
Contributor

@k5602 k5602 commented Mar 24, 2026

Description

This PR fixes a critical regression where a callable returned from Node to Python as TYPE_THROWABLE could cause a Python 3.14+ fatal error (segmentation fault).

Previously, py_loader_impl_value_to_capi() did not handle TYPE_THROWABLE values, leading it to return NULL without setting a proper Python exception that made the segfault in the mac ci. In newer Python releases (3.14+), returning NULL from a C API extension without an active exception state is treated as a fatal error.

Changes:

  • Added support for TYPE_THROWABLE (id 18) in py_loader_impl_value_to_capi(). It now properly extracts the inner TYPE_EXCEPTION label and message and correctly sets the Python error state using PyErr_Format(PyExc_RuntimeError, ...).
  • Added a fallback check in py_loader_impl_func_call to ensure PyErr_SetString is called whenever a foreign function call fails to convert a return value and returns NULL without an existing exception state.
  • Added metacall-node-python-throwable-test to the test suite to validate cross-language error propagation (Python throwing callback passed to a Node helper).

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update
  • Documentation update

Checklist:

  • I have performed a self-review of my own code.
  • I have commented my code, particularly in hard-to-understand areas.
  • I have made corresponding changes to the documentation.
  • My changes generate no new warnings.
  • I have added tests/screenshots (if any) that prove my fix is effective or that my feature works.
  • I have tested the tests implicated (if any) by my own code and they pass (make test or ctest -VV -R <test-name>).
  • If my change is significant or breaking, I have passed all tests with ./docker-compose.sh test &> output and attached the output.
  • I have tested my code with OPTION_BUILD_ADDRESS_SANITIZER or ./docker-compose.sh test-address-sanitizer &> output and OPTION_TEST_MEMORYCHECK.
  • I have tested my code with OPTION_BUILD_THREAD_SANITIZER or ./docker-compose.sh test-thread-sanitizer &> output.
  • I have tested with Helgrind in case my code works with threading.
  • I have run make clang-format in order to format my code and my code follows the style guidelines.

k5602 added 2 commits March 22, 2026 22:48
Reproduce regression where a callable returned from
Node to Python as TYPE_THROWABLE
which could cause a Python 3.14+ fatal error
because py_loader did not convert throwables into
Python exceptions leading to NULL without an
exception (fatal in newer Python releases).
Add a test that loads a Node 'flip' helper and a
Python script exercising a normal and a throwing
callback; asserts correct values and no SEGFAULT
Also register the test target in CMakeLists
@viferga
Copy link
Copy Markdown
Member

viferga commented Mar 24, 2026

@k5602 add better naming

@k5602
Copy link
Copy Markdown
Contributor Author

k5602 commented Mar 24, 2026

@k5602 add better naming
those names were only to show the two commits and link them to you,
i will change all naming before review.

@k5602 k5602 changed the title Mac py fix(py_loader): handle TYPE_THROWABLE to prevent fatal errors in Python 3.14+ Mar 25, 2026
k5602 added 2 commits March 25, 2026 04:48
Add defensive checks and error handling when
converting MetaCall values to Python objects

Return NULL on conversion failure and set a
Python exception when none is present
Avoid inserting NULL into PyList/PyDict and
release references on error
Include exception stacktrace when available for
MetaCall exceptions
Clean up tuple/list/dict refs and free
temporary allocations in function invoke/await
paths to prevent leaks and crashes
Add tests and improve handling of exceptions thrown across Node.js and Python.

This commit addresses issues with how exceptions are
propagated between Node.js and Python when using MetaCall. Specifically, it resolves a segmentation
fault that occurred in Python 3.14+ due to unhandled `TYPE_THROWABLE` return values.
@k5602 k5602 marked this pull request as ready for review March 25, 2026 02:52
@viferga viferga marked this pull request as draft April 17, 2026 07:28
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.

2 participants