ext/pycall/pycall.c in pycall-1.4.1 vs ext/pycall/pycall.c in pycall-1.4.2
- old
+ new
@@ -50,11 +50,11 @@
#undef pycall_python_hexversion
#define pycall_python_hexversion() python_hexversion
#define python_is_unicode_literals (python_major_version >= 3)
-long pycall_hash_salt;
+intptr_t pycall_hash_salt;
static VALUE pycall_call_python_callable(PyObject *pycallable, int argc, VALUE *argv);
#define PyType_Check(pyobj) PyType_FastSubclass(Py_TYPE(pyobj), Py_TPFLAGS_TYPE_SUBCLASS)
#define PyClass_Check(pyobj) (Py_API(PyClass_Type) && (pyobj)->ob_type == Py_API(PyClass_Type))
@@ -78,11 +78,11 @@
/*
* In pthread, the default value is NULL (== 0).
*
* In Win32 thread, the default value is 0 (initialized by TlsAlloc).
*/
- return (int)pycall_tls_get(without_gvl_key);
+ return pycall_tls_get(without_gvl_key) != (void*)0;
}
static inline int
pycall_set_without_gvl(void)
{
@@ -105,10 +105,14 @@
result = rb_protect(func, arg, &state);
pycall_set_with_gvl();
+ if (state) {
+ rb_jump_tag(state);
+ }
+
return result;
}
static VALUE
pycall_m_without_gvl(VALUE mod)
@@ -408,11 +412,10 @@
VALUE cname, str;
PyObject* pyobj = get_pyobj_ptr(obj);
cname = rb_class_name(CLASS_OF(obj));
str = rb_sprintf("#<%"PRIsVALUE":%p type=%s addr=%p>", cname, (void*)obj, Py_TYPE(pyobj)->tp_name, pyobj);
- OBJ_INFECT(str, obj);
return str;
}
static VALUE
@@ -860,10 +863,55 @@
res = Py_API(PyObject_HasAttrString)(pyobj, StringValueCStr(name));
return res ? Qtrue : Qfalse;
}
static VALUE
+pycall_libpython_helpers_m_setattr(VALUE mod, VALUE pyptr, VALUE name, VALUE val)
+{
+ PyObject *pyobj, *pyval;
+
+ if (!is_pycall_pyptr(pyptr)) {
+ rb_raise(rb_eTypeError, "PyCall::PyPtr is required");
+ }
+
+ pyobj = get_pyobj_ptr(pyptr);
+
+ if (RB_TYPE_P(name, T_SYMBOL)) {
+ name = rb_sym_to_s(name);
+ }
+
+ pyval = pycall_pyobject_from_ruby(val);
+ if (Py_API(PyObject_SetAttrString)(pyobj, StringValueCStr(name), pyval) == -1) {
+ pycall_pyerror_fetch_and_raise("PyObject_SetAttrString");
+ }
+
+ return Qnil;
+}
+
+static VALUE
+pycall_libpython_helpers_m_delattr(VALUE mod, VALUE pyptr, VALUE name)
+{
+ PyObject *pyobj;
+
+ if (!is_pycall_pyptr(pyptr)) {
+ rb_raise(rb_eTypeError, "PyCall::PyPtr is required");
+ }
+
+ pyobj = get_pyobj_ptr(pyptr);
+
+ if (RB_TYPE_P(name, T_SYMBOL)) {
+ name = rb_sym_to_s(name);
+ }
+
+ if (Py_API(PyObject_DelAttrString)(pyobj, StringValueCStr(name)) == -1) {
+ pycall_pyerror_fetch_and_raise("PyObject_DelAttrString");
+ }
+
+ return Qnil;
+}
+
+static VALUE
pycall_libpython_helpers_m_callable_p(VALUE mod, VALUE pyptr)
{
PyObject *pyobj;
int res;
@@ -1075,11 +1123,11 @@
}
static VALUE
pycall_libpython_helpers_m_define_wrapper_method(VALUE mod, VALUE wrapper, VALUE name)
{
- VALUE pyptr, name_sym;
+ VALUE pyptr;
PyObject *pyobj, *attr;
char *name_cstr;
pyptr = rb_attr_get(wrapper, rb_intern("@__pyptr__"));
if (NIL_P(pyptr) || !is_pycall_pyptr(pyptr)) {
@@ -1087,16 +1135,12 @@
}
pyobj = get_pyobj_ptr(pyptr);
if (RB_TYPE_P(name, T_SYMBOL)) {
- name_sym = name;
name = rb_sym_to_s(name);
}
- else if (RB_TYPE_P(name, T_STRING)) {
- name_sym = rb_str_intern(name);
- }
name_cstr = StringValueCStr(name);
if (name_cstr[RSTRING_LEN(name) - 1] == '=') {
name_cstr[RSTRING_LEN(name) - 1] = '\0';
attr = Py_API(PyObject_GetAttrString)(pyobj, name_cstr);
@@ -1187,11 +1231,11 @@
return v;
}
static VALUE
-pycall_libpython_helpers_m_delitem(VALUE mod, VALUE pyptr, VALUE key, VALUE v)
+pycall_libpython_helpers_m_delitem(VALUE mod, VALUE pyptr, VALUE key)
{
PyObject *pyobj, *pyobj_key;
int res;
pyobj = check_get_pyobj_ptr(pyptr, NULL);
@@ -1200,11 +1244,11 @@
res = Py_API(PyObject_DelItem)(pyobj, pyobj_key);
if (res == -1) {
pycall_pyerror_fetch_and_raise("PyObject_DelItem");
}
- return v;
+ return Qnil;
}
static VALUE
pycall_libpython_helpers_m_str(VALUE mod, VALUE pyptr)
{
@@ -2015,10 +2059,12 @@
pycall_pyerror_fetch_and_raise(char const *format, ...)
{
va_list args;
VALUE pyerror, msg;
+ RBIMPL_NONNULL_ARG(format);
+
pyerror = pycall_pyerror_fetch();
if (!NIL_P(pyerror))
rb_exc_raise(pyerror);
va_start(args, format);
@@ -2072,15 +2118,28 @@
return Py_API(PyString_FromFormatV)(format, vargs);
}
/* ==== Python ==== */
+int
+pycall_PyObject_DelAttrString(PyObject *pyobj, const char *attr_name)
+{
+ /* PyObject_DelAttrString is defined by using PyObject_SetAttrString in CPython's abstract.h */
+ return Py_API(PyObject_SetAttrString)(pyobj, attr_name, NULL);
+}
+
static void
init_python(void)
{
static char const *argv[1] = { "" };
+ /* optional functions */
+ if (! Py_API(PyObject_DelAttrString)) {
+ /* The case of PyObject_DelAttrString as a macro */
+ Py_API(PyObject_DelAttrString) = pycall_PyObject_DelAttrString;
+ }
+
Py_API(Py_InitializeEx)(0);
Py_API(PySys_SetArgvEx)(0, (char **)argv, 0);
if (!Py_API(PyEval_ThreadsInitialized)()) {
Py_API(PyEval_InitThreads)();
@@ -2234,11 +2293,11 @@
/* PyCall */
rb_define_module_function(mPyCall, "after_fork", pycall_after_fork, 0);
- pycall_tls_create(&without_gvl_key);
+ pycall_tls_create((pycall_tls_key *)&without_gvl_key);
rb_define_module_function(mPyCall, "without_gvl", pycall_m_without_gvl, 0);
/* PyCall::PyPtr */
cPyPtr = rb_define_class_under(mPyCall, "PyPtr", rb_cBasicObject);
@@ -2299,9 +2358,11 @@
rb_define_module_function(mHelpers, "import_module", pycall_libpython_helpers_m_import_module, -1);
rb_define_module_function(mHelpers, "define_wrapper_method", pycall_libpython_helpers_m_define_wrapper_method, 2);
rb_define_module_function(mHelpers, "compare", pycall_libpython_helpers_m_compare, 3);
rb_define_module_function(mHelpers, "getattr", pycall_libpython_helpers_m_getattr, -1);
rb_define_module_function(mHelpers, "hasattr?", pycall_libpython_helpers_m_hasattr_p, 2);
+ rb_define_module_function(mHelpers, "setattr", pycall_libpython_helpers_m_setattr, 3);
+ rb_define_module_function(mHelpers, "delattr", pycall_libpython_helpers_m_delattr, 2);
rb_define_module_function(mHelpers, "callable?", pycall_libpython_helpers_m_callable_p, 1);
rb_define_module_function(mHelpers, "call_object", pycall_libpython_helpers_m_call_object, -1);
rb_define_module_function(mHelpers, "getitem", pycall_libpython_helpers_m_getitem, 2);
rb_define_module_function(mHelpers, "setitem", pycall_libpython_helpers_m_setitem, 3);
rb_define_module_function(mHelpers, "delitem", pycall_libpython_helpers_m_delitem, 2);