@@ -3010,14 +3010,19 @@ static PyObject *
30103010import_copyreg (void )
30113011{
30123012 static PyObject * copyreg_str ;
3013+ static PyObject * mod_copyreg = NULL ;
30133014
30143015 if (!copyreg_str ) {
30153016 copyreg_str = PyUnicode_InternFromString ("copyreg" );
30163017 if (copyreg_str == NULL )
30173018 return NULL ;
30183019 }
3020+ if (!mod_copyreg ) {
3021+ mod_copyreg = PyImport_Import (copyreg_str );
3022+ }
30193023
3020- return PyImport_Import (copyreg_str );
3024+ Py_XINCREF (mod_copyreg );
3025+ return mod_copyreg ;
30213026}
30223027
30233028static PyObject *
@@ -3026,14 +3031,16 @@ slotnames(PyObject *cls)
30263031 PyObject * clsdict ;
30273032 PyObject * copyreg ;
30283033 PyObject * slotnames ;
3034+ static PyObject * str_slotnames ;
30293035
3030- if (!PyType_Check (cls )) {
3031- Py_INCREF (Py_None );
3032- return Py_None ;
3036+ if (str_slotnames == NULL ) {
3037+ str_slotnames = PyUnicode_InternFromString ("__slotnames__" );
3038+ if (str_slotnames == NULL )
3039+ return NULL ;
30333040 }
30343041
30353042 clsdict = ((PyTypeObject * )cls )-> tp_dict ;
3036- slotnames = PyDict_GetItemString (clsdict , "__slotnames__" );
3043+ slotnames = PyDict_GetItem (clsdict , str_slotnames );
30373044 if (slotnames != NULL && PyList_Check (slotnames )) {
30383045 Py_INCREF (slotnames );
30393046 return slotnames ;
@@ -3067,12 +3074,20 @@ reduce_2(PyObject *obj)
30673074 PyObject * slots = NULL , * listitems = NULL , * dictitems = NULL ;
30683075 PyObject * copyreg = NULL , * newobj = NULL , * res = NULL ;
30693076 Py_ssize_t i , n ;
3077+ static PyObject * str_getnewargs = NULL , * str_getstate = NULL ,
3078+ * str_newobj = NULL ;
3079+
3080+ if (str_getnewargs == NULL ) {
3081+ str_getnewargs = PyUnicode_InternFromString ("__getnewargs__" );
3082+ str_getstate = PyUnicode_InternFromString ("__getstate__" );
3083+ str_newobj = PyUnicode_InternFromString ("__newobj__" );
3084+ if (!str_getnewargs || !str_getstate || !str_newobj )
3085+ return NULL ;
3086+ }
30703087
3071- cls = PyObject_GetAttrString (obj , "__class__" );
3072- if (cls == NULL )
3073- return NULL ;
3088+ cls = (PyObject * ) Py_TYPE (obj );
30743089
3075- getnewargs = PyObject_GetAttrString (obj , "__getnewargs__" );
3090+ getnewargs = PyObject_GetAttr (obj , str_getnewargs );
30763091 if (getnewargs != NULL ) {
30773092 args = PyObject_CallObject (getnewargs , NULL );
30783093 Py_DECREF (getnewargs );
@@ -3090,25 +3105,26 @@ reduce_2(PyObject *obj)
30903105 if (args == NULL )
30913106 goto end ;
30923107
3093- getstate = PyObject_GetAttrString (obj , "__getstate__" );
3108+ getstate = PyObject_GetAttr (obj , str_getstate );
30943109 if (getstate != NULL ) {
30953110 state = PyObject_CallObject (getstate , NULL );
30963111 Py_DECREF (getstate );
30973112 if (state == NULL )
30983113 goto end ;
30993114 }
31003115 else {
3116+ PyObject * * dict ;
31013117 PyErr_Clear ();
3102- state = PyObject_GetAttrString (obj , "__dict__" );
3103- if (state == NULL ) {
3104- PyErr_Clear ();
3118+ dict = _PyObject_GetDictPtr (obj );
3119+ if (dict && * dict )
3120+ state = * dict ;
3121+ else
31053122 state = Py_None ;
3106- Py_INCREF (state );
3107- }
3123+ Py_INCREF (state );
31083124 names = slotnames (cls );
31093125 if (names == NULL )
31103126 goto end ;
3111- if (names != Py_None ) {
3127+ if (names != Py_None && PyList_GET_SIZE ( names ) > 0 ) {
31123128 assert (PyList_Check (names ));
31133129 slots = PyDict_New ();
31143130 if (slots == NULL )
@@ -3167,16 +3183,16 @@ reduce_2(PyObject *obj)
31673183 copyreg = import_copyreg ();
31683184 if (copyreg == NULL )
31693185 goto end ;
3170- newobj = PyObject_GetAttrString (copyreg , "__newobj__" );
3186+ newobj = PyObject_GetAttr (copyreg , str_newobj );
31713187 if (newobj == NULL )
31723188 goto end ;
31733189
31743190 n = PyTuple_GET_SIZE (args );
31753191 args2 = PyTuple_New (n + 1 );
31763192 if (args2 == NULL )
31773193 goto end ;
3194+ Py_INCREF (cls );
31783195 PyTuple_SET_ITEM (args2 , 0 , cls );
3179- cls = NULL ;
31803196 for (i = 0 ; i < n ; i ++ ) {
31813197 PyObject * v = PyTuple_GET_ITEM (args , i );
31823198 Py_INCREF (v );
@@ -3186,7 +3202,6 @@ reduce_2(PyObject *obj)
31863202 res = PyTuple_Pack (5 , newobj , args2 , state , listitems , dictitems );
31873203
31883204 end :
3189- Py_XDECREF (cls );
31903205 Py_XDECREF (args );
31913206 Py_XDECREF (args2 );
31923207 Py_XDECREF (slots );
@@ -3246,31 +3261,34 @@ object_reduce(PyObject *self, PyObject *args)
32463261static PyObject *
32473262object_reduce_ex (PyObject * self , PyObject * args )
32483263{
3264+ static PyObject * str_reduce = NULL , * objreduce ;
32493265 PyObject * reduce , * res ;
32503266 int proto = 0 ;
32513267
32523268 if (!PyArg_ParseTuple (args , "|i:__reduce_ex__" , & proto ))
32533269 return NULL ;
32543270
3255- reduce = PyObject_GetAttrString (self , "__reduce__" );
3271+ if (str_reduce == NULL ) {
3272+ str_reduce = PyUnicode_InternFromString ("__reduce__" );
3273+ objreduce = PyDict_GetItemString (PyBaseObject_Type .tp_dict ,
3274+ "__reduce__" );
3275+ if (str_reduce == NULL || objreduce == NULL )
3276+ return NULL ;
3277+ }
3278+
3279+ reduce = PyObject_GetAttr (self , str_reduce );
32563280 if (reduce == NULL )
32573281 PyErr_Clear ();
32583282 else {
3259- PyObject * cls , * clsreduce , * objreduce ;
3283+ PyObject * cls , * clsreduce ;
32603284 int override ;
3261- cls = PyObject_GetAttrString (self , "__class__" );
3262- if (cls == NULL ) {
3263- Py_DECREF (reduce );
3264- return NULL ;
3265- }
3266- clsreduce = PyObject_GetAttrString (cls , "__reduce__" );
3267- Py_DECREF (cls );
3285+
3286+ cls = (PyObject * ) Py_TYPE (self );
3287+ clsreduce = PyObject_GetAttr (cls , str_reduce );
32683288 if (clsreduce == NULL ) {
32693289 Py_DECREF (reduce );
32703290 return NULL ;
32713291 }
3272- objreduce = PyDict_GetItemString (PyBaseObject_Type .tp_dict ,
3273- "__reduce__" );
32743292 override = (clsreduce != objreduce );
32753293 Py_DECREF (clsreduce );
32763294 if (override ) {
0 commit comments