@@ -861,6 +861,51 @@ pycall_libpython_helpers_m_hasattr_p(VALUE mod, VALUE pyptr, VALUE name)
861861 return res ? Qtrue : Qfalse ;
862862}
863863
864+ static VALUE
865+ pycall_libpython_helpers_m_setattr (VALUE mod , VALUE pyptr , VALUE name , VALUE val )
866+ {
867+ PyObject * pyobj , * pyval ;
868+
869+ if (!is_pycall_pyptr (pyptr )) {
870+ rb_raise (rb_eTypeError , "PyCall::PyPtr is required" );
871+ }
872+
873+ pyobj = get_pyobj_ptr (pyptr );
874+
875+ if (RB_TYPE_P (name , T_SYMBOL )) {
876+ name = rb_sym_to_s (name );
877+ }
878+
879+ pyval = pycall_pyobject_from_ruby (val );
880+ if (Py_API (PyObject_SetAttrString )(pyobj , StringValueCStr (name ), pyval ) == -1 ) {
881+ pycall_pyerror_fetch_and_raise ("PyObject_SetAttrString" );
882+ }
883+
884+ return Qnil ;
885+ }
886+
887+ static VALUE
888+ pycall_libpython_helpers_m_delattr (VALUE mod , VALUE pyptr , VALUE name )
889+ {
890+ PyObject * pyobj ;
891+
892+ if (!is_pycall_pyptr (pyptr )) {
893+ rb_raise (rb_eTypeError , "PyCall::PyPtr is required" );
894+ }
895+
896+ pyobj = get_pyobj_ptr (pyptr );
897+
898+ if (RB_TYPE_P (name , T_SYMBOL )) {
899+ name = rb_sym_to_s (name );
900+ }
901+
902+ if (Py_API (PyObject_DelAttrString )(pyobj , StringValueCStr (name )) == -1 ) {
903+ pycall_pyerror_fetch_and_raise ("PyObject_DelAttrString" );
904+ }
905+
906+ return Qnil ;
907+ }
908+
864909static VALUE
865910pycall_libpython_helpers_m_callable_p (VALUE mod , VALUE pyptr )
866911{
@@ -2074,11 +2119,24 @@ pycall_pystring_from_formatv(char const *format, va_list vargs)
20742119
20752120/* ==== Python ==== */
20762121
2122+ int
2123+ pycall_PyObject_DelAttrString (PyObject * pyobj , const char * attr_name )
2124+ {
2125+ /* PyObject_DelAttrString is defined by using PyObject_SetAttrString in CPython's abstract.h */
2126+ return Py_API (PyObject_SetAttrString )(pyobj , attr_name , NULL );
2127+ }
2128+
20772129static void
20782130init_python (void )
20792131{
20802132 static char const * argv [1 ] = { "" };
20812133
2134+ /* optional functions */
2135+ if (! Py_API (PyObject_DelAttrString )) {
2136+ /* The case of PyObject_DelAttrString as a macro */
2137+ Py_API (PyObject_DelAttrString ) = pycall_PyObject_DelAttrString ;
2138+ }
2139+
20822140 Py_API (Py_InitializeEx )(0 );
20832141 Py_API (PySys_SetArgvEx )(0 , (char * * )argv , 0 );
20842142
@@ -2301,6 +2359,8 @@ Init_pycall(void)
23012359 rb_define_module_function (mHelpers , "compare" , pycall_libpython_helpers_m_compare , 3 );
23022360 rb_define_module_function (mHelpers , "getattr" , pycall_libpython_helpers_m_getattr , -1 );
23032361 rb_define_module_function (mHelpers , "hasattr?" , pycall_libpython_helpers_m_hasattr_p , 2 );
2362+ rb_define_module_function (mHelpers , "setattr" , pycall_libpython_helpers_m_setattr , 3 );
2363+ rb_define_module_function (mHelpers , "delattr" , pycall_libpython_helpers_m_delattr , 2 );
23042364 rb_define_module_function (mHelpers , "callable?" , pycall_libpython_helpers_m_callable_p , 1 );
23052365 rb_define_module_function (mHelpers , "call_object" , pycall_libpython_helpers_m_call_object , -1 );
23062366 rb_define_module_function (mHelpers , "getitem" , pycall_libpython_helpers_m_getitem , 2 );
0 commit comments