10
10
11
11
static VALUE mPyCall ;
12
12
static VALUE cPyPtr ;
13
+ static VALUE cPyTypePtr ;
13
14
14
15
static PyObject * Py_None = NULL ;
15
16
static PyTypeObject * PyType_Type = NULL ;
@@ -233,7 +234,7 @@ pycall_pyptr_new(PyObject *pyobj)
233
234
}
234
235
235
236
static VALUE
236
- pycall_pyptr_s_new (VALUE klass , VALUE val )
237
+ pycall_pyptr_initialize (VALUE pyptr , VALUE val )
237
238
{
238
239
VALUE addr ;
239
240
PyObject * pyobj ;
@@ -244,7 +245,8 @@ pycall_pyptr_s_new(VALUE klass, VALUE val)
244
245
}
245
246
246
247
pyobj = (PyObject * )NUM2PTR (addr );
247
- return pycall_pyptr_new_with_klass (klass , pyobj );
248
+ DATA_PTR (pyptr ) = pyobj ;
249
+ return pyptr ;
248
250
}
249
251
250
252
static VALUE
@@ -301,10 +303,28 @@ pycall_pyptr_inspect(VALUE obj)
301
303
return str ;
302
304
}
303
305
306
+ static VALUE
307
+ class_or_module_required (VALUE klass )
308
+ {
309
+ if (SPECIAL_CONST_P (klass )) goto not_class ;
310
+ switch (BUILTIN_TYPE (klass )) {
311
+ case T_MODULE :
312
+ case T_CLASS :
313
+ case T_ICLASS :
314
+ break ;
315
+
316
+ default :
317
+ not_class :
318
+ rb_raise (rb_eTypeError , "class or module required" );
319
+ }
320
+ return klass ;
321
+ }
322
+
304
323
static VALUE
305
324
pycall_pyptr_is_kind_of (VALUE obj , VALUE klass )
306
325
{
307
326
PyObject * pyobj = get_pyobj_ptr (obj );
327
+ VALUE res ;
308
328
309
329
if (is_pycall_pyptr (klass )) {
310
330
PyObject * pyobj_klass = get_pyobj_ptr (klass );
@@ -314,14 +334,94 @@ pycall_pyptr_is_kind_of(VALUE obj, VALUE klass)
314
334
}
315
335
}
316
336
317
- return rb_call_super (1 , & klass );
337
+ klass = class_or_module_required (klass );
338
+ res = rb_class_inherited_p (CLASS_OF (obj ), klass );
339
+ return NIL_P (res ) ? Qfalse : res ;
340
+ }
341
+
342
+
343
+ static const rb_data_type_t pycall_pytypeptr_data_type = {
344
+ "PyCall::PyTypePtr" ,
345
+ { 0 , pycall_pyptr_free , pycall_pyptr_memsize , },
346
+ #ifdef RUBY_TYPED_FREE_IMMEDIATELY
347
+ & pycall_pyptr_data_type , 0 , RUBY_TYPED_FREE_IMMEDIATELY
348
+ #endif
349
+ };
350
+
351
+ static inline int
352
+ is_pycall_pytypeptr (VALUE obj )
353
+ {
354
+ return rb_typeddata_is_kind_of (obj , & pycall_pytypeptr_data_type );
355
+ }
356
+
357
+ static inline PyTypeObject *
358
+ get_pytype_ptr (VALUE obj )
359
+ {
360
+ PyTypeObject * pytype ;
361
+ TypedData_Get_Struct (obj , PyTypeObject , & pycall_pytypeptr_data_type , pytype );
362
+ return pytype ;
363
+ }
364
+
365
+ static inline PyTypeObject *
366
+ try_get_pytype_ptr (VALUE obj )
367
+ {
368
+ if (is_pycall_pytypeptr (obj )) return NULL ;
369
+ return (PyTypeObject * )DATA_PTR (obj );
370
+ }
371
+
372
+ PyTypeObject *
373
+ pycall_pytypeptr_get_pytype_ptr (VALUE obj )
374
+ {
375
+ return try_get_pytype_ptr (obj );
376
+ }
377
+
378
+ static VALUE
379
+ pycall_pytypeptr_allocate (VALUE klass )
380
+ {
381
+ return TypedData_Wrap_Struct (klass , & pycall_pytypeptr_data_type , NULL );
382
+ }
383
+
384
+ static VALUE
385
+ pycall_pytypeptr_get_ob_size (VALUE obj )
386
+ {
387
+ PyTypeObject * pytype = get_pytype_ptr (obj );
388
+ if (pytype )
389
+ return SSIZET2NUM (pytype -> ob_base .ob_size );
390
+ return Qnil ;
391
+ }
392
+
393
+ static VALUE
394
+ pycall_pytypeptr_get_tp_name (VALUE obj )
395
+ {
396
+ PyTypeObject * pytype = get_pytype_ptr (obj );
397
+ if (pytype )
398
+ return rb_str_new2 (pytype -> tp_name );
399
+ return Qnil ;
400
+ }
401
+
402
+ static VALUE
403
+ pycall_pytypeptr_get_tp_basicsize (VALUE obj )
404
+ {
405
+ PyTypeObject * pytype = get_pytype_ptr (obj );
406
+ if (pytype )
407
+ return SSIZET2NUM (pytype -> tp_basicsize );
408
+ return Qnil ;
409
+ }
410
+
411
+ static VALUE
412
+ pycall_pytypeptr_get_tp_flags (VALUE obj )
413
+ {
414
+ PyTypeObject * pytype = get_pytype_ptr (obj );
415
+ if (pytype )
416
+ return ULONG2NUM (pytype -> tp_flags );
417
+ return Qnil ;
318
418
}
319
419
320
420
void
321
421
Init_pyptr (void )
322
422
{
323
423
mPyCall = rb_define_module ("PyCall" );
324
- cPyPtr = rb_define_class_under (mPyCall , "PyPtr" , rb_cData );
424
+ cPyPtr = rb_define_class_under (mPyCall , "PyPtr" , rb_cBasicObject );
325
425
326
426
rb_define_singleton_method (cPyPtr , "__initialize__" , pycall_pyptr_s_initialize , 1 );
327
427
rb_define_singleton_method (cPyPtr , "__initialized__" , pycall_pyptr_s_get_initialized , 0 );
@@ -330,7 +430,8 @@ Init_pyptr(void)
330
430
rb_define_singleton_method (cPyPtr , "decref" , pycall_pyptr_s_decref , 1 );
331
431
rb_define_singleton_method (cPyPtr , "sizeof" , pycall_pyptr_s_sizeof , 1 );
332
432
333
- rb_define_singleton_method (cPyPtr , "new" , pycall_pyptr_s_new , 1 );
433
+ rb_define_alloc_func (cPyPtr , pycall_pyptr_allocate );
434
+ rb_define_method (cPyPtr , "initialize" , pycall_pyptr_initialize , 1 );
334
435
rb_define_method (cPyPtr , "null?" , pycall_pyptr_is_null , 0 );
335
436
rb_define_method (cPyPtr , "none?" , pycall_pyptr_is_none , 0 );
336
437
rb_define_method (cPyPtr , "__address__" , pycall_pyptr_get_ptr_address , 0 );
@@ -344,4 +445,11 @@ Init_pyptr(void)
344
445
VALUE pyptr_null = pycall_pyptr_new (NULL );
345
446
rb_define_const (cPyPtr , "NULL" , pyptr_null );
346
447
}
448
+
449
+ cPyTypePtr = rb_define_class_under (mPyCall , "PyTypePtr" , cPyPtr );
450
+ rb_define_alloc_func (cPyTypePtr , pycall_pytypeptr_allocate );
451
+ rb_define_method (cPyTypePtr , "__ob_size__" , pycall_pytypeptr_get_ob_size , 0 );
452
+ rb_define_method (cPyTypePtr , "__tp_name__" , pycall_pytypeptr_get_tp_name , 0 );
453
+ rb_define_method (cPyTypePtr , "__tp_basicsize__" , pycall_pytypeptr_get_tp_basicsize , 0 );
454
+ rb_define_method (cPyTypePtr , "__tp_flags__" , pycall_pytypeptr_get_tp_flags , 0 );
347
455
}
0 commit comments