Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-gst for openSUSE:Factory checked in at 2025-12-31 10:47:05 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-gst (Old) and /work/SRC/openSUSE:Factory/.python-gst.new.1928 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-gst" Wed Dec 31 10:47:05 2025 rev:73 rq:1324801 version:1.26.10 Changes: -------- --- /work/SRC/openSUSE:Factory/python-gst/python-gst.changes 2025-12-10 15:31:39.245095253 +0100 +++ /work/SRC/openSUSE:Factory/.python-gst.new.1928/python-gst.changes 2025-12-31 10:47:27.110543562 +0100 @@ -1,0 +2,10 @@ +Tue Dec 30 09:46:41 UTC 2025 - Bjørn Lie <[email protected]> + +- Update to version 1.26.10: + + Override GstPadProbeInfo to get writable objects + + Misc improvements + + More typing fixes + + 1.26.2 breaks Python bindings: No longer able to modify + Gst.Buffer metadata in pad probe callbacks + +------------------------------------------------------------------- Old: ---- gst-python-1.26.9.obscpio New: ---- gst-python-1.26.10.obscpio ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-gst.spec ++++++ --- /var/tmp/diff_new_pack.9dKa9D/_old 2025-12-31 10:47:28.794612477 +0100 +++ /var/tmp/diff_new_pack.9dKa9D/_new 2025-12-31 10:47:28.814613296 +0100 @@ -21,7 +21,7 @@ %{?sle15_python_module_pythons} Name: python-gst -Version: 1.26.9 +Version: 1.26.10 Release: 0 Summary: Python Bindings for GStreamer License: LGPL-2.1-or-later ++++++ _service ++++++ --- /var/tmp/diff_new_pack.9dKa9D/_old 2025-12-31 10:47:29.118625736 +0100 +++ /var/tmp/diff_new_pack.9dKa9D/_new 2025-12-31 10:47:29.154627209 +0100 @@ -5,7 +5,7 @@ <param name="url">https://gitlab.freedesktop.org/gstreamer/gstreamer.git</param> <param name="subdir">subprojects/gst-python</param> <param name="filename">gst-python</param> - <param name="revision">1.26.9</param> + <param name="revision">1.26.10</param> <param name="versionformat">@PARENT_TAG@+@TAG_OFFSET@</param> <param name="versionrewrite-pattern">v?(.*)\+0</param> <param name="versionrewrite-replacement">\1</param> ++++++ gst-python-1.26.9.obscpio -> gst-python-1.26.10.obscpio ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gst-python-1.26.9/NEWS new/gst-python-1.26.10/NEWS --- old/gst-python-1.26.9/NEWS 2025-12-01 18:27:07.000000000 +0100 +++ new/gst-python-1.26.10/NEWS 2025-12-25 15:44:26.000000000 +0100 @@ -2,11 +2,11 @@ GStreamer 1.26.0 was originally released on 11 March 2025. -The latest bug-fix release in the stable 1.26 series is 1.26.9 and was released on 01 December 2025. +The latest bug-fix release in the stable 1.26 series is 1.26.10 and was released on 25 December 2025 See https://gstreamer.freedesktop.org/releases/1.26/ for the latest version of this document. -Last updated: Monday 01 December 2025, 17:00 UTC (log) +Last updated: Thursday 25 December 2025, 15:00 UTC (log) ## Introduction @@ -3120,6 +3120,191 @@ - List of Merge Requests applied in 1.26.9 - List of Issues fixed in 1.26.9 +1.26.10 + +The tenth 1.26 bug-fix release (1.26.10) was released on 25 December 2025. + +This release only contains bugfixes and it should be safe to update from 1.26.x. + +Highlighted bugfixes in 1.26.10 + +- curlhttpsrc fixes and improvements +- decklinkvideosink: Fix frame completion callbacks for firmware 14.3+ +- flac: Fix 6.1 and 7.1 channel layouts and support encoding and decoding of 32-bit audio +- glimagesink: Fix handling of odd height buffers +- matroskademux: make maximum allowed block size large enough to support 4k uncompressed video +- mxf: Add support for custom Sony XDCAM video variant +- opusenc: multichannel and surround sound handling improvements +- playbin3: HLS/DASH stream selection handling improvements to fix disabling and re-enabling of audio/video streams with + adaptivedemux2 +- qtmux: robust recording mode space left estimation fixes for streams that start with a timestamp offset +- splitmuxsrc seeking improvements +- Support FLAC audio in DASH manifests +- Python bindings: fix regression where buffers were no longer writable in pad probe callbacks +- cerbero: add python bindings for GstApp; Windows installer improvements +- Various bug fixes,build fixes,memory leak fixes,and other stability and reliability improvements + +gstreamer + +- pipeline: Improve resource cleanup logic for clock objects +- filesink: fix the build with recent mingw-w64 +- basetransform, basesrc: Fix handling of buffer pool configuration failures + +gst-plugins-base + +- basetextoverlay: Don’t negotiate if caps haven’t changed +- codec-utils: Update mime codec strings +- fdmemory: Fix size calculation when sharing +- gl elements add a yellow bar on JPEGs with non-even heights +- glimagesink: Fix handling of odd height buffers +- glwindow_cocoa: fix window not closing (w/o user window handle) +- opusenc: Simplify Vorbis channel layout mapping code and fix 7.1 layout & use surround multistream encoder +- parsebin: Improve debug logging +- playbin3: ensure GST_EVENT_SELECT_STREAMS event is sent to collection source +- tagdemux: propagate seek event seqnum to upstream +- videodecoder: Don’t assume the ALLOCATION query contains a pool +- videodecoder, videoaggregator: Fix handling of buffer pool configuration failures + +gst-plugins-good + +- adaptivedemux2: Initialize start bitrate for dashdemux2 and hlsdemux2 +- dashdemux2: Unknown codec ‘flac’ when streaming a DASH MPD manifest with a mp4 FLAC file +- deinterlace: Improve pool configuration +- flac: Fix 6.1 / 7.1 channel layouts +- flacdec: Don’t forbid S32 sample size (0x07) unnecessarily +- flacenc: Support S32 samples +- flacdec: Decode 32-bit FLAC files +- level: fix crash if no caps have been sent +- level: Floating point exception (core dumped) when sending buffers without caps +- matroskademux: Bump maximum block size from 15MB to 32MB to allow 4k raw video +- matroskamux: Fix some more thread-safety issues +- matroskamux: Fix thread-safety issues when requesting new pads +- matroskamux: pad->track handling results in segmentation fault +- mxfdemux / aiffparse / matroskaparse: Remove segment closing on non-flushing seeks +- qtdemux: Use gst_util_uint64_scale to scale guint64 +- qtmux: Fix robust recording estimates +- splitmuxsrc - fix for seeking / flushing deadlock +- v4l2object: Add support for colorimetry 1:4:16:3 +- wavenc: Fix downstream negotiation +- wavparse: prevent setting empty strings as title tag + +gst-plugins-bad + +- aesenc / aesdec: use correct format specifier for buffer size in debug log +- analytics: Fix build on MSVC by using libm dependency +- curlhttpsrc: Various fixes +- decklinkvideosink: Fix frame completion callbacks for firmware 14.3+ +- dtlsdec: mark generated cert agent with GST_OBJECT_FLAG_MAY_BE_LEAKED +- fdkaacdec: Assertion on handling unsupported channel layouts +- fdkaacdec: Invalidate channel_types/indices when setting a known config +- hlssink: Guard NULL structure and use gst_structure_has_name() +- midiparse: Fix a couple of potential out-of-bounds reads +- mpegtsmux: Fix potential deadlock changing pmt-interval +- mxfdemux: reconsider “closing running segment” for non flushing seeks +- mxfdemux / aiffparse / matroskaparse: Remove segment closing on non-flushing seeks +- mxfdemux: Simplify timestamp tracking +- mxfdemux: send event SegmentDone for segment seeks +- mxfmpeg: Add custom Sony picture essence coding UL +- playbin3: ensure GST_EVENT_SELECT_STREAMS event is sent to collection source +- vabasedec: Don’t assert when negotiating based on a gap event before the first buffer +- vkformat: Add VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16 format +- webrtc: Keep a ref of the ICEStream in the TransportStream +- GstPlay: set_audio_track_enabled / set_video_track_enabled not functioning for adaptivedemux2 sources +- video: decoders: Fix possible crash when flushing H265/H266 decoder + +gst-plugins-ugly + +- No changes + +GStreamer Rust plugins + +- cctost2038anc: Fix typo with c_not_y_channel property documentation +- dav1d: Stop iteration after finding first working pool +- dav1d: Various fixes to allocation query handling +- gtk4paintablesink: Propose a udmabuf pool / allocator if upstream asks for sysmem +- gtk4: Fix typo in odd-size subsample workaround +- rtp: Update to rtcp-types 0.3 +- st2038combiner: Some fixes +- st2038extractor: Add always-add-st2038-pad property +- threadshare: allow disabling the IPv4 or IPv6 socket in ts-udpsink +- threadshare: Update to flume 0.12 +- tracers: add function and signal for writing logs to PadPushTimings +- version-helper: Update to toml_edit 0.24 +- webrtc: mark static caps with GST_MINI_OBJECT_FLAG_MAY_BE_LEAKED +- webrtcsink: don’t upscale when mitigating low bitrate +- Fix new clippy 1.92 warnings +- Update dependencies + +gst-libav + +- avviddec: Various fixes to allocation query handling +- avviddec: Aggregate GstVideoAlignment on top of the meta api params, instead of overriding them +- avviddec: Set video alignment to internal pool + +gst-rtsp-server + +- No changes + +gstreamer-vaapi + +- No changes + +gstreamer-sharp + +- No changes + +gst-python + +- Override GstPadProbeInfo to get writable objects +- Misc improvements +- More typing fixes +- 1.26.2 breaks Python bindings: No longer able to modify Gst.Buffer metadata in pad probe callbacks + +gst-editing-services + +- python: More typing fixes + +gst-devtools,gst-validate + gst-integration-testsuites + +- dotsviewer: Update Rust dependencies + +gst-examples + +- webrtc: Update Rust dependencies + +gstreamer-docs + +- No changes + +Development build environment + +- No changes + +Cerbero build tool and packaging changes in 1.26.10 + +- pkg-config: Ship it in the devel package +- recipe: Update License enums to SPDX expressions +- recipes: Fix GPL categorization of some plugins +- recipes: Fix stray devel files making it into runtime +- recipes: add GstApp python binding +- Modernize MSI license.rtf formatting +- Use ninja for all cmake recipes by default instead of GNU make +- ci: Mark a racy xcode toolchain bug for retrying + +Contributors to 1.26.10 + +Aaron Boxer, Brad Reitmeyer, Christoph Reiter, Doug Nazar, F. Duncanh, François Laignel, Haejung Hwang, Hou Qi, Hyunjun Ko, +Jakub Adam, Jan Schmidt, Jeongmin Kwak, Jerome Colle, L. E. Segovia, Mathieu Duponchelle, Nicolas Dufresne, Nirbheek Chauhan, +Philippe Normand, Piotr Brzeziński, Pratik Pachange, Robert Mader, Sanchayan Maity, Sebastian Dröge, Stéphane Cerveau, Thibault +Saunier, Tim-Philipp Müller, Tobias Schlager, Vivia Nikolaidou, Wilhelm Bartel, Xavier Claessens, Yun Liu, + +… and many others who have contributed bug reports,translations,sent suggestions or helped testing. Thank you all! + +List of merge requests and issues fixed in 1.26.10 + +- List of Merge Requests applied in 1.26.10 +- List of Issues fixed in 1.26.10 + Schedule for 1.28 Our next major feature release will be 1.28, and 1.27 will be the unstable development version leading up to the stable 1.28 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gst-python-1.26.9/RELEASE new/gst-python-1.26.10/RELEASE --- old/gst-python-1.26.9/RELEASE 2025-12-01 18:27:07.000000000 +0100 +++ new/gst-python-1.26.10/RELEASE 2025-12-25 15:44:26.000000000 +0100 @@ -1,4 +1,4 @@ -This is GStreamer gst-python 1.26.9. +This is GStreamer gst-python 1.26.10. The GStreamer team is thrilled to announce a new major feature release of your favourite cross-platform multimedia framework! diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gst-python-1.26.9/gi/__init__.py new/gst-python-1.26.10/gi/__init__.py --- old/gst-python-1.26.9/gi/__init__.py 2025-12-01 18:27:07.000000000 +0100 +++ new/gst-python-1.26.10/gi/__init__.py 2025-12-25 15:44:26.000000000 +0100 @@ -1,7 +1,7 @@ import gi import os import sys -import importlib.util +import typing from importlib.machinery import PathFinder from pathlib import Path @@ -12,11 +12,17 @@ import gi +if typing.TYPE_CHECKING: + # Stubs for type checking our overrides + def require_version(namespace: str, version: str) -> None: + pass + + class GstOverrideImport: def find_spec(self, fullname, path, target=None): if not fullname.startswith("gi.overrides"): return None - finder = importlib.machinery.PathFinder() + finder = PathFinder() # From find_spec the docs: # If name is for a submodule (contains a dot), the parent module is automatically imported. spec = finder.find_spec( diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gst-python-1.26.9/gi/overrides/Gst.py new/gst-python-1.26.10/gi/overrides/Gst.py --- old/gst-python-1.26.9/gi/overrides/Gst.py 2025-12-01 18:27:07.000000000 +0100 +++ new/gst-python-1.26.10/gi/overrides/Gst.py 2025-12-25 15:44:26.000000000 +0100 @@ -23,7 +23,9 @@ # SPDX-License-Identifier: LGPL-2.0-or-later from __future__ import annotations +from typing_extensions import Self +import sys import inspect import itertools import weakref @@ -41,19 +43,26 @@ # g-i generated API which does not have the same signature as our override # Bin.add(). The type checker will use signature from stubs which is our # override signature. - # - # For similar reason, make sure the type of arguments and return values - # are e.g. `Element` and not `Gst.Element`. Once copied into stubs, - # `Gst.Element` would not be defined, Gst module cannot refer to itself. from gi.repository import Gst + + # Type annotations cannot have `Gst.` prefix because they are copied into + # Gst stubs module which cannot refer to itself. Use type aliases. + MiniObject = Gst.MiniObject + MiniObjectFlags = Gst.MiniObjectFlags + FlowReturn = Gst.FlowReturn + PadDirection = Gst.PadDirection + PadLinkReturn = Gst.PadLinkReturn + MapFlags = Gst.MapFlags + BufferFlags = Gst.BufferFlags else: from gi.module import get_introspection_module Gst = get_introspection_module('Gst') + __all__ = [] -if Gst._version == '0.10': +if Gst.VERSION_MAJOR < 1: import warnings warn_msg = "You have imported the Gst 0.10 module. Because Gst 0.10 \ was not designed for use with introspection some of the \ @@ -79,12 +88,11 @@ @staticmethod def link_many(*args: Element) -> None: # type: ignore[override] ''' - @raises: Gst.LinkError + :raises Gst.LinkError ''' for pair in pairwise(args): if not pair[0].link(pair[1]): - raise LinkError( - 'Failed to link {} and {}'.format(pair[0], pair[1])) + raise LinkError(f'Failed to link {pair[0]} and {pair[1]}') override(Element) @@ -102,7 +110,7 @@ def make_and_add(self, factoryname: str, name: typing.Optional[str] = None) -> Element: ''' - @raises: Gst.AddError + :raises Gst.AddError: ''' elem = Gst.ElementFactory.make(factoryname, name) if not elem: @@ -124,21 +132,27 @@ __all__.append('NotWritableMiniObject') -class MiniObject: - def make_writable(self) -> MiniObject: +class MiniObjectMixin: + def make_writable(self) -> bool: return _gi_gst.mini_object_make_writable(self) def is_writable(self) -> bool: return _gi_gst.mini_object_is_writable(self) @property - def flags(self) -> Gst.MiniObjectFlags: + def flags(self) -> MiniObjectFlags: return _gi_gst.mini_object_flags(self) @flags.setter - def flags(self, flags: Gst.MiniObjectFlags) -> None: + def flags(self, flags: MiniObjectFlags) -> None: _gi_gst.mini_object_set_flags(self, flags) + def __ptr__(self): + return _gi_gst._get_object_ptr(self) + + +__all__.append('MiniObjectMixin') + class NotWritableQuery(Exception): pass @@ -147,13 +161,13 @@ __all__.append('NotWritableQuery') -class Query(MiniObject, Gst.Query): +class Query(MiniObjectMixin, Gst.Query): # type: ignore[misc] def get_structure(self) -> typing.Optional[Structure]: s = _gi_gst.query_get_structure(self) return s._set_parent(self) if s is not None else None - def writable_structure(self) -> StructureWrapper: - return StructureWrapper(_gi_gst.query_writable_structure(self)._set_parent(self)) + def writable_structure(self) -> StructureContextManager: # type: ignore[override] + return StructureContextManager(_gi_gst.query_writable_structure(self), self) # type: ignore[arg-type] override(Query) @@ -167,13 +181,13 @@ __all__.append('NotWritableEvent') -class Event(MiniObject, Gst.Event): +class Event(MiniObjectMixin, Gst.Event): # type: ignore[misc] def get_structure(self) -> typing.Optional[Structure]: s = _gi_gst.event_get_structure(self) return s._set_parent(self) if s is not None else None - def writable_structure(self) -> StructureWrapper: - return StructureWrapper(_gi_gst.event_writable_structure(self)._set_parent(self)) + def writable_structure(self) -> StructureContextManager: # type: ignore[override] + return StructureContextManager(_gi_gst.event_writable_structure(self), self) # type: ignore[arg-type] override(Event) @@ -187,13 +201,13 @@ __all__.append('NotWritableContext') -class Context(MiniObject, Gst.Context): - def get_structure(self) -> typing.Optional[Structure]: +class Context(MiniObjectMixin, Gst.Context): # type: ignore[misc] + def get_structure(self) -> Structure: s = _gi_gst.context_get_structure(self) - return s._set_parent(self) if s is not None else None + return s._set_parent(self) - def writable_structure(self) -> StructureWrapper: - return StructureWrapper(_gi_gst.context_writable_structure(self)._set_parent(self)) + def writable_structure(self) -> StructureContextManager: # type: ignore[override] + return StructureContextManager(_gi_gst.context_writable_structure(self), self) # type: ignore[arg-type] override(Context) @@ -214,7 +228,7 @@ __all__.append('NotWritableStructure') -class Caps(MiniObject, Gst.Caps): +class Caps(MiniObjectMixin, Gst.Caps): # type: ignore[misc] def __nonzero__(self): return not self.is_empty() @@ -245,32 +259,64 @@ def __init__(self, *args, **kwargs): return super(Caps, self).__init__() - def __str__(self): + def __str__(self) -> str: return self.to_string() - def __getitem__(self, index): - if index >= self.get_size(): - raise IndexError('structure index out of range') - - return Gst.Caps.get_structure(self, index) + def __getitem__(self, index: int) -> Structure: + return self.get_structure(index) - def __len__(self): + def __len__(self) -> int: return self.get_size() - def get_structure(self, index: int) -> typing.Optional[Structure]: + def get_structure(self, index: int) -> Structure: + if index >= self.get_size(): + raise IndexError('structure index out of range') s = _gi_gst.caps_get_structure(self, index) - return s._set_parent(self) if s is not None else None + return s._set_parent(self) - def writable_structure(self, index: int) -> StructureWrapper: - return StructureWrapper(_gi_gst.caps_writable_structure(self, index)._set_parent(self)) + def writable_structure(self, index: int) -> StructureContextManager: # type: ignore[override] + return StructureContextManager(_gi_gst.caps_writable_structure(self, index), self) # type: ignore[arg-type] override(Caps) __all__.append('Caps') +class PadProbeInfoObjectContextManager: + def __init__(self, object: MiniObject, info: PadProbeInfo): + self.__object = object + self.__info = info + + def __enter__(self) -> MiniObject: + return self.__object + + def __exit__(self, _type, _value, _tb): + self.__info.set_object(self.__object) + self.__object = None + self.__info = None + + +__all__.append('PadProbeInfoObjectContextManager') + + +class PadProbeInfo(Gst.PadProbeInfo): # type: ignore[misc] + def writable_object(self) -> PadProbeInfoObjectContextManager: # type: ignore[override] + '''Return writable object contained in this PadProbeInfo. + It uses a context manager to steal the object from the PadProbeInfo, + and set it back when exiting the context. + ''' + return PadProbeInfoObjectContextManager(_gi_gst.pad_probe_info_writable_object(self), self) + + def set_object(self, obj: typing.Optional[MiniObject]) -> None: + _gi_gst.pad_probe_info_set_object(self, obj) + + +setattr(sys.modules["gi.repository.Gst"], 'PadProbeInfo', PadProbeInfo) +__all__.append('PadProbeInfo') + + class PadFunc: - def __init__(self, func: typing.Callable[..., Gst.FlowReturn]): + def __init__(self, func: typing.Callable[..., FlowReturn]): self.func = func def __call__(self, pad, parent, obj): @@ -285,8 +331,7 @@ try: res = func(pad, parent, obj) except TypeError: - raise TypeError("Invalid method %s, 2 or 3 arguments required" - % func) + raise TypeError(f"Invalid method {func}, 2 or 3 arguments required") return res @@ -295,21 +340,21 @@ def __init__(self, *args, **kwargs): super(Gst.Pad, self).__init__(*args, **kwargs) - def set_chain_function(self, func: typing.Callable[..., Gst.FlowReturn]) -> None: + def set_chain_function(self, func: typing.Callable[..., FlowReturn]) -> None: self.set_chain_function_full(PadFunc(func), None) - def set_event_function(self, func: typing.Callable[..., Gst.FlowReturn]) -> None: + def set_event_function(self, func: typing.Callable[..., FlowReturn]) -> None: self.set_event_function_full(PadFunc(func), None) - def set_query_function(self, func: typing.Callable[..., Gst.FlowReturn]) -> None: + def set_query_function(self, func: typing.Callable[..., FlowReturn]) -> None: self.set_query_function_full(PadFunc(func), None) def query_caps(self, filter=None): return Gst.Pad.query_caps(self, filter) - def set_caps(self, caps: Gst.Caps) -> bool: + def set_caps(self, caps: Caps) -> bool: # type: ignore[override] if not isinstance(caps, Gst.Caps): - raise TypeError("%s is not a Gst.Caps." % (type(caps))) + raise TypeError(f"{type(caps)} is not a Gst.Caps.") if not caps.is_fixed(): return False @@ -323,7 +368,7 @@ return res - def link(self, pad: Gst.Pad) -> Gst.PadLinkReturn: + def link(self, pad: Pad) -> PadLinkReturn: ret = Gst.Pad.link(self, pad) if ret != Gst.PadLinkReturn.OK: raise LinkError(ret) @@ -335,7 +380,7 @@ class GhostPad(Gst.GhostPad): - def __init__(self, name: str, target: typing.Optional[Gst.Pad] = None, direction: typing.Optional[Gst.PadDirection] = None): + def __init__(self, name: str, target: typing.Optional[Pad] = None, direction: typing.Optional[PadDirection] = None): if direction is None: if target is None: raise TypeError('you must pass at least one of target ' @@ -347,7 +392,7 @@ if target is not None: self.set_target(target) - def query_caps(self, filter: typing.Optional[Gst.Caps] = None) -> Gst.Caps: + def query_caps(self, filter: typing.Optional[Caps] = None) -> Caps: return Gst.GhostPad.query_caps(self, filter) @@ -384,7 +429,7 @@ class Iterator(Gst.Iterator): - def __iter__(self): + def __iter__(self) -> typing.Iterator[typing.Any]: while True: result, value = self.next() if result == Gst.IteratorResult.DONE: @@ -414,9 +459,11 @@ @staticmethod def make(factoryname: str, name: typing.Optional[str] = None) -> typing.Optional[Element]: # type: ignore[override] + ''' + :raises Gst.PluginMissingError: + ''' elem = Gst.ElementFactory.make(factoryname, name) - assert elem is None or isinstance(elem, Element) # Tell mypy we actually have our override subclass - return elem + return elem # type: ignore[return-value] class Pipeline(Gst.Pipeline): @@ -428,6 +475,24 @@ __all__.append('Pipeline') +class StructureContextManager: + """A Gst.Structure wrapper to force usage of a context manager. + """ + def __init__(self, structure: Structure, parent: MiniObject): + self.__structure = structure + self.__parent = parent + + def __enter__(self) -> Structure: + return self.__structure + + def __exit__(self, _type, _value, _tb): + self.__structure = None + self.__parent = None + + +__all__.append('StructureContextManager') + + class Structure(Gst.Structure): def __new__(cls, *args, **kwargs): if not args: @@ -459,10 +524,10 @@ def __ptr__(self): return _gi_gst._get_object_ptr(self) - def __getitem__(self, key): + def __getitem__(self, key: str) -> typing.Any: return self.get_value(key) - def keys(self) -> set[str]: + def keys(self) -> typing.Iterable[str]: keys = set() def foreach(fid, value, unused1, udata): @@ -472,8 +537,8 @@ self.foreach(foreach, None, None) return keys - def __setitem__(self, key, value): - return self.set_value(key, value) + def __setitem__(self, key: str, value: typing.Any) -> None: + self.set_value(key, value) def set_value(self, key: str, value: typing.Any) -> bool: if not _gi_gst.structure_is_writable(self): @@ -490,7 +555,7 @@ self.__parent__ = parent return self - def __enter__(self): + def __enter__(self) -> Self: return self def __exit__(self, _type, _value, _tb): @@ -505,6 +570,9 @@ class Fraction(Gst.Fraction): + num: int + denom: int + def __init__(self, num: int, denom: int = 1): def __gcd(a, b): while b != 0: @@ -524,8 +592,8 @@ # Compute greatest common divisor gcd = __gcd(num, denom) if gcd != 0: - num /= gcd - denom /= gcd + num //= gcd + denom //= gcd self.num = num self.denom = denom @@ -536,54 +604,52 @@ __simplify() self.type = "fraction" - def __repr__(self): - return '<Gst.Fraction %s>' % (str(self)) + def __repr__(self) -> str: + return f'<Gst.Fraction {self}>' def __value__(self): return self.num / self.denom - def __eq__(self, other): + def __eq__(self, other: object) -> bool: if isinstance(other, Fraction): return self.num * other.denom == other.num * self.denom return False - def __ne__(self, other): + def __ne__(self, other: object) -> bool: return not self.__eq__(other) - def __mul__(self, other): + def __mul__(self, other: object) -> Fraction: if isinstance(other, Fraction): return Fraction(self.num * other.num, self.denom * other.denom) elif isinstance(other, int): return Fraction(self.num * other, self.denom) - raise TypeError("%s is not supported, use Gst.Fraction or int." % - (type(other))) + raise TypeError(f"{type(other)} is not supported, use Gst.Fraction or int.") __rmul__ = __mul__ - def __truediv__(self, other): + def __truediv__(self, other: object) -> Fraction: if isinstance(other, Fraction): return Fraction(self.num * other.denom, self.denom * other.num) elif isinstance(other, int): return Fraction(self.num, self.denom * other) - return TypeError("%s is not supported, use Gst.Fraction or int." % - (type(other))) + raise TypeError(f"{type(other)} is not supported, use Gst.Fraction or int.") __div__ = __truediv__ - def __rtruediv__(self, other): + def __rtruediv__(self, other: object) -> Fraction: if isinstance(other, int): return Fraction(self.denom * other, self.num) - return TypeError("%s is not an int." % (type(other))) + raise TypeError(f"{type(other)} is not an int.") __rdiv__ = __rtruediv__ - def __float__(self): + def __float__(self) -> float: return float(self.num) / float(self.denom) - def __str__(self): - return '%d/%d' % (self.num, self.denom) + def __str__(self) -> str: + return f'{self.num}/{self.denom}' override(Fraction) @@ -591,9 +657,9 @@ class IntRange(Gst.IntRange): - def __init__(self, r): + def __init__(self, r: range): if not isinstance(r, range): - raise TypeError("%s is not a range." % (type(r))) + raise TypeError(f"{type(r)} is not a range.") if (r.start >= r.stop): raise TypeError("Range start must be smaller then stop") @@ -606,18 +672,16 @@ self.range = r - def __repr__(self): - return '<Gst.IntRange [%d,%d,%d]>' % (self.range.start, - self.range.stop, self.range.step) + def __repr__(self) -> str: + return f'<Gst.IntRange [{self.range.start},{self.range.stop},{self.range.step}]>' - def __str__(self): + def __str__(self) -> str: if self.range.step == 1: - return '[%d,%d]' % (self.range.start, self.range.stop) + return f'[{self.range.start},{self.range.stop}]' else: - return '[%d,%d,%d]' % (self.range.start, self.range.stop, - self.range.step) + return f'[{self.range.start},{self.range.stop},{self.range.step}]' - def __eq__(self, other): + def __eq__(self, other: object) -> bool: if isinstance(other, range): return self.range == other elif isinstance(other, IntRange): @@ -630,9 +694,9 @@ class Int64Range(Gst.Int64Range): - def __init__(self, r): + def __init__(self, r: range): if not isinstance(r, range): - raise TypeError("%s is not a range." % (type(r))) + raise TypeError(f"{type(r)} is not a range.") if (r.start >= r.stop): raise TypeError("Range start must be smaller then stop") @@ -645,18 +709,16 @@ self.range = r - def __repr__(self): - return '<Gst.Int64Range [%d,%d,%d]>' % (self.range.start, - self.range.stop, self.range.step) + def __repr__(self) -> str: + return f'<Gst.Int64Range [{self.range.start},{self.range.stop},{self.range.step}]>' - def __str__(self): + def __str__(self) -> str: if self.range.step == 1: - return '(int64)[%d,%d]' % (self.range.start, self.range.stop) + return f'(int64)[{self.range.start},{self.range.stop}]' else: - return '(int64)[%d,%d,%d]' % (self.range.start, self.range.stop, - self.range.step) + return f'(int64)[{self.range.start},{self.range.stop},{self.range.step}]' - def __eq__(self, other): + def __eq__(self, other: object) -> bool: if isinstance(other, range): return self.range == other elif isinstance(other, IntRange): @@ -667,14 +729,14 @@ class Bitmask(Gst.Bitmask): def __init__(self, v: int) -> None: if not isinstance(v, int): - raise TypeError("%s is not an int." % (type(v))) + raise TypeError(f"{type(v)} is not an int.") self.v = int(v) - def __str__(self): + def __str__(self) -> str: return hex(self.v) - def __eq__(self, other): + def __eq__(self, other: object): return self.v == other @@ -694,11 +756,11 @@ if (start >= stop): raise TypeError("Range start must be smaller then stop") - def __repr__(self): - return '<Gst.DoubleRange [%s,%s]>' % (str(self.start), str(self.stop)) + def __repr__(self) -> str: + return f'<Gst.DoubleRange [{self.start},{self.stop}]>' - def __str__(self): - return '(double)[%s,%s]' % (str(self.range.start), str(self.range.stop)) + def __str__(self) -> str: + return f'(double)[{self.start},{self.stop}]' override(DoubleRange) @@ -708,10 +770,10 @@ class FractionRange(Gst.FractionRange): def __init__(self, start: Fraction, stop: Fraction): if not isinstance(start, Fraction): - raise TypeError("%s is not a Gst.Fraction." % (type(start))) + raise TypeError(f"{type(start)} is not a Gst.Fraction.") if not isinstance(stop, Fraction): - raise TypeError("%s is not a Gst.Fraction." % (type(stop))) + raise TypeError(f"{type(stop)} is not a Gst.Fraction.") if (float(start) >= float(stop)): raise TypeError("Range start must be smaller then stop") @@ -719,12 +781,11 @@ self.start = start self.stop = stop - def __repr__(self): - return '<Gst.FractionRange [%s,%s]>' % (str(self.start), - str(self.stop)) + def __repr__(self) -> str: + return f'<Gst.FractionRange [{self.start},{self.stop}]>' - def __str__(self): - return '(fraction)[%s,%s]' % (str(self.start), str(self.stop)) + def __str__(self) -> str: + return f'(fraction)[{self.start},{self.stop}]' override(FractionRange) @@ -732,23 +793,23 @@ class ValueArray(Gst.ValueArray): - def __init__(self, array): + def __init__(self, array: typing.List[typing.Any]): self.array = list(array) - def __getitem__(self, index): + def __getitem__(self, index: int) -> typing.Any: return self.array[index] - def __setitem__(self, index, value): + def __setitem__(self, index: int, value: typing.Any) -> None: self.array[index] = value - def __len__(self): + def __len__(self) -> int: return len(self.array) - def __str__(self): + def __str__(self) -> str: return '<' + ','.join(map(str, self.array)) + '>' - def __repr__(self): - return '<Gst.ValueArray %s>' % (str(self)) + def __repr__(self) -> str: + return f'<Gst.ValueArray {self}>' override(ValueArray) @@ -756,23 +817,23 @@ class ValueList(Gst.ValueList): - def __init__(self, array): + def __init__(self, array: typing.List[typing.Any]): self.array = list(array) - def __getitem__(self, index): + def __getitem__(self, index: int) -> typing.Any: return self.array[index] - def __setitem__(self, index, value): + def __setitem__(self, index: int, value: typing.Any) -> None: self.array[index] = value - def __len__(self): + def __len__(self) -> int: return len(self.array) - def __str__(self): + def __str__(self) -> str: return '{' + ','.join(map(str, self.array)) + '}' - def __repr__(self): - return '<Gst.ValueList %s>' % (str(self)) + def __repr__(self) -> str: + return f'<Gst.ValueList {self}>' override(ValueList) @@ -783,7 +844,7 @@ def __init__(self): Gst.TagList.__init__(self) - def __getitem__(self, index): + def __getitem__(self, index: int) -> typing.Any: if index >= self.n_tags(): raise IndexError('taglist index out of range') @@ -793,30 +854,30 @@ raise KeyError(f"tag {key} not found") return val - def __setitem__(self, key, value): - self.add(Gst.TagMergeMode.REPLACE, key, value) + def __setitem__(self, key: str, value: typing.Any) -> None: + self.add_value(Gst.TagMergeMode.REPLACE, key, value) - def keys(self): + def keys(self) -> typing.Iterable[str]: keys = set() - def foreach(list, fid, value, udata): + def foreach(list, fid: str, udata): keys.add(fid) return True self.foreach(foreach, None, None) return keys - def enumerate(self): + def enumerate(self) -> map[tuple[str, typing.Any]]: return map(lambda k: (k, Gst.TagList.copy_value(self, k)[1]), self.keys()) - def __len__(self): + def __len__(self) -> int: return self.n_tags() - def __str__(self): + def __str__(self) -> str: return self.to_string() - def __repr__(self): - return '<Gst.TagList %s>' % (str(self)) + def __repr__(self) -> str: + return f'<Gst.TagList {self}>' override(TagList) @@ -831,19 +892,6 @@ return zip(a, b) -class StructureWrapper: - """A Gst.Structure wrapper to force usage of a context manager. - """ - def __init__(self, structure: Structure): - self.__structure = structure - - def __enter__(self) -> Structure: - return self.__structure - - def __exit__(self, _type, _value, _tb): - self.__structure._set_parent(None) - - class MapInfo: def __init__(self): self.memory = None @@ -860,7 +908,7 @@ for i in (self.__parent__ is not None, self): yield i - def __enter__(self): + def __enter__(self) -> Self: if not self.__parent__: raise MapError('MappingError', 'Mapping was not successful') @@ -874,13 +922,13 @@ __all__.append("MapInfo") -class Buffer(MiniObject, Gst.Buffer): +class Buffer(MiniObjectMixin, Gst.Buffer): @property # type: ignore[override] - def flags(self) -> Gst.BufferFlags: + def flags(self) -> BufferFlags: return _gi_gst.mini_object_flags(self) @flags.setter - def flags(self, flags: Gst.BufferFlags) -> None: + def flags(self, flags: BufferFlags) -> None: _gi_gst.mini_object_set_flags(self, flags) @property @@ -923,14 +971,14 @@ def offset_end(self, offset_end: int) -> None: _gi_gst.buffer_set_offset_end(self, offset_end) - def map_range(self, idx: int, length: int, flags: Gst.MapFlags) -> MapInfo: # type: ignore[override] + def map_range(self, idx: int, length: int, flags: MapFlags) -> MapInfo: # type: ignore[override] mapinfo = MapInfo() if (_gi_gst.buffer_override_map_range(self, mapinfo, idx, length, int(flags))): mapinfo.__parent__ = self return mapinfo - def map(self, flags: Gst.MapFlags) -> MapInfo: # type: ignore[override] + def map(self, flags: MapFlags) -> MapInfo: # type: ignore[override] mapinfo = MapInfo() if _gi_gst.buffer_override_map(self, mapinfo, int(flags)): mapinfo.__parent__ = self @@ -948,7 +996,7 @@ class Memory(Gst.Memory): - def map(self, flags: Gst.MapFlags) -> MapInfo: # type: ignore[override] + def map(self, flags: MapFlags) -> MapInfo: # type: ignore[override] mapinfo = MapInfo() if (_gi_gst.memory_override_map(self, mapinfo, int(flags))): mapinfo.__parent__ = self diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gst-python-1.26.9/gi/overrides/gstmodule.c new/gst-python-1.26.10/gi/overrides/gstmodule.c --- old/gst-python-1.26.9/gi/overrides/gstmodule.c 2025-12-01 18:27:07.000000000 +0100 +++ new/gst-python-1.26.10/gi/overrides/gstmodule.c 2025-12-25 15:44:26.000000000 +0100 @@ -1676,6 +1676,52 @@ return success; } +static PyObject * +_gst_pad_probe_info_writable_object (PyObject * self, PyObject * args) +{ + PyObject *py_info = PyTuple_GetItem (args, 0); + if (py_info == NULL) { + PyErr_SetString (PyExc_TypeError, "Expected a PyGObject"); + return NULL; + } + + GstPadProbeInfo *info = pyg_boxed_get (py_info, GstPadProbeInfo); + if (info->data == NULL) + return NULL; + + /* Make object writable and transfer ownership to python */ + GstMiniObject *mini_object = GST_MINI_OBJECT (info->data); + mini_object = gst_mini_object_make_writable (mini_object); + info->data = NULL; + return pyg_boxed_new (GST_MINI_OBJECT_TYPE (mini_object), mini_object, FALSE, + TRUE); +} + +static PyObject * +_gst_pad_probe_info_set_object (PyObject * self, PyObject * args) +{ + PyObject *py_info = PyTuple_GetItem (args, 0); + if (py_info == NULL) { + PyErr_SetString (PyExc_TypeError, "Expected a PyGObject"); + return NULL; + } + PyObject *py_obj = PyTuple_GetItem (args, 1); + if (py_obj == NULL) { + PyErr_SetString (PyExc_TypeError, "Expected a PyGObject"); + return NULL; + } + + GstPadProbeInfo *info = pyg_boxed_get (py_info, GstPadProbeInfo); + gst_clear_mini_object (&info->data); + if (py_obj != Py_None) { + GstMiniObject *obj = pyg_boxed_get (py_obj, GstMiniObject); + info->data = gst_mini_object_ref (obj); + } + + Py_INCREF (Py_None); + return Py_None; +} + /* *INDENT-OFF* */ static PyMethodDef _gi_gst_functions[] = { {"trace", (PyCFunction) _wrap_gst_trace, METH_VARARGS, NULL}, @@ -1724,6 +1770,9 @@ {"buffer_get_offset_end", (PyCFunction) _gst_buffer_get_offset_end, METH_VARARGS, NULL}, {"buffer_set_offset_end", (PyCFunction) _gst_buffer_set_offset_end, METH_VARARGS, NULL}, + {"pad_probe_info_writable_object", (PyCFunction)_gst_pad_probe_info_writable_object, METH_VARARGS, NULL}, + {"pad_probe_info_set_object", (PyCFunction)_gst_pad_probe_info_set_object, METH_VARARGS, NULL}, + {"_get_object_ptr", (PyCFunction) _gst_get_object_ptr, METH_VARARGS, NULL}, {NULL, NULL, 0, NULL} }; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gst-python-1.26.9/gi/overrides/meson.build new/gst-python-1.26.10/gi/overrides/meson.build --- old/gst-python-1.26.9/gi/overrides/meson.build 2025-12-01 18:27:07.000000000 +0100 +++ new/gst-python-1.26.10/gi/overrides/meson.build 2025-12-25 15:44:26.000000000 +0100 @@ -31,8 +31,6 @@ ) env = environment() -env.prepend('_GI_OVERRIDES_PATH', [ - meson.current_source_dir(), - meson.current_build_dir() -]) +env.prepend('_GI_OVERRIDES_PATH', [meson.current_source_dir(), meson.current_build_dir()]) +env.prepend('PYGI_OVERRIDES_PATH', [meson.current_source_dir(), meson.current_build_dir()]) meson.add_devenv(env) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gst-python-1.26.9/gst-python.doap new/gst-python-1.26.10/gst-python.doap --- old/gst-python-1.26.9/gst-python.doap 2025-12-01 18:27:07.000000000 +0100 +++ new/gst-python-1.26.10/gst-python.doap 2025-12-25 15:44:26.000000000 +0100 @@ -32,6 +32,16 @@ <release> <Version> + <revision>1.26.10</revision> + <branch>1.26</branch> + <name></name> + <created>2025-12-25</created> + <file-release rdf:resource="https://gstreamer.freedesktop.org/src/gst-python/gst-python-1.26.10.tar.xz" /> + </Version> + </release> + + <release> + <Version> <revision>1.26.9</revision> <branch>1.26</branch> <name></name> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gst-python-1.26.9/meson.build new/gst-python-1.26.10/meson.build --- old/gst-python-1.26.9/meson.build 2025-12-01 18:27:07.000000000 +0100 +++ new/gst-python-1.26.10/meson.build 2025-12-25 15:44:26.000000000 +0100 @@ -1,5 +1,5 @@ project('gst-python', 'c', - version : '1.26.9', + version : '1.26.10', meson_version : '>= 1.4', default_options : [ 'warning_level=1', 'buildtype=debugoptimized' ]) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gst-python-1.26.9/testsuite/meson.build new/gst-python-1.26.10/testsuite/meson.build --- old/gst-python-1.26.9/testsuite/meson.build 2025-12-01 18:27:07.000000000 +0100 +++ new/gst-python-1.26.10/testsuite/meson.build 2025-12-25 15:44:26.000000000 +0100 @@ -2,6 +2,7 @@ tests = [ ['Test gst', 'test_gst.py'], + ['gstinit', 'test_gst_init.py'], ['Test fundamentals', 'test_types.py'], ['Test plugins', 'test_plugin.py'], ['Test analytics', 'test_analytics.py', ['gst-plugins-bad/gst-libs/gst/analytics', 'gst-plugins-base/gst-libs/gst/video']], diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gst-python-1.26.9/testsuite/test_gst.py new/gst-python-1.26.10/testsuite/test_gst.py --- old/gst-python-1.26.9/testsuite/test_gst.py 2025-12-01 18:27:07.000000000 +0100 +++ new/gst-python-1.26.10/testsuite/test_gst.py 2025-12-25 15:44:26.000000000 +0100 @@ -43,45 +43,6 @@ self.assertEqual(Gst.TIME_ARGS(Gst.SECOND), '0:00:01.000000000') -class TestNotInitialized(TestCase): - def testNotInitialized(self): - if sys.version_info >= (3, 0): - assert_type = Gst.NotInitialized - else: - assert_type = TypeError - - with self.assertRaises(assert_type): - Gst.Caps.from_string("audio/x-raw") - - with self.assertRaises(assert_type): - Gst.Structure.from_string("audio/x-raw") - - with self.assertRaises(assert_type): - Gst.ElementFactory.make("identity", None) - - def testNotDeinitialized(self): - Gst.init(None) - - self.assertIsNotNone(Gst.Caps.from_string("audio/x-raw")) - self.assertIsNotNone(Gst.Structure.from_string("audio/x-raw")) - self.assertIsNotNone(Gst.ElementFactory.make("identity", None)) - - Gst.deinit() - if sys.version_info >= (3, 0): - assert_type = Gst.NotInitialized - else: - assert_type = TypeError - - with self.assertRaises(assert_type): - Gst.Caps.from_string("audio/x-raw") - - with self.assertRaises(assert_type): - Gst.Structure.from_string("audio/x-raw") - - with self.assertRaises(assert_type): - Gst.ElementFactory.make("identity", None) - - class TestCaps(TestCase): def test_writable_make_writable_no_copy(self): @@ -311,5 +272,62 @@ info.data[0] +class TestPadProbe(TestCase): + + def test_pad_probe(self): + Gst.init(None) + pipeline = Gst.Pipeline("pipeline") + src = pipeline.make_and_add("fakesrc", "src") + sink = pipeline.make_and_add("fakesink", "sink") + src.link(sink) + + src.props.num_buffers = 5 + + buffer_count = 0 + + def probe_cb(pad, info): + nonlocal buffer_count + + buffer_count += 1 + + # Get a writable buffer from the probe info + with info.writable_object() as buffer: + self.assertIsInstance(buffer, Gst.Buffer) + self.assertTrue(buffer.is_writable()) + buffer.pts = buffer_count * Gst.SECOND * 2 + ptr = buffer.__ptr__() + # Info does not hold a buffer any more + self.assertIsNone(info.get_buffer()) + + # info.get_buffer() never returns a writable buffer because both + # python and GstPadProbeInfo hold references to it. + buffer = info.get_buffer() + self.assertIsNotNone(buffer) + self.assertFalse(buffer.is_writable()) + self.assertEqual(buffer.pts, buffer_count * Gst.SECOND * 2) + self.assertEqual(buffer.__ptr__(), ptr) + + return Gst.PadProbeReturn.OK + + sink_pad = sink.get_static_pad("sink") + probe_id = sink_pad.add_probe(Gst.PadProbeType.BUFFER, probe_cb) + + pipeline.set_state(Gst.State.PLAYING) + bus = pipeline.get_bus() + msg = bus.timed_pop_filtered(Gst.SECOND * 5, Gst.MessageType.EOS) + self.assertIsNotNone(msg) + + # We should have seen exactly 5 buffers + self.assertEqual(buffer_count, 5) + + # Check that last buffer has the expected PTS + sample = sink.props.last_sample + buffer = sample.get_buffer() + self.assertEqual(buffer.pts, buffer_count * Gst.SECOND * 2) + + sink_pad.remove_probe(probe_id) + pipeline.set_state(Gst.State.NULL) + + if __name__ == "__main__": unittest.main() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gst-python-1.26.9/testsuite/test_gst_init.py new/gst-python-1.26.10/testsuite/test_gst_init.py --- old/gst-python-1.26.9/testsuite/test_gst_init.py 1970-01-01 01:00:00.000000000 +0100 +++ new/gst-python-1.26.10/testsuite/test_gst_init.py 2025-12-25 15:44:26.000000000 +0100 @@ -0,0 +1,68 @@ +# -*- Mode: Python -*- +# vi:si:et:sw=4:sts=4:ts=4 +# +# Copyright (C) 2009 Thomas Vander Stichele +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +import overrides_hack +import sys +from common import TestCase, unittest +from gi.repository import Gst +import gi + + +gi.require_version('Gst', '1.0') + + +overrides_hack + + +class TestNotInitialized(TestCase): + def testNotInitialized(self): + if sys.version_info >= (3, 0): + assert_type = Gst.NotInitialized + else: + assert_type = TypeError + + with self.assertRaises(assert_type): + Gst.Caps.from_string("audio/x-raw") + + with self.assertRaises(assert_type): + Gst.Structure.from_string("audio/x-raw") + + with self.assertRaises(assert_type): + Gst.ElementFactory.make("identity", None) + + def testNotDeinitialized(self): + Gst.init(None) + + self.assertIsNotNone(Gst.Caps.from_string("audio/x-raw")) + self.assertIsNotNone(Gst.Structure.from_string("audio/x-raw")) + self.assertIsNotNone(Gst.ElementFactory.make("identity", None)) + + Gst.deinit() + if sys.version_info >= (3, 0): + assert_type = Gst.NotInitialized + else: + assert_type = TypeError + + with self.assertRaises(assert_type): + Gst.Caps.from_string("audio/x-raw") + + with self.assertRaises(assert_type): + Gst.Structure.from_string("audio/x-raw") + + with self.assertRaises(assert_type): + Gst.ElementFactory.make("identity", None) ++++++ gst-python.obsinfo ++++++ --- /var/tmp/diff_new_pack.9dKa9D/_old 2025-12-31 10:47:30.406678445 +0100 +++ /var/tmp/diff_new_pack.9dKa9D/_new 2025-12-31 10:47:30.438679754 +0100 @@ -1,5 +1,5 @@ name: gst-python -version: 1.26.9 -mtime: 1764610027 -commit: f313fae193089408e278c0dd3450145e5a12307b +version: 1.26.10 +mtime: 1766673866 +commit: bfdc62185e243d3633aa916187a566d03a587792
