Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-gmpy2 for openSUSE:Factory 
checked in at 2026-10-12 22:07:41
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-gmpy2 (Old)
 and      /work/SRC/openSUSE:Factory/.python-gmpy2.new.3698736 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-gmpy2"

Mon Oct 12 22:07:41 2026 rev:11 rq:1384294 version:2.3.2

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-gmpy2/python-gmpy2.changes        
2026-07-15 17:02:30.148944116 +0200
+++ /work/SRC/openSUSE:Factory/.python-gmpy2.new.3698736/python-gmpy2.changes   
2026-10-12 22:07:43.547568456 +0200
@@ -1,0 +2,7 @@
+Mon Oct  5 11:30:01 UTC 2026 - Dirk Müller <[email protected]>
+
+- update to 2.3.2:
+  * Fix processing defaults for e/E format types precision.
+  * Support PyPy3.12.
+
+-------------------------------------------------------------------

Old:
----
  gmpy2-2.3.1.tar.gz

New:
----
  gmpy2-2.3.2.tar.gz

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

Other differences:
------------------
++++++ python-gmpy2.spec ++++++
--- /var/tmp/diff_new_pack.e6M6NM/_old  2026-10-12 22:07:44.329601079 +0200
+++ /var/tmp/diff_new_pack.e6M6NM/_new  2026-10-12 22:07:44.331601162 +0200
@@ -18,7 +18,7 @@
 
 %{?sle15_python_module_pythons}
 Name:           python-gmpy2
-Version:        2.3.1
+Version:        2.3.2
 Release:        0
 Summary:        GMP/MPIR, MPFR, and MPC interface to Python 2.6+ and 3x
 License:        LGPL-3.0-only

++++++ gmpy2-2.3.1.tar.gz -> gmpy2-2.3.2.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gmpy2-2.3.1/.github/workflows/backport.yml 
new/gmpy2-2.3.2/.github/workflows/backport.yml
--- old/gmpy2-2.3.1/.github/workflows/backport.yml      2026-06-24 
02:39:59.000000000 +0200
+++ new/gmpy2-2.3.2/.github/workflows/backport.yml      2026-10-04 
03:16:17.000000000 +0200
@@ -25,7 +25,7 @@
           echo "matched=$matched" >> $GITHUB_OUTPUT
       - name: Backport Action
         if: fromJSON(steps.check_labels.outputs.matched) > 0
-        uses: sorenlouv/[email protected]
+        uses: sorenlouv/[email protected]
         with:
           github_token: ${{ secrets.GITHUB_TOKEN }}
           auto_backport_label_prefix: backport-to-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gmpy2-2.3.1/.github/workflows/ci.yml 
new/gmpy2-2.3.2/.github/workflows/ci.yml
--- old/gmpy2-2.3.1/.github/workflows/ci.yml    2026-06-24 02:39:59.000000000 
+0200
+++ new/gmpy2-2.3.2/.github/workflows/ci.yml    2026-10-04 03:16:17.000000000 
+0200
@@ -5,6 +5,9 @@
   workflow_dispatch:
   schedule:
     - cron: '0 0 * * 2'
+concurrency:
+  group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
+  cancel-in-progress: true
 jobs:
   coverage:
     uses: ./.github/workflows/coverage.yml
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gmpy2-2.3.1/.github/workflows/coverage.yml 
new/gmpy2-2.3.2/.github/workflows/coverage.yml
--- old/gmpy2-2.3.1/.github/workflows/coverage.yml      2026-06-24 
02:39:59.000000000 +0200
+++ new/gmpy2-2.3.2/.github/workflows/coverage.yml      2026-10-04 
03:16:17.000000000 +0200
@@ -7,14 +7,14 @@
     strategy:
       fail-fast: false
       matrix:
-        python-version: [pypy3.11, "3.x"]
+        python-version: [pypy3.12, "3.x"]
         os: [ubuntu-22.04]
     runs-on: ${{ matrix.os }}
     steps:
-      - uses: actions/checkout@v6
+      - uses: actions/checkout@v7
         with:
           fetch-depth: 0
-      - uses: actions/setup-python@v6
+      - uses: actions/setup-python@v7
         with:
           python-version: ${{ matrix.python-version }}
           allow-prereleases: true
@@ -49,7 +49,7 @@
     needs:
       - coverage
     steps:
-      - uses: actions/checkout@v6
+      - uses: actions/checkout@v7
         with:
           fetch-depth: 0
       - run: sudo apt-get update
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gmpy2-2.3.1/.github/workflows/publish.yml 
new/gmpy2-2.3.2/.github/workflows/publish.yml
--- old/gmpy2-2.3.1/.github/workflows/publish.yml       2026-06-24 
02:39:59.000000000 +0200
+++ new/gmpy2-2.3.2/.github/workflows/publish.yml       2026-10-04 
03:16:17.000000000 +0200
@@ -6,16 +6,16 @@
     if: startsWith(github.ref, 'refs/tags/')
     runs-on: ubuntu-24.04
     steps:
-    - uses: actions/checkout@v6
+    - uses: actions/checkout@v7
       with:
         fetch-depth: 0
-    - uses: actions/setup-python@v6
+    - uses: actions/setup-python@v7
       with:
         python-version: "3.x"
     - run: pip install build
     - name: Cache GNU GMP/MPFR/MPC builds
       id: cache-gmp
-      uses: actions/cache@v5
+      uses: actions/cache@v6
       with:
         path: .local
         key: ${{ matrix.os }}-${{ hashFiles('scripts/*') }}
@@ -65,7 +65,7 @@
         pattern: gmpy2-*
         path: dist/
         merge-multiple: true
-    - uses: sigstore/[email protected]
+    - uses: sigstore/[email protected]
       with:
         inputs: >-
           ./dist/*.tar.gz
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gmpy2-2.3.1/.github/workflows/wheels.yml 
new/gmpy2-2.3.2/.github/workflows/wheels.yml
--- old/gmpy2-2.3.1/.github/workflows/wheels.yml        2026-06-24 
02:39:59.000000000 +0200
+++ new/gmpy2-2.3.2/.github/workflows/wheels.yml        2026-10-04 
03:16:17.000000000 +0200
@@ -17,7 +17,7 @@
             msystem: clangarm64
             menv: clang-aarch64
     steps:
-      - uses: actions/checkout@v6
+      - uses: actions/checkout@v7
         with:
           fetch-depth: 0
       - uses: msys2/setup-msys2@v2
@@ -34,7 +34,7 @@
           path-type: inherit
         if: contains(matrix.os, 'windows')
       - name: Build wheels
-        uses: pypa/[email protected]
+        uses: pypa/cibuildwheel@84f6233892f964b4c2aba196595e85602bc61b34
       - uses: actions/upload-artifact@v7
         with:
           name: wheels-${{ matrix.os }}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gmpy2-2.3.1/PKG-INFO new/gmpy2-2.3.2/PKG-INFO
--- old/gmpy2-2.3.1/PKG-INFO    2026-06-24 02:41:18.768638100 +0200
+++ new/gmpy2-2.3.2/PKG-INFO    2026-10-04 03:17:27.883381400 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.4
 Name: gmpy2
-Version: 2.3.1
+Version: 2.3.2
 Summary: gmpy2 interface to GMP, MPFR, and MPC for Python
 Author: Alex Martelli, Case Van Horsen
 Maintainer-email: Matthias Köppe <[email protected]>, Sergey B 
Kirpichev <[email protected]>
@@ -37,11 +37,12 @@
 Requires-Dist: sphinx-rtd-theme>=1; extra == "docs"
 Provides-Extra: tests
 Requires-Dist: pytest; extra == "tests"
-Requires-Dist: hypothesis; extra == "tests"
+Requires-Dist: hypothesis; implementation_name != "pypy" and extra == "tests"
+Requires-Dist: hypothesis<=6.150.0; implementation_name == "pypy" and extra == 
"tests"
 Requires-Dist: cython; extra == "tests"
 Requires-Dist: mpmath; extra == "tests"
 Requires-Dist: setuptools; extra == "tests"
-Requires-Dist: numpy; (python_version >= "3.11" and python_version < "3.15") 
and extra == "tests"
+Requires-Dist: numpy; (python_version >= "3.11" and python_version < "3.15" 
and implementation_name != "pypy") and extra == "tests"
 Dynamic: license-file
 
 gmpy2 is an optimized, C-coded Python extension module that supports fast
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gmpy2-2.3.1/docs/history.rst 
new/gmpy2-2.3.2/docs/history.rst
--- old/gmpy2-2.3.1/docs/history.rst    2026-06-24 02:39:59.000000000 +0200
+++ new/gmpy2-2.3.2/docs/history.rst    2026-10-04 03:16:17.000000000 +0200
@@ -3,6 +3,12 @@
 
 .. currentmodule:: gmpy2
 
+Changes in gmpy2 2.3.2
+----------------------
+
+* Fix processing defaults for e/E format types precision. (skirpichev)
+* Support PyPy3.12. (skirpichev)
+
 Changes in gmpy2 2.3.1
 ----------------------
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gmpy2-2.3.1/gmpy2/mpc.h new/gmpy2-2.3.2/gmpy2/mpc.h
--- old/gmpy2-2.3.1/gmpy2/mpc.h 2026-06-24 02:41:15.000000000 +0200
+++ new/gmpy2-2.3.2/gmpy2/mpc.h 2026-10-04 03:17:25.000000000 +0200
@@ -34,8 +34,8 @@
 /* Define MPC version number */
 #define MPC_VERSION_MAJOR 1
 #define MPC_VERSION_MINOR 4
-#define MPC_VERSION_PATCHLEVEL 0
-#define MPC_VERSION_STRING "1.4.0"
+#define MPC_VERSION_PATCHLEVEL 1
+#define MPC_VERSION_STRING "1.4.1"
 
 /* Macros dealing with MPC VERSION */
 #define MPC_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gmpy2-2.3.1/gmpy2.egg-info/PKG-INFO 
new/gmpy2-2.3.2/gmpy2.egg-info/PKG-INFO
--- old/gmpy2-2.3.1/gmpy2.egg-info/PKG-INFO     2026-06-24 02:41:18.000000000 
+0200
+++ new/gmpy2-2.3.2/gmpy2.egg-info/PKG-INFO     2026-10-04 03:17:27.000000000 
+0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.4
 Name: gmpy2
-Version: 2.3.1
+Version: 2.3.2
 Summary: gmpy2 interface to GMP, MPFR, and MPC for Python
 Author: Alex Martelli, Case Van Horsen
 Maintainer-email: Matthias Köppe <[email protected]>, Sergey B 
Kirpichev <[email protected]>
@@ -37,11 +37,12 @@
 Requires-Dist: sphinx-rtd-theme>=1; extra == "docs"
 Provides-Extra: tests
 Requires-Dist: pytest; extra == "tests"
-Requires-Dist: hypothesis; extra == "tests"
+Requires-Dist: hypothesis; implementation_name != "pypy" and extra == "tests"
+Requires-Dist: hypothesis<=6.150.0; implementation_name == "pypy" and extra == 
"tests"
 Requires-Dist: cython; extra == "tests"
 Requires-Dist: mpmath; extra == "tests"
 Requires-Dist: setuptools; extra == "tests"
-Requires-Dist: numpy; (python_version >= "3.11" and python_version < "3.15") 
and extra == "tests"
+Requires-Dist: numpy; (python_version >= "3.11" and python_version < "3.15" 
and implementation_name != "pypy") and extra == "tests"
 Dynamic: license-file
 
 gmpy2 is an optimized, C-coded Python extension module that supports fast
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gmpy2-2.3.1/gmpy2.egg-info/SOURCES.txt 
new/gmpy2-2.3.2/gmpy2.egg-info/SOURCES.txt
--- old/gmpy2-2.3.1/gmpy2.egg-info/SOURCES.txt  2026-06-24 02:41:18.000000000 
+0200
+++ new/gmpy2-2.3.2/gmpy2.egg-info/SOURCES.txt  2026-10-04 03:17:27.000000000 
+0200
@@ -60,7 +60,6 @@
 scripts/dll-importexport.diff
 scripts/fat_build_fix.diff
 scripts/gcc15.diff
-scripts/mp_bitcnt_t.diff
 scripts/show-cov.sh
 src/fr_div.c
 src/gmpy2.c
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gmpy2-2.3.1/gmpy2.egg-info/requires.txt 
new/gmpy2-2.3.2/gmpy2.egg-info/requires.txt
--- old/gmpy2-2.3.1/gmpy2.egg-info/requires.txt 2026-06-24 02:41:18.000000000 
+0200
+++ new/gmpy2-2.3.2/gmpy2.egg-info/requires.txt 2026-10-04 03:17:27.000000000 
+0200
@@ -5,10 +5,15 @@
 
 [tests]
 pytest
-hypothesis
 cython
 mpmath
 setuptools
 
-[tests:python_version >= "3.11" and python_version < "3.15"]
+[tests:implementation_name != "pypy"]
+hypothesis
+
+[tests:implementation_name == "pypy"]
+hypothesis<=6.150.0
+
+[tests:python_version >= "3.11" and python_version < "3.15" and 
implementation_name != "pypy"]
 numpy
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gmpy2-2.3.1/gmpy2.egg-info/scm_file_list.json 
new/gmpy2-2.3.2/gmpy2.egg-info/scm_file_list.json
--- old/gmpy2-2.3.1/gmpy2.egg-info/scm_file_list.json   2026-06-24 
02:41:18.000000000 +0200
+++ new/gmpy2-2.3.2/gmpy2.egg-info/scm_file_list.json   2026-10-04 
03:17:27.000000000 +0200
@@ -1,180 +1,179 @@
 {
   "files": [
     ".backportrc.json",
-    "COPYING.LESSER",
-    "setup.py",
-    "pyproject.toml",
-    "README.rst",
-    "COPYING",
-    "MANIFEST.in",
+    ".github/dependabot.yml",
+    ".github/workflows/backport.yml",
+    ".github/workflows/ci.yml",
+    ".github/workflows/coverage.yml",
+    ".github/workflows/publish.yml",
+    ".github/workflows/wheels.yml",
     ".gitignore",
     ".readthedocs.yaml",
+    "COPYING",
+    "COPYING.LESSER",
     "INSTALL",
-    "scripts/fat_build_fix.diff",
-    "scripts/gcc15.diff",
-    "scripts/cibw_repair_wheel_command_windows.bat",
-    "scripts/dll-importexport.diff",
-    "scripts/cibw_repair_wheel_command_windows.sh",
-    "scripts/cibw_before_all.sh",
-    "scripts/README",
-    "scripts/show-cov.sh",
-    "scripts/cibw_repair_wheel_command.sh",
-    "scripts/mp_bitcnt_t.diff",
-    "gmpy2/__init__.py",
-    "gmpy2/__init__.pxd",
-    "gmpy2/gmpy2.h",
-    "gmpy2/gmpy2.pxd",
-    "docs/overview.rst",
-    "docs/generic.rst",
+    "MANIFEST.in",
+    "README.rst",
+    "demo/gmpy2_demo.c",
+    "demo/parallel_powmod.py",
+    "demo/setup.py",
     "docs/Makefile",
     "docs/advmpz.rst",
-    "docs/index.rst",
-    "docs/mpq.rst",
-    "docs/tutorial.rst",
-    "docs/mpc.rst",
-    "docs/cython.rst",
-    "docs/conversion.rst",
-    "docs/history.rst",
-    "docs/mpz.rst",
-    "docs/misc.rst",
+    "docs/conf.py",
     "docs/contexts.rst",
-    "docs/win_build.rst",
-    "docs/make.bat",
+    "docs/conversion.rst",
+    "docs/cython.rst",
     "docs/exceptions.rst",
+    "docs/generic.rst",
+    "docs/history.rst",
+    "docs/index.rst",
     "docs/install.rst",
+    "docs/make.bat",
+    "docs/misc.rst",
+    "docs/mpc.rst",
     "docs/mpfr.rst",
-    "docs/conf.py",
-    "src/gmpy2_truediv.h",
-    "src/gmpy2_math.c",
-    "src/gmpy2_sign.c",
-    "src/gmpy2_plus.c",
-    "src/gmpy2_xmpz_misc.c",
-    "src/gmpy2_hash.c",
-    "src/gmpy2_const.h",
-    "src/gmpy2_mpz_divmod.c",
-    "src/gmpy2_fused.c",
-    "src/gmpy2_binary.h",
-    "src/gmpy2_convert.c",
-    "src/gmpy2_convert_mpc.c",
-    "src/gmpy2_square.c",
-    "src/gmpy2_pow.c",
-    "src/gmpy2_mpz_divmod.h",
-    "src/gmpy2_richcompare.h",
-    "src/gmpy2_mpz_pack.h",
+    "docs/mpq.rst",
+    "docs/mpz.rst",
+    "docs/overview.rst",
+    "docs/tutorial.rst",
+    "docs/win_build.rst",
+    "gmpy2/__init__.pxd",
+    "gmpy2/__init__.py",
+    "gmpy2/gmpy2.h",
+    "gmpy2/gmpy2.pxd",
+    "pyproject.toml",
+    "scripts/README",
+    "scripts/cibw_before_all.sh",
+    "scripts/cibw_repair_wheel_command.sh",
+    "scripts/cibw_repair_wheel_command_windows.bat",
+    "scripts/cibw_repair_wheel_command_windows.sh",
+    "scripts/dll-importexport.diff",
+    "scripts/fat_build_fix.diff",
+    "scripts/gcc15.diff",
+    "scripts/show-cov.sh",
+    "setup.py",
     "src/fr_div.c",
-    "src/gmpy2_format.c",
-    "src/gmpy2_math.h",
-    "src/gmpy2_xmpz.c",
-    "src/gmpy2_mpc.h",
-    "src/gmpy2_context.c",
-    "src/gmpy2_convert_mpc.h",
-    "src/gmpy2_cache.h",
-    "src/gmpy2_xmpz.h",
-    "src/gmpy2_cache.c",
-    "src/gmpy2_cmp.h",
-    "src/gmpy2_minus.h",
-    "src/gmpy_mpz_lucas.h",
-    "src/gmpy_mpz_lucas.c",
-    "src/gmpy2_add.h",
-    "src/gmpy2_predicate.c",
-    "src/gmpy2_binary.c",
-    "src/gmpy2_mpz_divmod2exp.c",
     "src/gmpy2.c",
-    "src/gmpy2_mpz.c",
-    "src/gmpy2_xmpz_limbs.h",
-    "src/gmpy2_floordiv.h",
-    "src/gmpy2_random.c",
-    "src/gmpy2_sub.c",
-    "src/gmpy2_plus.h",
-    "src/gmpy2_mpq_misc.c",
-    "src/gmpy2_mul.h",
+    "src/gmpy2.h",
+    "src/gmpy2.pxd",
+    "src/gmpy2_abs.c",
+    "src/gmpy2_abs.h",
     "src/gmpy2_add.c",
-    "src/gmpy2_mod.c",
-    "src/gmpy2_hash.h",
-    "src/gmpy2_mpmath.c",
-    "src/gmpy2_truediv.c",
-    "src/gmpy2_muldiv_2exp.c",
-    "src/gmpy2_sign.h",
-    "src/gmpy2_misc.c",
-    "src/gmpy2_mpfr_misc.c",
-    "src/gmpy2_fused.h",
-    "src/gmpy2_macros.h",
-    "src/pythoncapi_compat.h",
-    "src/gmpy2_types.h",
-    "src/gmpy2_convert_mpfr.c",
-    "src/gmpy_mpz_prp.c",
-    "src/gmpy2_xmpz_limbs.c",
-    "src/gmpy2_random.h",
+    "src/gmpy2_add.h",
+    "src/gmpy2_binary.c",
+    "src/gmpy2_binary.h",
+    "src/gmpy2_cache.c",
+    "src/gmpy2_cache.h",
     "src/gmpy2_cmp.c",
-    "src/gmpy2_convert_gmp.h",
+    "src/gmpy2_cmp.h",
+    "src/gmpy2_const.c",
+    "src/gmpy2_const.h",
+    "src/gmpy2_context.c",
+    "src/gmpy2_context.h",
+    "src/gmpy2_convert.c",
     "src/gmpy2_convert.h",
+    "src/gmpy2_convert_gmp.c",
+    "src/gmpy2_convert_gmp.h",
+    "src/gmpy2_convert_mpc.c",
+    "src/gmpy2_convert_mpc.h",
+    "src/gmpy2_convert_mpfr.c",
     "src/gmpy2_convert_mpfr.h",
+    "src/gmpy2_convert_utils.c",
+    "src/gmpy2_convert_utils.h",
+    "src/gmpy2_divmod.c",
     "src/gmpy2_divmod.h",
-    "src/gmpy2_sub.h",
-    "src/gmpy2_const.c",
-    "src/gmpy2_mul.c",
-    "src/gmpy2_abs.c",
-    "src/gmpy2_mpfr_misc.h",
-    "src/gmpy2_mpq_misc.h",
-    "src/gmpy2_pow.h",
-    "src/gmpy2_xmpz_inplace.c",
+    "src/gmpy2_floordiv.c",
+    "src/gmpy2_floordiv.h",
+    "src/gmpy2_format.c",
+    "src/gmpy2_format.h",
+    "src/gmpy2_fused.c",
+    "src/gmpy2_fused.h",
+    "src/gmpy2_hash.c",
+    "src/gmpy2_hash.h",
+    "src/gmpy2_macros.h",
+    "src/gmpy2_math.c",
+    "src/gmpy2_math.h",
     "src/gmpy2_minus.c",
+    "src/gmpy2_minus.h",
+    "src/gmpy2_misc.c",
+    "src/gmpy2_misc.h",
+    "src/gmpy2_mod.c",
+    "src/gmpy2_mod.h",
     "src/gmpy2_mpc.c",
-    "src/gmpy2_context.h",
+    "src/gmpy2_mpc.h",
+    "src/gmpy2_mpc_misc.c",
     "src/gmpy2_mpc_misc.h",
     "src/gmpy2_mpfr.c",
-    "src/gmpy2.h",
-    "src/gmpy2_mpz_misc.h",
-    "src/gmpy2_richcompare.c",
-    "src/gmpy2_convert_utils.c",
-    "src/gmpy2_mpz_divmod2exp.h",
-    "src/gmpy2_square.h",
-    "src/gmpy2_divmod.c",
-    "src/gmpy2_convert_utils.h",
+    "src/gmpy2_mpfr.h",
+    "src/gmpy2_mpfr_misc.c",
+    "src/gmpy2_mpfr_misc.h",
+    "src/gmpy2_mpmath.c",
+    "src/gmpy2_mpq.c",
+    "src/gmpy2_mpq.h",
+    "src/gmpy2_mpq_misc.c",
+    "src/gmpy2_mpq_misc.h",
+    "src/gmpy2_mpz.c",
     "src/gmpy2_mpz.h",
-    "src/gmpy2_abs.h",
-    "src/gmpy2_mpz_misc.c",
     "src/gmpy2_mpz_bitops.c",
     "src/gmpy2_mpz_bitops.h",
-    "src/gmpy2_misc.h",
+    "src/gmpy2_mpz_divmod.c",
+    "src/gmpy2_mpz_divmod.h",
+    "src/gmpy2_mpz_divmod2exp.c",
+    "src/gmpy2_mpz_divmod2exp.h",
+    "src/gmpy2_mpz_misc.c",
+    "src/gmpy2_mpz_misc.h",
+    "src/gmpy2_mpz_pack.c",
+    "src/gmpy2_mpz_pack.h",
+    "src/gmpy2_mul.c",
+    "src/gmpy2_mul.h",
+    "src/gmpy2_muldiv_2exp.c",
     "src/gmpy2_muldiv_2exp.h",
-    "src/gmpy2_mod.h",
+    "src/gmpy2_plus.c",
+    "src/gmpy2_plus.h",
+    "src/gmpy2_pow.c",
+    "src/gmpy2_pow.h",
+    "src/gmpy2_predicate.c",
     "src/gmpy2_predicate.h",
-    "src/gmpy2_convert_gmp.c",
-    "src/gmpy2_mpq.c",
-    "src/gmpy2_mpfr.h",
+    "src/gmpy2_random.c",
+    "src/gmpy2_random.h",
+    "src/gmpy2_richcompare.c",
+    "src/gmpy2_richcompare.h",
+    "src/gmpy2_sign.c",
+    "src/gmpy2_sign.h",
+    "src/gmpy2_square.c",
+    "src/gmpy2_square.h",
+    "src/gmpy2_sub.c",
+    "src/gmpy2_sub.h",
+    "src/gmpy2_truediv.c",
+    "src/gmpy2_truediv.h",
+    "src/gmpy2_types.h",
+    "src/gmpy2_xmpz.c",
+    "src/gmpy2_xmpz.h",
+    "src/gmpy2_xmpz_inplace.c",
+    "src/gmpy2_xmpz_inplace.h",
+    "src/gmpy2_xmpz_limbs.c",
+    "src/gmpy2_xmpz_limbs.h",
+    "src/gmpy2_xmpz_misc.c",
     "src/gmpy2_xmpz_misc.h",
-    "src/gmpy2_floordiv.c",
-    "src/gmpy2_mpc_misc.c",
-    "src/gmpy2_mpz_pack.c",
+    "src/gmpy_mpz_lucas.c",
+    "src/gmpy_mpz_lucas.h",
+    "src/gmpy_mpz_prp.c",
     "src/gmpy_mpz_prp.h",
-    "src/gmpy2_format.h",
-    "src/gmpy2.pxd",
-    "src/gmpy2_xmpz_inplace.h",
-    "src/gmpy2_mpq.h",
-    "test/test_xmpz.py",
-    "test/test_mpz.py",
+    "src/pythoncapi_compat.h",
+    "test/conftest.py",
+    "test/supportclasses.py",
     "test/test_consts.py",
+    "test/test_context.py",
     "test/test_functions.py",
-    "test/test_mpc.py",
-    "test/test_misc.py",
-    "test/test_mpq.py",
     "test/test_generic.py",
-    "test/conftest.py",
+    "test/test_misc.py",
+    "test/test_mpc.py",
     "test/test_mpfr.py",
-    "test/supportclasses.py",
-    "test/test_context.py",
-    "demo/gmpy2_demo.c",
-    "demo/setup.py",
-    "demo/parallel_powmod.py",
-    "test_cython/setup_cython.py",
-    "test_cython/test_cython.pyx",
+    "test/test_mpq.py",
+    "test/test_mpz.py",
+    "test/test_xmpz.py",
     "test_cython/runtests.py",
-    ".github/dependabot.yml",
-    ".github/workflows/backport.yml",
-    ".github/workflows/wheels.yml",
-    ".github/workflows/coverage.yml",
-    ".github/workflows/ci.yml",
-    ".github/workflows/publish.yml"
+    "test_cython/setup_cython.py",
+    "test_cython/test_cython.pyx"
   ]
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gmpy2-2.3.1/gmpy2.egg-info/scm_version.json 
new/gmpy2-2.3.2/gmpy2.egg-info/scm_version.json
--- old/gmpy2-2.3.1/gmpy2.egg-info/scm_version.json     2026-06-24 
02:41:18.000000000 +0200
+++ new/gmpy2-2.3.2/gmpy2.egg-info/scm_version.json     2026-10-04 
03:17:27.000000000 +0200
@@ -1,8 +1,8 @@
 {
-  "tag": "2.3.1",
+  "tag": "2.3.2",
   "distance": 0,
-  "node": "g49b9de3b07421d621cd04e1a4c1acb1382940d77",
+  "node": "gdbf4520e9912fa8f3ae61edb5682a589d064fa22",
   "dirty": false,
   "branch": "HEAD",
-  "node_date": "2026-06-23"
+  "node_date": "2026-10-04"
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gmpy2-2.3.1/pyproject.toml 
new/gmpy2-2.3.2/pyproject.toml
--- old/gmpy2-2.3.1/pyproject.toml      2026-06-24 02:39:59.000000000 +0200
+++ new/gmpy2-2.3.2/pyproject.toml      2026-10-04 03:16:17.000000000 +0200
@@ -42,8 +42,10 @@
 
 [project.optional-dependencies]
 docs = ['sphinx>=4', 'sphinx-rtd-theme>=1']
-tests = ['pytest', 'hypothesis', 'cython', 'mpmath', 'setuptools',
-         'numpy; python_version>="3.11" and python_version<"3.15"']
+tests = ['pytest', 'hypothesis; implementation_name != "pypy"',
+         'hypothesis<=6.150.0; implementation_name == "pypy"',
+         'cython', 'mpmath', 'setuptools',
+         'numpy; python_version>="3.11" and python_version<"3.15" and 
implementation_name != "pypy"']
 
 [project.urls]
 Homepage = 'https://github.com/gmpy2/gmpy2'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gmpy2-2.3.1/scripts/cibw_before_all.sh 
new/gmpy2-2.3.2/scripts/cibw_before_all.sh
--- old/gmpy2-2.3.1/scripts/cibw_before_all.sh  2026-06-24 02:39:59.000000000 
+0200
+++ new/gmpy2-2.3.2/scripts/cibw_before_all.sh  2026-10-04 03:16:17.000000000 
+0200
@@ -4,7 +4,7 @@
 
 GMP_VERSION=6.3.0
 MPFR_VERSION=4.2.2
-MPC_VERSION=1.4.0
+MPC_VERSION=1.4.1
 
 PREFIX="$(pwd)/.local/"
 
@@ -18,13 +18,24 @@
     sleep_ivl=$((${sleep_ivl}*2))
   done
 }
+genlib () {
+  cd .local/bin/
+  dll_file=$1
+  lib_name=$(basename -s .dll ${dll_file})
+  name=$(echo ${lib_name}|sed 's/^lib//;s/-[0-9]\+//')
+
+  gendef ${dll_file}
+  dlltool -d ${lib_name}.def -l ${name}.lib
+
+  cp ${name}.lib ../lib/
+  cp ${dll_file} ../lib/
+  cd ../../
+}
 
 # -- build GMP --
 download https://ftp.gnu.org/gnu/gmp/gmp-${GMP_VERSION}.tar.xz
 tar -xf gmp-${GMP_VERSION}.tar.xz
 cd gmp-${GMP_VERSION}
-# Patch the mp_bitcnt_t to "unsigned long long int" on WINDOWS AMD64:
-#patch -N -Z -p0 < ../scripts/mp_bitcnt_t.diff
 
 patch -N -Z -p0 < ../scripts/fat_build_fix.diff
 patch -N -Z -p0 < ../scripts/dll-importexport.diff
@@ -84,35 +95,9 @@
 cp $PREFIX/include/{gmp,mpfr,mpc}.h gmpy2/
 
 # -- generate *.lib files from *.dll on M$ Windows --
-if [ "$OSTYPE" = "msys" ] || [ "$OSTYPE" = "cygwin" ]
+if [ "$OSTYPE" = "cygwin" ]
 then
-  # Set path to dumpbin & lib
-  PATH="$PATH:$(find "/c/Program Files/Microsoft Visual Studio/2022/" -name 
"Hostx86")/x64/"
-
-  # See http://stackoverflow.com/questions/9946322/
-  cd .local/bin
-  for dll_file in libgmp-10.dll libmpfr-6.dll libmpc-3.dll
-  do
-    lib_name=$(basename -s .dll ${dll_file})
-    exports_file=${lib_name}-exports.txt
-    def_file=${lib_name}.def
-    lib_file=${lib_name}.lib
-    name=$(echo ${lib_name}|sed 's/^lib//;s/-[0-9]\+//')
-
-    dumpbin //exports ${dll_file} > ${exports_file}
-
-    echo LIBRARY ${lib_name} > ${def_file}
-    echo EXPORTS >> ${def_file}
-    cat ${exports_file} | awk 'NR>19 && $4 != "" {print $4 " @"$1}' >> 
${def_file}
-    sed -i 's/$/\r/' ${def_file}
-
-    if [ "${RUNNER_ARCH}" = "ARM64" ]
-    then
-      lib //def:${def_file} //out:${lib_file} //machine:arm64
-    else
-      lib //def:${def_file} //out:${lib_file} //machine:x64
-    fi
-    rm ${exports_file} ${def_file} ${lib_name}.exp
-    mv ${lib_file} ${name}.lib
-  done
+  genlib libgmp-10.dll
+  genlib libmpfr-6.dll
+  genlib libmpc-3.dll
 fi
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gmpy2-2.3.1/scripts/mp_bitcnt_t.diff 
new/gmpy2-2.3.2/scripts/mp_bitcnt_t.diff
--- old/gmpy2-2.3.1/scripts/mp_bitcnt_t.diff    2026-06-24 02:39:59.000000000 
+0200
+++ new/gmpy2-2.3.2/scripts/mp_bitcnt_t.diff    1970-01-01 01:00:00.000000000 
+0100
@@ -1,25 +0,0 @@
---- gmp-h.in.orig      2024-03-24 10:55:03.711573465 +0300
-+++ gmp-h.in   2024-03-24 10:58:02.762349548 +0300
-@@ -143,7 +143,11 @@
- typedef long int              mp_limb_signed_t;
- #endif
- #endif
-+#if defined(_WIN64)
-+typedef unsigned long long int        mp_bitcnt_t;
-+#else
- typedef unsigned long int     mp_bitcnt_t;
-+#endif
- 
- /* For reference, note that the name __mpz_struct gets into C++ mangled
-    function names, which means although the "__" suggests an internal, we
---- mpz/millerrabin.c.orig     2024-03-24 10:59:05.420511561 +0300
-+++ mpz/millerrabin.c  2024-03-24 10:59:11.428335102 +0300
-@@ -59,7 +59,7 @@
- 
- static int millerrabin (mpz_srcptr,
-                       mpz_ptr, mpz_ptr,
--                      mpz_srcptr, unsigned long int);
-+                      mpz_srcptr, mp_bitcnt_t);
- 
- int
- mpz_millerrabin (mpz_srcptr n, int reps)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gmpy2-2.3.1/src/gmpy2_format.c 
new/gmpy2-2.3.2/src/gmpy2_format.c
--- old/gmpy2-2.3.1/src/gmpy2_format.c  2026-06-24 02:39:59.000000000 +0200
+++ new/gmpy2-2.3.2/src/gmpy2_format.c  2026-10-04 03:16:17.000000000 +0200
@@ -310,23 +310,25 @@
         }
         if (!seendigits) {
             seendigits = 1;
-            if ((*p1 == 'e' || *p1 == 'E')
-                || ((*p1 == 'U' || *p1 == 'D' || *p1 == 'Y' || *p1 == 'Z' ||
-                     *p1 == 'N') && (*(p1+1) == 'e' || *(p1+1) == 'E')))
-            {
-                *(p2++) = '.';
-                *(p2++) = '6';
-            }
-            if ((*p1 == 'U' || *p1 == 'D' || *p1 == 'Y' || *p1 == 'Z' ||
-                 *p1 == 'N') && *(p1+1) == '\00')
-            {
-                long precision = (long)(log10(2) * 
(double)mpfr_get_prec(MPFR(self))) + 2;
-                char tmp[23];
-
-                *(p2++) = '.';
-                sprintf(tmp, "%ld", precision);
-                for (char *c = tmp; *c != '\00'; c++) {
-                    *(p2++) = *c;
+            if (!seendecimal) {
+                if ((*p1 == 'e' || *p1 == 'E')
+                    || ((*p1 == 'U' || *p1 == 'D' || *p1 == 'Y' || *p1 == 'Z' 
||
+                         *p1 == 'N') && (*(p1+1) == 'e' || *(p1+1) == 'E')))
+                {
+                    *(p2++) = '.';
+                    *(p2++) = '6';
+                }
+                if ((*p1 == 'U' || *p1 == 'D' || *p1 == 'Y' || *p1 == 'Z' ||
+                     *p1 == 'N') && *(p1+1) == '\00')
+                {
+                    long precision = (long)(log10(2) * 
(double)mpfr_get_prec(MPFR(self))) + 2;
+                    char tmp[23];
+
+                    *(p2++) = '.';
+                    sprintf(tmp, "%ld", precision);
+                    for (char *c = tmp; *c != '\00'; c++) {
+                        *(p2++) = *c;
+                    }
                 }
             }
             *(p2++) = 'R';
@@ -580,31 +582,33 @@
         }
         if (!seendigits) {
             seendigits = 1;
-            if ((*p == 'e' || *p == 'E')
-                || ((*p == 'U' || *p == 'D' || *p == 'Y' || *p == 'Z' ||
-                     *p == 'N') && (*(p+1) == 'e' || *(p+1) == 'E')))
-            {
-                *(rfmtptr++) = '.';
-                *(rfmtptr++) = '6';
-                *(ifmtptr++) = '.';
-                *(ifmtptr++) = '6';
-            }
-            if ((*p == 'U' || *p == 'D' || *p == 'Y' || *p == 'Z' ||
-                 *p == 'N') && *(p+1) == '\00')
-            {
-                long precision = (long)(log10(2) * 
(double)mpfr_get_prec(mpc_realref(MPC(self)))) + 2;
-                char tmp[23];
-
-                *(rfmtptr++) = '.';
-                sprintf(tmp, "%ld", precision);
-                for (char *c = tmp; *c != '\00'; c++) {
-                    *(rfmtptr++) = *c;
+            if (!seendecimal) {
+                if ((*p == 'e' || *p == 'E')
+                    || ((*p == 'U' || *p == 'D' || *p == 'Y' || *p == 'Z' ||
+                         *p == 'N') && (*(p+1) == 'e' || *(p+1) == 'E')))
+                {
+                    *(rfmtptr++) = '.';
+                    *(rfmtptr++) = '6';
+                    *(ifmtptr++) = '.';
+                    *(ifmtptr++) = '6';
                 }
-                precision = (long)(log10(2) * 
(double)mpfr_get_prec(mpc_imagref(MPC(self)))) + 2;
-                *(ifmtptr++) = '.';
-                sprintf(tmp, "%ld", precision);
-                for (char *c = tmp; *c != '\00'; c++) {
-                    *(ifmtptr++) = *c;
+                if ((*p == 'U' || *p == 'D' || *p == 'Y' || *p == 'Z' ||
+                     *p == 'N') && *(p+1) == '\00')
+                {
+                    long precision = (long)(log10(2) * 
(double)mpfr_get_prec(mpc_realref(MPC(self)))) + 2;
+                    char tmp[23];
+
+                    *(rfmtptr++) = '.';
+                    sprintf(tmp, "%ld", precision);
+                    for (char *c = tmp; *c != '\00'; c++) {
+                        *(rfmtptr++) = *c;
+                    }
+                    precision = (long)(log10(2) * 
(double)mpfr_get_prec(mpc_imagref(MPC(self)))) + 2;
+                    *(ifmtptr++) = '.';
+                    sprintf(tmp, "%ld", precision);
+                    for (char *c = tmp; *c != '\00'; c++) {
+                        *(ifmtptr++) = *c;
+                    }
                 }
             }
             *(rfmtptr++) = 'R';
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gmpy2-2.3.1/src/pythoncapi_compat.h 
new/gmpy2-2.3.2/src/pythoncapi_compat.h
--- old/gmpy2-2.3.1/src/pythoncapi_compat.h     2026-06-24 02:39:59.000000000 
+0200
+++ new/gmpy2-2.3.2/src/pythoncapi_compat.h     2026-10-04 03:16:17.000000000 
+0200
@@ -1,4 +1,5 @@
 // Header file providing new C API functions to old Python versions.
+// Python 3.6 or newer is required.
 //
 // File distributed under the Zero Clause BSD (0BSD) license.
 // Copyright Contributors to the pythoncapi_compat project.
@@ -88,27 +89,6 @@
 #endif
 
 
-// Py_SETREF() and Py_XSETREF() were added to Python 3.5.2.
-// It is excluded from the limited C API.
-#if (PY_VERSION_HEX < 0x03050200 && !defined(Py_SETREF)) && 
!defined(Py_LIMITED_API)
-#define Py_SETREF(dst, src)                                     \
-    do {                                                        \
-        PyObject **_tmp_dst_ptr = _Py_CAST(PyObject**, &(dst)); \
-        PyObject *_tmp_dst = (*_tmp_dst_ptr);                   \
-        *_tmp_dst_ptr = _PyObject_CAST(src);                    \
-        Py_DECREF(_tmp_dst);                                    \
-    } while (0)
-
-#define Py_XSETREF(dst, src)                                    \
-    do {                                                        \
-        PyObject **_tmp_dst_ptr = _Py_CAST(PyObject**, &(dst)); \
-        PyObject *_tmp_dst = (*_tmp_dst_ptr);                   \
-        *_tmp_dst_ptr = _PyObject_CAST(src);                    \
-        Py_XDECREF(_tmp_dst);                                   \
-    } while (0)
-#endif
-
-
 // bpo-43753 added Py_Is(), Py_IsNone(), Py_IsTrue() and Py_IsFalse()
 // to Python 3.10.0b1.
 #if PY_VERSION_HEX < 0x030A00B1 && !defined(Py_Is)
@@ -146,7 +126,8 @@
 
 
 // bpo-40421 added PyFrame_GetCode() to Python 3.9.0b1
-#if PY_VERSION_HEX < 0x030900B1 || defined(PYPY_VERSION)
+// PyPy added PyFrame_GetCode() to PyPy3.12 v8.0.0
+#if PY_VERSION_HEX < 0x030900B1 || (defined(PYPY_VERSION) && PY_VERSION_HEX < 
0x030C0000)
 static inline PyCodeObject* PyFrame_GetCode(PyFrameObject *frame)
 {
     assert(frame != _Py_NULL);
@@ -186,13 +167,9 @@
 #if PY_VERSION_HEX < 0x030B00A7 && !defined(PYPY_VERSION)
 static inline PyObject* PyFrame_GetLocals(PyFrameObject *frame)
 {
-#if PY_VERSION_HEX >= 0x030400B1
     if (PyFrame_FastToLocalsWithError(frame) < 0) {
         return NULL;
     }
-#else
-    PyFrame_FastToLocals(frame);
-#endif
     return Py_NewRef(frame->f_locals);
 }
 #endif
@@ -245,22 +222,14 @@
     if (locals == NULL) {
         return NULL;
     }
-#if PY_VERSION_HEX >= 0x03000000
     value = PyDict_GetItemWithError(locals, name);
-#else
-    value = _PyDict_GetItemWithError(locals, name);
-#endif
     Py_DECREF(locals);
 
     if (value == NULL) {
         if (PyErr_Occurred()) {
             return NULL;
         }
-#if PY_VERSION_HEX >= 0x03000000
         PyErr_Format(PyExc_NameError, "variable %R does not exist", name);
-#else
-        PyErr_SetString(PyExc_NameError, "variable does not exist");
-#endif
         return NULL;
     }
     return Py_NewRef(value);
@@ -274,11 +243,7 @@
 PyFrame_GetVarString(PyFrameObject *frame, const char *name)
 {
     PyObject *name_obj, *value;
-#if PY_VERSION_HEX >= 0x03000000
     name_obj = PyUnicode_FromString(name);
-#else
-    name_obj = PyString_FromString(name);
-#endif
     if (name_obj == NULL) {
         return NULL;
     }
@@ -321,7 +286,8 @@
 
 
 // bpo-39947 added PyInterpreterState_Get() to Python 3.9.0a5
-#if PY_VERSION_HEX < 0x030900A5 || defined(PYPY_VERSION)
+// PyPy added PyInterpreterState_Get() to PyPy3.12 v8.0.0
+#if PY_VERSION_HEX < 0x030900A5 || (defined(PYPY_VERSION) && PY_VERSION_HEX < 
0x030C0000)
 static inline PyInterpreterState* PyInterpreterState_Get(void)
 {
     PyThreadState *tstate;
@@ -458,7 +424,7 @@
 
 // bpo-40241 added PyObject_GC_IsFinalized() to Python 3.9.0a6.
 // bpo-18112 added _PyGCHead_FINALIZED() to Python 3.4.0 final.
-#if PY_VERSION_HEX < 0x030900A6 && PY_VERSION_HEX >= 0x030400F0 && 
!defined(PYPY_VERSION)
+#if PY_VERSION_HEX < 0x030900A6 && !defined(PYPY_VERSION)
 static inline int PyObject_GC_IsFinalized(PyObject *obj)
 {
     PyGC_Head *gc = _Py_CAST(PyGC_Head*, obj) - 1;
@@ -480,7 +446,7 @@
 // bpo-11734 added _PyFloat_Pack2() and _PyFloat_Unpack2() to Python 3.6.0b1.
 // Python 3.11a2 moved _PyFloat_Pack2() and _PyFloat_Unpack2() to the internal
 // C API: Python 3.11a2-3.11a6 versions are not supported.
-#if 0x030600B1 <= PY_VERSION_HEX && PY_VERSION_HEX <= 0x030B00A1 && 
!defined(PYPY_VERSION)
+#if PY_VERSION_HEX <= 0x030B00A1 && !defined(PYPY_VERSION)
 static inline int PyFloat_Pack2(double x, char *p, int le)
 { return _PyFloat_Pack2(x, (unsigned char*)p, le); }
 
@@ -544,7 +510,7 @@
 
 
 // Py_UNUSED() was added to Python 3.4.0b2.
-#if PY_VERSION_HEX < 0x030400B2 && !defined(Py_UNUSED)
+#ifndef Py_UNUSED
 #  if defined(__GNUC__) || defined(__clang__)
 #    define Py_UNUSED(name) _unused_ ## name __attribute__((unused))
 #  else
@@ -705,13 +671,8 @@
 static inline int
 PyObject_GetOptionalAttrString(PyObject *obj, const char *attr_name, PyObject 
**result)
 {
-    PyObject *name_obj;
     int rc;
-#if PY_VERSION_HEX >= 0x03000000
-    name_obj = PyUnicode_FromString(attr_name);
-#else
-    name_obj = PyString_FromString(attr_name);
-#endif
+    PyObject *name_obj = PyUnicode_FromString(attr_name);
     if (name_obj == NULL) {
         *result = NULL;
         return -1;
@@ -743,13 +704,8 @@
 static inline int
 PyMapping_GetOptionalItemString(PyObject *obj, const char *key, PyObject 
**result)
 {
-    PyObject *key_obj;
     int rc;
-#if PY_VERSION_HEX >= 0x03000000
-    key_obj = PyUnicode_FromString(key);
-#else
-    key_obj = PyString_FromString(key);
-#endif
+    PyObject *key_obj = PyUnicode_FromString(key);
     if (key_obj == NULL) {
         *result = NULL;
         return -1;
@@ -812,11 +768,7 @@
 static inline int
 PyDict_GetItemRef(PyObject *mp, PyObject *key, PyObject **result)
 {
-#if PY_VERSION_HEX >= 0x03000000
     PyObject *item = PyDict_GetItemWithError(mp, key);
-#else
-    PyObject *item = _PyDict_GetItemWithError(mp, key);
-#endif
     if (item != NULL) {
         *result = Py_NewRef(item);
         return 1;  // found
@@ -833,11 +785,7 @@
 PyDict_GetItemStringRef(PyObject *mp, const char *key, PyObject **result)
 {
     int res;
-#if PY_VERSION_HEX >= 0x03000000
     PyObject *key_obj = PyUnicode_FromString(key);
-#else
-    PyObject *key_obj = PyString_FromString(key);
-#endif
     if (key_obj == NULL) {
         *result = NULL;
         return -1;
@@ -864,7 +812,7 @@
 // gh-108014 added Py_IsFinalizing() to Python 3.13.0a1
 // bpo-1856 added _Py_Finalizing to Python 3.2.1b1.
 // _Py_IsFinalizing() was added to PyPy 7.3.0.
-#if (0x030201B1 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x030D00A1) \
+#if (PY_VERSION_HEX < 0x030D00A1) \
         && (!defined(PYPY_VERSION_NUM) || PYPY_VERSION_NUM >= 0x7030000)
 static inline int Py_IsFinalizing(void)
 {
@@ -941,7 +889,7 @@
 
 // gh-108867 added PyThreadState_GetUnchecked() to Python 3.13.0a1
 // Python 3.5.2 added _PyThreadState_UncheckedGet().
-#if PY_VERSION_HEX >= 0x03050200 && PY_VERSION_HEX < 0x030D00A1
+#if PY_VERSION_HEX < 0x030D00A1
 static inline PyThreadState*
 PyThreadState_GetUnchecked(void)
 {
@@ -963,13 +911,12 @@
     // API cannot report errors so save/restore the exception
     PyErr_Fetch(&exc_type, &exc_value, &exc_tb);
 
-    // Python 3.3.0a1 added PyUnicode_AsUTF8AndSize()
-#if PY_VERSION_HEX >= 0x030300A1
     if (PyUnicode_IS_ASCII(unicode)) {
         utf8 = PyUnicode_DATA(unicode);
         len = PyUnicode_GET_LENGTH(unicode);
     }
     else {
+        // Python 3.3.0a1 added PyUnicode_AsUTF8AndSize()
         utf8 = PyUnicode_AsUTF8AndSize(unicode, &len);
         if (utf8 == NULL) {
             // Memory allocation failure. The API cannot report error,
@@ -984,31 +931,6 @@
         goto done;
     }
     res = (memcmp(utf8, str, (size_t)len) == 0);
-#else
-    PyObject *bytes = PyUnicode_AsUTF8String(unicode);
-    if (bytes == NULL) {
-        // Memory allocation failure. The API cannot report error,
-        // so ignore the exception and return 0.
-        res = 0;
-        goto done;
-    }
-
-#if PY_VERSION_HEX >= 0x03000000
-    len = PyBytes_GET_SIZE(bytes);
-    utf8 = PyBytes_AS_STRING(bytes);
-#else
-    len = PyString_GET_SIZE(bytes);
-    utf8 = PyString_AS_STRING(bytes);
-#endif
-    if (len != str_len) {
-        Py_DECREF(bytes);
-        res = 0;
-        goto done;
-    }
-
-    res = (memcmp(utf8, str, (size_t)len) == 0);
-    Py_DECREF(bytes);
-#endif
 
 done:
     PyErr_Restore(exc_type, exc_value, exc_tb);
@@ -1056,10 +978,8 @@
     // bpo-16991 added _PyDict_Pop() to Python 3.5.0b2.
     // Python 3.6.0b3 changed _PyDict_Pop() first argument type to PyObject*.
     // Python 3.13.0a1 removed _PyDict_Pop().
-#if defined(PYPY_VERSION) || PY_VERSION_HEX < 0x030500b2 || PY_VERSION_HEX >= 
0x030D0000
+#if defined(PYPY_VERSION) || PY_VERSION_HEX >= 0x030D0000
     value = PyObject_CallMethod(dict, "pop", "O", key);
-#elif PY_VERSION_HEX < 0x030600b3
-    value = _PyDict_Pop(_Py_CAST(PyDictObject*, dict), key, NULL);
 #else
     value = _PyDict_Pop(dict, key, NULL);
 #endif
@@ -1100,12 +1020,6 @@
 #endif
 
 
-#if PY_VERSION_HEX < 0x030200A4
-// Python 3.2.0a4 added Py_hash_t type
-typedef Py_ssize_t Py_hash_t;
-#endif
-
-
 // gh-111545 added Py_HashPointer() to Python 3.13.0a3
 #if PY_VERSION_HEX < 0x030D00A3
 static inline Py_hash_t Py_HashPointer(const void *ptr)
@@ -1121,7 +1035,7 @@
 
 // Python 3.13a4 added a PyTime API.
 // Use the private API added to Python 3.5.
-#if PY_VERSION_HEX < 0x030D00A4 && PY_VERSION_HEX  >= 0x03050000
+#if PY_VERSION_HEX < 0x030D00A4
 typedef _PyTime_t PyTime_t;
 #define PyTime_MIN _PyTime_MIN
 #define PyTime_MAX _PyTime_MAX
@@ -1355,7 +1269,7 @@
 #  define Py_END_CRITICAL_SECTION2() }
 #endif
 
-#if PY_VERSION_HEX < 0x030E0000 && PY_VERSION_HEX >= 0x03060000 && 
!defined(PYPY_VERSION)
+#if PY_VERSION_HEX < 0x030E0000 && !defined(PYPY_VERSION)
 typedef struct PyUnicodeWriter PyUnicodeWriter;
 
 static inline void PyUnicodeWriter_Discard(PyUnicodeWriter *writer)
@@ -1425,6 +1339,11 @@
 static inline int
 PyUnicodeWriter_WriteRepr(PyUnicodeWriter *writer, PyObject *obj)
 {
+    if (obj == NULL) {
+        return _PyUnicodeWriter_WriteASCIIString((_PyUnicodeWriter*)writer,
+                                                 "<NULL>", 6);
+    }
+
     PyObject *str = PyObject_Repr(obj);
     if (str == NULL) {
         return -1;
@@ -1569,6 +1488,11 @@
 
 // gh-124502 added PyUnicode_Equal() to Python 3.14.0a0
 #if PY_VERSION_HEX < 0x030E00A0
+
+#if PY_VERSION_HEX >= 0x030d0000 && !defined(PYPY_VERSION)
+PyAPI_FUNC(int) _PyUnicode_Equal(PyObject *str1, PyObject *str2);
+#endif
+
 static inline int PyUnicode_Equal(PyObject *str1, PyObject *str2)
 {
     if (!PyUnicode_Check(str1)) {
@@ -1583,10 +1507,8 @@
     }
 
 #if PY_VERSION_HEX >= 0x030d0000 && !defined(PYPY_VERSION)
-    PyAPI_FUNC(int) _PyUnicode_Equal(PyObject *str1, PyObject *str2);
-
     return _PyUnicode_Equal(str1, str2);
-#elif PY_VERSION_HEX >= 0x03060000 && !defined(PYPY_VERSION)
+#elif !defined(PYPY_VERSION)
     return _PyUnicode_EQ(str1, str2);
 #elif PY_VERSION_HEX >= 0x03090000 && defined(PYPY_VERSION)
     return _PyUnicode_EQ(str1, str2);
@@ -1607,11 +1529,14 @@
 
 
 #if PY_VERSION_HEX < 0x030E00A0
+
+#ifndef PYPY_VERSION
+PyAPI_FUNC(Py_hash_t) _Py_HashBytes(const void *src, Py_ssize_t len);
+#endif
+
 static inline Py_hash_t Py_HashBuffer(const void *ptr, Py_ssize_t len)
 {
-#if PY_VERSION_HEX >= 0x03000000 && !defined(PYPY_VERSION)
-    PyAPI_FUNC(Py_hash_t) _Py_HashBytes(const void *src, Py_ssize_t len);
-
+#ifndef PYPY_VERSION
     return _Py_HashBytes(ptr, len);
 #else
     Py_hash_t hash;
@@ -1737,7 +1662,7 @@
 
 
 // gh-102471 added import and export API for integers to 3.14.0a2.
-#if PY_VERSION_HEX < 0x030E00A2 && PY_VERSION_HEX >= 0x03000000 && 
!defined(PYPY_VERSION)
+#if PY_VERSION_HEX < 0x030E00A2 && !defined(PYPY_VERSION)
 // Helpers to access PyLongObject internals.
 static inline void
 _PyLong_SetSignAndDigitCount(PyLongObject *op, int sign, Py_ssize_t size)
@@ -1936,7 +1861,7 @@
 #  define Py_T_ULONGLONG  18
 #  define Py_T_PYSSIZET   19
 
-#  if PY_VERSION_HEX >= 0x03000000 && !defined(PYPY_VERSION)
+#  ifndef PYPY_VERSION
 #    define _Py_T_NONE      20
 #  endif
 
@@ -1948,26 +1873,21 @@
 
 // gh-127350 added Py_fopen() and Py_fclose() to Python 3.14a4
 #if PY_VERSION_HEX < 0x030E00A4
+
+#ifndef PYPY_VERSION
+PyAPI_FUNC(FILE*) _Py_fopen_obj(PyObject *path, const char *mode);
+#endif
+
 static inline FILE* Py_fopen(PyObject *path, const char *mode)
 {
-#if 0x030400A2 <= PY_VERSION_HEX && !defined(PYPY_VERSION)
-    PyAPI_FUNC(FILE*) _Py_fopen_obj(PyObject *path, const char *mode);
-
+#ifndef PYPY_VERSION
     return _Py_fopen_obj(path, mode);
 #else
     FILE *f;
     PyObject *bytes;
-#if PY_VERSION_HEX >= 0x03000000
     if (!PyUnicode_FSConverter(path, &bytes)) {
         return NULL;
     }
-#else
-    if (!PyString_Check(path)) {
-        PyErr_SetString(PyExc_TypeError, "except str");
-        return NULL;
-    }
-    bytes = Py_NewRef(path);
-#endif
     const char *path_bytes = PyBytes_AS_STRING(bytes);
 
     f = fopen(path_bytes, mode);
@@ -2212,7 +2132,8 @@
 
 // gh-133144 added PyUnstable_Object_IsUniquelyReferenced() to Python 3.14.0b1.
 // Adapted from  _PyObject_IsUniquelyReferenced() implementation.
-#if PY_VERSION_HEX < 0x030E00B0
+// Not available on PyPy: Py_REFCNT() semantics is different on PyPy.
+#if PY_VERSION_HEX < 0x030E00B0 && !defined(PYPY_VERSION)
 static inline int PyUnstable_Object_IsUniquelyReferenced(PyObject *obj)
 {
 #if !defined(Py_GIL_DISABLED)
@@ -2230,7 +2151,8 @@
 
 // gh-128926 added PyUnstable_TryIncRef() and PyUnstable_EnableTryIncRef() to
 // Python 3.14.0a5. Adapted from _Py_TryIncref() and 
_PyObject_SetMaybeWeakref().
-#if PY_VERSION_HEX < 0x030E00A5
+// Not available on PyPy: Py_REFCNT() semantics is different on PyPy.
+#if PY_VERSION_HEX < 0x030E00A5 && !defined(PYPY_VERSION)
 static inline int PyUnstable_TryIncRef(PyObject *op)
 {
 #ifndef Py_GIL_DISABLED
@@ -2301,18 +2223,14 @@
     (void)op;  // unused argument
 #endif
 }
-#endif
+#endif  // PY_VERSION_HEX < 0x030E00A5 && !defined(PYPY_VERSION)
 
 
 #if PY_VERSION_HEX < 0x030F0000
 static inline PyObject*
 PySys_GetAttrString(const char *name)
 {
-#if PY_VERSION_HEX >= 0x03000000
     PyObject *value = Py_XNewRef(PySys_GetObject(name));
-#else
-    PyObject *value = Py_XNewRef(PySys_GetObject((char*)name));
-#endif
     if (value != NULL) {
         return value;
     }
@@ -2325,11 +2243,7 @@
 static inline PyObject*
 PySys_GetAttr(PyObject *name)
 {
-#if PY_VERSION_HEX >= 0x03000000
     const char *name_str = PyUnicode_AsUTF8(name);
-#else
-    const char *name_str = PyString_AsString(name);
-#endif
     if (name_str == NULL) {
         return NULL;
     }
@@ -2340,11 +2254,7 @@
 static inline int
 PySys_GetOptionalAttrString(const char *name, PyObject **value)
 {
-#if PY_VERSION_HEX >= 0x03000000
     *value = Py_XNewRef(PySys_GetObject(name));
-#else
-    *value = Py_XNewRef(PySys_GetObject((char*)name));
-#endif
     if (*value != NULL) {
         return 1;
     }
@@ -2354,11 +2264,7 @@
 static inline int
 PySys_GetOptionalAttr(PyObject *name, PyObject **value)
 {
-#if PY_VERSION_HEX >= 0x03000000
     const char *name_str = PyUnicode_AsUTF8(name);
-#else
-    const char *name_str = PyString_AsString(name);
-#endif
     if (name_str == NULL) {
         *value = NULL;
         return -1;
@@ -2651,14 +2557,46 @@
 #ifdef PYPY_VERSION
     (void)op;  // unused argument
     return -1;
-#elif PY_VERSION_HEX >= 0x03000000
-    return ((PyASCIIObject*)op)->hash;
 #else
-    return ((PyUnicodeObject*)op)->hash;
+    return ((PyASCIIObject*)op)->hash;
 #endif
 }
 #endif
 
+#if 0x030D0000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x030F00A7 && 
!defined(PYPY_VERSION)
+// Immortal objects were implemented in Python 3.12, however there is no easy 
API
+// to make objects immortal until 3.14 which has _Py_SetImmortal(). Since
+// immortal objects are primarily needed for free-threading, this API is 
implemented
+// for 3.14 using _Py_SetImmortal() and uses private macros on 3.13.
+#if 0x030E0000 <= PY_VERSION_HEX
+PyAPI_FUNC(void) _Py_SetImmortal(PyObject *op);
+#endif
+
+static inline int
+PyUnstable_SetImmortal(PyObject *op)
+{
+    assert(op != NULL);
+    if (!PyUnstable_Object_IsUniquelyReferenced(op) || PyUnicode_Check(op)) {
+        return 0;
+    }
+#if 0x030E0000 <= PY_VERSION_HEX
+    _Py_SetImmortal(op);
+#else
+    // Python 3.13 doesn't export _Py_SetImmortal() function
+    if (PyObject_GC_IsTracked(op)) {
+        PyObject_GC_UnTrack(op);
+    }
+#ifdef Py_GIL_DISABLED
+    op->ob_tid = _Py_UNOWNED_TID;
+    op->ob_ref_local = _Py_IMMORTAL_REFCNT_LOCAL;
+    op->ob_ref_shared = 0;
+#else
+    op->ob_refcnt = _Py_IMMORTAL_REFCNT;
+#endif
+#endif
+    return 1;
+}
+#endif
 
 #ifdef __cplusplus
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gmpy2-2.3.1/test/test_mpfr.py 
new/gmpy2-2.3.2/test/test_mpfr.py
--- old/gmpy2-2.3.1/test/test_mpfr.py   2026-06-24 02:39:59.000000000 +0200
+++ new/gmpy2-2.3.2/test/test_mpfr.py   2026-10-04 03:16:17.000000000 +0200
@@ -363,6 +363,9 @@
 
     pytest.raises(ValueError, lambda: format(mpfr(1), "1" + "0"*70))
 
+    # issue 710
+    assert format(gmpy2.sin(1), ".10De") == '8.4147098480e-01'
+
 
 def test_mpfr_digits():
     r, r2 = mpfr(5.6), mpfr(5)

Reply via email to