Skip to content

Commit 088580d

Browse files
authored
Merge pull request pythonnet#545 from testrunner123/patch-2
Add traceback information to exception
2 parents f807a81 + d80a8b9 commit 088580d

File tree

3 files changed

+40
-2
lines changed

3 files changed

+40
-2
lines changed

CHANGELOG.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ This document follows the conventions laid out in [Keep a CHANGELOG][].
2525

2626
### Changed
2727

28+
- Reattach python exception traceback information (#545)
29+
2830
### Fixed
2931

3032
- Fixed secondary PythonEngine.Initialize call, all sensitive static variables now reseted.
@@ -697,4 +699,4 @@ This document follows the conventions laid out in [Keep a CHANGELOG][].
697699
[i131]: https://github.com/pythonnet/pythonnet/issues/131
698700
[p531]: https://github.com/pythonnet/pythonnet/pull/531
699701
[i755]: https://github.com/pythonnet/pythonnet/pull/755
700-
[p534]: https://github.com/pythonnet/pythonnet/pull/534
702+
[p534]: https://github.com/pythonnet/pythonnet/pull/534

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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy