Skip to content

Commit

Permalink
Merge pull request #444 from skirpichev/misc
Browse files Browse the repository at this point in the history
Misc fixes
  • Loading branch information
casevh authored Oct 28, 2023
2 parents a751ea9 + b56dfe3 commit 1253106
Show file tree
Hide file tree
Showing 22 changed files with 95 additions and 97 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/pip_install_gmpy2.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
- run: pip --verbose install --editable .[tests]
- run: python test/runtests.py
- run: PYTHONPATH=`pwd`/gmpy2 python test_cython/runtests.py
if: ${{ matrix.python-version == '3.11' }}
if: ${{ matrix.python-version != '3.13' }}

linux:
strategy:
Expand Down
22 changes: 21 additions & 1 deletion docs/index.rst
Original file line number Diff line number Diff line change
@@ -1,10 +1,30 @@
Welcome to gmpy2's documentation!
=================================

gmpy2 is a C-coded Python extension module that supports multiple-precision
arithmetic. It is the successor to the original gmpy module (supported only
the GMP library). gmpy2 adds support for the MPFR (correctly rounded real
floating-point arithmetic) and MPC (correctly rounded complex floating-point
arithmetic) libraries.

The following libraries are supported:

* GMP for integer and rational arithmetic (https://gmplib.org)
* MPFR (https://www.mpfr.org)
* MPC (https://www.multiprecision.org/mpc/)
* Generalized Lucas sequences and primality tests are based on the following
code:

* mpz_lucas: https://sourceforge.net/projects/mpzlucas/
* mpz_prp: https://sourceforge.net/projects/mpzprp/

Contents
--------

.. toctree::
:maxdepth: 2

intro
install
overview
mpz
advmpz
Expand Down
11 changes: 11 additions & 0 deletions docs/install.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
Installation
============

gmpy2 requires CPython 3.7 or above. Pre-compiled binary wheels are available
on PyPI. You can install latest release with pip::

pip install gmpy2

or some specific version with::

pip install gmpy2==2.1.5
38 changes: 0 additions & 38 deletions docs/intro.rst

This file was deleted.

2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ content-type = 'text/x-rst'

[project.optional-dependencies]
docs = ['sphinx>=4', 'sphinx-rtd-theme>=1']
tests = ['pytest', 'hypothesis', 'cython', 'mpmath']
tests = ['pytest', 'hypothesis', 'cython', 'mpmath', 'setuptools']

[project.urls]
Homepage = 'https://github.com/aleaxit/gmpy'
Expand Down
6 changes: 3 additions & 3 deletions src/gmpy2.c
Original file line number Diff line number Diff line change
Expand Up @@ -704,10 +704,10 @@ static PyMethodDef Pygmpy_methods [] =
{ "bit_flip", GMPy_MPZ_bit_flip_function, METH_VARARGS, doc_bit_flip_function },
{ "bit_length", GMPy_MPZ_bit_length_function, METH_O, doc_bit_length_function },
{ "bit_mask", GMPy_MPZ_bit_mask, METH_O, doc_bit_mask },
{ "bit_scan0", GMPy_MPZ_bit_scan0_function, METH_VARARGS, doc_bit_scan0_function },
{ "bit_scan1", GMPy_MPZ_bit_scan1_function, METH_VARARGS, doc_bit_scan1_function },
{ "bit_scan0", (PyCFunction)GMPy_MPZ_bit_scan0_function, METH_FASTCALL, doc_bit_scan0_function },
{ "bit_scan1", (PyCFunction)GMPy_MPZ_bit_scan1_function, METH_FASTCALL, doc_bit_scan1_function },
{ "bit_set", GMPy_MPZ_bit_set_function, METH_VARARGS, doc_bit_set_function },
{ "bit_test", GMPy_MPZ_bit_test_function, METH_VARARGS, doc_bit_test_function },
{ "bit_test", (PyCFunction)GMPy_MPZ_bit_test_function, METH_FASTCALL, doc_bit_test_function },
{ "bincoef", GMPy_MPZ_Function_Bincoef, METH_VARARGS, GMPy_doc_mpz_function_bincoef },
{ "cmp", GMPy_MPANY_cmp, METH_VARARGS, GMPy_doc_mpany_cmp },
{ "cmp_abs", GMPy_MPANY_cmp_abs, METH_VARARGS, GMPy_doc_mpany_cmp_abs },
Expand Down
2 changes: 1 addition & 1 deletion src/gmpy2_context.c
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,7 @@ GMPy_CTXT_Repr_Slot(CTXT_Object *self)
static PyObject *
GMPy_CTXT_Manager_Repr_Slot(CTXT_Manager_Object *self)
{
return Py_BuildValue("s", "<gmpy2.ContextManagerObject>");
return PyUnicode_FromString("<gmpy2.ContextManagerObject>");
}

PyDoc_STRVAR(GMPy_doc_get_context,
Expand Down
2 changes: 1 addition & 1 deletion src/gmpy2_convert.c
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ mpz_ascii(mpz_t z, int base, int option, int which)
*(p++) = ')';
*(p++) = '\00';

result = Py_BuildValue("s", buffer);
result = PyUnicode_FromString(buffer);
if (negative == 1) {
mpz_neg(z, z);
}
Expand Down
4 changes: 2 additions & 2 deletions src/gmpy2_convert_mpc.c
Original file line number Diff line number Diff line change
Expand Up @@ -605,7 +605,7 @@ GMPy_MPC_Str_Slot(MPC_Object *self)

sprintf(fmtstr, "{0:.%ld.%ldg}", rprec, iprec);

temp = Py_BuildValue("s", fmtstr);
temp = PyUnicode_FromString(fmtstr);
if (!temp)
return NULL;
result = PyObject_CallMethod(temp, "format", "O", self);
Expand All @@ -631,7 +631,7 @@ GMPy_MPC_Repr_Slot(MPC_Object *self)
else
sprintf(fmtstr, "mpc('{0:.%ld.%ldg}')", rprec, iprec);

temp = Py_BuildValue("s", fmtstr);
temp = PyUnicode_FromString(fmtstr);
if (!temp)
return NULL;
result = PyObject_CallMethod(temp, "format", "O", self);
Expand Down
4 changes: 2 additions & 2 deletions src/gmpy2_convert_mpfr.c
Original file line number Diff line number Diff line change
Expand Up @@ -888,7 +888,7 @@ GMPy_MPFR_Str_Slot(MPFR_Object *self)

sprintf(fmtstr, "{0:.%ldg}", precision);

temp = Py_BuildValue("s", fmtstr);
temp = PyUnicode_FromString(fmtstr);
if (!temp)
return NULL;
result = PyObject_CallMethod(temp, "format", "O", self);
Expand All @@ -911,7 +911,7 @@ GMPy_MPFR_Repr_Slot(MPFR_Object *self)
else
sprintf(fmtstr, "mpfr('{0:.%ldg}')", precision);

temp = Py_BuildValue("s", fmtstr);
temp = PyUnicode_FromString(fmtstr);
if (!temp)
return NULL;
result = PyObject_CallMethod(temp, "format", "O", self);
Expand Down
6 changes: 3 additions & 3 deletions src/gmpy2_format.c
Original file line number Diff line number Diff line change
Expand Up @@ -332,11 +332,11 @@ GMPy_MPFR_Format(PyObject *self, PyObject *args)
strcat(newbuf, buffer);
strcat(newbuf, ".0");
mpfr_free_str(buffer);
mpfrstr = Py_BuildValue("s", newbuf);
mpfrstr = PyUnicode_FromString(newbuf);
free(newbuf);
}
else {
mpfrstr = Py_BuildValue("s", buffer);
mpfrstr = PyUnicode_FromString(buffer);
mpfr_free_str(buffer);
}
if (!mpfrstr) {
Expand Down Expand Up @@ -618,7 +618,7 @@ GMPy_MPC_Format(PyObject *self, PyObject *args)
mpfr_free_str(realbuf);
mpfr_free_str(imagbuf);

tempstr = Py_BuildValue("s", tempbuf);
tempstr = PyUnicode_FromString(tempbuf);
if (!tempstr) {
free(tempbuf);
return NULL;
Expand Down
6 changes: 3 additions & 3 deletions src/gmpy2_misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ PyDoc_STRVAR(GMPy_doc_license,
static PyObject *
GMPy_get_license(PyObject *self, PyObject *args)
{
return Py_BuildValue("s", gmpy_license);
return PyUnicode_FromString(gmpy_license);
}

PyDoc_STRVAR(GMPy_doc_version,
Expand All @@ -43,7 +43,7 @@ PyDoc_STRVAR(GMPy_doc_version,
static PyObject *
GMPy_get_version(PyObject *self, PyObject *args)
{
return Py_BuildValue("s", gmpy_version);
return PyUnicode_FromString(gmpy_version);
}

PyDoc_STRVAR(GMPy_doc_mp_version,
Expand Down Expand Up @@ -83,5 +83,5 @@ Return the number of bits per limb.");
static PyObject *
GMPy_get_mp_limbsize(PyObject *self, PyObject *args)
{
return Py_BuildValue("i", mp_bits_per_limb);
return PyLong_FromLong(mp_bits_per_limb);
}
6 changes: 3 additions & 3 deletions src/gmpy2_mpz.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,13 +95,13 @@ static PyMethodDef GMPy_MPZ_methods[] = {
{ "bit_count", GMPy_MPZ_bit_count_method, METH_NOARGS, doc_bit_count_method },
{ "bit_flip", GMPy_MPZ_bit_flip_method, METH_O, doc_bit_flip_method },
{ "bit_length", GMPy_MPZ_bit_length_method, METH_NOARGS, doc_bit_length_method },
{ "bit_scan0", GMPy_MPZ_bit_scan0_method, METH_VARARGS, doc_bit_scan0_method },
{ "bit_scan1", GMPy_MPZ_bit_scan1_method, METH_VARARGS, doc_bit_scan1_method },
{ "bit_scan0", (PyCFunction)GMPy_MPZ_bit_scan0_method, METH_FASTCALL, doc_bit_scan0_method },
{ "bit_scan1", (PyCFunction)GMPy_MPZ_bit_scan1_method, METH_FASTCALL, doc_bit_scan1_method },
{ "bit_set", GMPy_MPZ_bit_set_method, METH_O, doc_bit_set_method },
{ "bit_test", GMPy_MPZ_bit_test_method, METH_O, doc_bit_test_method },
{ "conjugate", GMPy_MP_Method_Conjugate, METH_NOARGS, GMPy_doc_mp_method_conjugate },
{ "digits", GMPy_MPZ_Digits_Method, METH_VARARGS, GMPy_doc_mpz_digits_method },
{ "is_congruent", GMPy_MPZ_Method_IsCongruent, METH_VARARGS, GMPy_doc_mpz_method_is_congruent },
{ "is_congruent", (PyCFunction)GMPy_MPZ_Method_IsCongruent, METH_FASTCALL, GMPy_doc_mpz_method_is_congruent },
{ "is_divisible", GMPy_MPZ_Method_IsDivisible, METH_O, GMPy_doc_mpz_method_is_divisible },
{ "is_even", GMPy_MPZ_Method_IsEven, METH_NOARGS, GMPy_doc_mpz_method_is_even },
{ "is_odd", GMPy_MPZ_Method_IsOdd, METH_NOARGS, GMPy_doc_mpz_method_is_odd },
Expand Down
45 changes: 25 additions & 20 deletions src/gmpy2_mpz_bitops.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,12 +96,13 @@ PyDoc_STRVAR(doc_bit_scan0_method,
"format), then `None` is returned.");

static PyObject *
GMPy_MPZ_bit_scan0_method(PyObject *self, PyObject *args)
GMPy_MPZ_bit_scan0_method(PyObject *self, PyObject *const *args,
Py_ssize_t nargs)
{
mp_bitcnt_t index, starting_bit = 0;

if (PyTuple_GET_SIZE(args) == 1) {
starting_bit = GMPy_Integer_AsMpBitCnt(PyTuple_GET_ITEM(args, 0));
if (nargs == 1) {
starting_bit = GMPy_Integer_AsMpBitCnt(args[0]);
if (starting_bit == (mp_bitcnt_t)(-1) && PyErr_Occurred()) {
return NULL;
}
Expand All @@ -125,21 +126,22 @@ PyDoc_STRVAR(doc_bit_scan0_function,
"format), then `None` is returned.");

static PyObject *
GMPy_MPZ_bit_scan0_function(PyObject *self, PyObject *args)
GMPy_MPZ_bit_scan0_function(PyObject *self, PyObject *const *args,
Py_ssize_t nargs)
{
mp_bitcnt_t index, starting_bit = 0;
MPZ_Object *tempx = NULL;

if (PyTuple_GET_SIZE(args) == 0 || PyTuple_GET_SIZE(args) > 2) {
if (nargs == 0 || nargs > 2) {
goto err;
}

if (!(tempx = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL))) {
if (!(tempx = GMPy_MPZ_From_Integer(args[0], NULL))) {
goto err;
}

if (PyTuple_GET_SIZE(args) == 2) {
starting_bit = GMPy_Integer_AsMpBitCnt(PyTuple_GET_ITEM(args, 1));
if (nargs == 2) {
starting_bit = GMPy_Integer_AsMpBitCnt(args[1]);
if (starting_bit == (mp_bitcnt_t)(-1) && PyErr_Occurred()) {
goto err_index;
}
Expand Down Expand Up @@ -170,12 +172,13 @@ PyDoc_STRVAR(doc_bit_scan1_method,
"format), then `None` is returned.");

static PyObject *
GMPy_MPZ_bit_scan1_method(PyObject *self, PyObject *args)
GMPy_MPZ_bit_scan1_method(PyObject *self, PyObject *const *args,
Py_ssize_t nargs)
{
mp_bitcnt_t index, starting_bit = 0;

if (PyTuple_GET_SIZE(args) == 1) {
starting_bit = GMPy_Integer_AsMpBitCnt(PyTuple_GET_ITEM(args, 0));
if (nargs == 1) {
starting_bit = GMPy_Integer_AsMpBitCnt(args[0]);
if (starting_bit == (mp_bitcnt_t)(-1) && PyErr_Occurred()) {
return NULL;
}
Expand All @@ -199,21 +202,22 @@ PyDoc_STRVAR(doc_bit_scan1_function,
"format), then `None` is returned.");

static PyObject *
GMPy_MPZ_bit_scan1_function(PyObject *self, PyObject *args)
GMPy_MPZ_bit_scan1_function(PyObject *self, PyObject *const *args,
Py_ssize_t nargs)
{
mp_bitcnt_t index, starting_bit = 0;
MPZ_Object *tempx = NULL;

if (PyTuple_GET_SIZE(args) == 0 || PyTuple_GET_SIZE(args) > 2) {
if (nargs == 0 || nargs > 2) {
goto err;
}

if (!(tempx = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL))) {
if (!(tempx = GMPy_MPZ_From_Integer(args[0], NULL))) {
goto err;
}

if (PyTuple_GET_SIZE(args) == 2) {
starting_bit = GMPy_Integer_AsMpBitCnt(PyTuple_GET_ITEM(args, 1));
if (nargs == 2) {
starting_bit = GMPy_Integer_AsMpBitCnt(args[1]);
if (starting_bit == (mp_bitcnt_t)(-1) && PyErr_Occurred()) {
goto err_index;
}
Expand Down Expand Up @@ -242,21 +246,22 @@ PyDoc_STRVAR(doc_bit_test_function,
"Return the value of the n-th bit of x.");

static PyObject *
GMPy_MPZ_bit_test_function(PyObject *self, PyObject *args)
GMPy_MPZ_bit_test_function(PyObject *self, PyObject *const *args,
Py_ssize_t nargs)
{
mp_bitcnt_t bit_index;
int temp;
MPZ_Object *tempx = NULL;

if (PyTuple_GET_SIZE(args) != 2) {
if (nargs != 2) {
goto err;
}

if (!(tempx = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL))) {
if (!(tempx = GMPy_MPZ_From_Integer(args[0], NULL))) {
goto err;
}

bit_index = GMPy_Integer_AsMpBitCnt(PyTuple_GET_ITEM(args, 1));
bit_index = GMPy_Integer_AsMpBitCnt(args[1]);
if (bit_index == (mp_bitcnt_t)(-1) && PyErr_Occurred()) {
goto err_index;
}
Expand Down
10 changes: 5 additions & 5 deletions src/gmpy2_mpz_bitops.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,12 @@ extern "C" {
static PyObject * GMPy_MPZ_bit_length_function(PyObject *self, PyObject *other);
static PyObject * GMPy_MPZ_bit_length_method(PyObject *self, PyObject *other);
static PyObject * GMPy_MPZ_bit_mask(PyObject *self, PyObject *other);
static PyObject * GMPy_MPZ_bit_scan0_function(PyObject *self, PyObject *args);
static PyObject * GMPy_MPZ_bit_scan0_method(PyObject *self, PyObject *args);
static PyObject * GMPy_MPZ_bit_scan1_function(PyObject *self, PyObject *args);
static PyObject * GMPy_MPZ_bit_scan1_method(PyObject *self, PyObject *args);
static PyObject * GMPy_MPZ_bit_scan0_function(PyObject *self, PyObject *const *args, Py_ssize_t nargs);
static PyObject * GMPy_MPZ_bit_scan0_method(PyObject *self, PyObject *const *args, Py_ssize_t nargs);
static PyObject * GMPy_MPZ_bit_scan1_function(PyObject *self, PyObject *const *args, Py_ssize_t nargs);
static PyObject * GMPy_MPZ_bit_scan1_method(PyObject *self, PyObject *const *args, Py_ssize_t nargs);

static PyObject * GMPy_MPZ_bit_test_function(PyObject *self, PyObject *args);
static PyObject * GMPy_MPZ_bit_test_function(PyObject *self, PyObject *const *args, Py_ssize_t nargs);
static PyObject * GMPy_MPZ_bit_test_method(PyObject *self, PyObject *other);
static PyObject * GMPy_MPZ_bit_clear_function(PyObject *self, PyObject *args);
static PyObject * GMPy_MPZ_bit_clear_method(PyObject *self, PyObject *other);
Expand Down
9 changes: 5 additions & 4 deletions src/gmpy2_mpz_misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1227,18 +1227,19 @@ PyDoc_STRVAR(GMPy_doc_mpz_method_is_congruent,
"Returns `True` if x is congruent to y modulo m, else return `False`.");

static PyObject *
GMPy_MPZ_Method_IsCongruent(PyObject *self, PyObject *args)
GMPy_MPZ_Method_IsCongruent(PyObject *self, PyObject *const *args,
Py_ssize_t nargs)
{
int res;
MPZ_Object *tempy = NULL, *tempm = NULL;

if (PyTuple_GET_SIZE(args) != 2) {
if (nargs != 2) {
TYPE_ERROR("is_congruent() requires 2 integer arguments");
return NULL;
}

if (!(tempy = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL)) ||
!(tempm = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 1), NULL))) {
if (!(tempy = GMPy_MPZ_From_Integer(args[0], NULL)) ||
!(tempm = GMPy_MPZ_From_Integer(args[1], NULL))) {

Py_XDECREF((PyObject*)tempy);
Py_XDECREF((PyObject*)tempm);
Expand Down
Loading

0 comments on commit 1253106

Please sign in to comment.