python-gmp 0.5.0b1__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 (47) 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.0b1 → python_gmp-0.5.0b2}/.github/workflows/coverage.yml +13 -14
  5. {python_gmp-0.5.0b1 → python_gmp-0.5.0b2}/.github/workflows/linter.yml +1 -1
  6. {python_gmp-0.5.0b1 → python_gmp-0.5.0b2}/.github/workflows/publish.yml +8 -6
  7. {python_gmp-0.5.0b1 → python_gmp-0.5.0b2}/.github/workflows/wheels.yml +18 -8
  8. {python_gmp-0.5.0b1 → 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.0b1 → python_gmp-0.5.0b2}/LICENSE +1 -1
  11. {python_gmp-0.5.0b1 → python_gmp-0.5.0b2}/PKG-INFO +25 -34
  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.0b1 → python_gmp-0.5.0b2}/docs/conf.py +1 -1
  17. {python_gmp-0.5.0b1 → python_gmp-0.5.0b2}/fmt.c +25 -21
  18. {python_gmp-0.5.0b1 → python_gmp-0.5.0b2}/gmp.c +733 -477
  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.0b1 → python_gmp-0.5.0b2}/pyproject.toml +13 -16
  22. {python_gmp-0.5.0b1 → 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.0b1 → python_gmp-0.5.0b2}/tests/test_functions.py +7 -15
  27. {python_gmp-0.5.0b1 → python_gmp-0.5.0b2}/tests/test_memory.py +4 -5
  28. {python_gmp-0.5.0b1 → python_gmp-0.5.0b2}/tests/test_mpz.py +95 -61
  29. python_gmp-0.5.0b1/tests/test_utils.py → python_gmp-0.5.0b2/tests/utils.py +47 -42
  30. {python_gmp-0.5.0b1 → python_gmp-0.5.0b2}/utils.c +46 -6
  31. {python_gmp-0.5.0b1 → python_gmp-0.5.0b2}/utils.h +8 -5
  32. python_gmp-0.5.0b1/.github/workflows/ci.yml +0 -53
  33. python_gmp-0.5.0b1/.github/workflows/os.yml +0 -66
  34. python_gmp-0.5.0b1/.readthedocs.yaml +0 -25
  35. python_gmp-0.5.0b1/README.rst +0 -88
  36. python_gmp-0.5.0b1/meson.build +0 -7
  37. python_gmp-0.5.0b1/mpz.h +0 -47
  38. python_gmp-0.5.0b1/scripts/cibw_before_all.sh +0 -52
  39. python_gmp-0.5.0b1/tests/conftest.py +0 -30
  40. python_gmp-0.5.0b1/tests/test_api.py +0 -192
  41. {python_gmp-0.5.0b1 → python_gmp-0.5.0b2}/.clang-format +0 -0
  42. {python_gmp-0.5.0b1 → python_gmp-0.5.0b2}/.github/dependabot.yml +0 -0
  43. {python_gmp-0.5.0b1 → python_gmp-0.5.0b2}/.gitignore +0 -0
  44. {python_gmp-0.5.0b1 → python_gmp-0.5.0b2}/docs/index.rst +0 -0
  45. {python_gmp-0.5.0b1 → python_gmp-0.5.0b2}/scripts/dll-importexport.diff +0 -0
  46. {python_gmp-0.5.0b1 → python_gmp-0.5.0b2}/scripts/fat_build_fix.diff +0 -0
  47. {python_gmp-0.5.0b1 → 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,17 +2,16 @@ 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
17
  - uses: actions/setup-python@v6
@@ -20,14 +19,14 @@ jobs:
20
19
  python-version: ${{ matrix.python-version }}
21
20
  allow-prereleases: true
22
21
  - run: sudo apt-get update
23
- - run: sudo apt-get install lcov
22
+ - run: sudo apt-get install autoconf-archive lcov
24
23
  - name: Setup locales
25
24
  run: |
26
25
  sudo locale-gen ru_RU.UTF-8
27
26
  sudo locale-gen ps_AF.UTF-8
28
27
  - name: Cache GNU GMP builds
29
28
  id: cache-gmp
30
- uses: actions/cache@v4
29
+ uses: actions/cache@v5
31
30
  with:
32
31
  path: .local
33
32
  key: ${{ matrix.os }}-${{ hashFiles('scripts/*') }}
@@ -35,12 +34,12 @@ jobs:
35
34
  if: steps.cache-gmp.outputs.cache-hit != 'true'
36
35
  - run: python -m pip install --upgrade pip
37
36
  - run: |
38
- pip install --verbose .[tests] -Cbuild-dir=build \
39
- -Csetup-args=-Dbuildtype=debug \
40
- -Csetup-args=-Db_coverage=true
37
+ pip install --verbose .[ci] -Cbuild-dir=build \
38
+ -Csetup-args=-Dbuildtype=debug \
39
+ -Csetup-args=-Db_coverage=true
41
40
  env:
42
41
  PKG_CONFIG_PATH: ${{ github.workspace }}/.local/lib/pkgconfig
43
- - run: pytest --hypothesis-profile=default
42
+ - run: pytest
44
43
  env:
45
44
  LD_LIBRARY_PATH: ${{ github.workspace }}/.local/lib
46
45
  - name: Get coverage data
@@ -49,7 +48,7 @@ jobs:
49
48
  lcov --remove coverage.info "*.h" --ignore-errors unused \
50
49
  --output-file coverage.info
51
50
  cp coverage.info build/coverage-${{ matrix.python-version }}.info
52
- - uses: actions/upload-artifact@v5
51
+ - uses: actions/upload-artifact@v6
53
52
  with:
54
53
  name: coverage-${{ matrix.python-version }}
55
54
  path: |
@@ -60,12 +59,12 @@ jobs:
60
59
  needs:
61
60
  - coverage
62
61
  steps:
63
- - uses: actions/checkout@v5
62
+ - uses: actions/checkout@v6
64
63
  with:
65
64
  fetch-depth: 0
66
65
  - run: sudo apt-get update
67
66
  - run: sudo apt-get install lcov diff-cover
68
- - uses: actions/download-artifact@v6
67
+ - uses: actions/download-artifact@v7
69
68
  with:
70
69
  pattern: coverage-*
71
70
  path: build/
@@ -76,7 +75,7 @@ jobs:
76
75
  - run: |
77
76
  diff-cover build/coverage*.info --fail-under=100 \
78
77
  --compare-branch=origin/master
79
- - uses: actions/upload-artifact@v5
78
+ - uses: actions/upload-artifact@v6
80
79
  with:
81
80
  name: coverage
82
81
  path: |
@@ -4,7 +4,7 @@ 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
10
  - uses: actions/setup-python@v6
@@ -6,16 +6,18 @@ 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
12
  - uses: actions/setup-python@v6
13
13
  with:
14
14
  python-version: "3.x"
15
+ - run: sudo apt-get update
16
+ - run: sudo apt-get install autoconf-archive
15
17
  - run: pip install build
16
18
  - name: Cache GNU GMP builds
17
19
  id: cache-gmp
18
- uses: actions/cache@v4
20
+ uses: actions/cache@v5
19
21
  with:
20
22
  path: .local
21
23
  key: ${{ matrix.os }}-${{ hashFiles('scripts/*') }}
@@ -24,7 +26,7 @@ jobs:
24
26
  - run: python -m build -s
25
27
  env:
26
28
  PKG_CONFIG_PATH: ${{ github.workspace }}/.local/lib/pkgconfig
27
- - uses: actions/upload-artifact@v5
29
+ - uses: actions/upload-artifact@v6
28
30
  with:
29
31
  name: python-gmp-sdist
30
32
  path: dist/
@@ -43,7 +45,7 @@ jobs:
43
45
  permissions:
44
46
  id-token: write
45
47
  steps:
46
- - uses: actions/download-artifact@v6
48
+ - uses: actions/download-artifact@v7
47
49
  with:
48
50
  pattern: python-gmp-*
49
51
  path: dist/
@@ -60,12 +62,12 @@ jobs:
60
62
  contents: write
61
63
  id-token: write
62
64
  steps:
63
- - uses: actions/download-artifact@v6
65
+ - uses: actions/download-artifact@v7
64
66
  with:
65
67
  pattern: python-gmp-*
66
68
  path: dist/
67
69
  merge-multiple: true
68
- - uses: sigstore/gh-action-sigstore-python@v3.1.0
70
+ - uses: sigstore/gh-action-sigstore-python@v3.2.0
69
71
  with:
70
72
  inputs: >-
71
73
  ./dist/*.tar.gz
@@ -8,20 +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
- - uses: msys2/setup-msys2@v2.29.0
21
+ - uses: msys2/setup-msys2@v2.30.0
16
22
  name: Setup msys2
17
23
  with:
18
24
  install: >-
19
- mingw-w64-ucrt-x86_64-gcc
25
+ mingw-w64-${{ matrix.menv }}-binutils
26
+ mingw-w64-${{ matrix.menv }}-gcc
27
+ mingw-w64-${{ matrix.menv }}-tools
20
28
  diffutils
21
29
  m4
22
30
  make
23
31
  patch
24
- msystem: ucrt64
32
+ autotools
33
+ autoconf-archive
34
+ msystem: ${{ matrix.msystem }}
25
35
  if: ${{ startsWith(matrix.os, 'windows') }}
26
36
  # Install pkgconfig on Windows from choco rather than from msys and
27
37
  # avoid using the Strawberry one.
@@ -30,10 +40,10 @@ jobs:
30
40
  # We have to set this here rather than in the cibuildwheel config
31
41
  # This is probably something to do with \ vs / in paths...
32
42
  - run: echo "PKG_CONFIG_PATH=${{ github.workspace }}/.local/lib/pkgconfig" >> $env:GITHUB_ENV
33
- if: ${{ startsWith( matrix.os , 'windows' ) }}
43
+ if: ${{ startsWith(matrix.os, 'windows') }}
34
44
  - name: Build wheels
35
- uses: pypa/cibuildwheel@v3.2.1
36
- - uses: actions/upload-artifact@v5
45
+ uses: pypa/cibuildwheel@v3.3.1
46
+ - uses: actions/upload-artifact@v6
37
47
  with:
38
48
  name: wheels-${{ matrix.os }}
39
49
  path: ./wheelhouse/
@@ -42,7 +52,7 @@ jobs:
42
52
  needs: build_wheels
43
53
  steps:
44
54
  - name: Merge Wheels
45
- uses: actions/upload-artifact/merge@v5
55
+ uses: actions/upload-artifact/merge@v6
46
56
  with:
47
57
  name: python-gmp-wheels
48
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.0b1
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,17 +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) via the `ZZ library <https://github.com/diofant/zz>`_.
56
- 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.
57
57
 
58
58
  The gmp can be used as a `gmpy2`_/`python-flint`_ replacement to provide
59
- integer type (`mpz`_), compatible with Python's `int`_. It includes few
60
- functions (`comb`_, `factorial`_, `gcd`_, `isqrt`_, `lcm`_ and `perm`_),
61
- 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>`_.
62
62
 
63
- This module requires Python 3.9 or later versions and has been tested with
64
- 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.
65
65
  Free-threading builds of the CPython are supported.
66
66
 
67
67
  Releases are available in the Python Package Index (PyPI) at
@@ -72,17 +72,16 @@ Motivation
72
72
  ----------
73
73
 
74
74
  The CPython (and most other Python implementations, like PyPy) is optimized to
75
- work with small integers. Algorithms used here for "big enough" integers
76
- usually aren't best known in the field. Fortunately, it's possible to use
77
- bindings (for example, the `gmpy2`_ package) to the GNU Multiple Precision
78
- Arithmetic Library (GMP), which aims to be faster than any other bignum library
79
- for all operand sizes.
80
-
81
- But such extension modules usually rely on default GMP's memory allocation
82
- functions and can't recover from errors such as out of memory. So, it's easy
83
- to crash the Python interpreter during the interactive session. Following
84
- example with the gmpy2 will work if you set address space limit for the Python
85
- 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):
86
85
 
87
86
  .. code:: pycon
88
87
 
@@ -120,19 +119,11 @@ Warning on --disable-alloca configure option
120
119
  --------------------------------------------
121
120
 
122
121
  You should use the GNU GMP library, compiled with the '--disable-alloca'
123
- configure option to prevent using alloca() for temporary workspace allocation
124
- (and use the heap instead), or this module can't prevent a crash in case of a
125
- 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.
126
124
 
127
125
 
128
126
  .. _gmpy2: https://pypi.org/project/gmpy2/
129
127
  .. _python-flint: https://pypi.org/project/python-flint/
130
128
  .. _mpz: https://python-gmp.readthedocs.io/en/latest/#gmp.mpz
131
129
  .. _int: https://docs.python.org/3/library/functions.html#int
132
- .. _factorial: https://python-gmp.readthedocs.io/en/latest/#gmp.factorial
133
- .. _gcd: https://python-gmp.readthedocs.io/en/latest/#gmp.gcd
134
- .. _isqrt: https://python-gmp.readthedocs.io/en/latest/#gmp.isqrt
135
- .. _lcm: https://python-gmp.readthedocs.io/en/latest/#gmp.lcm
136
- .. _comb: https://python-gmp.readthedocs.io/en/latest/#gmp.comb
137
- .. _perm: https://python-gmp.readthedocs.io/en/latest/#gmp.perm
138
- .. _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