Skip to content

Commit ffd568e

Browse files
Deprecate many BasicIo methods
I believe these methods are only useful to exiv2 internals and should not be called by user programs.
1 parent bf76499 commit ffd568e

6 files changed

Lines changed: 216 additions & 282 deletions

File tree

CHANGELOG.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ Changes in v0.18.0:
2424
3/ Exiv2 struct member names with a trailing underscore have more Pythonic
2525
aliases without the underscore.
2626
4/ Add data() method to exiv2.PreviewImage, deprecate pData() method.
27+
5/ Deprecated many BasicIo methods (read, write, seek, etc.) that should not
28+
be needed in Python scripts. Let me know if this is a problem.
2729

2830
Changes in v0.17.3:
2931
1/ Binary wheels incorporate libexiv2 v0.28.5.

src/interface/basicio.i

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,19 @@ WINDOWS_PATH(const std::string& orgPath)
7272
WINDOWS_PATH(const std::string& url)
7373
WINDOWS_PATH_OUT(path)
7474

75+
// Deprecate methods that Python should not be calling
76+
// Deprecated since 2025-07-09
77+
DEPRECATE_FUNCTION(Exiv2::BasicIo::eof,)
78+
DEPRECATE_FUNCTION(Exiv2::BasicIo::getb,)
79+
DEPRECATE_FUNCTION(Exiv2::BasicIo::putb,)
80+
DEPRECATE_FUNCTION(Exiv2::BasicIo::read,)
81+
DEPRECATE_FUNCTION(Exiv2::BasicIo::readOrThrow,)
82+
DEPRECATE_FUNCTION(Exiv2::BasicIo::seek,)
83+
DEPRECATE_FUNCTION(Exiv2::BasicIo::seekOrThrow,)
84+
DEPRECATE_FUNCTION(Exiv2::BasicIo::tell,)
85+
DEPRECATE_FUNCTION(Exiv2::BasicIo::transfer,)
86+
DEPRECATE_FUNCTION(Exiv2::BasicIo::write,)
87+
7588
// Add method to get the subclass type
7689
%feature("docstring") Exiv2::BasicIo::ioType "Return the derived class type.
7790
@@ -155,6 +168,16 @@ RETURN_VIEW(Exiv2::byte* mmap, $1 ? arg1->size() : 0,
155168
RETURN_VIEW_CB(Exiv2::byte* data, $1 ? arg1->size() : 0,
156169
_global_writeable ? PyBUF_WRITE : PyBUF_READ,
157170
PyObject_GetAttrString(self, "_release"),)
171+
%feature("docstring") Exiv2::BasicIo::data
172+
"Easy access to the IO data.
173+
174+
Calls open() and mmap() and returns a Python memoryview of the data.
175+
munmap() and close() are called when the memoryview object is deleted.
176+
177+
:type isWriteable: bool, optional
178+
:param isWriteable: Set to true if the mapped area should be writeable
179+
(default is false).
180+
:rtype: memoryview"
158181
%extend Exiv2::BasicIo {
159182
Exiv2::byte* data(bool isWriteable) {
160183
self->open();

src/interface/shared/exception.i

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,3 +80,24 @@ fail:
8080
}
8181
}
8282
%enddef // EXCEPTION
83+
84+
// Macro to deprecate a function
85+
%define DEPRECATE_FUNCTION(method, message)
86+
%fragment("_set_python_exception");
87+
%feature("docstring") method "Deprecated."
88+
%exception method {
89+
#if #message != ""
90+
PyErr_WarnEx(PyExc_DeprecationWarning, message, 1);
91+
#else
92+
PyErr_WarnEx(PyExc_DeprecationWarning,
93+
"Python scripts should not need to call " #method, 1);
94+
#endif
95+
try {
96+
$action
97+
}
98+
catch(std::exception const& e) {
99+
_set_python_exception();
100+
SWIG_fail;
101+
}
102+
}
103+
%enddef // DEPRECATE_FUNCTION

src/swig-0_27_7/basicio_wrap.cxx

Lines changed: 58 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -5024,6 +5024,9 @@ SWIGINTERN PyObject *_wrap_BasicIo_write__SWIG_0(PyObject *self, PyObject *args)
50245024
arg3 = (long) buff->len;
50255025
}
50265026
{
5027+
PyErr_WarnEx(PyExc_DeprecationWarning,
5028+
"Python scripts should not need to call ""Exiv2::BasicIo::write", 1);
5029+
50275030
try {
50285031
{
50295032
SWIG_PYTHON_THREAD_BEGIN_ALLOW;
@@ -5078,6 +5081,9 @@ SWIGINTERN PyObject *_wrap_BasicIo_write__SWIG_1(PyObject *self, PyObject *args)
50785081
}
50795082
arg2 = reinterpret_cast< Exiv2::BasicIo * >(argp2);
50805083
{
5084+
PyErr_WarnEx(PyExc_DeprecationWarning,
5085+
"Python scripts should not need to call ""Exiv2::BasicIo::write", 1);
5086+
50815087
try {
50825088
{
50835089
SWIG_PYTHON_THREAD_BEGIN_ALLOW;
@@ -5165,6 +5171,9 @@ SWIGINTERN PyObject *_wrap_BasicIo_putb(PyObject *self, PyObject *args) {
51655171
}
51665172
arg2 = static_cast< Exiv2::byte >(val2);
51675173
{
5174+
PyErr_WarnEx(PyExc_DeprecationWarning,
5175+
"Python scripts should not need to call ""Exiv2::BasicIo::putb", 1);
5176+
51685177
try {
51695178
result = (int)(arg1)->putb(arg2);
51705179
}
@@ -5203,6 +5212,9 @@ SWIGINTERN PyObject *_wrap_BasicIo_read__SWIG_0(PyObject *self, PyObject *args)
52035212
}
52045213
arg2 = static_cast< long >(val2);
52055214
{
5215+
PyErr_WarnEx(PyExc_DeprecationWarning,
5216+
"Python scripts should not need to call ""Exiv2::BasicIo::read", 1);
5217+
52065218
try {
52075219
{
52085220
SWIG_PYTHON_THREAD_BEGIN_ALLOW;
@@ -5267,6 +5279,9 @@ SWIGINTERN PyObject *_wrap_BasicIo_read__SWIG_1(PyObject *self, PyObject *args)
52675279
}
52685280
}
52695281
{
5282+
PyErr_WarnEx(PyExc_DeprecationWarning,
5283+
"Python scripts should not need to call ""Exiv2::BasicIo::read", 1);
5284+
52705285
try {
52715286
{
52725287
SWIG_PYTHON_THREAD_BEGIN_ALLOW;
@@ -5345,6 +5360,9 @@ SWIGINTERN PyObject *_wrap_BasicIo_getb(PyObject *self, PyObject *args) {
53455360
}
53465361
arg1 = reinterpret_cast< Exiv2::BasicIo * >(argp1);
53475362
{
5363+
PyErr_WarnEx(PyExc_DeprecationWarning,
5364+
"Python scripts should not need to call ""Exiv2::BasicIo::getb", 1);
5365+
53485366
try {
53495367
result = (int)(arg1)->getb();
53505368
}
@@ -5385,6 +5403,9 @@ SWIGINTERN PyObject *_wrap_BasicIo_transfer(PyObject *self, PyObject *args) {
53855403
}
53865404
arg2 = reinterpret_cast< Exiv2::BasicIo * >(argp2);
53875405
{
5406+
PyErr_WarnEx(PyExc_DeprecationWarning,
5407+
"Python scripts should not need to call ""Exiv2::BasicIo::transfer", 1);
5408+
53885409
try {
53895410
{
53905411
SWIG_PYTHON_THREAD_BEGIN_ALLOW;
@@ -5442,6 +5463,9 @@ SWIGINTERN PyObject *_wrap_BasicIo_seek(PyObject *self, PyObject *args) {
54425463
arg3 = static_cast< Exiv2::BasicIo::Position >(PyLong_AsLong(obj2));
54435464
}
54445465
{
5466+
PyErr_WarnEx(PyExc_DeprecationWarning,
5467+
"Python scripts should not need to call ""Exiv2::BasicIo::seek", 1);
5468+
54455469
try {
54465470
{
54475471
SWIG_PYTHON_THREAD_BEGIN_ALLOW;
@@ -5570,6 +5594,9 @@ SWIGINTERN PyObject *_wrap_BasicIo_tell(PyObject *self, PyObject *args) {
55705594
}
55715595
arg1 = reinterpret_cast< Exiv2::BasicIo * >(argp1);
55725596
{
5597+
PyErr_WarnEx(PyExc_DeprecationWarning,
5598+
"Python scripts should not need to call ""Exiv2::BasicIo::tell", 1);
5599+
55735600
try {
55745601
result = (long)((Exiv2::BasicIo const *)arg1)->tell();
55755602
}
@@ -5669,7 +5696,18 @@ SWIGINTERN PyObject *_wrap_BasicIo_eof(PyObject *self, PyObject *args) {
56695696
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "BasicIo_eof" "', argument " "1"" of type '" "Exiv2::BasicIo const *""'");
56705697
}
56715698
arg1 = reinterpret_cast< Exiv2::BasicIo * >(argp1);
5672-
result = (bool)((Exiv2::BasicIo const *)arg1)->eof();
5699+
{
5700+
PyErr_WarnEx(PyExc_DeprecationWarning,
5701+
"Python scripts should not need to call ""Exiv2::BasicIo::eof", 1);
5702+
5703+
try {
5704+
result = (bool)((Exiv2::BasicIo const *)arg1)->eof();
5705+
}
5706+
catch(std::exception const& e) {
5707+
_set_python_exception();
5708+
SWIG_fail;
5709+
}
5710+
}
56735711
resultobj = SWIG_From_bool(static_cast< bool >(result));
56745712
return resultobj;
56755713
fail:
@@ -5883,113 +5921,12 @@ SWIGINTERN PyMethodDef SwigPyBuiltin__Exiv2__BasicIo_methods[] = {
58835921
"\n"
58845922
" Nonzero if failure.\n"
58855923
"" },
5886-
{ "write", _wrap_BasicIo_write, METH_VARARGS, "\n"
5887-
"*Overload 1:*\n"
5888-
"\n"
5889-
"Write data to the IO source. Current IO position is advanced\n"
5890-
" by the number of bytes written.\n"
5891-
":type data: :py:term:`bytes-like object`\n"
5892-
":param data: Pointer to data. Data must be at least *wcount*\n"
5893-
" bytes long\n"
5894-
":type wcount: int\n"
5895-
":param wcount: Number of bytes to be written.\n"
5896-
":rtype: int\n"
5897-
":return: Number of bytes written to IO source successfully;\n"
5898-
"\n"
5899-
" 0 if failure;\n"
5900-
"\n"
5901-
"|\n"
5902-
"\n"
5903-
"*Overload 2:*\n"
5904-
"\n"
5905-
"Write data that is read from another BasicIo instance to\n"
5906-
" the IO source. Current IO position is advanced by the number\n"
5907-
" of bytes written.\n"
5908-
":type src: :py:class:`BasicIo`\n"
5909-
":param src: Reference to another BasicIo instance. Reading start\n"
5910-
" at the source's current IO position\n"
5911-
":rtype: int\n"
5912-
":return: Number of bytes written to IO source successfully;\n"
5913-
"\n"
5914-
" 0 if failure;\n"
5915-
"" },
5916-
{ "putb", _wrap_BasicIo_putb, METH_VARARGS, "\n"
5917-
"Write one byte to the IO source. Current IO position is\n"
5918-
" advanced by one byte.\n"
5919-
":type data: int\n"
5920-
":param data: The single byte to be written.\n"
5921-
":rtype: int\n"
5922-
":return: The value of the byte written if successful;\n"
5923-
"\n"
5924-
" EOF if failure;\n"
5925-
"" },
5926-
{ "read", _wrap_BasicIo_read, METH_VARARGS, "\n"
5927-
"*Overload 1:*\n"
5928-
"\n"
5929-
"Read data from the IO source. Reading starts at the current\n"
5930-
" IO position and the position is advanced by the number of bytes\n"
5931-
" read.\n"
5932-
":type rcount: int\n"
5933-
":param rcount: Maximum number of bytes to read. Fewer bytes may be\n"
5934-
" read if *rcount* bytes are not available.\n"
5935-
":rtype: :py:class:`DataBuf`\n"
5936-
":return: DataBuf instance containing the bytes read. Use the\n"
5937-
" DataBuf::size_ member to find the number of bytes read.\n"
5938-
" DataBuf::size_ will be 0 on failure.\n"
5939-
"\n"
5940-
"|\n"
5941-
"\n"
5942-
"*Overload 2:*\n"
5943-
"\n"
5944-
"Read data from the IO source. Reading starts at the current\n"
5945-
" IO position and the position is advanced by the number of bytes\n"
5946-
" read.\n"
5947-
":type buf: writeable :py:term:`bytes-like object`\n"
5948-
":param buf: Pointer to a block of memory into which the read data\n"
5949-
" is stored. The memory block must be at least *rcount* bytes\n"
5950-
" long.\n"
5951-
":type rcount: int\n"
5952-
":param rcount: Maximum number of bytes to read. Fewer bytes may be\n"
5953-
" read if *rcount* bytes are not available.\n"
5954-
":rtype: int\n"
5955-
":return: Number of bytes read from IO source successfully;\n"
5956-
"\n"
5957-
" 0 if failure;\n"
5958-
"" },
5959-
{ "getb", _wrap_BasicIo_getb, METH_VARARGS, "\n"
5960-
"Read one byte from the IO source. Current IO position is\n"
5961-
" advanced by one byte.\n"
5962-
":rtype: int\n"
5963-
":return: The byte read from the IO source if successful;\n"
5964-
"\n"
5965-
" EOF if failure;\n"
5966-
"" },
5967-
{ "transfer", _wrap_BasicIo_transfer, METH_VARARGS, "\n"
5968-
"Remove all data from this object's IO source and then transfer\n"
5969-
" data from the *src* BasicIo object into this object.\n"
5970-
"\n"
5971-
"The source object is invalidated by this operation and should not be\n"
5972-
"used after this method returns. This method exists primarily to\n"
5973-
"be used with the BasicIo::temporary() method.\n"
5974-
"\n"
5975-
":type src: :py:class:`BasicIo`\n"
5976-
":param src: Reference to another BasicIo instance. The entire contents\n"
5977-
" of src are transferred to this object. The *src* object is\n"
5978-
" invalidated by the method.\n"
5979-
":raises: Error In case of failure\n"
5980-
"" },
5981-
{ "seek", _wrap_BasicIo_seek, METH_VARARGS, "\n"
5982-
"Move the current IO position.\n"
5983-
":type offset: int\n"
5984-
":param offset: Number of bytes to move the position relative\n"
5985-
" to the starting position specified by *pos*\n"
5986-
":type pos: :py:class:`BasicIo.Position`\n"
5987-
":param pos: Position from which the seek should start\n"
5988-
":rtype: int\n"
5989-
":return: 0 if successful;\n"
5990-
"\n"
5991-
" Nonzero if failure;\n"
5992-
"" },
5924+
{ "write", _wrap_BasicIo_write, METH_VARARGS, "Deprecated." },
5925+
{ "putb", _wrap_BasicIo_putb, METH_VARARGS, "Deprecated." },
5926+
{ "read", _wrap_BasicIo_read, METH_VARARGS, "Deprecated." },
5927+
{ "getb", _wrap_BasicIo_getb, METH_VARARGS, "Deprecated." },
5928+
{ "transfer", _wrap_BasicIo_transfer, METH_VARARGS, "Deprecated." },
5929+
{ "seek", _wrap_BasicIo_seek, METH_VARARGS, "Deprecated." },
59935930
{ "mmap", _wrap_BasicIo_mmap, METH_VARARGS, "\n"
59945931
"Direct access to the IO data. For files, this is done by\n"
59955932
" mapping the file into the process's address space; for memory\n"
@@ -6009,13 +5946,7 @@ SWIGINTERN PyMethodDef SwigPyBuiltin__Exiv2__BasicIo_methods[] = {
60095946
"\n"
60105947
" Nonzero if failure;\n"
60115948
"" },
6012-
{ "tell", _wrap_BasicIo_tell, METH_VARARGS, "\n"
6013-
"Get the current IO position.\n"
6014-
":rtype: int\n"
6015-
":return: Offset from the start of IO if successful;\n"
6016-
"\n"
6017-
" -1 if failure;\n"
6018-
"" },
5949+
{ "tell", _wrap_BasicIo_tell, METH_VARARGS, "Deprecated." },
60195950
{ "size", _wrap_BasicIo_size, METH_VARARGS, "\n"
60205951
"Get the current size of the IO source in bytes.\n"
60215952
":rtype: int\n"
@@ -6025,7 +5956,7 @@ SWIGINTERN PyMethodDef SwigPyBuiltin__Exiv2__BasicIo_methods[] = {
60255956
"" },
60265957
{ "isopen", _wrap_BasicIo_isopen, METH_VARARGS, "Returns true if the IO source is open, otherwise false." },
60275958
{ "error", _wrap_BasicIo_error, METH_VARARGS, "Returns 0 if the IO source is in a valid state, otherwise nonzero." },
6028-
{ "eof", _wrap_BasicIo_eof, METH_VARARGS, "Returns true if the IO position has reached the end, otherwise false." },
5959+
{ "eof", _wrap_BasicIo_eof, METH_VARARGS, "Deprecated." },
60295960
{ "path", _wrap_BasicIo_path, METH_VARARGS, "\n"
60305961
"Return the path to the IO resource. Often used to form\n"
60315962
" comprehensive error messages where only a BasicIo instance is\n"
@@ -6039,7 +5970,17 @@ SWIGINTERN PyMethodDef SwigPyBuiltin__Exiv2__BasicIo_methods[] = {
60395970
":rtype: str\n"
60405971
":return: A class name such as \"FileIo\".\n"
60415972
"" },
6042-
{ "data", _wrap_BasicIo_data, METH_VARARGS, "" },
5973+
{ "data", _wrap_BasicIo_data, METH_VARARGS, "\n"
5974+
"Easy access to the IO data.\n"
5975+
"\n"
5976+
"Calls open() and mmap() and returns a Python memoryview of the data.\n"
5977+
"munmap() and close() are called when the memoryview object is deleted.\n"
5978+
"\n"
5979+
":type isWriteable: bool, optional\n"
5980+
":param isWriteable: Set to true if the mapped area should be writeable\n"
5981+
" (default is false).\n"
5982+
":rtype: memoryview\n"
5983+
"" },
60435984
{ "_release", _wrap_BasicIo__release, METH_VARARGS, "" },
60445985
{ NULL, NULL, 0, NULL } /* Sentinel */
60455986
};

0 commit comments

Comments
 (0)