Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
<PlatformTarget>AnyCPU</PlatformTarget>
<Prefer32Bit>false</Prefer32Bit>
<RunCodeAnalysis Condition="'$(Configuration)' == 'FxCop'">true</RunCodeAnalysis>
<LangVersion>latest</LangVersion>
</PropertyGroup>

<!-- Release -->
Expand Down
17 changes: 10 additions & 7 deletions Src/IronPython.Modules/_weakref.cs
Original file line number Diff line number Diff line change
Expand Up @@ -322,15 +322,15 @@ private weakproxy(CodeContext/*!*/ context, object target, object callback) {
/// <summary>
/// gets the object or throws a reference exception
/// </summary>
object GetObject() {
private object GetObject() {
object res;
if (!TryGetObject(out res)) {
throw PythonOps.ReferenceError("weakly referenced object no longer exists");
}
return res;
}

bool TryGetObject(out object result) {
private bool TryGetObject(out object result) {
result = _target.Target;
if (result == null) return false;
GC.KeepAlive(this);
Expand Down Expand Up @@ -754,7 +754,7 @@ public object __nonzero__() {
}
}

static class WeakRefHelpers {
private static class WeakRefHelpers {
public static WeakRefTracker InitializeWeakRef(PythonContext context, object self, object target, object callback) {
IWeakReferenceable iwr = ConvertToWeakReferenceable(context, target);

Expand All @@ -764,14 +764,17 @@ public static WeakRefTracker InitializeWeakRef(PythonContext context, object sel
throw PythonOps.TypeError("cannot create weak reference to '{0}' object", PythonOps.GetPythonTypeName(target));
}

wrt.ChainCallback(callback,self);
if (callback != null || !wrt.Contains(callback, self)) {
wrt.ChainCallback(callback, self);
}

return wrt;
}
}
}

[PythonType("wrapper_descriptor")]
class SlotWrapper : PythonTypeSlot, ICodeFormattable {
internal class SlotWrapper : PythonTypeSlot, ICodeFormattable {
private readonly string _name;
private readonly PythonType _type;

Expand Down Expand Up @@ -817,8 +820,8 @@ internal override bool TryGetValue(CodeContext context, object instance, PythonT

[PythonType("method-wrapper")]
public class GenericMethodWrapper {
string name;
IProxyObject target;
private readonly string name;
private readonly IProxyObject target;

public GenericMethodWrapper(string methodName, IProxyObject proxyTarget) {
name = methodName;
Expand Down
21 changes: 14 additions & 7 deletions Src/IronPython/Runtime/WeakRef.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,12 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Dynamic;
using System.Linq;
using System.Threading;

using Microsoft.Scripting.Actions;
using Microsoft.Scripting.Runtime;
using Microsoft.Scripting.Utils;

using IronPython.Runtime.Binding;
using IronPython.Runtime.Operations;

namespace IronPython.Runtime {
Expand All @@ -25,10 +23,10 @@ namespace IronPython.Runtime {
/// is held in objects that implement IWeakReferenceable.
/// </summary>
public class WeakRefTracker {
struct CallbackInfo {
readonly object _callback;
readonly WeakHandle _longRef;
readonly WeakHandle _shortRef;
private readonly struct CallbackInfo {
private readonly object _callback;
private readonly WeakHandle _longRef;
private readonly WeakHandle _shortRef;

public CallbackInfo(object callback, object weakRef) {
_callback = callback;
Expand Down Expand Up @@ -127,6 +125,15 @@ public void RemoveHandler(object o) {

}

internal bool Contains(object callback, object weakref) {
_lock.EnterReadLock();
try {
return _callbacks.Any(o => o.Callback == callback && o.WeakRef == weakref);
} finally {
_lock.ExitReadLock();
}
}

public object GetHandlerCallback(int index) {
_lock.EnterReadLock();
try {
Expand Down
8 changes: 8 additions & 0 deletions Tests/test_regressions.py
Original file line number Diff line number Diff line change
Expand Up @@ -1168,6 +1168,14 @@ def test_ipy2_gh25(self):
else:
self.assertTrue(hasattr(os, 'startfile'))

def test_ipy2_gh437(self):
"""https://github.com/IronLanguages/ironpython2/issues/437"""
import weakref
class SomeWeakReferenceableObject(object): pass

o = SomeWeakReferenceableObject()
x = [weakref.ref(o) for i in range(10)]
self.assertEqual(weakref.getweakrefcount(o), 1)


run_test(__name__)