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 2026-03-01 22:13:41
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-greenlet (Old)
 and      /work/SRC/openSUSE:Factory/.python-greenlet.new.29461 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-greenlet"

Sun Mar  1 22:13:41 2026 rev:58 rq:1335240 version:3.3.2

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-greenlet/python-greenlet.changes  
2026-02-01 22:02:32.401284113 +0100
+++ 
/work/SRC/openSUSE:Factory/.python-greenlet.new.29461/python-greenlet.changes   
    2026-03-01 22:13:43.347245002 +0100
@@ -1,0 +2,7 @@
+Wed Feb 25 09:53:31 UTC 2026 - John Paul Adrian Glaubitz 
<[email protected]>
+
+- Update to 3.3.2
+  * Fix a crash on Python 3.10 if there are active greenlets during
+    interpreter shutdown. See PR 495 by Nicolas Bouvrette.
+
+-------------------------------------------------------------------

Old:
----
  greenlet-3.3.1.tar.gz

New:
----
  greenlet-3.3.2.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-greenlet.spec ++++++
--- /var/tmp/diff_new_pack.IxxB5E/_old  2026-03-01 22:13:44.007272128 +0100
+++ /var/tmp/diff_new_pack.IxxB5E/_new  2026-03-01 22:13:44.007272128 +0100
@@ -22,7 +22,7 @@
 
 %{?sle15_python_module_pythons}
 Name:           python-greenlet
-Version:        3.3.1
+Version:        3.3.2
 Release:        0
 Summary:        Lightweight in-process concurrent programming
 License:        MIT

++++++ greenlet-3.3.1.tar.gz -> greenlet-3.3.2.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/greenlet-3.3.1/CHANGES.rst 
new/greenlet-3.3.2/CHANGES.rst
--- old/greenlet-3.3.1/CHANGES.rst      2026-01-23 16:28:32.000000000 +0100
+++ new/greenlet-3.3.2/CHANGES.rst      2026-02-20 21:14:45.000000000 +0100
@@ -2,6 +2,15 @@
  Changes
 =========
 
+3.3.2 (2026-02-20)
+==================
+
+- Fix a crash on Python 3.10 if there are active greenlets during
+  interpreter shutdown. See `PR 495
+  <https://github.com/python-greenlet/greenlet/pull/495>`_ by Nicolas
+  Bouvrette.
+
+
 3.3.1 (2026-01-23)
 ==================
 
@@ -40,6 +49,19 @@
      initial free-threaded support and a discussion of the current
      known issues.
 
+3.2.5 (2026-02-20)
+==================
+
+.. note::
+
+   The 3.2.x series will be the last to support Python 3.9.
+
+- Backport the changes from PR 495 in release 3.3.2 for Python 3.9.
+
+.. note::
+
+   No Windows wheels will be published for this version.
+
 3.2.4 (2025-08-07)
 ==================
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/greenlet-3.3.1/PKG-INFO new/greenlet-3.3.2/PKG-INFO
--- old/greenlet-3.3.1/PKG-INFO 2026-01-23 16:28:35.766325700 +0100
+++ new/greenlet-3.3.2/PKG-INFO 2026-02-20 21:14:48.818638300 +0100
@@ -1,10 +1,10 @@
 Metadata-Version: 2.4
 Name: greenlet
-Version: 3.3.1
+Version: 3.3.2
 Summary: Lightweight in-process concurrent programming
 Author-email: Alexey Borzenkov <[email protected]>
 Maintainer-email: Jason Madden <[email protected]>
-License-Expression: MIT AND Python-2.0
+License-Expression: MIT AND PSF-2.0
 Project-URL: Homepage, https://greenlet.readthedocs.io
 Project-URL: Documentation, https://greenlet.readthedocs.io
 Project-URL: Repository, https://github.com/python-greenlet/greenlet
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/greenlet-3.3.1/pyproject.toml 
new/greenlet-3.3.2/pyproject.toml
--- old/greenlet-3.3.1/pyproject.toml   2026-01-23 16:28:32.000000000 +0100
+++ new/greenlet-3.3.2/pyproject.toml   2026-02-20 21:14:45.000000000 +0100
@@ -14,7 +14,7 @@
 maintainers = [
     { name = "Jason Madden", email = "[email protected]" }
 ]
-license = "MIT AND Python-2.0"
+license = "MIT AND PSF-2.0"
 license-files = [
     'LICENSE',
     'LICENSE.PSF',
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/greenlet-3.3.1/src/greenlet/PyGreenlet.cpp 
new/greenlet-3.3.2/src/greenlet/PyGreenlet.cpp
--- old/greenlet-3.3.1/src/greenlet/PyGreenlet.cpp      2026-01-23 
16:28:32.000000000 +0100
+++ new/greenlet-3.3.2/src/greenlet/PyGreenlet.cpp      2026-02-20 
21:14:45.000000000 +0100
@@ -189,6 +189,27 @@
 static int
 _green_dealloc_kill_started_non_main_greenlet(BorrowedGreenlet self)
 {
+    // During interpreter finalization, we cannot safely throw GreenletExit
+    // into the greenlet. Doing so calls g_switch(), which performs a stack
+    // switch and runs Python code via _PyEval_EvalFrameDefault. On Python
+    // < 3.11, executing Python code in a partially-torn-down interpreter
+    // leads to SIGSEGV (greenlet 3.x) or SIGABRT (greenlet 2.x).
+    //
+    // Python 3.11+ restructured interpreter finalization internals (frame
+    // representation, data stack management, recursion tracking) so that
+    // g_switch() during finalization is safe. On older Pythons, we simply
+    // mark the greenlet dead without throwing, which avoids the crash at
+    // the cost of not running any cleanup code inside the greenlet.
+    //
+    // See: https://github.com/python-greenlet/greenlet/issues/411
+    //      https://github.com/python-greenlet/greenlet/issues/351
+#if !GREENLET_PY311
+    if (_Py_IsFinalizing()) {
+        self->murder_in_place();
+        return 1;
+    }
+#endif
+
     /* Hacks hacks hacks copied from instance_dealloc() */
     /* Temporarily resurrect the greenlet. */
     assert(self.REFCNT() == 0);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/greenlet-3.3.1/src/greenlet/TThreadState.hpp 
new/greenlet-3.3.2/src/greenlet/TThreadState.hpp
--- old/greenlet-3.3.1/src/greenlet/TThreadState.hpp    2026-01-23 
16:28:32.000000000 +0100
+++ new/greenlet-3.3.2/src/greenlet/TThreadState.hpp    2026-02-20 
21:14:45.000000000 +0100
@@ -384,6 +384,26 @@
             return;
         }
 
+        // During interpreter finalization, Python APIs like
+        // PyImport_ImportModule are unsafe (the import machinery may
+        // be partially torn down). On Python < 3.11, perform only the
+        // minimal cleanup that is safe: clear our strong references so
+        // we don't leak, but skip the GC-based leak detection.
+        //
+        // Python 3.11+ restructured interpreter finalization so that
+        // these APIs remain safe during shutdown.
+#if !GREENLET_PY311
+        if (_Py_IsFinalizing()) {
+            this->tracefunc.CLEAR();
+            if (this->current_greenlet) {
+                this->current_greenlet->murder_in_place();
+                this->current_greenlet.CLEAR();
+            }
+            this->main_greenlet.CLEAR();
+            return;
+        }
+#endif
+
         // We should not have an "origin" greenlet; that only exists
         // for the temporary time during a switch, which should not
         // be in progress as the thread dies.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/greenlet-3.3.1/src/greenlet/__init__.py 
new/greenlet-3.3.2/src/greenlet/__init__.py
--- old/greenlet-3.3.1/src/greenlet/__init__.py 2026-01-23 16:28:32.000000000 
+0100
+++ new/greenlet-3.3.2/src/greenlet/__init__.py 2026-02-20 21:14:45.000000000 
+0100
@@ -25,7 +25,7 @@
 ###
 # Metadata
 ###
-__version__ = '3.3.1'
+__version__ = '3.3.2'
 from ._greenlet import _C_API # pylint:disable=no-name-in-module
 
 ###
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/greenlet-3.3.1/src/greenlet/tests/test_interpreter_shutdown.py 
new/greenlet-3.3.2/src/greenlet/tests/test_interpreter_shutdown.py
--- old/greenlet-3.3.1/src/greenlet/tests/test_interpreter_shutdown.py  
1970-01-01 01:00:00.000000000 +0100
+++ new/greenlet-3.3.2/src/greenlet/tests/test_interpreter_shutdown.py  
2026-02-20 21:14:45.000000000 +0100
@@ -0,0 +1,320 @@
+# -*- coding: utf-8 -*-
+"""
+Tests for greenlet behavior during interpreter shutdown (Py_FinalizeEx).
+
+Prior to the safe finalization fix, active greenlets being deallocated
+during interpreter shutdown could trigger SIGSEGV or SIGABRT on Python
+< 3.11, because green_dealloc attempted to throw GreenletExit via
+g_switch() into a partially-torn-down interpreter.
+
+The fix adds _Py_IsFinalizing() guards (on Python < 3.11 only) that
+call murder_in_place() instead of g_switch() when the interpreter is
+shutting down, avoiding the crash at the cost of not running cleanup
+code inside the greenlet.
+
+These tests verify:
+  1. No crashes on ANY Python version (the core safety guarantee).
+  2. GreenletExit cleanup code runs correctly during normal thread exit
+     (the standard production path, e.g. uWSGI worker threads).
+"""
+import sys
+import subprocess
+import unittest
+import textwrap
+
+from greenlet.tests import TestCase
+
+
+class TestInterpreterShutdown(TestCase):
+
+    def _run_shutdown_script(self, script_body):
+        """
+        Run a Python script in a subprocess that exercises greenlet
+        during interpreter shutdown. Returns (returncode, stdout, stderr).
+        """
+        full_script = textwrap.dedent(script_body)
+        result = subprocess.run(
+            [sys.executable, '-c', full_script],
+            capture_output=True,
+            text=True,
+            timeout=30,
+            check=False,
+        )
+        return result.returncode, result.stdout, result.stderr
+
+    # -----------------------------------------------------------------
+    # Core safety tests: no crashes on any Python version
+    # -----------------------------------------------------------------
+
+    def test_active_greenlet_at_shutdown_no_crash(self):
+        """
+        An active (suspended) greenlet that is deallocated during
+        interpreter shutdown should not crash the process.
+
+        Before the fix, this would SIGSEGV on Python < 3.11 because
+        _green_dealloc_kill_started_non_main_greenlet tried to call
+        g_switch() during Py_FinalizeEx.
+        """
+        rc, stdout, stderr = self._run_shutdown_script("""\
+            import greenlet
+
+            def worker():
+                greenlet.getcurrent().parent.switch("from worker")
+                return "done"
+
+            g = greenlet.greenlet(worker)
+            result = g.switch()
+            assert result == "from worker", result
+            print("OK: exiting with active greenlet")
+        """)
+        self.assertEqual(rc, 0, f"Process crashed 
(rc={rc}):\n{stdout}{stderr}")
+        self.assertIn("OK: exiting with active greenlet", stdout)
+
+    def test_multiple_active_greenlets_at_shutdown(self):
+        """
+        Multiple suspended greenlets at shutdown should all be cleaned
+        up without crashing.
+        """
+        rc, stdout, stderr = self._run_shutdown_script("""\
+            import greenlet
+
+            def worker(name):
+                greenlet.getcurrent().parent.switch(f"hello from {name}")
+                return "done"
+
+            greenlets = []
+            for i in range(10):
+                g = greenlet.greenlet(worker)
+                result = g.switch(f"g{i}")
+                greenlets.append(g)
+
+            print(f"OK: {len(greenlets)} active greenlets at shutdown")
+        """)
+        self.assertEqual(rc, 0, f"Process crashed 
(rc={rc}):\n{stdout}{stderr}")
+        self.assertIn("OK: 10 active greenlets at shutdown", stdout)
+
+    def test_nested_greenlets_at_shutdown(self):
+        """
+        Nested (chained parent) greenlets at shutdown should not crash.
+        """
+        rc, stdout, stderr = self._run_shutdown_script("""\
+            import greenlet
+
+            def inner():
+                greenlet.getcurrent().parent.switch("inner done")
+
+            def outer():
+                g_inner = greenlet.greenlet(inner)
+                g_inner.switch()
+                greenlet.getcurrent().parent.switch("outer done")
+
+            g = greenlet.greenlet(outer)
+            result = g.switch()
+            assert result == "outer done", result
+            print("OK: nested greenlets at shutdown")
+        """)
+        self.assertEqual(rc, 0, f"Process crashed 
(rc={rc}):\n{stdout}{stderr}")
+        self.assertIn("OK: nested greenlets at shutdown", stdout)
+
+    def test_threaded_greenlets_at_shutdown(self):
+        """
+        Greenlets in worker threads that are still referenced at
+        shutdown should not crash.
+        """
+        rc, stdout, stderr = self._run_shutdown_script("""\
+            import greenlet
+            import threading
+
+            results = []
+
+            def thread_worker():
+                def greenlet_func():
+                    greenlet.getcurrent().parent.switch("from thread greenlet")
+                    return "done"
+
+                g = greenlet.greenlet(greenlet_func)
+                val = g.switch()
+                results.append((g, val))
+
+            threads = []
+            for _ in range(3):
+                t = threading.Thread(target=thread_worker)
+                t.start()
+                threads.append(t)
+
+            for t in threads:
+                t.join()
+
+            print(f"OK: {len(results)} threaded greenlets at shutdown")
+        """)
+        self.assertEqual(rc, 0, f"Process crashed 
(rc={rc}):\n{stdout}{stderr}")
+        self.assertIn("OK: 3 threaded greenlets at shutdown", stdout)
+
+    # -----------------------------------------------------------------
+    # Cleanup semantics tests
+    # -----------------------------------------------------------------
+    #
+    # Note on behavioral testing during interpreter shutdown:
+    #
+    # During Py_FinalizeEx, sys.stdout is set to None early, making
+    # print() a no-op.  More importantly, an active greenlet in the
+    # module-level scope interferes with module dict clearing — the
+    # greenlet's dealloc path (which temporarily resurrects the object
+    # and performs a stack switch via g_switch) prevents reliable
+    # observation of cleanup behavior.
+    #
+    # The production crash (SIGSEGV/SIGABRT) occurs during thread-state
+    # cleanup in Py_FinalizeEx, not during module dict clearing.  Our
+    # _Py_IsFinalizing() guard in _green_dealloc_kill_started_non_main_
+    # greenlet targets that path.  The safety tests above verify that no
+    # crashes occur; the tests below verify that greenlet cleanup works
+    # correctly during normal thread exit (the most common code path).
+
+    def test_greenlet_cleanup_during_thread_exit(self):
+        """
+        When a thread exits normally while holding active greenlets,
+        GreenletExit IS thrown and cleanup code runs.  This is the
+        standard cleanup path used in production (e.g. uWSGI worker
+        threads finishing a request).
+        """
+        rc, stdout, stderr = self._run_shutdown_script("""\
+            import os
+            import threading
+            import greenlet
+
+            _write = os.write
+
+            def thread_func():
+                def worker(_w=_write,
+                           _GreenletExit=greenlet.GreenletExit):
+                    try:
+                        greenlet.getcurrent().parent.switch("suspended")
+                    except _GreenletExit:
+                        _w(1, b"CLEANUP: GreenletExit caught\\n")
+                        raise
+
+                g = greenlet.greenlet(worker)
+                g.switch()
+                # Thread exits with active greenlet -> thread-state
+                # cleanup triggers GreenletExit
+
+            t = threading.Thread(target=thread_func)
+            t.start()
+            t.join()
+            print("OK: thread cleanup done")
+        """)
+        self.assertEqual(rc, 0, f"Process crashed 
(rc={rc}):\n{stdout}{stderr}")
+        self.assertIn("OK: thread cleanup done", stdout)
+        self.assertIn("CLEANUP: GreenletExit caught", stdout)
+
+    def test_finally_block_during_thread_exit(self):
+        """
+        try/finally blocks in active greenlets run correctly when the
+        owning thread exits.
+        """
+        rc, stdout, stderr = self._run_shutdown_script("""\
+            import os
+            import threading
+            import greenlet
+
+            _write = os.write
+
+            def thread_func():
+                def worker(_w=_write):
+                    try:
+                        greenlet.getcurrent().parent.switch("suspended")
+                    finally:
+                        _w(1, b"FINALLY: cleanup executed\\n")
+
+                g = greenlet.greenlet(worker)
+                g.switch()
+
+            t = threading.Thread(target=thread_func)
+            t.start()
+            t.join()
+            print("OK: thread cleanup done")
+        """)
+        self.assertEqual(rc, 0, f"Process crashed 
(rc={rc}):\n{stdout}{stderr}")
+        self.assertIn("OK: thread cleanup done", stdout)
+        self.assertIn("FINALLY: cleanup executed", stdout)
+
+    def test_many_greenlets_with_cleanup_at_shutdown(self):
+        """
+        Stress test: many active greenlets with cleanup code at shutdown.
+        Ensures no crashes regardless of deallocation order.
+        """
+        rc, stdout, stderr = self._run_shutdown_script("""\
+            import sys
+            import greenlet
+
+            cleanup_count = 0
+
+            def worker(idx):
+                global cleanup_count
+                try:
+                    greenlet.getcurrent().parent.switch(f"ready-{idx}")
+                except greenlet.GreenletExit:
+                    cleanup_count += 1
+                    raise
+
+            greenlets = []
+            for i in range(50):
+                g = greenlet.greenlet(worker)
+                result = g.switch(i)
+                greenlets.append(g)
+
+            print(f"OK: {len(greenlets)} greenlets about to shut down")
+            # Note: we can't easily print cleanup_count during shutdown
+            # since it happens after the main module's code runs.
+        """)
+        self.assertEqual(rc, 0, f"Process crashed 
(rc={rc}):\n{stdout}{stderr}")
+        self.assertIn("OK: 50 greenlets about to shut down", stdout)
+
+    def test_deeply_nested_greenlets_at_shutdown(self):
+        """
+        Deeply nested greenlet parent chains at shutdown.
+        Tests that the deallocation order doesn't cause issues.
+        """
+        rc, stdout, stderr = self._run_shutdown_script("""\
+            import greenlet
+
+            def level(depth, max_depth):
+                if depth < max_depth:
+                    g = greenlet.greenlet(level)
+                    g.switch(depth + 1, max_depth)
+                greenlet.getcurrent().parent.switch(f"depth-{depth}")
+
+            g = greenlet.greenlet(level)
+            result = g.switch(0, 10)
+            print(f"OK: nested to depth 10, got {result}")
+        """)
+        self.assertEqual(rc, 0, f"Process crashed 
(rc={rc}):\n{stdout}{stderr}")
+        self.assertIn("OK: nested to depth 10", stdout)
+
+    def test_greenlet_with_traceback_at_shutdown(self):
+        """
+        A greenlet that has an active exception context when it's
+        suspended should not crash during shutdown cleanup.
+        """
+        rc, stdout, stderr = self._run_shutdown_script("""\
+            import greenlet
+
+            def worker():
+                try:
+                    raise ValueError("test error")
+                except ValueError:
+                    # Suspend while an exception is active on the stack
+                    greenlet.getcurrent().parent.switch("suspended with exc")
+                return "done"
+
+            g = greenlet.greenlet(worker)
+            result = g.switch()
+            assert result == "suspended with exc"
+            print("OK: greenlet with active exception at shutdown")
+        """)
+        self.assertEqual(rc, 0, f"Process crashed 
(rc={rc}):\n{stdout}{stderr}")
+        self.assertIn("OK: greenlet with active exception at shutdown", stdout)
+
+
+if __name__ == '__main__':
+    unittest.main()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/greenlet-3.3.1/src/greenlet/tests/test_leaks.py 
new/greenlet-3.3.2/src/greenlet/tests/test_leaks.py
--- old/greenlet-3.3.1/src/greenlet/tests/test_leaks.py 2026-01-23 
16:28:32.000000000 +0100
+++ new/greenlet-3.3.2/src/greenlet/tests/test_leaks.py 2026-02-20 
21:14:45.000000000 +0100
@@ -16,6 +16,7 @@
 from . import TestCase
 from . import PY314
 from . import RUNNING_ON_FREETHREAD_BUILD
+from . import WIN
 from .leakcheck import fails_leakcheck
 from .leakcheck import ignores_leakcheck
 from .leakcheck import RUNNING_ON_MANYLINUX
@@ -365,6 +366,11 @@
         # Like the above test, but what if there are a bunch of
         # unfinished greenlets in a thread that dies?
         # Does it matter if we deallocate in the thread or not?
+
+        # First, make sure we can get useful measurements. This will
+        # be skipped if not.
+        self.get_process_uss()
+
         EXIT_COUNT = [0]
 
         def f():
@@ -451,6 +457,17 @@
     # Because the main greenlets from the background threads do not exit in a 
timely fashion,
     # we fail the object-based leakchecks.
     def 
test_untracked_memory_doesnt_increase_unfinished_thread_dealloc_in_main(self):
+        # Between Feb 10 and Feb 20 2026, this test started failing on
+        # Github Actions, windows 3.14t. With no relevant code changes on
+        # our part. Both versions were 3.14.3 (same build). The only change
+        # is the Github actions "Runner Image". The working one was version
+        # 20260202.17.1, while the updated failing version was
+        # 20260217.31.1. Both report the same version of the operating system
+        # (Microsoft Windows Server 2025 10.0.26100).
+        #
+        # Reevaluate on future runner image releases.
+        if WIN and RUNNING_ON_FREETHREAD_BUILD and PY314:
+            self.skipTest("Windows 3.14t appears to leak. No other platform 
does.")
         self._check_untracked_memory_thread(deallocate_in_thread=False)
 
 if __name__ == '__main__':
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/greenlet-3.3.1/src/greenlet.egg-info/PKG-INFO 
new/greenlet-3.3.2/src/greenlet.egg-info/PKG-INFO
--- old/greenlet-3.3.1/src/greenlet.egg-info/PKG-INFO   2026-01-23 
16:28:35.000000000 +0100
+++ new/greenlet-3.3.2/src/greenlet.egg-info/PKG-INFO   2026-02-20 
21:14:48.000000000 +0100
@@ -1,10 +1,10 @@
 Metadata-Version: 2.4
 Name: greenlet
-Version: 3.3.1
+Version: 3.3.2
 Summary: Lightweight in-process concurrent programming
 Author-email: Alexey Borzenkov <[email protected]>
 Maintainer-email: Jason Madden <[email protected]>
-License-Expression: MIT AND Python-2.0
+License-Expression: MIT AND PSF-2.0
 Project-URL: Homepage, https://greenlet.readthedocs.io
 Project-URL: Documentation, https://greenlet.readthedocs.io
 Project-URL: Repository, https://github.com/python-greenlet/greenlet
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/greenlet-3.3.1/src/greenlet.egg-info/SOURCES.txt 
new/greenlet-3.3.2/src/greenlet.egg-info/SOURCES.txt
--- old/greenlet-3.3.1/src/greenlet.egg-info/SOURCES.txt        2026-01-23 
16:28:35.000000000 +0100
+++ new/greenlet-3.3.2/src/greenlet.egg-info/SOURCES.txt        2026-02-20 
21:14:48.000000000 +0100
@@ -119,6 +119,7 @@
 src/greenlet/tests/test_generator_nested.py
 src/greenlet/tests/test_greenlet.py
 src/greenlet/tests/test_greenlet_trash.py
+src/greenlet/tests/test_interpreter_shutdown.py
 src/greenlet/tests/test_leaks.py
 src/greenlet/tests/test_stack_saved.py
 src/greenlet/tests/test_throw.py

Reply via email to