From ef8377b1be08eafe7ee9c14a25a23ce0a1170d8a Mon Sep 17 00:00:00 2001 From: Justin Bronder Date: Wed, 11 Jun 2025 22:57:23 -0400 Subject: [PATCH 1/4] make: add verbosity flag `make V=1` will enable extra debugging information when running specific tests or type checking. --- Makefile | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 9967f70..89b0b65 100644 --- a/Makefile +++ b/Makefile @@ -2,6 +2,10 @@ # substring expression UT ?= +# When enabled, tests/type-checking will be more verbose and not capture +# stdout/err. +V ?= + # Run uv offline by default OFFLINE ?= 1 @@ -44,8 +48,11 @@ format: lint: @$(UV) run flake8 --filename='*' $(LINT_TARGETS) type-check: - @$(UV) run mypy $(PACKAGE) test/ example.py + @$(UV) run mypy $(if $(V),--show-error-context) $(PACKAGE) test/ example.py test: @$(UV) run pytest --log-level=DEBUG -W default -v -s $(TEST_TARGETS): - @$(UV) run pytest --log-cli-level=DEBUG -W default -v -s test/$(@).py $(if $(UT),-k $(UT),) + @$(UV) run pytest --log-cli-level=DEBUG -W default -v \ + test/$(@).py \ + $(if $(V),,-s) \ + $(if $(UT),-k $(UT)) From 0ff3d6031b3280ee6513eaff40803043734e078b Mon Sep 17 00:00:00 2001 From: Justin Bronder Date: Mon, 16 Jun 2025 13:53:13 -0400 Subject: [PATCH 2/4] github: weekly: switch to uv --- .github/workflows/weekly.yml | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/.github/workflows/weekly.yml b/.github/workflows/weekly.yml index 9a6d9d2..1f6f371 100644 --- a/.github/workflows/weekly.yml +++ b/.github/workflows/weekly.yml @@ -13,24 +13,16 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: actions/setup-python@v5 + - name: Setup uv + - uses: actions/setup-uv@v5 with: + enable-cache: true python-version: ${{ matrix.python-version }} - - name: Install dependencies - run: | - python -m pip install --upgrade pip - make requirements - - name: Lint - run: | - make lint - - name: Format - run: | - make format && git diff --quiet HEAD - - name: Type check - run: | - make type-check + - name: Sync Environment + run: uv sync --frozen - name: Test - run: | - make test + run: make test + - name: Type check + run: make type-check # vim: sw=2 From d7be8b0a659d89f146fa9c2570fd43a400d89fa0 Mon Sep 17 00:00:00 2001 From: Justin Bronder Date: Mon, 7 Jul 2025 16:42:27 -0400 Subject: [PATCH 3/4] test: skip pause/resume test on python 3.13 and greater Accounting in asyncio.DatagramTransport is broken, so this won't pass. https://github.com/python/cpython/issues/135444 https://github.com/python/cpython/pull/135445 --- test/test_aio.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/test_aio.py b/test/test_aio.py index 50501d3..161cd16 100644 --- a/test/test_aio.py +++ b/test/test_aio.py @@ -393,6 +393,10 @@ async def test_unconnected_sender(addr: _Address) -> None: connected.close() +@pytest.mark.skipif( + sys.version_info >= (3, 13), + reason="https://github.com/python/cpython/issues/135444", +) @pytest.mark.asyncio async def test_protocol_pause_resume( monkeypatch: pytest.MonkeyPatch, From 1ea9badbbcebc24cfd1c962d09019a675ca248a5 Mon Sep 17 00:00:00 2001 From: Justin Bronder Date: Mon, 7 Jul 2025 16:54:00 -0400 Subject: [PATCH 4/4] test: use real socket fileno for mock socket In python 3.13, asyncio starts checking if the underlying fileno is something that can actually be passed to epoll, which is not the case for regular files. We can simply switch to using an actual sockets fileno instead of some regular file to resolve this. --- test/test_aio.py | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/test/test_aio.py b/test/test_aio.py index 161cd16..33e234d 100644 --- a/test/test_aio.py +++ b/test/test_aio.py @@ -445,21 +445,22 @@ async def passthrough() -> None: """ pass - mock_socket = unittest.mock.create_autospec(socket.socket) - mock_socket.family = socket.AF_INET - mock_socket.type = socket.SOCK_DGRAM - - with monkeypatch.context() as ctx: + with monkeypatch.context() as ctx, socket.socket( + socket.AF_INET, socket.SOCK_DGRAM + ) as sock: + sock.setblocking(False) ctx.setattr(asyncio_dgram.aio, "Protocol", TestableProtocol) + mock_socket = unittest.mock.create_autospec(socket.socket) + mock_socket.family = socket.AF_INET + mock_socket.type = socket.SOCK_DGRAM + mock_socket.fileno.return_value = sock.fileno() + client = await asyncio_dgram.from_socket(mock_socket) assert isinstance(client, asyncio_dgram.aio.DatagramClient) assert TestableProtocol.instance is not None mock_socket.send.side_effect = BlockingIOError - mock_socket.fileno.return_value = os.open( - tmp_path / "socket", os.O_RDONLY | os.O_CREAT - ) with monkeypatch.context() as ctx2: ctx2.setattr(client._drained, "wait", passthrough) @@ -470,9 +471,6 @@ async def passthrough() -> None: assert not TestableProtocol.instance._drained.is_set() mock_socket.send.side_effect = None - fd = os.open(tmp_path / "socket", os.O_WRONLY) - os.write(fd, b"\n") - os.close(fd) with monkeypatch.context() as ctx2: ctx2.setattr(client._drained, "wait", passthrough) @@ -483,8 +481,6 @@ async def passthrough() -> None: assert TestableProtocol.instance.resume_writing_called == 1 assert TestableProtocol.instance._drained.is_set() - os.close(mock_socket.fileno.return_value) - @pytest.mark.asyncio async def test_transport_closed() -> None: