From dcf122d0922d5ca66a9fbc44eaf854ef202ed0f3 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Fri, 2 Oct 2026 08:58:38 -0500 Subject: [PATCH 1/3] PYTHON-6140 Skip test_encode_size_limit on hosts with < 6GiB memory --- test/test_bson.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/test/test_bson.py b/test/test_bson.py index 191a706388..0315548ea6 100644 --- a/test/test_bson.py +++ b/test/test_bson.py @@ -75,6 +75,29 @@ _NUMPY_AVAILABLE = importlib.util.find_spec("numpy") is not None +def _total_memory(): + """Return total physical memory in bytes, or None if it cannot be determined.""" + if sys.platform == "win32": + import ctypes + + memory = ctypes.c_ulonglong() + if ctypes.windll.kernel32.GetPhysicallyInstalledSystemMemory(ctypes.byref(memory)): + return memory.value * 1024 + return None + try: + return os.sysconf("SC_PAGE_SIZE") * os.sysconf("SC_PHYS_PAGES") + except (ValueError, OSError, AttributeError): + return None + + +# PYTHON-6140: skip if the host cannot allocate the ~4GiB this test needs. +_TOTAL_MEMORY = _total_memory() +_ENCODE_SIZE_LIMIT_MIN_MEMORY = 6 << 30 +_SKIP_ENCODE_SIZE_LIMIT = ( + _TOTAL_MEMORY is not None and _TOTAL_MEMORY < _ENCODE_SIZE_LIMIT_MIN_MEMORY +) + + class NotADict(abc.MutableMapping): """Non-dict type that implements the mapping protocol.""" @@ -692,6 +715,10 @@ def test_overflow(self): self.assertRaises(OverflowError, encode, {"x": -9223372036854775809}) @unittest.skipUnless(bson.has_c(), "This test requires the C extension") + @unittest.skipIf( + _SKIP_ENCODE_SIZE_LIMIT, + "Test requires at least 6GiB of memory (PYTHON-6140)", + ) def test_encode_size_limit(self): # PYTHON-5996: encoding must raise when a document's encoded size # exceeds the BSON size limit. From d7ac1405bc5b2e313ab612360e950e54d9adaff9 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Fri, 2 Oct 2026 09:38:12 -0500 Subject: [PATCH 2/3] PYTHON-6140 Skip test_encode_size_limit on MemoryError --- test/test_bson.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/test/test_bson.py b/test/test_bson.py index 0315548ea6..0dec6de3d4 100644 --- a/test/test_bson.py +++ b/test/test_bson.py @@ -722,9 +722,15 @@ def test_overflow(self): def test_encode_size_limit(self): # PYTHON-5996: encoding must raise when a document's encoded size # exceeds the BSON size limit. - big_value = "a" * (1 << 30) - with self.assertRaises(ValueError): - encode({"a": big_value, "b": big_value, "c": big_value}) + try: + big_value = "a" * (1 << 30) + with self.assertRaises(ValueError): + encode({"a": big_value, "b": big_value, "c": big_value}) + except MemoryError: + # PYTHON-6140: some hosts report enough installed memory but + # cannot actually commit it (pagefile limits, mongod running on + # the same host). Skip rather than fail. + self.skipTest("Could not allocate enough memory (PYTHON-6140)") def test_small_long_encode_decode(self): encoded1 = encode({"x": 256}) From e5abdfa15d5b3acff7e9c87c0113694d39520473 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Fri, 2 Oct 2026 14:08:51 -0500 Subject: [PATCH 3/3] PYTHON-6140 Only check memory on Linux, rely on MemoryError skip elsewhere --- test/test_bson.py | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/test/test_bson.py b/test/test_bson.py index 0dec6de3d4..0800806b84 100644 --- a/test/test_bson.py +++ b/test/test_bson.py @@ -77,24 +77,20 @@ def _total_memory(): """Return total physical memory in bytes, or None if it cannot be determined.""" - if sys.platform == "win32": - import ctypes - - memory = ctypes.c_ulonglong() - if ctypes.windll.kernel32.GetPhysicallyInstalledSystemMemory(ctypes.byref(memory)): - return memory.value * 1024 - return None try: return os.sysconf("SC_PAGE_SIZE") * os.sysconf("SC_PHYS_PAGES") except (ValueError, OSError, AttributeError): return None -# PYTHON-6140: skip if the host cannot allocate the ~4GiB this test needs. +# PYTHON-6140: on Linux, skip if the host cannot allocate the ~4GiB this test +# needs. On other platforms, run the test and skip on MemoryError. _TOTAL_MEMORY = _total_memory() _ENCODE_SIZE_LIMIT_MIN_MEMORY = 6 << 30 _SKIP_ENCODE_SIZE_LIMIT = ( - _TOTAL_MEMORY is not None and _TOTAL_MEMORY < _ENCODE_SIZE_LIMIT_MIN_MEMORY + sys.platform == "linux" + and _TOTAL_MEMORY is not None + and _TOTAL_MEMORY < _ENCODE_SIZE_LIMIT_MIN_MEMORY )