SPECS: add python-greenlet

Signed-off-by: Jvle <keke.oerv@isrc.iscas.ac.cn>
This commit is contained in:
Jvle
2026-03-05 11:30:06 +08:00
commit a01a3db319
2 changed files with 150 additions and 0 deletions

53
python-greenlet.spec Normal file
View File

@@ -0,0 +1,53 @@
# SPDX-FileCopyrightText: (C) 2026 Institute of Software, Chinese Academy of Sciences (ISCAS)
# SPDX-FileCopyrightText: (C) 2026 openRuyi Project Contributors
# SPDX-FileContributor: Jvle <keke.oerv@isrc.iscas.ac.cn>
#
# SPDX-License-Identifier: MulanPSL-2.0
%global srcname greenlet
Name: python-%{srcname}
Version: 3.3.2
Release: %autorelease
Summary: Lightweight in-process concurrent programming
License: MIT AND PSF-2.0
URL: https://github.com/python-greenlet/greenlet
#!RemoteAsset
Source0: https://files.pythonhosted.org/packages/source/g/%{srcname}/%{srcname}-%{version}.tar.gz
BuildSystem: pyproject
# Skip leak checking to avoid a missing dependency, `objgraph`
Patch0: skip-leak-checks.patch
BuildOption(install): %{srcname}
BuildRequires: pkgconfig(python3)
BuildRequires: python3dist(psutil)
BuildRequires: pyproject-rpm-macros
BuildRequires: gcc-c++
Provides: python3-%{srcname}
%python_provide python3-%{srcname}
%description
The greenlet package is a spin-off of Stackless, a version of CPython
that supports micro-threads called "tasklets". Tasklets run
pseudo-concurrently (typically in a single or a few OS-level threads)
and are synchronized with data exchanges on "channels".
%generate_buildrequires
%pyproject_buildrequires
%check
cd /
PYTHONPATH="%{buildroot}%{python3_sitearch}" \
%{__python3} -m unittest discover -v \
-s "%{buildroot}%{python3_sitearch}/greenlet/tests" \
-t "%{buildroot}%{python3_sitearch}"
%files -f %{pyproject_files}
%doc AUTHORS README.rst
%{_includedir}/python%{python3_version}*/%{srcname}/
%changelog
%{?autochangelog}

97
skip-leak-checks.patch Normal file
View File

@@ -0,0 +1,97 @@
diff -up greenlet-3.2.4/src/greenlet/tests/leakcheck.py.noobjgraph greenlet-3.2.4/src/greenlet/tests/leakcheck.py
--- greenlet-3.2.4/src/greenlet/tests/leakcheck.py.noobjgraph 2025-11-29 13:57:36.924990116 -0700
+++ greenlet-3.2.4/src/greenlet/tests/leakcheck.py 2025-11-29 14:01:38.252622044 -0700
@@ -131,10 +131,6 @@ class _RefCountChecker(object):
return True
- def _growth(self):
- return objgraph.growth(limit=None, peak_stats=self.peak_stats,
- filter=self._include_object_p)
-
def _report_diff(self, growth):
if not growth:
return "<Unable to calculate growth>"
@@ -165,16 +161,6 @@ class _RefCountChecker(object):
if gc_enabled:
gc.enable()
- def _growth_after(self):
- # Grab post snapshot
- # pylint:disable=no-member
- if 'urlparse' in sys.modules:
- sys.modules['urlparse'].clear_cache()
- if 'urllib.parse' in sys.modules:
- sys.modules['urllib.parse'].clear_cache()
-
- return self._growth()
-
def _check_deltas(self, growth):
# Return false when we have decided there is no leak,
# true if we should keep looping, raises an assertion
@@ -206,20 +192,12 @@ class _RefCountChecker(object):
if len(deltas) >= 4 and sum(deltas[-4:]) == 0:
return False
- if len(deltas) >= 3 and deltas[-1] > 0 and deltas[-1] == deltas[-2] and deltas[-2] == deltas[-3]:
- diff = self._report_diff(growth)
- raise LeakCheckError('refcount increased by %r\n%s' % (deltas, diff))
-
# OK, we don't know for sure yet. Let's search for more
if sum(deltas[-3:]) <= 0 or sum(deltas[-4:]) <= 0 or deltas[-4:].count(0) >= 2:
# this is suspicious, so give a few more runs
limit = 11
else:
limit = 7
- if len(deltas) >= limit:
- raise LeakCheckError('refcount increased by %r\n%s'
- % (deltas,
- self._report_diff(growth)))
# We couldn't decide yet, keep going
return True
@@ -233,24 +211,6 @@ class _RefCountChecker(object):
self.testcase.expect_greenlet_leak = True
self.ignored_types = getattr(self.function, "leakcheck_ignore_types", ())
- # Capture state before; the incremental will be
- # updated by each call to _growth_after
- growth = self._growth()
-
- try:
- while self._check_deltas(growth):
- self._run_test(args, kwargs)
-
- growth = self._growth_after()
-
- self.deltas.append(sum((stat[2] for stat in growth)))
- except LeakCheckError:
- if not expect_failure:
- raise
- else:
- if expect_failure:
- raise LeakCheckError("Expected %s to leak but it did not." % (self.function,))
-
def wrap_refcount(method):
if getattr(method, 'ignore_leakcheck', False) or SKIP_LEAKCHECKS:
return method
diff -up greenlet-3.2.4/src/greenlet/tests/leakcheck.py.noobjgraph greenlet-3.2.4/src/greenlet/tests/leakcheck.py
--- greenlet-3.2.4/src/greenlet/tests/leakcheck.py.noobjgraph 2025-11-29 14:02:02.908119435 -0700
+++ greenlet-3.2.4/src/greenlet/tests/leakcheck.py 2025-11-29 14:03:16.651174702 -0700
@@ -31,8 +31,6 @@ from functools import wraps
import unittest
-import objgraph
-
# graphviz 0.18 (Nov 7 2021), available only on Python 3.6 and newer,
# has added type hints (sigh). It wants to use ``typing.Literal`` for
# some stuff, but that's only available on Python 3.9+. If that's not
@@ -109,7 +107,6 @@ if hasattr(sys, 'getobjects'):
return sys.getobjects(0) # pylint:disable=no-member
def __getattr__(self, name):
return getattr(gc, name)
- objgraph.gc = _MockGC()
fails_strict_leakcheck = fails_leakcheck
else:
def fails_strict_leakcheck(func):