gstreamer-python 1.27.90__cp313-cp313-win32.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. gstreamer_python/Lib/girepository-1.0/GdkPixbuf-2.0.typelib +0 -0
  2. gstreamer_python/Lib/girepository-1.0/HarfBuzz-0.0.typelib +0 -0
  3. gstreamer_python/Lib/girepository-1.0/Json-1.0.typelib +0 -0
  4. gstreamer_python/Lib/girepository-1.0/Pango-1.0.typelib +0 -0
  5. gstreamer_python/Lib/girepository-1.0/PangoCairo-1.0.typelib +0 -0
  6. gstreamer_python/Lib/girepository-1.0/Soup-3.0.typelib +0 -0
  7. gstreamer_python/Lib/gstreamer-1.0/gstpython.dll +0 -0
  8. gstreamer_python/Lib/site-packages/PyGObject-3.50.2.dist-info/METADATA +21 -0
  9. gstreamer_python/Lib/site-packages/cairo/__init__.py +25 -0
  10. gstreamer_python/Lib/site-packages/cairo/__init__.pyi +5889 -0
  11. gstreamer_python/Lib/site-packages/cairo/_cairo.cp313-win32.pyd +0 -0
  12. gstreamer_python/Lib/site-packages/cairo/include/py3cairo.h +266 -0
  13. gstreamer_python/Lib/site-packages/cairo/py.typed +0 -0
  14. gstreamer_python/Lib/site-packages/gi/__init__.py +197 -0
  15. gstreamer_python/Lib/site-packages/gi/_constants.py +47 -0
  16. gstreamer_python/Lib/site-packages/gi/_error.py +55 -0
  17. gstreamer_python/Lib/site-packages/gi/_gi.cp313-win32.pyd +0 -0
  18. gstreamer_python/Lib/site-packages/gi/_gi_cairo.cp313-win32.pyd +0 -0
  19. gstreamer_python/Lib/site-packages/gi/_gtktemplate.py +307 -0
  20. gstreamer_python/Lib/site-packages/gi/_option.py +379 -0
  21. gstreamer_python/Lib/site-packages/gi/_ossighelper.py +275 -0
  22. gstreamer_python/Lib/site-packages/gi/_propertyhelper.py +402 -0
  23. gstreamer_python/Lib/site-packages/gi/_signalhelper.py +249 -0
  24. gstreamer_python/Lib/site-packages/gi/docstring.py +205 -0
  25. gstreamer_python/Lib/site-packages/gi/events.py +674 -0
  26. gstreamer_python/Lib/site-packages/gi/importer.py +153 -0
  27. gstreamer_python/Lib/site-packages/gi/module.py +269 -0
  28. gstreamer_python/Lib/site-packages/gi/overrides/GES.py +94 -0
  29. gstreamer_python/Lib/site-packages/gi/overrides/GIMarshallingTests.py +72 -0
  30. gstreamer_python/Lib/site-packages/gi/overrides/GLib.py +882 -0
  31. gstreamer_python/Lib/site-packages/gi/overrides/GObject.py +692 -0
  32. gstreamer_python/Lib/site-packages/gi/overrides/Gdk.py +444 -0
  33. gstreamer_python/Lib/site-packages/gi/overrides/GdkPixbuf.py +53 -0
  34. gstreamer_python/Lib/site-packages/gi/overrides/Gio.py +655 -0
  35. gstreamer_python/Lib/site-packages/gi/overrides/Gst.py +1273 -0
  36. gstreamer_python/Lib/site-packages/gi/overrides/GstAnalytics.py +106 -0
  37. gstreamer_python/Lib/site-packages/gi/overrides/GstApp.py +50 -0
  38. gstreamer_python/Lib/site-packages/gi/overrides/GstAudio.py +18 -0
  39. gstreamer_python/Lib/site-packages/gi/overrides/GstPbutils.py +99 -0
  40. gstreamer_python/Lib/site-packages/gi/overrides/GstVideo.py +17 -0
  41. gstreamer_python/Lib/site-packages/gi/overrides/Gtk.py +1707 -0
  42. gstreamer_python/Lib/site-packages/gi/overrides/Pango.py +58 -0
  43. gstreamer_python/Lib/site-packages/gi/overrides/__init__.py +357 -0
  44. gstreamer_python/Lib/site-packages/gi/overrides/_gi_gst.cp313-win32.pyd +0 -0
  45. gstreamer_python/Lib/site-packages/gi/overrides/_gi_gst_analytics.cp313-win32.pyd +0 -0
  46. gstreamer_python/Lib/site-packages/gi/overrides/keysyms.py +53 -0
  47. gstreamer_python/Lib/site-packages/gi/pygtkcompat.py +26 -0
  48. gstreamer_python/Lib/site-packages/gi/repository/__init__.py +28 -0
  49. gstreamer_python/Lib/site-packages/gi/types.py +350 -0
  50. gstreamer_python/Lib/site-packages/pycairo-1.27.0.dist-info/METADATA +9 -0
  51. gstreamer_python/__init__.py +32 -0
  52. gstreamer_python-1.27.90.dist-info/METADATA +26 -0
  53. gstreamer_python-1.27.90.dist-info/RECORD +55 -0
  54. gstreamer_python-1.27.90.dist-info/WHEEL +5 -0
  55. gstreamer_python-1.27.90.dist-info/top_level.txt +1 -0
@@ -0,0 +1,275 @@
1
+ # Copyright 2017 Christoph Reiter
2
+ #
3
+ # This library is free software; you can redistribute it and/or
4
+ # modify it under the terms of the GNU Lesser General Public
5
+ # License as published by the Free Software Foundation; either
6
+ # version 2.1 of the License, or (at your option) any later version.
7
+ #
8
+ # This library is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11
+ # Lesser General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU Lesser General Public
14
+ # License along with this library; if not, see <http://www.gnu.org/licenses/>.
15
+
16
+ from __future__ import print_function
17
+
18
+ import os
19
+ import socket
20
+ import signal
21
+ import asyncio
22
+ import threading
23
+ from contextlib import closing, contextmanager
24
+
25
+ from . import _gi
26
+
27
+
28
+ def ensure_socket_not_inheritable(sock):
29
+ """Ensures that the socket is not inherited by child processes
30
+
31
+ Raises:
32
+ EnvironmentError
33
+ NotImplementedError: With Python <3.4 on Windows
34
+ """
35
+
36
+ if hasattr(sock, "set_inheritable"):
37
+ sock.set_inheritable(False)
38
+ else:
39
+ try:
40
+ import fcntl
41
+ except ImportError:
42
+ raise NotImplementedError(
43
+ "Not implemented for older Python on Windows")
44
+ else:
45
+ fd = sock.fileno()
46
+ flags = fcntl.fcntl(fd, fcntl.F_GETFD)
47
+ fcntl.fcntl(fd, fcntl.F_SETFD, flags | fcntl.FD_CLOEXEC)
48
+
49
+
50
+ _wakeup_fd_is_active = False
51
+ """Since we can't check if set_wakeup_fd() is already used for nested event
52
+ loops without introducing a race condition we keep track of it globally.
53
+ """
54
+
55
+
56
+ @contextmanager
57
+ def wakeup_on_signal():
58
+ """A decorator for functions which create a glib event loop to keep
59
+ Python signal handlers working while the event loop is idling.
60
+
61
+ In case an OS signal is received will wake the default event loop up
62
+ shortly so that any registered Python signal handlers registered through
63
+ signal.signal() can run.
64
+
65
+ In case the wrapped function is not called from the main thread it will be
66
+ called as is and it will not wake up the default loop for signals.
67
+ """
68
+
69
+ global _wakeup_fd_is_active
70
+
71
+ if _wakeup_fd_is_active:
72
+ yield
73
+ return
74
+
75
+ from gi.repository import GLib
76
+
77
+ read_socket, write_socket = socket.socketpair()
78
+ with closing(read_socket), closing(write_socket):
79
+
80
+ for sock in [read_socket, write_socket]:
81
+ sock.setblocking(False)
82
+ ensure_socket_not_inheritable(sock)
83
+
84
+ try:
85
+ orig_fd = signal.set_wakeup_fd(write_socket.fileno())
86
+ except ValueError:
87
+ # Raised in case this is not the main thread -> give up.
88
+ yield
89
+ return
90
+ else:
91
+ _wakeup_fd_is_active = True
92
+
93
+ def signal_notify(source, condition):
94
+ if condition & GLib.IO_IN:
95
+ try:
96
+ return bool(read_socket.recv(1))
97
+ except EnvironmentError as e:
98
+ print(e)
99
+ return False
100
+ return True
101
+ else:
102
+ return False
103
+
104
+ try:
105
+ if os.name == "nt":
106
+ channel = GLib.IOChannel.win32_new_socket(
107
+ read_socket.fileno())
108
+ else:
109
+ channel = GLib.IOChannel.unix_new(read_socket.fileno())
110
+
111
+ source_id = GLib.io_add_watch(
112
+ channel,
113
+ GLib.PRIORITY_DEFAULT,
114
+ (GLib.IOCondition.IN | GLib.IOCondition.HUP |
115
+ GLib.IOCondition.NVAL | GLib.IOCondition.ERR),
116
+ signal_notify)
117
+ try:
118
+ yield
119
+ finally:
120
+ GLib.source_remove(source_id)
121
+ finally:
122
+ write_fd = signal.set_wakeup_fd(orig_fd)
123
+ if write_fd != write_socket.fileno():
124
+ # Someone has called set_wakeup_fd while func() was active,
125
+ # so let's re-revert again.
126
+ signal.set_wakeup_fd(write_fd)
127
+ _wakeup_fd_is_active = False
128
+
129
+
130
+ PyOS_getsig = _gi.pyos_getsig
131
+ PyOS_setsig = _gi.pyos_setsig
132
+
133
+ # We save the signal pointer so we can detect if glib has changed the
134
+ # signal handler behind Python's back (GLib.unix_signal_add)
135
+ if signal.getsignal(signal.SIGINT) is signal.default_int_handler:
136
+ startup_sigint_ptr = PyOS_getsig(signal.SIGINT)
137
+ else:
138
+ # Something has set the handler before import, we can't get a ptr
139
+ # for the default handler so make sure the pointer will never match.
140
+ startup_sigint_ptr = -1
141
+
142
+
143
+ def sigint_handler_is_default():
144
+ """Returns if on SIGINT the default Python handler would be called"""
145
+
146
+ return (signal.getsignal(signal.SIGINT) is signal.default_int_handler and
147
+ PyOS_getsig(signal.SIGINT) == startup_sigint_ptr)
148
+
149
+
150
+ @contextmanager
151
+ def sigint_handler_set_and_restore_default(handler):
152
+ """Context manager for saving/restoring the SIGINT handler default state.
153
+
154
+ Will only restore the default handler again if the handler is not changed
155
+ while the context is active.
156
+ """
157
+
158
+ assert sigint_handler_is_default()
159
+
160
+ signal.signal(signal.SIGINT, handler)
161
+ sig_ptr = PyOS_getsig(signal.SIGINT)
162
+ try:
163
+ yield
164
+ finally:
165
+ if signal.getsignal(signal.SIGINT) is handler and \
166
+ PyOS_getsig(signal.SIGINT) == sig_ptr:
167
+ signal.signal(signal.SIGINT, signal.default_int_handler)
168
+
169
+
170
+ def is_main_thread():
171
+ """Returns True in case the function is called from the main thread"""
172
+
173
+ return threading.current_thread().name == "MainThread"
174
+
175
+
176
+ _callback_stack = []
177
+ _sigint_called = False
178
+
179
+
180
+ @contextmanager
181
+ def register_sigint_fallback(callback):
182
+ """Installs a SIGINT signal handler in case the default Python one is
183
+ active which calls 'callback' in case the signal occurs.
184
+
185
+ Only does something if called from the main thread.
186
+
187
+ In case of nested context managers the signal handler will be only
188
+ installed once and the callbacks will be called in the reverse order
189
+ of their registration.
190
+
191
+ The old signal handler will be restored in case no signal handler is
192
+ registered while the context is active.
193
+ """
194
+
195
+ # To handle multiple levels of event loops we need to call the last
196
+ # callback first, wait until the inner most event loop returns control
197
+ # and only then call the next callback, and so on... until we
198
+ # reach the outer most which manages the signal handler and raises
199
+ # in the end
200
+
201
+ global _callback_stack, _sigint_called
202
+
203
+ if not is_main_thread():
204
+ yield
205
+ return
206
+
207
+ if not sigint_handler_is_default():
208
+ if _callback_stack:
209
+ # This is an inner event loop, append our callback
210
+ # to the stack so the parent context can call it.
211
+ _callback_stack.append(callback)
212
+ try:
213
+ yield
214
+ finally:
215
+ cb = _callback_stack.pop()
216
+ if _sigint_called:
217
+ cb()
218
+ else:
219
+ # There is a signal handler set by the user, just do nothing
220
+ yield
221
+ return
222
+
223
+ _sigint_called = False
224
+
225
+ def sigint_handler(sig_num, frame):
226
+ global _callback_stack, _sigint_called
227
+
228
+ if _sigint_called:
229
+ return
230
+ _sigint_called = True
231
+ _callback_stack.pop()()
232
+
233
+ _callback_stack.append(callback)
234
+ try:
235
+ with sigint_handler_set_and_restore_default(sigint_handler):
236
+ yield
237
+ finally:
238
+ if _sigint_called:
239
+ signal.default_int_handler(signal.SIGINT, None)
240
+ else:
241
+ _callback_stack.pop()
242
+
243
+
244
+ class DummyEventLoop():
245
+ @classmethod
246
+ @contextmanager
247
+ def paused(cls):
248
+ yield
249
+
250
+ @classmethod
251
+ @contextmanager
252
+ def running(cls, quit_func):
253
+ with wakeup_on_signal():
254
+ yield
255
+
256
+
257
+ def get_event_loop(ctx):
258
+ """Return the correct GLibEventLoop or a dummy that just registers the
259
+ signal wakeup mechanism."""
260
+
261
+ # Try to use the running loop. If there is none, get the policy and
262
+ # try getting one in the hope that this will give us an event loop for the
263
+ # correct context.
264
+ loop = asyncio._get_running_loop()
265
+ if loop is None:
266
+ try:
267
+ loop = asyncio.get_event_loop_policy().get_event_loop_for_context(ctx)
268
+ except:
269
+ pass
270
+
271
+ if loop and hasattr(loop, '_context'):
272
+ if ctx is not None and hash(loop._context) == hash(ctx):
273
+ return loop
274
+
275
+ return DummyEventLoop
@@ -0,0 +1,402 @@
1
+ # -*- Mode: Python; py-indent-offset: 4 -*-
2
+ # pygobject - Python bindings for the GObject library
3
+ # Copyright (C) 2007 Johan Dahlin
4
+ #
5
+ # gi/_propertyhelper.py: GObject property wrapper/helper
6
+ #
7
+ # This library is free software; you can redistribute it and/or
8
+ # modify it under the terms of the GNU Lesser General Public
9
+ # License as published by the Free Software Foundation; either
10
+ # version 2.1 of the License, or (at your option) any later version.
11
+ #
12
+ # This library is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
+ # Lesser General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU Lesser General Public
18
+ # License along with this library; if not, see <http://www.gnu.org/licenses/>.
19
+
20
+ from . import _gi
21
+ from ._constants import \
22
+ TYPE_NONE, TYPE_INTERFACE, TYPE_CHAR, TYPE_UCHAR, \
23
+ TYPE_BOOLEAN, TYPE_INT, TYPE_UINT, TYPE_LONG, \
24
+ TYPE_ULONG, TYPE_INT64, TYPE_UINT64, TYPE_ENUM, TYPE_FLAGS, \
25
+ TYPE_FLOAT, TYPE_DOUBLE, TYPE_STRING, \
26
+ TYPE_POINTER, TYPE_BOXED, TYPE_PARAM, TYPE_OBJECT, \
27
+ TYPE_PYOBJECT, TYPE_GTYPE, TYPE_STRV, TYPE_VARIANT
28
+
29
+ G_MAXFLOAT = _gi.G_MAXFLOAT
30
+ G_MAXDOUBLE = _gi.G_MAXDOUBLE
31
+ G_MININT = _gi.G_MININT
32
+ G_MAXINT = _gi.G_MAXINT
33
+ G_MAXUINT = _gi.G_MAXUINT
34
+ G_MINLONG = _gi.G_MINLONG
35
+ G_MAXLONG = _gi.G_MAXLONG
36
+ G_MAXULONG = _gi.G_MAXULONG
37
+
38
+
39
+ class Property(object):
40
+ """Creates a new Property which when used in conjunction with
41
+ GObject subclass will create a Python property accessor for the
42
+ GObject ParamSpec.
43
+
44
+ :param callable getter:
45
+ getter to get the value of the property
46
+ :param callable setter:
47
+ setter to set the value of the property
48
+ :param type type:
49
+ type of property
50
+ :param default:
51
+ default value, must match the property type.
52
+ :param str nick:
53
+ short description
54
+ :param str blurb:
55
+ long description
56
+ :param GObject.ParamFlags flags:
57
+ parameter flags
58
+ :keyword minimum:
59
+ minimum allowed value (int, float, long only)
60
+ :keyword maximum:
61
+ maximum allowed value (int, float, long only)
62
+
63
+ .. code-block:: python
64
+
65
+ class MyObject(GObject.Object):
66
+ prop = GObject.Property(type=str)
67
+
68
+ obj = MyObject()
69
+ obj.prop = 'value'
70
+
71
+ obj.prop # now is 'value'
72
+
73
+ The API is similar to the builtin :py:func:`property`:
74
+
75
+ .. code-block:: python
76
+
77
+ class AnotherObject(GObject.Object):
78
+ value = 0
79
+
80
+ @GObject.Property
81
+ def prop(self):
82
+ 'Read only property.'
83
+ return 1
84
+
85
+ @GObject.Property(type=int)
86
+ def propInt(self):
87
+ 'Read-write integer property.'
88
+ return self.value
89
+
90
+ @propInt.setter
91
+ def propInt(self, value):
92
+ self.value = value
93
+ """
94
+ _type_from_pytype_lookup = {
95
+ int: TYPE_INT,
96
+ bool: TYPE_BOOLEAN,
97
+ float: TYPE_DOUBLE,
98
+ str: TYPE_STRING,
99
+ object: TYPE_PYOBJECT,
100
+ }
101
+
102
+ _min_value_lookup = {
103
+ TYPE_UINT: 0,
104
+ TYPE_ULONG: 0,
105
+ TYPE_UINT64: 0,
106
+ # Remember that G_MINFLOAT and G_MINDOUBLE are something different.
107
+ TYPE_FLOAT: -G_MAXFLOAT,
108
+ TYPE_DOUBLE: -G_MAXDOUBLE,
109
+ TYPE_INT: G_MININT,
110
+ TYPE_LONG: G_MINLONG,
111
+ TYPE_INT64: -2 ** 63,
112
+ }
113
+
114
+ _max_value_lookup = {
115
+ TYPE_UINT: G_MAXUINT,
116
+ TYPE_ULONG: G_MAXULONG,
117
+ TYPE_INT64: 2 ** 63 - 1,
118
+ TYPE_UINT64: 2 ** 64 - 1,
119
+ TYPE_FLOAT: G_MAXFLOAT,
120
+ TYPE_DOUBLE: G_MAXDOUBLE,
121
+ TYPE_INT: G_MAXINT,
122
+ TYPE_LONG: G_MAXLONG,
123
+ }
124
+
125
+ _default_lookup = {
126
+ TYPE_INT: 0,
127
+ TYPE_UINT: 0,
128
+ TYPE_LONG: 0,
129
+ TYPE_ULONG: 0,
130
+ TYPE_INT64: 0,
131
+ TYPE_UINT64: 0,
132
+ TYPE_STRING: '',
133
+ TYPE_FLOAT: 0.0,
134
+ TYPE_DOUBLE: 0.0,
135
+ }
136
+
137
+ class __metaclass__(type):
138
+ def __repr__(self):
139
+ return "<class 'GObject.Property'>"
140
+
141
+ def __init__(self, getter=None, setter=None, type=None, default=None,
142
+ nick='', blurb='', flags=_gi.PARAM_READWRITE,
143
+ minimum=None, maximum=None):
144
+ self.name = None
145
+
146
+ if type is None:
147
+ type = object
148
+ self.type = self._type_from_python(type)
149
+ self.default = self._get_default(default)
150
+ self._check_default()
151
+
152
+ if not isinstance(nick, str):
153
+ raise TypeError("nick must be a string")
154
+ self.nick = nick
155
+
156
+ if not isinstance(blurb, str):
157
+ raise TypeError("blurb must be a string")
158
+ self.blurb = blurb
159
+ # Always clobber __doc__ with blurb even if blurb is empty because
160
+ # we don't want the lengthy Property class documentation showing up
161
+ # on instances.
162
+ self.__doc__ = blurb
163
+ self.flags = flags
164
+
165
+ # Call after setting blurb for potential __doc__ usage.
166
+ if getter and not setter:
167
+ setter = self._readonly_setter
168
+ elif setter and not getter:
169
+ getter = self._writeonly_getter
170
+ elif not setter and not getter:
171
+ getter = self._default_getter
172
+ setter = self._default_setter
173
+ self.getter(getter)
174
+ # do not call self.setter() here, as this defines the property name
175
+ # already
176
+ self.fset = setter
177
+
178
+ if minimum is not None:
179
+ if minimum < self._get_minimum():
180
+ raise TypeError(
181
+ "Minimum for type %s cannot be lower than %d" %
182
+ (self.type, self._get_minimum()))
183
+ else:
184
+ minimum = self._get_minimum()
185
+ self.minimum = minimum
186
+ if maximum is not None:
187
+ if maximum > self._get_maximum():
188
+ raise TypeError(
189
+ "Maximum for type %s cannot be higher than %d" %
190
+ (self.type, self._get_maximum()))
191
+ else:
192
+ maximum = self._get_maximum()
193
+ self.maximum = maximum
194
+
195
+ self._exc = None
196
+
197
+ def __repr__(self):
198
+ return '<GObject Property %s (%s)>' % (
199
+ self.name or '(uninitialized)',
200
+ self.type.name)
201
+
202
+ def __get__(self, instance, klass):
203
+ if instance is None:
204
+ return self
205
+
206
+ self._exc = None
207
+ value = self.fget(instance)
208
+ if self._exc:
209
+ exc = self._exc
210
+ self._exc = None
211
+ raise exc
212
+
213
+ return value
214
+
215
+ def __set__(self, instance, value):
216
+ if instance is None:
217
+ raise TypeError
218
+
219
+ self._exc = None
220
+ instance.set_property(self.name, value)
221
+ if self._exc:
222
+ exc = self._exc
223
+ self._exc = None
224
+ raise exc
225
+
226
+ def __call__(self, fget):
227
+ """Allows application of the getter along with init arguments."""
228
+ return self.getter(fget)
229
+
230
+ def getter(self, fget):
231
+ """Set the getter function to fget. For use as a decorator."""
232
+ if fget.__doc__:
233
+ # Always clobber docstring and blurb with the getter docstring.
234
+ self.blurb = fget.__doc__
235
+ self.__doc__ = fget.__doc__
236
+ self.fget = fget
237
+ return self
238
+
239
+ def setter(self, fset):
240
+ """Set the setter function to fset. For use as a decorator."""
241
+ self.fset = fset
242
+ # with a setter decorator, we must ignore the name of the method in
243
+ # install_properties, as this does not need to be a valid property name
244
+ # and does not define the property name. So set the name here.
245
+ if not self.name:
246
+ self.name = self.fget.__name__
247
+ return self
248
+
249
+ def _type_from_python(self, type_):
250
+ if type_ in self._type_from_pytype_lookup:
251
+ return self._type_from_pytype_lookup[type_]
252
+ elif (isinstance(type_, type) and
253
+ issubclass(type_, (_gi.GObject,
254
+ _gi.GEnum,
255
+ _gi.GFlags,
256
+ _gi.GBoxed,
257
+ _gi.GInterface))):
258
+ return type_.__gtype__
259
+ elif type_ in (TYPE_NONE, TYPE_INTERFACE, TYPE_CHAR, TYPE_UCHAR,
260
+ TYPE_INT, TYPE_UINT, TYPE_BOOLEAN, TYPE_LONG,
261
+ TYPE_ULONG, TYPE_INT64, TYPE_UINT64,
262
+ TYPE_FLOAT, TYPE_DOUBLE, TYPE_POINTER,
263
+ TYPE_BOXED, TYPE_PARAM, TYPE_OBJECT, TYPE_STRING,
264
+ TYPE_PYOBJECT, TYPE_GTYPE, TYPE_STRV, TYPE_VARIANT):
265
+ return type_
266
+ else:
267
+ raise TypeError("Unsupported type: %r" % (type_,))
268
+
269
+ def _get_default(self, default):
270
+ if default is not None:
271
+ return default
272
+ return self._default_lookup.get(self.type, None)
273
+
274
+ def _check_default(self):
275
+ ptype = self.type
276
+ default = self.default
277
+ if (ptype == TYPE_BOOLEAN and (default not in (True, False))):
278
+ raise TypeError(
279
+ "default must be True or False, not %r" % (default,))
280
+ elif ptype == TYPE_PYOBJECT:
281
+ if default is not None:
282
+ raise TypeError("object types does not have default values")
283
+ elif ptype == TYPE_GTYPE:
284
+ if default is not None:
285
+ raise TypeError("GType types does not have default values")
286
+ elif ptype.is_a(TYPE_ENUM):
287
+ if default is None:
288
+ raise TypeError("enum properties needs a default value")
289
+ elif not _gi.GType(default).is_a(ptype):
290
+ raise TypeError("enum value %s must be an instance of %r" %
291
+ (default, ptype))
292
+ elif ptype.is_a(TYPE_FLAGS):
293
+ if not _gi.GType(default).is_a(ptype):
294
+ raise TypeError("flags value %s must be an instance of %r" %
295
+ (default, ptype))
296
+ elif ptype.is_a(TYPE_STRV) and default is not None:
297
+ if not isinstance(default, list):
298
+ raise TypeError("Strv value %s must be a list" % repr(default))
299
+ for val in default:
300
+ if type(val) not in (str, bytes):
301
+ raise TypeError("Strv value %s must contain only strings" % str(default))
302
+ elif ptype.is_a(TYPE_VARIANT) and default is not None:
303
+ if not hasattr(default, '__gtype__') or not _gi.GType(default).is_a(TYPE_VARIANT):
304
+ raise TypeError("variant value %s must be an instance of %r" %
305
+ (default, ptype))
306
+
307
+ def _get_minimum(self):
308
+ return self._min_value_lookup.get(self.type, None)
309
+
310
+ def _get_maximum(self):
311
+ return self._max_value_lookup.get(self.type, None)
312
+
313
+ #
314
+ # Getter and Setter
315
+ #
316
+
317
+ def _default_setter(self, instance, value):
318
+ setattr(instance, '_property_helper_' + self.name, value)
319
+
320
+ def _default_getter(self, instance):
321
+ return getattr(instance, '_property_helper_' + self.name, self.default)
322
+
323
+ def _readonly_setter(self, instance, value):
324
+ self._exc = TypeError("%s property of %s is read-only" % (
325
+ self.name, type(instance).__name__))
326
+
327
+ def _writeonly_getter(self, instance):
328
+ self._exc = TypeError("%s property of %s is write-only" % (
329
+ self.name, type(instance).__name__))
330
+
331
+ #
332
+ # Public API
333
+ #
334
+
335
+ def get_pspec_args(self):
336
+ ptype = self.type
337
+ if ptype in (TYPE_INT, TYPE_UINT, TYPE_LONG, TYPE_ULONG,
338
+ TYPE_INT64, TYPE_UINT64, TYPE_FLOAT, TYPE_DOUBLE):
339
+ args = self.minimum, self.maximum, self.default
340
+ elif (ptype == TYPE_STRING or ptype == TYPE_BOOLEAN or
341
+ ptype.is_a(TYPE_ENUM) or ptype.is_a(TYPE_FLAGS) or
342
+ ptype.is_a(TYPE_VARIANT)):
343
+ args = (self.default,)
344
+ elif ptype in (TYPE_PYOBJECT, TYPE_GTYPE):
345
+ args = ()
346
+ elif ptype.is_a(TYPE_OBJECT) or ptype.is_a(TYPE_BOXED):
347
+ args = ()
348
+ else:
349
+ raise NotImplementedError(ptype)
350
+
351
+ return (self.type, self.nick, self.blurb) + args + (self.flags,)
352
+
353
+
354
+ def install_properties(cls):
355
+ """
356
+ Scans the given class for instances of Property and merges them
357
+ into the classes __gproperties__ dict if it exists or adds it if not.
358
+ """
359
+ gproperties = cls.__dict__.get('__gproperties__', {})
360
+
361
+ props = []
362
+ for name, prop in cls.__dict__.items():
363
+ if isinstance(prop, Property): # not same as the built-in
364
+ # if a property was defined with a decorator, it may already have
365
+ # a name; if it was defined with an assignment (prop = Property(...))
366
+ # we set the property's name to the member name
367
+ if not prop.name:
368
+ prop.name = name
369
+ # we will encounter the same property multiple times in case of
370
+ # custom setter methods
371
+ if prop.name in gproperties:
372
+ if gproperties[prop.name] == prop.get_pspec_args():
373
+ continue
374
+ raise ValueError('Property %s was already found in __gproperties__' % prop.name)
375
+ gproperties[prop.name] = prop.get_pspec_args()
376
+ props.append(prop)
377
+
378
+ if not props:
379
+ return
380
+
381
+ cls.__gproperties__ = gproperties
382
+
383
+ if 'do_get_property' in cls.__dict__ or 'do_set_property' in cls.__dict__:
384
+ for prop in props:
385
+ if prop.fget != prop._default_getter or prop.fset != prop._default_setter:
386
+ raise TypeError(
387
+ "GObject subclass %r defines do_get/set_property"
388
+ " and it also uses a property with a custom setter"
389
+ " or getter. This is not allowed" %
390
+ (cls.__name__,))
391
+
392
+ def obj_get_property(self, pspec):
393
+ name = pspec.name.replace('-', '_')
394
+ return getattr(self, name, None)
395
+ cls.do_get_property = obj_get_property
396
+
397
+ def obj_set_property(self, pspec, value):
398
+ name = pspec.name.replace('-', '_')
399
+ prop = getattr(cls, name, None)
400
+ if prop:
401
+ prop.fset(self, value)
402
+ cls.do_set_property = obj_set_property