Skip to content

BUG: Test regressions related to garbage collection on Python 3.14.0a7 #2091

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
1 task done
musicinmybrain opened this issue Apr 14, 2025 · 0 comments
Open
1 task done

Comments

@musicinmybrain
Copy link

This is a pyzmq bug

  • This is a pyzmq-specific bug, not an issue of zmq socket behavior. Don't worry if you're not sure! We'll figure it out together.

What pyzmq version?

26.4.0

What libzmq version?

4.3.5 (this should be the system zeromq package, but it also should not matter)

Python version (and how it was installed)

Python 3.14.4a7, installed in Fedora 41 via dnf (system RPM package)

OS

Fedora 41 (x86_64)

What happened?

Three tests from tests/test_message.py, related to garbage collection, fail on Python 3.14.0a7.

====================================== short test summary info =======================================
FAILED tests/test_message.py::TestFrame::test_above_30 - AssertionError: assert 2 == 1
FAILED tests/test_message.py::TestFrame::test_lifecycle1 - AssertionError: assert 2 == 1
FAILED tests/test_message.py::TestFrame::test_lifecycle2 - AssertionError: assert 2 == 1
====================== 3 failed, 353 passed, 32 skipped, 411 warnings in 36.50s ======================

Code to reproduce bug

$ python3.14 --version
Python 3.14.0a7
$ python3.14 -m venv _e
$ . _e/bin/activate
(_e) $ pip install -e .
(_e) $ pip install -r test-requirements.txt
(_e) $ pytest

Traceback, if applicable

============================================== FAILURES ==============================================
______________________________________ TestFrame.test_above_30 _______________________________________

self = <tests.test_message.TestFrame testMethod=test_above_30>

    @skip_pypy
    def test_above_30(self):
        """Message above 30 bytes are never copied by 0MQ."""
        for i in range(5, 16):  # 32, 64,..., 65536
            s = (2**i) * x
            rc = grc(s)
            m = zmq.Frame(s, copy=False)
            assert grc(s) == rc + 2
            del m
            await_gc(s, rc)
>           assert grc(s) == rc
E           AssertionError: assert 2 == 1
E            +  where 2 = grc(b'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx')

tests/test_message.py:67: AssertionError
_____________________________________ TestFrame.test_lifecycle1 ______________________________________

self = <tests.test_message.TestFrame testMethod=test_lifecycle1>

    @skip_pypy
    def test_lifecycle1(self):
        """Run through a ref counting cycle with a copy."""
        for i in range(5, 16):  # 32, 64,..., 65536
            s = (2**i) * x
            rc = rc_0 = grc(s)
            m = zmq.Frame(s, copy=False)
            rc += 2
            assert grc(s) == rc
            m2 = copy.copy(m)
            rc += 1
            assert grc(s) == rc
            # no increase in refcount for accessing buffer
            # which references m2 directly
            buf = m2.buffer
            assert grc(s) == rc

            assert s == bytes(m2)
            assert s == m.bytes
            assert s == bytes(buf)
            del m2
            assert grc(s) == rc
            # buf holds direct reference to m2 which holds
            del buf
            rc -= 1
            assert grc(s) == rc
            del m
            rc -= 2
            await_gc(s, rc)
>           assert grc(s) == rc
E           AssertionError: assert 2 == 1
E            +  where 2 = grc(b'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx')

tests/test_message.py:141: AssertionError
_____________________________________ TestFrame.test_lifecycle2 ______________________________________

self = <tests.test_message.TestFrame testMethod=test_lifecycle2>

    @skip_pypy
    def test_lifecycle2(self):
        """Run through a different ref counting cycle with a copy."""
        for i in range(5, 16):  # 32, 64,..., 65536
            s = (2**i) * x
            rc = rc_0 = grc(s)
            m = zmq.Frame(s, copy=False)
            rc += 2
            assert grc(s) == rc
            m2 = copy.copy(m)
            rc += 1
            assert grc(s) == rc
            # no increase in refcount for accessing buffer
            # which references m directly
            buf = m.buffer
            assert grc(s) == rc
            assert s == bytes(m2)
            assert s == m2.bytes
            assert s == m.bytes
            assert s == bytes(buf)   
            del buf
            assert grc(s) == rc
            del m
            rc -= 1
            assert grc(s) == rc
            del m2
            rc -= 2
            await_gc(s, rc)
>           assert grc(s) == rc
E           AssertionError: assert 2 == 1
E            +  where 2 = grc(b'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx')

tests/test_message.py:173: AssertionError

More info

I originally observed this with the 26.4.0 release, but I also reproduced it on the current main branch, 27abf26. I am working on Fedora 41, x86_64, but I do not believe this issue should not be specific to a particular OS or distribution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant