Skip to content

Commit

Permalink
Support overriding static properties defined via def_prop_ro_static.
Browse files Browse the repository at this point in the history
See
pybind/pybind11@e0e2ea3
for the analogous change to pybind11.
  • Loading branch information
hawkinsp committed Dec 4, 2024
1 parent f33465c commit 2b35ac4
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 1 deletion.
4 changes: 4 additions & 0 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ Version TBD (unreleased)
Previously, after ``a += b``, ``a`` would be replaced with a copy.
(PR `#803 <https://github.com/wjakob/nanobind/pull/803>`__)

- Added support for overriding static properties, such as those defined using
``def_prop_ro_static``, in subclasses. Previously this would fail with an
error.

Version 2.2.0 (October 3, 2024)
-------------------------------

Expand Down
4 changes: 3 additions & 1 deletion src/nb_type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -513,7 +513,9 @@ int nb_type_setattro(PyObject* obj, PyObject* name, PyObject* value) {

if (cur) {
PyTypeObject *tp = int_p->nb_static_property;
if (Py_TYPE(cur) == tp) {
// For type.static_prop = value, call the setter.
// For type.static_prop = another_static_prop, replace the descriptor.
if (Py_TYPE(cur) == tp && Py_TYPE(value) != tp) {
int rv = int_p->nb_static_property_descr_set(cur, obj, value);
Py_DECREF(cur);
return rv;
Expand Down
8 changes: 8 additions & 0 deletions tests/test_classes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -705,4 +705,12 @@ NB_MODULE(test_classes_ext, m) {
nb::inst_mark_ready(h);
})
.def_rw("value", &MonkeyPatchable::value);

struct StaticPropertyOverride {};
struct StaticPropertyOverride2 : public StaticPropertyOverride {};

nb::class_<StaticPropertyOverride>(m, "StaticPropertyOverride")
.def_prop_ro_static("x", [](nb::handle /*unused*/) { return 42; });
nb::class_<StaticPropertyOverride2, StaticPropertyOverride>(m, "StaticPropertyOverride2")
.def_prop_ro_static("x", [](nb::handle /*unused*/) { return 43; });
}
4 changes: 4 additions & 0 deletions tests/test_classes.py
Original file line number Diff line number Diff line change
Expand Up @@ -916,3 +916,7 @@ def my_init(self):
t.MonkeyPatchable.__init__ = my_init
q = t.MonkeyPatchable()
assert q.value == 456

def test49_static_property_override():
assert t.StaticPropertyOverride.x == 42
assert t.StaticPropertyOverride2.x == 43
8 changes: 8 additions & 0 deletions tests/test_classes_ext.pyi.ref
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,14 @@ class StaticProperties:
class StaticProperties2(StaticProperties):
pass

class StaticPropertyOverride:
x: int = ...
"""(arg: object, /) -> int"""

class StaticPropertyOverride2(StaticPropertyOverride):
x: int = ...
"""(arg: object, /) -> int"""

class Struct:
"""Some documentation"""

Expand Down

0 comments on commit 2b35ac4

Please sign in to comment.