From 212a705a4dc7a343afe6c0e63534257d5340d521 Mon Sep 17 00:00:00 2001 From: blueloveTH Date: Thu, 14 Nov 2024 18:54:25 +0800 Subject: [PATCH] add `bindstaticmethod` --- include/pocketpy/pocketpy.h | 5 +++++ src/modules/linalg.c | 10 +++++----- src/public/py_object.c | 1 - src/public/values.c | 11 +++++++++++ tests/80_linalg.py | 11 ++--------- 5 files changed, 23 insertions(+), 15 deletions(-) diff --git a/include/pocketpy/pocketpy.h b/include/pocketpy/pocketpy.h index 6e6c255d..fa2248bf 100644 --- a/include/pocketpy/pocketpy.h +++ b/include/pocketpy/pocketpy.h @@ -376,6 +376,11 @@ PK_API void py_bind(py_Ref obj, const char* sig, py_CFunction f); /// @param name name of the method. /// @param f function to bind. PK_API void py_bindmethod(py_Type type, const char* name, py_CFunction f); +/// Bind a static method to type via "argc-based" style. +/// @param type the target type. +/// @param name name of the method. +/// @param f function to bind. +PK_API void py_bindstaticmethod(py_Type type, const char* name, py_CFunction f); /// Bind a function to the object via "argc-based" style. /// @param obj the target object. /// @param name name of the function. diff --git a/src/modules/linalg.c b/src/modules/linalg.c index 851f0cf0..3dcc337d 100644 --- a/src/modules/linalg.c +++ b/src/modules/linalg.c @@ -860,8 +860,8 @@ void pk__add_module_linalg() { py_newvec2(_const(vec2, "DOWN"), (c11_vec2){{0, 1}}); // clang-format on - py_bindmethod(vec2, "angle", vec2_angle_STATIC); - py_bindmethod(vec2, "smooth_damp", vec2_smoothdamp_STATIC); + py_bindstaticmethod(vec2, "angle", vec2_angle_STATIC); + py_bindstaticmethod(vec2, "smooth_damp", vec2_smoothdamp_STATIC); py_bindproperty(vec2, "x", vec2__x, NULL); py_bindproperty(vec2, "y", vec2__y, NULL); @@ -884,9 +884,9 @@ void pk__add_module_linalg() { py_bindmethod(mat3x3, "inverse", mat3x3_inverse); py_bindmethod(mat3x3, "copy_", mat3x3_copy_); py_bindmethod(mat3x3, "inverse_", mat3x3_inverse_); - py_bindmethod(mat3x3, "zeros", mat3x3_zeros_STATIC); - py_bindmethod(mat3x3, "identity", mat3x3_identity_STATIC); - py_bindmethod(mat3x3, "trs", mat3x3_trs_STATIC); + py_bindstaticmethod(mat3x3, "zeros", mat3x3_zeros_STATIC); + py_bindstaticmethod(mat3x3, "identity", mat3x3_identity_STATIC); + py_bindstaticmethod(mat3x3, "trs", mat3x3_trs_STATIC); py_bindmethod(mat3x3, "copy_trs_", mat3x3_copy_trs_); py_bindmethod(mat3x3, "t", mat3x3_t); py_bindmethod(mat3x3, "r", mat3x3_r); diff --git a/src/public/py_object.c b/src/public/py_object.c index 3f7c2f02..a612adfb 100644 --- a/src/public/py_object.c +++ b/src/public/py_object.c @@ -117,7 +117,6 @@ static bool type__annotations__(int argc, py_Ref argv) { } void pk_object__register() { - // TODO: use staticmethod py_bindmagic(tp_object, __new__, pk__object_new); py_bindmagic(tp_object, __hash__, object__hash__); diff --git a/src/public/values.c b/src/public/values.c index 20baf8d8..27d59e06 100644 --- a/src/public/values.c +++ b/src/public/values.c @@ -54,6 +54,17 @@ void py_bindmethod(py_Type type, const char* name, py_CFunction f) { py_setdict(py_tpobject(type), py_name(name), &tmp); } +void py_bindstaticmethod(py_Type type, const char* name, py_CFunction f) { + py_TValue tmp; + py_newnativefunc(&tmp, f); + bool ok = py_tpcall(tp_staticmethod, 1, &tmp); + if(!ok) { + py_printexc(); + c11__abort("py_bindstaticmethod(): failed to create staticmethod"); + } + py_setdict(py_tpobject(type), py_name(name), py_retval()); +} + void py_bindfunc(py_Ref obj, const char* name, py_CFunction f) { py_TValue tmp; py_newnativefunc(&tmp, f); diff --git a/tests/80_linalg.py b/tests/80_linalg.py index 1dc8cd3b..dbc91b22 100644 --- a/tests/80_linalg.py +++ b/tests/80_linalg.py @@ -315,16 +315,9 @@ val = vec2.angle(vec2(-1, 0), vec2(0, -1)) assert 1.57 < val < 1.58 # test about staticmethod -# class mymat3x3(mat3x3): -# def f(self): -# _0 = self.zeros() -# _1 = super().zeros() -# _2 = mat3x3.zeros() -# return _0 == _1 == _2 - -# assert mymat3x3().f() - d = mat3x3.identity() +d1 = mat3x3(1, 2, 3, 4, 5, 6, 7, 8, 9).identity() +assert d == d1 assert d.copy_(mat3x3.zeros()) is None assert d == mat3x3.zeros()