Skip to content

Commit cf7fb82

Browse files
Better "struct dict" initialisation
1 parent 0582438 commit cf7fb82

File tree

16 files changed

+349
-372
lines changed

16 files changed

+349
-372
lines changed

src/interface/datasets.i

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,3 +77,5 @@ STRUCT_DICT(Exiv2::DataSet, false, true)
7777
%immutable;
7878
%include "exiv2/datasets.hpp"
7979
%mutable;
80+
81+
INIT_STRUCT_DICT(Exiv2::DataSet)

src/interface/preview.i

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,3 +111,5 @@ STRUCT_DICT(Exiv2::PreviewProperties, false, true)
111111
%include "exiv2/preview.hpp"
112112
%mutable;
113113
#undef EXV_ENABLE_FILESYSTEM
114+
115+
INIT_STRUCT_DICT(Exiv2::PreviewProperties)

src/interface/properties.i

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,3 +128,6 @@ STRUCT_DICT(Exiv2::XmpNsInfo, false, true)
128128
%immutable;
129129
%include "exiv2/properties.hpp"
130130
%mutable;
131+
132+
INIT_STRUCT_DICT(Exiv2::XmpPropertyInfo)
133+
INIT_STRUCT_DICT(Exiv2::XmpNsInfo)

src/interface/shared/struct_dict.i

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,6 @@ typedef struct {
2929
}
3030
%fragment("init_struct_info", "header", fragment="struct_info_type") {
3131
static void init_struct_info(struct_info& info, swig_type_info* type) {
32-
if (!info.members.empty())
33-
return;
3432
PyGetSetDef* getset =
3533
((SwigPyClientData*)type->clientdata)->pytype->tp_getset;
3634
while (getset->name) {
@@ -156,64 +154,53 @@ Python interface uses names without underscores."
156154
%fragment("values_struct");
157155
%fragment("items_struct");
158156
static PyObject* keys() {
159-
init_info_%mangle(struct_type)();
160157
return keys_struct(info_%mangle(struct_type));
161158
}
162159
PyObject* values(PyObject* py_self) {
163-
init_info_%mangle(struct_type)();
164160
return values_struct(info_%mangle(struct_type), py_self);
165161
}
166162
PyObject* items(PyObject* py_self) {
167-
init_info_%mangle(struct_type)();
168163
return items_struct(info_%mangle(struct_type), py_self);
169164
}
170165
static PyObject* __iter__() {
171166
// Deprecated since 2025-09-11
172167
PyErr_WarnEx(PyExc_DeprecationWarning,
173168
"Please iterate over keys() function output", 1);
174-
init_info_%mangle(struct_type)();
175169
PyObject* seq = keys_struct(info_%mangle(struct_type));
176170
PyObject* result = PySeqIter_New(seq);
177171
Py_DECREF(seq);
178172
return result;
179173
}
180174
}
181175
%fragment("struct_info"{struct_type}, "header",
182-
fragment="init_struct_info") {
176+
fragment="struct_info_type") {
183177
static struct_info info_%mangle(struct_type);
184-
static void init_info_%mangle(struct_type)() {
185-
init_struct_info(info_%mangle(struct_type), $descriptor(struct_type*));
186-
};
187178
}
188179
%fragment("get_item"{struct_type}, "header",
189180
fragment="struct_info"{struct_type}, fragment="get_attr_struct") {
190181
static PyObject* get_item_%mangle(struct_type)(PyObject* obj,
191182
PyObject* key) {
192-
init_info_%mangle(struct_type)();
193183
return get_attr_struct(info_%mangle(struct_type), true, obj, key);
194184
};
195185
}
196186
%fragment("get_attr"{struct_type}, "header",
197187
fragment="struct_info"{struct_type}, fragment="get_attr_struct") {
198188
static PyObject* get_attr_%mangle(struct_type)(PyObject* obj,
199189
PyObject* name) {
200-
init_info_%mangle(struct_type)();
201190
return get_attr_struct(info_%mangle(struct_type), false, obj, name);
202191
};
203192
}
204193
%fragment("set_item"{struct_type}, "header",
205194
fragment="struct_info"{struct_type}, fragment="set_attr_struct") {
206195
static int set_item_%mangle(struct_type)(
207196
PyObject* obj, PyObject* key, PyObject* value) {
208-
init_info_%mangle(struct_type)();
209197
return set_attr_struct(info_%mangle(struct_type), true, obj, key, value);
210198
};
211199
}
212200
%fragment("set_attr"{struct_type}, "header",
213201
fragment="struct_info"{struct_type}, fragment="set_attr_struct") {
214202
static int set_attr_%mangle(struct_type)(
215203
PyObject* obj, PyObject* name, PyObject* value) {
216-
init_info_%mangle(struct_type)();
217204
return set_attr_struct(
218205
info_%mangle(struct_type), false, obj, name, value);
219206
};
@@ -237,3 +224,20 @@ static int set_attr_%mangle(struct_type)(
237224
#endif
238225
#endif // mutable
239226
%enddef // STRUCT_DICT
227+
228+
229+
// Put this at the end of a .i file, after the struct_type type object
230+
// has been initialised.
231+
%define INIT_STRUCT_DICT(struct_type)
232+
%fragment("init_struct_dict"{struct_type}, "init",
233+
fragment="struct_info"{struct_type},
234+
fragment="init_struct_info") {
235+
init_struct_info(info_%mangle(struct_type), $descriptor(struct_type*));
236+
if (info_%mangle(struct_type).aliases.empty()) {
237+
PyErr_SetString(
238+
PyExc_RuntimeError, "Failed to initialise struct_type info");
239+
return INIT_ERROR_RETURN;
240+
}
241+
}
242+
%fragment("init_struct_dict"{struct_type});
243+
%enddef // INIT_STRUCT_DICT

src/interface/tags.i

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,3 +122,6 @@ public:
122122
%immutable;
123123
%include "exiv2/tags.hpp"
124124
%mutable;
125+
126+
INIT_STRUCT_DICT(Exiv2::GroupInfo)
127+
INIT_STRUCT_DICT(Exiv2::TagInfo)

src/interface/value.i

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -553,3 +553,6 @@ VALUETYPE(LongValue, int32_t, Exiv2::signedLong)
553553
VALUETYPE(RationalValue, Exiv2::Rational, Exiv2::signedRational)
554554
VALUETYPE(FloatValue, float, Exiv2::tiffFloat)
555555
VALUETYPE(DoubleValue, double, Exiv2::tiffDouble)
556+
557+
INIT_STRUCT_DICT(Exiv2::DateValue::Date)
558+
INIT_STRUCT_DICT(Exiv2::TimeValue::Time)

src/swig-0_27_7/datasets_wrap.cxx

Lines changed: 27 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -4358,31 +4358,7 @@ typedef struct {
43584358
} struct_info;
43594359

43604360

4361-
static void init_struct_info(struct_info& info, swig_type_info* type) {
4362-
if (!info.members.empty())
4363-
return;
4364-
PyGetSetDef* getset =
4365-
((SwigPyClientData*)type->clientdata)->pytype->tp_getset;
4366-
while (getset->name) {
4367-
// __dict__ is also in the getset list
4368-
if (getset->name[0] != '_') {
4369-
info.members.push_back(getset->name);
4370-
std::string alias = getset->name;
4371-
if (alias.back() == '_') {
4372-
alias.pop_back();
4373-
info.aliased = true;
4374-
}
4375-
info.aliases.push_back(alias);
4376-
}
4377-
getset++;
4378-
}
4379-
};
4380-
4381-
43824361
static struct_info info_Exiv2_DataSet;
4383-
static void init_info_Exiv2_DataSet() {
4384-
init_struct_info(info_Exiv2_DataSet, SWIGTYPE_p_Exiv2__DataSet);
4385-
};
43864362

43874363

43884364
static PyObject* get_attr_struct(struct_info& info, bool as_item,
@@ -4400,14 +4376,12 @@ static PyObject* get_attr_struct(struct_info& info, bool as_item,
44004376

44014377
static PyObject* get_item_Exiv2_DataSet(PyObject* obj,
44024378
PyObject* key) {
4403-
init_info_Exiv2_DataSet();
44044379
return get_attr_struct(info_Exiv2_DataSet, true, obj, key);
44054380
};
44064381

44074382

44084383
static PyObject* get_attr_Exiv2_DataSet(PyObject* obj,
44094384
PyObject* name) {
4410-
init_info_Exiv2_DataSet();
44114385
return get_attr_struct(info_Exiv2_DataSet, false, obj, name);
44124386
};
44134387

@@ -4475,22 +4449,18 @@ SWIGINTERNINLINE PyObject*
44754449
static PyObject* Python_Exiv2_TypeId = NULL;
44764450

44774451
SWIGINTERN PyObject *Exiv2_DataSet_keys(){
4478-
init_info_Exiv2_DataSet();
44794452
return keys_struct(info_Exiv2_DataSet);
44804453
}
44814454
SWIGINTERN PyObject *Exiv2_DataSet_values(Exiv2::DataSet *self,PyObject *py_self){
4482-
init_info_Exiv2_DataSet();
44834455
return values_struct(info_Exiv2_DataSet, py_self);
44844456
}
44854457
SWIGINTERN PyObject *Exiv2_DataSet_items(Exiv2::DataSet *self,PyObject *py_self){
4486-
init_info_Exiv2_DataSet();
44874458
return items_struct(info_Exiv2_DataSet, py_self);
44884459
}
44894460
SWIGINTERN PyObject *Exiv2_DataSet___iter__(){
44904461
// Deprecated since 2025-09-11
44914462
PyErr_WarnEx(PyExc_DeprecationWarning,
44924463
"Please iterate over keys() function output", 1);
4493-
init_info_Exiv2_DataSet();
44944464
PyObject* seq = keys_struct(info_Exiv2_DataSet);
44954465
PyObject* result = PySeqIter_New(seq);
44964466
Py_DECREF(seq);
@@ -4794,6 +4764,25 @@ static PyObject* pointer_to_list(Exiv2::DataSet* ptr) {
47944764
return list;
47954765
};
47964766

4767+
4768+
static void init_struct_info(struct_info& info, swig_type_info* type) {
4769+
PyGetSetDef* getset =
4770+
((SwigPyClientData*)type->clientdata)->pytype->tp_getset;
4771+
while (getset->name) {
4772+
// __dict__ is also in the getset list
4773+
if (getset->name[0] != '_') {
4774+
info.members.push_back(getset->name);
4775+
std::string alias = getset->name;
4776+
if (alias.back() == '_') {
4777+
alias.pop_back();
4778+
info.aliased = true;
4779+
}
4780+
info.aliases.push_back(alias);
4781+
}
4782+
getset++;
4783+
}
4784+
};
4785+
47974786
#ifdef __cplusplus
47984787
extern "C" {
47994788
#endif
@@ -7956,6 +7945,14 @@ SWIG_init(void) {
79567945
PyModule_AddObject(m, "IptcKey", (PyObject *)builtin_pytype);
79577946
SwigPyBuiltin_AddPublicSymbol(public_interface, "IptcKey");
79587947
d = md;
7948+
7949+
init_struct_info(info_Exiv2_DataSet, SWIGTYPE_p_Exiv2__DataSet);
7950+
if (info_Exiv2_DataSet.aliases.empty()) {
7951+
PyErr_SetString(
7952+
PyExc_RuntimeError, "Failed to initialise Exiv2::DataSet info");
7953+
return INIT_ERROR_RETURN;
7954+
}
7955+
79597956
#if PY_VERSION_HEX >= 0x03000000
79607957
return m;
79617958
#else

src/swig-0_27_7/preview_wrap.cxx

Lines changed: 27 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -5447,31 +5447,7 @@ typedef struct {
54475447
} struct_info;
54485448

54495449

5450-
static void init_struct_info(struct_info& info, swig_type_info* type) {
5451-
if (!info.members.empty())
5452-
return;
5453-
PyGetSetDef* getset =
5454-
((SwigPyClientData*)type->clientdata)->pytype->tp_getset;
5455-
while (getset->name) {
5456-
// __dict__ is also in the getset list
5457-
if (getset->name[0] != '_') {
5458-
info.members.push_back(getset->name);
5459-
std::string alias = getset->name;
5460-
if (alias.back() == '_') {
5461-
alias.pop_back();
5462-
info.aliased = true;
5463-
}
5464-
info.aliases.push_back(alias);
5465-
}
5466-
getset++;
5467-
}
5468-
};
5469-
5470-
54715450
static struct_info info_Exiv2_PreviewProperties;
5472-
static void init_info_Exiv2_PreviewProperties() {
5473-
init_struct_info(info_Exiv2_PreviewProperties, SWIGTYPE_p_Exiv2__PreviewProperties);
5474-
};
54755451

54765452

54775453
static PyObject* get_attr_struct(struct_info& info, bool as_item,
@@ -5489,14 +5465,12 @@ static PyObject* get_attr_struct(struct_info& info, bool as_item,
54895465

54905466
static PyObject* get_item_Exiv2_PreviewProperties(PyObject* obj,
54915467
PyObject* key) {
5492-
init_info_Exiv2_PreviewProperties();
54935468
return get_attr_struct(info_Exiv2_PreviewProperties, true, obj, key);
54945469
};
54955470

54965471

54975472
static PyObject* get_attr_Exiv2_PreviewProperties(PyObject* obj,
54985473
PyObject* name) {
5499-
init_info_Exiv2_PreviewProperties();
55005474
return get_attr_struct(info_Exiv2_PreviewProperties, false, obj, name);
55015475
};
55025476

@@ -5550,22 +5524,18 @@ SWIGINTERNINLINE PyObject*
55505524
}
55515525

55525526
SWIGINTERN PyObject *Exiv2_PreviewProperties_keys(){
5553-
init_info_Exiv2_PreviewProperties();
55545527
return keys_struct(info_Exiv2_PreviewProperties);
55555528
}
55565529
SWIGINTERN PyObject *Exiv2_PreviewProperties_values(Exiv2::PreviewProperties *self,PyObject *py_self){
5557-
init_info_Exiv2_PreviewProperties();
55585530
return values_struct(info_Exiv2_PreviewProperties, py_self);
55595531
}
55605532
SWIGINTERN PyObject *Exiv2_PreviewProperties_items(Exiv2::PreviewProperties *self,PyObject *py_self){
5561-
init_info_Exiv2_PreviewProperties();
55625533
return items_struct(info_Exiv2_PreviewProperties, py_self);
55635534
}
55645535
SWIGINTERN PyObject *Exiv2_PreviewProperties___iter__(){
55655536
// Deprecated since 2025-09-11
55665537
PyErr_WarnEx(PyExc_DeprecationWarning,
55675538
"Please iterate over keys() function output", 1);
5568-
init_info_Exiv2_PreviewProperties();
55695539
PyObject* seq = keys_struct(info_Exiv2_PreviewProperties);
55705540
PyObject* result = PySeqIter_New(seq);
55715541
Py_DECREF(seq);
@@ -5918,6 +5888,25 @@ namespace swig {
59185888
};
59195889
}
59205890

5891+
5892+
static void init_struct_info(struct_info& info, swig_type_info* type) {
5893+
PyGetSetDef* getset =
5894+
((SwigPyClientData*)type->clientdata)->pytype->tp_getset;
5895+
while (getset->name) {
5896+
// __dict__ is also in the getset list
5897+
if (getset->name[0] != '_') {
5898+
info.members.push_back(getset->name);
5899+
std::string alias = getset->name;
5900+
if (alias.back() == '_') {
5901+
alias.pop_back();
5902+
info.aliased = true;
5903+
}
5904+
info.aliases.push_back(alias);
5905+
}
5906+
getset++;
5907+
}
5908+
};
5909+
59215910
#ifdef __cplusplus
59225911
extern "C" {
59235912
#endif
@@ -8831,6 +8820,14 @@ SWIG_init(void) {
88318820
PyModule_AddObject(m, "PreviewManager", (PyObject *)builtin_pytype);
88328821
SwigPyBuiltin_AddPublicSymbol(public_interface, "PreviewManager");
88338822
d = md;
8823+
8824+
init_struct_info(info_Exiv2_PreviewProperties, SWIGTYPE_p_Exiv2__PreviewProperties);
8825+
if (info_Exiv2_PreviewProperties.aliases.empty()) {
8826+
PyErr_SetString(
8827+
PyExc_RuntimeError, "Failed to initialise Exiv2::PreviewProperties info");
8828+
return INIT_ERROR_RETURN;
8829+
}
8830+
88348831
#if PY_VERSION_HEX >= 0x03000000
88358832
return m;
88368833
#else

0 commit comments

Comments
 (0)