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-07-15 16:44:17
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-gmpy2 (Old)
 and      /work/SRC/openSUSE:Factory/.python-gmpy2.new.1991 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-gmpy2"

Wed Jul 15 16:44:17 2026 rev:10 rq:1365770 version:2.3.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-gmpy2/python-gmpy2.changes        
2026-04-25 21:42:32.454456608 +0200
+++ /work/SRC/openSUSE:Factory/.python-gmpy2.new.1991/python-gmpy2.changes      
2026-07-15 17:02:30.148944116 +0200
@@ -1,0 +2,11 @@
+Sun Jul  5 08:35:10 UTC 2026 - Dirk Müller <[email protected]>
+
+- update to 2.3.1:
+  * Fix ieee() for bit width > 128. (skirpichev)
+  * Fix Fix mpc.__module__. (skirpichev)
+  * Check for buffer overflows in __format__() dunders.
+    (skirpichev)
+  * Support CPython v3.15. (skirpichev)
+  * Drop additional constraint for Jacobi symbol. (skirpichev)
+
+-------------------------------------------------------------------

Old:
----
  gmpy2-2.3.0.tar.gz

New:
----
  gmpy2-2.3.1.tar.gz

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

Other differences:
------------------
++++++ python-gmpy2.spec ++++++
--- /var/tmp/diff_new_pack.dfrcmm/_old  2026-07-15 17:02:31.400986640 +0200
+++ /var/tmp/diff_new_pack.dfrcmm/_new  2026-07-15 17:02:31.404986775 +0200
@@ -18,7 +18,7 @@
 
 %{?sle15_python_module_pythons}
 Name:           python-gmpy2
-Version:        2.3.0
+Version:        2.3.1
 Release:        0
 Summary:        GMP/MPIR, MPFR, and MPC interface to Python 2.6+ and 3x
 License:        LGPL-3.0-only
@@ -48,7 +48,7 @@
 rounded complex floating-point arithmetic) libraries.
 
 %prep
-%setup -q -n gmpy2-%{version}
+%autosetup -p1 -n gmpy2-%{version}
 
 %build
 export CFLAGS="%{optflags}"

++++++ gmpy2-2.3.0.tar.gz -> gmpy2-2.3.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gmpy2-2.3.0/.github/dependabot.yml 
new/gmpy2-2.3.1/.github/dependabot.yml
--- old/gmpy2-2.3.0/.github/dependabot.yml      2026-02-08 01:19:32.000000000 
+0100
+++ new/gmpy2-2.3.1/.github/dependabot.yml      2026-06-24 02:39:59.000000000 
+0200
@@ -4,3 +4,8 @@
     directory: "/"
     schedule:
       interval: "monthly"
+    rebase-strategy: "disabled"
+    groups:
+      actions-deps:
+        patterns:
+          - "*"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gmpy2-2.3.0/.github/workflows/backport.yml 
new/gmpy2-2.3.1/.github/workflows/backport.yml
--- old/gmpy2-2.3.0/.github/workflows/backport.yml      2026-02-08 
01:19:32.000000000 +0100
+++ new/gmpy2-2.3.1/.github/workflows/backport.yml      2026-06-24 
02:39:59.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.0/.github/workflows/coverage.yml 
new/gmpy2-2.3.1/.github/workflows/coverage.yml
--- old/gmpy2-2.3.0/.github/workflows/coverage.yml      2026-02-08 
01:19:32.000000000 +0100
+++ new/gmpy2-2.3.1/.github/workflows/coverage.yml      2026-06-24 
02:39:59.000000000 +0200
@@ -38,7 +38,7 @@
           PYTHONPATH=`pwd`/gmpy2 python test_cython/runtests.py
           lcov --capture --directory . --no-external --output-file 
coverage.info
           cp coverage.info build/coverage-${{ matrix.python-version }}.info
-      - uses: actions/upload-artifact@v6
+      - uses: actions/upload-artifact@v7
         with:
           name: coverage-${{ matrix.python-version }}
           path: |
@@ -54,7 +54,7 @@
           fetch-depth: 0
       - run: sudo apt-get update
       - run: sudo apt-get install lcov
-      - uses: actions/download-artifact@v7
+      - uses: actions/download-artifact@v8
         with:
           pattern: coverage-*
           path: build/
@@ -62,7 +62,7 @@
       - run: |
           genhtml build/coverage*.info --hierarchical \
             --output-directory build/coverage
-      - uses: actions/upload-artifact@v6
+      - uses: actions/upload-artifact@v7
         with:
           name: coverage
           path: |
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gmpy2-2.3.0/.github/workflows/publish.yml 
new/gmpy2-2.3.1/.github/workflows/publish.yml
--- old/gmpy2-2.3.0/.github/workflows/publish.yml       2026-02-08 
01:19:32.000000000 +0100
+++ new/gmpy2-2.3.1/.github/workflows/publish.yml       2026-06-24 
02:39:59.000000000 +0200
@@ -24,7 +24,7 @@
     - run: python -m build -s
       env:
         PKG_CONFIG_PATH: ${{ github.workspace }}/.local/lib/pkgconfig
-    - uses: actions/upload-artifact@v6
+    - uses: actions/upload-artifact@v7
       with:
         name: gmpy2-sdist
         path: dist/
@@ -43,7 +43,7 @@
     permissions:
       id-token: write
     steps:
-    - uses: actions/download-artifact@v7
+    - uses: actions/download-artifact@v8
       with:
         pattern: gmpy2-*
         path: dist/
@@ -60,12 +60,12 @@
       contents: write
       id-token: write
     steps:
-    - uses: actions/download-artifact@v7
+    - uses: actions/download-artifact@v8
       with:
         pattern: gmpy2-*
         path: dist/
         merge-multiple: true
-    - uses: sigstore/[email protected]
+    - uses: sigstore/[email protected]
       with:
         inputs: >-
           ./dist/*.tar.gz
@@ -73,11 +73,15 @@
     - name: Create GitHub Release
       env:
         GITHUB_TOKEN: ${{ github.token }}
-      run: >-
-        gh release create '${{ github.ref_name }}'
-        --repo '${{ github.repository }}'
-        --prerelease
-        --generate-notes
+      run: |
+        PRERELEASE_FLAG=""
+        if [[ "${{ github.ref_name }}" =~ [ab][0-9] ]]
+        then
+          PRERELEASE_FLAG="--prerelease"
+        fi
+        gh release create '${{ github.ref_name }}' \
+          --repo '${{ github.repository }}' ${PRERELEASE_FLAG} \
+          --generate-notes
     - name: Upload artifact signatures to GitHub Release
       env:
         GITHUB_TOKEN: ${{ github.token }}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gmpy2-2.3.0/.github/workflows/wheels.yml 
new/gmpy2-2.3.1/.github/workflows/wheels.yml
--- old/gmpy2-2.3.0/.github/workflows/wheels.yml        2026-02-08 
01:19:32.000000000 +0100
+++ new/gmpy2-2.3.1/.github/workflows/wheels.yml        2026-06-24 
02:39:59.000000000 +0200
@@ -34,8 +34,8 @@
           path-type: inherit
         if: contains(matrix.os, 'windows')
       - name: Build wheels
-        uses: pypa/[email protected]
-      - uses: actions/upload-artifact@v6
+        uses: pypa/[email protected]
+      - uses: actions/upload-artifact@v7
         with:
           name: wheels-${{ matrix.os }}
           path: ./wheelhouse/
@@ -44,7 +44,7 @@
     needs: build_wheels
     steps:
       - name: Merge Wheels
-        uses: actions/upload-artifact/merge@v6
+        uses: actions/upload-artifact/merge@v7
         with:
           name: gmpy2-wheels
           pattern: wheels-*
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gmpy2-2.3.0/PKG-INFO new/gmpy2-2.3.1/PKG-INFO
--- old/gmpy2-2.3.0/PKG-INFO    2026-02-08 01:20:47.331283000 +0100
+++ new/gmpy2-2.3.1/PKG-INFO    2026-06-24 02:41:18.768638100 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.4
 Name: gmpy2
-Version: 2.3.0
+Version: 2.3.1
 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]>
@@ -22,6 +22,7 @@
 Classifier: Programming Language :: Python :: 3.12
 Classifier: Programming Language :: Python :: 3.13
 Classifier: Programming Language :: Python :: 3.14
+Classifier: Programming Language :: Python :: 3.15
 Classifier: Programming Language :: Python :: Free Threading :: 2 - Beta
 Classifier: Programming Language :: Python :: Implementation :: CPython
 Classifier: Programming Language :: Python :: Implementation :: PyPy
@@ -40,7 +41,7 @@
 Requires-Dist: cython; extra == "tests"
 Requires-Dist: mpmath; extra == "tests"
 Requires-Dist: setuptools; extra == "tests"
-Requires-Dist: numpy; python_version >= "3.11" and extra == "tests"
+Requires-Dist: numpy; (python_version >= "3.11" and python_version < "3.15") 
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.0/docs/history.rst 
new/gmpy2-2.3.1/docs/history.rst
--- old/gmpy2-2.3.0/docs/history.rst    2026-02-08 01:19:32.000000000 +0100
+++ new/gmpy2-2.3.1/docs/history.rst    2026-06-24 02:39:59.000000000 +0200
@@ -3,6 +3,15 @@
 
 .. currentmodule:: gmpy2
 
+Changes in gmpy2 2.3.1
+----------------------
+
+* Fix ieee() for bit width > 128. (skirpichev)
+* Fix ``Fix mpc.__module__``. (skirpichev)
+* Check for buffer overflows in __format__() dunders. (skirpichev)
+* Support CPython v3.15. (skirpichev)
+* Drop additional constraint for Jacobi symbol. (skirpichev)
+
 Changes in gmpy2 2.3.0
 ----------------------
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gmpy2-2.3.0/gmpy2/mpc.h new/gmpy2-2.3.1/gmpy2/mpc.h
--- old/gmpy2-2.3.0/gmpy2/mpc.h 2026-02-08 01:20:44.000000000 +0100
+++ new/gmpy2-2.3.1/gmpy2/mpc.h 2026-06-24 02:41:15.000000000 +0200
@@ -1,6 +1,6 @@
 /* mpc.h -- Include file for mpc.
 
-Copyright (C) 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011, 2012, 
2016, 2017, 2018, 2020, 2021, 2022 INRIA
+Copyright (C) 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011, 2012, 
2016, 2017, 2018, 2020, 2021, 2022, 2023, 2024, 2026 INRIA
 
 This file is part of GNU MPC.
 
@@ -25,11 +25,17 @@
 #include "gmp.h"
 #include "mpfr.h"
 
+#if 1
+#define _MPC_HAVE_COMPLEX_H
+#else
+#undef _MPC_HAVE_COMPLEX_H
+#endif
+
 /* Define MPC version number */
 #define MPC_VERSION_MAJOR 1
-#define MPC_VERSION_MINOR 3
-#define MPC_VERSION_PATCHLEVEL 1
-#define MPC_VERSION_STRING "1.3.1"
+#define MPC_VERSION_MINOR 4
+#define MPC_VERSION_PATCHLEVEL 0
+#define MPC_VERSION_STRING "1.4.0"
 
 /* Macros dealing with MPC VERSION */
 #define MPC_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c))
@@ -220,8 +226,11 @@
 __MPC_DECLSPEC int  mpc_cmp_si_si   (mpc_srcptr, long int, long int);
 __MPC_DECLSPEC int  mpc_cmp_abs     (mpc_srcptr, mpc_srcptr);
 __MPC_DECLSPEC int  mpc_exp         (mpc_ptr, mpc_srcptr, mpc_rnd_t);
+__MPC_DECLSPEC int  mpc_exp10       (mpc_ptr, mpc_srcptr, mpc_rnd_t);
+__MPC_DECLSPEC int  mpc_exp2        (mpc_ptr, mpc_srcptr, mpc_rnd_t);
 __MPC_DECLSPEC int  mpc_log         (mpc_ptr, mpc_srcptr, mpc_rnd_t);
 __MPC_DECLSPEC int  mpc_log10       (mpc_ptr, mpc_srcptr, mpc_rnd_t);
+__MPC_DECLSPEC int  mpc_log2        (mpc_ptr, mpc_srcptr, mpc_rnd_t);
 __MPC_DECLSPEC int  mpc_agm         (mpc_ptr, mpc_srcptr, mpc_srcptr, 
mpc_rnd_t);
 __MPC_DECLSPEC int  mpc_sin         (mpc_ptr, mpc_srcptr, mpc_rnd_t);
 __MPC_DECLSPEC int  mpc_cos         (mpc_ptr, mpc_srcptr, mpc_rnd_t);
@@ -259,11 +268,23 @@
 __MPC_DECLSPEC int  mpc_set_uj_uj   (mpc_ptr, uintmax_t, uintmax_t, mpc_rnd_t);
 #endif
 
-#ifdef _Complex_I
-__MPC_DECLSPEC int  mpc_set_dc      (mpc_ptr, double _Complex, mpc_rnd_t);
-__MPC_DECLSPEC int  mpc_set_ldc     (mpc_ptr, long double _Complex, mpc_rnd_t);
-__MPC_DECLSPEC double _Complex mpc_get_dc (mpc_srcptr, mpc_rnd_t);
-__MPC_DECLSPEC long double _Complex mpc_get_ldc (mpc_srcptr, mpc_rnd_t);
+/* Microsoft Compiler does not have complex/_Complex, see
+   
https://learn.microsoft.com/en-US/cpp/c-runtime-library/complex-math-support?view=msvc-170
+   If you change this, also check tests/read_description.c.
+*/
+#ifdef _MSC_VER
+#define DOUBLE_COMPLEX _Dcomplex
+#define LONG_DOUBLE_COMPLEX _Lcomplex
+#else
+#define DOUBLE_COMPLEX double _Complex
+#define LONG_DOUBLE_COMPLEX long double _Complex
+#endif
+
+#if defined (_MPC_HAVE_COMPLEX_H) && defined (_Complex_I)
+__MPC_DECLSPEC int  mpc_set_dc      (mpc_ptr, DOUBLE_COMPLEX, mpc_rnd_t);
+__MPC_DECLSPEC int  mpc_set_ldc     (mpc_ptr, LONG_DOUBLE_COMPLEX, mpc_rnd_t);
+__MPC_DECLSPEC DOUBLE_COMPLEX mpc_get_dc (mpc_srcptr, mpc_rnd_t);
+__MPC_DECLSPEC LONG_DOUBLE_COMPLEX mpc_get_ldc (mpc_srcptr, mpc_rnd_t);
 #endif
 
 #ifdef _GMP_H_HAVE_FILE
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gmpy2-2.3.0/gmpy2.egg-info/PKG-INFO 
new/gmpy2-2.3.1/gmpy2.egg-info/PKG-INFO
--- old/gmpy2-2.3.0/gmpy2.egg-info/PKG-INFO     2026-02-08 01:20:47.000000000 
+0100
+++ new/gmpy2-2.3.1/gmpy2.egg-info/PKG-INFO     2026-06-24 02:41:18.000000000 
+0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.4
 Name: gmpy2
-Version: 2.3.0
+Version: 2.3.1
 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]>
@@ -22,6 +22,7 @@
 Classifier: Programming Language :: Python :: 3.12
 Classifier: Programming Language :: Python :: 3.13
 Classifier: Programming Language :: Python :: 3.14
+Classifier: Programming Language :: Python :: 3.15
 Classifier: Programming Language :: Python :: Free Threading :: 2 - Beta
 Classifier: Programming Language :: Python :: Implementation :: CPython
 Classifier: Programming Language :: Python :: Implementation :: PyPy
@@ -40,7 +41,7 @@
 Requires-Dist: cython; extra == "tests"
 Requires-Dist: mpmath; extra == "tests"
 Requires-Dist: setuptools; extra == "tests"
-Requires-Dist: numpy; python_version >= "3.11" and extra == "tests"
+Requires-Dist: numpy; (python_version >= "3.11" and python_version < "3.15") 
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.0/gmpy2.egg-info/SOURCES.txt 
new/gmpy2-2.3.1/gmpy2.egg-info/SOURCES.txt
--- old/gmpy2-2.3.0/gmpy2.egg-info/SOURCES.txt  2026-02-08 01:20:47.000000000 
+0100
+++ new/gmpy2-2.3.1/gmpy2.egg-info/SOURCES.txt  2026-06-24 02:41:18.000000000 
+0200
@@ -49,6 +49,8 @@
 gmpy2.egg-info/dependency_links.txt
 gmpy2.egg-info/not-zip-safe
 gmpy2.egg-info/requires.txt
+gmpy2.egg-info/scm_file_list.json
+gmpy2.egg-info/scm_version.json
 gmpy2.egg-info/top_level.txt
 scripts/README
 scripts/cibw_before_all.sh
@@ -59,7 +61,6 @@
 scripts/fat_build_fix.diff
 scripts/gcc15.diff
 scripts/mp_bitcnt_t.diff
-scripts/mpc-pkg-config.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.0/gmpy2.egg-info/requires.txt 
new/gmpy2-2.3.1/gmpy2.egg-info/requires.txt
--- old/gmpy2-2.3.0/gmpy2.egg-info/requires.txt 2026-02-08 01:20:47.000000000 
+0100
+++ new/gmpy2-2.3.1/gmpy2.egg-info/requires.txt 2026-06-24 02:41:18.000000000 
+0200
@@ -10,5 +10,5 @@
 mpmath
 setuptools
 
-[tests:python_version >= "3.11"]
+[tests:python_version >= "3.11" and python_version < "3.15"]
 numpy
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gmpy2-2.3.0/gmpy2.egg-info/scm_file_list.json 
new/gmpy2-2.3.1/gmpy2.egg-info/scm_file_list.json
--- old/gmpy2-2.3.0/gmpy2.egg-info/scm_file_list.json   1970-01-01 
01:00:00.000000000 +0100
+++ new/gmpy2-2.3.1/gmpy2.egg-info/scm_file_list.json   2026-06-24 
02:41:18.000000000 +0200
@@ -0,0 +1,180 @@
+{
+  "files": [
+    ".backportrc.json",
+    "COPYING.LESSER",
+    "setup.py",
+    "pyproject.toml",
+    "README.rst",
+    "COPYING",
+    "MANIFEST.in",
+    ".gitignore",
+    ".readthedocs.yaml",
+    "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",
+    "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/contexts.rst",
+    "docs/win_build.rst",
+    "docs/make.bat",
+    "docs/exceptions.rst",
+    "docs/install.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",
+    "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_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_cmp.c",
+    "src/gmpy2_convert_gmp.h",
+    "src/gmpy2_convert.h",
+    "src/gmpy2_convert_mpfr.h",
+    "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_minus.c",
+    "src/gmpy2_mpc.c",
+    "src/gmpy2_context.h",
+    "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_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_muldiv_2exp.h",
+    "src/gmpy2_mod.h",
+    "src/gmpy2_predicate.h",
+    "src/gmpy2_convert_gmp.c",
+    "src/gmpy2_mpq.c",
+    "src/gmpy2_mpfr.h",
+    "src/gmpy2_xmpz_misc.h",
+    "src/gmpy2_floordiv.c",
+    "src/gmpy2_mpc_misc.c",
+    "src/gmpy2_mpz_pack.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",
+    "test/test_consts.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_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_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"
+  ]
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gmpy2-2.3.0/gmpy2.egg-info/scm_version.json 
new/gmpy2-2.3.1/gmpy2.egg-info/scm_version.json
--- old/gmpy2-2.3.0/gmpy2.egg-info/scm_version.json     1970-01-01 
01:00:00.000000000 +0100
+++ new/gmpy2-2.3.1/gmpy2.egg-info/scm_version.json     2026-06-24 
02:41:18.000000000 +0200
@@ -0,0 +1,8 @@
+{
+  "tag": "2.3.1",
+  "distance": 0,
+  "node": "g49b9de3b07421d621cd04e1a4c1acb1382940d77",
+  "dirty": false,
+  "branch": "HEAD",
+  "node_date": "2026-06-23"
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gmpy2-2.3.0/pyproject.toml 
new/gmpy2-2.3.1/pyproject.toml
--- old/gmpy2-2.3.0/pyproject.toml      2026-02-08 01:19:32.000000000 +0100
+++ new/gmpy2-2.3.1/pyproject.toml      2026-06-24 02:39:59.000000000 +0200
@@ -28,6 +28,7 @@
                'Programming Language :: Python :: 3.12',
                'Programming Language :: Python :: 3.13',
                'Programming Language :: Python :: 3.14',
+               'Programming Language :: Python :: 3.15',
                'Programming Language :: Python :: Free Threading :: 2 - Beta',
                'Programming Language :: Python :: Implementation :: CPython',
                "Programming Language :: Python :: Implementation :: PyPy",
@@ -42,7 +43,7 @@
 [project.optional-dependencies]
 docs = ['sphinx>=4', 'sphinx-rtd-theme>=1']
 tests = ['pytest', 'hypothesis', 'cython', 'mpmath', 'setuptools',
-         'numpy; python_version>="3.11"']
+         'numpy; python_version>="3.11" and python_version<"3.15"']
 
 [project.urls]
 Homepage = 'https://github.com/gmpy2/gmpy2'
@@ -66,7 +67,7 @@
 
 [tool.cibuildwheel]
 build-frontend = {name="build", args=["--verbose"]}
-enable = "pypy cpython-prerelease cpython-freethreading"
+enable = "pypy cpython-prerelease"
 before-all = "bash scripts/cibw_before_all.sh"
 test-extras = "tests"
 test-command = """pytest {package}/test && \
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gmpy2-2.3.0/scripts/cibw_before_all.sh 
new/gmpy2-2.3.1/scripts/cibw_before_all.sh
--- old/gmpy2-2.3.0/scripts/cibw_before_all.sh  2026-02-08 01:19:32.000000000 
+0100
+++ new/gmpy2-2.3.1/scripts/cibw_before_all.sh  2026-06-24 02:39:59.000000000 
+0200
@@ -4,7 +4,7 @@
 
 GMP_VERSION=6.3.0
 MPFR_VERSION=4.2.2
-MPC_VERSION=1.3.1
+MPC_VERSION=1.4.0
 
 PREFIX="$(pwd)/.local/"
 
@@ -65,12 +65,10 @@
 make install
 cd ../
 # -- build MPC --
-download https://ftp.gnu.org/gnu/mpc/mpc-${MPC_VERSION}.tar.gz
-tar -xf mpc-${MPC_VERSION}.tar.gz
+download https://ftp.gnu.org/gnu/mpc/mpc-${MPC_VERSION}.tar.xz
+tar -xf mpc-${MPC_VERSION}.tar.xz
 cd mpc-${MPC_VERSION}
 
-patch -N -Z -p1 < ../scripts/mpc-pkg-config.diff
-
 ./configure --enable-shared \
             --disable-static \
             --with-pic \
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gmpy2-2.3.0/scripts/mpc-pkg-config.diff 
new/gmpy2-2.3.1/scripts/mpc-pkg-config.diff
--- old/gmpy2-2.3.0/scripts/mpc-pkg-config.diff 2026-02-08 01:19:32.000000000 
+0100
+++ new/gmpy2-2.3.1/scripts/mpc-pkg-config.diff 1970-01-01 01:00:00.000000000 
+0100
@@ -1,203 +0,0 @@
-# Backport from upstream, starting from commit b9f00062
-diff --git a/Makefile.am b/Makefile.am
-index d0a0085..bf94553 100644
---- a/Makefile.am
-+++ b/Makefile.am
-@@ -25,6 +25,9 @@ VERSION = @VERSION@
- 
- SUBDIRS = src tests doc tools
- 
-+pkgconfigdir = $(libdir)/pkgconfig
-+pkgconfig_DATA = mpc.pc
-+
- EXTRA_HEADERS = src/mpc-log.h
- include_HEADERS = src/mpc.h @MPC_LOG_H@
- EXTRA_DIST = doc/fdl-1.3.texi src/mpc-log.h
-diff --git a/Makefile.in b/Makefile.in
-index d2a0090..96651d2 100644
---- a/Makefile.in
-+++ b/Makefile.in
-@@ -14,6 +14,7 @@
- 
- @SET_MAKE@
- 
-+
- VPATH = @srcdir@
- am__is_gnu_make = { \
-   if test -z '$(MAKELEVEL)'; then \
-@@ -104,7 +105,7 @@ am__CONFIG_DISTCLEAN_FILES = config.status config.cache 
config.log \
-  configure.lineno config.status.lineno
- mkinstalldirs = $(install_sh) -d
- CONFIG_HEADER = config.h
--CONFIG_CLEAN_FILES =
-+CONFIG_CLEAN_FILES = mpc.pc
- CONFIG_CLEAN_VPATH_FILES =
- AM_V_P = $(am__v_P_@AM_V@)
- am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
-@@ -160,7 +161,9 @@ am__uninstall_files_from_dir = { \
-     || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
-          $(am__cd) "$$dir" && rm -f $$files; }; \
-   }
--am__installdirs = "$(DESTDIR)$(includedir)"
-+am__installdirs = "$(DESTDIR)$(pkgconfigdir)" \
-+      "$(DESTDIR)$(includedir)"
-+DATA = $(pkgconfig_DATA)
- HEADERS = $(include_HEADERS)
- RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive       \
-   distclean-recursive maintainer-clean-recursive
-@@ -190,7 +193,8 @@ am__define_uniq_tagged_files = \
-   done | $(am__uniquify_input)`
- DIST_SUBDIRS = $(SUBDIRS)
- am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in \
--      $(top_srcdir)/build-aux/ar-lib $(top_srcdir)/build-aux/compile \
-+      $(srcdir)/mpc.pc.in $(top_srcdir)/build-aux/ar-lib \
-+      $(top_srcdir)/build-aux/compile \
-       $(top_srcdir)/build-aux/config.guess \
-       $(top_srcdir)/build-aux/config.sub \
-       $(top_srcdir)/build-aux/install-sh \
-@@ -376,6 +381,8 @@ top_builddir = @top_builddir@
- top_srcdir = @top_srcdir@
- ACLOCAL_AMFLAGS = -I m4
- SUBDIRS = src tests doc tools
-+pkgconfigdir = $(libdir)/pkgconfig
-+pkgconfig_DATA = mpc.pc
- EXTRA_HEADERS = src/mpc-log.h
- include_HEADERS = src/mpc.h @MPC_LOG_H@
- EXTRA_DIST = doc/fdl-1.3.texi src/mpc-log.h
-@@ -431,6 +438,8 @@ $(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ 
$(am__configure_deps)
- 
- distclean-hdr:
-       -rm -f config.h stamp-h1
-+mpc.pc: $(top_builddir)/config.status $(srcdir)/mpc.pc.in
-+      cd $(top_builddir) && $(SHELL) ./config.status $@
- 
- mostlyclean-libtool:
-       -rm -f *.lo
-@@ -440,6 +449,27 @@ clean-libtool:
- 
- distclean-libtool:
-       -rm -f libtool config.lt
-+install-pkgconfigDATA: $(pkgconfig_DATA)
-+      @$(NORMAL_INSTALL)
-+      @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \
-+      if test -n "$$list"; then \
-+        echo " $(MKDIR_P) '$(DESTDIR)$(pkgconfigdir)'"; \
-+        $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" || exit 1; \
-+      fi; \
-+      for p in $$list; do \
-+        if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
-+        echo "$$d$$p"; \
-+      done | $(am__base_list) | \
-+      while read files; do \
-+        echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \
-+        $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \
-+      done
-+
-+uninstall-pkgconfigDATA:
-+      @$(NORMAL_UNINSTALL)
-+      @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \
-+      files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
-+      dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir)
- install-includeHEADERS: $(include_HEADERS)
-       @$(NORMAL_INSTALL)
-       @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \
-@@ -766,10 +796,10 @@ distcleancheck: distclean
-              exit 1; } >&2
- check-am: all-am
- check: check-recursive
--all-am: Makefile $(HEADERS) config.h
-+all-am: Makefile $(DATA) $(HEADERS) config.h
- installdirs: installdirs-recursive
- installdirs-am:
--      for dir in "$(DESTDIR)$(includedir)"; do \
-+      for dir in "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(includedir)"; do \
-         test -z "$$dir" || $(MKDIR_P) "$$dir"; \
-       done
- install: install-recursive
-@@ -824,7 +854,7 @@ info: info-recursive
- 
- info-am:
- 
--install-data-am: install-includeHEADERS
-+install-data-am: install-includeHEADERS install-pkgconfigDATA
- 
- install-dvi: install-dvi-recursive
- 
-@@ -870,7 +900,7 @@ ps: ps-recursive
- 
- ps-am:
- 
--uninstall-am: uninstall-includeHEADERS
-+uninstall-am: uninstall-includeHEADERS uninstall-pkgconfigDATA
- 
- .MAKE: $(am__recursive_targets) all install-am install-strip
- 
-@@ -885,12 +915,12 @@ uninstall-am: uninstall-includeHEADERS
-       install-data install-data-am install-dvi install-dvi-am \
-       install-exec install-exec-am install-html install-html-am \
-       install-includeHEADERS install-info install-info-am \
--      install-man install-pdf install-pdf-am install-ps \
--      install-ps-am install-strip installcheck installcheck-am \
--      installdirs installdirs-am maintainer-clean \
-+      install-man install-pdf install-pdf-am install-pkgconfigDATA \
-+      install-ps install-ps-am install-strip installcheck \
-+      installcheck-am installdirs installdirs-am maintainer-clean \
-       maintainer-clean-generic mostlyclean mostlyclean-generic \
-       mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \
--      uninstall-am uninstall-includeHEADERS
-+      uninstall-am uninstall-includeHEADERS uninstall-pkgconfigDATA
- 
- .PRECIOUS: Makefile
- 
-diff --git a/configure b/configure
-index dac395e..4a0c5d3 100755
---- a/configure
-+++ b/configure
-@@ -14342,7 +14342,8 @@ fi
-    fi
- 
- 
--ac_config_files="$ac_config_files Makefile src/Makefile tests/Makefile 
doc/Makefile tools/Makefile tools/bench/Makefile tools/mpcheck/Makefile"
-+ac_config_files="$ac_config_files mpc.pc Makefile src/Makefile tests/Makefile 
doc/Makefile tools/Makefile tools/bench/Makefile tools/mpcheck/Makefile"
-+
- 
- cat >confcache <<\_ACEOF
- # This file is a shell script that caches the results of configure
-@@ -15358,6 +15359,7 @@ do
-     "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
-     "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
-     "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;;
-+    "mpc.pc") CONFIG_FILES="$CONFIG_FILES mpc.pc" ;;
-     "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
-     "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;;
-     "tests/Makefile") CONFIG_FILES="$CONFIG_FILES tests/Makefile" ;;
-diff --git a/configure.ac b/configure.ac
-index 23231da..31c2847 100644
---- a/configure.ac
-+++ b/configure.ac
-@@ -228,5 +228,6 @@ AC_DEFINE_UNQUOTED([MPC_GCC_VERSION], ["$GCC_VERSION"], 
[Version of gcc])
- # Looks for short git hash if the version string contains "dev"
- MPC_GITVERSION
- 
--AC_CONFIG_FILES([Makefile src/Makefile tests/Makefile doc/Makefile 
tools/Makefile tools/bench/Makefile tools/mpcheck/Makefile])
-+AC_CONFIG_FILES([mpc.pc Makefile src/Makefile tests/Makefile doc/Makefile 
tools/Makefile tools/bench/Makefile tools/mpcheck/Makefile])
-+
- AC_OUTPUT
-diff --git a/mpc.pc.in b/mpc.pc.in
-new file mode 100644
-index 0000000..71232d9
---- /dev/null
-+++ b/mpc.pc.in
-@@ -0,0 +1,12 @@
-+prefix=@prefix@
-+exec_prefix=@exec_prefix@
-+includedir=@includedir@
-+libdir=@libdir@
-+
-+Name: GNU MPC
-+Description: A complex floating-point library with exact rounding
-+URL: https://www.multiprecision.org/mpc/
-+Version: @VERSION@
-+Requires.private: mpfr >= @REQUIRES_MPFR_VERSION@, gmp >= 
@REQUIRES_GMP_VERSION@
-+Cflags: -I${includedir}
-+Libs: -L${libdir} -lmpc
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gmpy2-2.3.0/src/gmpy2_cmp.c 
new/gmpy2-2.3.1/src/gmpy2_cmp.c
--- old/gmpy2-2.3.0/src/gmpy2_cmp.c     2026-02-08 01:19:32.000000000 +0100
+++ new/gmpy2-2.3.1/src/gmpy2_cmp.c     2026-06-24 02:39:59.000000000 +0200
@@ -264,7 +264,7 @@
     CHECK_CONTEXT(context);
 
     if (PyTuple_GET_SIZE(args) != 2) {
-        TYPE_ERROR("cmp() requires 2 arguments");
+        TYPE_ERROR("cmp_abs() requires 2 arguments");
         return NULL;
     }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gmpy2-2.3.0/src/gmpy2_context.c 
new/gmpy2-2.3.1/src/gmpy2_context.c
--- old/gmpy2-2.3.0/src/gmpy2_context.c 2026-02-08 01:19:32.000000000 +0100
+++ new/gmpy2-2.3.1/src/gmpy2_context.c 2026-06-24 02:39:59.000000000 +0200
@@ -267,8 +267,9 @@
         result->ctx.emax = 16384;
     }
     else {
-        if ((bitwidth < 128) && (bitwidth & 31)) {
-            VALUE_ERROR("bitwidth must be 16, 32, 64, 128; or must be greater 
than 128 and divisible by 32.");
+        if ((bitwidth < 128) || (bitwidth & 31)) {
+            VALUE_ERROR("bitwidth must be 16, 32, 64, 128; or "
+                        "must be greater than 128 and divisible by 32.");
             Py_DECREF((PyObject*)result);
             return NULL;
         }
@@ -282,7 +283,7 @@
     return (PyObject*)result;
 }
 
-/* Helper function to convert to convert a rounding mode to a string. */
+/* Helper function to convert a rounding mode to a string. */
 
 static PyObject *
 _round_to_name(int val)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gmpy2-2.3.0/src/gmpy2_convert_mpc.c 
new/gmpy2-2.3.1/src/gmpy2_convert_mpc.c
--- old/gmpy2-2.3.0/src/gmpy2_convert_mpc.c     2026-02-08 01:19:32.000000000 
+0100
+++ new/gmpy2-2.3.1/src/gmpy2_convert_mpc.c     2026-06-24 02:39:59.000000000 
+0200
@@ -542,7 +542,7 @@
 static PyObject *
 GMPy_MPC_Float_Slot(PyObject *self)
 {
-    TYPE_ERROR("can't covert 'mpc' to 'float'");
+    TYPE_ERROR("can't convert 'mpc' to float");
     return NULL;
 }
 
@@ -565,7 +565,7 @@
 static PyObject *
 GMPy_MPC_Int_Slot(PyObject *self)
 {
-    TYPE_ERROR("can't covert mpc to int");
+    TYPE_ERROR("can't convert 'mpc' to int");
     return NULL;
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gmpy2-2.3.0/src/gmpy2_convert_mpfr.c 
new/gmpy2-2.3.1/src/gmpy2_convert_mpfr.c
--- old/gmpy2-2.3.0/src/gmpy2_convert_mpfr.c    2026-02-08 01:19:32.000000000 
+0100
+++ new/gmpy2-2.3.1/src/gmpy2_convert_mpfr.c    2026-06-24 02:39:59.000000000 
+0200
@@ -220,7 +220,7 @@
             bitlen = MPFR_PREC_MIN;
        }
        if (bitlen > MPFR_PREC_MAX) {
-           OVERFLOW_ERROR("'mpz' to large to convert to 'mpfr'\n");
+           OVERFLOW_ERROR("'mpz' too large to convert to 'mpfr'\n");
            return NULL;
        }
        prec = (mpfr_prec_t)bitlen;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gmpy2-2.3.0/src/gmpy2_format.c 
new/gmpy2-2.3.1/src/gmpy2_format.c
--- old/gmpy2-2.3.0/src/gmpy2_format.c  2026-02-08 01:19:32.000000000 +0100
+++ new/gmpy2-2.3.1/src/gmpy2_format.c  2026-06-24 02:39:59.000000000 +0200
@@ -59,6 +59,10 @@
 
     p2 = (unsigned char*)fmt;
     for (p1 = (unsigned char*)fmtcode; *p1 != '\00'; p1++) {
+        if ((size_t)(p2 - (unsigned char*)fmt) >= sizeof(fmt)) {
+            VALUE_ERROR("too long format string");
+            return NULL;
+        }
         if (*p1 == '<' || *p1 == '>' || *p1 == '^') {
             if (seenalign || seensign || seenindicator || seendigits) {
                 VALUE_ERROR("Invalid conversion specification");
@@ -225,6 +229,13 @@
     *(p2++) = '%';
 
     for (p1 = (unsigned char*)fmtcode; *p1 != '\00'; p1++) {
+        /* Reserve space for precision value, when it's not specified. */
+        if (((size_t)(p2 - mpfrfmt) > sizeof(mpfrfmt) - 30)
+            || ((size_t)(p3 - fmt) >= sizeof(fmt)))
+        {
+            VALUE_ERROR("too long format string");
+            return NULL;
+        }
         if (*p1 == '<' || *p1 == '>' || *p1 == '^') {
             if (seenalign || seensign || seendecimal || seendigits || 
seenround || seenindicator) {
                 VALUE_ERROR("Invalid conversion specification");
@@ -445,8 +456,8 @@
 {
     PyObject *result = NULL, *tempstr = NULL;
     char *realbuf = 0, *imagbuf = 0, *tempbuf = 0, *fmtcode = 0;
-    char *rfmtptr, *fmtptr;
-    unsigned char *p, *ifmtptr;
+    char *rfmtptr, *fmtptr, *ifmtptr;
+    unsigned char *p;
     char rfmt[100], ifmt[100], fmt[30];
     int rbuflen, ibuflen;
     int seensign = 0, seenalign = 0, seendecimal = 0, seendigits = 0;
@@ -468,12 +479,20 @@
     }
 
     rfmtptr = rfmt;
-    ifmtptr = (unsigned char*)ifmt;
+    ifmtptr = ifmt;
     fmtptr = fmt;
     *(rfmtptr++) = '%';
     *(ifmtptr++) = '%';
 
     for (p = (unsigned char*)fmtcode; *p != '\00'; p++) {
+        /* Reserve space for precision value, when it's not specified. */
+        if (((size_t)(rfmtptr - rfmt) > sizeof(rfmt) - 30)
+            || ((size_t)(ifmtptr - ifmt) > sizeof(ifmt) - 30)
+            || ((size_t)(fmtptr - fmt) >= sizeof(fmt)))
+        {
+            VALUE_ERROR("too long format string");
+            return NULL;
+        }
         if (*p == '<' || *p == '>' || *p == '^') {
             if (seenalign || seensign || seendecimal || seendigits ||
                 seenround || seenstyle || seenindicator)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gmpy2-2.3.0/src/gmpy2_mpc.c 
new/gmpy2-2.3.1/src/gmpy2_mpc.c
--- old/gmpy2-2.3.0/src/gmpy2_mpc.c     2026-02-08 01:19:32.000000000 +0100
+++ new/gmpy2-2.3.1/src/gmpy2_mpc.c     2026-06-24 02:39:59.000000000 +0200
@@ -202,7 +202,7 @@
 static PyTypeObject MPC_Type =
 {
     PyVarObject_HEAD_INIT(NULL, 0)
-    .tp_name = "mpc",
+    .tp_name = "gmpy2.mpc",
     .tp_basicsize = sizeof(MPC_Object),
     .tp_dealloc = (destructor) GMPy_MPC_Dealloc,
     .tp_repr = (reprfunc) GMPy_MPC_Repr_Slot,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gmpy2-2.3.0/src/gmpy2_mpz_misc.c 
new/gmpy2-2.3.1/src/gmpy2_mpz_misc.c
--- old/gmpy2-2.3.0/src/gmpy2_mpz_misc.c        2026-02-08 01:19:32.000000000 
+0100
+++ new/gmpy2-2.3.1/src/gmpy2_mpz_misc.c        2026-06-24 02:39:59.000000000 
+0200
@@ -1593,7 +1593,7 @@
 
 PyDoc_STRVAR(GMPy_doc_mpz_function_jacobi,
 "jacobi($module, x, y, /)\n--\n\n"
-"Return the Jacobi symbol (x|y). y must be odd and >0.");
+"Return the Jacobi symbol (x|y). y must be odd.");
 
 static PyObject *
 GMPy_MPZ_Function_Jacobi(PyObject *self, PyObject *const *args,
@@ -1615,8 +1615,8 @@
         return NULL;
     }
 
-    if (mpz_sgn(tempy->z) <= 0 || mpz_even_p(tempy->z)) {
-        VALUE_ERROR("y must be odd and >0");
+    if (mpz_even_p(tempy->z)) {
+        VALUE_ERROR("y must be odd");
         Py_DECREF((PyObject*)tempx);
         Py_DECREF((PyObject*)tempy);
         return NULL;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gmpy2-2.3.0/test/test_context.py 
new/gmpy2-2.3.1/test/test_context.py
--- old/gmpy2-2.3.0/test/test_context.py        2026-02-08 01:19:32.000000000 
+0100
+++ new/gmpy2-2.3.1/test/test_context.py        2026-06-24 02:39:59.000000000 
+0200
@@ -57,6 +57,9 @@
 
     assert gmpy2.const_pi().digits(2) == 
('11001001000011111101101010100010001000010110100011000010001101001100010011000110011000101000101110000000110111000',
 2, 113)
 
+    pytest.raises(ValueError, lambda: ieee(16*31))
+    assert ieee(32*31).precision == 965
+
 
 def test_context():
     ctx = context()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gmpy2-2.3.0/test/test_functions.py 
new/gmpy2-2.3.1/test/test_functions.py
--- old/gmpy2-2.3.0/test/test_functions.py      2026-02-08 01:19:32.000000000 
+0100
+++ new/gmpy2-2.3.1/test/test_functions.py      2026-06-24 02:39:59.000000000 
+0200
@@ -1595,11 +1595,11 @@
 
 def test_jacobi():
     pytest.raises(TypeError, lambda: jacobi('a', 10))
-    pytest.raises(ValueError, lambda: jacobi(10,-3))
     pytest.raises(TypeError, lambda: jacobi(3))
     pytest.raises(TypeError, lambda: jacobi())
 
-    assert jacobi(10,3) == 1
+    assert jacobi(10, 3) == 1
+    assert jacobi(10, -3) == 1
 
 
 def test_kronecker():
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gmpy2-2.3.0/test/test_misc.py 
new/gmpy2-2.3.1/test/test_misc.py
--- old/gmpy2-2.3.0/test/test_misc.py   2026-02-08 01:19:32.000000000 +0100
+++ new/gmpy2-2.3.1/test/test_misc.py   2026-06-24 02:39:59.000000000 +0200
@@ -7,7 +7,7 @@
 
 
 def test_misc():
-    assert gmpy2.version().startswith('2.3')
+    assert gmpy2.version().startswith('2.')
     assert gmpy2.mp_limbsize() in (32,64)
     assert '5.0.0' <= gmpy2.mp_version()
     assert gmpy2.mpfr_version() and gmpy2.mpfr_version().startswith('MPFR')
@@ -25,3 +25,11 @@
 def test_sizeof():
     assert sys.getsizeof(gmpy2.mpz(10)) > 0
     assert sys.getsizeof(gmpy2.mpfr('1.0')) > 0
+
+
+def test_issue_686():
+    assert gmpy2.mpz.__module__ == 'gmpy2'
+    assert gmpy2.xmpz.__module__ == 'gmpy2'
+    assert gmpy2.mpq.__module__ == 'gmpy2'
+    assert gmpy2.mpfr.__module__ == 'gmpy2'
+    assert gmpy2.mpc.__module__ == 'gmpy2'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gmpy2-2.3.0/test/test_mpc.py 
new/gmpy2-2.3.1/test/test_mpc.py
--- old/gmpy2-2.3.0/test/test_mpc.py    2026-02-08 01:19:32.000000000 +0100
+++ new/gmpy2-2.3.1/test/test_mpc.py    2026-06-24 02:39:59.000000000 +0200
@@ -229,6 +229,8 @@
     gmpy2.set_context(gmpy2.context(round=gmpy2.RoundUp))
     assert f'{c:.2f}' == '2.68+0.00j'
 
+    pytest.raises(ValueError, lambda: format(mpc(1), "1" + "0"*70))
+
 
 def test_mpc_repr():
     c = 
mpc('1.2999999999999999999999999999994-4.7000000000000000000000000000000025j',(100,110))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gmpy2-2.3.0/test/test_mpfr.py 
new/gmpy2-2.3.1/test/test_mpfr.py
--- old/gmpy2-2.3.0/test/test_mpfr.py   2026-02-08 01:19:32.000000000 +0100
+++ new/gmpy2-2.3.1/test/test_mpfr.py   2026-06-24 02:39:59.000000000 +0200
@@ -361,6 +361,8 @@
     gmpy2.set_context(gmpy2.context(round=gmpy2.RoundUp))
     assert f'{r:.2f}' == '2.68'
 
+    pytest.raises(ValueError, lambda: format(mpfr(1), "1" + "0"*70))
+
 
 def test_mpfr_digits():
     r, r2 = mpfr(5.6), mpfr(5)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gmpy2-2.3.0/test/test_mpz.py 
new/gmpy2-2.3.1/test/test_mpz.py
--- old/gmpy2-2.3.0/test/test_mpz.py    2026-02-08 01:19:32.000000000 +0100
+++ new/gmpy2-2.3.1/test/test_mpz.py    2026-06-24 02:39:59.000000000 +0200
@@ -666,6 +666,8 @@
     gmpy2.set_context(gmpy2.ieee(64))
     assert '{:f}'.format(a<<1024) == 'inf'
 
+    raises(ValueError, lambda: format(mpz(1), "1" + "0"*70))
+
 
 def test_mpz_digits():
     z1, z2 = mpz(-3), mpz(15)

Reply via email to