[Stdlib] Enforce non-NULL PythonObjects by c-pozzi · Pull Request #6332 · modular/modular

added 2 commits

April 1, 2026 15:33
BEGIN_PUBLIC
[Stdlib] Enforce non-NULL PythonObject storage via NonNullPyObjectPtr

Change `PythonObject._obj_ptr` from nullable `PyObjectPtr` to
`NonNullPyObjectPtr` (alias for `NonNullUnsafePointer[PyObject,
MutAnyOrigin]`), enforcing at the type level that a `PythonObject`
always holds a valid Python object reference.

Key changes:
- Add `NonNullPyObjectPtr` comptime alias in `_cpython.mojo`
- Add `debug_assert` NULL checks in `from_owned`/`from_borrowed`
  constructors (the enforcement boundary)
- `steal_data()` swaps in an IncRef'd `Py_None` instead of setting
  NULL, so `__del__` always has a valid pointer to DecRef
- Add `_as_py_object_ptr()` helper for converting back to `PyObjectPtr`
  at FFI call sites
- Add `_owned_or_raise()` helper for the common check-NULL-then-wrap
  pattern
- Update all `_obj_ptr` access sites across stdlib and integration tests
- Replace bare `._obj_ptr` truthiness checks on kwargs with `Bool()`

Fixes modular#5414
END_PUBLIC

Signed-off-by: c-pozzi <corina.rios@gmail.com>
BEGIN_PUBLIC
[Stdlib] Remove unused _owned_or_raise helper

Remove _owned_or_raise and its tests — the explicit NULL-check pattern
already established in the codebase is clearer and this helper was never
used.
END_PUBLIC

Signed-off-by: c-pozzi <corina.rios@gmail.com>

@c-pozzi

BEGIN_PUBLIC
[Stdlib] Apply mojo format
END_PUBLIC

Signed-off-by: c-pozzi <corina.rios@gmail.com>

@c-pozzi c-pozzi marked this pull request as ready for review

April 2, 2026 08:13

Copilot AI review requested due to automatic review settings

April 2, 2026 08:13

@c-pozzi

BEGIN_PUBLIC
[Stdlib] Enforce non-NULL PythonObject at FFI boundary

Harden PythonObject constructors to abort on NULL in all builds
(not just debug). Guard CPython call sites that can return NULL
(PyImport_AddModule, PyType_GetName) and substitute Py_None for
NULL kwargs/self pointers passed by CPython to extension wrappers.

Preserve user-set Python exceptions (e.g. ValueError) in the
wrapper's error handler instead of overwriting with generic
Exception.
END_PUBLIC

Signed-off-by: c-pozzi <corina.rios@gmail.com>