@@ -945,113 +945,105 @@ _xidregistry_fini(struct _xidregistry *registry)
945945/*************************/
946946
947947static const char *
948- _copy_raw_string ( const char * str , Py_ssize_t len )
948+ _copy_string_obj_raw ( PyObject * strobj , Py_ssize_t * p_size )
949949{
950- size_t size = len + 1 ;
951- if (len <= 0 ) {
952- size = strlen (str ) + 1 ;
953- }
954- char * copied = PyMem_RawMalloc (size );
955- if (copied == NULL ) {
956- return NULL ;
957- }
958- if (len <= 0 ) {
959- strcpy (copied , str );
960- }
961- else {
962- memcpy (copied , str , size );
963- }
964- return copied ;
965- }
966-
967- static const char *
968- _copy_string_obj_raw (PyObject * strobj )
969- {
970- const char * str = PyUnicode_AsUTF8 (strobj );
950+ Py_ssize_t size = -1 ;
951+ const char * str = PyUnicode_AsUTF8AndSize (strobj , & size );
971952 if (str == NULL ) {
972953 return NULL ;
973954 }
974955
975- char * copied = PyMem_RawMalloc (strlen ( str ) + 1 );
956+ char * copied = PyMem_RawMalloc (size + 1 );
976957 if (copied == NULL ) {
977958 PyErr_NoMemory ();
978959 return NULL ;
979960 }
980961 strcpy (copied , str );
962+ if (p_size != NULL ) {
963+ * p_size = size ;
964+ }
981965 return copied ;
982966}
983967
984968
985969static int
986- _pickle_object (PyObject * obj , const char * * p_pickled , Py_ssize_t * p_len )
970+ _convert_exc_to_TracebackException (PyObject * exc , PyObject * * p_tbexc )
987971{
988- assert (! PyErr_Occurred ()) ;
989- PyObject * picklemod = PyImport_ImportModule ( "_pickle" ) ;
990- if ( picklemod == NULL ) {
991- PyErr_Clear ();
992- picklemod = PyImport_ImportModule ( "pickle" );
993- if ( picklemod == NULL ) {
994- return -1 ;
995- }
972+ PyObject * args = NULL ;
973+ PyObject * kwargs = NULL ;
974+ PyObject * create = NULL ;
975+
976+ // This is inspired by _PyErr_Display().
977+ PyObject * tbmod = PyImport_ImportModule ( "traceback" );
978+ if ( tbmod == NULL ) {
979+ return -1 ;
996980 }
997- PyObject * dumps = PyObject_GetAttrString (picklemod , "dumps " );
998- Py_DECREF (picklemod );
999- if (dumps == NULL ) {
981+ PyObject * tbexc_type = PyObject_GetAttrString (tbmod , "TracebackException " );
982+ Py_DECREF (tbmod );
983+ if (tbexc_type == NULL ) {
1000984 return -1 ;
1001985 }
1002- PyObject * pickledobj = PyObject_CallOneArg ( dumps , obj );
1003- Py_DECREF (dumps );
1004- if (pickledobj == NULL ) {
986+ create = PyObject_GetAttrString ( tbexc_type , "from_exception" );
987+ Py_DECREF (tbexc_type );
988+ if (create == NULL ) {
1005989 return -1 ;
1006990 }
1007991
1008- char * pickled = NULL ;
1009- Py_ssize_t len = 0 ;
1010- if (PyBytes_AsStringAndSize (pickledobj , & pickled , & len ) < 0 ) {
1011- Py_DECREF (pickledobj );
1012- return -1 ;
992+ args = PyTuple_Pack (1 , exc );
993+ if (args == NULL ) {
994+ goto error ;
1013995 }
1014- const char * copied = _copy_raw_string (pickled , len );
1015- Py_DECREF (pickledobj );
1016- if (copied == NULL ) {
1017- return -1 ;
996+
997+ kwargs = PyDict_New ();
998+ if (kwargs == NULL ) {
999+ goto error ;
1000+ }
1001+ if (PyDict_SetItemString (kwargs , "save_exc_type" , Py_False ) < 0 ) {
1002+ goto error ;
1003+ }
1004+ if (PyDict_SetItemString (kwargs , "lookup_lines" , Py_False ) < 0 ) {
1005+ goto error ;
1006+ }
1007+
1008+ PyObject * tbexc = PyObject_Call (create , args , kwargs );
1009+ Py_DECREF (args );
1010+ Py_DECREF (kwargs );
1011+ Py_DECREF (create );
1012+ if (tbexc == NULL ) {
1013+ goto error ;
10181014 }
10191015
1020- * p_pickled = copied ;
1021- * p_len = len ;
1016+ * p_tbexc = tbexc ;
10221017 return 0 ;
1018+
1019+ error :
1020+ Py_XDECREF (args );
1021+ Py_XDECREF (kwargs );
1022+ Py_XDECREF (create );
1023+ return -1 ;
10231024}
10241025
1025- static int
1026- _unpickle_object (const char * pickled , Py_ssize_t size , PyObject * * p_obj )
1026+
1027+ static const char *
1028+ _format_TracebackException (PyObject * tbexc )
10271029{
1028- assert (!PyErr_Occurred ());
1029- PyObject * picklemod = PyImport_ImportModule ("_pickle" );
1030- if (picklemod == NULL ) {
1031- PyErr_Clear ();
1032- picklemod = PyImport_ImportModule ("pickle" );
1033- if (picklemod == NULL ) {
1034- return -1 ;
1035- }
1036- }
1037- PyObject * loads = PyObject_GetAttrString (picklemod , "loads" );
1038- Py_DECREF (picklemod );
1039- if (loads == NULL ) {
1040- return -1 ;
1041- }
1042- PyObject * pickledobj = PyBytes_FromStringAndSize (pickled , size );
1043- if (pickledobj == NULL ) {
1044- Py_DECREF (loads );
1045- return -1 ;
1030+ PyObject * lines = PyObject_CallMethod (tbexc , "format" , NULL );
1031+ if (lines == NULL ) {
1032+ return NULL ;
10461033 }
1047- PyObject * obj = PyObject_CallOneArg (loads , pickledobj );
1048- Py_DECREF (loads );
1049- Py_DECREF (pickledobj );
1050- if (obj == NULL ) {
1051- return -1 ;
1034+ PyObject * formatted_obj = PyUnicode_Join (& _Py_STR (empty ), lines );
1035+ Py_DECREF (lines );
1036+ if (formatted_obj == NULL ) {
1037+ return NULL ;
10521038 }
1053- * p_obj = obj ;
1054- return 0 ;
1039+
1040+ Py_ssize_t size = -1 ;
1041+ const char * formatted = _copy_string_obj_raw (formatted_obj , & size );
1042+ Py_DECREF (formatted_obj );
1043+ // We remove trailing the newline added by TracebackException.format().
1044+ assert (formatted [size - 1 ] == '\n' );
1045+ ((char * )formatted )[size - 1 ] = '\0' ;
1046+ return formatted ;
10551047}
10561048
10571049
@@ -1101,7 +1093,7 @@ _excinfo_init_type(struct _excinfo_type *info, PyObject *exc)
11011093 if (strobj == NULL ) {
11021094 return -1 ;
11031095 }
1104- info -> name = _copy_string_obj_raw (strobj );
1096+ info -> name = _copy_string_obj_raw (strobj , NULL );
11051097 Py_DECREF (strobj );
11061098 if (info -> name == NULL ) {
11071099 return -1 ;
@@ -1112,7 +1104,7 @@ _excinfo_init_type(struct _excinfo_type *info, PyObject *exc)
11121104 if (strobj == NULL ) {
11131105 return -1 ;
11141106 }
1115- info -> qualname = _copy_string_obj_raw (strobj );
1107+ info -> qualname = _copy_string_obj_raw (strobj , NULL );
11161108 Py_DECREF (strobj );
11171109 if (info -> name == NULL ) {
11181110 return -1 ;
@@ -1123,7 +1115,7 @@ _excinfo_init_type(struct _excinfo_type *info, PyObject *exc)
11231115 if (strobj == NULL ) {
11241116 return -1 ;
11251117 }
1126- info -> module = _copy_string_obj_raw (strobj );
1118+ info -> module = _copy_string_obj_raw (strobj , NULL );
11271119 Py_DECREF (strobj );
11281120 if (info -> name == NULL ) {
11291121 return -1 ;
@@ -1188,8 +1180,8 @@ _PyXI_excinfo_Clear(_PyXI_excinfo *info)
11881180 if (info -> msg != NULL ) {
11891181 PyMem_RawFree ((void * )info -> msg );
11901182 }
1191- if (info -> pickled != NULL ) {
1192- PyMem_RawFree ((void * )info -> pickled );
1183+ if (info -> errdisplay != NULL ) {
1184+ PyMem_RawFree ((void * )info -> errdisplay );
11931185 }
11941186 * info = (_PyXI_excinfo ){{NULL }};
11951187}
@@ -1226,63 +1218,6 @@ _PyXI_excinfo_format(_PyXI_excinfo *info)
12261218 }
12271219}
12281220
1229- static int
1230- _convert_exc_to_TracebackException (PyObject * exc , PyObject * * p_tbexc )
1231- {
1232- PyObject * args = NULL ;
1233- PyObject * kwargs = NULL ;
1234- PyObject * create = NULL ;
1235-
1236- // This is inspired by _PyErr_Display().
1237- PyObject * tbmod = PyImport_ImportModule ("traceback" );
1238- if (tbmod == NULL ) {
1239- return -1 ;
1240- }
1241- PyObject * tbexc_type = PyObject_GetAttrString (tbmod , "TracebackException" );
1242- Py_DECREF (tbmod );
1243- if (tbexc_type == NULL ) {
1244- return -1 ;
1245- }
1246- create = PyObject_GetAttrString (tbexc_type , "from_exception" );
1247- Py_DECREF (tbexc_type );
1248- if (create == NULL ) {
1249- return -1 ;
1250- }
1251-
1252- args = PyTuple_Pack (1 , exc );
1253- if (args == NULL ) {
1254- goto error ;
1255- }
1256-
1257- kwargs = PyDict_New ();
1258- if (kwargs == NULL ) {
1259- goto error ;
1260- }
1261- if (PyDict_SetItemString (kwargs , "save_exc_type" , Py_False ) < 0 ) {
1262- goto error ;
1263- }
1264- if (PyDict_SetItemString (kwargs , "lookup_lines" , Py_False ) < 0 ) {
1265- goto error ;
1266- }
1267-
1268- PyObject * tbexc = PyObject_Call (create , args , kwargs );
1269- Py_DECREF (args );
1270- Py_DECREF (kwargs );
1271- Py_DECREF (create );
1272- if (tbexc == NULL ) {
1273- goto error ;
1274- }
1275-
1276- * p_tbexc = tbexc ;
1277- return 0 ;
1278-
1279- error :
1280- Py_XDECREF (args );
1281- Py_XDECREF (kwargs );
1282- Py_XDECREF (create );
1283- return -1 ;
1284- }
1285-
12861221static const char *
12871222_PyXI_excinfo_InitFromException (_PyXI_excinfo * info , PyObject * exc )
12881223{
@@ -1305,7 +1240,7 @@ _PyXI_excinfo_InitFromException(_PyXI_excinfo *info, PyObject *exc)
13051240 failure = "error while formatting exception" ;
13061241 goto error ;
13071242 }
1308- info -> msg = _copy_string_obj_raw (msgobj );
1243+ info -> msg = _copy_string_obj_raw (msgobj , NULL );
13091244 Py_DECREF (msgobj );
13101245 if (info -> msg == NULL ) {
13111246 failure = "error while copying exception message" ;
@@ -1321,13 +1256,14 @@ _PyXI_excinfo_InitFromException(_PyXI_excinfo *info, PyObject *exc)
13211256 PyErr_Clear ();
13221257 }
13231258 else {
1324- if (_pickle_object (tbexc , & info -> pickled , & info -> pickled_len ) < 0 ) {
1259+ info -> errdisplay = _format_TracebackException (tbexc );
1260+ Py_DECREF (tbexc );
1261+ if (info -> errdisplay == NULL ) {
13251262#ifdef Py_DEBUG
1326- PyErr_FormatUnraisable ("Exception ignored while pickling TracebackException" );
1263+ PyErr_FormatUnraisable ("Exception ignored while formating TracebackException" );
13271264#endif
13281265 PyErr_Clear ();
13291266 }
1330- Py_DECREF (tbexc );
13311267 }
13321268
13331269 return NULL ;
@@ -1342,8 +1278,9 @@ static void
13421278_PyXI_excinfo_Apply (_PyXI_excinfo * info , PyObject * exctype )
13431279{
13441280 PyObject * tbexc = NULL ;
1345- if (info -> pickled != NULL ) {
1346- if (_unpickle_object (info -> pickled , info -> pickled_len , & tbexc ) < 0 ) {
1281+ if (info -> errdisplay != NULL ) {
1282+ tbexc = PyUnicode_FromString (info -> errdisplay );
1283+ if (tbexc == NULL ) {
13471284 PyErr_Clear ();
13481285 }
13491286 }
@@ -1354,9 +1291,9 @@ _PyXI_excinfo_Apply(_PyXI_excinfo *info, PyObject *exctype)
13541291
13551292 if (tbexc != NULL ) {
13561293 PyObject * exc = PyErr_GetRaisedException ();
1357- if (PyObject_SetAttrString (exc , "_tbexc " , tbexc ) < 0 ) {
1294+ if (PyObject_SetAttrString (exc , "_errdisplay " , tbexc ) < 0 ) {
13581295#ifdef Py_DEBUG
1359- PyErr_FormatUnraisable ("Exception ignored when setting _tbexc " );
1296+ PyErr_FormatUnraisable ("Exception ignored when setting _errdisplay " );
13601297#endif
13611298 PyErr_Clear ();
13621299 }
@@ -1468,13 +1405,13 @@ _PyXI_excinfo_AsObject(_PyXI_excinfo *info)
14681405 goto error ;
14691406 }
14701407
1471- if (info -> pickled != NULL ) {
1472- PyObject * tbexc = NULL ;
1473- if (_unpickle_object ( info -> pickled , info -> pickled_len , & tbexc ) < 0 ) {
1408+ if (info -> errdisplay != NULL ) {
1409+ PyObject * tbexc = PyUnicode_FromString ( info -> errdisplay ) ;
1410+ if (tbexc == NULL ) {
14741411 PyErr_Clear ();
14751412 }
14761413 else {
1477- res = PyObject_SetAttrString (ns , "tbexc " , tbexc );
1414+ res = PyObject_SetAttrString (ns , "errdisplay " , tbexc );
14781415 Py_DECREF (tbexc );
14791416 if (res < 0 ) {
14801417 goto error ;
@@ -1646,7 +1583,7 @@ _sharednsitem_is_initialized(_PyXI_namespace_item *item)
16461583static int
16471584_sharednsitem_init (_PyXI_namespace_item * item , PyObject * key )
16481585{
1649- item -> name = _copy_string_obj_raw (key );
1586+ item -> name = _copy_string_obj_raw (key , NULL );
16501587 if (item -> name == NULL ) {
16511588 assert (!_sharednsitem_is_initialized (item ));
16521589 return -1 ;
0 commit comments