Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-pyppmd for openSUSE:Factory checked in at 2026-02-17 16:52:46 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-pyppmd (Old) and /work/SRC/openSUSE:Factory/.python-pyppmd.new.1977 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-pyppmd" Tue Feb 17 16:52:46 2026 rev:6 rq:1333514 version:1.3.1 Changes: -------- --- /work/SRC/openSUSE:Factory/python-pyppmd/python-pyppmd.changes 2025-06-23 15:05:43.766876708 +0200 +++ /work/SRC/openSUSE:Factory/.python-pyppmd.new.1977/python-pyppmd.changes 2026-02-17 16:57:50.705743241 +0100 @@ -1,0 +2,32 @@ +Sat Feb 14 08:38:38 UTC 2026 - Andreas Prittwitz <[email protected]> + +- Update to version 1.3.1 + * Change BuildRequires for: + - python-devel to >= 3.10 + * Add BuildRequires for: + - python-pytest-cov + * Remove extra export CFLAGS statement from %build section. + This statement makes test_ppmd_7_decode_chunks crash + with: Fatal Python error: Aborted (core dumped) with + version 1.3.1. + * Disable test_ppmd8.py for automated test runs and + add separate test run for test_ppmd8.py to ensure it passes + reliably. + See comment in spec file. + * Fix publish CI/CD configuration + * Bump musllinux image musllinux_1_2 + * Bump manylinux image manylinux_2_28 +- Changes in version 1.3.0 + * Fix several issues in ThreadDecoder.c (#126) + * Fix the double call of Ppmd7_Free from both + Ppmd7T_Free and Ppmd7Decoder_dealloc + * Fix the double call of Ppmd8_Free from both + Ppmd8T_Free and Ppmd8Decoder_dealloc + * Fix the issue in PyPY (#126) + * Fix initialization order in ffi_build.py + * Fix eof handling in cffi_ppmd.py + * Add support for Python 3.14 + * Add compile and link flag for building C++ with + `-pthread` (#126) + * Minimum required python to be 3.10 +------------------------------------------------------------------- Old: ---- pyppmd-1.2.0.tar.gz New: ---- pyppmd-1.3.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-pyppmd.spec ++++++ --- /var/tmp/diff_new_pack.Sn3zBl/_old 2026-02-17 16:57:54.997923075 +0100 +++ /var/tmp/diff_new_pack.Sn3zBl/_new 2026-02-17 16:57:54.997923075 +0100 @@ -1,7 +1,7 @@ # # spec file for package python-pyppmd # -# Copyright (c) 2025 SUSE LLC +# Copyright (c) 2026 SUSE LLC and contributors # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -18,13 +18,13 @@ %{?sle15_python_module_pythons} Name: python-pyppmd -Version: 1.2.0 +Version: 1.3.1 Release: 0 Summary: PPMd compression/decompression library License: LGPL-2.1-or-later -URL: https://codeberg.org/miurahr/pyppmd +URL: https://github.com/miurahr/pyppmd Source: https://files.pythonhosted.org/packages/source/p/pyppmd/pyppmd-%{version}.tar.gz -BuildRequires: %{python_module devel >= 3.9} +BuildRequires: %{python_module devel >= 3.10} BuildRequires: %{python_module pip} BuildRequires: %{python_module setuptools_scm >= 6.0.1} BuildRequires: %{python_module wheel} @@ -35,6 +35,7 @@ BuildRequires: %{python_module py-cpuinfo} BuildRequires: %{python_module pytest >= 6} BuildRequires: %{python_module pytest-benchmark} +BuildRequires: %{python_module pytest-cov} BuildRequires: %{python_module pytest-timeout} # /SECTION %python_subpackages @@ -65,7 +66,6 @@ sed -i 's/milliseconds=300/milliseconds=5000/g' tests/test_fuzzer.py %build -export CFLAGS="%{optflags}" %pyproject_wheel %install @@ -73,7 +73,10 @@ %python_expand %fdupes %{buildroot}%{$python_sitearch} %check -%pytest_arch --hypothesis-profile=obs +# test_ppmd8 hangs randomly in automated pytest runs. +# This test is run separately in the build process to ensure it passes. +%pytest_arch --hypothesis-profile=obs -k "not test_ppmd8" +%pytest_arch --hypothesis-profile=obs tests/test_ppmd8.py %files %{python_files} %doc Changelog.rst README.rst ++++++ pyppmd-1.2.0.tar.gz -> pyppmd-1.3.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyppmd-1.2.0/.github/workflows/publish-to-pypi.yml new/pyppmd-1.3.1/.github/workflows/publish-to-pypi.yml --- old/pyppmd-1.2.0/.github/workflows/publish-to-pypi.yml 2025-05-01 13:28:58.000000000 +0200 +++ new/pyppmd-1.3.1/.github/workflows/publish-to-pypi.yml 2025-11-27 22:58:19.000000000 +0100 @@ -26,9 +26,9 @@ - name: Fetch release tags run: git fetch --depth=1 origin +refs/tags/*:refs/tags/* - name: Set up Python ๐ - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: - python-version: 3.11 + python-version: 3.13 - name: Install cibuildwheel run: | python -m pip install -U pip cibuildwheel @@ -59,7 +59,7 @@ - name: Fetch release tags run: git fetch --depth=1 origin +refs/tags/*:refs/tags/* - name: Set up Python ๐ - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: 3.11 - name: Build source distribution & wheels๐ก diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyppmd-1.2.0/.github/workflows/run-tox-tests.yml new/pyppmd-1.3.1/.github/workflows/run-tox-tests.yml --- old/pyppmd-1.2.0/.github/workflows/run-tox-tests.yml 2025-05-01 13:28:58.000000000 +0200 +++ new/pyppmd-1.3.1/.github/workflows/run-tox-tests.yml 2025-11-27 22:58:19.000000000 +0100 @@ -18,16 +18,20 @@ matrix: os: [ubuntu-24.04, windows-latest] python-version: [ - "3.9", "3.10", "3.11", "3.12", "3.13", + "3.14", "pypy-3.10", ] include: - os: macos-latest - python-version: "3.11" + python-version: "3.14" + - os: ubuntu-24.04-arm + python-version: "3.13" + - os: windows-11-arm + python-version: "3.13" exclude: - os: windows-latest python-version: 'pypy-3.10' @@ -37,10 +41,9 @@ with: fetch-depth: 20 - name: Setup python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: ${{ matrix.python-version }} - architecture: x64 - name: Install dependencies run: | pip install -U pip tox wheel setuptools setuptools_scm[toml] @@ -48,32 +51,3 @@ - name: Test project with tox run: | tox - - test_on_aarch64: - name: Test on ${{ matrix.arch }} - runs-on: ubuntu-22.04 - strategy: - matrix: - arch: [aarch64] - distro: [ubuntu22.04] - steps: - - name: Checkout ๐๏ธ - uses: actions/checkout@v4 - with: - fetch-depth: 20 - - name: Build & run test - uses: uraimo/run-on-arch-action@v2 - with: - arch: ${{ matrix.arch }} - distro: ${{ matrix.distro }} - githubToken: ${{ github.token }} - install: | - apt-get update -q -y - apt-get install -q -y python3 python3-pip python3-dev build-essential gcc git - python3 -m pip install -U pip tox setuptools setuptools_scm[toml] - run: | - git config --global --add safe.directory ${GITHUB_WORKSPACE} - python3 -c "import platform;print('Machine type:', platform.machine())" - python3 -m tox -e py310 - env: | - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyppmd-1.2.0/Changelog.rst new/pyppmd-1.3.1/Changelog.rst --- old/pyppmd-1.2.0/Changelog.rst 2025-05-01 13:28:58.000000000 +0200 +++ new/pyppmd-1.3.1/Changelog.rst 2025-11-27 22:58:19.000000000 +0100 @@ -7,6 +7,36 @@ `Unreleased`_ ============= +v1.3.1_ +======= + +Fixed +----- +* Fix publish CI/CD configuration + * Bump musllinux image musllinux_1_2 + * Bump manylinux image manylinux_2_28 + +v1.3.0_ +======= + +Fixed +----- +* Fix several issues in ThreadDecoder.c (#126) + * Fix the double call of Ppmd7_Free from both Ppmd7T_Free and Ppmd7Decoder_dealloc + * Fix the double call of Ppmd8_Free from both Ppmd8T_Free and Ppmd8Decoder_dealloc +* Fix the issue in PyPY (#126) + * Fix initialization order in ffi_build.py + * Fix eof handling in cffi_ppmd.py + +Added +----- +* Add support for Python 3.14 + +Changed +------- +* Add compile and link flag for building C++ with `-pthread` (#126) +* Minimum required python to be 3.10 + v1.2.0_ ======= @@ -126,7 +156,9 @@ .. History links -.. _Unreleased: https://github.com/miurahr/pyppmd/compare/v1.2.0...HEAD +.. _Unreleased: https://github.com/miurahr/pyppmd/compare/v1.3.1...HEAD +.. _v1.3.1: https://github.com/miurahr/pyppmd/compare/v1.3.0...v1.3.1 +.. _v1.3.0: https://github.com/miurahr/pyppmd/compare/v1.2.0...v1.3.0 .. _v1.2.0: https://github.com/miurahr/pyppmd/compare/v1.1.1...v1.2.0 .. _v1.1.1: https://github.com/miurahr/pyppmd/compare/v1.0.0...v1.1.1 .. _v1.1.0: https://github.com/miurahr/pyppmd/compare/v1.0.0...v1.1.0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyppmd-1.2.0/PKG-INFO new/pyppmd-1.3.1/PKG-INFO --- old/pyppmd-1.2.0/PKG-INFO 2025-05-01 13:29:04.781758300 +0200 +++ new/pyppmd-1.3.1/PKG-INFO 2025-11-27 22:58:24.000000000 +0100 @@ -1,13 +1,13 @@ Metadata-Version: 2.4 Name: pyppmd -Version: 1.2.0 +Version: 1.3.1 Summary: PPMd compression/decompression library Author-email: Hiroshi Miura <[email protected]> License: LGPL-2.1-or-later -Project-URL: Source, https://codeberg.org/miurahr/pyppmd +Project-URL: Source, https://github.com/miurahr/pyppmd Project-URL: Homepage, https://pyppmd.readthedocs.io/ Project-URL: Documentation, https://pyppmd.readthedocs.io/en/stable/ -Project-URL: Bug Tracker, https://codeberg.org/miurahr/pyppmd/issues +Project-URL: Bug Tracker, https://github.com/miurahr/pyppmd/issues Project-URL: Changelog, https://pyppmd.readthedocs.io/en/latest/changelog.html Classifier: Development Status :: 5 - Production/Stable Classifier: Operating System :: MacOS :: MacOS X @@ -16,16 +16,16 @@ Classifier: Operating System :: POSIX :: Linux Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.9 Classifier: Programming Language :: Python :: 3.10 Classifier: Programming Language :: Python :: 3.11 Classifier: Programming Language :: Python :: 3.12 Classifier: Programming Language :: Python :: 3.13 +Classifier: Programming Language :: Python :: 3.14 Classifier: Programming Language :: Python :: 3 :: Only Classifier: Programming Language :: Python :: Implementation :: CPython Classifier: Programming Language :: Python :: Implementation :: PyPy Classifier: Topic :: Software Development :: Libraries :: Python Modules -Requires-Python: >=3.9 +Requires-Python: >=3.10 Description-Content-Type: text/x-rst License-File: LICENSE Provides-Extra: test diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyppmd-1.2.0/pyproject.toml new/pyppmd-1.3.1/pyproject.toml --- old/pyppmd-1.2.0/pyproject.toml 2025-05-01 13:28:58.000000000 +0200 +++ new/pyppmd-1.3.1/pyproject.toml 2025-11-27 22:58:19.000000000 +0100 @@ -1,6 +1,6 @@ [project] name = "pyppmd" -requires-python = ">=3.9" +requires-python = ">=3.10" description = "PPMd compression/decompression library" readme = "README.rst" license = {text = "LGPL-2.1-or-later"} @@ -15,11 +15,11 @@ "Operating System :: POSIX :: Linux", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", "Programming Language :: Python :: 3 :: Only", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", @@ -55,10 +55,10 @@ ] [project.urls] -Source = "https://codeberg.org/miurahr/pyppmd" +Source = "https://github.com/miurahr/pyppmd" Homepage = "https://pyppmd.readthedocs.io/" Documentation = "https://pyppmd.readthedocs.io/en/stable/" -"Bug Tracker" = "https://codeberg.org/miurahr/pyppmd/issues" +"Bug Tracker" = "https://github.com/miurahr/pyppmd/issues" Changelog = "https://pyppmd.readthedocs.io/en/latest/changelog.html" [build-system] @@ -113,18 +113,18 @@ norecursedirs = [".git", "_build", "tmp", ".eggs"] [tool.cibuildwheel] -manylinux-x86_64-image = "manylinux2014" -manylinux-i686-image = "manylinux2014" -manylinux-aarch64-image = "manylinux2014" -manylinux-ppc64le-image = "manylinux2014" -manylinux-s390x-image = "manylinux2014" -manylinux-pypy_x86_64-image = "manylinux2014" -manylinux-pypy_aarch64-image = "manylinux2014" - -musllinux-x86_64-image = "musllinux_1_1" -musllinux-aarch64-image = "musllinux_1_1" -musllinux-ppc64le-image = "musllinux_1_1" -musllinux-s390x-image = "musllinux_1_1" +manylinux-x86_64-image = "manylinux_2_28" +manylinux-i686-image = "manylinux_2_28" +manylinux-aarch64-image = "manylinux_2_28" +manylinux-ppc64le-image = "manylinux_2_28" +manylinux-s390x-image = "manylinux_2_28" +manylinux-pypy_x86_64-image = "manylinux_2_28" +manylinux-pypy_aarch64-image = "manylinux_2_28" + +musllinux-x86_64-image = "musllinux_1_2" +musllinux-aarch64-image = "musllinux_1_2" +musllinux-ppc64le-image = "musllinux_1_2" +musllinux-s390x-image = "musllinux_1_2" [tool.cibuildwheel.linux] archs = ["auto64", "aarch64"] @@ -135,7 +135,7 @@ [tool.tox] legacy_tox_ini = """ [tox] -envlist = check, py{39,310,311,312,313}, pypy39, docs +envlist = check, py{310,311,312,313,314}, pypy310, docs [testenv] passenv = @@ -145,8 +145,8 @@ commands = python -m pytest -vv -s -[testenv:pypy39] -basepython = pypy3.9 +[testenv:pypy310] +basepython = pypy3.10 [testenv:check] basepython = python3.12 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyppmd-1.2.0/setup.py new/pyppmd-1.3.1/setup.py --- old/pyppmd-1.2.0/setup.py 2025-05-01 13:28:58.000000000 +0200 +++ new/pyppmd-1.3.1/setup.py 2025-11-27 22:58:19.000000000 +0100 @@ -11,6 +11,8 @@ "include_dirs": ["src/lib/ppmd", "src/lib/buffer"], "library_dirs": [], "libraries": [], + "extra_compile_args": [], + "extra_link_args": [], "sources": [ "src/lib/ppmd/Ppmd7.c", "src/lib/ppmd/Ppmd8.c", @@ -62,6 +64,11 @@ def build_extensions(self): for extension in self.extensions: if self.compiler.compiler_type.lower() in ("unix", "mingw32"): + # Ensure pthread is used for synchronization primitives + extension.extra_compile_args.append("-pthread") + if not hasattr(extension, "extra_link_args") or extension.extra_link_args is None: + extension.extra_link_args = [] + extension.extra_link_args.append("-pthread") if WARNING_AS_ERROR: extension.extra_compile_args.append("-Werror") elif self.compiler.compiler_type.lower() == "msvc": diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyppmd-1.2.0/src/ext/ffi_build.py new/pyppmd-1.3.1/src/ext/ffi_build.py --- old/pyppmd-1.2.0/src/ext/ffi_build.py 2025-05-01 13:28:58.000000000 +0200 +++ new/pyppmd-1.3.1/src/ext/ffi_build.py 2025-11-27 22:58:19.000000000 +0100 @@ -320,10 +320,14 @@ int ppmd7_decompress_init(CPpmd7z_RangeDec *rc, BufferReader *reader, ppmd_info *info, IAllocPtr allocator) { - reader->Read = (Byte (*)(void *)) Reader; + /* Use threaded reader and initialize thread control BEFORE range init, + since RangeDec_Init will read from the stream immediately. */ + reader->Read = (Byte (*)(void *)) Ppmd_thread_Reader; + reader->t = info; + info->in = reader->inBuffer; + Ppmd_thread_decode_init(info, allocator); rc->Stream = (IByteIn *) reader; Bool res = Ppmd7z_RangeDec_Init(rc); - Ppmd_thread_decode_init(info, allocator); return res; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyppmd-1.2.0/src/lib/buffer/ThreadDecoder.c new/pyppmd-1.3.1/src/lib/buffer/ThreadDecoder.c --- old/pyppmd-1.2.0/src/lib/buffer/ThreadDecoder.c 2025-05-01 13:28:58.000000000 +0200 +++ new/pyppmd-1.3.1/src/lib/buffer/ThreadDecoder.c 2025-11-27 22:58:19.000000000 +0100 @@ -4,6 +4,7 @@ #include "ThreadDecoder.h" #include "Buffer.h" +#include <time.h> #ifdef __APPLE__ #include <mach/clock.h> #include <mach/mach.h> @@ -56,6 +57,11 @@ } #endif +/* cleanup helper for pthread_cleanup_push/pop */ +static void ppmd_mutex_unlock(void *m) { + pthread_mutex_unlock((pthread_mutex_t *)m); +} + Byte Ppmd_thread_Reader(const void *p) { BufferReader *bufferReader = (BufferReader *)p; ppmd_info *threadInfo = bufferReader->t; @@ -65,10 +71,12 @@ pthread_mutex_lock(&tc->mutex); tc->empty = True; pthread_cond_broadcast(&tc->inEmpty); + /* Ensure mutex is unlocked if this thread is cancelled while waiting */ + pthread_cleanup_push(ppmd_mutex_unlock, (void *)&tc->mutex); do { pthread_cond_wait(&tc->notEmpty, &tc->mutex); } while (tc->empty); - pthread_mutex_unlock(&tc->mutex); + pthread_cleanup_pop(1); /* unlocks mutex */ } return *((const Byte *)inBuffer->src + inBuffer->pos++); } @@ -102,19 +110,23 @@ int i = 0; int result; while (i < max_length ) { - Bool inbuf_empty = reader->inBuffer->size == reader->inBuffer->pos; Bool outbuf_full = threadInfo->out->size == threadInfo->out->pos; + /* + * Only stop when output buffer is full. Do NOT stop just because + * input buffer appears empty, since decoder may still be able to + * produce symbols without consuming new input bytes. If more input + * is actually required, Reader() will block and signal controller + * via inEmpty condition. + */ if (outbuf_full) { break; } - if (inbuf_empty && reader->inBuffer->size > 0) { - break; - } int c = Ppmd7_DecodeSymbol(cPpmd7, rc); if (c == PPMD_RESULT_EOF) { result = PPMD_RESULT_EOF; goto exit; - } else if (c == PPMD_RESULT_ERROR) { + } + if (c == PPMD_RESULT_ERROR) { result = PPMD_RESULT_ERROR; goto exit; } @@ -130,6 +142,8 @@ pthread_mutex_lock(&tc->mutex); threadInfo->result = result; tc->finished = True; + /* Wake controller that might be waiting on input-empty condition */ + pthread_cond_broadcast(&tc->inEmpty); pthread_mutex_unlock(&tc->mutex); return NULL; } @@ -178,12 +192,23 @@ void Ppmd7T_Free(CPpmd7 *cPpmd7, ppmd_info *threadInfo, IAllocPtr allocator) { ppmd_thread_control_t *tc = (ppmd_thread_control_t *)threadInfo->t; - if (!(tc->finished)) { + if (tc && !(tc->finished)) { + /* Wake worker if it's waiting for input, then cancel and join */ + pthread_mutex_lock(&tc->mutex); + tc->empty = False; + pthread_cond_broadcast(&tc->notEmpty); + pthread_mutex_unlock(&tc->mutex); + pthread_cancel(tc->handle); + pthread_join(tc->handle, NULL); tc->finished = True; } - IAlloc_Free(allocator, tc); - Ppmd7_Free(cPpmd7, allocator); + if (tc) { + pthread_mutex_destroy(&tc->mutex); + pthread_cond_destroy(&tc->inEmpty); + pthread_cond_destroy(&tc->notEmpty); + IAlloc_Free(allocator, tc); + } } static void * @@ -200,9 +225,10 @@ int i = 0; int result; while (i < max_length ) { - Bool inbuf_empty = reader->inBuffer->size == reader->inBuffer->pos; Bool outbuf_full = threadInfo->out->size == threadInfo->out->pos; - if (inbuf_empty || outbuf_full) { + /* Only stop when output buffer is full; let Reader() handle + * input starvation by signaling controller. */ + if (outbuf_full) { break; } int c = Ppmd8_DecodeSymbol(cPpmd8); @@ -225,6 +251,8 @@ pthread_mutex_lock(&tc->mutex); threadInfo->result = result; tc->finished = True; + /* Wake controller that might be waiting on input-empty condition */ + pthread_cond_broadcast(&tc->inEmpty); pthread_mutex_unlock(&tc->mutex); return NULL; } @@ -273,10 +301,21 @@ void Ppmd8T_Free(CPpmd8 *cPpmd8, ppmd_info *threadInfo, IAllocPtr allocator) { ppmd_thread_control_t *tc = (ppmd_thread_control_t *)threadInfo->t; - if (!(tc->finished)) { + if (tc && !(tc->finished)) { + /* Wake worker if it's waiting for input, then cancel and join */ + pthread_mutex_lock(&tc->mutex); + tc->empty = False; + pthread_cond_broadcast(&tc->notEmpty); + pthread_mutex_unlock(&tc->mutex); + pthread_cancel(tc->handle); + pthread_join(tc->handle, NULL); tc->finished = True; } - IAlloc_Free(allocator, tc); - Ppmd8_Free(cPpmd8, allocator); + if (tc) { + pthread_mutex_destroy(&tc->mutex); + pthread_cond_destroy(&tc->inEmpty); + pthread_cond_destroy(&tc->notEmpty); + IAlloc_Free(allocator, tc); + } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyppmd-1.2.0/src/pyppmd/cffi/cffi_ppmd.py new/pyppmd-1.3.1/src/pyppmd/cffi/cffi_ppmd.py --- old/pyppmd-1.2.0/src/pyppmd/cffi/cffi_ppmd.py 2025-05-01 13:28:58.000000000 +0200 +++ new/pyppmd-1.3.1/src/pyppmd/cffi/cffi_ppmd.py 2025-11-27 22:58:19.000000000 +0100 @@ -557,6 +557,11 @@ if not isinstance(length, int): raise PpmdError("Wrong length argument is specified.") self.lock.acquire() + # If EOF already reached in a previous call, subsequent decode calls + # should be no-ops and return empty bytes without touching freed/native state. + if getattr(self, "_eof", False): + self.lock.release() + return b"" in_buf, use_input_buffer = self._setup_inBuffer(data) out, out_buf = self._setup_outBuffer() self.threadInfo.out = out_buf @@ -578,7 +583,6 @@ self._needs_input = False res = out.finish(out_buf) self.lock.release() - self._free() return res elif size == -2: raise ValueError("Corrupted archive data.") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyppmd-1.2.0/src/pyppmd.egg-info/PKG-INFO new/pyppmd-1.3.1/src/pyppmd.egg-info/PKG-INFO --- old/pyppmd-1.2.0/src/pyppmd.egg-info/PKG-INFO 2025-05-01 13:29:04.000000000 +0200 +++ new/pyppmd-1.3.1/src/pyppmd.egg-info/PKG-INFO 2025-11-27 22:58:24.000000000 +0100 @@ -1,13 +1,13 @@ Metadata-Version: 2.4 Name: pyppmd -Version: 1.2.0 +Version: 1.3.1 Summary: PPMd compression/decompression library Author-email: Hiroshi Miura <[email protected]> License: LGPL-2.1-or-later -Project-URL: Source, https://codeberg.org/miurahr/pyppmd +Project-URL: Source, https://github.com/miurahr/pyppmd Project-URL: Homepage, https://pyppmd.readthedocs.io/ Project-URL: Documentation, https://pyppmd.readthedocs.io/en/stable/ -Project-URL: Bug Tracker, https://codeberg.org/miurahr/pyppmd/issues +Project-URL: Bug Tracker, https://github.com/miurahr/pyppmd/issues Project-URL: Changelog, https://pyppmd.readthedocs.io/en/latest/changelog.html Classifier: Development Status :: 5 - Production/Stable Classifier: Operating System :: MacOS :: MacOS X @@ -16,16 +16,16 @@ Classifier: Operating System :: POSIX :: Linux Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.9 Classifier: Programming Language :: Python :: 3.10 Classifier: Programming Language :: Python :: 3.11 Classifier: Programming Language :: Python :: 3.12 Classifier: Programming Language :: Python :: 3.13 +Classifier: Programming Language :: Python :: 3.14 Classifier: Programming Language :: Python :: 3 :: Only Classifier: Programming Language :: Python :: Implementation :: CPython Classifier: Programming Language :: Python :: Implementation :: PyPy Classifier: Topic :: Software Development :: Libraries :: Python Modules -Requires-Python: >=3.9 +Requires-Python: >=3.10 Description-Content-Type: text/x-rst License-File: LICENSE Provides-Extra: test
