Skip to content

One test failure in the Windows cp313t CI job #304

Description

@rgommers

I just noticed that the last CI run on gh-301 contained a failure on the Windows cp313t (free-threading) job that was added. From this CI log:

                  if prev_snapshot:
                      stats = snapshot.compare_to(prev_snapshot, 'lineno')
   >                   assert stats[0].size_diff < MEM_INCREASE_LIMIT
  E                   AssertionError: assert 25848 < 25600
  E                    +  where 25848 = <StatisticDiff traceback=<Traceback (<Frame filename='C:\\Users\\runneradmin\\AppData\\Local\\pypa\\cibuildwheel\\Cach...t-cpython\\python-freethreaded.3.13.2\\tools\\Lib\\tracemalloc.py' lineno=125>,)> size=25848 (+25848) count=359 (+359)>.size_diff
Full pytest output:
  _________________ test_frame_open_decompress_mem_usage[data0] _________________
  
  data = b'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa...aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
  
      def test_frame_open_decompress_mem_usage(data):
          tracemalloc = pytest.importorskip('tracemalloc')
          tracemalloc.start()
      
          with lz4.frame.open('test.lz4', 'w') as f:
              f.write(data)
      
          prev_snapshot = None
      
          for i in range(1000):
              with lz4.frame.open('test.lz4', 'r') as f:
                  decompressed = f.read()  # noqa: F841
      
              if i % 100 == 0:
                  gc.collect()
                  snapshot = tracemalloc.take_snapshot()
      
                  if prev_snapshot:
                      stats = snapshot.compare_to(prev_snapshot, 'lineno')
   >                   assert stats[0].size_diff < MEM_INCREASE_LIMIT
  E                   AssertionError: assert 25848 < 25600
  E                    +  where 25848 = <StatisticDiff traceback=<Traceback (<Frame filename='C:\\Users\\runneradmin\\AppData\\Local\\pypa\\cibuildwheel\\Cach...t-cpython\\python-freethreaded.3.13.2\\tools\\Lib\\tracemalloc.py' lineno=125>,)> size=25848 (+25848) count=359 (+359)>.size_diff
  
  data       = b'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa...aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
  decompressed = b'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa...aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
  f          = <lz4.frame.LZ4FrameFile object at 0x000005DC06266F00>
  i          = 200
  prev_snapshot = <tracemalloc.Snapshot object at 0x000005DBF4847D50>
  snapshot   = <tracemalloc.Snapshot object at 0x000005DBF48471B0>
  stats      = [<StatisticDiff traceback=<Traceback (<Frame filename='C:\\Users\\runneradmin\\AppData\\Local\\pypa\\cibuildwheel\\Cac...t-cpython\\python-freethreaded.3.13.2\\tools\\Lib\\tracemalloc.py' lineno=503>,)> size=816 (+816) count=17 (+17)>, ...]
  tracemalloc = <module 'tracemalloc' from 'C:\\Users\\runneradmin\\AppData\\Local\\pypa\\cibuildwheel\\Cache\\nuget-cpython\\python-freethreaded.3.13.2\\tools\\Lib\\tracemalloc.py'>
  
  tests\frame\test_frame_5.py:90: AssertionError
  =============================== tests coverage ================================
  _______________ coverage: platform win32, python 3.13.2-final-0 _______________
  
  Name                    Stmts   Miss  Cover
  -------------------------------------------
  lz4\block\__init__.py       1      0   100%
  lz4\frame\__init__.py     245     47    81%
  -------------------------------------------
  TOTAL                     246     47    81%
  =========================== short test summary info ===========================
  FAILED tests/frame/test_frame_5.py::test_frame_open_decompress_mem_usage[data0]
  !!!!!!!!!!!!!!!!!!!!!!!!!! stopping after 1 failures !!!!!!!!!!!!!!!!!!!!!!!!!!
  ================= 1 failed, 19015 passed in 515.47s (0:08:35) =================
  SystemError: deallocated bytearray object has exported buffers

Here is the test code:

def test_frame_open_decompress_mem_usage(data):
tracemalloc = pytest.importorskip('tracemalloc')
tracemalloc.start()
with lz4.frame.open('test.lz4', 'w') as f:
f.write(data)
prev_snapshot = None
for i in range(1000):
with lz4.frame.open('test.lz4', 'r') as f:
decompressed = f.read() # noqa: F841
if i % 100 == 0:
gc.collect()
snapshot = tracemalloc.take_snapshot()
if prev_snapshot:
stats = snapshot.compare_to(prev_snapshot, 'lineno')
assert stats[0].size_diff < MEM_INCREASE_LIMIT
prev_snapshot = snapshot

There are a couple of potential issues:

  1. The GC behavior is quite different in a free-threaded interpreter, and I'm not sure that the test is supposed to always pass
  2. tracemalloc and bytearray are involved, and they may not yet have been made thread-safe under parallel testing (I'm fairly sure that's true of bytearray as of today), so the test may be flaky.

@nascheme could I ask for your GC-expert opinion on that test please?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions