@@ -82,6 +82,59 @@ static void TupleRoundtripGeneric<T, TTuple>() {
8282 Assert . AreEqual ( expected : tuple , actual : restored ) ;
8383 }
8484 }
85+
86+ const string TestExceptionMessage = "Hello World!" ;
87+ [ Test ]
88+ public void ExceptionEncoded ( ) {
89+ PyObjectConversions . RegisterEncoder ( new ValueErrorCodec ( ) ) ;
90+ void CallMe ( ) => throw new ValueErrorWrapper ( TestExceptionMessage ) ;
91+ var callMeAction = new Action ( CallMe ) ;
92+ using var _ = Py . GIL ( ) ;
93+ using var scope = Py . CreateScope ( ) ;
94+ scope . Exec ( @"
95+ def call(func):
96+ try:
97+ func()
98+ except ValueError as e:
99+ return str(e)
100+ " ) ;
101+ var callFunc = scope . Get ( "call" ) ;
102+ string message = callFunc . Invoke ( callMeAction . ToPython ( ) ) . As < string > ( ) ;
103+ Assert . AreEqual ( TestExceptionMessage , message ) ;
104+ }
105+
106+ [ Test ]
107+ public void ExceptionDecoded ( ) {
108+ PyObjectConversions . RegisterDecoder ( new ValueErrorCodec ( ) ) ;
109+ using var _ = Py . GIL ( ) ;
110+ using var scope = Py . CreateScope ( ) ;
111+ var error = Assert . Throws < ValueErrorWrapper > ( ( ) => PythonEngine . Exec (
112+ $ "raise ValueError('{ TestExceptionMessage } ')") ) ;
113+ Assert . AreEqual ( TestExceptionMessage , error . Message ) ;
114+ }
115+
116+ class ValueErrorWrapper : Exception {
117+ public ValueErrorWrapper ( string message ) : base ( message ) { }
118+ }
119+
120+ class ValueErrorCodec : IPyObjectEncoder , IPyObjectDecoder {
121+ public bool CanDecode ( PyObject objectType , Type targetType )
122+ => this . CanEncode ( targetType ) && objectType . Equals ( PythonEngine . Eval ( "ValueError" ) ) ;
123+
124+ public bool CanEncode ( Type type ) => type == typeof ( ValueErrorWrapper )
125+ || typeof ( ValueErrorWrapper ) . IsSubclassOf ( type ) ;
126+
127+ public bool TryDecode < T > ( PyObject pyObj , out T value ) {
128+ var message = pyObj . GetAttr ( "args" ) [ 0 ] . As < string > ( ) ;
129+ value = ( T ) ( object ) new ValueErrorWrapper ( message ) ;
130+ return true ;
131+ }
132+
133+ public PyObject TryEncode ( object value ) {
134+ var error = ( ValueErrorWrapper ) value ;
135+ return PythonEngine . Eval ( "ValueError" ) . Invoke ( error . Message . ToPython ( ) ) ;
136+ }
137+ }
85138 }
86139
87140 /// <summary>
0 commit comments