Skip to content

Commit 790eaec

Browse files
Merge pull request #202 from jim-easterbrook/devel
Devel
2 parents a288ef5 + 38947bc commit 790eaec

43 files changed

Lines changed: 1086 additions & 1712 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/build-gphoto2-wheels.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ jobs:
2424
target: 14.0
2525
arch: arm64
2626
env:
27-
GPHOTO_SRC: https://github.com/gphoto/libgphoto2/releases/download/v2.5.33/libgphoto2-2.5.33.tar.xz
27+
GPHOTO_SRC: https://github.com/gphoto/libgphoto2/releases/download/v2.5.34/libgphoto2-2.5.34.tar.xz
2828
GPHOTO2_ROOT: libgphoto2/local_install
2929
MACOSX_DEPLOYMENT_TARGET: ${{ matrix.target }}
3030
steps:

CHANGELOG.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
python-gphoto2 - Python interface to libgphoto2
22
http://github.com/jim-easterbrook/python-gphoto2
3-
Copyright (C) 2014-25 Jim Easterbrook jim@jim-easterbrook.me.uk
3+
Copyright (C) 2014-26 Jim Easterbrook jim@jim-easterbrook.me.uk
44

55
This file is part of python-gphoto2.
66

@@ -19,6 +19,9 @@ License along with python-gphoto2. If not, see
1919
<https://www.gnu.org/licenses/>.
2020

2121

22+
Changes in 2.6.4:
23+
1/ Binary wheels include libgphoto2 v2.5.34
24+
2225
Changes in 2.6.3:
2326
1/ Binary wheels include libgphoto2 v2.5.33
2427

README.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
python-gphoto2 v\ 2.6.3
1+
python-gphoto2 v\ 2.6.4
22
=======================
33

44
python-gphoto2 is a comprehensive Python interface (or binding) to libgphoto2_.

developer/Doxyfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -506,7 +506,7 @@ HIDE_IN_BODY_DOCS = NO
506506
# will be excluded. Set it to YES to include the internal documentation.
507507
# The default value is: NO.
508508

509-
INTERNAL_DOCS = NO
509+
INTERNAL_DOCS = YES
510510

511511
# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file
512512
# names in lower-case letters. If set to YES, upper-case letters are also

developer/README.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ Using local libgphoto2
1414

1515
To build python-gphoto2 with a different version of libgphoto2 than the one installed on your system you first need to build a local copy of libgphoto2. Download and extract the libgphoto2 source, change to the source directory and then configure, build and install::
1616

17-
./configure --prefix=$PWD/local_install CFLAGS="-std=gnu99 -g -O2"
17+
./configure --prefix=$PWD/local_install --enable-vusb
1818
make
1919
make install
2020

@@ -55,6 +55,7 @@ Differences found so far::
5555
2.5.31 No change
5656
2.5.32 Add GP_MIME_MPO, GP_MIME_QTKN, GP_MIME_QTKT, and GP_MIME_RAF constants
5757
2.5.33 No change
58+
2.5.44 Add GP_MIME_DNG constant
5859

5960
Documentation
6061
-------------

pyproject.toml

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# python-gphoto2 - Python interface to libgphoto2
22
# http://github.com/jim-easterbrook/python-gphoto2
3-
# Copyright (C) 2023 Jim Easterbrook jim@jim-easterbrook.me.uk
3+
# Copyright (C) 2023-26 Jim Easterbrook jim@jim-easterbrook.me.uk
44
#
55
# This file is part of python-gphoto2.
66
#
@@ -19,19 +19,22 @@
1919
# <https://www.gnu.org/licenses/>.
2020

2121
[build-system]
22-
requires = ["setuptools >= 59.6", "toml"]
22+
requires = [
23+
"setuptools >= 59.6, < 61.0; python_version < '3.9'",
24+
"setuptools >= 77.0; python_version >= '3.9'",
25+
"toml; python_version < '3.9'"
26+
]
2327
build-backend = "setuptools.build_meta"
2428

2529
[project]
2630
name = "gphoto2"
2731
description = "Python interface to libgphoto2"
2832
readme = "README.rst"
29-
license = {text = "GNU LGPL"}
33+
license = "LGPL-3.0-or-later"
3034
authors = [{name = "Jim Easterbrook", email = "jim@jim-easterbrook.me.uk"}]
3135
classifiers = [
3236
"Development Status :: 5 - Production/Stable",
3337
"Intended Audience :: Developers",
34-
"License :: OSI Approved :: GNU Lesser General Public License v3 or later (LGPLv3+)",
3538
"Operating System :: MacOS",
3639
"Operating System :: MacOS :: MacOS X",
3740
"Operating System :: POSIX",

setup.py

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# python-gphoto2 - Python interface to libgphoto2
22
# http://github.com/jim-easterbrook/python-gphoto2
3-
# Copyright (C) 2014-24 Jim Easterbrook jim@jim-easterbrook.me.uk
3+
# Copyright (C) 2014-26 Jim Easterbrook jim@jim-easterbrook.me.uk
44
#
55
# This file is part of python-gphoto2.
66
#
@@ -35,8 +35,7 @@
3535
# using a local build of libgphoto2
3636
gphoto2_dir = os.environ['GPHOTO2_ROOT']
3737
gphoto2_dir = os.path.expanduser(gphoto2_dir)
38-
if not os.path.isabs(gphoto2_dir):
39-
raise RuntimeError('GPHOTO2_ROOT is not an absolute path')
38+
gphoto2_dir = os.path.abspath(gphoto2_dir)
4039
print('Using libgphoto2 from {}'.format(gphoto2_dir))
4140
for root, dirs, files in os.walk(gphoto2_dir):
4241
if 'libgphoto2.pc' in files:
@@ -58,22 +57,27 @@
5857
package_data['gphoto2.libgphoto2'].append(name)
5958
# get cam libs
6059
packages.append('gphoto2.libgphoto2.camlibs')
61-
lib_dir = subprocess.check_output(
60+
camlib_dir = subprocess.check_output(
6261
['pkg-config', '--variable=driverdir', 'libgphoto2'],
6362
universal_newlines=True).strip()
64-
package_dir['gphoto2.libgphoto2.camlibs'] = os.path.relpath(lib_dir)
63+
package_dir['gphoto2.libgphoto2.camlibs'] = os.path.relpath(camlib_dir)
6564
package_data['gphoto2.libgphoto2.camlibs'] = ['*.so']
6665
# get io libs
6766
packages.append('gphoto2.libgphoto2.iolibs')
68-
lib_dir = subprocess.check_output(
67+
iolib_dir = subprocess.check_output(
6968
['pkg-config', '--variable=driverdir', 'libgphoto2_port'],
7069
universal_newlines=True).strip()
71-
package_dir['gphoto2.libgphoto2.iolibs'] = os.path.relpath(lib_dir)
70+
if not iolib_dir:
71+
iolib_vsn = subprocess.check_output(
72+
['pkg-config', '--variable=VERSION', 'libgphoto2_port'],
73+
universal_newlines=True).strip()
74+
iolib_dir = os.path.join(lib_dir, 'libgphoto2_port', iolib_vsn)
75+
package_dir['gphoto2.libgphoto2.iolibs'] = os.path.relpath(iolib_dir)
7276
package_data['gphoto2.libgphoto2.iolibs'] = []
73-
for name in os.listdir(lib_dir):
77+
for name in os.listdir(iolib_dir):
7478
if name == 'vusb.so':
7579
packages.append('gphoto2.libgphoto2.vusb')
76-
package_dir['gphoto2.libgphoto2.vusb'] = os.path.relpath(lib_dir)
80+
package_dir['gphoto2.libgphoto2.vusb'] = os.path.relpath(iolib_dir)
7781
package_data['gphoto2.libgphoto2.vusb'] = [name]
7882
elif name.endswith('.so'):
7983
package_data['gphoto2.libgphoto2.iolibs'].append(name)
@@ -183,6 +187,10 @@
183187
# python-gphoto2 version
184188
version = long_description.split('\n')[0].split()[-1]
185189

190+
classifiers = metadata['project']['classifiers']
191+
classifiers.append('License :: OSI Approved :: GNU Lesser General Public'
192+
' License v3 or later (LGPLv3+)')
193+
186194
setup_kwds.update(
187195
name = metadata['project']['name'],
188196
version = version,
@@ -191,9 +199,9 @@
191199
author = metadata['project']['authors'][0]['name'],
192200
author_email = metadata['project']['authors'][0]['email'],
193201
url = metadata['project']['urls']['homepage'],
194-
classifiers = metadata['project']['classifiers'],
202+
classifiers = classifiers,
195203
platforms = metadata['tool']['setuptools']['platforms'],
196-
license = metadata['project']['license']['text'],
204+
license = 'GNU LGPL',
197205
zip_safe = metadata['tool']['setuptools']['zip-safe'],
198206
)
199207

src/gphoto2/abilities_list.i

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// python-gphoto2 - Python interface to libgphoto2
22
// http://github.com/jim-easterbrook/python-gphoto2
3-
// Copyright (C) 2014-24 Jim Easterbrook jim@jim-easterbrook.me.uk
3+
// Copyright (C) 2014-25 Jim Easterbrook jim@jim-easterbrook.me.uk
44
//
55
// This file is part of python-gphoto2.
66
//
@@ -65,18 +65,15 @@ LEN_MEMBER_FUNCTION(_CameraAbilitiesList, gp_abilities_list_count)
6565
if (PyErr_Occurred() != NULL) goto fail;
6666
}
6767
%extend _CameraAbilitiesList {
68+
%fragment("gphoto2_error");
6869
void __getitem__(int idx, CameraAbilities *abilities) {
6970
if (idx < 0 || idx >= gp_abilities_list_count($self)) {
7071
PyErr_SetString(PyExc_IndexError, "CameraAbilitiesList index out of range");
7172
return;
7273
}
73-
{
74-
int error = gp_abilities_list_get_abilities($self, idx, abilities);
75-
if (error < GP_OK) {
76-
GPHOTO2_ERROR(error)
77-
return;
78-
}
79-
}
74+
if (gphoto2_error(gp_abilities_list_get_abilities(
75+
$self, idx, abilities)))
76+
return;
8077
}
8178
};
8279

src/gphoto2/camera.i

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// python-gphoto2 - Python interface to libgphoto2
22
// http://github.com/jim-easterbrook/python-gphoto2
3-
// Copyright (C) 2014-25 Jim Easterbrook jim@jim-easterbrook.me.uk
3+
// Copyright (C) 2014-26 Jim Easterbrook jim@jim-easterbrook.me.uk
44
//
55
// This file is part of python-gphoto2.
66
//
@@ -58,6 +58,10 @@ DEFAULT_EXCEPTION
5858
// Many functions accept NULL context value
5959
DEFAULT_CONTEXT
6060

61+
// SWIG ref counting
62+
%feature("ref") _Camera "gp_camera_ref($this);"
63+
%feature("unref") _Camera "gp_camera_unref($this);"
64+
6165
// gp_camera_get_abilities() returns a pointer in an output parameter
6266
CALLOC_ARGOUT(CameraAbilities *abilities)
6367

@@ -78,11 +82,9 @@ NEW_ARGOUT(CameraList *, gp_list_new, gp_list_unref)
7882
%typemap(default) CameraFile *camera_file (int new_file = 0) %{
7983
$1 = NULL;
8084
%}
81-
%typemap(check) CameraFile *camera_file {
85+
%typemap(check, fragment="gphoto2_error") CameraFile *camera_file {
8286
if (!$1) {
83-
int error = gp_file_new(&$1);
84-
if (error < GP_OK) {
85-
GPHOTO2_ERROR(error)
87+
if (gphoto2_error(gp_file_new(&$1))) {
8688
SWIG_fail;
8789
}
8890
new_file$argnum = 1;
@@ -139,9 +141,9 @@ CALLOC_ARGOUT(CameraFilePath *path)
139141
$result = SWIG_AppendOutput($result, PyLong_FromUnsignedLongLong(*$2));
140142
}
141143

142-
// Add default constructor and destructor to _Camera
144+
// Add default constructor to _Camera
143145
DEFAULT_CTOR(_Camera, gp_camera_new)
144-
DEFAULT_DTOR(_Camera, gp_camera_unref)
146+
145147
%ignore gp_camera_ref;
146148
%ignore gp_camera_unref;
147149

src/gphoto2/common/macros.i

Lines changed: 42 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// python-gphoto2 - Python interface to libgphoto2
22
// http://github.com/jim-easterbrook/python-gphoto2
3-
// Copyright (C) 2014-24 Jim Easterbrook jim@jim-easterbrook.me.uk
3+
// Copyright (C) 2014-26 Jim Easterbrook jim@jim-easterbrook.me.uk
44
//
55
// This file is part of python-gphoto2.
66
//
@@ -37,13 +37,39 @@
3737
}
3838
%enddef
3939

40-
%define GPHOTO2_ERROR(error)
41-
PyErr_SetObject(PyExc_GPhoto2Error, PyInt_FromLong(error));
42-
%enddef
40+
// Get PyExc_GPhoto2Error object
41+
%fragment("_declare_GPhoto2Error", "header") {
42+
PyObject *PyExc_GPhoto2Error = NULL;
43+
}
44+
%fragment("_import_GPhoto2Error", "init", fragment="_declare_GPhoto2Error") {
45+
{
46+
PyObject *module = PyImport_ImportModule("gphoto2");
47+
if (module) {
48+
PyExc_GPhoto2Error = PyObject_GetAttrString(module, "GPhoto2Error");
49+
SWIG_Py_DECREF(module);
50+
}
51+
if (!PyExc_GPhoto2Error)
52+
#if SWIG_VERSION >= 0x040400
53+
return -1;
54+
#else
55+
return NULL;
56+
#endif
57+
}
58+
}
59+
60+
// Set Python exception if result is a failure
61+
%fragment("gphoto2_error", "header", fragment="_import_GPhoto2Error") {
62+
static int gphoto2_error(int error) {
63+
if (error < GP_OK) {
64+
PyErr_SetObject(PyExc_GPhoto2Error, PyInt_FromLong(error));
65+
return 1;
66+
}
67+
return 0;
68+
};
69+
}
4370

4471
%define PLAIN_ARGOUT(typepattern)
45-
%typemap(in, numinputs=0) typepattern ($*1_type temp) {
46-
temp = NULL;
72+
%typemap(in, numinputs=0) typepattern ($*1_type temp = NULL) {
4773
$1 = &temp;
4874
}
4975
%typemap(argout) typepattern {
@@ -55,7 +81,7 @@ PyErr_SetObject(PyExc_GPhoto2Error, PyInt_FromLong(error));
5581
%define CALLOC_ARGOUT(typepattern)
5682
%typemap(in, numinputs=0) typepattern () {
5783
$1 = ($1_type)calloc(1, sizeof($*1_type));
58-
if ($1 == NULL) {
84+
if (!$1) {
5985
PyErr_SetString(PyExc_MemoryError, "Cannot allocate " "$*1_type");
6086
SWIG_fail;
6187
}
@@ -71,16 +97,14 @@ PyErr_SetObject(PyExc_GPhoto2Error, PyInt_FromLong(error));
7197
%enddef
7298

7399
%define NEW_ARGOUT(typepattern, alloc_func, free_func)
74-
%typemap(in, numinputs=0) typepattern () {
75-
int error = alloc_func(&$1);
76-
if (error < GP_OK) {
100+
%typemap(in, numinputs=0, fragment="gphoto2_error") typepattern () {
101+
if (gphoto2_error(alloc_func(&$1))) {
77102
$1 = NULL;
78-
GPHOTO2_ERROR(error)
79103
SWIG_fail;
80104
}
81105
}
82106
%typemap(freearg) typepattern {
83-
if ($1 != NULL) {
107+
if ($1) {
84108
free_func($1);
85109
}
86110
}
@@ -93,11 +117,10 @@ PyErr_SetObject(PyExc_GPhoto2Error, PyInt_FromLong(error));
93117

94118
%define DEFAULT_CTOR(type, function)
95119
%extend type {
120+
%fragment("gphoto2_error");
96121
type() {
97122
struct type *result;
98-
int error = function(&result);
99-
if (error < GP_OK)
100-
GPHOTO2_ERROR(error)
123+
gphoto2_error(function(&result));
101124
return result;
102125
}
103126
};
@@ -106,9 +129,9 @@ PyErr_SetObject(PyExc_GPhoto2Error, PyInt_FromLong(error));
106129
%define DEFAULT_DTOR(name, free_func)
107130
%delobject free_func;
108131
%extend name {
132+
%fragment("gphoto2_error");
109133
~name() {
110-
int error = free_func($self);
111-
if (error < GP_OK) GPHOTO2_ERROR(error)
134+
gphoto2_error(free_func($self));
112135
}
113136
};
114137
%enddef
@@ -117,6 +140,7 @@ PyErr_SetObject(PyExc_GPhoto2Error, PyInt_FromLong(error));
117140
%define MEMBER_FUNCTION(type, member_rtn, member, member_args,
118141
function, function_args, thread_allow)
119142
%extend type {
143+
%fragment("gphoto2_error");
120144
member_rtn member member_args {
121145
#if #thread_allow != ""
122146
SWIG_PYTHON_THREAD_BEGIN_ALLOW;
@@ -125,7 +149,7 @@ PyErr_SetObject(PyExc_GPhoto2Error, PyInt_FromLong(error));
125149
#if #thread_allow != ""
126150
SWIG_PYTHON_THREAD_END_ALLOW;
127151
#endif
128-
if (result < GP_OK) GPHOTO2_ERROR(result)
152+
gphoto2_error(result);
129153
#if #member_rtn == "int" || #member_rtn == "static int"
130154
return result;
131155
#endif

0 commit comments

Comments
 (0)