Skip to content

Commit 44b224a

Browse files
Add 'mutable' option to STRUCT_DICT macro
If the struct members are immutable then it doesn't need a __setitem__ function.
1 parent b6fcdf7 commit 44b224a

File tree

16 files changed

+46
-881
lines changed

16 files changed

+46
-881
lines changed

CHANGELOG.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ Changes in v0.18.0:
2020
1/ Removed features deprecated in v0.13.0:
2121
Value (and derived types) copy constructors
2222
Single value (such as DateValue) index methods
23+
2/ Added binary wheels for Linux on arm64.
2324

2425
Changes in v0.17.3:
2526
1/ Binary wheels incorporate libexiv2 v0.28.5.

src/interface/datasets.i

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// python-exiv2 - Python interface to libexiv2
22
// http://github.com/jim-easterbrook/python-exiv2
3-
// Copyright (C) 2021-24 Jim Easterbrook [email protected]
3+
// Copyright (C) 2021-25 Jim Easterbrook [email protected]
44
//
55
// This program is free software: you can redistribute it and/or modify
66
// it under the terms of the GNU General Public License as published by
@@ -46,7 +46,7 @@ EXTEND_KEY(Exiv2::IptcKey);
4646
LIST_POINTER(const Exiv2::DataSet*, Exiv2::DataSet, number_ != 0xffff)
4747

4848
// Give Exiv2::DataSet dict-like behaviour
49-
STRUCT_DICT(Exiv2::DataSet)
49+
STRUCT_DICT(Exiv2::DataSet, false)
5050

5151
// Structs are all static data
5252
%ignore Exiv2::IptcDataSets::IptcDataSets;

src/interface/preview.i

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// python-exiv2 - Python interface to libexiv2
22
// http://github.com/jim-easterbrook/python-exiv2
3-
// Copyright (C) 2021-24 Jim Easterbrook [email protected]
3+
// Copyright (C) 2021-25 Jim Easterbrook [email protected]
44
//
55
// This program is free software: you can redistribute it and/or modify
66
// it under the terms of the GNU General Public License as published by
@@ -93,7 +93,7 @@ RETURN_VIEW(Exiv2::byte* pData, arg1->size(), PyBUF_READ,
9393
Exiv2::PreviewImage::pData)
9494

9595
// Give Exiv2::PreviewProperties dict-like behaviour
96-
STRUCT_DICT(Exiv2::PreviewProperties)
96+
STRUCT_DICT(Exiv2::PreviewProperties, false)
9797

9898
%immutable Exiv2::PreviewProperties::mimeType_;
9999
%immutable Exiv2::PreviewProperties::extension_;

src/interface/properties.i

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// python-exiv2 - Python interface to libexiv2
22
// http://github.com/jim-easterbrook/python-exiv2
3-
// Copyright (C) 2021-24 Jim Easterbrook [email protected]
3+
// Copyright (C) 2021-25 Jim Easterbrook [email protected]
44
//
55
// This program is free software: you can redistribute it and/or modify
66
// it under the terms of the GNU General Public License as published by
@@ -83,10 +83,10 @@ LIST_POINTER(const Exiv2::XmpPropertyInfo* xmpPropertyInfo_,
8383
Exiv2::XmpPropertyInfo, name_)
8484

8585
// Give Exiv2::XmpPropertyInfo dict-like behaviour
86-
STRUCT_DICT(Exiv2::XmpPropertyInfo)
86+
STRUCT_DICT(Exiv2::XmpPropertyInfo, false)
8787

8888
// Give Exiv2::XmpNsInfo dict-like behaviour
89-
STRUCT_DICT(Exiv2::XmpNsInfo)
89+
STRUCT_DICT(Exiv2::XmpNsInfo, false)
9090

9191
// Structs are all static data
9292
%ignore Exiv2::XmpPropertyInfo::XmpPropertyInfo;

src/interface/shared/struct_dict.i

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,14 +69,12 @@ static PyObject* getset_to_value(PyObject* obj, PyGetSetDef* getset) {
6969
}
7070

7171
// Macro definition
72-
%define STRUCT_DICT(struct_type)
72+
%define STRUCT_DICT(struct_type, mutable)
7373
// Type slots
7474
%feature("python:slot", "tp_iter", functype="getiterfunc")
7575
struct_type::__iter__;
7676
%feature("python:slot", "mp_subscript", functype="binaryfunc")
7777
struct_type::__getitem__;
78-
%feature("python:slot", "mp_ass_subscript", functype="objobjargproc")
79-
struct_type::__setitem__;
8078
// Typemaps for slot functions
8179
%typemap(in, numinputs=0) PyObject* py_self {$1 = self;}
8280
%typemap(default) PyObject* value {$1 = NULL;}
@@ -117,6 +115,11 @@ static PyObject* getset_to_value(PyObject* obj, PyGetSetDef* getset) {
117115
return NULL;
118116
return getset->get(py_self, getset->closure);
119117
}
118+
}
119+
#if #mutable == "true"
120+
%feature("python:slot", "mp_ass_subscript", functype="objobjargproc")
121+
struct_type::__setitem__;
122+
%extend struct_type {
120123
PyObject* __setitem__(PyObject* py_self, const std::string& key,
121124
PyObject* value) {
122125
PyGetSetDef* getset = find_getset(py_self, key.c_str());
@@ -134,4 +137,5 @@ static PyObject* getset_to_value(PyObject* obj, PyGetSetDef* getset) {
134137
return SWIG_Py_Void();
135138
}
136139
}
140+
#endif // mutable
137141
%enddef // STRUCT_DICT

src/interface/tags.i

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// python-exiv2 - Python interface to libexiv2
22
// http://github.com/jim-easterbrook/python-exiv2
3-
// Copyright (C) 2021-24 Jim Easterbrook [email protected]
3+
// Copyright (C) 2021-25 Jim Easterbrook [email protected]
44
//
55
// This program is free software: you can redistribute it and/or modify
66
// it under the terms of the GNU General Public License as published by
@@ -98,10 +98,10 @@ LIST_POINTER(const Exiv2::GroupInfo*, Exiv2::GroupInfo, tagList_)
9898
LIST_POINTER(const Exiv2::TagInfo*, Exiv2::TagInfo, tag_ != 0xFFFF)
9999

100100
// Give Exiv2::GroupInfo dict-like behaviour
101-
STRUCT_DICT(Exiv2::GroupInfo)
101+
STRUCT_DICT(Exiv2::GroupInfo, false)
102102

103103
// Give Exiv2::TagInfo dict-like behaviour
104-
STRUCT_DICT(Exiv2::TagInfo)
104+
STRUCT_DICT(Exiv2::TagInfo, false)
105105

106106
// Wrapper class for TagListFct function pointer
107107
#ifndef SWIGIMPORTED

src/interface/value.i

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -334,8 +334,8 @@ VALUE_SUBCLASS(Exiv2::ValueType<item_type>, type_name)
334334
%enddef // VALUETYPE
335335

336336
// Give Date and Time structs some dict-like behaviour
337-
STRUCT_DICT(Exiv2::DateValue::Date)
338-
STRUCT_DICT(Exiv2::TimeValue::Time)
337+
STRUCT_DICT(Exiv2::DateValue::Date, true)
338+
STRUCT_DICT(Exiv2::TimeValue::Time, true)
339339

340340
%extend Exiv2::DateValue {
341341
// Allow DateValue to be constructed from a Date

src/swig-0_27_7/datasets_wrap.cxx

Lines changed: 2 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -4604,21 +4604,6 @@ SWIGINTERN PyObject *Exiv2_DataSet___getitem__(Exiv2::DataSet *self,PyObject *py
46044604
return NULL;
46054605
return getset->get(py_self, getset->closure);
46064606
}
4607-
SWIGINTERN PyObject *Exiv2_DataSet___setitem__(Exiv2::DataSet *self,PyObject *py_self,std::string const &key,PyObject *value){
4608-
PyGetSetDef* getset = find_getset(py_self, key.c_str());
4609-
if (!getset)
4610-
return NULL;
4611-
if (!value)
4612-
return PyErr_Format(PyExc_TypeError,
4613-
"%s['%s'] can not be deleted", py_self->ob_type->tp_name,
4614-
key.c_str());
4615-
if (!getset->set)
4616-
return PyErr_Format(PyExc_TypeError, "%s['%s'] is read-only",
4617-
py_self->ob_type->tp_name, key.c_str());
4618-
if (getset->set(py_self, value, getset->closure) != 0)
4619-
return NULL;
4620-
return SWIG_Py_Void();
4621-
}
46224607

46234608
#include <limits.h>
46244609
#if !defined(SWIG_NO_LLONG_MAX)
@@ -5184,58 +5169,8 @@ SWIGINTERN PyObject *_wrap_DataSet___getitem__(PyObject *self, PyObject *args) {
51845169
}
51855170

51865171

5187-
SWIGINTERN PyObject *_wrap_DataSet___setitem__(PyObject *self, PyObject *args) {
5188-
PyObject *resultobj = 0;
5189-
Exiv2::DataSet *arg1 = (Exiv2::DataSet *) 0 ;
5190-
PyObject *arg2 = (PyObject *) 0 ;
5191-
std::string *arg3 = 0 ;
5192-
PyObject *arg4 = (PyObject *) 0 ;
5193-
void *argp1 = 0 ;
5194-
int res1 = 0 ;
5195-
int res3 = SWIG_OLDOBJ ;
5196-
PyObject *swig_obj[3] ;
5197-
PyObject *result = 0 ;
5198-
5199-
{
5200-
arg4 = NULL;
5201-
}
5202-
{
5203-
arg2 = self;
5204-
}
5205-
if (!SWIG_Python_UnpackTuple(args, "DataSet___setitem__", 1, 2, swig_obj)) SWIG_fail;
5206-
res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_Exiv2__DataSet, 0 | 0 );
5207-
if (!SWIG_IsOK(res1)) {
5208-
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DataSet___setitem__" "', argument " "1"" of type '" "Exiv2::DataSet *""'");
5209-
}
5210-
arg1 = reinterpret_cast< Exiv2::DataSet * >(argp1);
5211-
{
5212-
std::string *ptr = (std::string *)0;
5213-
res3 = SWIG_AsPtr_std_string(swig_obj[0], &ptr);
5214-
if (!SWIG_IsOK(res3)) {
5215-
SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "DataSet___setitem__" "', argument " "3"" of type '" "std::string const &""'");
5216-
}
5217-
if (!ptr) {
5218-
SWIG_exception_fail(SWIG_NullReferenceError, "invalid null reference " "in method '" "DataSet___setitem__" "', argument " "3"" of type '" "std::string const &""'");
5219-
}
5220-
arg3 = ptr;
5221-
}
5222-
if (swig_obj[1]) {
5223-
arg4 = swig_obj[1];
5224-
}
5225-
result = (PyObject *)Exiv2_DataSet___setitem__(arg1,arg2,(std::string const &)*arg3,arg4);
5226-
resultobj = result;
5227-
if (SWIG_IsNewObj(res3)) delete arg3;
5228-
return resultobj;
5229-
fail:
5230-
if (SWIG_IsNewObj(res3)) delete arg3;
5231-
return NULL;
5232-
}
5233-
5234-
52355172
SWIGPY_GETITERFUNC_CLOSURE(_wrap_DataSet___iter__) /* defines _wrap_DataSet___iter___getiterfunc_closure */
52365173

5237-
SWIGPY_OBJOBJARGPROC_CLOSURE(_wrap_DataSet___setitem__) /* defines _wrap_DataSet___setitem___objobjargproc_closure */
5238-
52395174
SWIGINTERN PyObject *_wrap_IptcDataSets_dataSetName(PyObject *self, PyObject *args) {
52405175
PyObject *resultobj = 0;
52415176
uint16_t arg1 ;
@@ -5997,7 +5932,6 @@ SWIGINTERN PyMethodDef SwigPyBuiltin__Exiv2__DataSet_methods[] = {
59975932
"" },
59985933
{ "__iter__", _wrap_DataSet___iter__, METH_NOARGS, "" },
59995934
{ "__getitem__", _wrap_DataSet___getitem__, METH_O, "" },
6000-
{ "__setitem__", _wrap_DataSet___setitem__, METH_VARARGS, "" },
60015935
{ NULL, NULL, 0, NULL } /* Sentinel */
60025936
};
60035937

@@ -6161,7 +6095,7 @@ static PyHeapTypeObject SwigPyBuiltin__Exiv2__DataSet_type = {
61616095
{
61626096
(lenfunc) 0, /* mp_length */
61636097
_wrap_DataSet___getitem__, /* mp_subscript */
6164-
_wrap_DataSet___setitem___objobjargproc_closure, /* mp_ass_subscript */
6098+
(objobjargproc) 0, /* mp_ass_subscript */
61656099
},
61666100
{
61676101
(lenfunc) 0, /* sq_length */
@@ -6262,7 +6196,7 @@ static PyTypeObject *SwigPyBuiltin__Exiv2__DataSet_type_create(PyTypeObject *typ
62626196
{ Py_tp_descr_set, (void *)(descrsetfunc) 0 },
62636197
{ Py_mp_length, (void *)(lenfunc) 0 },
62646198
{ Py_mp_subscript, (void *)_wrap_DataSet___getitem__ },
6265-
{ Py_mp_ass_subscript, (void *)_wrap_DataSet___setitem___objobjargproc_closure },
6199+
{ Py_mp_ass_subscript, (void *)(objobjargproc) 0 },
62666200
{ Py_tp_iter, (void *)_wrap_DataSet___iter___getiterfunc_closure },
62676201
{ Py_tp_iternext, (void *)(iternextfunc) 0 },
62686202
{ Py_nb_add, (void *)(binaryfunc) 0 },

src/swig-0_27_7/preview_wrap.cxx

Lines changed: 2 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -5661,21 +5661,6 @@ SWIGINTERN PyObject *Exiv2_PreviewProperties___getitem__(Exiv2::PreviewPropertie
56615661
return NULL;
56625662
return getset->get(py_self, getset->closure);
56635663
}
5664-
SWIGINTERN PyObject *Exiv2_PreviewProperties___setitem__(Exiv2::PreviewProperties *self,PyObject *py_self,std::string const &key,PyObject *value){
5665-
PyGetSetDef* getset = find_getset(py_self, key.c_str());
5666-
if (!getset)
5667-
return NULL;
5668-
if (!value)
5669-
return PyErr_Format(PyExc_TypeError,
5670-
"%s['%s'] can not be deleted", py_self->ob_type->tp_name,
5671-
key.c_str());
5672-
if (!getset->set)
5673-
return PyErr_Format(PyExc_TypeError, "%s['%s'] is read-only",
5674-
py_self->ob_type->tp_name, key.c_str());
5675-
if (getset->set(py_self, value, getset->closure) != 0)
5676-
return NULL;
5677-
return SWIG_Py_Void();
5678-
}
56795664

56805665
#define SWIG_From_long PyInt_FromLong
56815666

@@ -6186,62 +6171,6 @@ SWIGINTERN PyObject *_wrap_PreviewProperties___getitem__(PyObject *self, PyObjec
61866171
}
61876172

61886173

6189-
SWIGINTERN PyObject *_wrap_PreviewProperties___setitem__(PyObject *self, PyObject *args) {
6190-
PyObject *resultobj = 0;
6191-
Exiv2::PreviewProperties *arg1 = (Exiv2::PreviewProperties *) 0 ;
6192-
PyObject *arg2 = (PyObject *) 0 ;
6193-
std::string *arg3 = 0 ;
6194-
PyObject *arg4 = (PyObject *) 0 ;
6195-
void *argp1 = 0 ;
6196-
int res1 = 0 ;
6197-
int res3 = SWIG_OLDOBJ ;
6198-
PyObject *swig_obj[3] ;
6199-
PyObject *result = 0 ;
6200-
6201-
{
6202-
arg4 = NULL;
6203-
}
6204-
{
6205-
arg2 = self;
6206-
}
6207-
if (!SWIG_Python_UnpackTuple(args, "PreviewProperties___setitem__", 1, 2, swig_obj)) SWIG_fail;
6208-
res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_Exiv2__PreviewProperties, 0 | 0 );
6209-
if (!SWIG_IsOK(res1)) {
6210-
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "PreviewProperties___setitem__" "', argument " "1"" of type '" "Exiv2::PreviewProperties *""'");
6211-
}
6212-
arg1 = reinterpret_cast< Exiv2::PreviewProperties * >(argp1);
6213-
{
6214-
std::string *ptr = (std::string *)0;
6215-
res3 = SWIG_AsPtr_std_string(swig_obj[0], &ptr);
6216-
if (!SWIG_IsOK(res3)) {
6217-
SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "PreviewProperties___setitem__" "', argument " "3"" of type '" "std::string const &""'");
6218-
}
6219-
if (!ptr) {
6220-
SWIG_exception_fail(SWIG_NullReferenceError, "invalid null reference " "in method '" "PreviewProperties___setitem__" "', argument " "3"" of type '" "std::string const &""'");
6221-
}
6222-
arg3 = ptr;
6223-
}
6224-
if (swig_obj[1]) {
6225-
arg4 = swig_obj[1];
6226-
}
6227-
{
6228-
try {
6229-
result = (PyObject *)Exiv2_PreviewProperties___setitem__(arg1,arg2,(std::string const &)*arg3,arg4);
6230-
}
6231-
catch(std::exception const& e) {
6232-
_set_python_exception();
6233-
SWIG_fail;
6234-
}
6235-
}
6236-
resultobj = result;
6237-
if (SWIG_IsNewObj(res3)) delete arg3;
6238-
return resultobj;
6239-
fail:
6240-
if (SWIG_IsNewObj(res3)) delete arg3;
6241-
return NULL;
6242-
}
6243-
6244-
62456174
SWIGINTERN PyObject *_wrap_delete_PreviewProperties(PyObject *self, PyObject *args) {
62466175
PyObject *resultobj = 0;
62476176
Exiv2::PreviewProperties *arg1 = (Exiv2::PreviewProperties *) 0 ;
@@ -6272,8 +6201,6 @@ SWIGINTERN PyObject *_wrap_delete_PreviewProperties(PyObject *self, PyObject *ar
62726201

62736202
SWIGPY_GETITERFUNC_CLOSURE(_wrap_PreviewProperties___iter__) /* defines _wrap_PreviewProperties___iter___getiterfunc_closure */
62746203

6275-
SWIGPY_OBJOBJARGPROC_CLOSURE(_wrap_PreviewProperties___setitem__) /* defines _wrap_PreviewProperties___setitem___objobjargproc_closure */
6276-
62776204
SWIGPY_DESTRUCTOR_CLOSURE(_wrap_delete_PreviewProperties) /* defines _wrap_delete_PreviewProperties_destructor_closure */
62786205

62796206
SWIGINTERN int _wrap_new_PreviewImage(PyObject *self, PyObject *args, PyObject *kwargs) {
@@ -6809,7 +6736,6 @@ SWIGINTERN PyMethodDef SwigPyBuiltin__Exiv2__PreviewProperties_methods[] = {
68096736
"" },
68106737
{ "__iter__", _wrap_PreviewProperties___iter__, METH_NOARGS, "" },
68116738
{ "__getitem__", _wrap_PreviewProperties___getitem__, METH_O, "" },
6812-
{ "__setitem__", _wrap_PreviewProperties___setitem__, METH_VARARGS, "" },
68136739
{ NULL, NULL, 0, NULL } /* Sentinel */
68146740
};
68156741

@@ -6973,7 +6899,7 @@ static PyHeapTypeObject SwigPyBuiltin__Exiv2__PreviewProperties_type = {
69736899
{
69746900
(lenfunc) 0, /* mp_length */
69756901
_wrap_PreviewProperties___getitem__, /* mp_subscript */
6976-
_wrap_PreviewProperties___setitem___objobjargproc_closure, /* mp_ass_subscript */
6902+
(objobjargproc) 0, /* mp_ass_subscript */
69776903
},
69786904
{
69796905
(lenfunc) 0, /* sq_length */
@@ -7074,7 +7000,7 @@ static PyTypeObject *SwigPyBuiltin__Exiv2__PreviewProperties_type_create(PyTypeO
70747000
{ Py_tp_descr_set, (void *)(descrsetfunc) 0 },
70757001
{ Py_mp_length, (void *)(lenfunc) 0 },
70767002
{ Py_mp_subscript, (void *)_wrap_PreviewProperties___getitem__ },
7077-
{ Py_mp_ass_subscript, (void *)_wrap_PreviewProperties___setitem___objobjargproc_closure },
7003+
{ Py_mp_ass_subscript, (void *)(objobjargproc) 0 },
70787004
{ Py_tp_iter, (void *)_wrap_PreviewProperties___iter___getiterfunc_closure },
70797005
{ Py_tp_iternext, (void *)(iternextfunc) 0 },
70807006
{ Py_nb_add, (void *)(binaryfunc) 0 },

0 commit comments

Comments
 (0)