Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-greenlet for openSUSE:Factory checked in at 2025-04-30 19:02:46 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-greenlet (Old) and /work/SRC/openSUSE:Factory/.python-greenlet.new.30101 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-greenlet" Wed Apr 30 19:02:46 2025 rev:52 rq:1273387 version:3.2.1 Changes: -------- --- /work/SRC/openSUSE:Factory/python-greenlet/python-greenlet.changes 2024-09-29 18:09:43.967387095 +0200 +++ /work/SRC/openSUSE:Factory/.python-greenlet.new.30101/python-greenlet.changes 2025-04-30 19:02:58.194793368 +0200 @@ -1,0 +2,12 @@ +Tue Apr 29 09:23:14 UTC 2025 - John Paul Adrian Glaubitz <adrian.glaub...@suse.com> + +- Update to 3.2.1 + * Fix a crash regression for Riscv64. See issue 443. +- from version 3.2.0 + * Remove support for Python 3.7 and 3.8. + * Add untested, community supported implementation for RiscV 32. See PR 438. + * Make greenlet build and run on Python 3.14a7. It will not build on earlier + 3.14 alpha releases, and may not build on later 3.14 releases. + * Packaging: Use PEP 639 license expressions and include license files. + +------------------------------------------------------------------- Old: ---- greenlet-3.1.1.tar.gz New: ---- greenlet-3.2.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-greenlet.spec ++++++ --- /var/tmp/diff_new_pack.1hR2n9/_old 2025-04-30 19:02:58.682813718 +0200 +++ /var/tmp/diff_new_pack.1hR2n9/_new 2025-04-30 19:02:58.686813885 +0200 @@ -1,7 +1,7 @@ # # spec file for package python-greenlet # -# Copyright (c) 2024 SUSE LLC +# Copyright (c) 2025 SUSE LLC # Copyright (c) 2010 B1 Systems GmbH, Vohburg, Germany. # # All modifications and additions to the file contributed by third parties @@ -22,7 +22,7 @@ %{?sle15_python_module_pythons} Name: python-greenlet -Version: 3.1.1 +Version: 3.2.1 Release: 0 Summary: Lightweight in-process concurrent programming License: MIT ++++++ greenlet-3.1.1.tar.gz -> greenlet-3.2.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/greenlet-3.1.1/.github/workflows/tests.yml new/greenlet-3.2.1/.github/workflows/tests.yml --- old/greenlet-3.1.1/.github/workflows/tests.yml 2024-09-20 19:01:59.000000000 +0200 +++ new/greenlet-3.2.1/.github/workflows/tests.yml 2025-04-22 16:38:54.000000000 +0200 @@ -10,9 +10,6 @@ PYTHONDEVMODE: 1 PYTHONFAULTHANDLER: 1 PIP_UPGRADE_STRATEGY: eager - # Don't get warnings about Python 2 support being deprecated. We - # know. The env var works for pip 20. - PIP_NO_PYTHON_VERSION_WARNING: 1 PIP_NO_WARN_SCRIPT_LOCATION: 1 # Uploading built wheels for releases. # TWINE_PASSWORD is encrypted and stored directly in the @@ -25,23 +22,10 @@ runs-on: ${{ matrix.os }} strategy: matrix: - python-version: [3.7, 3.8, 3.9, "3.10", "3.11", "3.12", "3.13"] - os: [ubuntu-latest] - include: - # Needs to be all supported Python versions, they upload the built - # wheels for releases. - - os: macos-latest - python-version: 3.8 - - os: macos-latest - python-version: 3.9 - - os: macos-latest - python-version: "3.10" - - os: macos-latest - python-version: "3.11" - - os: macos-latest - python-version: "3.12" - - os: macos-latest - python-version: "3.13" + python-version: [3.9, "3.10", "3.11", "3.12", "3.13", "3.14.0-alpha.7"] + # Recall the macOS builds upload built wheels so all supported versions + # need to run on mac. + os: [ubuntu-latest, macos-latest] steps: - uses: actions/checkout@v4 - name: Set up Python @@ -148,17 +132,11 @@ run: | python -m pip install -U pip python -m pip install -U setuptools wheel - # Set the `CODEQL-PYTHON` environment variable to the Python executable - # that includes the dependencies - echo "CODEQL_PYTHON=$(which python)" >> $GITHUB_ENV # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL uses: github/codeql-action/init@v3 with: languages: python, cpp - # Override the default behavior so that the action doesn't attempt - # to auto-install Python dependencies - setup-python-dependencies: false - name: Install greenlet run: | python setup.py build @@ -167,8 +145,27 @@ - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v3 - manylinux: + riscv64: + runs-on: ubuntu-latest + name: RiscV 64 + steps: + - name: checkout + uses: actions/checkout@v4 + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.13" + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + with: + platforms: all + - name: Build and test greenlet + env: + DOCKER_IMAGE: riscv64/ubuntu:latest + run: bash ./ubuntu-test + + manylinux: runs-on: ubuntu-latest # We use a regular Python matrix entry to share as much code as possible. strategy: @@ -205,7 +202,7 @@ path: wheelhouse/*whl name: ${{ matrix.image }}_wheels.zip - name: Publish package to PyPI - uses: pypa/gh-action-pypi-publish@v1.10.1 + uses: pypa/gh-action-pypi-publish@v1.12.4 if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags') with: user: __token__ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/greenlet-3.1.1/CHANGES.rst new/greenlet-3.2.1/CHANGES.rst --- old/greenlet-3.1.1/CHANGES.rst 2024-09-20 19:01:59.000000000 +0200 +++ new/greenlet-3.2.1/CHANGES.rst 2025-04-22 16:39:14.000000000 +0200 @@ -2,6 +2,24 @@ Changes ========= +3.2.1 (2025-04-22) +================== + +- Fix a crash regression for Riscv64. See `issue 443 + <https://github.com/python-greenlet/greenlet/issues/443>`_. + + +3.2.0 (2025-04-15) +================== + +- Remove support for Python 3.7 and 3.8. +- Add untested, community supported implementation for RiscV 32. See + `PR 438 <https://github.com/python-greenlet/greenlet/pull/439>`_. +- Make greenlet build and run on Python 3.14a7. It will not build on + earlier 3.14 alpha releases, and may not build on later 3.14 + releases. +- Packaging: Use :pep:`639` license expressions and include license files. + 3.1.1 (2024-09-20) ================== diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/greenlet-3.1.1/MANIFEST.in new/greenlet-3.2.1/MANIFEST.in --- old/greenlet-3.1.1/MANIFEST.in 2024-09-20 19:01:59.000000000 +0200 +++ new/greenlet-3.2.1/MANIFEST.in 2025-04-22 16:38:54.000000000 +0200 @@ -50,6 +50,7 @@ include MANIFEST.in include make-manylinux +include ubuntu-test global-exclude *.pyc global-exclude *.pyd diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/greenlet-3.1.1/PKG-INFO new/greenlet-3.2.1/PKG-INFO --- old/greenlet-3.1.1/PKG-INFO 2024-09-20 19:02:00.404219200 +0200 +++ new/greenlet-3.2.1/PKG-INFO 2025-04-22 16:39:29.194077500 +0200 @@ -1,28 +1,26 @@ -Metadata-Version: 2.1 +Metadata-Version: 2.4 Name: greenlet -Version: 3.1.1 +Version: 3.2.1 Summary: Lightweight in-process concurrent programming Home-page: https://greenlet.readthedocs.io/ Author: Alexey Borzenkov Author-email: sna...@gmail.com Maintainer: Jason Madden Maintainer-email: ja...@seecoresoftware.com -License: MIT License +License: MIT AND Python-2.0 Project-URL: Bug Tracker, https://github.com/python-greenlet/greenlet/issues Project-URL: Source Code, https://github.com/python-greenlet/greenlet/ Project-URL: Documentation, https://greenlet.readthedocs.io/ +Project-URL: Changes, https://greenlet.readthedocs.io/en/latest/changes.html Keywords: greenlet coroutine concurrency threads cooperative Platform: any Classifier: Development Status :: 5 - Production/Stable Classifier: Intended Audience :: Developers -Classifier: License :: OSI Approved :: MIT License Classifier: Natural Language :: English Classifier: Programming Language :: C Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3 :: Only -Classifier: Programming Language :: Python :: 3.7 -Classifier: Programming Language :: Python :: 3.8 Classifier: Programming Language :: Python :: 3.9 Classifier: Programming Language :: Python :: 3.10 Classifier: Programming Language :: Python :: 3.11 @@ -30,17 +28,32 @@ Classifier: Programming Language :: Python :: 3.13 Classifier: Operating System :: OS Independent Classifier: Topic :: Software Development :: Libraries :: Python Modules -Requires-Python: >=3.7 +Requires-Python: >=3.9 Description-Content-Type: text/x-rst License-File: LICENSE License-File: LICENSE.PSF -License-File: AUTHORS Provides-Extra: docs Requires-Dist: Sphinx; extra == "docs" Requires-Dist: furo; extra == "docs" Provides-Extra: test Requires-Dist: objgraph; extra == "test" Requires-Dist: psutil; extra == "test" +Dynamic: author +Dynamic: author-email +Dynamic: classifier +Dynamic: description +Dynamic: description-content-type +Dynamic: home-page +Dynamic: keywords +Dynamic: license +Dynamic: license-file +Dynamic: maintainer +Dynamic: maintainer-email +Dynamic: platform +Dynamic: project-url +Dynamic: provides-extra +Dynamic: requires-python +Dynamic: summary .. This file is included into docs/history.rst diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/greenlet-3.1.1/appveyor.yml new/greenlet-3.2.1/appveyor.yml --- old/greenlet-3.1.1/appveyor.yml 2024-09-20 19:01:59.000000000 +0200 +++ new/greenlet-3.2.1/appveyor.yml 2025-04-22 16:38:54.000000000 +0200 @@ -69,17 +69,6 @@ PYTHON_EXE: python - - PYTHON: "C:\\Python38-x64" - PYTHON_ARCH: "64" - PYTHON_VERSION: "3.8.x" - PYTHON_EXE: python - - - - PYTHON: "C:\\Python37-x64" - PYTHON_ARCH: "64" - PYTHON_VERSION: "3.7.x" - PYTHON_EXE: python - # Tested 32-bit versions. A small, hand-picked selection covering # important variations. No need to include newer versions of @@ -100,17 +89,7 @@ # Untested 32-bit versions. As above, we don't expect any variance # from the tested 32-bit versions, OR they are very EOL. - - PYTHON: "C:\\Python38" - PYTHON_ARCH: "32" - PYTHON_VERSION: "3.8.x" - PYTHON_EXE: python - GWHEEL_ONLY: true - - - PYTHON: "C:\\Python37" - PYTHON_ARCH: "32" - PYTHON_VERSION: "3.7.x" - PYTHON_EXE: python - GWHEEL_ONLY: true + # None right now. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/greenlet-3.1.1/make-manylinux new/greenlet-3.2.1/make-manylinux --- old/greenlet-3.1.1/make-manylinux 2024-09-20 19:01:59.000000000 +0200 +++ new/greenlet-3.2.1/make-manylinux 2025-04-22 16:38:54.000000000 +0200 @@ -35,7 +35,7 @@ which auditwheel echo "Installed Python versions" ls -l /opt/python - for variant in `ls -d /opt/python/cp{313,37,38,39,310,311,312}*`; do + for variant in `ls -d /opt/python/cp{313,39,310,311,312}*`; do if [ "$variant" = "/opt/python/cp313-313t" ]; then echo "Skipping no-gil build. The GIL is required." continue diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/greenlet-3.1.1/setup.py new/greenlet-3.2.1/setup.py --- old/greenlet-3.1.1/setup.py 2024-09-20 19:01:59.000000000 +0200 +++ new/greenlet-3.2.1/setup.py 2025-04-22 16:38:54.000000000 +0200 @@ -223,8 +223,13 @@ 'Bug Tracker': 'https://github.com/python-greenlet/greenlet/issues', 'Source Code': 'https://github.com/python-greenlet/greenlet/', 'Documentation': 'https://greenlet.readthedocs.io/', + 'Changes': 'https://greenlet.readthedocs.io/en/latest/changes.html', }, - license="MIT License", + license="MIT AND Python-2.0", + license_files=[ + 'LICENSE', + 'LICENSE.PSF', + ], platforms=['any'], package_dir={'': 'src'}, packages=find_packages('src'), @@ -234,14 +239,11 @@ classifiers=[ "Development Status :: 5 - Production/Stable", 'Intended Audience :: Developers', - 'License :: OSI Approved :: MIT License', 'Natural Language :: English', 'Programming Language :: C', 'Programming Language :: Python', 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3 :: Only', - 'Programming Language :: Python :: 3.7', - 'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: 3.9', 'Programming Language :: Python :: 3.10', 'Programming Language :: Python :: 3.11', @@ -260,6 +262,6 @@ 'psutil', ], }, - python_requires=">=3.7", + python_requires=">=3.9", zip_safe=False, ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/greenlet-3.1.1/src/greenlet/TGreenlet.hpp new/greenlet-3.2.1/src/greenlet/TGreenlet.hpp --- old/greenlet-3.1.1/src/greenlet/TGreenlet.hpp 2024-09-20 19:01:59.000000000 +0200 +++ new/greenlet-3.2.1/src/greenlet/TGreenlet.hpp 2025-04-22 16:38:54.000000000 +0200 @@ -27,6 +27,11 @@ # include "internal/pycore_frame.h" #endif +#if GREENLET_PY314 +# include "internal/pycore_interpframe_structs.h" +# include "internal/pycore_interpframe.h" +#endif + // XXX: TODO: Work to remove all virtual functions // for speed of calling and size of objects (no vtable). // One pattern is the Curiously Recurring Template diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/greenlet-3.1.1/src/greenlet/TThreadStateDestroy.cpp new/greenlet-3.2.1/src/greenlet/TThreadStateDestroy.cpp --- old/greenlet-3.1.1/src/greenlet/TThreadStateDestroy.cpp 2024-09-20 19:01:59.000000000 +0200 +++ new/greenlet-3.2.1/src/greenlet/TThreadStateDestroy.cpp 2025-04-22 16:38:54.000000000 +0200 @@ -15,7 +15,6 @@ #include "TGreenlet.hpp" #include "greenlet_thread_support.hpp" -#include "greenlet_cpython_add_pending.hpp" #include "greenlet_compiler_compat.hpp" #include "TGreenletGlobals.cpp" #include "TThreadState.hpp" @@ -168,47 +167,7 @@ delete state; // Deleting this runs the destructor, DECREFs the main greenlet. } - // ensure this is actually defined. - static_assert(GREENLET_BROKEN_PY_ADD_PENDING == 1 || GREENLET_BROKEN_PY_ADD_PENDING == 0, - "GREENLET_BROKEN_PY_ADD_PENDING not defined correctly."); - -#if GREENLET_BROKEN_PY_ADD_PENDING - static int _push_pending_call(struct _pending_calls *pending, - int (*func)(void *), void *arg) - { - int i = pending->last; - int j = (i + 1) % NPENDINGCALLS; - if (j == pending->first) { - return -1; /* Queue full */ - } - pending->calls[i].func = func; - pending->calls[i].arg = arg; - pending->last = j; - return 0; - } - static int AddPendingCall(int (*func)(void *), void *arg) - { - _PyRuntimeState *runtime = &_PyRuntime; - if (!runtime) { - // obviously impossible - return 0; - } - struct _pending_calls *pending = &runtime->ceval.pending; - if (!pending->lock) { - return 0; - } - int result = 0; - PyThread_acquire_lock(pending->lock, WAIT_LOCK); - if (!pending->finishing) { - result = _push_pending_call(pending, func, arg); - } - PyThread_release_lock(pending->lock); - SIGNAL_PENDING_CALLS(&runtime->ceval); - return result; - } -#else - // Python < 3.8 or >= 3.9 static int AddPendingCall(int (*func)(void*), void* arg) { // If the interpreter is in the middle of finalizing, we can't add a @@ -234,7 +193,7 @@ } return Py_AddPendingCall(func, arg); } -#endif + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/greenlet-3.1.1/src/greenlet/__init__.py new/greenlet-3.2.1/src/greenlet/__init__.py --- old/greenlet-3.1.1/src/greenlet/__init__.py 2024-09-20 19:01:59.000000000 +0200 +++ new/greenlet-3.2.1/src/greenlet/__init__.py 2025-04-22 16:39:14.000000000 +0200 @@ -25,7 +25,7 @@ ### # Metadata ### -__version__ = '3.1.1' +__version__ = '3.2.1' from ._greenlet import _C_API # pylint:disable=no-name-in-module ### diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/greenlet-3.1.1/src/greenlet/greenlet_cpython_add_pending.hpp new/greenlet-3.2.1/src/greenlet/greenlet_cpython_add_pending.hpp --- old/greenlet-3.1.1/src/greenlet/greenlet_cpython_add_pending.hpp 2024-09-20 19:01:59.000000000 +0200 +++ new/greenlet-3.2.1/src/greenlet/greenlet_cpython_add_pending.hpp 1970-01-01 01:00:00.000000000 +0100 @@ -1,172 +0,0 @@ -#ifndef GREENLET_CPYTHON_ADD_PENDING_HPP -#define GREENLET_CPYTHON_ADD_PENDING_HPP - -#if (PY_VERSION_HEX >= 0x30800A0 && PY_VERSION_HEX < 0x3090000) && !(defined(_WIN32) || defined(WIN32)) -// XXX: From Python 3.8a3 [1] up until Python 3.9a6 [2][3], -// ``Py_AddPendingCall`` would try to produce a Python exception if -// the interpreter was in the beginning of shutting down when this -// function is called. However, ``Py_AddPendingCall`` doesn't require -// the GIL, and we are absolutely not holding it when we make that -// call. That means that trying to create the Python exception is -// using the C API in an undefined state; here the C API detects this -// and aborts the process with an error ("Fatal Python error: Python -// memory allocator called without holding the GIL": Add -> -// PyErr_SetString -> PyUnicode_New -> PyObject_Malloc). This arises -// (obviously) in multi-threaded programs and happens if one thread is -// exiting and cleaning up its thread-local data while the other -// thread is trying to shut down the interpreter. A crash on shutdown -// is still a crash and could result in data loss (e.g., daemon -// threads are still running, pending signal handlers may be present, -// buffers may not be flushed, there may be __del__ that need run, -// etc), so we have to work around it. -// -// Of course, we can (and do) check for whether the interpreter is -// shutting down before calling ``Py_AddPendingCall``, but that's a -// race condition since we don't hold the GIL, and so we may not -// actually get the right answer. Plus, ``Py_FinalizeEx`` actually -// calls ``_Py_FinishPendingCalls`` (which sets the pending->finishing -// flag, which is used to gate creating the exceptioen) *before* -// publishing any other data that would let us detect the shutdown -// (such as runtime->finalizing). So that point is moot. -// -// Our solution for those versions is to inline the same code, without -// the problematic bit that sets the exception. Unfortunately, all of -// the structure definitions are private/opaque, *and* we can't -// actually count on being able to include their definitions from -// ``internal/pycore_*``, because on some platforms those header files -// are incomplete (i.e., on macOS with macports 3.8, the includes are -// fine, but on Ubuntu jammy with 3.8 from ppa:deadsnakes or GitHub -// Actions 3.8 (I think it's Ubuntu 18.04), they con't be used; at -// least, I couldn't get them to work). So we need to define the -// structures and _PyRuntime data member ourself. Yet more -// unfortunately, _PyRuntime won't link on Windows, so we can only do -// this on other platforms. -// -// [1] https://github.com/python/cpython/commit/842a2f07f2f08a935ef470bfdaeef40f87490cfc -// [2] https://github.com/python/cpython/commit/cfc3c2f8b34d3864717ab584c5b6c260014ba55a -// [3] https://github.com/python/cpython/issues/81308 -# define GREENLET_BROKEN_PY_ADD_PENDING 1 - -// When defining these structures, the important thing is to get -// binary compatibility, i.e., structure layout. For that, we only -// need to define fields up to the ones we use; after that they're -// irrelevant UNLESS the structure is included in another structure -// *before* the structure we're interested in --- in that case, it -// must be complete. Ellipsis indicate elided trailing members. -// Pointer types are changed to void* to keep from having to define -// more structures. - -// From "internal/pycore_atomic.h" - -// There are several different definitions of this, including the -// plain ``int`` version, a ``volatile int`` and an ``_Atomic int`` -// I don't think any of those change the size/layout. -typedef struct _Py_atomic_int { - volatile int _value; -} _Py_atomic_int; - -// This needs too much infrastructure, so we just do a regular store. -#define _Py_atomic_store_relaxed(ATOMIC_VAL, NEW_VAL) \ - (ATOMIC_VAL)->_value = NEW_VAL - - - -// From "internal/pycore_pymem.h" -#define NUM_GENERATIONS 3 - - -struct gc_generation { - PyGC_Head head; // We already have this defined. - int threshold; - int count; -}; -struct gc_generation_stats { - Py_ssize_t collections; - Py_ssize_t collected; - Py_ssize_t uncollectable; -}; - -struct _gc_runtime_state { - void *trash_delete_later; - int trash_delete_nesting; - int enabled; - int debug; - struct gc_generation generations[NUM_GENERATIONS]; - void *generation0; - struct gc_generation permanent_generation; - struct gc_generation_stats generation_stats[NUM_GENERATIONS]; - int collecting; - void *garbage; - void *callbacks; - Py_ssize_t long_lived_total; - Py_ssize_t long_lived_pending; -}; - -// From "internal/pycore_pystate.h" -struct _pending_calls { - int finishing; - PyThread_type_lock lock; - _Py_atomic_int calls_to_do; - int async_exc; -#define NPENDINGCALLS 32 - struct { - int (*func)(void *); - void *arg; - } calls[NPENDINGCALLS]; - int first; - int last; -}; - -struct _ceval_runtime_state { - int recursion_limit; - int tracing_possible; - _Py_atomic_int eval_breaker; - _Py_atomic_int gil_drop_request; - struct _pending_calls pending; - // ... -}; - -typedef struct pyruntimestate { - int preinitializing; - int preinitialized; - int core_initialized; - int initialized; - void *finalizing; - - struct pyinterpreters { - PyThread_type_lock mutex; - void *head; - void *main; - int64_t next_id; - } interpreters; - // XXX Remove this field once we have a tp_* slot. - struct _xidregistry { - PyThread_type_lock mutex; - void *head; - } xidregistry; - - unsigned long main_thread; - -#define NEXITFUNCS 32 - void (*exitfuncs[NEXITFUNCS])(void); - int nexitfuncs; - - struct _gc_runtime_state gc; - struct _ceval_runtime_state ceval; - // ... -} _PyRuntimeState; - -#define SIGNAL_PENDING_CALLS(ceval) \ - do { \ - _Py_atomic_store_relaxed(&(ceval)->pending.calls_to_do, 1); \ - _Py_atomic_store_relaxed(&(ceval)->eval_breaker, 1); \ - } while (0) - -extern _PyRuntimeState _PyRuntime; - -#else -# define GREENLET_BROKEN_PY_ADD_PENDING 0 -#endif - - -#endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/greenlet-3.1.1/src/greenlet/greenlet_cpython_compat.hpp new/greenlet-3.2.1/src/greenlet/greenlet_cpython_compat.hpp --- old/greenlet-3.1.1/src/greenlet/greenlet_cpython_compat.hpp 2024-09-20 19:01:59.000000000 +0200 +++ new/greenlet-3.2.1/src/greenlet/greenlet_cpython_compat.hpp 2025-04-22 16:38:54.000000000 +0200 @@ -61,6 +61,12 @@ # define GREENLET_PY313 0 #endif +#if PY_VERSION_HEX >= 0x30E0000 +# define GREENLET_PY314 1 +#else +# define GREENLET_PY314 0 +#endif + #ifndef Py_SET_REFCNT /* Py_REFCNT and Py_SIZE macros are converted to functions https://bugs.python.org/issue39573 */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/greenlet-3.1.1/src/greenlet/platform/switch_riscv_unix.h new/greenlet-3.2.1/src/greenlet/platform/switch_riscv_unix.h --- old/greenlet-3.1.1/src/greenlet/platform/switch_riscv_unix.h 2024-09-20 19:02:00.000000000 +0200 +++ new/greenlet-3.2.1/src/greenlet/platform/switch_riscv_unix.h 2025-04-22 16:38:54.000000000 +0200 @@ -11,9 +11,10 @@ static int slp_switch(void) { - long fp; int ret; + long fp; long *stackref, stsizediff; + __asm__ volatile ("" : : : REGS_TO_SAVE); __asm__ volatile ("mv %0, fp" : "=r" (fp) : ); __asm__ volatile ("mv %0, sp" : "=r" (stackref) : ); @@ -28,7 +29,11 @@ SLP_RESTORE_STATE(); } __asm__ volatile ("" : : : REGS_TO_SAVE); +#if __riscv_xlen == 32 + __asm__ volatile ("lw fp, %0" : : "m" (fp)); +#else __asm__ volatile ("ld fp, %0" : : "m" (fp)); +#endif __asm__ volatile ("mv %0, zero" : "=r" (ret) : ); return ret; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/greenlet-3.1.1/src/greenlet/slp_platformselect.h new/greenlet-3.2.1/src/greenlet/slp_platformselect.h --- old/greenlet-3.1.1/src/greenlet/slp_platformselect.h 2024-09-20 19:02:00.000000000 +0200 +++ new/greenlet-3.2.1/src/greenlet/slp_platformselect.h 2025-04-22 16:38:54.000000000 +0200 @@ -32,7 +32,7 @@ #elif defined(__GNUC__) && defined(sparc) # include "platform/switch_sparc_sun_gcc.h" /* SunOS sparc with gcc */ #elif defined(__SUNPRO_C) && defined(sparc) && defined(sun) -# iiclude "platform/switch_sparc_sun_gcc.h" /* SunStudio on amd64 */ +# include "platform/switch_sparc_sun_gcc.h" /* SunStudio on amd64 */ #elif defined(__SUNPRO_C) && defined(__amd64__) && defined(sun) # include "platform/switch_amd64_unix.h" /* SunStudio on amd64 */ #elif defined(__SUNPRO_C) && defined(__i386__) && defined(sun) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/greenlet-3.1.1/src/greenlet/tests/__init__.py new/greenlet-3.2.1/src/greenlet/tests/__init__.py --- old/greenlet-3.1.1/src/greenlet/tests/__init__.py 2024-09-20 19:02:00.000000000 +0200 +++ new/greenlet-3.2.1/src/greenlet/tests/__init__.py 2025-04-22 16:38:54.000000000 +0200 @@ -25,6 +25,9 @@ PY312 = sys.version_info[:2] >= (3, 12) PY313 = sys.version_info[:2] >= (3, 13) +# XXX: First tested on 3.14a7. Revisit all uses of this on later versions to ensure they +# are still valid. +PY314 = sys.version_info[:2] >= (3, 14) WIN = sys.platform.startswith("win") RUNNING_ON_GITHUB_ACTIONS = os.environ.get('GITHUB_ACTIONS') @@ -55,10 +58,7 @@ return type.__new__(cls, classname, bases, classDict) -class TestCase(TestCaseMetaClass( - "NewBase", - (unittest.TestCase,), - {})): +class TestCase(unittest.TestCase, metaclass=TestCaseMetaClass): cleanup_attempt_sleep_duration = 0.001 cleanup_max_sleep_seconds = 1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/greenlet-3.1.1/src/greenlet/tests/test_contextvars.py new/greenlet-3.2.1/src/greenlet/tests/test_contextvars.py --- old/greenlet-3.1.1/src/greenlet/tests/test_contextvars.py 2024-09-20 19:02:00.000000000 +0200 +++ new/greenlet-3.2.1/src/greenlet/tests/test_contextvars.py 2025-04-22 16:38:54.000000000 +0200 @@ -11,7 +11,7 @@ from greenlet import greenlet from greenlet import getcurrent from . import TestCase - +from . import PY314 try: from contextvars import Context @@ -208,8 +208,10 @@ # Make sure there are no reference leaks gr = None gc.collect() - self.assertEqual(sys.getrefcount(old_context), 2) - self.assertEqual(sys.getrefcount(new_context), 2) + # Python 3.14 elides reference counting operations + # in some cases. See https://github.com/python/cpython/pull/130708 + self.assertEqual(sys.getrefcount(old_context), 2 if not PY314 else 1) + self.assertEqual(sys.getrefcount(new_context), 2 if not PY314 else 1) def test_context_assignment_different_thread(self): import threading diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/greenlet-3.1.1/src/greenlet/tests/test_greenlet.py new/greenlet-3.2.1/src/greenlet/tests/test_greenlet.py --- old/greenlet-3.1.1/src/greenlet/tests/test_greenlet.py 2024-09-20 19:02:00.000000000 +0200 +++ new/greenlet-3.2.1/src/greenlet/tests/test_greenlet.py 2025-04-22 16:38:54.000000000 +0200 @@ -12,6 +12,7 @@ from . import TestCase from . import RUNNING_ON_MANYLINUX from . import PY313 +from . import PY314 from .leakcheck import fails_leakcheck @@ -123,13 +124,15 @@ g = RawGreenlet(f) g.switch() lst.append('c') - + self.assertEqual(sys.getrefcount(g), 2 if not PY314 else 1) g = RawGreenlet(g) - self.assertEqual(sys.getrefcount(g), 2) + # Python 3.14 elides reference counting operations + # in some cases. See https://github.com/python/cpython/pull/130708 + self.assertEqual(sys.getrefcount(g), 2 if not PY314 else 1) g.switch() self.assertEqual(lst, ['a', 'b', 'c']) # Just the one in this frame, plus the one on the stack we pass to the function - self.assertEqual(sys.getrefcount(g), 2) + self.assertEqual(sys.getrefcount(g), 2 if not PY314 else 1) def test_threads(self): success = [] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/greenlet-3.1.1/src/greenlet/tests/test_leaks.py new/greenlet-3.2.1/src/greenlet/tests/test_leaks.py --- old/greenlet-3.1.1/src/greenlet/tests/test_leaks.py 2024-09-20 19:02:00.000000000 +0200 +++ new/greenlet-3.2.1/src/greenlet/tests/test_leaks.py 2025-04-22 16:38:54.000000000 +0200 @@ -14,6 +14,7 @@ import greenlet from . import TestCase +from . import PY314 from .leakcheck import fails_leakcheck from .leakcheck import ignores_leakcheck from .leakcheck import RUNNING_ON_MANYLINUX @@ -52,12 +53,15 @@ def test_kwarg_refs(self): kwargs = {} + self.assertEqual(sys.getrefcount(kwargs), 2 if not PY314 else 1) # pylint:disable=unnecessary-lambda g = greenlet.greenlet( - lambda **kwargs: greenlet.getcurrent().parent.switch(**kwargs)) + lambda **gkwargs: greenlet.getcurrent().parent.switch(**gkwargs)) for _ in range(100): g.switch(**kwargs) - self.assertEqual(sys.getrefcount(kwargs), 2) + # Python 3.14 elides reference counting operations + # in some cases. See https://github.com/python/cpython/pull/130708 + self.assertEqual(sys.getrefcount(kwargs), 2 if not PY314 else 1) @staticmethod diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/greenlet-3.1.1/src/greenlet.egg-info/PKG-INFO new/greenlet-3.2.1/src/greenlet.egg-info/PKG-INFO --- old/greenlet-3.1.1/src/greenlet.egg-info/PKG-INFO 2024-09-20 19:02:00.000000000 +0200 +++ new/greenlet-3.2.1/src/greenlet.egg-info/PKG-INFO 2025-04-22 16:39:28.000000000 +0200 @@ -1,28 +1,26 @@ -Metadata-Version: 2.1 +Metadata-Version: 2.4 Name: greenlet -Version: 3.1.1 +Version: 3.2.1 Summary: Lightweight in-process concurrent programming Home-page: https://greenlet.readthedocs.io/ Author: Alexey Borzenkov Author-email: sna...@gmail.com Maintainer: Jason Madden Maintainer-email: ja...@seecoresoftware.com -License: MIT License +License: MIT AND Python-2.0 Project-URL: Bug Tracker, https://github.com/python-greenlet/greenlet/issues Project-URL: Source Code, https://github.com/python-greenlet/greenlet/ Project-URL: Documentation, https://greenlet.readthedocs.io/ +Project-URL: Changes, https://greenlet.readthedocs.io/en/latest/changes.html Keywords: greenlet coroutine concurrency threads cooperative Platform: any Classifier: Development Status :: 5 - Production/Stable Classifier: Intended Audience :: Developers -Classifier: License :: OSI Approved :: MIT License Classifier: Natural Language :: English Classifier: Programming Language :: C Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3 :: Only -Classifier: Programming Language :: Python :: 3.7 -Classifier: Programming Language :: Python :: 3.8 Classifier: Programming Language :: Python :: 3.9 Classifier: Programming Language :: Python :: 3.10 Classifier: Programming Language :: Python :: 3.11 @@ -30,17 +28,32 @@ Classifier: Programming Language :: Python :: 3.13 Classifier: Operating System :: OS Independent Classifier: Topic :: Software Development :: Libraries :: Python Modules -Requires-Python: >=3.7 +Requires-Python: >=3.9 Description-Content-Type: text/x-rst License-File: LICENSE License-File: LICENSE.PSF -License-File: AUTHORS Provides-Extra: docs Requires-Dist: Sphinx; extra == "docs" Requires-Dist: furo; extra == "docs" Provides-Extra: test Requires-Dist: objgraph; extra == "test" Requires-Dist: psutil; extra == "test" +Dynamic: author +Dynamic: author-email +Dynamic: classifier +Dynamic: description +Dynamic: description-content-type +Dynamic: home-page +Dynamic: keywords +Dynamic: license +Dynamic: license-file +Dynamic: maintainer +Dynamic: maintainer-email +Dynamic: platform +Dynamic: project-url +Dynamic: provides-extra +Dynamic: requires-python +Dynamic: summary .. This file is included into docs/history.rst diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/greenlet-3.1.1/src/greenlet.egg-info/SOURCES.txt new/greenlet-3.2.1/src/greenlet.egg-info/SOURCES.txt --- old/greenlet-3.1.1/src/greenlet.egg-info/SOURCES.txt 2024-09-20 19:02:00.000000000 +0200 +++ new/greenlet-3.2.1/src/greenlet.egg-info/SOURCES.txt 2025-04-22 16:39:29.000000000 +0200 @@ -14,6 +14,7 @@ setup.cfg setup.py tox.ini +ubuntu-test .github/dependabot.yml .github/workflows/tests.yml appveyor/install.ps1 @@ -60,7 +61,6 @@ src/greenlet/greenlet.h src/greenlet/greenlet_allocator.hpp src/greenlet/greenlet_compiler_compat.hpp -src/greenlet/greenlet_cpython_add_pending.hpp src/greenlet/greenlet_cpython_compat.hpp src/greenlet/greenlet_exceptions.hpp src/greenlet/greenlet_internal.hpp diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/greenlet-3.1.1/ubuntu-test new/greenlet-3.2.1/ubuntu-test --- old/greenlet-3.1.1/ubuntu-test 1970-01-01 01:00:00.000000000 +0100 +++ new/greenlet-3.2.1/ubuntu-test 2025-04-22 16:38:54.000000000 +0200 @@ -0,0 +1,47 @@ +#!/bin/bash + +# This needs to be run from the root of the project. + +set -e +export PYTHONUNBUFFERED=1 +export PYTHONDONTWRITEBYTECODE=1 +# Use a fixed hash seed for reproducibility +export PYTHONHASHSEED=8675309 +export CI=1 +export TRAVIS=true +export PIP_NO_WARN_SCRIPT_LOCATION=1 + + +if [ -d /greenlet ]; then + # Running inside docker + export GREENLET_MANYLINUX=1 + # Our setup.py overrides this with -Os; be sure it does. + export CFLAGS="-O3 -DNDEBUG -Wall" + + apt-get update + apt-get install -y python3.12 python3.12-dev python3.12-venv gcc git g++ + update-alternatives --install /usr/bin/python python /usr/bin/python3.12 1 + + # Build in an isolated directory + mkdir /tmp/build + cd /tmp/build + git config --global --add safe.directory /greenlet/.git + git clone /greenlet greenlet + cd greenlet + + python -m venv /tmp/venv + . /tmp/venv/bin/activate + echo "Python" + python --version + + python -mpip install -U pip + python -mpip install -U setuptools wheel + python -mpip wheel -v --wheel-dir ./dist . + python -mpip install -U .[test] + python -m unittest discover -v greenlet.tests + + exit 0 +fi + +# Mount the current directory as /greenlet +docker run --rm --platform linux/riscv64 -v "$(pwd):/greenlet" ${DOCKER_IMAGE:-riscv64/ubuntu:latest} /greenlet/$(basename $0)