From 2f3f61a278e285c4fde47994b8b4bdac20d60351 Mon Sep 17 00:00:00 2001 From: Jeffrey 'Alex' Clark Date: Wed, 17 Jun 2026 12:50:17 -0400 Subject: [PATCH 1/3] PYTHON-5728 Improve bson code coverage --- test/test_bson.py | 49 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/test/test_bson.py b/test/test_bson.py index da1cdf42c3..12f5544228 100644 --- a/test/test_bson.py +++ b/test/test_bson.py @@ -1275,6 +1275,18 @@ def test_binary_length_accounts_for_header(self): with self.assertRaises(InvalidBSON): decode(payload) + def test_large_list_encoding(self): + # gen_list_name yields pre-cached names for indices 0-999 then + # generates on the fly for 1000+. Encode a list that crosses that + # boundary and verify the round-trip is correct. + values = list(range(1002)) + doc = encode({"a": values}) + self.assertEqual(decode(doc)["a"], values) + # Spot-check: the 1000th and 1001st elements (0-indexed) must + # survive the cache/on-demand boundary intact. + self.assertEqual(decode(doc)["a"][1000], 1000) + self.assertEqual(decode(doc)["a"][1001], 1001) + class TestCodecOptions(unittest.TestCase): def test_document_class(self): @@ -1746,6 +1758,43 @@ def test_array_of_documents_to_buffer(self): with self.assertRaises(InvalidBSON): _array_of_documents_to_buffer(buf) + def test_datetime_ms_hash(self): + # Equal values must have equal hashes. + self.assertEqual(hash(DatetimeMS(0)), hash(DatetimeMS(0))) + self.assertEqual(hash(DatetimeMS(-1)), hash(DatetimeMS(-1))) + self.assertEqual(hash(DatetimeMS(2**62)), hash(DatetimeMS(2**62))) + # Unequal values should produce unequal hashes (not guaranteed, but + # true for plain int hashes which is what DatetimeMS delegates to). + self.assertNotEqual(hash(DatetimeMS(0)), hash(DatetimeMS(1))) + # Usable as a dict key. + d = {DatetimeMS(0): "epoch", DatetimeMS(1): "one"} + self.assertEqual(d[DatetimeMS(0)], "epoch") + self.assertEqual(d[DatetimeMS(1)], "one") + # Usable in a set. + s = {DatetimeMS(0), DatetimeMS(1), DatetimeMS(0)} + self.assertEqual(len(s), 2) + + def test_datetime_ms_repr(self): + self.assertEqual(repr(DatetimeMS(0)), "DatetimeMS(0)") + self.assertEqual(repr(DatetimeMS(-1)), "DatetimeMS(-1)") + self.assertEqual(repr(DatetimeMS(2**62)), f"DatetimeMS({2**62})") + # repr round-trips through eval. + for value in (0, 1, -1, 2**32): + obj = DatetimeMS(value) + self.assertEqual(eval(repr(obj)), obj) + + def test_datetime_ms_invalid_type(self): + # Non-int, non-datetime arguments must raise TypeError. + for bad in ("2024-01-01", 3.14, [], None, b"bytes"): + with self.assertRaises(TypeError): + DatetimeMS(bad) + # Out-of-range int must raise OverflowError directly, not only + # when encoding. + with self.assertRaises(OverflowError): + DatetimeMS(2**63) + with self.assertRaises(OverflowError): + DatetimeMS(-(2**63) - 1) + class TestLongLongToString(unittest.TestCase): def test_long_long_to_string(self): From e4750905dd92544a53d3e69c8d6a94469aae775e Mon Sep 17 00:00:00 2001 From: Jeffrey 'Alex' Clark Date: Wed, 17 Jun 2026 13:46:35 -0400 Subject: [PATCH 2/3] Address PR feedback: decode once, check boundary on both sides, drop brittle hash inequality assertion --- test/test_bson.py | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/test/test_bson.py b/test/test_bson.py index 12f5544228..5359ea95bd 100644 --- a/test/test_bson.py +++ b/test/test_bson.py @@ -1280,12 +1280,12 @@ def test_large_list_encoding(self): # generates on the fly for 1000+. Encode a list that crosses that # boundary and verify the round-trip is correct. values = list(range(1002)) - doc = encode({"a": values}) - self.assertEqual(decode(doc)["a"], values) - # Spot-check: the 1000th and 1001st elements (0-indexed) must - # survive the cache/on-demand boundary intact. - self.assertEqual(decode(doc)["a"][1000], 1000) - self.assertEqual(decode(doc)["a"][1001], 1001) + decoded = decode(encode({"a": values})) + self.assertEqual(decoded["a"], values) + # Spot-check elements on both sides of the cache/on-demand boundary. + self.assertEqual(decoded["a"][999], 999) + self.assertEqual(decoded["a"][1000], 1000) + self.assertEqual(decoded["a"][1001], 1001) class TestCodecOptions(unittest.TestCase): @@ -1763,9 +1763,6 @@ def test_datetime_ms_hash(self): self.assertEqual(hash(DatetimeMS(0)), hash(DatetimeMS(0))) self.assertEqual(hash(DatetimeMS(-1)), hash(DatetimeMS(-1))) self.assertEqual(hash(DatetimeMS(2**62)), hash(DatetimeMS(2**62))) - # Unequal values should produce unequal hashes (not guaranteed, but - # true for plain int hashes which is what DatetimeMS delegates to). - self.assertNotEqual(hash(DatetimeMS(0)), hash(DatetimeMS(1))) # Usable as a dict key. d = {DatetimeMS(0): "epoch", DatetimeMS(1): "one"} self.assertEqual(d[DatetimeMS(0)], "epoch") From 25cf00e727903a40e631840b0125f92a4b7ac618 Mon Sep 17 00:00:00 2001 From: Jeffrey 'Alex' Clark Date: Wed, 17 Jun 2026 13:50:17 -0400 Subject: [PATCH 3/3] Fix mypy error in test_datetime_ms_invalid_type --- test/test_bson.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_bson.py b/test/test_bson.py index 5359ea95bd..98087960ca 100644 --- a/test/test_bson.py +++ b/test/test_bson.py @@ -1784,7 +1784,7 @@ def test_datetime_ms_invalid_type(self): # Non-int, non-datetime arguments must raise TypeError. for bad in ("2024-01-01", 3.14, [], None, b"bytes"): with self.assertRaises(TypeError): - DatetimeMS(bad) + DatetimeMS(bad) # type: ignore[arg-type] # Out-of-range int must raise OverflowError directly, not only # when encoding. with self.assertRaises(OverflowError):