@@ -851,6 +851,57 @@ static PyMappingMethods odict_as_mapping = {
851
851
};
852
852
853
853
854
+ /* ----------------------------------------------
855
+ * OrderedDict number methods
856
+ */
857
+
858
+ static int mutablemapping_update_arg (PyObject * , PyObject * );
859
+
860
+ static PyObject *
861
+ odict_or (PyObject * left , PyObject * right )
862
+ {
863
+ PyTypeObject * type ;
864
+ PyObject * other ;
865
+ if (PyODict_Check (left )) {
866
+ type = Py_TYPE (left );
867
+ other = right ;
868
+ }
869
+ else {
870
+ type = Py_TYPE (right );
871
+ other = left ;
872
+ }
873
+ if (!PyDict_Check (other )) {
874
+ Py_RETURN_NOTIMPLEMENTED ;
875
+ }
876
+ PyObject * new = PyObject_CallOneArg ((PyObject * )type , left );
877
+ if (!new ) {
878
+ return NULL ;
879
+ }
880
+ if (mutablemapping_update_arg (new , right ) < 0 ) {
881
+ Py_DECREF (new );
882
+ return NULL ;
883
+ }
884
+ return new ;
885
+ }
886
+
887
+ static PyObject *
888
+ odict_inplace_or (PyObject * self , PyObject * other )
889
+ {
890
+ if (mutablemapping_update_arg (self , other ) < 0 ) {
891
+ return NULL ;
892
+ }
893
+ Py_INCREF (self );
894
+ return self ;
895
+ }
896
+
897
+ /* tp_as_number */
898
+
899
+ static PyNumberMethods odict_as_number = {
900
+ .nb_or = odict_or ,
901
+ .nb_inplace_or = odict_inplace_or ,
902
+ };
903
+
904
+
854
905
/* ----------------------------------------------
855
906
* OrderedDict methods
856
907
*/
@@ -1555,7 +1606,7 @@ PyTypeObject PyODict_Type = {
1555
1606
0 , /* tp_setattr */
1556
1607
0 , /* tp_as_async */
1557
1608
(reprfunc )odict_repr , /* tp_repr */
1558
- 0 , /* tp_as_number */
1609
+ & odict_as_number , /* tp_as_number */
1559
1610
0 , /* tp_as_sequence */
1560
1611
& odict_as_mapping , /* tp_as_mapping */
1561
1612
0 , /* tp_hash */
@@ -2189,100 +2240,94 @@ mutablemapping_add_pairs(PyObject *self, PyObject *pairs)
2189
2240
return 0 ;
2190
2241
}
2191
2242
2192
- static PyObject *
2193
- mutablemapping_update (PyObject * self , PyObject * args , PyObject * kwargs )
2243
+ static int
2244
+ mutablemapping_update_arg (PyObject * self , PyObject * arg )
2194
2245
{
2195
2246
int res = 0 ;
2196
- Py_ssize_t len ;
2247
+ if (PyDict_CheckExact (arg )) {
2248
+ PyObject * items = PyDict_Items (arg );
2249
+ if (items == NULL ) {
2250
+ return -1 ;
2251
+ }
2252
+ res = mutablemapping_add_pairs (self , items );
2253
+ Py_DECREF (items );
2254
+ return res ;
2255
+ }
2197
2256
_Py_IDENTIFIER (keys );
2257
+ PyObject * func ;
2258
+ if (_PyObject_LookupAttrId (arg , & PyId_keys , & func ) < 0 ) {
2259
+ return -1 ;
2260
+ }
2261
+ if (func != NULL ) {
2262
+ PyObject * keys = _PyObject_CallNoArg (func );
2263
+ Py_DECREF (func );
2264
+ if (keys == NULL ) {
2265
+ return -1 ;
2266
+ }
2267
+ PyObject * iterator = PyObject_GetIter (keys );
2268
+ Py_DECREF (keys );
2269
+ if (iterator == NULL ) {
2270
+ return -1 ;
2271
+ }
2272
+ PyObject * key ;
2273
+ while (res == 0 && (key = PyIter_Next (iterator ))) {
2274
+ PyObject * value = PyObject_GetItem (arg , key );
2275
+ if (value != NULL ) {
2276
+ res = PyObject_SetItem (self , key , value );
2277
+ Py_DECREF (value );
2278
+ }
2279
+ else {
2280
+ res = -1 ;
2281
+ }
2282
+ Py_DECREF (key );
2283
+ }
2284
+ Py_DECREF (iterator );
2285
+ if (res != 0 || PyErr_Occurred ()) {
2286
+ return -1 ;
2287
+ }
2288
+ return 0 ;
2289
+ }
2290
+ if (_PyObject_LookupAttrId (arg , & PyId_items , & func ) < 0 ) {
2291
+ return -1 ;
2292
+ }
2293
+ if (func != NULL ) {
2294
+ PyObject * items = _PyObject_CallNoArg (func );
2295
+ Py_DECREF (func );
2296
+ if (items == NULL ) {
2297
+ return -1 ;
2298
+ }
2299
+ res = mutablemapping_add_pairs (self , items );
2300
+ Py_DECREF (items );
2301
+ return res ;
2302
+ }
2303
+ res = mutablemapping_add_pairs (self , arg );
2304
+ return res ;
2305
+ }
2198
2306
2307
+ static PyObject *
2308
+ mutablemapping_update (PyObject * self , PyObject * args , PyObject * kwargs )
2309
+ {
2310
+ int res ;
2199
2311
/* first handle args, if any */
2200
2312
assert (args == NULL || PyTuple_Check (args ));
2201
- len = (args != NULL ) ? PyTuple_GET_SIZE (args ) : 0 ;
2313
+ Py_ssize_t len = (args != NULL ) ? PyTuple_GET_SIZE (args ) : 0 ;
2202
2314
if (len > 1 ) {
2203
2315
const char * msg = "update() takes at most 1 positional argument (%zd given)" ;
2204
2316
PyErr_Format (PyExc_TypeError , msg , len );
2205
2317
return NULL ;
2206
2318
}
2207
2319
2208
2320
if (len ) {
2209
- PyObject * func ;
2210
2321
PyObject * other = PyTuple_GET_ITEM (args , 0 ); /* borrowed reference */
2211
2322
assert (other != NULL );
2212
2323
Py_INCREF (other );
2213
- if (PyDict_CheckExact (other )) {
2214
- PyObject * items = PyDict_Items (other );
2215
- Py_DECREF (other );
2216
- if (items == NULL )
2217
- return NULL ;
2218
- res = mutablemapping_add_pairs (self , items );
2219
- Py_DECREF (items );
2220
- if (res == -1 )
2221
- return NULL ;
2222
- goto handle_kwargs ;
2223
- }
2224
-
2225
- if (_PyObject_LookupAttrId (other , & PyId_keys , & func ) < 0 ) {
2226
- Py_DECREF (other );
2227
- return NULL ;
2228
- }
2229
- if (func != NULL ) {
2230
- PyObject * keys , * iterator , * key ;
2231
- keys = _PyObject_CallNoArg (func );
2232
- Py_DECREF (func );
2233
- if (keys == NULL ) {
2234
- Py_DECREF (other );
2235
- return NULL ;
2236
- }
2237
- iterator = PyObject_GetIter (keys );
2238
- Py_DECREF (keys );
2239
- if (iterator == NULL ) {
2240
- Py_DECREF (other );
2241
- return NULL ;
2242
- }
2243
- while (res == 0 && (key = PyIter_Next (iterator ))) {
2244
- PyObject * value = PyObject_GetItem (other , key );
2245
- if (value != NULL ) {
2246
- res = PyObject_SetItem (self , key , value );
2247
- Py_DECREF (value );
2248
- }
2249
- else {
2250
- res = -1 ;
2251
- }
2252
- Py_DECREF (key );
2253
- }
2254
- Py_DECREF (other );
2255
- Py_DECREF (iterator );
2256
- if (res != 0 || PyErr_Occurred ())
2257
- return NULL ;
2258
- goto handle_kwargs ;
2259
- }
2260
-
2261
- if (_PyObject_LookupAttrId (other , & PyId_items , & func ) < 0 ) {
2262
- Py_DECREF (other );
2263
- return NULL ;
2264
- }
2265
- if (func != NULL ) {
2266
- PyObject * items ;
2267
- Py_DECREF (other );
2268
- items = _PyObject_CallNoArg (func );
2269
- Py_DECREF (func );
2270
- if (items == NULL )
2271
- return NULL ;
2272
- res = mutablemapping_add_pairs (self , items );
2273
- Py_DECREF (items );
2274
- if (res == -1 )
2275
- return NULL ;
2276
- goto handle_kwargs ;
2277
- }
2278
-
2279
- res = mutablemapping_add_pairs (self , other );
2324
+ res = mutablemapping_update_arg (self , other );
2280
2325
Py_DECREF (other );
2281
- if (res != 0 )
2326
+ if (res < 0 ) {
2282
2327
return NULL ;
2328
+ }
2283
2329
}
2284
2330
2285
- handle_kwargs :
2286
2331
/* now handle kwargs */
2287
2332
assert (kwargs == NULL || PyDict_Check (kwargs ));
2288
2333
if (kwargs != NULL && PyDict_GET_SIZE (kwargs )) {
0 commit comments