Skip to content

Commit c47448e

Browse files
committed
Add pycall_getattr_default and pycall_getattr functions
1 parent 88a4ef3 commit c47448e

File tree

2 files changed

+31
-9
lines changed

2 files changed

+31
-9
lines changed

ext/pycall/pycall.c

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -725,11 +725,38 @@ pycall_libpython_helpers_m_compare(VALUE mod, VALUE op, VALUE pyptr_a, VALUE pyp
725725
return pycall_pyobject_to_ruby(res);
726726
}
727727

728+
static int is_pyobject_wrapper(VALUE obj);
729+
730+
VALUE
731+
pycall_getattr_default(VALUE obj, char const *name, VALUE default_value)
732+
{
733+
PyObject *pyobj, *res;
734+
735+
if (is_pyobject_wrapper(obj)) {
736+
pyobj = pycall_pyobject_wrapper_get_pyobj_ptr(obj);
737+
}
738+
else {
739+
pyobj = check_get_pyobj_ptr(obj, NULL);
740+
}
741+
742+
res = Py_API(PyObject_GetAttrString)(pyobj, name);
743+
if (!res && default_value == Qundef) {
744+
pycall_pyerror_fetch_and_raise("PyObject_GetAttrString in pycall_libpython_helpers_m_getattr");
745+
}
746+
Py_API(PyErr_Clear)();
747+
return res ? pycall_pyobject_to_ruby(res) : default_value;
748+
}
749+
750+
VALUE
751+
pycall_getattr(VALUE pyptr, char const *name)
752+
{
753+
return pycall_getattr_default(pyptr, name, Qundef);
754+
}
755+
728756
static VALUE
729757
pycall_libpython_helpers_m_getattr(int argc, VALUE *argv, VALUE mod)
730758
{
731759
VALUE pyptr, name, default_value;
732-
PyObject *pyobj, *res;
733760

734761
if (rb_scan_args(argc, argv, "21", &pyptr, &name, &default_value) == 2) {
735762
default_value = Qundef;
@@ -739,18 +766,11 @@ pycall_libpython_helpers_m_getattr(int argc, VALUE *argv, VALUE mod)
739766
rb_raise(rb_eTypeError, "PyCall::PyPtr is required");
740767
}
741768

742-
pyobj = get_pyobj_ptr(pyptr);
743-
744769
if (RB_TYPE_P(name, T_SYMBOL)) {
745770
name = rb_sym_to_s(name);
746771
}
747772

748-
res = Py_API(PyObject_GetAttrString)(pyobj, StringValueCStr(name));
749-
if (!res && default_value == Qundef) {
750-
pycall_pyerror_fetch_and_raise("PyObject_GetAttrString in pycall_libpython_helpers_m_getattr");
751-
}
752-
Py_API(PyErr_Clear)();
753-
return res ? pycall_pyobject_to_ruby(res) : default_value;
773+
return pycall_getattr_default(pyptr, StringValueCStr(name), default_value);
754774
}
755775

756776
static VALUE

ext/pycall/pycall_internal.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -632,6 +632,8 @@ void pycall_pyptr_free(void *);
632632

633633
VALUE pycall_import_module(char const *name);
634634
VALUE pycall_import_module_level(char const *name, VALUE globals, VALUE locals, VALUE fromlist, int level);
635+
VALUE pycall_getattr_default(VALUE pyobj, char const *name, VALUE default_value);
636+
VALUE pycall_getattr(VALUE pyobj, char const *name);
635637

636638
VALUE pycall_pyobject_to_ruby(PyObject *);
637639
VALUE pycall_pytype_to_ruby(PyObject *);

0 commit comments

Comments
 (0)