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

Call tp_clear of base unmanaged type#1541

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes fromall commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletionssrc/embed_tests/Inheritance.cs
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;

using NUnit.Framework;

Expand DownExpand Up@@ -100,6 +98,18 @@ public void SetAdHocAttributes_WhenExtraBasePresent()
int actual = scope.Eval<int>($"{nameof(instance)}.{nameof(Inherited.XProp)}");
Assert.AreEqual(expected: Inherited.X, actual);
}

// https://github.com/pythonnet/pythonnet/issues/1476
[Test]
public void BaseClearIsCalled()
{
using var scope = Py.CreateScope();
scope.Set("exn", new Exception("42"));
var msg = scope.Eval("exn.args[0]");
Assert.AreEqual(2, msg.Refcount);
scope.Set("exn", null);
Assert.AreEqual(1, msg.Refcount);
}
}

class ExtraBaseTypeProvider : IPythonBaseTypeProvider
Expand Down
20 changes: 20 additions & 0 deletionssrc/runtime/classbase.cs
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;

namespace Python.Runtime
{
Expand DownExpand Up@@ -365,11 +366,30 @@ public static int tp_clear(IntPtr ob)
if (!isTypeObject)
{
ClearObjectDict(ob);

int baseClearResult = BaseUnmanagedClear(ob);
if (baseClearResult != 0)
{
return baseClearResult;
}
}
if (self is not null) self.tpHandle = IntPtr.Zero;
return 0;
}

static unsafe int BaseUnmanagedClear(IntPtr ob)
{
var type = Runtime.PyObject_TYPE(new BorrowedReference(ob));
var unmanagedBase = GetUnmanagedBaseType(type);
var clearPtr = Marshal.ReadIntPtr(unmanagedBase.DangerousGetAddress(), TypeOffset.tp_clear);
if (clearPtr == IntPtr.Zero)
{
return 0;
}
var clear = (delegate* unmanaged[Cdecl]<IntPtr, int>)clearPtr;
return clear(ob);
}

protected override void OnSave(InterDomainContext context)
{
base.OnSave(context);
Expand Down
10 changes: 10 additions & 0 deletionssrc/runtime/managedtype.cs
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -149,6 +149,16 @@ internal static bool IsManagedType(BorrowedReference type)
return (flags & TypeFlags.HasClrInstance) != 0;
}

internal static BorrowedReference GetUnmanagedBaseType(BorrowedReference managedType)
{
Debug.Assert(managedType != null && IsManagedType(managedType));
do
{
managedType = PyType.GetBase(managedType);
} while (IsManagedType(managedType));
return managedType;
}

public bool IsClrMetaTypeInstance()
{
Debug.Assert(Runtime.PyCLRMetaType != IntPtr.Zero);
Expand Down
18 changes: 14 additions & 4 deletionssrc/runtime/pytype.cs
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
#nullable enable
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;

using Python.Runtime.Native;
Expand DownExpand Up@@ -60,6 +61,11 @@ public static bool IsType(PyObject value)

return Runtime.PyType_Check(value.obj);
}
/// <summary>Checks if specified object is a Python type.</summary>
internal static bool IsType(BorrowedReference value)
{
return Runtime.PyType_Check(value.DangerousGetAddress());
}

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

internal BorrowedReference BaseReference
{
get
{
return new(Marshal.ReadIntPtr(Handle, TypeOffset.tp_base));
}
get => GetBase(Reference);
set
{
var old = BaseReference.DangerousGetAddressOrNull();
Expand All@@ -100,6 +103,13 @@ internal IntPtr GetSlot(TypeSlotID slot)
return Exceptions.ErrorCheckIfNull(result);
}

internal static BorrowedReference GetBase(BorrowedReference type)
{
Debug.Assert(IsType(type));
IntPtr basePtr = Marshal.ReadIntPtr(type.DangerousGetAddress(), TypeOffset.tp_base);
return new BorrowedReference(basePtr);
}

private static IntPtr EnsureIsType(in StolenReference reference)
{
IntPtr address = reference.DangerousGetAddressOrNull();
Expand Down

[8]ページ先頭

©2009-2025 Movatter.jp