Skip to content

Commit 9d6e59a

Browse files
Add MP_ASS_SUBSCRIPT macro
1 parent f5e3b1c commit 9d6e59a

File tree

4 files changed

+517
-331
lines changed

4 files changed

+517
-331
lines changed

src/interface/shared/slots.i

Lines changed: 52 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,51 @@
1919
*/
2020

2121

22+
// Macro to add mp_ass_subscript slot and functions
23+
%define MP_ASS_SUBSCRIPT(type, item_type, setfunc, delfunc)
24+
// Use %inline so SWIG generates wrappers with type conversions.
25+
// Names start with '_' so it's invisible in normal use.
26+
%noexception __setitem__%mangle(type);
27+
%noexception __delitem__%mangle(type);
28+
%inline %{
29+
static PyObject* __setitem__%mangle(type)(
30+
type* self, char* key, item_type value) {
31+
setfunc;
32+
return SWIG_Py_Void();
33+
};
34+
static PyObject* __delitem__%mangle(type)(type* self, char* key) {
35+
delfunc;
36+
return SWIG_Py_Void();
37+
};
38+
%}
39+
%fragment("__setitem__"{type}, "header") {
40+
extern "C" {
41+
static PyObject* _wrap___setitem__%mangle(type)(PyObject*, PyObject*);
42+
static PyObject* _wrap___delitem__%mangle(type)(PyObject*, PyObject*);
43+
}
44+
static int __setitem__%mangle(type)_closure(
45+
PyObject* self, PyObject* key, PyObject* value) {
46+
PyObject* args;
47+
PyObject* result;
48+
if (value) {
49+
args = Py_BuildValue("(OOO)", self, key, value);
50+
result = _wrap___setitem__%mangle(type)(self, args);
51+
} else {
52+
args = Py_BuildValue("(OO)", self, key);
53+
result = _wrap___delitem__%mangle(type)(self, args);
54+
}
55+
Py_DECREF(args);
56+
if (!result)
57+
return -1;
58+
Py_DECREF(result);
59+
return 0;
60+
};
61+
}
62+
%fragment("__setitem__"{type});
63+
%feature("python:mp_ass_subscript") type QUOTE(__setitem__%mangle(type)_closure);
64+
%enddef // MP_ASS_SUBSCRIPT
65+
66+
2267
// Macro to add mp_subscript slot and functions
2368
%define MP_SUBSCRIPT(type, item_type, func)
2469
// Use %inline so SWIG generates a wrapper with type conversions.
@@ -50,16 +95,17 @@ static PyObject* __getitem__%mangle(type)_closure(
5095
%define SQ_ASS_ITEM(type, item_type, setfunc, delfunc)
5196
// Use %inline so SWIG generates wrappers with type conversions.
5297
// Names start with '_' so it's invisible in normal use.
53-
%noexception __setitem__%mangle(Exiv2::ValueType<item_type>);
54-
%noexception __delitem__%mangle(Exiv2::ValueType<item_type>);
98+
%noexception __setitem__%mangle(type);
99+
%noexception __delitem__%mangle(type);
55100
%inline %{
56-
static void __setitem__%mangle(Exiv2::ValueType<item_type>)(
57-
Exiv2::ValueType<item_type>* self, size_t idx, item_type value) {
101+
static PyObject* __setitem__%mangle(type)(
102+
type* self, size_t idx, item_type value) {
58103
setfunc;
104+
return SWIG_Py_Void();
59105
};
60-
static void __delitem__%mangle(Exiv2::ValueType<item_type>)(
61-
Exiv2::ValueType<item_type>* self, size_t idx) {
106+
static PyObject* __delitem__%mangle(type)(type* self, size_t idx) {
62107
delfunc;
108+
return SWIG_Py_Void();
63109
};
64110
%}
65111
%fragment("__setitem__"{type}, "header") {

src/interface/value.i

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -361,8 +361,13 @@ STRUCT_DICT(Exiv2::TimeValue::Time, true, false)
361361
%feature("python:slot", "mp_length", functype="lenfunc")
362362
Exiv2::LangAltValue::count;
363363
MP_SUBSCRIPT(Exiv2::LangAltValue, std::string, self->value_.at(key))
364-
%feature("python:slot", "mp_ass_subscript", functype="objobjargproc")
365-
Exiv2::LangAltValue::__setitem__;
364+
MP_ASS_SUBSCRIPT(Exiv2::LangAltValue, std::string, self->value_[key] = value,
365+
{
366+
auto pos = self->value_.find(key);
367+
if (pos == self->value_.end())
368+
return PyErr_Format(PyExc_KeyError, "'%s'", key);
369+
self->value_.erase(pos);
370+
})
366371
%feature("python:slot", "sq_contains", functype="objobjproc")
367372
Exiv2::LangAltValue::__contains__;
368373
%feature("docstring") Exiv2::LangAltValue::keys
@@ -374,7 +379,6 @@ MP_SUBSCRIPT(Exiv2::LangAltValue, std::string, self->value_.at(key))
374379
components."
375380
%noexception Exiv2::LangAltValue::__contains__;
376381
%noexception Exiv2::LangAltValue::__iter__;
377-
%noexception Exiv2::LangAltValue::__setitem__;
378382
%noexception Exiv2::LangAltValue::keys;
379383
%noexception Exiv2::LangAltValue::items;
380384
%noexception Exiv2::LangAltValue::values;
@@ -412,20 +416,6 @@ components."
412416
Py_DECREF(keys);
413417
return result;
414418
}
415-
PyObject* __setitem__(const std::string& key, const std::string* INPUT) {
416-
if (INPUT)
417-
$self->value_[key] = *INPUT;
418-
else {
419-
typedef Exiv2::LangAltValue::ValueType::iterator iter;
420-
iter pos = $self->value_.find(key);
421-
if (pos == $self->value_.end()) {
422-
PyErr_SetString(PyExc_KeyError, key.c_str());
423-
return NULL;
424-
}
425-
$self->value_.erase(pos);
426-
}
427-
return SWIG_Py_Void();
428-
}
429419
bool __contains__(const std::string& key) {
430420
return $self->value_.find(key) != $self->value_.end();
431421
}

0 commit comments

Comments
 (0)