| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent d9e15a7 commit a0d1a3d
4 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -40,6 +40,7 @@ details about the cause of the failure | |||
| 40 | 40 | - Indexers can now be used with interface objects | |
| 41 | 41 | - Fixed a bug where indexers could not be used if they were inherited | |
| 42 | 42 | - Made it possible to use `__len__` also on `ICollection<>` interface objects | |
| 43 | + - Fixed issue when calling PythonException.Format where another exception would be raise for unnormalized exceptions | ||
| 43 | 44 | - Made it possible to call `ToString`, `GetHashCode`, and `GetType` on inteface objects | |
| 44 | 45 | - Fixed objects returned by enumerating `PyObject` being disposed too soon | |
| 45 | 46 | - Incorrectly using a non-generic type with type parameters now produces a helpful Python error instead of throwing NullReferenceException | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -86,9 +86,54 @@ public void TestPythonExceptionFormatNoTraceback() | |||
| 86 | 86 | } | |
| 87 | 87 | catch (PythonException ex) | |
| 88 | 88 | { | |
| 89 | - // ImportError/ModuleNotFoundError do not have a traceback when not running in a script | ||
| 89 | + // ImportError/ModuleNotFoundError do not have a traceback when not running in a script | ||
| 90 | 90 | Assert.AreEqual(ex.StackTrace, ex.Format()); | |
| 91 | 91 | } | |
| 92 | 92 | } | |
| 93 | + | ||
| 94 | + [Test] | ||
| 95 | + public void TestPythonExceptionFormatNormalized() | ||
| 96 | + { | ||
| 97 | + try | ||
| 98 | + { | ||
| 99 | + PythonEngine.Exec("a=b\n"); | ||
| 100 | + } | ||
| 101 | + catch (PythonException ex) | ||
| 102 | + { | ||
| 103 | + Assert.AreEqual("Traceback (most recent call last):\n File \"<string>\", line 1, in <module>\nNameError: name 'b' is not defined\n", ex.Format()); | ||
| 104 | + } | ||
| 105 | + } | ||
| 106 | + | ||
| 107 | + [Test] | ||
| 108 | + public void TestPythonException_PyErr_NormalizeException() | ||
| 109 | + { | ||
| 110 | + using (var scope = Py.CreateScope()) | ||
| 111 | + { | ||
| 112 | + scope.Exec(@" | ||
| 113 | + class TestException(NameError): | ||
| 114 | + def __init__(self, val): | ||
| 115 | + super().__init__(val) | ||
| 116 | + x = int(val)"); | ||
| 117 | + Assert.IsTrue(scope.TryGet("TestException", out PyObject type)); | ||
| 118 | + | ||
| 119 | + PyObject str = "dummy string".ToPython(); | ||
| 120 | + IntPtr typePtr = type.Handle; | ||
| 121 | + IntPtr strPtr = str.Handle; | ||
| 122 | + IntPtr tbPtr = Runtime.Runtime.None.Handle; | ||
| 123 | + Runtime.Runtime.XIncref(typePtr); | ||
| 124 | + Runtime.Runtime.XIncref(strPtr); | ||
| 125 | + Runtime.Runtime.XIncref(tbPtr); | ||
| 126 | + Runtime.Runtime.PyErr_NormalizeException(ref typePtr, ref strPtr, ref tbPtr); | ||
| 127 | + | ||
| 128 | + using (PyObject typeObj = new PyObject(typePtr), strObj = new PyObject(strPtr), tbObj = new PyObject(tbPtr)) | ||
| 129 | + { | ||
| 130 | + // the type returned from PyErr_NormalizeException should not be the same type since a new | ||
| 131 | + // exception was raised by initializing the exception | ||
| 132 | + Assert.AreNotEqual(type.Handle, typePtr); | ||
| 133 | + // the message should now be the string from the throw exception during normalization | ||
| 134 | + Assert.AreEqual("invalid literal for int() with base 10: 'dummy string'", strObj.ToString()); | ||
| 135 | + } | ||
| 136 | + } | ||
| 137 | + } | ||
| 93 | 138 | } | |
| 94 | 139 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -160,12 +160,18 @@ public string Format() | |||
| 160 | 160 | { | |
| 161 | 161 | if (_pyTB != IntPtr.Zero && _pyType != IntPtr.Zero && _pyValue != IntPtr.Zero) | |
| 162 | 162 | { | |
| 163 | - Runtime.XIncref(_pyType); | ||
| 164 | - Runtime.XIncref(_pyValue); | ||
| 165 | - Runtime.XIncref(_pyTB); | ||
| 166 | - using (PyObject pyType = new PyObject(_pyType)) | ||
| 167 | - using (PyObject pyValue = new PyObject(_pyValue)) | ||
| 168 | - using (PyObject pyTB = new PyObject(_pyTB)) | ||
| 163 | + IntPtr tb = _pyTB; | ||
| 164 | + IntPtr type = _pyType; | ||
| 165 | + IntPtr value = _pyValue; | ||
| 166 | + | ||
| 167 | + Runtime.XIncref(type); | ||
| 168 | + Runtime.XIncref(value); | ||
| 169 | + Runtime.XIncref(tb); | ||
| 170 | + Runtime.PyErr_NormalizeException(ref type, ref value, ref tb); | ||
| 171 | + | ||
| 172 | + using (PyObject pyType = new PyObject(type)) | ||
| 173 | + using (PyObject pyValue = new PyObject(value)) | ||
| 174 | + using (PyObject pyTB = new PyObject(tb)) | ||
| 169 | 175 | using (PyObject tb_mod = PythonEngine.ImportModule("traceback")) | |
| 170 | 176 | { | |
| 171 | 177 | var buffer = new StringBuilder(); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -2035,7 +2035,7 @@ internal static IntPtr PyMem_Realloc(IntPtr ptr, long size) | |||
| 2035 | 2035 | internal static extern int PyErr_GivenExceptionMatches(IntPtr ob, IntPtr val); | |
| 2036 | 2036 | ||
| 2037 | 2037 | [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)] | |
| 2038 | - internal static extern void PyErr_NormalizeException(IntPtr ob, IntPtr val, IntPtr tb); | ||
| 2038 | + internal static extern void PyErr_NormalizeException(ref IntPtr ob, ref IntPtr val, ref IntPtr tb); | ||
| 2039 | 2039 | ||
| 2040 | 2040 | [DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)] | |
| 2041 | 2041 | internal static extern IntPtr PyErr_Occurred(); | |
| Back | FazBrowse Home | New Git URL |
0 commit comments