- Notifications
You must be signed in to change notification settings - Fork750
Weakref support#1267
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
Uh oh!
There was an error while loading.Please reload this page.
Weakref support#1267
Changes fromall commits
d6c9716
5d57e5a
f08813c
b014ce1
e7f97a9
b68f0a4
b4b1cff
ff35e6d
ea3d47a
958a8eb
53ad8d9
647bc8a
f474039
File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading.Please reload this page.
Jump to
Uh oh!
There was an error while loading.Please reload this page.
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
using System; | ||
using System.Runtime.InteropServices; | ||
using NUnit.Framework; | ||
using Python.Runtime; | ||
using PyRuntime = Python.Runtime.Runtime; | ||
namespace Python.EmbeddingTest | ||
{ | ||
public class TestClass | ||
{ | ||
public class MyClass | ||
{ | ||
} | ||
[OneTimeSetUp] | ||
public void SetUp() | ||
{ | ||
PythonEngine.Initialize(); | ||
} | ||
[OneTimeTearDown] | ||
public void Dispose() | ||
{ | ||
PythonEngine.Shutdown(); | ||
} | ||
[Test] | ||
public void WeakRefForClrObject() | ||
{ | ||
var obj = new MyClass(); | ||
using var scope = Py.CreateScope(); | ||
scope.Set("clr_obj", obj); | ||
scope.Exec(@" | ||
import weakref | ||
ref = weakref.ref(clr_obj) | ||
"); | ||
using PyObject pyobj = scope.Get("clr_obj"); | ||
ValidateAttachedGCHandle(obj, pyobj.Handle); | ||
} | ||
[Test] | ||
public void WeakRefForSubClass() | ||
{ | ||
using (var scope = Py.CreateScope()) | ||
{ | ||
scope.Exec(@" | ||
from Python.EmbeddingTest import TestClass | ||
import weakref | ||
class Sub(TestClass.MyClass): | ||
pass | ||
obj = Sub() | ||
ref = weakref.ref(obj) | ||
"); | ||
using (PyObject pyobj = scope.Get("obj")) | ||
{ | ||
IntPtr op = pyobj.Handle; | ||
IntPtr type = PyRuntime.PyObject_TYPE(op); | ||
IntPtr clrHandle = Marshal.ReadIntPtr(op, ObjectOffset.magic(type)); | ||
var clobj = (CLRObject)GCHandle.FromIntPtr(clrHandle).Target; | ||
Assert.IsTrue(clobj.inst is MyClass); | ||
} | ||
} | ||
} | ||
private static void ValidateAttachedGCHandle(object obj, IntPtr op) | ||
{ | ||
IntPtr type = PyRuntime.PyObject_TYPE(op); | ||
IntPtr clrHandle = Marshal.ReadIntPtr(op, ObjectOffset.magic(type)); | ||
var clobj = (CLRObject)GCHandle.FromIntPtr(clrHandle).Target; | ||
Assert.True(ReferenceEquals(clobj.inst, obj)); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,7 @@ | ||
using System; | ||
using System.Collections; | ||
using System.Collections.Generic; | ||
using System.Runtime.InteropServices; | ||
namespace Python.Runtime | ||
{ | ||
@@ -354,44 +352,39 @@ public static IntPtr tp_repr(IntPtr ob) | ||
public static void tp_dealloc(IntPtr ob) | ||
{ | ||
ManagedType self = GetManagedObject(ob); | ||
if (Runtime.PyType_SUPPORTS_WEAKREFS(Runtime.PyObject_TYPE(ob))) | ||
lostmsu marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
{ | ||
Runtime.PyObject_ClearWeakRefs(ob); | ||
} | ||
RemoveObjectDict(ob); | ||
Runtime.Py_CLEAR(ref self.tpHandle); | ||
Runtime.PyObject_GC_UnTrack(ob); | ||
Runtime.PyObject_GC_Del(ob); | ||
self.FreeGCHandle(); | ||
} | ||
public static int tp_clear(IntPtr ob) | ||
{ | ||
ClearObjectDict(ob); | ||
return 0; | ||
} | ||
protected override void OnSave(InterDomainContext context) | ||
{ | ||
base.OnSave(context); | ||
IntPtr dict = GetObjectDict(pyHandle); | ||
Runtime.XIncref(dict); | ||
Runtime.XIncref(tpHandle); | ||
lostmsu marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
context.Storage.AddValue("dict", dict); | ||
} | ||
protected override void OnLoad(InterDomainContext context) | ||
{ | ||
base.OnLoad(context); | ||
IntPtr dict = context.Storage.GetValue<IntPtr>("dict"); | ||
SetObjectDict(pyHandle, dict); | ||
gcHandle = AllocGCHandle(); | ||
Marshal.WriteIntPtr(pyHandle,ObjectOffset.magic(tpHandle), (IntPtr)gcHandle); | ||
} | ||
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -85,6 +85,13 @@ internal static Exception ToException(IntPtr ob) | ||
} | ||
return Runtime.PyUnicode_FromString(message); | ||
} | ||
public static int tp_init(IntPtr ob, IntPtr args, IntPtr kwds) | ||
{ | ||
Exceptions.SetArgsAndCause(ob); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Please, move the original comment here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. What comment? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. NIT: You seem to have moved this from
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. The comment on | ||
return 0; | ||
} | ||
} | ||
/// <summary> | ||
@@ -180,16 +187,23 @@ internal static void SetArgsAndCause(IntPtr ob) | ||
args = Runtime.PyTuple_New(0); | ||
} | ||
int baseOffset = OriginalObjectOffsets.Size; | ||
Runtime.Py_SETREF(ob, baseOffset + ExceptionOffset.args, args); | ||
if (e.InnerException != null) | ||
{ | ||
IntPtr cause = GetExceptHandle(e.InnerException); | ||
Runtime.Py_SETREF(ob, baseOffset + ExceptionOffset.cause, cause); | ||
} | ||
} | ||
internal static IntPtr GetExceptHandle(Exception e) | ||
{ | ||
IntPtr op = CLRObject.GetInstHandle(e); | ||
SetArgsAndCause(op); | ||
return op; | ||
} | ||
/// <summary> | ||
/// Shortcut for (pointer == NULL) -> throw PythonException | ||
/// </summary> | ||
@@ -289,7 +303,7 @@ public static void SetError(Exception e) | ||
return; | ||
} | ||
IntPtr op =GetExceptHandle(e); | ||
IntPtr etype = Runtime.PyObject_GetAttr(op, PyIdentifier.__class__); | ||
Runtime.PyErr_SetObject(new BorrowedReference(etype), new BorrowedReference(op)); | ||
Runtime.XDecref(etype); | ||
Uh oh!
There was an error while loading.Please reload this page.