python-gmp 0.5.0a6__tar.gz → 0.5.0b2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. python_gmp-0.5.0b2/.backportrc.json +16 -0
  2. python_gmp-0.5.0b2/.github/workflows/backport.yml +37 -0
  3. python_gmp-0.5.0b2/.github/workflows/ci.yml +19 -0
  4. {python_gmp-0.5.0a6 → python_gmp-0.5.0b2}/.github/workflows/coverage.yml +14 -18
  5. {python_gmp-0.5.0a6 → python_gmp-0.5.0b2}/.github/workflows/linter.yml +1 -2
  6. {python_gmp-0.5.0a6 → python_gmp-0.5.0b2}/.github/workflows/publish.yml +17 -6
  7. {python_gmp-0.5.0a6 → python_gmp-0.5.0b2}/.github/workflows/wheels.yml +18 -9
  8. {python_gmp-0.5.0a6 → python_gmp-0.5.0b2}/.pre-commit-config.yaml +1 -0
  9. python_gmp-0.5.0b2/.readthedocs.yaml +34 -0
  10. {python_gmp-0.5.0a6 → python_gmp-0.5.0b2}/LICENSE +1 -1
  11. {python_gmp-0.5.0a6 → python_gmp-0.5.0b2}/PKG-INFO +25 -33
  12. python_gmp-0.5.0b2/README.rst +78 -0
  13. python_gmp-0.5.0b2/bench/README.rst +11 -0
  14. python_gmp-0.5.0b2/bench/collatz.py +42 -0
  15. python_gmp-0.5.0b2/bench/mul.py +24 -0
  16. {python_gmp-0.5.0a6 → python_gmp-0.5.0b2}/docs/conf.py +1 -1
  17. {python_gmp-0.5.0a6 → python_gmp-0.5.0b2}/fmt.c +24 -20
  18. {python_gmp-0.5.0a6 → python_gmp-0.5.0b2}/gmp.c +887 -428
  19. python_gmp-0.5.0b2/meson.build +8 -0
  20. python_gmp-0.5.0b2/mpz.h +18 -0
  21. {python_gmp-0.5.0a6 → python_gmp-0.5.0b2}/pyproject.toml +13 -16
  22. {python_gmp-0.5.0a6 → python_gmp-0.5.0b2}/pythoncapi_compat.h +412 -29
  23. python_gmp-0.5.0b2/scripts/cibw_before_all.sh +96 -0
  24. python_gmp-0.5.0b2/scripts/gitversion.py +39 -0
  25. python_gmp-0.5.0b2/tests/conftest.py +32 -0
  26. {python_gmp-0.5.0a6 → python_gmp-0.5.0b2}/tests/test_functions.py +7 -15
  27. {python_gmp-0.5.0a6 → python_gmp-0.5.0b2}/tests/test_memory.py +4 -5
  28. {python_gmp-0.5.0a6 → python_gmp-0.5.0b2}/tests/test_mpz.py +119 -66
  29. python_gmp-0.5.0a6/tests/test_utils.py → python_gmp-0.5.0b2/tests/utils.py +47 -42
  30. {python_gmp-0.5.0a6 → python_gmp-0.5.0b2}/utils.c +46 -6
  31. {python_gmp-0.5.0a6 → python_gmp-0.5.0b2}/utils.h +8 -5
  32. python_gmp-0.5.0a6/.github/workflows/ci.yml +0 -54
  33. python_gmp-0.5.0a6/.github/workflows/os.yml +0 -62
  34. python_gmp-0.5.0a6/.gitmodules +0 -3
  35. python_gmp-0.5.0a6/.readthedocs.yaml +0 -23
  36. python_gmp-0.5.0a6/README.rst +0 -87
  37. python_gmp-0.5.0a6/libzz/.github/workflows/ci.yml +0 -54
  38. python_gmp-0.5.0a6/libzz/.github/workflows/publish.yml +0 -36
  39. python_gmp-0.5.0a6/libzz/.gitignore +0 -51
  40. python_gmp-0.5.0a6/libzz/AUTHORS +0 -1
  41. python_gmp-0.5.0a6/libzz/COPYING +0 -165
  42. python_gmp-0.5.0a6/libzz/ChangeLog +0 -66
  43. python_gmp-0.5.0a6/libzz/NEWS +0 -5
  44. python_gmp-0.5.0a6/libzz/README +0 -2
  45. python_gmp-0.5.0a6/libzz/configure.ac +0 -75
  46. python_gmp-0.5.0a6/libzz/doc/fdl.texi +0 -513
  47. python_gmp-0.5.0a6/libzz/doc/makefile.am +0 -2
  48. python_gmp-0.5.0a6/libzz/doc/zz.texi +0 -441
  49. python_gmp-0.5.0a6/libzz/makefile.am +0 -24
  50. python_gmp-0.5.0a6/libzz/scripts/cibw_before_all.sh +0 -33
  51. python_gmp-0.5.0a6/libzz/tests/makefile.am +0 -5
  52. python_gmp-0.5.0a6/libzz/tests/t-fac.c +0 -75
  53. python_gmp-0.5.0a6/libzz/tests/t-mul.c +0 -121
  54. python_gmp-0.5.0a6/libzz/zz.c +0 -2217
  55. python_gmp-0.5.0a6/libzz/zz.h +0 -133
  56. python_gmp-0.5.0a6/libzz/zz.pc.in +0 -11
  57. python_gmp-0.5.0a6/meson.build +0 -18
  58. python_gmp-0.5.0a6/mpz.h +0 -47
  59. python_gmp-0.5.0a6/scripts/cibw_before_all.sh +0 -33
  60. python_gmp-0.5.0a6/scripts/dll-importexport.diff +0 -20
  61. python_gmp-0.5.0a6/scripts/fat_build_fix.diff +0 -37
  62. python_gmp-0.5.0a6/scripts/gcc15.diff +0 -51
  63. python_gmp-0.5.0a6/tests/conftest.py +0 -30
  64. python_gmp-0.5.0a6/tests/test_api.py +0 -187
  65. {python_gmp-0.5.0a6 → python_gmp-0.5.0b2}/.clang-format +0 -0
  66. {python_gmp-0.5.0a6 → python_gmp-0.5.0b2}/.github/dependabot.yml +0 -0
  67. {python_gmp-0.5.0a6 → python_gmp-0.5.0b2}/.gitignore +0 -0
  68. {python_gmp-0.5.0a6 → python_gmp-0.5.0b2}/docs/index.rst +0 -0
  69. {python_gmp-0.5.0a6/libzz → python_gmp-0.5.0b2}/scripts/dll-importexport.diff +0 -0
  70. {python_gmp-0.5.0a6/libzz → python_gmp-0.5.0b2}/scripts/fat_build_fix.diff +0 -0
  71. {python_gmp-0.5.0a6/libzz → python_gmp-0.5.0b2}/scripts/gcc15.diff +0 -0
@@ -0,0 +1,16 @@
1
+ // .backportrc.json -- for https://github.com/sorenlouv/backport
2
+ {
3
+ // Required
4
+ "repoOwner": "diofant",
5
+ "repoName": "python-gmp",
6
+ // the branches available to backport to
7
+ "targetBranchChoices": ["gmp-0.4.x"],
8
+ // Automatically detect which branches a pull request should be
9
+ // backported to based on the pull request labels.
10
+ "branchLabelMapping": {
11
+ "^backport-to-(.+)$": "gmp-$1"
12
+ },
13
+ "targetPRLabels": ["backport"],
14
+ "sourcePRLabels": ["backport-pr-created"],
15
+ "commitConflicts": true
16
+ }
@@ -0,0 +1,37 @@
1
+ name: Automatic backport action
2
+
3
+ on:
4
+ pull_request_target:
5
+ types: ["labeled", "closed"]
6
+
7
+ permissions:
8
+ contents: write # so it can comment
9
+ pull-requests: write # so it can create pull requests
10
+
11
+ jobs:
12
+ backport:
13
+ name: Backport PR
14
+ if: github.event.pull_request.merged == true && !(contains(github.event.pull_request.labels.*.name, 'backport')) && !(contains(github.event.pull_request.labels.*.name, 'backport-pr-created'))
15
+ runs-on: ubuntu-24.04
16
+ steps:
17
+ # Workaround not to fail the workflow if the PR does not need a backport
18
+ # https://github.com/sorenlouv/backport-github-action/issues/127#issuecomment-2277248320
19
+ - name: Check for backport labels
20
+ id: check_labels
21
+ run: |-
22
+ labels='${{ toJSON(github.event.pull_request.labels.*.name) }}'
23
+ matched=$(echo "${labels}" | jq '. | map(select(startswith("backport-to-"))) | length')
24
+ echo "matched=$matched"
25
+ echo "matched=$matched" >> $GITHUB_OUTPUT
26
+ - name: Backport Action
27
+ if: fromJSON(steps.check_labels.outputs.matched) > 0
28
+ uses: sorenlouv/backport-github-action@v10.2.0
29
+ with:
30
+ github_token: ${{ secrets.GITHUB_TOKEN }}
31
+ auto_backport_label_prefix: backport-to-
32
+ - name: Info log
33
+ if: ${{ success() && fromJSON(steps.check_labels.outputs.matched) > 0 }}
34
+ run: cat ~/.backport/backport.info.log
35
+ - name: Debug log
36
+ if: ${{ failure() && fromJSON(steps.check_labels.outputs.matched) > 0 }}
37
+ run: cat ~/.backport/backport.debug.log
@@ -0,0 +1,19 @@
1
+ name: Run CI tests
2
+ on:
3
+ push:
4
+ pull_request:
5
+ workflow_dispatch:
6
+ schedule:
7
+ - cron: '0 0 * * 2'
8
+ jobs:
9
+ linter:
10
+ uses: ./.github/workflows/linter.yml
11
+ coverage:
12
+ uses: ./.github/workflows/coverage.yml
13
+ needs:
14
+ - linter
15
+ os:
16
+ uses: ./.github/workflows/wheels.yml
17
+ if: startsWith(github.ref, 'refs/tags/') != true
18
+ needs:
19
+ - coverage
@@ -2,33 +2,31 @@ name: Run coverage tests
2
2
  on: [workflow_dispatch, workflow_call]
3
3
  jobs:
4
4
  coverage:
5
+ timeout-minutes: 20
5
6
  runs-on: ${{ matrix.os }}
6
7
  env:
7
- PYTEST_ADDOPTS: --verbose
8
8
  CFLAGS: -Wall -Wpedantic -Werror -std=c17 -Wconversion
9
9
  strategy:
10
- fail-fast: true
11
10
  matrix:
12
11
  os: [ubuntu-24.04]
13
- python-version: [pypy3.11, "3.x", 3.14]
12
+ python-version: [pypy3.11, "graalpy-25.0", "3.x"]
14
13
  steps:
15
- - uses: actions/checkout@v5
14
+ - uses: actions/checkout@v6
16
15
  with:
17
16
  fetch-depth: 0
18
- submodules: true
19
17
  - uses: actions/setup-python@v6
20
18
  with:
21
19
  python-version: ${{ matrix.python-version }}
22
20
  allow-prereleases: true
23
21
  - run: sudo apt-get update
24
- - run: sudo apt-get install lcov
22
+ - run: sudo apt-get install autoconf-archive lcov
25
23
  - name: Setup locales
26
24
  run: |
27
25
  sudo locale-gen ru_RU.UTF-8
28
26
  sudo locale-gen ps_AF.UTF-8
29
27
  - name: Cache GNU GMP builds
30
28
  id: cache-gmp
31
- uses: actions/cache@v4
29
+ uses: actions/cache@v5
32
30
  with:
33
31
  path: .local
34
32
  key: ${{ matrix.os }}-${{ hashFiles('scripts/*') }}
@@ -36,12 +34,12 @@ jobs:
36
34
  if: steps.cache-gmp.outputs.cache-hit != 'true'
37
35
  - run: python -m pip install --upgrade pip
38
36
  - run: |
39
- pip install --verbose .[tests] -Cbuild-dir=build \
40
- -Csetup-args=-Dbuildtype=debug \
41
- -Csetup-args=-Db_coverage=true
37
+ pip install --verbose .[ci] -Cbuild-dir=build \
38
+ -Csetup-args=-Dbuildtype=debug \
39
+ -Csetup-args=-Db_coverage=true
42
40
  env:
43
41
  PKG_CONFIG_PATH: ${{ github.workspace }}/.local/lib/pkgconfig
44
- - run: pytest --hypothesis-profile=default
42
+ - run: pytest
45
43
  env:
46
44
  LD_LIBRARY_PATH: ${{ github.workspace }}/.local/lib
47
45
  - name: Get coverage data
@@ -50,7 +48,7 @@ jobs:
50
48
  lcov --remove coverage.info "*.h" --ignore-errors unused \
51
49
  --output-file coverage.info
52
50
  cp coverage.info build/coverage-${{ matrix.python-version }}.info
53
- - uses: actions/upload-artifact@v5
51
+ - uses: actions/upload-artifact@v6
54
52
  with:
55
53
  name: coverage-${{ matrix.python-version }}
56
54
  path: |
@@ -61,13 +59,12 @@ jobs:
61
59
  needs:
62
60
  - coverage
63
61
  steps:
64
- - uses: actions/checkout@v5
62
+ - uses: actions/checkout@v6
65
63
  with:
66
64
  fetch-depth: 0
67
- submodules: true
68
65
  - run: sudo apt-get update
69
66
  - run: sudo apt-get install lcov diff-cover
70
- - uses: actions/download-artifact@v6
67
+ - uses: actions/download-artifact@v7
71
68
  with:
72
69
  pattern: coverage-*
73
70
  path: build/
@@ -78,7 +75,7 @@ jobs:
78
75
  - run: |
79
76
  diff-cover build/coverage*.info --fail-under=100 \
80
77
  --compare-branch=origin/master
81
- - uses: actions/upload-artifact@v5
78
+ - uses: actions/upload-artifact@v6
82
79
  with:
83
80
  name: coverage
84
81
  path: |
@@ -88,7 +85,6 @@ jobs:
88
85
  with:
89
86
  token: ${{ secrets.CODECOV_TOKEN }}
90
87
  gcov_ignore: pythoncapi_compat.h
91
- gcov_include: '*.c, libzz/*.c'
88
+ gcov_include: '*.c'
92
89
  gcov_args: --no-external --preserve-paths
93
90
  fail_ci_if_error: true
94
- recurse_submodules: true
@@ -4,10 +4,9 @@ jobs:
4
4
  linter:
5
5
  runs-on: ubuntu-24.04
6
6
  steps:
7
- - uses: actions/checkout@v5
7
+ - uses: actions/checkout@v6
8
8
  with:
9
9
  fetch-depth: 0
10
- submodules: true
11
10
  - uses: actions/setup-python@v6
12
11
  with:
13
12
  python-version: "3.x"
@@ -6,16 +6,27 @@ jobs:
6
6
  if: startsWith(github.ref, 'refs/tags/')
7
7
  runs-on: ubuntu-24.04
8
8
  steps:
9
- - uses: actions/checkout@v5
9
+ - uses: actions/checkout@v6
10
10
  with:
11
11
  fetch-depth: 0
12
- submodules: true
13
12
  - uses: actions/setup-python@v6
14
13
  with:
15
14
  python-version: "3.x"
15
+ - run: sudo apt-get update
16
+ - run: sudo apt-get install autoconf-archive
16
17
  - run: pip install build
18
+ - name: Cache GNU GMP builds
19
+ id: cache-gmp
20
+ uses: actions/cache@v5
21
+ with:
22
+ path: .local
23
+ key: ${{ matrix.os }}-${{ hashFiles('scripts/*') }}
24
+ - run: bash scripts/cibw_before_all.sh
25
+ if: steps.cache-gmp.outputs.cache-hit != 'true'
17
26
  - run: python -m build -s
18
- - uses: actions/upload-artifact@v5
27
+ env:
28
+ PKG_CONFIG_PATH: ${{ github.workspace }}/.local/lib/pkgconfig
29
+ - uses: actions/upload-artifact@v6
19
30
  with:
20
31
  name: python-gmp-sdist
21
32
  path: dist/
@@ -34,7 +45,7 @@ jobs:
34
45
  permissions:
35
46
  id-token: write
36
47
  steps:
37
- - uses: actions/download-artifact@v6
48
+ - uses: actions/download-artifact@v7
38
49
  with:
39
50
  pattern: python-gmp-*
40
51
  path: dist/
@@ -51,12 +62,12 @@ jobs:
51
62
  contents: write
52
63
  id-token: write
53
64
  steps:
54
- - uses: actions/download-artifact@v6
65
+ - uses: actions/download-artifact@v7
55
66
  with:
56
67
  pattern: python-gmp-*
57
68
  path: dist/
58
69
  merge-multiple: true
59
- - uses: sigstore/gh-action-sigstore-python@v3.1.0
70
+ - uses: sigstore/gh-action-sigstore-python@v3.2.0
60
71
  with:
61
72
  inputs: >-
62
73
  ./dist/*.tar.gz
@@ -8,21 +8,30 @@ jobs:
8
8
  matrix:
9
9
  os: [ubuntu-24.04, ubuntu-24.04-arm, macos-15-intel, macos-15,
10
10
  windows-2022]
11
+ msystem: [ucrt64]
12
+ menv: [ucrt-x86_64]
13
+ include:
14
+ - os: windows-11-arm
15
+ msystem: clangarm64
16
+ menv: clang-aarch64
11
17
  steps:
12
- - uses: actions/checkout@v5
18
+ - uses: actions/checkout@v6
13
19
  with:
14
20
  fetch-depth: 0
15
- submodules: true
16
- - uses: msys2/setup-msys2@v2.29.0
21
+ - uses: msys2/setup-msys2@v2.30.0
17
22
  name: Setup msys2
18
23
  with:
19
24
  install: >-
20
- mingw-w64-ucrt-x86_64-gcc
25
+ mingw-w64-${{ matrix.menv }}-binutils
26
+ mingw-w64-${{ matrix.menv }}-gcc
27
+ mingw-w64-${{ matrix.menv }}-tools
21
28
  diffutils
22
29
  m4
23
30
  make
24
31
  patch
25
- msystem: ucrt64
32
+ autotools
33
+ autoconf-archive
34
+ msystem: ${{ matrix.msystem }}
26
35
  if: ${{ startsWith(matrix.os, 'windows') }}
27
36
  # Install pkgconfig on Windows from choco rather than from msys and
28
37
  # avoid using the Strawberry one.
@@ -31,10 +40,10 @@ jobs:
31
40
  # We have to set this here rather than in the cibuildwheel config
32
41
  # This is probably something to do with \ vs / in paths...
33
42
  - run: echo "PKG_CONFIG_PATH=${{ github.workspace }}/.local/lib/pkgconfig" >> $env:GITHUB_ENV
34
- if: ${{ startsWith( matrix.os , 'windows' ) }}
43
+ if: ${{ startsWith(matrix.os, 'windows') }}
35
44
  - name: Build wheels
36
- uses: pypa/cibuildwheel@v3.2.1
37
- - uses: actions/upload-artifact@v5
45
+ uses: pypa/cibuildwheel@v3.3.1
46
+ - uses: actions/upload-artifact@v6
38
47
  with:
39
48
  name: wheels-${{ matrix.os }}
40
49
  path: ./wheelhouse/
@@ -43,7 +52,7 @@ jobs:
43
52
  needs: build_wheels
44
53
  steps:
45
54
  - name: Merge Wheels
46
- uses: actions/upload-artifact/merge@v5
55
+ uses: actions/upload-artifact/merge@v6
47
56
  with:
48
57
  name: python-gmp-wheels
49
58
  pattern: wheels-*
@@ -8,6 +8,7 @@ repos:
8
8
  - id: trailing-whitespace
9
9
  - id: name-tests-test
10
10
  args: [--pytest-test-first]
11
+ exclude: ^tests/utils.py$
11
12
  - repo: https://github.com/astral-sh/ruff-pre-commit
12
13
  rev: v0.8.3
13
14
  hooks:
@@ -0,0 +1,34 @@
1
+ version: 2
2
+ formats:
3
+ - htmlzip
4
+ - pdf
5
+ build:
6
+ os: ubuntu-24.04
7
+ apt_packages:
8
+ - libgmp-dev
9
+ - build-essential
10
+ - pkg-config
11
+ jobs:
12
+ pre_create_environment:
13
+ - |
14
+ PREFIX=$(pwd)/.local
15
+ ZZ_VERSION=0.8.0b0
16
+ ZZ_DIR=zz-${ZZ_VERSION}
17
+ GITHUB_URL=https://github.com/diofant/zz/releases/download/
18
+ ZZ_URL=${GITHUB_URL}v${ZZ_VERSION}/${ZZ_DIR}.tar.gz
19
+ wget ${ZZ_URL}
20
+ tar xzf ${ZZ_DIR}.tar.gz
21
+ cd ${ZZ_DIR}
22
+ ./configure -q --prefix=$PREFIX
23
+ make -s
24
+ make -s install
25
+ tools:
26
+ python: "3"
27
+ python:
28
+ install:
29
+ - path: .
30
+ extra_requirements:
31
+ - docs
32
+ sphinx:
33
+ fail_on_warning: true
34
+ configuration: docs/conf.py
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2024-2025 Sergey B Kirpichev
3
+ Copyright (c) 2024-2026 Sergey B Kirpichev
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-gmp
3
- Version: 0.5.0a6
3
+ Version: 0.5.0b2
4
4
  Summary: Safe bindings to the GNU GMP library
5
5
  Keywords: gmp,multiple-precision,arbitrary-precision,bignum
6
6
  Author-Email: Sergey B Kirpichev <skirpichev@gmail.com>
@@ -15,8 +15,6 @@ Classifier: Operating System :: POSIX
15
15
  Classifier: Programming Language :: C
16
16
  Classifier: Programming Language :: Python :: 3
17
17
  Classifier: Programming Language :: Python :: 3 :: Only
18
- Classifier: Programming Language :: Python :: 3.9
19
- Classifier: Programming Language :: Python :: 3.10
20
18
  Classifier: Programming Language :: Python :: 3.11
21
19
  Classifier: Programming Language :: Python :: 3.12
22
20
  Classifier: Programming Language :: Python :: 3.13
@@ -35,11 +33,14 @@ Project-URL: Homepage, https://github.com/diofant/python-gmp
35
33
  Project-URL: Source Code, https://github.com/diofant/python-gmp
36
34
  Project-URL: Bug Tracker, https://github.com/diofant/python-gmp/issues
37
35
  Project-URL: Documentation, https://python-gmp.readthedocs.io/en/latest/
38
- Requires-Python: >=3.9
36
+ Requires-Python: >=3.11
39
37
  Provides-Extra: tests
40
38
  Requires-Dist: pytest; extra == "tests"
41
39
  Requires-Dist: hypothesis; extra == "tests"
42
- Requires-Dist: mpmath>=1.4.0a7; extra == "tests"
40
+ Requires-Dist: mpmath; extra == "tests"
41
+ Provides-Extra: ci
42
+ Requires-Dist: python-gmp[tests]; extra == "ci"
43
+ Requires-Dist: pytest-xdist; extra == "ci"
43
44
  Provides-Extra: docs
44
45
  Requires-Dist: sphinx>=8.2; extra == "docs"
45
46
  Provides-Extra: develop
@@ -51,16 +52,16 @@ Description-Content-Type: text/x-rst
51
52
  Python-GMP
52
53
  ==========
53
54
 
54
- Python extension module, gmp, providing safe bindings to the GNU GMP (version
55
- 6.3.0 or later required). This module shouldn't crash the interpreter.
55
+ Python extension module, providing bindings to the GNU GMP via the `ZZ library
56
+ <https://github.com/diofant/zz>`_. This module shouldn't crash the interpreter.
56
57
 
57
58
  The gmp can be used as a `gmpy2`_/`python-flint`_ replacement to provide
58
- integer type (`mpz`_), compatible with Python's `int`_. It includes few
59
- functions (`comb`_, `factorial`_, `gcd`_, `isqrt`_, `lcm`_ and `perm`_),
60
- compatible with the Python stdlib's module `math`_.
59
+ integer type (`mpz`_), compatible with Python's `int`_. It also includes
60
+ functions, compatible with the Python stdlib's submodule `math.integer
61
+ <https://docs.python.org/3.15/library/math.integer.html>`_.
61
62
 
62
- This module requires Python 3.9 or later versions and has been tested with
63
- CPython 3.9 through 3.14, with PyPy3.11 7.3.20 and with GraalPy 25.0.
63
+ This module requires Python 3.11 or later versions and has been tested with
64
+ CPython 3.11 through 3.14, with PyPy3.11 7.3.20 and with GraalPy 25.0.
64
65
  Free-threading builds of the CPython are supported.
65
66
 
66
67
  Releases are available in the Python Package Index (PyPI) at
@@ -71,17 +72,16 @@ Motivation
71
72
  ----------
72
73
 
73
74
  The CPython (and most other Python implementations, like PyPy) is optimized to
74
- work with small integers. Algorithms used here for "big enough" integers
75
- usually aren't best known in the field. Fortunately, it's possible to use
76
- bindings (for example, the `gmpy2`_ package) to the GNU Multiple Precision
77
- Arithmetic Library (GMP), which aims to be faster than any other bignum library
78
- for all operand sizes.
79
-
80
- But such extension modules usually rely on default GMP's memory allocation
81
- functions and can't recover from errors such as out of memory. So, it's easy
82
- to crash the Python interpreter during the interactive session. Following
83
- example with the gmpy2 will work if you set address space limit for the Python
84
- interpreter (e.g. by ``prlimit`` command on Linux):
75
+ work with small (machine-sized) integers. Algorithms used here for big
76
+ integers usually aren't best known in the field. Fortunately, it's possible to
77
+ use bindings (for example, the `gmpy2`_ package) to the GNU GMP, which aims to
78
+ be faster than any other bignum library for all operand sizes.
79
+
80
+ But such extension modules usually rely on default GMP's memory management and
81
+ can't recover from allocation failure. So, it's easy to crash the Python
82
+ interpreter during the interactive session. Following example with the gmpy2
83
+ will work if you set address space limit for the Python interpreter (e.g. by
84
+ ``prlimit`` command on Linux):
85
85
 
86
86
  .. code:: pycon
87
87
 
@@ -119,19 +119,11 @@ Warning on --disable-alloca configure option
119
119
  --------------------------------------------
120
120
 
121
121
  You should use the GNU GMP library, compiled with the '--disable-alloca'
122
- configure option to prevent using alloca() for temporary workspace allocation
123
- (and use the heap instead), or this module can't prevent a crash in case of a
124
- stack overflow.
122
+ configure option to prevent using alloca() for temporary workspace allocation,
123
+ or this module may crash the interpreter in case of a stack overflow.
125
124
 
126
125
 
127
126
  .. _gmpy2: https://pypi.org/project/gmpy2/
128
127
  .. _python-flint: https://pypi.org/project/python-flint/
129
128
  .. _mpz: https://python-gmp.readthedocs.io/en/latest/#gmp.mpz
130
129
  .. _int: https://docs.python.org/3/library/functions.html#int
131
- .. _factorial: https://python-gmp.readthedocs.io/en/latest/#gmp.factorial
132
- .. _gcd: https://python-gmp.readthedocs.io/en/latest/#gmp.gcd
133
- .. _isqrt: https://python-gmp.readthedocs.io/en/latest/#gmp.isqrt
134
- .. _lcm: https://python-gmp.readthedocs.io/en/latest/#gmp.lcm
135
- .. _comb: https://python-gmp.readthedocs.io/en/latest/#gmp.comb
136
- .. _perm: https://python-gmp.readthedocs.io/en/latest/#gmp.perm
137
- .. _math: https://docs.python.org/3/library/math.html#number-theoretic-functions
@@ -0,0 +1,78 @@
1
+ Python-GMP
2
+ ==========
3
+
4
+ Python extension module, providing bindings to the GNU GMP via the `ZZ library
5
+ <https://github.com/diofant/zz>`_. This module shouldn't crash the interpreter.
6
+
7
+ The gmp can be used as a `gmpy2`_/`python-flint`_ replacement to provide
8
+ integer type (`mpz`_), compatible with Python's `int`_. It also includes
9
+ functions, compatible with the Python stdlib's submodule `math.integer
10
+ <https://docs.python.org/3.15/library/math.integer.html>`_.
11
+
12
+ This module requires Python 3.11 or later versions and has been tested with
13
+ CPython 3.11 through 3.14, with PyPy3.11 7.3.20 and with GraalPy 25.0.
14
+ Free-threading builds of the CPython are supported.
15
+
16
+ Releases are available in the Python Package Index (PyPI) at
17
+ https://pypi.org/project/python-gmp/.
18
+
19
+
20
+ Motivation
21
+ ----------
22
+
23
+ The CPython (and most other Python implementations, like PyPy) is optimized to
24
+ work with small (machine-sized) integers. Algorithms used here for big
25
+ integers usually aren't best known in the field. Fortunately, it's possible to
26
+ use bindings (for example, the `gmpy2`_ package) to the GNU GMP, which aims to
27
+ be faster than any other bignum library for all operand sizes.
28
+
29
+ But such extension modules usually rely on default GMP's memory management and
30
+ can't recover from allocation failure. So, it's easy to crash the Python
31
+ interpreter during the interactive session. Following example with the gmpy2
32
+ will work if you set address space limit for the Python interpreter (e.g. by
33
+ ``prlimit`` command on Linux):
34
+
35
+ .. code:: pycon
36
+
37
+ >>> import gmpy2
38
+ >>> gmpy2.__version__
39
+ '2.2.1'
40
+ >>> z = gmpy2.mpz(29925959575501)
41
+ >>> while True: # this loop will crash interpter
42
+ ... z = z*z
43
+ ...
44
+ GNU MP: Cannot allocate memory (size=46956584)
45
+ Aborted
46
+
47
+ The gmp module handles such errors correctly:
48
+
49
+ .. code:: pycon
50
+
51
+ >>> import gmp
52
+ >>> z = gmp.mpz(29925959575501)
53
+ >>> while True:
54
+ ... z = z*z
55
+ ...
56
+ Traceback (most recent call last):
57
+ File "<python-input-3>", line 2, in <module>
58
+ z = z*z
59
+ ~^~
60
+ MemoryError
61
+ >>> # interpreter still works, all variables in
62
+ >>> # the current scope are available,
63
+ >>> z.bit_length() # including pre-failure value of z
64
+ 93882077
65
+
66
+
67
+ Warning on --disable-alloca configure option
68
+ --------------------------------------------
69
+
70
+ You should use the GNU GMP library, compiled with the '--disable-alloca'
71
+ configure option to prevent using alloca() for temporary workspace allocation,
72
+ or this module may crash the interpreter in case of a stack overflow.
73
+
74
+
75
+ .. _gmpy2: https://pypi.org/project/gmpy2/
76
+ .. _python-flint: https://pypi.org/project/python-flint/
77
+ .. _mpz: https://python-gmp.readthedocs.io/en/latest/#gmp.mpz
78
+ .. _int: https://docs.python.org/3/library/functions.html#int
@@ -0,0 +1,11 @@
1
+ This directory holds some basic benchmarks for the gmp extension.
2
+
3
+ It's possible to run them also with gmpy2's and flint's integer types:
4
+
5
+ .. code:: sh
6
+
7
+ ( export T="gmpy2.mpz"; \
8
+ python bench/mul.py -q --copy-env --rigorous -o $T.json )
9
+
10
+ Beware, that the gmp prefers clang over gcc and extensions might
11
+ use different compiler options per default.
@@ -0,0 +1,42 @@
1
+ # collatz.py
2
+
3
+ import os
4
+
5
+ import pyperf
6
+
7
+ if os.getenv("T") == "gmpy2.mpz":
8
+ from gmpy2 import mpz
9
+ elif os.getenv("T") == "flint.fmpz":
10
+ from flint import fmpz as mpz
11
+ else:
12
+ from gmp import mpz
13
+
14
+ zero = mpz(0)
15
+ one = mpz(1)
16
+ two = mpz(2)
17
+ three = mpz(3)
18
+
19
+ # https://en.wikipedia.org/wiki/Collatz_conjecture
20
+
21
+ def collatz0(n):
22
+ total = 0
23
+ n = mpz(n)
24
+ while n > one:
25
+ n = n*three + one if n & one else n//two
26
+ total += 1
27
+ return total
28
+
29
+ def collatz1(n):
30
+ total = 0
31
+ n = mpz(n)
32
+ while n > 1:
33
+ n = n*3 + 1 if n & 1 else n//2
34
+ total += 1
35
+ return total
36
+
37
+ runner = pyperf.Runner()
38
+ for f in [collatz0, collatz1]:
39
+ for v in ["97", "871", "(1<<128)+31"]:
40
+ h = f"{f.__name__}({v})"
41
+ i = eval(v)
42
+ runner.bench_func(h, f, i)
@@ -0,0 +1,24 @@
1
+ # mul.py
2
+
3
+ import os
4
+ from operator import mul
5
+
6
+ import pyperf
7
+
8
+ if os.getenv("T") == "gmpy2.mpz":
9
+ from gmpy2 import mpz
10
+ elif os.getenv("T") == "flint.fmpz":
11
+ from flint import fmpz as mpz
12
+ else:
13
+ from gmp import mpz
14
+
15
+ values = ["1<<7", "1<<38", "1<<300", "1<<3000"]
16
+
17
+ runner = pyperf.Runner()
18
+ for v in values:
19
+ i = eval(v)
20
+ bn = '("'+v+'")**2'
21
+ x = mpz(i)
22
+ # make y != x to avoid a quick mpn_sqr() path on gmp/flint
23
+ y = mpz(i + 1)
24
+ runner.bench_func(bn, mul, x, y)
@@ -36,7 +36,7 @@ autodoc_default_options = {"members": True}
36
36
 
37
37
  # General information about the project.
38
38
  project = gmp.__package__
39
- copyright = "2024-2025, Sergey B Kirpichev"
39
+ copyright = "2024-2026, Sergey B Kirpichev"
40
40
  gmp_version = packaging.version.parse(gmp.__version__)
41
41
 
42
42
  # The version info for the project you're documenting, acts as