Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 43c56bb

Browse files
authored
Merge branch 'master' into minimal-initializeex
2 parents c986d5c + 5c9f035 commit 43c56bb

File tree

5 files changed

+76
-11
lines changed

5 files changed

+76
-11
lines changed

CHANGELOG.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ This document follows the conventions laid out in [Keep a CHANGELOG][].
88
## [unreleased][]
99

1010
### Added
11+
1112
- Added support for embedding python into dotnet core 2.0 (NetStandard 2.0)
1213
- Added new build system (pythonnet.15.sln) based on dotnetcore-sdk/xplat(crossplatform msbuild).
1314
Currently there two side-by-side build systems that produces the same output (net40) from the same sources.
@@ -26,6 +27,7 @@ This document follows the conventions laid out in [Keep a CHANGELOG][].
2627
### Changed
2728

2829
- PythonEngine.Intialize will now call `Py_InitializeEx` with a default value of 0, so signals will not be configured by default on embedding. This is different from the previous behaviour, where `Py_Initialize` was called instead, which sets initSigs to 1. ([#449][i449])
30+
- Reattach python exception traceback information (#545)
2931

3032
### Fixed
3133

@@ -46,6 +48,7 @@ This document follows the conventions laid out in [Keep a CHANGELOG][].
4648
- Fixed errors breaking .NET Remoting on method invoke ([#276][i276])
4749
- Fixed PyObject.GetHashCode ([#676][i676])
4850
- Fix memory leaks due to spurious handle incrementation ([#691][i691])
51+
- Fix spurious assembly loading exceptions from private types ([#703][i703])
4952
- Fix inheritance of non-abstract base methods ([#755][i755])
5053

5154

@@ -700,4 +703,4 @@ This document follows the conventions laid out in [Keep a CHANGELOG][].
700703
[p531]: https://github.com/pythonnet/pythonnet/pull/531
701704
[i755]: https://github.com/pythonnet/pythonnet/pull/755
702705
[p534]: https://github.com/pythonnet/pythonnet/pull/534
703-
[i499]: https://github.com/pythonnet/pythonnet/issues/499
706+
[i449]: https://github.com/pythonnet/pythonnet/issues/449

src/runtime/assemblymanager.cs

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.Collections.Generic;
55
using System.Diagnostics;
66
using System.IO;
7+
using System.Linq;
78
using System.Reflection;
89
using System.Threading;
910

@@ -348,9 +349,7 @@ internal static void ScanAssembly(Assembly assembly)
348349
// A couple of things we want to do here: first, we want to
349350
// gather a list of all of the namespaces contributed to by
350351
// the assembly.
351-
352-
Type[] types = assembly.GetTypes();
353-
foreach (Type t in types)
352+
foreach (Type t in GetTypes(assembly))
354353
{
355354
string ns = t.Namespace ?? "";
356355
if (!namespaces.ContainsKey(ns))
@@ -424,10 +423,9 @@ public static List<string> GetNames(string nsname)
424423
{
425424
foreach (Assembly a in namespaces[nsname].Keys)
426425
{
427-
Type[] types = a.GetTypes();
428-
foreach (Type t in types)
426+
foreach (Type t in GetTypes(a))
429427
{
430-
if ((t.Namespace ?? "") == nsname)
428+
if ((t.Namespace ?? "") == nsname && !t.IsNested)
431429
{
432430
names.Add(t.Name);
433431
}
@@ -466,5 +464,32 @@ public static Type LookupType(string qname)
466464
}
467465
return null;
468466
}
467+
468+
internal static Type[] GetTypes(Assembly a)
469+
{
470+
if (a.IsDynamic)
471+
{
472+
try
473+
{
474+
return a.GetTypes();
475+
}
476+
catch (ReflectionTypeLoadException exc)
477+
{
478+
// Return all types that were successfully loaded
479+
return exc.Types.Where(x => x != null).ToArray();
480+
}
481+
}
482+
else
483+
{
484+
try
485+
{
486+
return a.GetExportedTypes();
487+
}
488+
catch (FileNotFoundException)
489+
{
490+
return new Type[0];
491+
}
492+
}
493+
}
469494
}
470-
}
495+
}

src/runtime/converter.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Reflection;
66
using System.Runtime.InteropServices;
77
using System.Security;
8+
using System.ComponentModel;
89

910
namespace Python.Runtime
1011
{
@@ -134,8 +135,8 @@ internal static IntPtr ToPython(object value, Type type)
134135
return result;
135136
}
136137

137-
if (value is IList && value.GetType().IsGenericType)
138-
{
138+
if (value is IList && !(value is INotifyPropertyChanged) && value.GetType().IsGenericType)
139+
{
139140
using (var resultlist = new PyList())
140141
{
141142
foreach (object o in (IEnumerable)value)

src/runtime/exceptions.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,10 @@ public static void SetError(Exception e)
256256
var pe = e as PythonException;
257257
if (pe != null)
258258
{
259-
Runtime.PyErr_SetObject(pe.PyType, pe.PyValue);
259+
Runtime.XIncref(pe.PyType);
260+
Runtime.XIncref(pe.PyValue);
261+
Runtime.XIncref(pe.PyTB);
262+
Runtime.PyErr_Restore(pe.PyType, pe.PyValue, pe.PyTB);
260263
return;
261264
}
262265

src/tests/test_subclass.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,39 @@ def test_derived_class():
128128
assert id(x) == id(ob)
129129

130130

131+
def test_derived_traceback():
132+
"""Test python exception traceback in class derived from managed base"""
133+
class DerivedClass(SubClassTest):
134+
__namespace__ = "Python.Test.traceback"
135+
136+
def foo(self):
137+
print (xyzname)
138+
return None
139+
140+
import sys,traceback
141+
ob = DerivedClass()
142+
143+
# direct call
144+
try:
145+
ob.foo()
146+
assert False
147+
except:
148+
e = sys.exc_info()
149+
assert "xyzname" in str(e[1])
150+
location = traceback.extract_tb(e[2])[-1]
151+
assert location[2] == "foo"
152+
153+
# call through managed code
154+
try:
155+
FunctionsTest.test_foo(ob)
156+
assert False
157+
except:
158+
e = sys.exc_info()
159+
assert "xyzname" in str(e[1])
160+
location = traceback.extract_tb(e[2])[-1]
161+
assert location[2] == "foo"
162+
163+
131164
def test_create_instance():
132165
"""Test derived instances can be created from managed code"""
133166
DerivedClass = derived_class_fixture(test_create_instance.__name__)

0 commit comments

Comments
 (0)