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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions