12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646 |
- #include "Python.h"
- #include "structmember.h"
- // Include order important
- #include "_multilib/defs.h"
- #include "_multilib/istr.h"
- #include "_multilib/pair_list.h"
- #include "_multilib/dict.h"
- #include "_multilib/iter.h"
- #include "_multilib/views.h"
- static PyObject *collections_abc_mapping;
- static PyObject *collections_abc_mut_mapping;
- static PyObject *collections_abc_mut_multi_mapping;
- static PyTypeObject multidict_type;
- static PyTypeObject cimultidict_type;
- static PyTypeObject multidict_proxy_type;
- static PyTypeObject cimultidict_proxy_type;
- static PyObject *repr_func;
- #define MultiDict_CheckExact(o) (Py_TYPE(o) == &multidict_type)
- #define CIMultiDict_CheckExact(o) (Py_TYPE(o) == &cimultidict_type)
- #define MultiDictProxy_CheckExact(o) (Py_TYPE(o) == &multidict_proxy_type)
- #define CIMultiDictProxy_CheckExact(o) (Py_TYPE(o) == &cimultidict_proxy_type)
- /* Helper macro for something like isinstance(obj, Base) */
- #define _MultiDict_Check(o) \
- ((MultiDict_CheckExact(o)) || \
- (CIMultiDict_CheckExact(o)) || \
- (MultiDictProxy_CheckExact(o)) || \
- (CIMultiDictProxy_CheckExact(o)))
- /******************** Internal Methods ********************/
- /* Forward declaration */
- static PyObject *multidict_items(MultiDictObject *self);
- static inline PyObject *
- _multidict_getone(MultiDictObject *self, PyObject *key, PyObject *_default)
- {
- PyObject *val = pair_list_get_one(&self->pairs, key);
- if (val == NULL &&
- PyErr_ExceptionMatches(PyExc_KeyError) &&
- _default != NULL)
- {
- PyErr_Clear();
- Py_INCREF(_default);
- return _default;
- }
- return val;
- }
- static inline int
- _multidict_eq(MultiDictObject *self, MultiDictObject *other)
- {
- Py_ssize_t pos1 = 0,
- pos2 = 0;
- Py_hash_t h1 = 0,
- h2 = 0;
- PyObject *identity1 = NULL,
- *identity2 = NULL,
- *value1 = NULL,
- *value2 = NULL;
- int cmp_identity = 0,
- cmp_value = 0;
- if (self == other) {
- return 1;
- }
- if (pair_list_len(&self->pairs) != pair_list_len(&other->pairs)) {
- return 0;
- }
- while (_pair_list_next(&self->pairs, &pos1, &identity1, NULL, &value1, &h1) &&
- _pair_list_next(&other->pairs, &pos2, &identity2, NULL, &value2, &h2))
- {
- if (h1 != h2) {
- return 0;
- }
- cmp_identity = PyObject_RichCompareBool(identity1, identity2, Py_NE);
- if (cmp_identity < 0) {
- return -1;
- }
- cmp_value = PyObject_RichCompareBool(value1, value2, Py_NE);
- if (cmp_value < 0) {
- return -1;
- }
- if (cmp_identity || cmp_value) {
- return 0;
- }
- }
- return 1;
- }
- static inline int
- _multidict_update_items(MultiDictObject *self, pair_list_t *pairs)
- {
- return pair_list_update(&self->pairs, pairs);
- }
- static inline int
- _multidict_append_items(MultiDictObject *self, pair_list_t *pairs)
- {
- PyObject *key = NULL,
- *value = NULL;
- Py_ssize_t pos = 0;
- while (_pair_list_next(pairs, &pos, NULL, &key, &value, NULL)) {
- if (pair_list_add(&self->pairs, key, value) < 0) {
- return -1;
- }
- }
- return 0;
- }
- static inline int
- _multidict_append_items_seq(MultiDictObject *self, PyObject *arg,
- const char *name)
- {
- PyObject *key = NULL,
- *value = NULL,
- *item = NULL,
- *iter = PyObject_GetIter(arg);
- if (iter == NULL) {
- return -1;
- }
- while ((item = PyIter_Next(iter)) != NULL) {
- if (PyTuple_CheckExact(item)) {
- if (PyTuple_GET_SIZE(item) != 2) {
- goto invalid_type;
- }
- key = PyTuple_GET_ITEM(item, 0);
- Py_INCREF(key);
- value = PyTuple_GET_ITEM(item, 1);
- Py_INCREF(value);
- }
- else if (PyList_CheckExact(item)) {
- if (PyList_GET_SIZE(item) != 2) {
- goto invalid_type;
- }
- key = PyList_GET_ITEM(item, 0);
- Py_INCREF(key);
- value = PyList_GET_ITEM(item, 1);
- Py_INCREF(value);
- }
- else if (PySequence_Check(item)) {
- if (PySequence_Size(item) != 2) {
- goto invalid_type;
- }
- key = PySequence_GetItem(item, 0);
- value = PySequence_GetItem(item, 1);
- } else {
- goto invalid_type;
- }
- if (pair_list_add(&self->pairs, key, value) < 0) {
- goto fail;
- }
- Py_CLEAR(key);
- Py_CLEAR(value);
- Py_CLEAR(item);
- }
- Py_DECREF(iter);
- if (PyErr_Occurred()) {
- return -1;
- }
- return 0;
- invalid_type:
- PyErr_Format(
- PyExc_TypeError,
- "%s takes either dict or list of (key, value) pairs",
- name,
- NULL
- );
- goto fail;
- fail:
- Py_XDECREF(key);
- Py_XDECREF(value);
- Py_XDECREF(item);
- Py_DECREF(iter);
- return -1;
- }
- static inline int
- _multidict_list_extend(PyObject *list, PyObject *target_list)
- {
- PyObject *item = NULL,
- *iter = PyObject_GetIter(target_list);
- if (iter == NULL) {
- return -1;
- }
- while ((item = PyIter_Next(iter)) != NULL) {
- if (PyList_Append(list, item) < 0) {
- Py_DECREF(item);
- Py_DECREF(iter);
- return -1;
- }
- Py_DECREF(item);
- }
- Py_DECREF(iter);
- if (PyErr_Occurred()) {
- return -1;
- }
- return 0;
- }
- static inline int
- _multidict_extend_with_args(MultiDictObject *self, PyObject *arg,
- PyObject *kwds, const char *name, int do_add)
- {
- PyObject *arg_items = NULL, /* tracked by GC */
- *kwds_items = NULL; /* new reference */
- pair_list_t *pairs = NULL;
- int err = 0;
- if (kwds && !PyArg_ValidateKeywordArguments(kwds)) {
- return -1;
- }
- // TODO: mb can be refactored more clear
- if (_MultiDict_Check(arg) && kwds == NULL) {
- if (MultiDict_CheckExact(arg) || CIMultiDict_CheckExact(arg)) {
- pairs = &((MultiDictObject*)arg)->pairs;
- } else if (MultiDictProxy_CheckExact(arg) || CIMultiDictProxy_CheckExact(arg)) {
- pairs = &((MultiDictProxyObject*)arg)->md->pairs;
- }
- if (do_add) {
- return _multidict_append_items(self, pairs);
- }
- return _multidict_update_items(self, pairs);
- }
- if (PyObject_HasAttrString(arg, "items")) {
- if (_MultiDict_Check(arg)) {
- arg_items = multidict_items((MultiDictObject*)arg);
- } else {
- arg_items = PyMapping_Items(arg);
- }
- if (arg_items == NULL) {
- return -1;
- }
- } else {
- arg_items = arg;
- Py_INCREF(arg_items);
- }
- if (kwds) {
- PyObject *tmp = PySequence_List(arg_items);
- Py_DECREF(arg_items);
- arg_items = tmp;
- if (arg_items == NULL) {
- return -1;
- }
- kwds_items = PyDict_Items(kwds);
- if (kwds_items == NULL) {
- Py_DECREF(arg_items);
- return -1;
- }
- err = _multidict_list_extend(arg_items, kwds_items);
- Py_DECREF(kwds_items);
- if (err < 0) {
- Py_DECREF(arg_items);
- return -1;
- }
- }
- if (do_add) {
- err = _multidict_append_items_seq(self, arg_items, name);
- } else {
- err = pair_list_update_from_seq(&self->pairs, arg_items);
- }
- Py_DECREF(arg_items);
- return err;
- }
- static inline int
- _multidict_extend_with_kwds(MultiDictObject *self, PyObject *kwds,
- const char *name, int do_add)
- {
- PyObject *arg = NULL;
- int err = 0;
- if (!PyArg_ValidateKeywordArguments(kwds)) {
- return -1;
- }
- arg = PyDict_Items(kwds);
- if (do_add) {
- err = _multidict_append_items_seq(self, arg, name);
- } else {
- err = pair_list_update_from_seq(&self->pairs, arg);
- }
- Py_DECREF(arg);
- return err;
- }
- static inline int
- _multidict_extend(MultiDictObject *self, PyObject *args, PyObject *kwds,
- const char *name, int do_add)
- {
- PyObject *arg = NULL;
- if (args && PyObject_Length(args) > 1) {
- PyErr_Format(
- PyExc_TypeError,
- "%s takes at most 1 positional argument (%zd given)",
- name, PyObject_Length(args), NULL
- );
- return -1;
- }
- if (args && PyObject_Length(args) > 0) {
- if (!PyArg_UnpackTuple(args, name, 0, 1, &arg)) {
- return -1;
- }
- if (_multidict_extend_with_args(self, arg, kwds, name, do_add) < 0) {
- return -1;
- }
- } else if (kwds && PyObject_Length(kwds) > 0) {
- if (_multidict_extend_with_kwds(self, kwds, name, do_add) < 0) {
- return -1;
- }
- }
- return 0;
- }
- static inline PyObject *
- _multidict_copy(MultiDictObject *self, PyTypeObject *multidict_tp_object)
- {
- MultiDictObject *new_multidict = NULL;
- PyObject *arg_items = NULL,
- *items = NULL;
- new_multidict = (MultiDictObject*)PyType_GenericNew(
- multidict_tp_object, NULL, NULL);
- if (new_multidict == NULL) {
- return NULL;
- }
- if (multidict_tp_object->tp_init(
- (PyObject*)new_multidict, NULL, NULL) < 0)
- {
- return NULL;
- }
- items = multidict_items(self);
- if (items == NULL) {
- goto fail;
- }
- // TODO: "Implementation looks as slow as possible ..."
- arg_items = PyTuple_New(1);
- if (arg_items == NULL) {
- goto fail;
- }
- Py_INCREF(items);
- PyTuple_SET_ITEM(arg_items, 0, items);
- if (_multidict_extend(
- new_multidict, arg_items, NULL, "copy", 1) < 0)
- {
- goto fail;
- }
- Py_DECREF(items);
- Py_DECREF(arg_items);
- return (PyObject*)new_multidict;
- fail:
- Py_XDECREF(items);
- Py_XDECREF(arg_items);
- Py_DECREF(new_multidict);
- return NULL;
- }
- static inline PyObject *
- _multidict_proxy_copy(MultiDictProxyObject *self, PyTypeObject *type)
- {
- PyObject *new_multidict = PyType_GenericNew(type, NULL, NULL);
- if (new_multidict == NULL) {
- goto fail;
- }
- if (type->tp_init(new_multidict, NULL, NULL) < 0) {
- goto fail;
- }
- if (_multidict_extend_with_args(
- (MultiDictObject*)new_multidict, (PyObject*)self, NULL, "copy", 1) < 0)
- {
- goto fail;
- }
- return new_multidict;
- fail:
- Py_XDECREF(new_multidict);
- return NULL;
- }
- /******************** Base Methods ********************/
- static inline PyObject *
- multidict_getall(MultiDictObject *self, PyObject *args, PyObject *kwds)
- {
- PyObject *list = NULL,
- *key = NULL,
- *_default = NULL;
- static char *getall_keywords[] = {"key", "default", NULL};
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:getall",
- getall_keywords, &key, &_default))
- {
- return NULL;
- }
- list = pair_list_get_all(&self->pairs, key);
- if (list == NULL &&
- PyErr_ExceptionMatches(PyExc_KeyError) &&
- _default != NULL)
- {
- PyErr_Clear();
- Py_INCREF(_default);
- return _default;
- }
- return list;
- }
- static inline PyObject *
- multidict_getone(MultiDictObject *self, PyObject *args, PyObject *kwds)
- {
- PyObject *key = NULL,
- *_default = NULL;
- static char *getone_keywords[] = {"key", "default", NULL};
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:getone",
- getone_keywords, &key, &_default))
- {
- return NULL;
- }
- return _multidict_getone(self, key, _default);
- }
- static inline PyObject *
- multidict_get(MultiDictObject *self, PyObject *args, PyObject *kwds)
- {
- PyObject *key = NULL,
- *_default = Py_None,
- *ret;
- static char *getone_keywords[] = {"key", "default", NULL};
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:getone",
- getone_keywords, &key, &_default))
- {
- return NULL;
- }
- ret = _multidict_getone(self, key, _default);
- return ret;
- }
- static inline PyObject *
- multidict_keys(MultiDictObject *self)
- {
- return multidict_keysview_new((PyObject*)self);
- }
- static inline PyObject *
- multidict_items(MultiDictObject *self)
- {
- return multidict_itemsview_new((PyObject*)self);
- }
- static inline PyObject *
- multidict_values(MultiDictObject *self)
- {
- return multidict_valuesview_new((PyObject*)self);
- }
- static inline PyObject *
- multidict_reduce(MultiDictObject *self)
- {
- PyObject *items = NULL,
- *items_list = NULL,
- *args = NULL,
- *result = NULL;
- items = multidict_items(self);
- if (items == NULL) {
- goto ret;
- }
- items_list = PySequence_List(items);
- if (items_list == NULL) {
- goto ret;
- }
- args = PyTuple_Pack(1, items_list);
- if (args == NULL) {
- goto ret;
- }
- result = PyTuple_Pack(2, Py_TYPE(self), args);
- ret:
- Py_XDECREF(args);
- Py_XDECREF(items_list);
- Py_XDECREF(items);
- return result;
- }
- static inline PyObject *
- multidict_repr(PyObject *self)
- {
- return PyObject_CallFunctionObjArgs(
- repr_func, self, NULL);
- }
- static inline Py_ssize_t
- multidict_mp_len(MultiDictObject *self)
- {
- return pair_list_len(&self->pairs);
- }
- static inline PyObject *
- multidict_mp_subscript(MultiDictObject *self, PyObject *key)
- {
- return _multidict_getone(self, key, NULL);
- }
- static inline int
- multidict_mp_as_subscript(MultiDictObject *self, PyObject *key, PyObject *val)
- {
- if (val == NULL) {
- return pair_list_del(&self->pairs, key);
- } else {
- return pair_list_replace(&self->pairs, key, val);
- }
- }
- static inline int
- multidict_sq_contains(MultiDictObject *self, PyObject *key)
- {
- return pair_list_contains(&self->pairs, key);
- }
- static inline PyObject *
- multidict_tp_iter(MultiDictObject *self)
- {
- return multidict_keys_iter_new(self);
- }
- static inline PyObject *
- multidict_tp_richcompare(PyObject *self, PyObject *other, int op)
- {
- // TODO: refactoring me with love
- int cmp = 0;
- if (op != Py_EQ && op != Py_NE) {
- Py_RETURN_NOTIMPLEMENTED;
- }
- if (MultiDict_CheckExact(other) || CIMultiDict_CheckExact(other)) {
- cmp = _multidict_eq(
- (MultiDictObject*)self,
- (MultiDictObject*)other
- );
- if (cmp < 0) {
- return NULL;
- }
- if (op == Py_NE) {
- cmp = !cmp;
- }
- return PyBool_FromLong(cmp);
- }
- if (MultiDictProxy_CheckExact(other) || CIMultiDictProxy_CheckExact(other)) {
- cmp = _multidict_eq(
- (MultiDictObject*)self,
- ((MultiDictProxyObject*)other)->md
- );
- if (cmp < 0) {
- return NULL;
- }
- if (op == Py_NE) {
- cmp = !cmp;
- }
- return PyBool_FromLong(cmp);
- }
- cmp = PyObject_IsInstance(other, (PyObject*)collections_abc_mapping);
- if (cmp < 0) {
- return NULL;
- }
- if (cmp) {
- cmp = pair_list_eq_to_mapping(&((MultiDictObject*)self)->pairs, other);
- if (cmp < 0) {
- return NULL;
- }
- if (op == Py_NE) {
- cmp = !cmp;
- }
- return PyBool_FromLong(cmp);
- }
- Py_RETURN_NOTIMPLEMENTED;
- }
- static inline void
- multidict_tp_dealloc(MultiDictObject *self)
- {
- PyObject_GC_UnTrack(self);
- Py_TRASHCAN_SAFE_BEGIN(self);
- if (self->weaklist != NULL) {
- PyObject_ClearWeakRefs((PyObject *)self);
- };
- pair_list_dealloc(&self->pairs);
- Py_TYPE(self)->tp_free((PyObject *)self);
- Py_TRASHCAN_SAFE_END(self);
- }
- static inline int
- multidict_tp_traverse(MultiDictObject *self, visitproc visit, void *arg)
- {
- return pair_list_traverse(&self->pairs, visit, arg);
- }
- static inline int
- multidict_tp_clear(MultiDictObject *self)
- {
- return pair_list_clear(&self->pairs);
- }
- PyDoc_STRVAR(multidict_getall_doc,
- "Return a list of all values matching the key.");
- PyDoc_STRVAR(multidict_getone_doc,
- "Get first value matching the key.");
- PyDoc_STRVAR(multidict_get_doc,
- "Get first value matching the key.\n\nThe method is alias for .getone().");
- PyDoc_STRVAR(multidict_keys_doc,
- "Return a new view of the dictionary's keys.");
- PyDoc_STRVAR(multidict_items_doc,
- "Return a new view of the dictionary's items *(key, value) pairs).");
- PyDoc_STRVAR(multidict_values_doc,
- "Return a new view of the dictionary's values.");
- /******************** MultiDict ********************/
- static inline int
- multidict_tp_init(MultiDictObject *self, PyObject *args, PyObject *kwds)
- {
- if (pair_list_init(&self->pairs) < 0) {
- return -1;
- }
- if (_multidict_extend(self, args, kwds, "MultiDict", 1) < 0) {
- return -1;
- }
- return 0;
- }
- static inline PyObject *
- multidict_add(MultiDictObject *self, PyObject *args, PyObject *kwds)
- {
- PyObject *key = NULL,
- *val = NULL;
- static char *kwlist[] = {"key", "value", NULL};
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO:add",
- kwlist, &key, &val))
- {
- return NULL;
- }
- if (pair_list_add(&self->pairs, key, val) < 0) {
- return NULL;
- }
- Py_RETURN_NONE;
- }
- static inline PyObject *
- multidict_copy(MultiDictObject *self)
- {
- return _multidict_copy(self, &multidict_type);
- }
- static inline PyObject *
- multidict_extend(MultiDictObject *self, PyObject *args, PyObject *kwds)
- {
- if (_multidict_extend(self, args, kwds, "extend", 1) < 0) {
- return NULL;
- }
- Py_RETURN_NONE;
- }
- static inline PyObject *
- multidict_clear(MultiDictObject *self)
- {
- if (pair_list_clear(&self->pairs) < 0) {
- return NULL;
- }
- Py_RETURN_NONE;
- }
- static inline PyObject *
- multidict_setdefault(MultiDictObject *self, PyObject *args, PyObject *kwds)
- {
- PyObject *key = NULL,
- *_default = NULL;
- static char *setdefault_keywords[] = {"key", "default", NULL};
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:setdefault",
- setdefault_keywords, &key, &_default))
- {
- return NULL;
- }
- return pair_list_set_default(&self->pairs, key, _default);
- }
- static inline PyObject *
- multidict_popone(MultiDictObject *self, PyObject *args, PyObject *kwds)
- {
- PyObject *key = NULL,
- *_default = NULL,
- *ret_val = NULL;
- static char *popone_keywords[] = {"key", "default", NULL};
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:popone",
- popone_keywords, &key, &_default))
- {
- return NULL;
- }
- ret_val = pair_list_pop_one(&self->pairs, key);
- if (ret_val == NULL &&
- PyErr_ExceptionMatches(PyExc_KeyError) &&
- _default != NULL)
- {
- PyErr_Clear();
- Py_INCREF(_default);
- return _default;
- }
- return ret_val;
- }
- static inline PyObject *
- multidict_popall(MultiDictObject *self, PyObject *args, PyObject *kwds)
- {
- PyObject *key = NULL,
- *_default = NULL,
- *ret_val = NULL;
- static char *popall_keywords[] = {"key", "default", NULL};
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:popall",
- popall_keywords, &key, &_default))
- {
- return NULL;
- }
- ret_val = pair_list_pop_all(&self->pairs, key);
- if (ret_val == NULL &&
- PyErr_ExceptionMatches(PyExc_KeyError) &&
- _default != NULL)
- {
- PyErr_Clear();
- Py_INCREF(_default);
- return _default;
- }
- return ret_val;
- }
- static inline PyObject *
- multidict_popitem(MultiDictObject *self)
- {
- return pair_list_pop_item(&self->pairs);
- }
- static inline PyObject *
- multidict_update(MultiDictObject *self, PyObject *args, PyObject *kwds)
- {
- if (_multidict_extend(self, args, kwds, "update", 0) < 0) {
- return NULL;
- }
- Py_RETURN_NONE;
- }
- PyDoc_STRVAR(multidict_add_doc,
- "Add the key and value, not overwriting any previous value.");
- PyDoc_STRVAR(multidict_copy_doc,
- "Return a copy of itself.");
- PyDoc_STRVAR(multdicit_method_extend_doc,
- "Extend current MultiDict with more values.\n\
- This method must be used instead of update.");
- PyDoc_STRVAR(multidict_clear_doc,
- "Remove all items from MultiDict");
- PyDoc_STRVAR(multidict_setdefault_doc,
- "Return value for key, set value to default if key is not present.");
- PyDoc_STRVAR(multidict_popone_doc,
- "Remove the last occurrence of key and return the corresponding value.\n\n\
- If key is not found, default is returned if given, otherwise KeyError is \
- raised.\n");
- PyDoc_STRVAR(multidict_popall_doc,
- "Remove all occurrences of key and return the list of corresponding values.\n\n\
- If key is not found, default is returned if given, otherwise KeyError is \
- raised.\n");
- PyDoc_STRVAR(multidict_popitem_doc,
- "Remove and return an arbitrary (key, value) pair.");
- PyDoc_STRVAR(multidict_update_doc,
- "Update the dictionary from *other*, overwriting existing keys.");
- #if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 9
- #define multidict_class_getitem Py_GenericAlias
- #else
- static inline PyObject *
- multidict_class_getitem(PyObject *self, PyObject *arg)
- {
- Py_INCREF(self);
- return self;
- }
- #endif
- PyDoc_STRVAR(sizeof__doc__,
- "D.__sizeof__() -> size of D in memory, in bytes");
- static inline PyObject *
- _multidict_sizeof(MultiDictObject *self)
- {
- Py_ssize_t size = sizeof(MultiDictObject);
- if (self->pairs.pairs != self->pairs.buffer) {
- size += (Py_ssize_t)sizeof(pair_t) * self->pairs.capacity;
- }
- return PyLong_FromSsize_t(size);
- }
- static PySequenceMethods multidict_sequence = {
- .sq_contains = (objobjproc)multidict_sq_contains,
- };
- static PyMappingMethods multidict_mapping = {
- .mp_length = (lenfunc)multidict_mp_len,
- .mp_subscript = (binaryfunc)multidict_mp_subscript,
- .mp_ass_subscript = (objobjargproc)multidict_mp_as_subscript,
- };
- static PyMethodDef multidict_methods[] = {
- {
- "getall",
- (PyCFunction)multidict_getall,
- METH_VARARGS | METH_KEYWORDS,
- multidict_getall_doc
- },
- {
- "getone",
- (PyCFunction)multidict_getone,
- METH_VARARGS | METH_KEYWORDS,
- multidict_getone_doc
- },
- {
- "get",
- (PyCFunction)multidict_get,
- METH_VARARGS | METH_KEYWORDS,
- multidict_get_doc
- },
- {
- "keys",
- (PyCFunction)multidict_keys,
- METH_NOARGS,
- multidict_keys_doc
- },
- {
- "items",
- (PyCFunction)multidict_items,
- METH_NOARGS,
- multidict_items_doc
- },
- {
- "values",
- (PyCFunction)multidict_values,
- METH_NOARGS,
- multidict_values_doc
- },
- {
- "add",
- (PyCFunction)multidict_add,
- METH_VARARGS | METH_KEYWORDS,
- multidict_add_doc
- },
- {
- "copy",
- (PyCFunction)multidict_copy,
- METH_NOARGS,
- multidict_copy_doc
- },
- {
- "extend",
- (PyCFunction)multidict_extend,
- METH_VARARGS | METH_KEYWORDS,
- multdicit_method_extend_doc
- },
- {
- "clear",
- (PyCFunction)multidict_clear,
- METH_NOARGS,
- multidict_clear_doc
- },
- {
- "setdefault",
- (PyCFunction)multidict_setdefault,
- METH_VARARGS | METH_KEYWORDS,
- multidict_setdefault_doc
- },
- {
- "popone",
- (PyCFunction)multidict_popone,
- METH_VARARGS | METH_KEYWORDS,
- multidict_popone_doc
- },
- {
- "pop",
- (PyCFunction)multidict_popone,
- METH_VARARGS | METH_KEYWORDS,
- multidict_popone_doc
- },
- {
- "popall",
- (PyCFunction)multidict_popall,
- METH_VARARGS | METH_KEYWORDS,
- multidict_popall_doc
- },
- {
- "popitem",
- (PyCFunction)multidict_popitem,
- METH_NOARGS,
- multidict_popitem_doc
- },
- {
- "update",
- (PyCFunction)multidict_update,
- METH_VARARGS | METH_KEYWORDS,
- multidict_update_doc
- },
- {
- "__reduce__",
- (PyCFunction)multidict_reduce,
- METH_NOARGS,
- NULL,
- },
- {
- "__class_getitem__",
- (PyCFunction)multidict_class_getitem,
- METH_O | METH_CLASS,
- NULL
- },
- {
- "__sizeof__",
- (PyCFunction)_multidict_sizeof,
- METH_NOARGS,
- sizeof__doc__,
- },
- {
- NULL,
- NULL
- } /* sentinel */
- };
- PyDoc_STRVAR(MultDict_doc,
- "Dictionary with the support for duplicate keys.");
- static PyTypeObject multidict_type = {
- PyVarObject_HEAD_INIT(NULL, 0)
- "multidict._multidict.MultiDict", /* tp_name */
- sizeof(MultiDictObject), /* tp_basicsize */
- .tp_dealloc = (destructor)multidict_tp_dealloc,
- .tp_repr = (reprfunc)multidict_repr,
- .tp_as_sequence = &multidict_sequence,
- .tp_as_mapping = &multidict_mapping,
- .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
- .tp_doc = MultDict_doc,
- .tp_traverse = (traverseproc)multidict_tp_traverse,
- .tp_clear = (inquiry)multidict_tp_clear,
- .tp_richcompare = (richcmpfunc)multidict_tp_richcompare,
- .tp_weaklistoffset = offsetof(MultiDictObject, weaklist),
- .tp_iter = (getiterfunc)multidict_tp_iter,
- .tp_methods = multidict_methods,
- .tp_init = (initproc)multidict_tp_init,
- .tp_alloc = PyType_GenericAlloc,
- .tp_new = PyType_GenericNew,
- .tp_free = PyObject_GC_Del,
- };
- /******************** CIMultiDict ********************/
- static inline int
- cimultidict_tp_init(MultiDictObject *self, PyObject *args, PyObject *kwds)
- {
- if (ci_pair_list_init(&self->pairs) < 0) {
- return -1;
- }
- if (_multidict_extend(self, args, kwds, "CIMultiDict", 1) < 0) {
- return -1;
- }
- return 0;
- }
- static inline PyObject *
- cimultidict_copy(MultiDictObject *self)
- {
- return _multidict_copy(self, &cimultidict_type);
- }
- PyDoc_STRVAR(cimultidict_copy_doc,
- "Return a copy of itself.");
- static PyMethodDef cimultidict_methods[] = {
- {
- "copy",
- (PyCFunction)cimultidict_copy,
- METH_NOARGS,
- cimultidict_copy_doc
- },
- {
- NULL,
- NULL
- } /* sentinel */
- };
- PyDoc_STRVAR(CIMultDict_doc,
- "Dictionary with the support for duplicate case-insensitive keys.");
- static PyTypeObject cimultidict_type = {
- PyVarObject_HEAD_INIT(NULL, 0)
- "multidict._multidict.CIMultiDict", /* tp_name */
- sizeof(MultiDictObject), /* tp_basicsize */
- .tp_dealloc = (destructor)multidict_tp_dealloc,
- .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
- .tp_doc = CIMultDict_doc,
- .tp_traverse = (traverseproc)multidict_tp_traverse,
- .tp_clear = (inquiry)multidict_tp_clear,
- .tp_weaklistoffset = offsetof(MultiDictObject, weaklist),
- .tp_methods = cimultidict_methods,
- .tp_base = &multidict_type,
- .tp_init = (initproc)cimultidict_tp_init,
- .tp_alloc = PyType_GenericAlloc,
- .tp_new = PyType_GenericNew,
- .tp_free = PyObject_GC_Del,
- };
- /******************** MultiDictProxy ********************/
- static inline int
- multidict_proxy_tp_init(MultiDictProxyObject *self, PyObject *args,
- PyObject *kwds)
- {
- PyObject *arg = NULL;
- MultiDictObject *md = NULL;
- if (!PyArg_UnpackTuple(args, "multidict._multidict.MultiDictProxy",
- 0, 1, &arg))
- {
- return -1;
- }
- if (arg == NULL) {
- PyErr_Format(
- PyExc_TypeError,
- "__init__() missing 1 required positional argument: 'arg'"
- );
- return -1;
- }
- if (!MultiDictProxy_CheckExact(arg) &&
- !CIMultiDict_CheckExact(arg) &&
- !MultiDict_CheckExact(arg))
- {
- PyErr_Format(
- PyExc_TypeError,
- "ctor requires MultiDict or MultiDictProxy instance, "
- "not <classs '%s'>",
- Py_TYPE(arg)->tp_name
- );
- return -1;
- }
- md = (MultiDictObject*)arg;
- if (MultiDictProxy_CheckExact(arg)) {
- md = ((MultiDictProxyObject*)arg)->md;
- }
- Py_INCREF(md);
- self->md = md;
- return 0;
- }
- static inline PyObject *
- multidict_proxy_getall(MultiDictProxyObject *self, PyObject *args,
- PyObject *kwds)
- {
- return multidict_getall(self->md, args, kwds);
- }
- static inline PyObject *
- multidict_proxy_getone(MultiDictProxyObject *self, PyObject *args,
- PyObject *kwds)
- {
- return multidict_getone(self->md, args, kwds);
- }
- static inline PyObject *
- multidict_proxy_get(MultiDictProxyObject *self, PyObject *args,
- PyObject *kwds)
- {
- return multidict_get(self->md, args, kwds);
- }
- static inline PyObject *
- multidict_proxy_keys(MultiDictProxyObject *self)
- {
- return multidict_keys(self->md);
- }
- static inline PyObject *
- multidict_proxy_items(MultiDictProxyObject *self)
- {
- return multidict_items(self->md);
- }
- static inline PyObject *
- multidict_proxy_values(MultiDictProxyObject *self)
- {
- return multidict_values(self->md);
- }
- static inline PyObject *
- multidict_proxy_copy(MultiDictProxyObject *self)
- {
- return _multidict_proxy_copy(self, &multidict_type);
- }
- static inline PyObject *
- multidict_proxy_reduce(MultiDictProxyObject *self)
- {
- PyErr_Format(
- PyExc_TypeError,
- "can't pickle %s objects", Py_TYPE(self)->tp_name
- );
- return NULL;
- }
- static inline Py_ssize_t
- multidict_proxy_mp_len(MultiDictProxyObject *self)
- {
- return multidict_mp_len(self->md);
- }
- static inline PyObject *
- multidict_proxy_mp_subscript(MultiDictProxyObject *self, PyObject *key)
- {
- return multidict_mp_subscript(self->md, key);
- }
- static inline int
- multidict_proxy_sq_contains(MultiDictProxyObject *self, PyObject *key)
- {
- return multidict_sq_contains(self->md, key);
- }
- static inline PyObject *
- multidict_proxy_tp_iter(MultiDictProxyObject *self)
- {
- return multidict_tp_iter(self->md);
- }
- static inline PyObject *
- multidict_proxy_tp_richcompare(MultiDictProxyObject *self, PyObject *other,
- int op)
- {
- return multidict_tp_richcompare((PyObject*)self->md, other, op);
- }
- static inline void
- multidict_proxy_tp_dealloc(MultiDictProxyObject *self)
- {
- PyObject_GC_UnTrack(self);
- if (self->weaklist != NULL) {
- PyObject_ClearWeakRefs((PyObject *)self);
- };
- Py_XDECREF(self->md);
- Py_TYPE(self)->tp_free((PyObject *)self);
- }
- static inline int
- multidict_proxy_tp_traverse(MultiDictProxyObject *self, visitproc visit,
- void *arg)
- {
- Py_VISIT(self->md);
- return 0;
- }
- static inline int
- multidict_proxy_tp_clear(MultiDictProxyObject *self)
- {
- Py_CLEAR(self->md);
- return 0;
- }
- static PySequenceMethods multidict_proxy_sequence = {
- .sq_contains = (objobjproc)multidict_proxy_sq_contains,
- };
- static PyMappingMethods multidict_proxy_mapping = {
- .mp_length = (lenfunc)multidict_proxy_mp_len,
- .mp_subscript = (binaryfunc)multidict_proxy_mp_subscript,
- };
- static PyMethodDef multidict_proxy_methods[] = {
- {
- "getall",
- (PyCFunction)multidict_proxy_getall,
- METH_VARARGS | METH_KEYWORDS,
- multidict_getall_doc
- },
- {
- "getone",
- (PyCFunction)multidict_proxy_getone,
- METH_VARARGS | METH_KEYWORDS,
- multidict_getone_doc
- },
- {
- "get",
- (PyCFunction)multidict_proxy_get,
- METH_VARARGS | METH_KEYWORDS,
- multidict_get_doc
- },
- {
- "keys",
- (PyCFunction)multidict_proxy_keys,
- METH_NOARGS,
- multidict_keys_doc
- },
- {
- "items",
- (PyCFunction)multidict_proxy_items,
- METH_NOARGS,
- multidict_items_doc
- },
- {
- "values",
- (PyCFunction)multidict_proxy_values,
- METH_NOARGS,
- multidict_values_doc
- },
- {
- "copy",
- (PyCFunction)multidict_proxy_copy,
- METH_NOARGS,
- multidict_copy_doc
- },
- {
- "__reduce__",
- (PyCFunction)multidict_proxy_reduce,
- METH_NOARGS,
- NULL
- },
- {
- "__class_getitem__",
- (PyCFunction)multidict_class_getitem,
- METH_O | METH_CLASS,
- NULL
- },
- {
- NULL,
- NULL
- } /* sentinel */
- };
- PyDoc_STRVAR(MultDictProxy_doc,
- "Read-only proxy for MultiDict instance.");
- static PyTypeObject multidict_proxy_type = {
- PyVarObject_HEAD_INIT(NULL, 0)
- "multidict._multidict.MultiDictProxy", /* tp_name */
- sizeof(MultiDictProxyObject), /* tp_basicsize */
- .tp_dealloc = (destructor)multidict_proxy_tp_dealloc,
- .tp_repr = (reprfunc)multidict_repr,
- .tp_as_sequence = &multidict_proxy_sequence,
- .tp_as_mapping = &multidict_proxy_mapping,
- .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
- .tp_doc = MultDictProxy_doc,
- .tp_traverse = (traverseproc)multidict_proxy_tp_traverse,
- .tp_clear = (inquiry)multidict_proxy_tp_clear,
- .tp_richcompare = (richcmpfunc)multidict_proxy_tp_richcompare,
- .tp_weaklistoffset = offsetof(MultiDictProxyObject, weaklist),
- .tp_iter = (getiterfunc)multidict_proxy_tp_iter,
- .tp_methods = multidict_proxy_methods,
- .tp_init = (initproc)multidict_proxy_tp_init,
- .tp_alloc = PyType_GenericAlloc,
- .tp_new = PyType_GenericNew,
- .tp_free = PyObject_GC_Del,
- };
- /******************** CIMultiDictProxy ********************/
- static inline int
- cimultidict_proxy_tp_init(MultiDictProxyObject *self, PyObject *args,
- PyObject *kwds)
- {
- PyObject *arg = NULL;
- MultiDictObject *md = NULL;
- if (!PyArg_UnpackTuple(args, "multidict._multidict.CIMultiDictProxy",
- 1, 1, &arg))
- {
- return -1;
- }
- if (arg == NULL) {
- PyErr_Format(
- PyExc_TypeError,
- "__init__() missing 1 required positional argument: 'arg'"
- );
- return -1;
- }
- if (!CIMultiDictProxy_CheckExact(arg) && !CIMultiDict_CheckExact(arg)) {
- PyErr_Format(
- PyExc_TypeError,
- "ctor requires CIMultiDict or CIMultiDictProxy instance, "
- "not <class '%s'>",
- Py_TYPE(arg)->tp_name
- );
- return -1;
- }
- md = (MultiDictObject*)arg;
- if (CIMultiDictProxy_CheckExact(arg)) {
- md = ((MultiDictProxyObject*)arg)->md;
- }
- Py_INCREF(md);
- self->md = md;
- return 0;
- }
- static inline PyObject *
- cimultidict_proxy_copy(MultiDictProxyObject *self)
- {
- return _multidict_proxy_copy(self, &cimultidict_type);
- }
- PyDoc_STRVAR(CIMultDictProxy_doc,
- "Read-only proxy for CIMultiDict instance.");
- PyDoc_STRVAR(cimultidict_proxy_copy_doc,
- "Return copy of itself");
- static PyMethodDef cimultidict_proxy_methods[] = {
- {
- "copy",
- (PyCFunction)cimultidict_proxy_copy,
- METH_NOARGS,
- cimultidict_proxy_copy_doc
- },
- {
- NULL,
- NULL
- } /* sentinel */
- };
- static PyTypeObject cimultidict_proxy_type = {
- PyVarObject_HEAD_INIT(NULL, 0)
- "multidict._multidict.CIMultiDictProxy", /* tp_name */
- sizeof(MultiDictProxyObject), /* tp_basicsize */
- .tp_dealloc = (destructor)multidict_proxy_tp_dealloc,
- .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
- .tp_doc = CIMultDictProxy_doc,
- .tp_traverse = (traverseproc)multidict_proxy_tp_traverse,
- .tp_clear = (inquiry)multidict_proxy_tp_clear,
- .tp_richcompare = (richcmpfunc)multidict_proxy_tp_richcompare,
- .tp_weaklistoffset = offsetof(MultiDictProxyObject, weaklist),
- .tp_methods = cimultidict_proxy_methods,
- .tp_base = &multidict_proxy_type,
- .tp_init = (initproc)cimultidict_proxy_tp_init,
- .tp_alloc = PyType_GenericAlloc,
- .tp_new = PyType_GenericNew,
- .tp_free = PyObject_GC_Del,
- };
- /******************** Other functions ********************/
- static inline PyObject *
- getversion(PyObject *self, PyObject *md)
- {
- pair_list_t *pairs = NULL;
- if (MultiDict_CheckExact(md) || CIMultiDict_CheckExact(md)) {
- pairs = &((MultiDictObject*)md)->pairs;
- } else if (MultiDictProxy_CheckExact(md) || CIMultiDictProxy_CheckExact(md)) {
- pairs = &((MultiDictProxyObject*)md)->md->pairs;
- } else {
- PyErr_Format(PyExc_TypeError, "unexpected type");
- return NULL;
- }
- return PyLong_FromUnsignedLong(pair_list_version(pairs));
- }
- /******************** Module ********************/
- static inline void
- module_free(void *m)
- {
- Py_CLEAR(collections_abc_mapping);
- Py_CLEAR(collections_abc_mut_mapping);
- Py_CLEAR(collections_abc_mut_multi_mapping);
- }
- static PyMethodDef multidict_module_methods[] = {
- {
- "getversion",
- (PyCFunction)getversion,
- METH_O
- },
- {
- NULL,
- NULL
- } /* sentinel */
- };
- static PyModuleDef multidict_module = {
- PyModuleDef_HEAD_INIT, /* m_base */
- "_multidict", /* m_name */
- .m_size = -1,
- .m_methods = multidict_module_methods,
- .m_free = (freefunc)module_free,
- };
- PyMODINIT_FUNC
- PyInit__multidict()
- {
- PyObject *module = NULL,
- *reg_func_call_result = NULL;
- #define WITH_MOD(NAME) \
- Py_CLEAR(module); \
- module = PyImport_ImportModule(NAME); \
- if (module == NULL) { \
- goto fail; \
- }
- #define GET_MOD_ATTR(VAR, NAME) \
- VAR = PyObject_GetAttrString(module, NAME); \
- if (VAR == NULL) { \
- goto fail; \
- }
- if (multidict_views_init() < 0) {
- goto fail;
- }
- if (multidict_iter_init() < 0) {
- goto fail;
- }
- if (istr_init() < 0) {
- goto fail;
- }
- if (PyType_Ready(&multidict_type) < 0 ||
- PyType_Ready(&cimultidict_type) < 0 ||
- PyType_Ready(&multidict_proxy_type) < 0 ||
- PyType_Ready(&cimultidict_proxy_type) < 0)
- {
- goto fail;
- }
- WITH_MOD("collections.abc");
- GET_MOD_ATTR(collections_abc_mapping, "Mapping");
- WITH_MOD("multidict._abc");
- GET_MOD_ATTR(collections_abc_mut_mapping, "MultiMapping");
- WITH_MOD("multidict._abc");
- GET_MOD_ATTR(collections_abc_mut_multi_mapping, "MutableMultiMapping");
- WITH_MOD("multidict._multidict_base");
- GET_MOD_ATTR(repr_func, "_mdrepr");
- /* Register in _abc mappings (CI)MultiDict and (CI)MultiDictProxy */
- reg_func_call_result = PyObject_CallMethod(
- collections_abc_mut_mapping,
- "register", "O",
- (PyObject*)&multidict_proxy_type
- );
- if (reg_func_call_result == NULL) {
- goto fail;
- }
- Py_DECREF(reg_func_call_result);
- reg_func_call_result = PyObject_CallMethod(
- collections_abc_mut_mapping,
- "register", "O",
- (PyObject*)&cimultidict_proxy_type
- );
- if (reg_func_call_result == NULL) {
- goto fail;
- }
- Py_DECREF(reg_func_call_result);
- reg_func_call_result = PyObject_CallMethod(
- collections_abc_mut_multi_mapping,
- "register", "O",
- (PyObject*)&multidict_type
- );
- if (reg_func_call_result == NULL) {
- goto fail;
- }
- Py_DECREF(reg_func_call_result);
- reg_func_call_result = PyObject_CallMethod(
- collections_abc_mut_multi_mapping,
- "register", "O",
- (PyObject*)&cimultidict_type
- );
- if (reg_func_call_result == NULL) {
- goto fail;
- }
- Py_DECREF(reg_func_call_result);
- /* Instantiate this module */
- module = PyModule_Create(&multidict_module);
- Py_INCREF(&istr_type);
- if (PyModule_AddObject(
- module, "istr", (PyObject*)&istr_type) < 0)
- {
- goto fail;
- }
- Py_INCREF(&multidict_type);
- if (PyModule_AddObject(
- module, "MultiDict", (PyObject*)&multidict_type) < 0)
- {
- goto fail;
- }
- Py_INCREF(&cimultidict_type);
- if (PyModule_AddObject(
- module, "CIMultiDict", (PyObject*)&cimultidict_type) < 0)
- {
- goto fail;
- }
- Py_INCREF(&multidict_proxy_type);
- if (PyModule_AddObject(
- module, "MultiDictProxy", (PyObject*)&multidict_proxy_type) < 0)
- {
- goto fail;
- }
- Py_INCREF(&cimultidict_proxy_type);
- if (PyModule_AddObject(
- module, "CIMultiDictProxy", (PyObject*)&cimultidict_proxy_type) < 0)
- {
- goto fail;
- }
- return module;
- fail:
- Py_XDECREF(collections_abc_mapping);
- Py_XDECREF(collections_abc_mut_mapping);
- Py_XDECREF(collections_abc_mut_multi_mapping);
- return NULL;
- #undef WITH_MOD
- #undef GET_MOD_ATTR
- }
|