@@ -6,8 +6,17 @@ from libcpp.vector cimport vector
6
6
from libc.stdint cimport int8_t, int16_t, int32_t, int64_t, uint8_t, uint16_t, uint32_t, uint64_t
7
7
from libc.stdlib cimport malloc, free
8
8
from numbers import Integral, Number
9
- from cpython cimport Py_DECREF, Py_INCREF, PyCapsule_IsValid, PyCapsule_GetPointer, PyCapsule_SetName, PyCapsule_New
10
9
from . import base
10
+ from cpython.pycapsule cimport (
11
+ PyCapsule_IsValid,
12
+ PyCapsule_GetPointer,
13
+ PyCapsule_SetName,
14
+ PyCapsule_New,
15
+ )
16
+
17
+ cdef extern from " Python.h" :
18
+ void Py_IncRef(object )
19
+ void Py_DecRef(object )
11
20
12
21
Ptr = base.Ptr
13
22
PyCode_NewEmpty = ctypes.pythonapi.PyCode_NewEmpty
@@ -417,21 +426,17 @@ cdef class PyAny:
417
426
raise e.with_traceback(None )
418
427
return _any_c2py_no_inc_ref(c_ret)
419
428
420
- cdef class Str(str ):
421
- cdef MLCAny _mlc_any
422
- __slots__ = ()
423
-
424
- def __cinit__ (self ):
425
- self ._mlc_any = _MLCAnyNone()
426
429
427
- def __init__ (self , value ):
428
- cdef str value_unicode = self
429
- cdef bytes value_c = str_py2c(value_unicode)
430
- self ._mlc_any = _MLCAnyRawStr(value_c)
431
- _check_error(_C_AnyInplaceViewToOwned(& self ._mlc_any))
430
+ class Str (str ):
431
+ __slots__ = (" _pyany" ,)
432
432
433
- def __dealloc__ (self ):
434
- _check_error(_C_AnyDecRef(& self ._mlc_any))
433
+ def __new__ (cls , value: str ):
434
+ cdef PyAny pyany = PyAny()
435
+ self = super ().__new__(cls , value)
436
+ self ._pyany = pyany
437
+ pyany._mlc_any = _MLCAnyRawStr(str_py2c(value))
438
+ _check_error(_C_AnyInplaceViewToOwned(& pyany._mlc_any))
439
+ return self
435
440
436
441
def __reduce__ (self ):
437
442
return (Str, (str (self ),))
@@ -541,7 +546,7 @@ cdef inline object _any_c2py_no_inc_ref(const MLCAny x):
541
546
cdef int32_t type_index = x.type_index
542
547
cdef MLCStr* mlc_str = NULL
543
548
cdef PyAny any_ret
544
- cdef Str str_ret
549
+ cdef object str_ret
545
550
if type_index == kMLCNone:
546
551
return None
547
552
elif type_index == kMLCBool:
@@ -556,8 +561,10 @@ cdef inline object _any_c2py_no_inc_ref(const MLCAny x):
556
561
return str_c2py(x.v.v_str)
557
562
elif type_index == kMLCStr:
558
563
mlc_str = < MLCStr* > (x.v.v_obj)
564
+ any_ret = PyAny()
565
+ any_ret._mlc_any = x
559
566
str_ret = Str.__new__ (Str, str_c2py(mlc_str.data[:mlc_str.length]))
560
- str_ret._mlc_any = x
567
+ str_ret._pyany = any_ret
561
568
return str_ret
562
569
elif type_index == kMLCOpaque:
563
570
return < object > ((< MLCOpaque* > (x.v.v_obj)).handle)
@@ -572,7 +579,7 @@ cdef inline object _any_c2py_inc_ref(MLCAny x):
572
579
cdef int32_t type_index = x.type_index
573
580
cdef MLCStr* mlc_str = NULL
574
581
cdef PyAny any_ret
575
- cdef Str str_ret
582
+ cdef object str_ret
576
583
if type_index == kMLCNone:
577
584
return None
578
585
elif type_index == kMLCBool:
@@ -587,8 +594,10 @@ cdef inline object _any_c2py_inc_ref(MLCAny x):
587
594
return str_c2py(x.v.v_str)
588
595
elif type_index == kMLCStr:
589
596
mlc_str = < MLCStr* > (x.v.v_obj)
597
+ any_ret = PyAny()
598
+ any_ret._mlc_any = x
590
599
str_ret = Str.__new__ (Str, str_c2py(mlc_str.data[:mlc_str.length]))
591
- str_ret._mlc_any = x
600
+ str_ret._pyany = any_ret
592
601
_check_error(_C_AnyIncRef(& x))
593
602
return str_ret
594
603
elif type_index == kMLCOpaque:
@@ -624,11 +633,11 @@ cdef inline PyAny _pyany_from_opaque(object x):
624
633
args[0 ] = _MLCAnyPtr(< uint64_t> (< void * > x))
625
634
args[1 ] = _MLCAnyPtr(< uint64_t> (< void * > _pyobj_deleter))
626
635
args[2 ] = _MLCAnyRawStr(type_name)
627
- Py_INCREF (x)
636
+ Py_IncRef (x)
628
637
try :
629
638
_func_call_impl_with_c_args(_OPAQUE_INIT, 3 , args, & ret._mlc_any)
630
639
except : # no-cython-lint
631
- Py_DECREF (x)
640
+ Py_DecRef (x)
632
641
raise
633
642
return ret
634
643
@@ -677,7 +686,7 @@ cdef inline MLCAny _any_py2c(object x, list temporary_storage):
677
686
elif isinstance (x, PyAny):
678
687
y = (< PyAny> x)._mlc_any
679
688
elif isinstance (x, Str):
680
- y = (< Str > x )._mlc_any
689
+ y = (< PyAny > (x._pyany) )._mlc_any
681
690
elif isinstance (x, bool ):
682
691
y = _MLCAnyBool(< bint> x)
683
692
elif isinstance (x, Integral):
@@ -729,7 +738,7 @@ cdef inline MLCAny _any_py2c_dict(tuple x, list temporary_storage):
729
738
cdef void _pyobj_deleter(void * handle) noexcept nogil:
730
739
with gil:
731
740
try :
732
- Py_DECREF (< object > (handle))
741
+ Py_DecRef (< object > (handle))
733
742
except Exception as exception:
734
743
# TODO(@junrushao): Will need to handle exceptions more gracefully
735
744
print (f" Error in _pyobj_deleter: {exception}" )
@@ -767,7 +776,7 @@ cdef inline int32_t _func_safe_call_impl(
767
776
768
777
cdef inline PyAny _pyany_from_func(object py_func):
769
778
cdef PyAny ret = PyAny()
770
- Py_INCREF (py_func)
779
+ Py_IncRef (py_func)
771
780
_check_error(_C_FuncCreate(< void * > (py_func), _pyobj_deleter, _func_safe_call, & ret._mlc_any))
772
781
return ret
773
782
0 commit comments