8000 More changes to use BorrowedReference and NewReference · pythonnet/pythonnet@cc6b8e4 · GitHub
[go: up one dir, main page]

Skip to content
8000

Commit cc6b8e4

Browse files
committed
More changes to use BorrowedReference and NewReference
Also adds implicit IntPtr conversion operators to simplify their use.
1 parent 2343f89 commit cc6b8e4

File tree

4 files changed

+29
-7
lines changed

4 files changed

+29
-7
lines changed

src/runtime/BorrowedReference.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ readonly ref struct BorrowedReference
1010
readonly IntPtr pointer;
1111
public bool IsNull => this.pointer == IntPtr.Zero;
1212

13+
public static implicit operator IntPtr(in BorrowedReference self) => self.DangerousGetAddress();
14+
1315
/// <summary>Gets a raw pointer to the Python object</summary>
1416
public IntPtr DangerousGetAddress()
1517
=> this.IsNull ? throw new NullReferenceException() : this.pointer;

src/runtime/NewReference.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ ref struct NewReference
1515
public static implicit operator BorrowedReference(in NewReference reference)
1616
=> new BorrowedReference(reference.pointer);
1717

18+
[Pure]
19+
public static implicit operator IntPtr(in NewReference reference)
20+
=> DangerousGetAddress(reference);
21+
1822
/// <summary>
1923
/// Returns <see cref="PyObject"/> wrapper around this reference, which now owns
2024
/// the pointer. Sets the original reference to <c>null</c>, as it no longer owns it.

src/runtime/runtime.cs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -748,6 +748,22 @@ internal static IntPtr SelfIncRef(IntPtr op)
748748
return op;
749749
}
750750

751+
/// <remark>
752+
/// We need this method because BorrowedReference can be implicitly casted to IntPtr.
753+
/// </remark>
754+
internal static void XDecref(BorrowedReference op)
755+
{
756+
throw new InvalidOperationException("Cannot DecRef a borrowed reference.");
757+
}
758+
759+
/// <remark>
760+
/// We need this method because NewReference can be implicitly casted to IntPtr.
761+
/// </remark>
762+
internal static void XDecref(NewReference op)
763+
{
764+
op.Dispose();
765+
}
766+
751767
internal static unsafe void XDecref(IntPtr op)
752768
{
753769
#if PYTHON_WITH_PYDEBUG || NETSTANDARD
@@ -2129,7 +2145,7 @@ internal static void Py_CLEAR(ref IntPtr ob)
21292145
//====================================================================
21302146

21312147
[DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
2132-
internal static extern IntPtr PyCapsule_New(IntPtr pointer, string name, IntPtr destructor);
2148+
internal static extern NewReference PyCapsule_New(IntPtr pointer, string name, IntPtr destructor);
21332149

21342150
[DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
21352151
internal static extern IntPtr PyCapsule_GetPointer(IntPtr capsule, string name);

src/runtime/runtime_data.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ public static Type FormatterType
3636
/// </summary>
3737
static void ClearCLRData ()
3838
{
39-
IntPtr capsule = PySys_GetObject("clr_data").DangerousGetAddressUnchecked();
40-
if (capsule != IntPtr.Zero)
39+
BorrowedReference capsule = PySys_GetObject("clr_data");
40+
if (!capsule.IsNull)
4141
{
4242
IntPtr oldData = PyCapsule_GetPointer(capsule, null);
4343
PyMem_Free(oldData);
@@ -85,10 +85,10 @@ internal static void Stash()
8585
Marshal.Copy(data, 0, mem + IntPtr.Size, (int)ms.Length);
8686

8787
ClearCLRData();
88-
IntPtr capsule = PyCapsule_New(mem, null, IntPtr.Zero);
88+
NewReference capsule = PyCapsule_New(mem, null, IntPtr.Zero);
8989
PySys_SetObject("clr_data", capsule);
9090
// Let the dictionary own the reference
91-
XDecref(capsule);
91+
capsule.Dispose();
9292
}
9393

9494
internal static void RestoreRuntimeData()
@@ -105,8 +105,8 @@ internal static void RestoreRuntimeData()
105105

106106
private static void RestoreRuntimeDataImpl()
107107
{
108-
IntPtr capsule = PySys_GetObject("clr_data").DangerousGetAddressUnchecked();
109-
if (capsule == IntPtr.Zero)
108+
BorrowedReference capsule = PySys_GetObject("clr_data");
109+
if (capsule.IsNull)
110110
{
111111
return;
112112
}

0 commit comments

Comments
 (0)
0