Skip to content

Commit 85074c1

Browse files
committed
adding tests
1 parent 1e69bec commit 85074c1

1 file changed

Lines changed: 67 additions & 0 deletions

File tree

tests/test_quaddtype.py

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5689,6 +5689,73 @@ def test_pickle_scalar_in_list(self):
56895689
assert math.isnan(float(loaded[2]))
56905690
assert loaded[3] == original[3]
56915691

5692+
@staticmethod
5693+
def _raw_bytes(q):
5694+
"""The exact on-the-wire payload used by __reduce__ (bit pattern)."""
5695+
return q.__reduce__()[1][0]
5696+
5697+
def test_pickle_scalar_extreme_values_roundtrip(self):
5698+
"""Subnormals and values near the maximum are exactly where a decimal
5699+
string round-trip would lose bits; the raw-bytes path must preserve
5700+
them exactly."""
5701+
import pickle
5702+
extremes = [
5703+
numpy_quaddtype.smallest_subnormal,
5704+
numpy_quaddtype.smallest_normal,
5705+
numpy_quaddtype.smallest_subnormal * QuadPrecision("13.0"),
5706+
numpy_quaddtype.max_value,
5707+
-numpy_quaddtype.max_value,
5708+
numpy_quaddtype.epsilon,
5709+
]
5710+
for original in extremes:
5711+
loaded = pickle.loads(pickle.dumps(original))
5712+
assert isinstance(loaded, QuadPrecision)
5713+
assert self._raw_bytes(loaded) == self._raw_bytes(original)
5714+
assert loaded == original
5715+
5716+
def test_pickle_scalar_raw_bit_fuzz(self):
5717+
"""Fuzz the entire 128-bit space (subnormals, inf, NaN payloads, values
5718+
near overflow) and assert every value survives a pickle round-trip
5719+
bit-for-bit. Uses the new from_raw_bytes reconstructor to synthesize
5720+
arbitrary bit patterns that decimal fuzzing cannot reach."""
5721+
import pickle
5722+
import random
5723+
from numpy_quaddtype._quaddtype_main import from_raw_bytes
5724+
5725+
nbytes = len(self._raw_bytes(QuadPrecision("1.0", backend="sleef")))
5726+
rng = random.Random(0xC0FFEE)
5727+
for _ in range(4000):
5728+
raw = bytes(rng.randrange(256) for _ in range(nbytes))
5729+
original = from_raw_bytes(raw, "sleef")
5730+
loaded = pickle.loads(pickle.dumps(original))
5731+
# Compare bit patterns directly so NaNs (which are != themselves)
5732+
# are also checked.
5733+
assert self._raw_bytes(loaded) == self._raw_bytes(original)
5734+
5735+
def test_from_raw_bytes_roundtrip_matches_reduce(self):
5736+
"""from_raw_bytes is the inverse of the __reduce__ payload for both
5737+
backends, including the little-endian canonicalization."""
5738+
from numpy_quaddtype._quaddtype_main import from_raw_bytes
5739+
for backend in ("sleef", "longdouble"):
5740+
original = QuadPrecision("3.14159265358979323846264338327950288",
5741+
backend=backend)
5742+
_, (data, be) = original.__reduce__()
5743+
assert be == backend
5744+
rebuilt = from_raw_bytes(data, backend)
5745+
assert self._raw_bytes(rebuilt) == self._raw_bytes(original)
5746+
assert rebuilt == original
5747+
5748+
def test_from_raw_bytes_rejects_wrong_length(self):
5749+
from numpy_quaddtype._quaddtype_main import from_raw_bytes
5750+
with pytest.raises(ValueError):
5751+
from_raw_bytes(b"\x00" * 3, "sleef")
5752+
5753+
def test_from_raw_bytes_rejects_bad_backend(self):
5754+
from numpy_quaddtype._quaddtype_main import from_raw_bytes
5755+
good = QuadPrecision("1.0", backend="sleef").__reduce__()[1][0]
5756+
with pytest.raises(ValueError):
5757+
from_raw_bytes(good, "float128")
5758+
56925759

56935760
@pytest.mark.parametrize("dtype", [
56945761
"bool",

0 commit comments

Comments
 (0)