Skip to content

Commit f3714a2

Browse files
committed
Set __classcell__ if it exists
1 parent 5c50198 commit f3714a2

File tree

2 files changed

+33
-0
lines changed

2 files changed

+33
-0
lines changed

src/runtime/runtime.cs

+18
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,11 @@ internal static void Initialize(bool initSigs = false)
285285
() => PyFloatType = IntPtr.Zero);
286286
XDecref(op);
287287

288+
op = PyCell_New();
289+
SetPyMember(ref PyCellType, PyObject_Type(op),
290+
() => PyCellType = IntPtr.Zero);
291+
// XDecref(op);
292+
288293
#if !PYTHON2
289294
PyClassType = IntPtr.Zero;
290295
PyInstanceType = IntPtr.Zero;
@@ -452,6 +457,7 @@ private static void ResetPyMembers()
452457
internal static IntPtr PyBoolType;
453458
internal static IntPtr PyNoneType;
454459
internal static IntPtr PyTypeType;
460+
internal static IntPtr PyCellType;
455461

456462
internal static IntPtr Py_NoSiteFlag;
457463

@@ -1965,6 +1971,18 @@ internal static IntPtr PyMem_Realloc(IntPtr ptr, long size)
19651971
[DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
19661972
internal static extern void PyErr_Print();
19671973

1974+
//====================================================================
1975+
// Cell API
1976+
//====================================================================
1977+
1978+
[DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
1979+
internal static extern IntPtr PyCell_New();
1980+
1981+
[DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
1982+
internal static extern NewReference PyCell_Get(IntPtr cell);
1983+
1984+
[DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
1985+
internal static extern int PyCell_Set(IntPtr cell, IntPtr value);
19681986

19691987
//====================================================================
19701988
// Miscellaneous

src/runtime/typemanager.cs

+15
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,21 @@ internal static IntPtr CreateSubType(IntPtr py_name, IntPtr py_base_type, IntPtr
280280
IntPtr cls_dict = Marshal.ReadIntPtr(py_type, TypeOffset.tp_dict);
281281
Runtime.PyDict_Update(cls_dict, py_dict);
282282

283+
// Update the __classcell__ if it exists
284+
IntPtr classCell = Runtime.PyString_FromString("__classcell__");
285+
if (Runtime.PySequence_Contains(cls_dict, classCell) > 0)
286+
{
287+
IntPtr cell = Runtime.PyDict_GetItem(cls_dict, classCell);
288+
if (Runtime.PyObject_TypeCheck(cell, Runtime.PyCellType))
289+
{
290+
Runtime.XIncref(py_type);
291+
Runtime.PyCell_Set(cell, py_type);
292+
}
293+
Runtime.PyDict_DelItem(cls_dict, classCell);
294+
}
295+
296+
Runtime.XDecref(classCell);
297+
283298
return py_type;
284299
}
285300
catch (Exception e)

0 commit comments

Comments
 (0)