diff --git a/src/embed_tests/pyimport.cs b/src/embed_tests/pyimport.cs
index acb3433de..6b2408745 100644
--- a/src/embed_tests/pyimport.cs
+++ b/src/embed_tests/pyimport.cs
@@ -39,7 +39,7 @@ public void SetUp()
IntPtr str = Runtime.Runtime.PyString_FromString(testPath);
IntPtr path = Runtime.Runtime.PySys_GetObject("path");
- Runtime.Runtime.PyList_Append(path, str);
+ Runtime.Runtime.PyList_Append(new BorrowedReference(path), str);
}
[TearDown]
diff --git a/src/runtime/BorrowedReference.cs b/src/runtime/BorrowedReference.cs
index 7dbc7a811..a3bf29056 100644
--- a/src/runtime/BorrowedReference.cs
+++ b/src/runtime/BorrowedReference.cs
@@ -14,7 +14,10 @@ readonly ref struct BorrowedReference
public IntPtr DangerousGetAddress()
=> this.IsNull ? throw new NullReferenceException() : this.pointer;
- BorrowedReference(IntPtr pointer)
+ ///
+ /// Creates new instance of from raw pointer. Unsafe.
+ ///
+ public BorrowedReference(IntPtr pointer)
{
this.pointer = pointer;
}
diff --git a/src/runtime/pylist.cs b/src/runtime/pylist.cs
index b22d9d51f..347cc3000 100644
--- a/src/runtime/pylist.cs
+++ b/src/runtime/pylist.cs
@@ -120,7 +120,7 @@ public static PyList AsList(PyObject value)
///
public void Append(PyObject item)
{
- int r = Runtime.PyList_Append(obj, item.obj);
+ int r = Runtime.PyList_Append(this.Reference, item.obj);
if (r < 0)
{
throw new PythonException();
@@ -135,7 +135,7 @@ public void Append(PyObject item)
///
public void Insert(int index, PyObject item)
{
- int r = Runtime.PyList_Insert(obj, index, item.obj);
+ int r = Runtime.PyList_Insert(this.Reference, index, item.obj);
if (r < 0)
{
throw new PythonException();
@@ -151,7 +151,7 @@ public void Insert(int index, PyObject item)
///
public void Reverse()
{
- int r = Runtime.PyList_Reverse(obj);
+ int r = Runtime.PyList_Reverse(this.Reference);
if (r < 0)
{
throw new PythonException();
@@ -167,7 +167,7 @@ public void Reverse()
///
public void Sort()
{
- int r = Runtime.PyList_Sort(obj);
+ int r = Runtime.PyList_Sort(this.Reference);
if (r < 0)
{
throw new PythonException();
diff --git a/src/runtime/pyobject.cs b/src/runtime/pyobject.cs
index 8ae99ecd0..37d53eeec 100644
--- a/src/runtime/pyobject.cs
+++ b/src/runtime/pyobject.cs
@@ -33,6 +33,8 @@ public class PyObject : DynamicObject, IEnumerable, IPyDisposable
private bool disposed = false;
private bool _finalized = false;
+ internal BorrowedReference Reference => new BorrowedReference(obj);
+
///
/// PyObject Constructor
///
@@ -52,9 +54,24 @@ public PyObject(IntPtr ptr)
#endif
}
+ ///
+ /// Creates new pointing to the same object as
+ /// the . Increments refcount, allowing
+ /// to have ownership over its own reference.
+ ///
+ internal PyObject(BorrowedReference reference)
+ {
+ if (reference.IsNull) throw new ArgumentNullException(nameof(reference));
+
+ obj = Runtime.SelfIncRef(reference.DangerousGetAddress());
+#if TRACE_ALLOC
+ Traceback = new StackTrace(1);
+#endif
+ }
+
// Protected default constructor to allow subclasses to manage
// initialization in different ways as appropriate.
- [Obsolete("Please, always use PyObject(IntPtr)")]
+ [Obsolete("Please, always use PyObject(*Reference)")]
protected PyObject()
{
#if TRACE_ALLOC
diff --git a/src/runtime/runtime.cs b/src/runtime/runtime.cs
index 9c9d674a6..bae3daa15 100644
--- a/src/runtime/runtime.cs
+++ b/src/runtime/runtime.cs
@@ -341,7 +341,7 @@ internal static void Initialize(bool initSigs = false)
string rtdir = RuntimeEnvironment.GetRuntimeDirectory();
IntPtr path = PySys_GetObject("path");
IntPtr item = PyString_FromString(rtdir);
- PyList_Append(path, item);
+ PyList_Append(new BorrowedReference(path), item);
XDecref(item);
AssemblyManager.UpdatePath();
}
@@ -1658,22 +1658,22 @@ internal static int PyList_SetItem(IntPtr pointer, long index, IntPtr value)
[DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
private static extern int PyList_SetItem(IntPtr pointer, IntPtr index, IntPtr value);
- internal static int PyList_Insert(IntPtr pointer, long index, IntPtr value)
+ internal static int PyList_Insert(BorrowedReference pointer, long index, IntPtr value)
{
return PyList_Insert(pointer, new IntPtr(index), value);
}
[DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
- private static extern int PyList_Insert(IntPtr pointer, IntPtr index, IntPtr value);
+ private static extern int PyList_Insert(BorrowedReference pointer, IntPtr index, IntPtr value);
[DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
- internal static extern int PyList_Append(IntPtr pointer, IntPtr value);
+ internal static extern int PyList_Append(BorrowedReference pointer, IntPtr value);
[DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
- internal static extern int PyList_Reverse(IntPtr pointer);
+ internal static extern int PyList_Reverse(BorrowedReference pointer);
[DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
- internal static extern int PyList_Sort(IntPtr pointer);
+ internal static extern int PyList_Sort(BorrowedReference pointer);
internal static IntPtr PyList_GetSlice(IntPtr pointer, long start, long end)
{