@@ -66,7 +66,7 @@ _multidict_getone(MultiDictObject *self, PyObject *key, PyObject *_default)
6666
6767static inline int
6868_multidict_extend (MultiDictObject * self , PyObject * arg , PyObject * kwds ,
69- const char * name , bool update )
69+ const char * name , UpdateOp op )
7070{
7171 mod_state * state = self -> state ;
7272 PyObject * seq = NULL ;
@@ -78,24 +78,24 @@ _multidict_extend(MultiDictObject *self, PyObject *arg, PyObject *kwds,
7878 if (arg != NULL ) {
7979 if (AnyMultiDict_Check (state , arg )) {
8080 MultiDictObject * other = (MultiDictObject * )arg ;
81- if (md_update_from_ht (self , other , update ) < 0 ) {
81+ if (md_update_from_ht (self , other , op ) < 0 ) {
8282 goto fail ;
8383 }
8484 } else if (AnyMultiDictProxy_Check (state , arg )) {
8585 MultiDictObject * other = ((MultiDictProxyObject * )arg )-> md ;
86- if (md_update_from_ht (self , other , update ) < 0 ) {
86+ if (md_update_from_ht (self , other , op ) < 0 ) {
8787 goto fail ;
8888 }
8989 } else if (PyDict_CheckExact (arg )) {
90- if (md_update_from_dict (self , arg , update ) < 0 ) {
90+ if (md_update_from_dict (self , arg , op ) < 0 ) {
9191 goto fail ;
9292 }
9393 } else if (PyList_CheckExact (arg )) {
94- if (md_update_from_seq (self , arg , update ) < 0 ) {
94+ if (md_update_from_seq (self , arg , op ) < 0 ) {
9595 goto fail ;
9696 }
9797 } else if (PyTuple_CheckExact (arg )) {
98- if (md_update_from_seq (self , arg , update ) < 0 ) {
98+ if (md_update_from_seq (self , arg , op ) < 0 ) {
9999 goto fail ;
100100 }
101101 } else {
@@ -105,19 +105,19 @@ _multidict_extend(MultiDictObject *self, PyObject *arg, PyObject *kwds,
105105 seq = Py_NewRef (arg );
106106 }
107107
108- if (md_update_from_seq (self , seq , update ) < 0 ) {
108+ if (md_update_from_seq (self , seq , op ) < 0 ) {
109109 goto fail ;
110110 }
111111 }
112112 }
113113
114114 if (kwds != NULL ) {
115- if (md_update_from_dict (self , kwds , update ) < 0 ) {
115+ if (md_update_from_dict (self , kwds , op ) < 0 ) {
116116 goto fail ;
117117 }
118118 }
119119
120- if (update ) {
120+ if (op != Extend ) { // Update or Merge
121121 if (md_post_update (self ) < 0 ) {
122122 goto fail ;
123123 }
@@ -551,7 +551,7 @@ multidict_tp_init(MultiDictObject *self, PyObject *args, PyObject *kwds)
551551 if (md_init (self , state , false, size ) < 0 ) {
552552 goto fail ;
553553 }
554- if (_multidict_extend (self , arg , kwds , "MultiDict" , false ) < 0 ) {
554+ if (_multidict_extend (self , arg , kwds , "MultiDict" , Extend ) < 0 ) {
555555 goto fail ;
556556 }
557557done :
@@ -592,7 +592,7 @@ multidict_extend(MultiDictObject *self, PyObject *args, PyObject *kwds)
592592 if (md_reserve (self , size ) < 0 ) {
593593 goto fail ;
594594 }
595- if (_multidict_extend (self , arg , kwds , "extend" , false ) < 0 ) {
595+ if (_multidict_extend (self , arg , kwds , "extend" , Extend ) < 0 ) {
596596 goto fail ;
597597 }
598598 Py_CLEAR (arg );
@@ -774,7 +774,30 @@ multidict_update(MultiDictObject *self, PyObject *args, PyObject *kwds)
774774 if (md_reserve (self , size ) < 0 ) {
775775 goto fail ;
776776 }
777- if (_multidict_extend (self , arg , kwds , "update" , true) < 0 ) {
777+ if (_multidict_extend (self , arg , kwds , "update" , Update ) < 0 ) {
778+ goto fail ;
779+ }
780+ Py_CLEAR (arg );
781+ ASSERT_CONSISTENT (self , false);
782+ Py_RETURN_NONE ;
783+ fail :
784+ Py_CLEAR (arg );
785+ return NULL ;
786+ }
787+
788+ static PyObject *
789+ multidict_merge (MultiDictObject * self , PyObject * args , PyObject * kwds )
790+ {
791+ PyObject * arg = NULL ;
792+ Py_ssize_t size =
793+ _multidict_extend_parse_args (self -> state , args , kwds , "merge" , & arg );
794+ if (size < 0 ) {
795+ goto fail ;
796+ }
797+ if (md_reserve (self , size ) < 0 ) {
798+ goto fail ;
799+ }
800+ if (_multidict_extend (self , arg , kwds , "merge" , Merge ) < 0 ) {
778801 goto fail ;
779802 }
780803 Py_CLEAR (arg );
@@ -824,6 +847,9 @@ PyDoc_STRVAR(multidict_popitem_doc,
824847PyDoc_STRVAR (multidict_update_doc ,
825848 "Update the dictionary, overwriting existing keys." );
826849
850+ PyDoc_STRVAR (multidict_merge_doc ,
851+ "Merge into the dictionary, adding non-existing keys." );
852+
827853PyDoc_STRVAR (sizeof__doc__ , "D.__sizeof__() -> size of D in memory, in bytes" );
828854
829855static PyObject *
@@ -887,6 +913,10 @@ static PyMethodDef multidict_methods[] = {
887913 (PyCFunction )multidict_update ,
888914 METH_VARARGS | METH_KEYWORDS ,
889915 multidict_update_doc },
916+ {"merge" ,
917+ (PyCFunction )multidict_merge ,
918+ METH_VARARGS | METH_KEYWORDS ,
919+ multidict_merge_doc },
890920 {
891921 "__reduce__" ,
892922 (PyCFunction )multidict_reduce ,
@@ -979,7 +1009,7 @@ cimultidict_tp_init(MultiDictObject *self, PyObject *args, PyObject *kwds)
9791009 if (md_init (self , state , true, size ) < 0 ) {
9801010 goto fail ;
9811011 }
982- if (_multidict_extend (self , arg , kwds , "CIMultiDict" , false ) < 0 ) {
1012+ if (_multidict_extend (self , arg , kwds , "CIMultiDict" , Extend ) < 0 ) {
9831013 goto fail ;
9841014 }
9851015done :
0 commit comments