Skip to content

Commit 11bebe4

Browse files
committed
Bugfix and improvements
- Handle the `PyType` reference in `OverloadMapper` and `MethodBinding` in the same way as the object reference - Unconditionally store the `PyType` of the object - Introduce `NewReference` helper function for the object and type passing - Fix the remaining missing reference count bump for the type (`MethodObject`) - As the count is now correct, `Dispose` the type as well
1 parent 7f8a247 commit 11bebe4

5 files changed

Lines changed: 24 additions & 18 deletions

File tree

src/runtime/PythonTypes/PyObject.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,12 @@ internal PyObject(in StolenReference reference)
9393
Finalizer.Instance.ThrottledCollect();
9494
}
9595

96+
/// <summary>
97+
/// Create a new PyObject instance of this object, bumping the reference
98+
/// count.
99+
/// </summary>
100+
public PyObject NewReference() => new(this);
101+
96102
// Ensure that encapsulated Python object is decref'ed appropriately
97103
// when the managed wrapper is garbage-collected.
98104
~PyObject()

src/runtime/PythonTypes/PyType.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,12 @@ internal PyType(in StolenReference reference, bool prevalidated = false) : base(
3535
throw new ArgumentException("object is not a type");
3636
}
3737

38+
/// <summary>
39+
/// Create a new PyType instance of this object, bumping the reference
40+
/// count.
41+
/// </summary>
42+
public new PyType NewReference() => new(this);
43+
3844
protected PyType(SerializationInfo info, StreamingContext context) : base(info, context) { }
3945

4046
internal new static PyType? FromNullableReference(BorrowedReference reference)

src/runtime/Types/MethodBinding.cs

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,12 @@ internal class MethodBinding : ExtensionType
1818
internal MaybeMethodInfo info;
1919
internal MethodObject m;
2020
internal PyObject? target;
21-
internal PyType? targetType;
21+
internal PyType targetType;
2222

23-
public MethodBinding(MethodObject m, PyObject? target, PyType? targetType = null)
23+
public MethodBinding(MethodObject m, PyObject? target, PyType targetType)
2424
{
2525
this.target = target;
26-
27-
this.targetType = targetType ?? target?.GetPythonType();
28-
26+
this.targetType = targetType;
2927
this.info = null;
3028
this.m = m;
3129
}
@@ -54,10 +52,7 @@ public static NewReference mp_subscript(BorrowedReference tp, BorrowedReference
5452
}
5553

5654
MethodObject overloaded = self.m.WithOverloads(overloads);
57-
var mb = new MethodBinding(
58-
overloaded,
59-
self.target is null ? null : new PyObject(self.target.Reference),
60-
self.targetType is null ? null : new PyType(self.targetType.Reference));
55+
var mb = new MethodBinding(overloaded, self.target?.NewReference(), self.targetType.NewReference());
6156
return mb.Alloc();
6257
}
6358

@@ -144,8 +139,7 @@ public static NewReference tp_getattro(BorrowedReference ob, BorrowedReference k
144139
// FIXME: deprecate __overloads__ soon...
145140
case "__overloads__":
146141
case "Overloads":
147-
var om = new OverloadMapper(self.m,
148-
self.target is null ? null : new PyObject(self.target.Reference));
142+
var om = new OverloadMapper(self.m, self.target?.NewReference(), self.targetType.NewReference());
149143
return om.Alloc();
150144
case "__signature__" when Runtime.InspectModule is not null:
151145
var sig = self.Signature;
@@ -253,7 +247,6 @@ public static NewReference tp_call(BorrowedReference ob, BorrowedReference args,
253247
}
254248
}
255249

256-
257250
/// <summary>
258251
/// MethodBinding __hash__ implementation.
259252
/// </summary>
@@ -289,6 +282,7 @@ public static NewReference tp_repr(BorrowedReference ob)
289282
protected override void OnClear()
290283
{
291284
target?.Dispose();
285+
targetType.Dispose();
292286
target = null;
293287
}
294288
}

src/runtime/Types/MethodObject.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ public static NewReference tp_descr_get(BorrowedReference ds, BorrowedReference
197197
&& self.type.Value.IsInstanceOfType(obj.inst))
198198
{
199199
var basecls = ReflectedClrType.GetOrCreate(self.type.Value);
200-
return new MethodBinding(self, new PyObject(ob), basecls).Alloc();
200+
return new MethodBinding(self, new PyObject(ob), basecls.NewReference()).Alloc();
201201
}
202202

203203
return new MethodBinding(self, target: new PyObject(ob), targetType: new PyType(tp)).Alloc();

src/runtime/Types/OverloadMapper.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,12 @@ internal class OverloadMapper : ExtensionType
1111
{
1212
private readonly MethodObject m;
1313
private PyObject? target;
14+
readonly PyType targetType;
1415

15-
public OverloadMapper(MethodObject m, PyObject? target)
16+
public OverloadMapper(MethodObject m, PyObject? target, PyType targetType)
1617
{
1718
this.target = target;
19+
this.targetType = targetType;
1820
this.m = m;
1921
}
2022

@@ -42,10 +44,7 @@ public static NewReference mp_subscript(BorrowedReference tp, BorrowedReference
4244
return Exceptions.RaiseTypeError(e);
4345
}
4446

45-
var mb = new MethodBinding(
46-
self.m,
47-
self.target is null ? null : new PyObject(self.target.Reference))
48-
{ info = mi };
47+
var mb = new MethodBinding(self.m, self.target?.NewReference(), self.targetType.NewReference()) { info = mi };
4948
return mb.Alloc();
5049
}
5150

@@ -61,6 +60,7 @@ public static NewReference tp_repr(BorrowedReference op)
6160
protected override void OnClear()
6261
{
6362
target?.Dispose();
63+
targetType.Dispose();
6464
target = null;
6565
}
6666
}

0 commit comments

Comments
 (0)