@@ -2320,6 +2320,25 @@ dict_fromkeys_impl(PyTypeObject *type, PyObject *iterable, PyObject *value)
23202320 return _PyDict_FromKeys ((PyObject * )type , iterable , value );
23212321}
23222322
2323+ /* Single-arg dict update; used by dict_update_common and operators. */
2324+ static int
2325+ dict_update_arg (PyObject * self , PyObject * arg )
2326+ {
2327+ if (PyDict_CheckExact (arg )) {
2328+ return PyDict_Merge (self , arg , 1 );
2329+ }
2330+ _Py_IDENTIFIER (keys );
2331+ PyObject * func ;
2332+ if (_PyObject_LookupAttrId (arg , & PyId_keys , & func ) < 0 ) {
2333+ return -1 ;
2334+ }
2335+ if (func != NULL ) {
2336+ Py_DECREF (func );
2337+ return PyDict_Merge (self , arg , 1 );
2338+ }
2339+ return PyDict_MergeFromSeq2 (self , arg , 1 );
2340+ }
2341+
23232342static int
23242343dict_update_common (PyObject * self , PyObject * args , PyObject * kwds ,
23252344 const char * methname )
@@ -2331,23 +2350,7 @@ dict_update_common(PyObject *self, PyObject *args, PyObject *kwds,
23312350 result = -1 ;
23322351 }
23332352 else if (arg != NULL ) {
2334- if (PyDict_CheckExact (arg )) {
2335- result = PyDict_Merge (self , arg , 1 );
2336- }
2337- else {
2338- _Py_IDENTIFIER (keys );
2339- PyObject * func ;
2340- if (_PyObject_LookupAttrId (arg , & PyId_keys , & func ) < 0 ) {
2341- result = -1 ;
2342- }
2343- else if (func != NULL ) {
2344- Py_DECREF (func );
2345- result = PyDict_Merge (self , arg , 1 );
2346- }
2347- else {
2348- result = PyDict_MergeFromSeq2 (self , arg , 1 );
2349- }
2350- }
2353+ result = dict_update_arg (self , arg );
23512354 }
23522355
23532356 if (result == 0 && kwds != NULL ) {
@@ -3169,6 +3172,33 @@ dict_sizeof(PyDictObject *mp, PyObject *Py_UNUSED(ignored))
31693172 return PyLong_FromSsize_t (_PyDict_SizeOf (mp ));
31703173}
31713174
3175+ static PyObject *
3176+ dict_or (PyObject * self , PyObject * other )
3177+ {
3178+ if (!PyDict_Check (self ) || !PyDict_Check (other )) {
3179+ Py_RETURN_NOTIMPLEMENTED ;
3180+ }
3181+ PyObject * new = PyDict_Copy (self );
3182+ if (new == NULL ) {
3183+ return NULL ;
3184+ }
3185+ if (dict_update_arg (new , other )) {
3186+ Py_DECREF (new );
3187+ return NULL ;
3188+ }
3189+ return new ;
3190+ }
3191+
3192+ static PyObject *
3193+ dict_ior (PyObject * self , PyObject * other )
3194+ {
3195+ if (dict_update_arg (self , other )) {
3196+ return NULL ;
3197+ }
3198+ Py_INCREF (self );
3199+ return self ;
3200+ }
3201+
31723202PyDoc_STRVAR (getitem__doc__ , "x.__getitem__(y) <==> x[y]" );
31733203
31743204PyDoc_STRVAR (sizeof__doc__ ,
@@ -3274,6 +3304,11 @@ static PySequenceMethods dict_as_sequence = {
32743304 0 , /* sq_inplace_repeat */
32753305};
32763306
3307+ static PyNumberMethods dict_as_number = {
3308+ .nb_or = dict_or ,
3309+ .nb_inplace_or = dict_ior ,
3310+ };
3311+
32773312static PyObject *
32783313dict_new (PyTypeObject * type , PyObject * args , PyObject * kwds )
32793314{
@@ -3335,7 +3370,7 @@ PyTypeObject PyDict_Type = {
33353370 0 , /* tp_setattr */
33363371 0 , /* tp_as_async */
33373372 (reprfunc )dict_repr , /* tp_repr */
3338- 0 , /* tp_as_number */
3373+ & dict_as_number , /* tp_as_number */
33393374 & dict_as_sequence , /* tp_as_sequence */
33403375 & dict_as_mapping , /* tp_as_mapping */
33413376 PyObject_HashNotImplemented , /* tp_hash */
0 commit comments