Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
This repository was archived by the owner on Jul 22, 2023. It is now read-only.
/pythonnetPublic archive
forked frompythonnet/pythonnet

Commita0d1a3d

Browse files
slidefilmor
andauthored
Call PyErr_NormalizeException for exceptions (pythonnet#1265)
* Call PyErr_NormalizeException for exceptionsSeehttps://docs.python.org/3/c-api/exceptions.html#c.PyErr_NormalizeExceptionThis fixes cases where some exceptions are "unnormalized" (seehttps://docs.python.org/3/c-api/exceptions.html#c.PyErr_NormalizeException). Calling PyErr_NormalizeException will normalize the exception so that any calls to the traceback module functions correctly.Fixespythonnet#1190Co-authored-by: Benedikt Reinartz <filmor@gmail.com>
1 parentd9e15a7 commita0d1a3d

File tree

4 files changed

+60
-8
lines changed

4 files changed

+60
-8
lines changed

‎CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ details about the cause of the failure
4040
- Indexers can now be used with interface objects
4141
- Fixed a bug where indexers could not be used if they were inherited
4242
- 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
4344
- Made it possible to call`ToString`,`GetHashCode`, and`GetType` on inteface objects
4445
- Fixed objects returned by enumerating`PyObject` being disposed too soon
4546
- Incorrectly using a non-generic type with type parameters now produces a helpful Python error instead of throwing NullReferenceException

‎src/embed_tests/TestPythonException.cs

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,54 @@ public void TestPythonExceptionFormatNoTraceback()
8686
}
8787
catch(PythonExceptionex)
8888
{
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
9090
Assert.AreEqual(ex.StackTrace,ex.Format());
9191
}
9292
}
93+
94+
[Test]
95+
publicvoidTestPythonExceptionFormatNormalized()
96+
{
97+
try
98+
{
99+
PythonEngine.Exec("a=b\n");
100+
}
101+
catch(PythonExceptionex)
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+
publicvoidTestPythonException_PyErr_NormalizeException()
109+
{
110+
using(varscope=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",outPyObjecttype));
118+
119+
PyObjectstr="dummy string".ToPython();
120+
IntPtrtypePtr=type.Handle;
121+
IntPtrstrPtr=str.Handle;
122+
IntPtrtbPtr=Runtime.Runtime.None.Handle;
123+
Runtime.Runtime.XIncref(typePtr);
124+
Runtime.Runtime.XIncref(strPtr);
125+
Runtime.Runtime.XIncref(tbPtr);
126+
Runtime.Runtime.PyErr_NormalizeException(reftypePtr,refstrPtr,reftbPtr);
127+
128+
using(PyObjecttypeObj=newPyObject(typePtr),strObj=newPyObject(strPtr),tbObj=newPyObject(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+
}
93138
}
94139
}

‎src/runtime/pythonexception.cs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -160,12 +160,18 @@ public string Format()
160160
{
161161
if(_pyTB!=IntPtr.Zero&&_pyType!=IntPtr.Zero&&_pyValue!=IntPtr.Zero)
162162
{
163-
Runtime.XIncref(_pyType);
164-
Runtime.XIncref(_pyValue);
165-
Runtime.XIncref(_pyTB);
166-
using(PyObjectpyType=newPyObject(_pyType))
167-
using(PyObjectpyValue=newPyObject(_pyValue))
168-
using(PyObjectpyTB=newPyObject(_pyTB))
163+
IntPtrtb=_pyTB;
164+
IntPtrtype=_pyType;
165+
IntPtrvalue=_pyValue;
166+
167+
Runtime.XIncref(type);
168+
Runtime.XIncref(value);
169+
Runtime.XIncref(tb);
170+
Runtime.PyErr_NormalizeException(reftype,refvalue,reftb);
171+
172+
using(PyObjectpyType=newPyObject(type))
173+
using(PyObjectpyValue=newPyObject(value))
174+
using(PyObjectpyTB=newPyObject(tb))
169175
using(PyObjecttb_mod=PythonEngine.ImportModule("traceback"))
170176
{
171177
varbuffer=newStringBuilder();

‎src/runtime/runtime.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2035,7 +2035,7 @@ internal static IntPtr PyMem_Realloc(IntPtr ptr, long size)
20352035
internalstaticexternint PyErr_GivenExceptionMatches(IntPtr ob, IntPtr val);
20362036

20372037
[DllImport(_PythonDll, CallingConvention= CallingConvention.Cdecl)]
2038-
internalstaticexternvoid PyErr_NormalizeException(IntPtr ob, IntPtr val, IntPtr tb);
2038+
internalstaticexternvoid PyErr_NormalizeException(refIntPtr ob,refIntPtr val,ref IntPtr tb);
20392039

20402040
[DllImport(_PythonDll, CallingConvention= CallingConvention.Cdecl)]
20412041
internalstaticextern IntPtr PyErr_Occurred();

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp