8000 Enforce usage of reference types in a few more places · pythonnet/pythonnet@70c0200 · GitHub
[go: up one dir, main page]

Skip to content

Commit 70c0200

Browse files
committed
Enforce usage of reference types in a few more places
1 parent ad4d76b commit 70c0200

19 files changed

+171
-214
lines changed

src/runtime/BorrowedReference.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,14 @@ public BorrowedReference(IntPtr pointer)
3838
=> reference.IsNull;
3939
public static bool operator !=(NullOnly @null, BorrowedReference reference)
4040
=> !reference.IsNull;
41+
public static bool operator ==(BorrowedReference reference, IntPtr pointer)
42+
=> reference.pointer == pointer;
43+
public static bool operator !=(BorrowedReference reference, IntPtr pointer)
44+
=> reference.pointer != pointer;
45+
public static bool operator ==(IntPtr pointer, BorrowedReference reference)
46+
=> reference.pointer == pointer;
47+
public static bool operator !=(IntPtr pointer, BorrowedReference reference)
48+
=> reference.pointer != pointer;
4149

4250
public override bool Equals(object obj) {
4351
if (obj is IntPtr ptr)

src/runtime/CollectionWrappers/IterableWrapper.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ public IEnumerator<T> GetEnumerator()
3131
{
3232
using (Py.GIL())
3333
{
34-
var item = Runtime.PyIter_Next(iterObject.Handle);
35-
if (item == IntPtr.Zero)
34+
var item = Runtime.PyIter_Next(iterObject.Reference);
35+
if (item.IsNull())
3636
{
3737
Runtime.CheckExceptionOccurred();
3838
iterObject.Dispose();

src/runtime/arrayobject.cs

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,15 @@ internal override bool CanSubclass()
2222
return false;
2323
}
2424

25-
public static IntPtr tp_new(IntPtr tpRaw, IntPtr args, IntPtr kw)
25+
public static IntPtr tp_new(IntPtr tpRaw, IntPtr argsRaw, IntPtr kw)
2626
{
2727
if (kw != IntPtr.Zero)
2828
{
2929
return Exceptions.RaiseTypeError("array constructor takes no keyword arguments");
3030
}
3131

3232
var tp = new BorrowedReference(tpRaw);
33+
var args = new BorrowedReference(argsRaw);
3334

3435
var self = GetManagedObject(tp) as ArrayObject;
3536
if (!self.type.Valid)
@@ -38,20 +39,20 @@ public static IntPtr tp_new(IntPtr tpRaw, IntPtr args, IntPtr kw)
3839
}
3940
Type arrType = self.type.Value;
4041

41-
long[] dimensions = new long[Runtime.PyTuple_Size(args)];
42+
var dimensions = new long[Runtime.PyTuple_Size(args)];
4243
if (dimensions.Length == 0)
4344
{
4445
return Exceptions.RaiseTypeError("array constructor requires at least one integer argument or an object convertible to array");
4546
}
4647
if (dimensions.Length != 1)
4748
{
4849
return CreateMultidimensional(arrType.GetElementType(), dimensions,
49-
shapeTuple: new BorrowedReference(args),
50+
shapeTuple: args,
5051
pyType: tp)
5152
.DangerousMoveToPointerOrNull();
5253
}
5354

54-
IntPtr op = Runtime.PyTuple_GetItem(args, 0);
55+
var op = Runtime.PyTuple_GetItem(args, 0);
5556

5657
// create single dimensional array
5758
if (Runtime.PyInt_Check(op))
@@ -136,8 +137,9 @@ static NewReference NewInstance(Type elementType, BorrowedReference arrayPyType,
136137
/// <summary>
137138
/// Implements __getitem__ for array types.
138139
/// </summary>
139-
public new static IntPtr mp_subscript(IntPtr ob, IntPtr idx)
140+
public new static IntPtr mp_subscript(IntPtr ob, IntPtr idxRaw)
140141
{
142+
var idx = new BorrowedReference(idxRaw);
141143
var obj = (CLRObject)GetManagedObject(ob);
142144
var arrObj = (ArrayObject)GetManagedObjectType(ob);
143145
if (!arrObj.type.Valid)
@@ -204,7 +206,7 @@ static NewReference NewInstance(Type elementType, BorrowedReference arrayPyType,
204206

205207
for (int dimension = 0; dimension < count; dimension++)
206208
{
207-
IntPtr op = Runtime.PyTuple_GetItem(idx, dimension);
209+
var op = Runtime.PyTuple_GetItem(idx, dimension);
208210
if (!Runtime.PyInt_Check(op))
209211
{
210212
return RaiseIndexMustBeIntegerError(op);
@@ -241,8 +243,9 @@ static NewReference NewInstance(Type elementType, BorrowedReference arrayPyType,
241243
/// <summary>
242244
/// Implements __setitem__ for array types.
243245
/// </summary>
244-
public static new int mp_ass_subscript(IntPtr ob, IntPtr idx, IntPtr v)
246+
public static new int mp_ass_subscript(IntPtr ob, IntPtr idxRaw, IntPtr v)
245247
{
248+
var idx = new BorrowedReference(idxRaw);
246249
var obj = (CLRObject)GetManagedObject(ob);
247250
var items = obj.inst as Array;
248251
Type itemType = obj.inst.GetType().GetElementType();
@@ -305,7 +308,7 @@ static NewReference NewInstance(Type elementType, BorrowedReference arrayPyType,
305308

306309
for (int dimension = 0; dimension < count; dimension++)
307310
{
308-
IntPtr op = Runtime.PyTuple_GetItem(idx, dimension);
311+
var op = Runtime.PyTuple_GetItem(idx, dimension);
309312
if (!Runtime.PyInt_Check(op))
310313
{
311314
RaiseIndexMustBeIntegerError(op);
@@ -340,7 +343,7 @@ static NewReference NewInstance(Type elementType, BorrowedReference arrayPyType,
340343
return 0;
341344
}
342345

343-
private static IntPtr RaiseIndexMustBeIntegerError(IntPtr idx)
346+
private static IntPtr RaiseIndexMustBeIntegerError(BorrowedReference idx)
344347
{
345348
string tpName = Runtime.PyObject_GetTypeName(idx);
346349
return Exceptions.RaiseTypeError($"array index has type {tpName}, expected an integer");

src/runtime/classderived.cs

Lines changed: 18 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -655,20 +655,15 @@ public static T InvokeMethod<T>(IPythonDerivedType obj, string methodName, strin
655655
IntPtr gs = Runtime.PyGILState_Ensure();
656656
try
657657
{
658-
Runtime.XIncref(self.pyHandle);
659-
var pyself = new PyObject(self.pyHandle);
658+
var pyself = new PyObject(self.ObjectReference);
660659
disposeList.Add(pyself);
661660

662-
Runtime.XIncref(Runtime.PyNone);
663-
var pynone = new PyObject(Runtime.PyNone);
664-
disposeList.Add(pynone);
661+
if (pyself.HasAttr(methodName)) {
662+
PyObject method = pyself.GetAttr(methodName);
663+
disposeList.Add(method);
665664

666-
PyObject method = pyself.GetAttr(methodName, pynone);
667-
disposeList.Add(method);
668-
if (method.Handle != Runtime.PyNone)
669-
{
670665
// if the method hasn't been overridden then it will be a managed object
671-
ManagedType managedMethod = ManagedType.GetManagedObject(method.Handle);
666+
ManagedType managedMethod = ManagedType.GetManagedObject(method.Reference);
672667
if (null == managedMethod)
673668
{
674669
var pyargs = new PyObject[args.Length];
@@ -717,20 +712,15 @@ public static void InvokeMethodVoid(IPythonDerivedType obj, string methodName, s
717712
IntPtr gs = Runtime.PyGILState_Ensure();
718713
try
719714
{
720-
Runtime.XIncref(self.pyHandle);
721-
var pyself = new PyObject(self.pyHandle);
715+
var pyself = new PyObject(self.ObjectReference);
722716
disposeList.Add(pyself);
723717

724-
Runtime.XIncref(Runtime.PyNone);
725-
var pynone = new PyObject(Runtime.PyNone);
726-
disposeList.Add(pynone);
718+
if (pyself.HasAttr(methodName)) {
719+
PyObject method = pyself.GetAttr(methodName);
720+
disposeList.Add(method);
727721

728-
PyObject method = pyself.GetAttr(methodName, pynone);
729-
disposeList.Add(method);
730-
if (method.Handle != Runtime.PyNone)
731-
{
732722
// if the method hasn't been overridden then it will be a managed object
733-
ManagedType managedMethod = ManagedType.GetManagedObject(method.Handle);
723+
ManagedType managedMethod = ManagedType.GetManagedObject(method.Reference);
734724
if (null == managedMethod)
735725
{
736726
var pyargs = new PyObject[args.Length];
@@ -781,12 +771,10 @@ public static T InvokeGetProperty<T>(IPythonDerivedType obj, string propertyName
781771
IntPtr gs = Runtime.PyGILState_Ensure();
782772
try
783773
{
784-
Runtime.XIncref(self.pyHandle);
785-
using (var pyself = new PyObject(self.pyHandle))
786-
using (PyObject pyvalue = pyself.GetAttr(propertyName))
787-
{
788-
return (T)pyvalue.AsManagedObject(typeof(T));
789-
}
774+
using var pyself = new PyObject(self.ObjectReference);
775+
using var pyvalue = pyself.GetAttr(propertyName);
776+
777+
return (T)pyvalue.AsManagedObject(typeof(T));
790778
}
791779
finally
792780
{
@@ -807,12 +795,10 @@ public static void InvokeSetProperty<T>(IPythonDerivedType obj, string propertyN
807795
IntPtr gs = Runtime.PyGILState_Ensure();
808796
try
809797
{
810-
Runtime.XIncref(self.pyHandle);
811-
using (var pyself = new PyObject(self.pyHandle))
812-
using (var pyvalue = new PyObject(Converter.ToPythonImplicit(value)))
813-
{
814-
pyself.SetAttr(propertyName, pyvalue);
815-
}
798+
var pyself = new PyObject(self.ObjectReference);
799+
var pyvalue = new PyObject(Converter.ToPythonImplicit(value));
800+
801+
pyself.SetAttr(propertyName, pyvalue);
816802
}
817803
finally
818804
{

src/runtime/converter.cs

Lines changed: 17 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,7 @@ internal static bool ToManaged(IntPtr value, Type type,
298298
{
299299
type = type.GetElementType();
300300
}
301-
return Converter.ToManagedValue(value, type, out result, setError);
301+
return Converter.ToManagedValue(new BorrowedReference(value), type, out result, setError);
302302
}
303303
/// <summary>
304304
/// Return a managed object for the given Python object, taking funny
@@ -315,13 +315,9 @@ internal static bool ToManaged(BorrowedReference value, Type type,
315315

316316
internal static bool ToManagedValue(BorrowedReference value, Type obType,
317317
out object? result, bool setError)
318-
=> ToManagedValue(value.DangerousGetAddress(), obType, out result, setError);
319-
internal static bool ToManagedValue(IntPtr value, Type obType,
320-
out object? result, bool setError)
321318
{
322319
if (obType == typeof(PyObject))
323320
{
324-
Runtime.XIncref(value); // PyObject() assumes ownership
325321
result = new PyObject(value);
326322
return true;
327323
}
@@ -330,7 +326,7 @@ internal static bool ToManagedValue(IntPtr value, Type obType,
330326
&& !obType.IsAbstract
331327
&& obType.GetConstructor(new[] { typeof(PyObject) }) is { } ctor)
332328
{
333-
var untyped = new PyObject(new BorrowedReference(value));
329+
var untyped = new PyObject(value);
334330
result = ToPyObjectSubclass(ctor, untyped, setError);
335331
return result is not null;
336332
}
@@ -370,15 +366,15 @@ internal static bool ToManagedValue(IntPtr value, Type obType,
370366
throw new ArgumentException("We should never receive instances of other managed types");
371367
}
372368

373-
if (value == Runtime.PyNone && !obType.IsValueType)
369+
if (value.IsNone() && !obType.IsValueType)
374370
{
375371
result = null;
376372
return true;
377373
}
378374

379375
if (obType.IsGenericType && obType.GetGenericTypeDefinition() == typeof(Nullable<>))
380376
{
381-
if( value == Runtime.PyNone )
377+
if(value.IsNone())
382378
{
383379
result = null;
384380
return true;
@@ -421,15 +417,15 @@ internal static bool ToManagedValue(IntPtr value, Type obType,
421417
}
422418

423419
// give custom codecs a chance to take over conversion of ints and sequences
424-
IntPtr pyType = Runtime.PyObject_TYPE(value);
420+
var pyType = Runtime.PyObject_TYPE(value);
425421
if (PyObjectConversions.TryDecode(value, pyType, obType, out result))
426422
{
427423
return true;
428424
}
429425

430426
if (Runtime.PyInt_Check(value))
431427
{
432-
result = new PyInt(new BorrowedReference(value));
428+
result = new PyInt(value);
433429
return true;
434430
}
435431

@@ -438,7 +434,6 @@ internal static bool ToManagedValue(IntPtr value, Type obType,
438434
return ToArray(value, typeof(object[]), out result, setError);
439435
}
440436

441-
Runtime.XIncref(value); // PyObject() assumes ownership
442437
result = new PyObject(value);
443438
return true;
444439
}
@@ -492,7 +487,7 @@ internal static bool ToManagedValue(IntPtr value, Type obType,
492487

493488
if (DecodableByUser< 10000 span class=pl-kos>(obType))
494489
{
495-
IntPtr pyType = Runtime.PyObject_TYPE(value);
490+
var pyType = Runtime.PyObject_TYPE(value);
496491
if (PyObjectConversions.TryDecode(value, pyType, obType, out result))
497492
{
498493
return true;
@@ -583,12 +578,10 @@ internal static int ToInt32(BorrowedReference value)
583578
return checked((int)num);
584579
}
585580

586-
private static bool ToPrimitive(BorrowedReference value, Type obType, out object? result, bool setError)
587-
=> ToPrimitive(value.DangerousGetAddress(), obType, out result, setError);
588581
/// <summary>
589582
/// Convert a Python value to an instance of a primitive managed type.
590583
/// </summary>
591-
private static bool ToPrimitive(IntPtr value, Type obType, out object? result, bool setError)
584+
private static bool ToPrimitive(BorrowedReference value, Type obType, out object? result, bool setError)
592585
{
593586
result = null;
594587
if (obType.IsEnum)
@@ -649,7 +642,7 @@ private static bool ToPrimitive(IntPtr value, Type obType, out object? result, b
649642

650643
case TypeCode.Byte:
651644
{
652-
if (Runtime.PyObject_TypeCheck(value, Runtime.PyBytesType))
645+
if (Runtime.PyObject_TypeCheck(value, new BorrowedReference(Runtime.PyBytesType)))
653646
{
654647
if (Runtime.PyBytes_Size(value) == 1)
655648
{
@@ -675,7 +668,7 @@ private static bool ToPrimitive(IntPtr value, Type obType, out object? result, b
675668

676669
case TypeCode.SByte:
677670
{
678-
if (Runtime.PyObject_TypeCheck(value, Runtime.PyBytesType))
671+
if (Runtime.PyObject_TypeCheck(value, new BorrowedReference(Runtime.PyBytesType)))
679672
{
680673
if (Runtime.PyBytes_Size(value) == 1)
681674
{
@@ -701,7 +694,7 @@ private static bool ToPrimitive(IntPtr value, Type obType, out object? result, b
701694

702695
case TypeCode.Char:
703696
{
704-
if (Runtime.PyObject_TypeCheck(value, Runtime.PyBytesType))
697+
if (Runtime.PyObject_TypeCheck(value, new BorrowedReference(Runtime.PyBytesType)))
705698
{
706699
if (Runtime.PyBytes_Size(value) == 1)
707700
{
@@ -711,11 +704,11 @@ private static bool ToPrimitive(IntPtr value, Type obType, out object? result, b
711704
}
712705
goto type_error;
713706
}
714-
else if (Runtime.PyObject_TypeCheck(value, Runtime.PyUnicodeType))
707+
else if (Runtime.PyObject_TypeCheck(value, new BorrowedReference(Runtime.PyUnicodeType)))
715708
{
716709
if (Runtime.PyUnicode_GetSize(value) == 1)
717710
{
718-
op = Runtime.PyUnicode_AsUnicode(value);
711+
op = Runtime.PyUnicode_AsUnicode(value).DangerousMoveToPointer();
719712
Char[] buff = new Char[1];
720713
Marshal.Copy(op, buff, 0, 1);
721714
result = buff[0];
@@ -892,14 +885,13 @@ private static bool ToPrimitive(IntPtr value, Type obType, out object? result, b
892885
return false;
893886
}
894887

895-
private static void SetConversionError(IntPtr value, Type target) 741A
888+
private static void SetConversionError(BorrowedReference value, Type target)
896889
{
897890
// PyObject_Repr might clear the error
898891
Runtime.PyErr_Fetch(out var causeType, out var causeVal, out var causeTrace);
899892

900-
IntPtr ob = Runtime.PyObject_Repr(value);
893+
using var ob = Runtime.PyObject_Repr(value);
901894
string src = Runtime.GetManagedString(ob);
902-
Runtime.XDecref(ob);
903895

904896
Runtime.PyErr_Restore(causeType.StealNullable(), causeVal.StealNullable(), causeTrace.StealNullable());
905897
Exceptions.RaiseTypeError($"Cannot convert {src} to {target}");
@@ -911,12 +903,12 @@ private static void SetConversionError(IntPtr value, Type target)
911903
/// The Python value must support the Python iterator protocol or and the
912904
/// items in the sequence must be convertible to the target array type.
913905
/// </summary>
914-
private static bool ToArray(IntPtr value, Type obType, out object? result, bool setError)
906+
private static bool ToArray(BorrowedReference value, Type obType, out object? result, bool setError)
915907
{
916908
Type elementType = obType.GetElementType();
917909
result = null;
918910

919-
using var IterObject = Runtime.PyObject_GetIter(new BorrowedReference(value));
911+
using var IterObject = Runtime.PyObject_GetIter(value);
920912
if (IterObject.IsNull())
921913
{
922914
if (setError)

src/runtime/debughelper.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,8 @@ public static void Print(string msg, params IntPtr[] args)
2525
{
2626
Console.WriteLine("null arg to print");
2727
}
28-
IntPtr ob = Runtime.PyObject_Repr(t);
28+
using var ob = Runtime.PyObject_Repr(new BorrowedReference(t));
2929
result += Runtime.GetManagedString(ob);
30-
Runtime.XDecref(ob);
3130
result += " ";
3231
}
3332
Console.WriteLine(result);

src/runtime/finalizer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public class ErrorArgs : EventArgs
3333
[DefaultValue(true)]
3434
public bool Enable { get; set; } = true;
3535

36-
private ConcurrentQueue<IntPtr> _objQueue = new ConcurrentQueue<IntPtr>();
36+
private readonly ConcurrentQueue<IntPtr> _objQueue = new();
3737
private int _throttled;
3838

3939
#region FINALIZER_CHECK

0 commit comments

Comments
 (0)
0