Skip to content

Commit

Permalink
Make crc32c method accept keyword arguments; add 'crc', 'release_gil'…
Browse files Browse the repository at this point in the history
… keyword arguments'
  • Loading branch information
jonded94 committed Aug 3, 2024
1 parent 981dada commit 2218ee4
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 14 deletions.
37 changes: 23 additions & 14 deletions _crc32c.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,13 @@ static crc_function crc_fn;
int is_big_endian;

static
PyObject* crc32c_crc32c(PyObject *self, PyObject *args) {
PyObject* crc32c_crc32c(PyObject *self, PyObject *args, PyObject *kwargs) {
Py_buffer pbin;
unsigned char *bin_data = NULL;
uint32_t crc = 0U, result;
int release_gil = -1;

static char *kwlist[] = {"inp", "crc", "release_gil", NULL};

/* In python 3 we accept only bytes-like objects */
const char *format =
Expand All @@ -49,31 +52,37 @@ PyObject* crc32c_crc32c(PyObject *self, PyObject *args) {
#else
"s*"
#endif
"|I:crc32";
"|Ii:crc32";

if (!PyArg_ParseTuple(args, format, &pbin, &crc) )
if (!PyArg_ParseTupleAndKeywords(args, kwargs, format, kwlist, &pbin, &crc, &release_gil) )
return NULL;

bin_data = pbin.buf;
Py_BEGIN_ALLOW_THREADS
crc ^= 0xffffffff;
result = crc_fn(crc, bin_data, pbin.len);
result ^= 0xffffffff;
Py_END_ALLOW_THREADS
if ((release_gil < 0 && pbin.len >= 32768) || release_gil >= 1) {
Py_BEGIN_ALLOW_THREADS
crc ^= 0xffffffff;
result = crc_fn(crc, bin_data, pbin.len);
result ^= 0xffffffff;
Py_END_ALLOW_THREADS
} else {
crc ^= 0xffffffff;
result = crc_fn(crc, bin_data, pbin.len);
result ^= 0xffffffff;
}

PyBuffer_Release(&pbin);
return PyLong_FromUnsignedLong(result);
}

static
PyObject *crc32c_crc32(PyObject *self, PyObject *args)
PyObject *crc32c_crc32(PyObject *self, PyObject *args, PyObject *kwargs)
{
if (PyErr_WarnEx(PyExc_DeprecationWarning,
"crc32c.crc32 will be eventually removed, use crc32c.crc32c instead",
1) == -1) {
"crc32c.crc32 will be eventually removed, use crc32c.crc32c instead",
1) == -1) {
return NULL;
}
return crc32c_crc32c(self, args);
return crc32c_crc32c(self, args, kwargs);
}

/* The different values the SW mode preference can take */
Expand Down Expand Up @@ -103,8 +112,8 @@ static enum crc32c_sw_mode get_sw_mode(void)
}

static PyMethodDef CRC32CMethods[] = {
{"crc32", crc32c_crc32, METH_VARARGS, "Calculate crc32c incrementally (deprecated)"},
{"crc32c", crc32c_crc32c, METH_VARARGS, "Calculate crc32c incrementally"},
{"crc32", (PyCFunction)crc32c_crc32, METH_VARARGS | METH_KEYWORDS, "Calculate crc32c incrementally (deprecated)"},
{"crc32c", (PyCFunction)crc32c_crc32c, METH_VARARGS | METH_KEYWORDS, "Calculate crc32c incrementally"},
{NULL, NULL, 0, NULL} /* Sentinel */
};

Expand Down
3 changes: 3 additions & 0 deletions test/test_crc32c.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ class TestMisc(unittest.TestCase):
def test_zero(self):
self.assertEqual(0, crc32c.crc32c(b''))

def test_keyword(self):
self.assertEqual(10, crc32c.crc32c(b'', crc=10))

def test_crc32_deprecated(self):
with warning_catcher() as warns:
crc32c.crc32(b'')
Expand Down

0 comments on commit 2218ee4

Please sign in to comment.