Skip to content

Commit 1126819

Browse files
authored
Merge branch 'master' into master
2 parents 1f7ebd8 + f0f6b6b commit 1126819

File tree

8 files changed

+26
-104
lines changed

8 files changed

+26
-104
lines changed

AUTHORS.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
- Arvid JB ([@ArvidJB](https://github.com/ArvidJB))
1616
- Bradley Friedman ([@leith-bartrich](https://github.com/leith-bartrich))
17+
- Callum Noble ([@callumnoble](https://github.com/callumnoble))
1718
- Christian Heimes ([@tiran](https://github.com/tiran))
1819
- Christoph Gohlke ([@cgohlke](https://github.com/cgohlke))
1920
- Christopher Pow ([@christopherpow](https://github.com/christopherpow))
@@ -47,4 +48,5 @@
4748
- ([@rmadsen-ks](https://github.com/rmadsen-ks))
4849
- ([@stonebig](https://github.com/stonebig))
4950
- ([@testrunner123](https://github.com/testrunner123))
51+
- ([@GSPP](https://github.com/GSPP))
5052

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ This document follows the conventions laid out in [Keep a CHANGELOG][].
2929
- Fixed 'clrmethod' for python 2 (#492)
3030
- Fixed double calling of constructor when deriving from .NET class (#495)
3131
- Fixed `clr.GetClrType` when iterating over `System` members (#607)
32+
- Fixed `LockRecursionException` when loading assemblies (#627)
33+
- Fixed errors breaking .NET Remoting on method invoke (#276)
34+
- Fixed PyObject.GetHashCode (#676)
3235

3336

3437
## [2.3.0][] - 2017-03-11

appveyor.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ init:
4141
- set PATH=%PYTHON%;%PYTHON%\Scripts;%PATH%
4242

4343
install:
44+
- python -m pip install -U pip
4445
- pip install --upgrade -r requirements.txt --quiet
4546

4647
# Install OpenCover. Can't put on `packages.config`, not Mono compatible

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,6 @@ coverage
66
codecov
77

88
# Platform specific requirements
9-
pip; sys_platform == 'win32'
9+
# pip; sys_platform == 'win32'
1010
wheel; sys_platform == 'win32'
1111
pycparser; sys_platform != 'win32'

src/runtime/assemblymanager.cs

Lines changed: 4 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ internal class AssemblyManager
2626
private static Dictionary<string, int> probed;
2727

2828
// modified from event handlers below, potentially triggered from different .NET threads
29-
private static AssemblyList assemblies;
29+
private static ConcurrentQueue<Assembly> assemblies;
3030
internal static List<string> pypath;
3131

3232
private AssemblyManager()
@@ -43,7 +43,7 @@ internal static void Initialize()
4343
namespaces = new ConcurrentDictionary<string, ConcurrentDictionary<Assembly, string>>();
4444
probed = new Dictionary<string, int>(32);
4545
//generics = new Dictionary<string, Dictionary<string, string>>();
46-
assemblies = new AssemblyList(16);
46+
assemblies = new ConcurrentQueue<Assembly>();
4747
pypath = new List<string>(16);
4848

4949
AppDomain domain = AppDomain.CurrentDomain;
@@ -60,7 +60,7 @@ internal static void Initialize()
6060
try
6161
{
6262
ScanAssembly(a);
63-
assemblies.Add(a);
63+
assemblies.Enqueue(a);
6464
}
6565
catch (Exception ex)
6666
{
@@ -91,7 +91,7 @@ internal static void Shutdown()
9191
private static void AssemblyLoadHandler(object ob, AssemblyLoadEventArgs args)
9292
{
9393
Assembly assembly = args.LoadedAssembly;
94-
assemblies.Add(assembly);
94+
assemblies.Enqueue(assembly);
9595
ScanAssembly(assembly);
9696
}
9797

@@ -461,103 +461,5 @@ public static Type LookupType(string qname)
461461
}
462462
return null;
463463
}
464-
465-
/// <summary>
466-
/// Wrapper around List&lt;Assembly&gt; for thread safe access
467-
/// </summary>
468-
private class AssemblyList : IEnumerable<Assembly>
469-
{
470-
private readonly List<Assembly> _list;
471-
private readonly ReaderWriterLockSlim _lock;
472-
473-
public AssemblyList(int capacity)
474-
{
475-
_list = new List<Assembly>(capacity);
476-
_lock = new ReaderWriterLockSlim();
477-
}
478-
479-
public int Count
480-
{
481-
get
482-
{
483-
_lock.EnterReadLock();
484-
try
485-
{
486-
return _list.Count;
487-
}
488-
finally
489-
{
490-
_lock.ExitReadLock();
491-
}
492-
}
493-
}
494-
495-
public void Add(Assembly assembly)
496-
{
497-
_lock.EnterWriteLock();
498-
try
499-
{
500-
_list.Add(assembly);
501-
}
502-
finally
503-
{
504-
_lock.ExitWriteLock();
505-
}
506-
}
507-
508-
public IEnumerator GetEnumerator()
509-
{
510-
return ((IEnumerable<Assembly>)this).GetEnumerator();
511-
}
512-
513-
/// <summary>
514-
/// Enumerator wrapping around <see cref="AssemblyList._list" />'s enumerator.
515-
/// Acquires and releases a read lock on <see cref="AssemblyList._lock" /> during enumeration
516-
/// </summary>
517-
private class Enumerator : IEnumerator<Assembly>
518-
{
519-
private readonly AssemblyList _assemblyList;
520-
521-
private readonly IEnumerator<Assembly> _listEnumerator;
522-
523-
public Enumerator(AssemblyList assemblyList)
524-
{
525-
_assemblyList = assemblyList;
526-
_assemblyList._lock.EnterReadLock();
527-
_listEnumerator = _assemblyList._list.GetEnumerator();
528-
}
529-
530-
public void Dispose()
531-
{
532-
_listEnumerator.Dispose();
533-
_assemblyList._lock.ExitReadLock();
534-
}
535-
536-
public bool MoveNext()
537-
{
538-
return _listEnumerator.MoveNext();
539-
}
540-
541-
public void Reset()
542-
{
543-
_listEnumerator.Reset();
544-
}
545-
546-
public Assembly Current
547-
{
548-
get { return _listEnumerator.Current; }
549-
}
550-
551-
object IEnumerator.Current
552-
{
553-
get { return Current; }
554-
}
555-
}
556-
557-
IEnumerator<Assembly> IEnumerable<Assembly>.GetEnumerator()
558-
{
559-
return new Enumerator(this);
560-
}
561-
}
562464
}
563465
}

src/runtime/converter.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,15 @@ internal static IntPtr ToPython(object value, Type type)
155155
var pyderived = value as IPythonDerivedType;
156156
if (null != pyderived)
157157
{
158+
#if NETSTANDARD
158159
return ClassDerivedObject.ToPython(pyderived);
160+
#else
161+
// if object is remote don't do this
162+
if (!System.Runtime.Remoting.RemotingServices.IsTransparentProxy(pyderived))
163+
{
164+
return ClassDerivedObject.ToPython(pyderived);
165+
}
166+
#endif
159167
}
160168

161169
// hmm - from Python, we almost never care what the declared

src/runtime/pyobject.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -909,7 +909,7 @@ public override bool Equals(object o)
909909
/// </remarks>
910910
public override int GetHashCode()
911911
{
912-
return Runtime.PyObject_Hash(obj).ToInt32();
912+
return ((ulong)Runtime.PyObject_Hash(obj)).GetHashCode();
913913
}
914914

915915

src/tests/test_module.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,3 +387,9 @@ def test_assembly_load_thread_safety():
387387
from System.Collections.Generic import Dictionary
388388
_ = Dictionary[Guid, DateTime]()
389389
ModuleTest.JoinThreads()
390+
391+
def test_assembly_load_recursion_bug():
392+
"""Test fix for recursion bug documented in #627"""
393+
from System.Configuration import ConfigurationManager
394+
content = dir(ConfigurationManager)
395+
assert len(content) > 5, content

0 commit comments

Comments
 (0)