Skip to content

Commit bc137bb

Browse files
committed
added a workaround for tp_clear implementations, that do not check, that they are not the first in tp_clear's MRO
https://bugs.python.org/issue45266
1 parent 6b20409 commit bc137bb

File tree

4 files changed

+31
-12
lines changed

4 files changed

+31
-12
lines changed

src/runtime/classbase.cs

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -360,21 +360,33 @@ public static void tp_dealloc(IntPtr ob)
360360

361361
public static int tp_clear(IntPtr ob)
362362
{
363-
ManagedType self = GetManagedObject(ob);
363+
var self = (CLRObject)GetManagedObject(ob);
364364

365-
bool isTypeObject = Runtime.PyObject_TYPE(ob) == Runtime.PyCLRMetaType;
366-
if (!isTypeObject)
367-
{
368-
ClearObjectDict(ob);
365+
if (self.clearReentryGuard) return 0;
369366

370-
int baseClearResult = BaseUnmanagedClear(ob);
371-
if (baseClearResult != 0)
367+
// workaround for https://bugs.python.org/issue45266
368+
self.clearReentryGuard = true;
369+
370+
try
371+
{
372+
bool isTypeObject = Runtime.PyObject_TYPE(ob) == Runtime.PyCLRMetaType;
373+
if (!isTypeObject)
372374
{
373-
return baseClearResult;
375+
int baseClearResult = BaseUnmanagedClear(ob);
376+
if (baseClearResult != 0)
377+
{
378+
return baseClearResult;
379+
}
380+
381+
ClearObjectDict(ob);
374382
}
383+
if (self is not null) self.tpHandle = IntPtr.Zero;
384+
return 0;
385+
}
386+
finally
387+
{
388+
self.clearReentryGuard = false;
375389
}
376-
if (self is not null) self.tpHandle = IntPtr.Zero;
377-
return 0;
378390
}
379391

380392
static unsafe int BaseUnmanagedClear(IntPtr ob)

src/runtime/clrobject.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,11 @@ namespace Python.Runtime
99
internal class CLRObject : ManagedType
1010
{
1111
internal object inst;
12+
internal bool clearReentryGuard;
1213

1314
internal CLRObject(object ob, IntPtr tp)
1415
{
15-
System.Diagnostics.Debug.Assert(tp != IntPtr.Zero);
16+
Debug.Assert(tp != IntPtr.Zero);
1617
IntPtr py = Runtime.PyType_GenericAlloc(tp, 0);
1718

1819
tpHandle = tp;

src/runtime/managedtype.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ internal static bool IsInstanceOfManagedType(IntPtr ob)
145145

146146
internal static bool IsManagedType(BorrowedReference type)
147147
{
148-
var flags = (TypeFlags)Util.ReadCLong(type.DangerousGetAddress(), TypeOffset.tp_flags);
148+
var flags = PyType.GetFlags(type);
149149
return (flags & TypeFlags.HasClrInstance) != 0;
150150
}
151151

src/runtime/pytype.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,12 @@ internal IntPtr GetSlot(TypeSlotID slot)
103103
return Exceptions.ErrorCheckIfNull(result);
104104
}
105105

106+
internal static TypeFlags GetFlags(BorrowedReference type)
107+
{
108+
Debug.Assert(TypeOffset.tp_flags > 0);
109+
return (TypeFlags)Util.ReadCLong(type.DangerousGetAddress(), TypeOffset.tp_flags);
110+
}
111+
106112
internal static BorrowedReference GetBase(BorrowedReference type)
107113
{
108114
Debug.Assert(IsType(type));

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy