python-gmp 0.4.0b4__tar.gz → 0.5.0a1__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.4.0b4 → python_gmp-0.5.0a1}/.github/workflows/ci.yml +1 -0
  2. {python_gmp-0.4.0b4 → python_gmp-0.5.0a1}/.github/workflows/coverage.yml +2 -0
  3. {python_gmp-0.4.0b4 → python_gmp-0.5.0a1}/.github/workflows/linter.yml +3 -0
  4. {python_gmp-0.4.0b4 → python_gmp-0.5.0a1}/.github/workflows/os.yml +3 -0
  5. {python_gmp-0.4.0b4 → python_gmp-0.5.0a1}/.github/workflows/publish.yml +1 -0
  6. {python_gmp-0.4.0b4 → python_gmp-0.5.0a1}/.github/workflows/wheels.yml +4 -1
  7. python_gmp-0.5.0a1/.gitmodules +3 -0
  8. {python_gmp-0.4.0b4 → python_gmp-0.5.0a1}/.readthedocs.yaml +4 -0
  9. {python_gmp-0.4.0b4 → python_gmp-0.5.0a1}/PKG-INFO +2 -2
  10. {python_gmp-0.4.0b4 → python_gmp-0.5.0a1}/gmp.c +267 -8
  11. python_gmp-0.5.0a1/libzz/.gitignore +42 -0
  12. python_gmp-0.5.0a1/libzz/AUTHORS +1 -0
  13. python_gmp-0.5.0a1/libzz/COPYING +674 -0
  14. python_gmp-0.5.0a1/libzz/COPYING.LESSER +165 -0
  15. python_gmp-0.5.0a1/libzz/ChangeLog +0 -0
  16. python_gmp-0.5.0a1/libzz/NEWS +0 -0
  17. python_gmp-0.5.0a1/libzz/README +0 -0
  18. python_gmp-0.5.0a1/libzz/configure.ac +66 -0
  19. python_gmp-0.5.0a1/libzz/makefile.am +12 -0
  20. {python_gmp-0.4.0b4 → python_gmp-0.5.0a1/libzz}/zz.c +50 -84
  21. {python_gmp-0.4.0b4 → python_gmp-0.5.0a1/libzz}/zz.h +2 -2
  22. python_gmp-0.5.0a1/libzz/zz.pc.in +11 -0
  23. {python_gmp-0.4.0b4 → python_gmp-0.5.0a1}/meson.build +2 -2
  24. {python_gmp-0.4.0b4 → python_gmp-0.5.0a1}/mpz.h +8 -1
  25. {python_gmp-0.4.0b4 → python_gmp-0.5.0a1}/pyproject.toml +2 -1
  26. {python_gmp-0.4.0b4 → python_gmp-0.5.0a1}/scripts/cibw_before_all.sh +3 -4
  27. python_gmp-0.5.0a1/scripts/gcc15.diff +29 -0
  28. {python_gmp-0.4.0b4 → python_gmp-0.5.0a1}/tests/test_functions.py +75 -0
  29. {python_gmp-0.4.0b4 → python_gmp-0.5.0a1}/tests/test_mpz.py +4 -0
  30. {python_gmp-0.4.0b4 → python_gmp-0.5.0a1}/utils.h +7 -0
  31. {python_gmp-0.4.0b4 → python_gmp-0.5.0a1}/.clang-format +0 -0
  32. {python_gmp-0.4.0b4 → python_gmp-0.5.0a1}/.github/dependabot.yml +0 -0
  33. {python_gmp-0.4.0b4 → python_gmp-0.5.0a1}/.gitignore +0 -0
  34. {python_gmp-0.4.0b4 → python_gmp-0.5.0a1}/.pre-commit-config.yaml +0 -0
  35. {python_gmp-0.4.0b4 → python_gmp-0.5.0a1}/LICENSE +0 -0
  36. {python_gmp-0.4.0b4 → python_gmp-0.5.0a1}/README.rst +0 -0
  37. {python_gmp-0.4.0b4 → python_gmp-0.5.0a1}/docs/conf.py +0 -0
  38. {python_gmp-0.4.0b4 → python_gmp-0.5.0a1}/docs/index.rst +0 -0
  39. {python_gmp-0.4.0b4 → python_gmp-0.5.0a1}/fmt.c +0 -0
  40. {python_gmp-0.4.0b4 → python_gmp-0.5.0a1}/pythoncapi_compat.h +0 -0
  41. {python_gmp-0.4.0b4 → python_gmp-0.5.0a1}/scripts/dll-importexport.diff +0 -0
  42. {python_gmp-0.4.0b4 → python_gmp-0.5.0a1}/scripts/fat_build_fix.diff +0 -0
  43. {python_gmp-0.4.0b4 → python_gmp-0.5.0a1}/tests/conftest.py +0 -0
  44. {python_gmp-0.4.0b4 → python_gmp-0.5.0a1}/tests/test_api.py +0 -0
  45. {python_gmp-0.4.0b4 → python_gmp-0.5.0a1}/tests/test_memory.py +0 -0
  46. {python_gmp-0.4.0b4 → python_gmp-0.5.0a1}/tests/test_utils.py +0 -0
  47. {python_gmp-0.4.0b4 → python_gmp-0.5.0a1}/utils.c +0 -0
@@ -27,6 +27,7 @@ jobs:
27
27
  - uses: actions/checkout@v4
28
28
  with:
29
29
  fetch-depth: 0
30
+ submodules: true
30
31
  - uses: actions/setup-python@v5
31
32
  with:
32
33
  python-version: ${{ matrix.python-version }}
@@ -16,6 +16,7 @@ jobs:
16
16
  - uses: actions/checkout@v4
17
17
  with:
18
18
  fetch-depth: 0
19
+ submodules: true
19
20
  - uses: actions/setup-python@v5
20
21
  with:
21
22
  python-version: ${{ matrix.python-version }}
@@ -64,6 +65,7 @@ jobs:
64
65
  - uses: actions/checkout@v4
65
66
  with:
66
67
  fetch-depth: 0
68
+ submodules: true
67
69
  - run: sudo apt-get update
68
70
  - run: sudo apt-get install lcov
69
71
  - uses: actions/download-artifact@v4
@@ -6,6 +6,9 @@ jobs:
6
6
  runs-on: ubuntu-24.04
7
7
  steps:
8
8
  - uses: actions/checkout@v4
9
+ with:
10
+ fetch-depth: 0
11
+ submodules: true
9
12
  - uses: actions/setup-python@v5
10
13
  with:
11
14
  python-version: "3.x"
@@ -15,9 +15,12 @@ jobs:
15
15
  - uses: actions/checkout@v4
16
16
  with:
17
17
  fetch-depth: 0
18
+ submodules: true
18
19
  - uses: actions/setup-python@v5
19
20
  with:
20
21
  python-version: "3.x"
22
+ - run: brew install autoconf automake libtool
23
+ if: ${{ startsWith(matrix.os, 'macos') }}
21
24
  - name: Cache GNU GMP builds
22
25
  id: cache-gmp
23
26
  uses: actions/cache@v4
@@ -9,6 +9,7 @@ jobs:
9
9
  - uses: actions/checkout@v4
10
10
  with:
11
11
  fetch-depth: 0
12
+ submodules: true
12
13
  - uses: actions/setup-python@v5
13
14
  with:
14
15
  python-version: "3.x"
@@ -12,7 +12,8 @@ jobs:
12
12
  - uses: actions/checkout@v4
13
13
  with:
14
14
  fetch-depth: 0
15
- - uses: msys2/setup-msys2@v2.27.0
15
+ submodules: true
16
+ - uses: msys2/setup-msys2@v2.28.0
16
17
  name: Setup msys2
17
18
  with:
18
19
  install: >-
@@ -21,6 +22,8 @@ jobs:
21
22
  patch
22
23
  msystem: ucrt64
23
24
  if: ${{ startsWith(matrix.os, 'windows') }}
25
+ - run: brew install autoconf automake libtool
26
+ if: ${{ startsWith(matrix.os, 'macos') }}
24
27
  # Install pkgconfig on Windows from choco rather than from msys and
25
28
  # avoid using the Strawberry one.
26
29
  - run: choco install -y --stoponfirstfailure --checksum 6004DF17818F5A6DBF19CB335CC92702 pkgconfiglite
@@ -0,0 +1,3 @@
1
+ [submodule "libzz"]
2
+ path = libzz
3
+ url = https://github.com/diofant/zz.git
@@ -1,4 +1,8 @@
1
1
  version: 2
2
+ submodules:
3
+ include:
4
+ - libzz
5
+ recursive: true
2
6
  formats:
3
7
  - htmlzip
4
8
  - pdf
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-gmp
3
- Version: 0.4.0b4
3
+ Version: 0.5.0a1
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>
@@ -39,7 +39,7 @@ Requires-Python: >=3.9
39
39
  Provides-Extra: tests
40
40
  Requires-Dist: pytest; extra == "tests"
41
41
  Requires-Dist: hypothesis; extra == "tests"
42
- Requires-Dist: mpmath>=1.4.0a6; extra == "tests"
42
+ Requires-Dist: mpmath>=1.4.0a7; extra == "tests"
43
43
  Provides-Extra: docs
44
44
  Requires-Dist: sphinx>=8.2; extra == "docs"
45
45
  Provides-Extra: develop
@@ -1713,7 +1713,7 @@ gmp_gcdext(PyObject *Py_UNUSED(module), PyObject *const *args,
1713
1713
  Py_XDECREF(x);
1714
1714
  Py_XDECREF(y);
1715
1715
  if (ret == ZZ_MEM) {
1716
- PyErr_NoMemory(); /* LCOV_EXCL_LINE */
1716
+ return PyErr_NoMemory(); /* LCOV_EXCL_LINE */
1717
1717
  }
1718
1718
  PyObject *tup = PyTuple_Pack(3, g, s, t);
1719
1719
 
@@ -1730,6 +1730,37 @@ end:
1730
1730
  return NULL;
1731
1731
  }
1732
1732
 
1733
+ static PyObject *
1734
+ gmp_lcm(PyObject *Py_UNUSED(module), PyObject *const *args, Py_ssize_t nargs)
1735
+ {
1736
+ MPZ_Object *res = MPZ_new(0);
1737
+
1738
+ if (!res || zz_from_i64(1, &res->z)) {
1739
+ return PyErr_NoMemory(); /* LCOV_EXCL_LINE */
1740
+ }
1741
+ for (Py_ssize_t i = 0; i < nargs; i++) {
1742
+ MPZ_Object *arg;
1743
+
1744
+ CHECK_OP_INT(arg, args[i]);
1745
+ if (zz_cmp_i32(&res->z, 0) == ZZ_EQ) {
1746
+ Py_DECREF(arg);
1747
+ continue;
1748
+ }
1749
+ if (zz_lcm(&res->z, &arg->z, &res->z)) {
1750
+ /* LCOV_EXCL_START */
1751
+ Py_DECREF(res);
1752
+ Py_DECREF(arg);
1753
+ return PyErr_NoMemory();
1754
+ /* LCOV_EXCL_STOP */
1755
+ }
1756
+ Py_DECREF(arg);
1757
+ }
1758
+ return (PyObject *)res;
1759
+ end:
1760
+ Py_DECREF(res);
1761
+ return NULL;
1762
+ }
1763
+
1733
1764
  static PyObject *
1734
1765
  gmp_isqrt(PyObject *Py_UNUSED(module), PyObject *arg)
1735
1766
  {
@@ -1834,6 +1865,118 @@ MAKE_MPZ_UI_FUN(fac)
1834
1865
  MAKE_MPZ_UI_FUN(fac2)
1835
1866
  MAKE_MPZ_UI_FUN(fib)
1836
1867
 
1868
+ static PyObject *
1869
+ gmp_comb(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
1870
+ {
1871
+ if (nargs != 2) {
1872
+ PyErr_SetString(PyExc_TypeError, "two arguments required");
1873
+ return NULL;
1874
+ }
1875
+
1876
+ MPZ_Object *x, *y, *res = MPZ_new(0);
1877
+
1878
+ if (!res) {
1879
+ return NULL; /* LCOV_EXCL_LINE */
1880
+ }
1881
+ CHECK_OP_INT(x, args[0]);
1882
+ CHECK_OP_INT(y, args[1]);
1883
+ if (zz_isneg(&x->z) || zz_isneg(&y->z)) {
1884
+ PyErr_SetString(PyExc_ValueError,
1885
+ "comb() not defined for negative values");
1886
+ goto err;
1887
+ }
1888
+
1889
+ int64_t n, k;
1890
+
1891
+ if ((zz_to_i64(&x->z, &n) || n > ULONG_MAX)
1892
+ || (zz_to_i64(&y->z, &k) || k > ULONG_MAX))
1893
+ {
1894
+ PyErr_Format(PyExc_OverflowError,
1895
+ "comb() arguments should not exceed %ld",
1896
+ ULONG_MAX);
1897
+ goto err;
1898
+ }
1899
+ Py_XDECREF(x);
1900
+ Py_XDECREF(y);
1901
+ if (zz_bin((uint64_t)n, (uint64_t)k, &res->z)) {
1902
+ /* LCOV_EXCL_START */
1903
+ PyErr_NoMemory();
1904
+ goto err;
1905
+ /* LCOV_EXCL_STOP */
1906
+ }
1907
+ return (PyObject *)res;
1908
+ err:
1909
+ end:
1910
+ Py_DECREF(res);
1911
+ return NULL;
1912
+ }
1913
+
1914
+ static PyObject *
1915
+ gmp_perm(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
1916
+ {
1917
+ if (nargs > 2 || nargs < 1) {
1918
+ PyErr_SetString(PyExc_TypeError, "one or two arguments required");
1919
+ return NULL;
1920
+ }
1921
+ if (nargs == 1) {
1922
+ return gmp_fac(self, args[0]);
1923
+ }
1924
+
1925
+ MPZ_Object *x, *y, *res = MPZ_new(0);
1926
+
1927
+ if (!res) {
1928
+ return NULL; /* LCOV_EXCL_LINE */
1929
+ }
1930
+ CHECK_OP_INT(x, args[0]);
1931
+ CHECK_OP_INT(y, args[1]);
1932
+ if (zz_isneg(&x->z) || zz_isneg(&y->z)) {
1933
+ PyErr_SetString(PyExc_ValueError,
1934
+ "perm() not defined for negative values");
1935
+ goto err;
1936
+ }
1937
+
1938
+ int64_t n, k;
1939
+
1940
+ if ((zz_to_i64(&x->z, &n) || n > ULONG_MAX)
1941
+ || (zz_to_i64(&y->z, &k) || k > ULONG_MAX))
1942
+ {
1943
+ PyErr_Format(PyExc_OverflowError,
1944
+ "perm() arguments should not exceed %ld",
1945
+ ULONG_MAX);
1946
+ goto err;
1947
+ }
1948
+ Py_XDECREF(x);
1949
+ Py_XDECREF(y);
1950
+ if (k > n) {
1951
+ return (PyObject *)res;
1952
+ }
1953
+
1954
+ MPZ_Object *den = MPZ_new(0);
1955
+
1956
+ if (!den) {
1957
+ /* LCOV_EXCL_START */
1958
+ PyErr_NoMemory();
1959
+ goto err;
1960
+ /* LCOV_EXCL_STOP */
1961
+ }
1962
+ if (zz_fac((uint64_t)n, &res->z)
1963
+ || zz_fac((uint64_t)(n-k), &den->z)
1964
+ || zz_div(&res->z, &den->z, ZZ_RNDD, &res->z, NULL))
1965
+ {
1966
+ /* LCOV_EXCL_START */
1967
+ Py_DECREF(den);
1968
+ PyErr_NoMemory();
1969
+ goto err;
1970
+ /* LCOV_EXCL_STOP */
1971
+ }
1972
+ Py_DECREF(den);
1973
+ return (PyObject *)res;
1974
+ err:
1975
+ end:
1976
+ Py_DECREF(res);
1977
+ return NULL;
1978
+ }
1979
+
1837
1980
  static zz_rnd
1838
1981
  get_round_mode(PyObject *rndstr)
1839
1982
  {
@@ -1868,6 +2011,100 @@ invalid:
1868
2011
  return rnd;
1869
2012
  }
1870
2013
 
2014
+ static zz_err
2015
+ zz_mpmath_normalize(zz_bitcnt_t prec, zz_rnd rnd, bool *negative,
2016
+ zz_t *man, zz_t *exp, zz_bitcnt_t *bc)
2017
+ {
2018
+ /* If the mantissa is 0, return the normalized representation. */
2019
+ if (zz_iszero(man)) {
2020
+ *negative = false;
2021
+ *bc = 0;
2022
+ return zz_from_i32(0, exp);
2023
+ }
2024
+ /* if size <= prec and the number is odd return it */
2025
+ if (*bc <= prec && zz_isodd(man)) {
2026
+ return ZZ_OK;
2027
+ }
2028
+ if (*bc > prec) {
2029
+ zz_bitcnt_t shift = *bc - prec;
2030
+
2031
+ do_rnd:
2032
+ switch (rnd) {
2033
+ case ZZ_RNDD:
2034
+ rnd = *negative ? ZZ_RNDA : ZZ_RNDZ;
2035
+ goto do_rnd;
2036
+ case ZZ_RNDU:
2037
+ rnd = *negative ? ZZ_RNDZ : ZZ_RNDA;
2038
+ goto do_rnd;
2039
+ case ZZ_RNDZ:
2040
+ zz_quo_2exp(man, shift, man);
2041
+ break;
2042
+ case ZZ_RNDA:
2043
+ zz_neg(man, man);
2044
+ zz_quo_2exp(man, shift, man);
2045
+ zz_abs(man, man);
2046
+ break;
2047
+ case ZZ_RNDN:
2048
+ default:
2049
+ {
2050
+ bool t = zz_lsbpos(man) + 2 <= shift;
2051
+
2052
+ if (zz_quo_2exp(man, shift - 1, man)) {
2053
+ return ZZ_MEM; /* LCOV_EXCL_LINE */
2054
+ }
2055
+ t = zz_isodd(man) && (man->digits[0]&2 || t);
2056
+ if (zz_quo_2exp(man, 1, man)) {
2057
+ return ZZ_MEM; /* LCOV_EXCL_LINE */
2058
+ }
2059
+ if (t && zz_add_i32(man, 1, man)) {
2060
+ return ZZ_MEM; /* LCOV_EXCL_LINE */
2061
+ }
2062
+ }
2063
+ }
2064
+
2065
+ zz_t tmp;
2066
+
2067
+ if (zz_init(&tmp) || shift > INT64_MAX
2068
+ || zz_from_i64((int64_t)shift, &tmp)
2069
+ || zz_add(exp, &tmp, exp))
2070
+ {
2071
+ /* LCOV_EXCL_START */
2072
+ zz_clear(&tmp);
2073
+ return ZZ_MEM;
2074
+ /* LCOV_EXCL_STOP */
2075
+ }
2076
+ zz_clear(&tmp);
2077
+ *bc = prec;
2078
+ }
2079
+
2080
+ zz_bitcnt_t zbits = 0;
2081
+
2082
+ /* Strip trailing 0 bits. */
2083
+ if (!zz_iszero(man) && (zbits = zz_lsbpos(man))) {
2084
+ if (zz_quo_2exp(man, zbits, man)) {
2085
+ return ZZ_MEM; /* LCOV_EXCL_LINE */
2086
+ }
2087
+ }
2088
+
2089
+ zz_t tmp;
2090
+
2091
+ if (zz_init(&tmp) || zbits > INT64_MAX
2092
+ || zz_from_i64((int64_t)zbits, &tmp)
2093
+ || zz_add(exp, &tmp, exp))
2094
+ {
2095
+ /* LCOV_EXCL_START */
2096
+ zz_clear(&tmp);
2097
+ return ZZ_MEM;
2098
+ /* LCOV_EXCL_STOP */
2099
+ }
2100
+ zz_clear(&tmp);
2101
+ *bc -= zbits;
2102
+ /* Check if one less than a power of 2 was rounded up. */
2103
+ if (zz_cmp_i32(man, 1) == ZZ_EQ) {
2104
+ *bc = 1;
2105
+ }
2106
+ return ZZ_OK;
2107
+ }
1871
2108
  static PyObject *
1872
2109
  gmp__mpmath_normalize(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
1873
2110
  {
@@ -1898,8 +2135,8 @@ gmp__mpmath_normalize(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
1898
2135
  MPZ_Object *man = (MPZ_Object *)plus(args[1]);
1899
2136
  MPZ_Object *exp = MPZ_from_int(args[2]);
1900
2137
 
1901
- if (!exp || !man || _zz_mpmath_normalize(prec, rnd, &negative,
1902
- &man->z, &exp->z, &bc))
2138
+ if (!exp || !man || zz_mpmath_normalize(prec, rnd, &negative,
2139
+ &man->z, &exp->z, &bc))
1903
2140
  {
1904
2141
  /* LCOV_EXCL_START */
1905
2142
  Py_XDECREF(man);
@@ -1926,13 +2163,24 @@ gmp__mpmath_create(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
1926
2163
  if (nargs < 2 || nargs > 4) {
1927
2164
  PyErr_Format(PyExc_TypeError,
1928
2165
  "_mpmath_create() takes from 2 to 4 arguments");
1929
- end:
1930
2166
  return NULL;
1931
2167
  }
1932
2168
 
1933
2169
  MPZ_Object *man;
1934
2170
 
1935
- CHECK_OP_INT(man, args[0]);
2171
+ if (MPZ_Check(args[0])) {
2172
+ man = (MPZ_Object *)plus(args[0]);
2173
+ }
2174
+ else if (PyLong_Check(args[0])) {
2175
+ man = MPZ_from_int(args[0]);
2176
+ if (!man) {
2177
+ return NULL; /* LCOV_EXCL_LINE */
2178
+ }
2179
+ }
2180
+ else {
2181
+ PyErr_Format(PyExc_TypeError, "_mpmath_create() expects an integer");
2182
+ return NULL;
2183
+ }
1936
2184
  if (!PyLong_Check(args[1])) {
1937
2185
  Py_DECREF(man);
1938
2186
  PyErr_Format(PyExc_TypeError,
@@ -1970,8 +2218,8 @@ end:
1970
2218
 
1971
2219
  MPZ_Object *exp = MPZ_from_int(args[1]);
1972
2220
 
1973
- if (!exp || _zz_mpmath_normalize(prec, rnd, &negative,
1974
- &man->z, &exp->z, &bc))
2221
+ if (!exp || zz_mpmath_normalize(prec, rnd, &negative,
2222
+ &man->z, &exp->z, &bc))
1975
2223
  {
1976
2224
  /* LCOV_EXCL_START */
1977
2225
  Py_DECREF(man);
@@ -2014,6 +2262,9 @@ static PyMethodDef gmp_functions[] = {
2014
2262
  {"gcdext", (PyCFunction)gmp_gcdext, METH_FASTCALL,
2015
2263
  ("gcdext($module, x, y, /)\n--\n\n"
2016
2264
  "Compute extended GCD.")},
2265
+ {"lcm", (PyCFunction)gmp_lcm, METH_FASTCALL,
2266
+ ("lcm($module, /, *integers)\n--\n\n"
2267
+ "Least Common Multiple.")},
2017
2268
  {"isqrt", gmp_isqrt, METH_O,
2018
2269
  ("isqrt($module, n, /)\n--\n\n"
2019
2270
  "Return the integer part of the square root of n.")},
@@ -2029,6 +2280,13 @@ static PyMethodDef gmp_functions[] = {
2029
2280
  {"fib", gmp_fib, METH_O,
2030
2281
  ("fib($module, n, /)\n--\n\n"
2031
2282
  "Return the n-th Fibonacci number.")},
2283
+ {"comb", (PyCFunction)gmp_comb, METH_FASTCALL,
2284
+ ("comb($module, n, k, /)\n--\n\nNumber of ways to choose k"
2285
+ " items from n items without repetition and order.\n\n"
2286
+ "Also called the binomial coefficient.")},
2287
+ {"perm", (PyCFunction)gmp_perm, METH_FASTCALL,
2288
+ ("perm($module, n, k=None, /)\n--\n\nNumber of ways to choose k"
2289
+ " items from n items without repetition and with order.")},
2032
2290
  {"_mpmath_normalize", (PyCFunction)gmp__mpmath_normalize, METH_FASTCALL,
2033
2291
  NULL},
2034
2292
  {"_mpmath_create", (PyCFunction)gmp__mpmath_create, METH_FASTCALL, NULL},
@@ -2120,7 +2378,8 @@ gmp_exec(PyObject *m)
2120
2378
  const char *str = ("import numbers, importlib.metadata as imp\n"
2121
2379
  "numbers.Integral.register(gmp.mpz)\n"
2122
2380
  "gmp.fac = gmp.factorial\n"
2123
- "gmp.__all__ = ['factorial', 'gcd', 'isqrt', 'mpz']\n"
2381
+ "gmp.__all__ = ['comb', 'factorial', 'gcd', 'isqrt',\n"
2382
+ " 'lcm', 'mpz', 'perm']\n"
2124
2383
  "gmp.__version__ = imp.version('python-gmp')\n");
2125
2384
 
2126
2385
  PyObject *res = PyRun_String(str, Py_file_input, ns, ns);
@@ -0,0 +1,42 @@
1
+ .libs
2
+ .*.swp
3
+ [Mm]akefile
4
+ [Mm]akefile.in
5
+ aclocal.m4
6
+ *.o
7
+ *.lo
8
+ *.la
9
+ # doc's stuff:
10
+ *.info
11
+ *.aux
12
+ *.cp
13
+ *.fn
14
+ *.fns
15
+ *.ky
16
+ *.log
17
+ *.pdf
18
+ *.ps
19
+ *.pg
20
+ *.toc
21
+ *.tp
22
+ *.vr
23
+ #
24
+ config.*
25
+ configure
26
+ stamp-h1
27
+ test
28
+ texinfo.tex
29
+ INSTALL
30
+ install-sh
31
+ libtool
32
+ ltmain.sh
33
+ mdate-sh
34
+ missing
35
+ autom4te.cache/
36
+ *.dat
37
+ compile
38
+ test-driver
39
+ *~
40
+ a.out
41
+ m4/
42
+ *.pc
@@ -0,0 +1 @@
1
+ Sergey B Kirpichev (skirpichev@gmail.com)