@@ -4162,17 +4162,34 @@ static PySequenceMethods dictkeys_as_sequence = {
41624162 (objobjproc )dictkeys_contains , /* sq_contains */
41634163};
41644164
4165+ // Create an set object from dictviews object.
4166+ // Returns a new reference.
4167+ // This utility function is used by set operations.
41654168static PyObject *
4166- dictviews_sub (PyObject * self , PyObject * other )
4169+ dictviews_to_set (PyObject * self )
41674170{
4168- PyObject * result = PySet_New (self );
4169- PyObject * tmp ;
4170- _Py_IDENTIFIER (difference_update );
4171+ PyObject * left = self ;
4172+ if (PyDictKeys_Check (self )) {
4173+ // PySet_New() has fast path for the dict object.
4174+ PyObject * dict = (PyObject * )((_PyDictViewObject * )self )-> dv_dict ;
4175+ if (PyDict_CheckExact (dict )) {
4176+ left = dict ;
4177+ }
4178+ }
4179+ return PySet_New (left );
4180+ }
41714181
4172- if (result == NULL )
4182+ static PyObject *
4183+ dictviews_sub (PyObject * self , PyObject * other )
4184+ {
4185+ PyObject * result = dictviews_to_set (self );
4186+ if (result == NULL ) {
41734187 return NULL ;
4188+ }
41744189
4175- tmp = _PyObject_CallMethodIdOneArg (result , & PyId_difference_update , other );
4190+ _Py_IDENTIFIER (difference_update );
4191+ PyObject * tmp = _PyObject_CallMethodIdOneArg (
4192+ result , & PyId_difference_update , other );
41764193 if (tmp == NULL ) {
41774194 Py_DECREF (result );
41784195 return NULL ;
@@ -4273,34 +4290,29 @@ _PyDictView_Intersect(PyObject* self, PyObject *other)
42734290static PyObject *
42744291dictviews_or (PyObject * self , PyObject * other )
42754292{
4276- PyObject * result = PySet_New (self );
4277- PyObject * tmp ;
4278- _Py_IDENTIFIER (update );
4279-
4280- if (result == NULL )
4293+ PyObject * result = dictviews_to_set (self );
4294+ if (result == NULL ) {
42814295 return NULL ;
4296+ }
42824297
4283- tmp = _PyObject_CallMethodIdOneArg (result , & PyId_update , other );
4284- if (tmp == NULL ) {
4298+ if (_PySet_Update (result , other ) < 0 ) {
42854299 Py_DECREF (result );
42864300 return NULL ;
42874301 }
4288-
4289- Py_DECREF (tmp );
42904302 return result ;
42914303}
42924304
42934305static PyObject *
42944306dictviews_xor (PyObject * self , PyObject * other )
42954307{
4296- PyObject * result = PySet_New (self );
4297- PyObject * tmp ;
4298- _Py_IDENTIFIER (symmetric_difference_update );
4299-
4300- if (result == NULL )
4308+ PyObject * result = dictviews_to_set (self );
4309+ if (result == NULL ) {
43014310 return NULL ;
4311+ }
43024312
4303- tmp = _PyObject_CallMethodIdOneArg (result , & PyId_symmetric_difference_update , other );
4313+ _Py_IDENTIFIER (symmetric_difference_update );
4314+ PyObject * tmp = _PyObject_CallMethodIdOneArg (
4315+ result , & PyId_symmetric_difference_update , other );
43044316 if (tmp == NULL ) {
43054317 Py_DECREF (result );
43064318 return NULL ;
0 commit comments