FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Implement writing the __cause__ attribute on exceptions by filmor · Pull Request #287 · pythonnet/pythonnet · GitHub

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

Filter by extension

Filter by extension .cs  (3) .py  (1) All 2 file types selected
Viewed files
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Unified
Split
Hide whitespace
Diff view
Unified
Split
Hide whitespace
7 changes: 4 additions & 3 deletions src/runtime/clrobject.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,9 @@ internal CLRObject(Object ob, IntPtr tp) : base()
this.gcHandle = gc;
inst = ob;

// Fix the BaseException args slot if wrapping a CLR exception
Exceptions.SetArgs(py);
// Fix the BaseException args (and __cause__ in case of Python 3)
// slot if wrapping a CLR exception
Exceptions.SetArgsAndCause(py);
}


Expand Down Expand Up @@ -70,4 +71,4 @@ internal static IntPtr GetInstHandle(Object ob)
return co.pyHandle;
}
}
}
}
12 changes: 10 additions & 2 deletions src/runtime/exceptions.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ internal static void Shutdown()
/// </summary>
/// <param name="e">A CLR exception</param>
/// <param name="ob">The python object wrapping </param>
internal static void SetArgs(IntPtr ob)
internal static void SetArgsAndCause(IntPtr ob)
{
var e = ExceptionClassObject.ToException(ob);
if (e == null)
Expand All @@ -163,6 +163,14 @@ internal static void SetArgs(IntPtr ob)
}

Marshal.WriteIntPtr(ob, ExceptionOffset.args, args);

#if !(PYTHON25 || PYTHON26 || PYTHON27)
if (e.InnerException != null)
{
IntPtr cause = CLRObject.GetInstHandle(e.InnerException);
Marshal.WriteIntPtr(ob, ExceptionOffset.cause, cause);
}
#endif
}

/// <summary>
Expand Down Expand Up @@ -434,4 +442,4 @@ puplic static variables on the Exceptions class filled in from
//PyAPI_DATA(PyObject *) PyExc_BytesWarning;
#endif
}
}
}
20 changes: 19 additions & 1 deletion src/testing/exceptiontest.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using System;


namespace Python.Test
{
//========================================================================
Expand Down Expand Up @@ -55,6 +54,25 @@ public static bool ThrowException()
{
throw new OverflowException("error");
}

public static void ThrowChainedExceptions()
{
try
{
try
{
throw new Exception("Innermost exception");
}
catch (Exception exc)
{
throw new Exception("Inner exception", exc);
}
}
catch (Exception exc2)
{
throw new Exception("Outer exception", exc2);
}
}
}


Expand Down
21 changes: 21 additions & 0 deletions src/tests/test_exceptions.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,27 @@ def testPicklingExceptions(self):

self.assertEqual(exc.args, loaded.args)

def testChainedExceptions(self):
if six.PY3:
from Python.Test import ExceptionTest

try:
ExceptionTest.ThrowChainedExceptions()
except Exception as exc:
msgs = [
"Outer exception",
"Inner exception",
"Innermost exception"
]

for msg in msgs:
self.assertEqual(exc.Message, msg)
self.assertEqual(exc.__cause__, exc.InnerException)
exc = exc.__cause__

else:
self.fail("Test should raise an exception")


def test_suite():
return unittest.makeSuite(ExceptionTests)
Expand Down

Back | FazBrowse Home | New Git URL