Skip to content

PyPI openstudio==3.11.0 wheel still emits SWIG memleak warnings — #5422 fix not applied to wheel build #5608

@brianlball

Description

@brianlball

Follow-up to #5421, which was closed by #5422. That PR defined SWIG_PYTHON_SILENT_MEMLEAK for the .deb build, which silences the SWIG memory-leak printfs. The fix works — I verified every _openstudio*.so in /usr/local/openstudio-3.11.0/Python/ from nrel/openstudio:3.11.0 contains zero "detected a memory leak" strings.

But the same fix was not applied to the PyPI wheel build. The openstudio==3.11.0 wheel published on PyPI still has the fprintf compiled in — all 38 _openstudio*.so files contain the "detected a memory leak" string — and it fires at runtime. The original 5421 reproducer still reproduces exactly, word for word, against pip install openstudio==3.11.0.

Reproduction (identical to #5421, but against PyPI wheel)

docker run --rm python:3.12-slim bash -lc '
  pip install openstudio==3.11.0 pytest
  cat > /tmp/t.py <<PY
import openstudio, pytest
def _go():
    m = openstudio.model.Model()
    raise ValueError("boom")
def test_it():
    _go()
PY
  pytest /tmp/t.py
'

Last line of output:

swig/python detected a memory leak of type '\''openstudio::model::Model *'\'', no destructor found.

Impact

This breaks any tool that uses stdio as a protocol channel — MCP servers over JSON-RPC/stdio, Unix pipes carrying JSON, anything that parses child-process stdout as structured data. openstudio-mcp has a permanent fd-1→fd-2 redirect in its server startup specifically to work around this.

I also see additional types at interpreter shutdown under more complex workloads:

swig/python detected a memory leak of type 'boost::optional< openstudio::model::Model > *', no destructor found.
swig/python detected a memory leak of type 'boost::optional< double > *', no destructor found.  (xmany)
swig/python detected a memory leak of type 'std::vector< openstudio::Point3d,std::allocator< openstudio::Point3d > > *', no destructor found.

Verification commands

# .deb install (has the fix)
docker run --rm nrel/openstudio:3.11.0 bash -c   'for f in /usr/local/openstudio-3.11.0/Python/_openstudio*.so; do
     printf "%s: %d\n" "$(basename $f)" "$(strings $f | grep -c "detected a memory leak")"
   done' | sort -u -t: -k2
# → all 0

# PyPI wheel (missing the fix)
docker run --rm python:3.12-slim bash -c '
  apt-get -qq update && apt-get -qq install -y binutils
  pip install --quiet openstudio==3.11.0
  for f in /usr/local/lib/python3.12/site-packages/openstudio/_openstudio*.so; do
    printf "%s: %d\n" "$(basename $f)" "$(strings $f | grep -c "detected a memory leak")"
  done' | sort -u -t: -k2
# → all 1

Suggested fix

Apply the same -DSWIG_PYTHON_SILENT_MEMLEAK compile definition in the Python wheel build path that #5422 added for the .deb build. Depending on how the wheel is built, this may be a CMake flag in the cibuildwheel / setup.py / pyproject.toml scripts for the Python packaging job.

Upstream SWIG root cause is swig/swig#2638, still open; the define is the pragmatic workaround and should be consistent across both build outputs.

Environment

  • openstudio==3.11.0 from PyPI
  • SHA256 of _openstudiomodelcore.so: d8c99ffc4bbf76983411736659e84a5dc2bd51ccffa27e171f2cc194e9b9f6bb
  • Python 3.12.3
  • ubuntu 24.04 host / python:3.12-slim container

Downstream impact: https://github.com/NatLabRockies/openstudio-mcp/blob/develop/mcp_server/stdout_suppression.py

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