Skip to content

Commit 2b63d54

Browse files
authored
Merge pull request #84 from ejeffrey/add_default_constructor
Add default zero constructor for QuadPrecision
2 parents b69a9cb + 66f6b4e commit 2b63d54

5 files changed

Lines changed: 59 additions & 10 deletions

File tree

.github/workflows/big_endian.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ jobs:
137137
python -m pip install --break-system-packages --no-deps . -v --no-build-isolation --force-reinstall &&
138138
139139
# Install test dependencies separately
140-
python -m pip install --break-system-packages pytest pytest-run-parallel pytest-timeout mpmath &&
140+
python -m pip install --break-system-packages .[test] &&
141141
142142
python -m pytest -vvv --color=yes --timeout=600 --tb=short tests/
143143
'"

.github/workflows/test_old_cpu.yml

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,9 @@ jobs:
5454
# For Sandy Bridge (x86-64-v2), we need to disable FMA code paths
5555
# since FMA instructions are not available on that microarchitecture
5656
if [ "${{ matrix.cpu[0] }}" = "snb" ]; then
57-
pip install . --no-build-isolation -v -Csetup-args=-Ddisable_fma=true
57+
pip install .[test] --no-build-isolation -v -Csetup-args=-Ddisable_fma=true
5858
else
59-
pip install . --no-build-isolation -v
59+
pip install .[test] --no-build-isolation -v
6060
fi
6161
6262
- name: Test import on ${{ matrix.cpu[1] }}
@@ -74,5 +74,4 @@ jobs:
7474
7575
- name: Run tests on ${{ matrix.cpu[1] }}
7676
run: |
77-
pip install pytest mpmath
78-
sde -${{ matrix.cpu[0] }} -- python -m pytest tests/ -v --tb=short -v -s
77+
sde -${{ matrix.cpu[0] }} -- python -m pytest tests/ -v --tb=short -v -s

pyproject.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ dependencies = [
3636
test = [
3737
"pytest",
3838
"mpmath",
39-
"pytest-run-parallel"
39+
"pytest-run-parallel",
40+
"pandas"
4041
]
4142

4243
docs = [

src/csrc/scalar.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -281,11 +281,11 @@ QuadPrecision_from_object(PyObject *value, QuadBackendType backend)
281281
static PyObject *
282282
QuadPrecision_new(PyTypeObject *cls, PyObject *args, PyObject *kwargs)
283283
{
284-
PyObject *value;
284+
PyObject *value = NULL;
285285
const char *backend_str = "sleef";
286286
static char *kwlist[] = {"value", "backend", NULL};
287287

288-
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|s", kwlist, &value, &backend_str)) {
288+
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Os", kwlist, &value, &backend_str)) {
289289
return NULL;
290290
}
291291

@@ -298,6 +298,9 @@ QuadPrecision_new(PyTypeObject *cls, PyObject *args, PyObject *kwargs)
298298
return NULL;
299299
}
300300

301+
if (value == NULL) {
302+
return (PyObject *)QuadPrecision_raw_new(backend);
303+
}
301304
return (PyObject *)QuadPrecision_from_object(value, backend);
302305
}
303306

@@ -747,4 +750,4 @@ init_quadprecision_scalar(void)
747750
{
748751
QuadPrecision_Type.tp_base = &PyFloatingArrType_Type;
749752
return PyType_Ready(&QuadPrecision_Type);
750-
}
753+
}

tests/test_quaddtype.py

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5996,4 +5996,50 @@ def test_sleef_purecfma_symbols():
59965996
for sym in purecfma_symbols[:5]:
59975997
print(f" {sym}")
59985998
if len(purecfma_symbols) > 5:
5999-
print(f" ... and {len(purecfma_symbols) - 5} more")
5999+
print(f" ... and {len(purecfma_symbols) - 5} more")
6000+
6001+
6002+
def test_empty_construct():
6003+
# Default backend (sleef): no-arg construction yields zero.
6004+
assert QuadPrecision() == QuadPrecision(0) == 0
6005+
assert QuadPrecision().dtype == QuadPrecDType()
6006+
assert str(QuadPrecision()) == str(QuadPrecision(0))
6007+
6008+
# longdouble backend: no-arg construction also yields zero.
6009+
assert QuadPrecision(backend="longdouble") == QuadPrecision(0, backend="longdouble") == 0
6010+
assert QuadPrecision(backend="longdouble").dtype == QuadPrecDType(backend="longdouble")
6011+
6012+
# Round-trip through dtype.type(), this is the call path pandas uses
6013+
# in `_take_preprocess_indexer_and_fill_value` (see issue #83).
6014+
for backend in ("sleef", "longdouble"):
6015+
dtype = QuadPrecDType(backend=backend)
6016+
zero = dtype.type()
6017+
assert isinstance(zero, QuadPrecision)
6018+
assert zero == 0
6019+
6020+
# Invalid backend must still raise even when no value is supplied.
6021+
with pytest.raises(ValueError):
6022+
QuadPrecision(backend="bogus")
6023+
6024+
# Explicit None should NOT be silently treated as zero, it must go
6025+
# through QuadPrecision_from_object and raise.
6026+
with pytest.raises((TypeError, ValueError)):
6027+
QuadPrecision(None)
6028+
6029+
6030+
def test_pandas_strrep():
6031+
"""Test that we can construct a pandas data frame with quad precision columns
6032+
6033+
Make sure the string representation can be generated
6034+
"""
6035+
import pandas as pd
6036+
6037+
BIG_NUMBER=123456789098765432123456789
6038+
x = np.arange(500, dtype=np.float64) * BIG_NUMBER
6039+
y = np.arange(500, dtype=QuadPrecDType()) * BIG_NUMBER
6040+
df = pd.DataFrame({"col1": x, "col2": y})
6041+
assert isinstance(str(df), str) # Make sure this doesn't fail
6042+
assert df["col1"].dtype == np.float64
6043+
assert df["col2"].dtype == QuadPrecDType()
6044+
assert df["col1"].iloc[499] != QuadPrecision(499 * BIG_NUMBER)
6045+
assert df["col2"].iloc[499] == QuadPrecision(499 * BIG_NUMBER)

0 commit comments

Comments
 (0)