Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit2ef6b50

Browse files
committed
call tp_clear (if any) of base unmanaged type when a reflected CLR object instance is cleared
fixes#1476 : C# exceptions inherit from Python BaseException class, which has tp_clear. Prior to this change it was not called, leaving dangling references to BaseException.args and BaseException.__cause__.call tp_clear of base unmanaged type when a reflected CLR object instance is clearedfixes#1476 : C# exceptions inherit from Python BaseException class, which has tp_clear. Prior to this change it was not called, leaving dangling references to BaseException.args and BaseException.__cause__.
1 parentdc3c818 commit2ef6b50

File tree

4 files changed

+56
-6
lines changed

4 files changed

+56
-6
lines changed

‎src/embed_tests/Inheritance.cs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
usingSystem;
22
usingSystem.Collections.Generic;
3-
usingSystem.Diagnostics;
4-
usingSystem.Runtime.InteropServices;
53

64
usingNUnit.Framework;
75

@@ -100,6 +98,18 @@ public void SetAdHocAttributes_WhenExtraBasePresent()
10098
intactual=scope.Eval<int>($"{nameof(instance)}.{nameof(Inherited.XProp)}");
10199
Assert.AreEqual(expected:Inherited.X,actual);
102100
}
101+
102+
// https://github.com/pythonnet/pythonnet/issues/1476
103+
[Test]
104+
publicvoidBaseClearIsCalled()
105+
{
106+
usingvarscope=Py.CreateScope();
107+
scope.Set("exn",newException("42"));
108+
varmsg=scope.Eval("exn.args[0]");
109+
Assert.AreEqual(2,msg.Refcount);
110+
scope.Set("exn",null);
111+
Assert.AreEqual(1,msg.Refcount);
112+
}
103113
}
104114

105115
classExtraBaseTypeProvider:IPythonBaseTypeProvider

‎src/runtime/classbase.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
usingSystem;
22
usingSystem.Collections;
33
usingSystem.Collections.Generic;
4+
usingSystem.Runtime.InteropServices;
45

56
namespacePython.Runtime
67
{
@@ -365,11 +366,30 @@ public static int tp_clear(IntPtr ob)
365366
if(!isTypeObject)
366367
{
367368
ClearObjectDict(ob);
369+
370+
intbaseClearResult=BaseUnmanagedClear(ob);
371+
if(baseClearResult!=0)
372+
{
373+
returnbaseClearResult;
374+
}
368375
}
369376
if(selfis notnull)self.tpHandle=IntPtr.Zero;
370377
return0;
371378
}
372379

380+
staticunsafeintBaseUnmanagedClear(IntPtrob)
381+
{
382+
vartype=Runtime.PyObject_TYPE(newBorrowedReference(ob));
383+
varunmanagedBase=GetUnmanagedBaseType(type);
384+
varclearPtr=Marshal.ReadIntPtr(unmanagedBase.DangerousGetAddress(),TypeOffset.tp_clear);
385+
if(clearPtr==IntPtr.Zero)
386+
{
387+
return0;
388+
}
389+
varclear=(delegate* unmanaged[Cdecl]<IntPtr,int>)clearPtr;
390+
returnclear(ob);
391+
}
392+
373393
protectedoverridevoidOnSave(InterDomainContextcontext)
374394
{
375395
base.OnSave(context);

‎src/runtime/managedtype.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,16 @@ internal static bool IsManagedType(BorrowedReference type)
149149
return(flags&TypeFlags.HasClrInstance)!=0;
150150
}
151151

152+
internalstaticBorrowedReferenceGetUnmanagedBaseType(BorrowedReferencemanagedType)
153+
{
154+
Debug.Assert(managedType!=null&&IsManagedType(managedType));
155+
do
156+
{
157+
managedType=PyType.GetBase(managedType);
158+
}while(IsManagedType(managedType));
159+
returnmanagedType;
160+
}
161+
152162
publicboolIsClrMetaTypeInstance()
153163
{
154164
Debug.Assert(Runtime.PyCLRMetaType!=IntPtr.Zero);

‎src/runtime/pytype.cs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#nullable enable
22
usingSystem;
3+
usingSystem.Diagnostics;
34
usingSystem.Runtime.InteropServices;
45

56
usingPython.Runtime.Native;
@@ -60,6 +61,11 @@ public static bool IsType(PyObject value)
6061

6162
returnRuntime.PyType_Check(value.obj);
6263
}
64+
/// <summary>Checks if specified object is a Python type.</summary>
65+
internalstaticboolIsType(BorrowedReferencevalue)
66+
{
67+
returnRuntime.PyType_Check(value.DangerousGetAddress());
68+
}
6369

6470
/// <summary>
6571
/// Gets <see cref="PyType"/>, which represents the specified CLR type.
@@ -78,10 +84,7 @@ internal static PyType Get(Type clrType)
7884

7985
internalBorrowedReferenceBaseReference
8086
{
81-
get
82-
{
83-
returnnew(Marshal.ReadIntPtr(Handle,TypeOffset.tp_base));
84-
}
87+
get=>GetBase(Reference);
8588
set
8689
{
8790
varold=BaseReference.DangerousGetAddressOrNull();
@@ -100,6 +103,13 @@ internal IntPtr GetSlot(TypeSlotID slot)
100103
returnExceptions.ErrorCheckIfNull(result);
101104
}
102105

106+
internalstaticBorrowedReferenceGetBase(BorrowedReferencetype)
107+
{
108+
Debug.Assert(IsType(type));
109+
IntPtrbasePtr=Marshal.ReadIntPtr(type.DangerousGetAddress(),TypeOffset.tp_base);
110+
returnnewBorrowedReference(basePtr);
111+
}
112+
103113
privatestaticIntPtrEnsureIsType(inStolenReferencereference)
104114
{
105115
IntPtraddress=reference.DangerousGetAddressOrNull();

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp