From b18644bee94a29fa0df33e413fc91538f7adf774 Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Sat, 21 Mar 2026 14:01:44 +0300 Subject: [PATCH 1/5] Use Py_NewRef() --- gmp.c | 95 +++++++++++++++++++++++++++-------------------------------- 1 file changed, 43 insertions(+), 52 deletions(-) diff --git a/gmp.c b/gmp.c index 7150f278..7aeaefc8 100644 --- a/gmp.c +++ b/gmp.c @@ -729,22 +729,21 @@ str(PyObject *self) #define Number_Check(op) (PyFloat_Check((op)) || PyComplex_Check((op))) -#define CHECK_OP(u, a) \ - if (MPZ_Check(a)) { \ - u = (MPZ_Object *)a; \ - Py_INCREF(a); \ - } \ - else if (PyLong_Check(a)) { \ - u = MPZ_from_int(a); \ - if (!u) { \ - goto end; \ - } \ - } \ - else if (Number_Check(a)) { \ - goto numbers; \ - } \ - else { \ - goto fallback; \ +#define CHECK_OP(u, a) \ + if (MPZ_Check(a)) { \ + u = (MPZ_Object *)Py_NewRef(a); \ + } \ + else if (PyLong_Check(a)) { \ + u = MPZ_from_int(a); \ + if (!u) { \ + goto end; \ + } \ + } \ + else if (Number_Check(a)) { \ + goto numbers; \ + } \ + else { \ + goto fallback; \ } PyObject * @@ -916,19 +915,18 @@ to_bool(PyObject *self) return !zz_iszero(&((MPZ_Object *)self)->z); } -#define CHECK_OPv2(u, a) \ - if (MPZ_Check(a)) { \ - u = (MPZ_Object *)a; \ - Py_INCREF(a); \ - } \ - else if (PyLong_Check(a)) { \ - ; \ - } \ - else if (Number_Check(a)) { \ - goto numbers; \ - } \ - else { \ - goto fallback; \ +#define CHECK_OPv2(u, a) \ + if (MPZ_Check(a)) { \ + u = (MPZ_Object *)Py_NewRef(a); \ + } \ + else if (PyLong_Check(a)) { \ + ; \ + } \ + else if (Number_Check(a)) { \ + goto numbers; \ + } \ + else { \ + goto fallback; \ } #define BINOP(suff, slot) \ @@ -1004,8 +1002,7 @@ done: \ PyObject *uf, *vf, *rf; \ \ if (Number_Check(self)) { \ - uf = self; \ - Py_INCREF(uf); \ + uf = Py_NewRef(self); \ } \ else { \ uf = to_float(self); \ @@ -1014,8 +1011,7 @@ done: \ } \ } \ if (Number_Check(other)) { \ - vf = other; \ - Py_INCREF(vf); \ + vf = Py_NewRef(other); \ } \ else { \ vf = to_float(other); \ @@ -1309,8 +1305,7 @@ nb_truediv(PyObject *self, PyObject *other) PyObject *uf, *vf; if (Number_Check(self)) { - uf = self; - Py_INCREF(uf); + uf = Py_NewRef(self); } else { uf = to_float(self); @@ -1319,8 +1314,7 @@ nb_truediv(PyObject *self, PyObject *other) } } if (Number_Check(other)) { - vf = other; - Py_INCREF(vf); + vf = Py_NewRef(other); } else { vf = to_float(other); @@ -1337,17 +1331,16 @@ nb_truediv(PyObject *self, PyObject *other) return res; } -#define CHECK_OP_INT(u, a) \ - if (MPZ_Check(a)) { \ - u = (MPZ_Object *)a; \ - Py_INCREF(a); \ - } \ - else { \ - u = MPZ_from_int(a); \ - if (!u) { \ - goto end; \ - } \ - } \ +#define CHECK_OP_INT(u, a) \ + if (MPZ_Check(a)) { \ + u = (MPZ_Object *)Py_NewRef(a); \ + } \ + else { \ + u = MPZ_from_int(a); \ + if (!u) { \ + goto end; \ + } \ + } \ #define BINOP_INT(suff) \ static PyObject * \ @@ -1527,8 +1520,7 @@ power(PyObject *self, PyObject *other, PyObject *module) PyObject *uf, *vf; if (Number_Check(self)) { - uf = self; - Py_INCREF(uf); + uf = Py_NewRef(self); } else { uf = to_float(self); @@ -1537,8 +1529,7 @@ power(PyObject *self, PyObject *other, PyObject *module) } } if (Number_Check(other)) { - vf = other; - Py_INCREF(vf); + vf = Py_NewRef(other); } else { vf = to_float(other); From f01195f9d905b626ce9eb5a5881c92597262289c Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Sat, 28 Mar 2026 06:08:05 +0300 Subject: [PATCH 2/5] Polish pytest_report_header() --- tests/conftest.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index f59aa7cd..090ec111 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -20,9 +20,9 @@ def pytest_report_header(config): print(f""" Using the ZZ library v{gmp._zz_version} - Bits per digit : {gmp.mpz_info.bits_per_digit} - sizeof(zz_digit_t): {gmp.mpz_info.sizeof_digit} - Maximal bit count : {gmp.mpz_info.bitcnt_max} + Bits per digit : {gmp.mpz_info.bits_per_digit} + sizeof(digit) : {gmp.mpz_info.sizeof_digit} + Maximal bit count: {gmp.mpz_info.bitcnt_max} The gmp module v{gmp.__version__} """) From 78db2e57969db7f61c5e5a417946dd6a02a11a75 Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Sat, 28 Mar 2026 06:54:03 +0300 Subject: [PATCH 3/5] Use new runner images for MacOS/Windows --- .github/workflows/wheels.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/wheels.yml b/.github/workflows/wheels.yml index 9906aed5..d93f5975 100644 --- a/.github/workflows/wheels.yml +++ b/.github/workflows/wheels.yml @@ -6,8 +6,8 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - os: [ubuntu-24.04, ubuntu-24.04-arm, macos-15-intel, macos-15, - windows-2022] + os: [ubuntu-24.04, ubuntu-24.04-arm, macos-26-intel, macos-26, + windows-2025] msystem: [ucrt64] menv: [ucrt-x86_64] include: From 20b33d8d580efc4c1e8185061016fd8cc59f88d1 Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Sat, 28 Mar 2026 10:10:30 +0300 Subject: [PATCH 4/5] Refactor benchmarks, add sum and harmonic --- bench/README.rst | 1 + bench/collatz.py | 13 ++----------- bench/harmonic.py | 12 ++++++++++++ bench/mul.py | 12 ++---------- bench/sum.py | 10 ++++++++++ bench/utils.py | 17 +++++++++++++++++ 6 files changed, 44 insertions(+), 21 deletions(-) create mode 100644 bench/harmonic.py create mode 100644 bench/sum.py create mode 100644 bench/utils.py diff --git a/bench/README.rst b/bench/README.rst index 474d3da7..a5fae97b 100644 --- a/bench/README.rst +++ b/bench/README.rst @@ -5,6 +5,7 @@ It's possible to run them also with gmpy2's and flint's integer types: .. code:: sh ( export T="gmpy2.mpz"; \ + export PYTHONPATH=. ; \ python bench/mul.py -q --copy-env --rigorous -o $T.json ) Beware, that the gmp prefers clang over gcc and extensions might diff --git a/bench/collatz.py b/bench/collatz.py index 6c0f63fc..2d143706 100644 --- a/bench/collatz.py +++ b/bench/collatz.py @@ -1,17 +1,8 @@ -# collatz.py - -import os +# bench/collatz.py import pyperf -if os.getenv("T") == "gmpy2.mpz": - from gmpy2 import mpz -elif os.getenv("T") == "flint.fmpz": - from flint import fmpz as mpz -elif os.getenv("T") == "int": - mpz = int -else: - from gmp import mpz +from bench.utils import mpz zero = mpz(0) one = mpz(1) diff --git a/bench/harmonic.py b/bench/harmonic.py new file mode 100644 index 00000000..067fa21c --- /dev/null +++ b/bench/harmonic.py @@ -0,0 +1,12 @@ +# bench/harmonic.py + +from fractions import Fraction + +import pyperf + +from bench.utils import mpz, mysum + +runner = pyperf.Runner() +for n in [100, 1000]: + xs = [Fraction(mpz(1), mpz(i)) for i in range(1, n + 1)] + runner.bench_func(f"H({n})", mysum, xs) diff --git a/bench/mul.py b/bench/mul.py index 09cc5758..b7e6f056 100644 --- a/bench/mul.py +++ b/bench/mul.py @@ -1,18 +1,10 @@ -# mul.py +# bench/mul.py -import os from operator import mul import pyperf -if os.getenv("T") == "gmpy2.mpz": - from gmpy2 import mpz -elif os.getenv("T") == "flint.fmpz": - from flint import fmpz as mpz -elif os.getenv("T") == "int": - mpz = int -else: - from gmp import mpz +from bench.utils import mpz values = ["1<<7", "1<<38", "1<<300", "1<<3000"] diff --git a/bench/sum.py b/bench/sum.py new file mode 100644 index 00000000..1d348f50 --- /dev/null +++ b/bench/sum.py @@ -0,0 +1,10 @@ +# bench/sum.py + +import pyperf + +from bench.utils import mpz, mysum + +runner = pyperf.Runner() +for n in [100, 1000]: + xs = [mpz(i) for i in range(1, n + 1)] + runner.bench_func(f"sum({n})", mysum, xs) diff --git a/bench/utils.py b/bench/utils.py new file mode 100644 index 00000000..a21e46df --- /dev/null +++ b/bench/utils.py @@ -0,0 +1,17 @@ +import os + +if os.getenv("T") == "gmpy2.mpz": + from gmpy2 import mpz +elif os.getenv("T") == "flint.fmpz": + from flint import fmpz as mpz +elif os.getenv("T") == "int": + mpz = int +else: + pass + + +def mysum(xs): + total = xs[0] + for t in xs[1:]: + total += t + return t From c619768f0fd59a21dcd303db2ad641fe8930dad5 Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Sat, 28 Mar 2026 10:57:53 +0300 Subject: [PATCH 5/5] Update msys2/setup-msys2 action --- .github/workflows/wheels.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/wheels.yml b/.github/workflows/wheels.yml index d93f5975..f42ce0cb 100644 --- a/.github/workflows/wheels.yml +++ b/.github/workflows/wheels.yml @@ -18,7 +18,7 @@ jobs: - uses: actions/checkout@v6 with: fetch-depth: 0 - - uses: msys2/setup-msys2@v2.30.0 + - uses: msys2/setup-msys2@v2.31.0 name: Setup msys2 with: install: >-