Diff of the two buildlogs: -- --- b1/build.log 2024-12-27 10:33:24.939003862 +0000 +++ b2/build.log 2024-12-27 10:35:16.421929746 +0000 @@ -1,6 +1,6 @@ I: pbuilder: network access will be disabled during build -I: Current time: Thu Dec 26 22:27:51 -12 2024 -I: pbuilder-time-stamp: 1735295271 +I: Current time: Fri Jan 30 06:56:26 +14 2026 +I: pbuilder-time-stamp: 1769705786 I: Building the build Environment I: extracting base tarball [/var/cache/pbuilder/unstable-reproducible-base.tgz] I: copying local configuration @@ -22,52 +22,84 @@ dpkg-source: info: unpacking python-sse-starlette_2.2.1-1.debian.tar.xz I: Not using root during the build. I: Installing the build-deps -I: user script /srv/workspace/pbuilder/2529655/tmp/hooks/D02_print_environment starting +I: user script /srv/workspace/pbuilder/579511/tmp/hooks/D01_modify_environment starting +debug: Running on ionos15-amd64. +I: Changing host+domainname to test build reproducibility +I: Adding a custom variable just for the fun of it... +I: Changing /bin/sh to bash +'/bin/sh' -> '/bin/bash' +lrwxrwxrwx 1 root root 9 Jan 29 16:56 /bin/sh -> /bin/bash +I: Setting pbuilder2's login shell to /bin/bash +I: Setting pbuilder2's GECOS to second user,second room,second work-phone,second home-phone,second other +I: user script /srv/workspace/pbuilder/579511/tmp/hooks/D01_modify_environment finished +I: user script /srv/workspace/pbuilder/579511/tmp/hooks/D02_print_environment starting I: set - BUILDDIR='/build/reproducible-path' - BUILDUSERGECOS='first user,first room,first work-phone,first home-phone,first other' - BUILDUSERNAME='pbuilder1' - BUILD_ARCH='amd64' - DEBIAN_FRONTEND='noninteractive' - DEB_BUILD_OPTIONS='buildinfo=+all reproducible=+all parallel=20 ' - DISTRIBUTION='unstable' - HOME='/root' - HOST_ARCH='amd64' + BASH=/bin/sh + BASHOPTS=checkwinsize:cmdhist:complete_fullquote:extquote:force_fignore:globasciiranges:globskipdots:hostcomplete:interactive_comments:patsub_replacement:progcomp:promptvars:sourcepath + BASH_ALIASES=() + BASH_ARGC=() + BASH_ARGV=() + BASH_CMDS=() + BASH_LINENO=([0]="12" [1]="0") + BASH_LOADABLES_PATH=/usr/local/lib/bash:/usr/lib/bash:/opt/local/lib/bash:/usr/pkg/lib/bash:/opt/pkg/lib/bash:. + BASH_SOURCE=([0]="/tmp/hooks/D02_print_environment" [1]="/tmp/hooks/D02_print_environment") + BASH_VERSINFO=([0]="5" [1]="2" [2]="37" [3]="1" [4]="release" [5]="x86_64-pc-linux-gnu") + BASH_VERSION='5.2.37(1)-release' + BUILDDIR=/build/reproducible-path + BUILDUSERGECOS='second user,second room,second work-phone,second home-phone,second other' + BUILDUSERNAME=pbuilder2 + BUILD_ARCH=amd64 + DEBIAN_FRONTEND=noninteractive + DEB_BUILD_OPTIONS='buildinfo=+all reproducible=+all parallel=42 ' + DIRSTACK=() + DISTRIBUTION=unstable + EUID=0 + FUNCNAME=([0]="Echo" [1]="main") + GROUPS=() + HOME=/root + HOSTNAME=i-capture-the-hostname + HOSTTYPE=x86_64 + HOST_ARCH=amd64 IFS=' ' - INVOCATION_ID='c7ce4bcfb1464606aef5749fe17fdf1e' - LANG='C' - LANGUAGE='en_US:en' - LC_ALL='C' - MAIL='/var/mail/root' - OPTIND='1' - PATH='/usr/sbin:/usr/bin:/sbin:/bin:/usr/games' - PBCURRENTCOMMANDLINEOPERATION='build' - PBUILDER_OPERATION='build' - PBUILDER_PKGDATADIR='/usr/share/pbuilder' - PBUILDER_PKGLIBDIR='/usr/lib/pbuilder' - PBUILDER_SYSCONFDIR='/etc' - PPID='2529655' - PS1='# ' - PS2='> ' + INVOCATION_ID=94711bcc108c4bb5abb0798b46c2fdbd + LANG=C + LANGUAGE=et_EE:et + LC_ALL=C + MACHTYPE=x86_64-pc-linux-gnu + MAIL=/var/mail/root + OPTERR=1 + OPTIND=1 + OSTYPE=linux-gnu + PATH=/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/i/capture/the/path + PBCURRENTCOMMANDLINEOPERATION=build + PBUILDER_OPERATION=build + PBUILDER_PKGDATADIR=/usr/share/pbuilder + PBUILDER_PKGLIBDIR=/usr/lib/pbuilder + PBUILDER_SYSCONFDIR=/etc + PIPESTATUS=([0]="0") + POSIXLY_CORRECT=y + PPID=579511 PS4='+ ' - PWD='/' - SHELL='/bin/bash' - SHLVL='2' - SUDO_COMMAND='/usr/bin/timeout -k 18.1h 18h /usr/bin/ionice -c 3 /usr/bin/nice /usr/sbin/pbuilder --build --configfile /srv/reproducible-results/rbuild-debian/r-b-build.Ae0TGUOq/pbuilderrc_GP7j --distribution unstable --hookdir /etc/pbuilder/first-build-hooks --debbuildopts -b --basetgz /var/cache/pbuilder/unstable-reproducible-base.tgz --buildresult /srv/reproducible-results/rbuild-debian/r-b-build.Ae0TGUOq/b1 --logfile b1/build.log python-sse-starlette_2.2.1-1.dsc' - SUDO_GID='111' - SUDO_UID='106' - SUDO_USER='jenkins' - TERM='unknown' - TZ='/usr/share/zoneinfo/Etc/GMT+12' - USER='root' - _='/usr/bin/systemd-run' - http_proxy='http://46.16.76.132:3128' + PWD=/ + SHELL=/bin/bash + SHELLOPTS=braceexpand:errexit:hashall:interactive-comments:posix + SHLVL=3 + SUDO_COMMAND='/usr/bin/timeout -k 24.1h 24h /usr/bin/ionice -c 3 /usr/bin/nice -n 11 /usr/bin/unshare --uts -- /usr/sbin/pbuilder --build --configfile /srv/reproducible-results/rbuild-debian/r-b-build.Ae0TGUOq/pbuilderrc_9Xu6 --distribution unstable --hookdir /etc/pbuilder/rebuild-hooks --debbuildopts -b --basetgz /var/cache/pbuilder/unstable-reproducible-base.tgz --buildresult /srv/reproducible-results/rbuild-debian/r-b-build.Ae0TGUOq/b2 --logfile b2/build.log python-sse-starlette_2.2.1-1.dsc' + SUDO_GID=111 + SUDO_UID=106 + SUDO_USER=jenkins + TERM=unknown + TZ=/usr/share/zoneinfo/Etc/GMT-14 + UID=0 + USER=root + _='I: set' + http_proxy=http://213.165.73.152:3128 I: uname -a - Linux ionos11-amd64 6.1.0-28-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.119-1 (2024-11-22) x86_64 GNU/Linux + Linux i-capture-the-hostname 6.11.10+bpo-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.11.10-1~bpo12+1 (2024-12-19) x86_64 GNU/Linux I: ls -l /bin - lrwxrwxrwx 1 root root 7 Nov 22 14:40 /bin -> usr/bin -I: user script /srv/workspace/pbuilder/2529655/tmp/hooks/D02_print_environment finished + lrwxrwxrwx 1 root root 7 Nov 22 2024 /bin -> usr/bin +I: user script /srv/workspace/pbuilder/579511/tmp/hooks/D02_print_environment finished -> Attempting to satisfy build-dependencies -> Creating pbuilder-satisfydepends-dummy package Package: pbuilder-satisfydepends-dummy @@ -241,7 +273,7 @@ Get: 110 http://deb.debian.org/debian unstable/main amd64 python3-urllib3 all 2.2.3-4 [112 kB] Get: 111 http://deb.debian.org/debian unstable/main amd64 python3-requests all 2.32.3+dfsg-1 [71.9 kB] Get: 112 http://deb.debian.org/debian unstable/main amd64 python3-starlette all 0.41.3-2 [51.2 kB] -Fetched 39.6 MB in 1s (29.2 MB/s) +Fetched 39.6 MB in 2s (16.3 MB/s) Preconfiguring packages ... Selecting previously unselected package libjs-jquery. (Reading database ... (Reading database ... 5% (Reading database ... 10% (Reading database ... 15% (Reading database ... 20% (Reading database ... 25% (Reading database ... 30% (Reading database ... 35% (Reading database ... 40% (Reading database ... 45% (Reading database ... 50% (Reading database ... 55% (Reading database ... 60% (Reading database ... 65% (Reading database ... 70% (Reading database ... 75% (Reading database ... 80% (Reading database ... 85% (Reading database ... 90% (Reading database ... 95% (Reading database ... 100% (Reading database ... 19858 files and directories currently installed.) @@ -612,8 +644,8 @@ Setting up tzdata (2024b-4) ... Current default time zone: 'Etc/UTC' -Local time is now: Fri Dec 27 10:29:58 UTC 2024. -Universal Time is now: Fri Dec 27 10:29:58 UTC 2024. +Local time is now: Thu Jan 29 16:57:00 UTC 2026. +Universal Time is now: Thu Jan 29 16:57:00 UTC 2026. Run 'dpkg-reconfigure tzdata' if you wish to change it. Setting up libpython3.13-minimal:amd64 (3.13.1-2) ... @@ -725,7 +757,11 @@ Building tag database... -> Finished parsing the build-deps I: Building the package -I: Running cd /build/reproducible-path/python-sse-starlette-2.2.1/ && env PATH="/usr/sbin:/usr/bin:/sbin:/bin:/usr/games" HOME="/nonexistent/first-build" dpkg-buildpackage -us -uc -b && env PATH="/usr/sbin:/usr/bin:/sbin:/bin:/usr/games" HOME="/nonexistent/first-build" dpkg-genchanges -S > ../python-sse-starlette_2.2.1-1_source.changes +I: user script /srv/workspace/pbuilder/579511/tmp/hooks/A99_set_merged_usr starting +Not re-configuring usrmerge for unstable +I: user script /srv/workspace/pbuilder/579511/tmp/hooks/A99_set_merged_usr finished +hostname: Name or service not known +I: Running cd /build/reproducible-path/python-sse-starlette-2.2.1/ && env PATH="/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/i/capture/the/path" HOME="/nonexistent/second-build" dpkg-buildpackage -us -uc -b && env PATH="/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/i/capture/the/path" HOME="/nonexistent/second-build" dpkg-genchanges -S > ../python-sse-starlette_2.2.1-1_source.changes dpkg-buildpackage: info: source package python-sse-starlette dpkg-buildpackage: info: source version 2.2.1-1 dpkg-buildpackage: info: source distribution unstable @@ -755,8 +791,8 @@ running build running build_py creating build/lib/sse_starlette -copying sse_starlette/__init__.py -> build/lib/sse_starlette copying sse_starlette/event.py -> build/lib/sse_starlette +copying sse_starlette/__init__.py -> build/lib/sse_starlette copying sse_starlette/sse.py -> build/lib/sse_starlette running egg_info creating sse_starlette.egg-info @@ -775,15 +811,15 @@ running install_lib creating build/bdist.linux-x86_64/wheel creating build/bdist.linux-x86_64/wheel/sse_starlette -copying build/lib/sse_starlette/__init__.py -> build/bdist.linux-x86_64/wheel/./sse_starlette -copying build/lib/sse_starlette/event.py -> build/bdist.linux-x86_64/wheel/./sse_starlette copying build/lib/sse_starlette/py.typed -> build/bdist.linux-x86_64/wheel/./sse_starlette +copying build/lib/sse_starlette/event.py -> build/bdist.linux-x86_64/wheel/./sse_starlette +copying build/lib/sse_starlette/__init__.py -> build/bdist.linux-x86_64/wheel/./sse_starlette copying build/lib/sse_starlette/sse.py -> build/bdist.linux-x86_64/wheel/./sse_starlette running install_egg_info Copying sse_starlette.egg-info to build/bdist.linux-x86_64/wheel/./sse_starlette-2.2.1.egg-info running install_scripts creating build/bdist.linux-x86_64/wheel/sse_starlette-2.2.1.dist-info/WHEEL -creating '/build/reproducible-path/python-sse-starlette-2.2.1/.pybuild/cpython3_3.13_sse_starlette/.tmp-dppsqhqq/sse_starlette-2.2.1-py3-none-any.whl' and adding 'build/bdist.linux-x86_64/wheel' to it +creating '/build/reproducible-path/python-sse-starlette-2.2.1/.pybuild/cpython3_3.13_sse_starlette/.tmp-kjyc0koq/sse_starlette-2.2.1-py3-none-any.whl' and adding 'build/bdist.linux-x86_64/wheel' to it adding 'sse_starlette/__init__.py' adding 'sse_starlette/event.py' adding 'sse_starlette/py.typed' @@ -817,15 +853,15 @@ running install_lib creating build/bdist.linux-x86_64/wheel creating build/bdist.linux-x86_64/wheel/sse_starlette -copying build/lib/sse_starlette/__init__.py -> build/bdist.linux-x86_64/wheel/./sse_starlette -copying build/lib/sse_starlette/event.py -> build/bdist.linux-x86_64/wheel/./sse_starlette copying build/lib/sse_starlette/py.typed -> build/bdist.linux-x86_64/wheel/./sse_starlette +copying build/lib/sse_starlette/event.py -> build/bdist.linux-x86_64/wheel/./sse_starlette +copying build/lib/sse_starlette/__init__.py -> build/bdist.linux-x86_64/wheel/./sse_starlette copying build/lib/sse_starlette/sse.py -> build/bdist.linux-x86_64/wheel/./sse_starlette running install_egg_info Copying sse_starlette.egg-info to build/bdist.linux-x86_64/wheel/./sse_starlette-2.2.1.egg-info running install_scripts creating build/bdist.linux-x86_64/wheel/sse_starlette-2.2.1.dist-info/WHEEL -creating '/build/reproducible-path/python-sse-starlette-2.2.1/.pybuild/cpython3_3.12_sse_starlette/.tmp-uth7zi5a/sse_starlette-2.2.1-py3-none-any.whl' and adding 'build/bdist.linux-x86_64/wheel' to it +creating '/build/reproducible-path/python-sse-starlette-2.2.1/.pybuild/cpython3_3.12_sse_starlette/.tmp-kxwvz8jn/sse_starlette-2.2.1-py3-none-any.whl' and adding 'build/bdist.linux-x86_64/wheel' to it adding 'sse_starlette/__init__.py' adding 'sse_starlette/event.py' adding 'sse_starlette/py.typed' @@ -849,7 +885,7 @@ platform linux -- Python 3.13.1, pytest-8.3.4, pluggy-1.5.0 rootdir: /build/reproducible-path/python-sse-starlette-2.2.1/.pybuild/cpython3_3.13_sse_starlette/build configfile: pyproject.toml -plugins: anyio-4.6.2, typeguard-4.4.1, cov-5.0.0, asyncio-0.24.0a1 +plugins: cov-5.0.0, typeguard-4.4.1, anyio-4.6.2, asyncio-0.24.0a1 asyncio: mode=Mode.AUTO, default_loop_scope=None collected 44 items @@ -862,7 +898,7 @@ warnings.warn( -- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html -======================== 44 passed, 1 warning in 8.26s ========================= +======================== 44 passed, 1 warning in 7.87s ========================= I: pybuild base:311: cd /build/reproducible-path/python-sse-starlette-2.2.1/.pybuild/cpython3_3.12_sse_starlette/build; python3.12 -m pytest --ignore tests/experimentation/test_multiple_consumers_asyncio.py --ignore tests/experimentation/test_multiple_consumers_threads.py --ignore tests/integration/test_multiple_consumers.py /usr/lib/python3/dist-packages/pytest_asyncio/plugin.py:208: PytestDeprecationWarning: The configuration option "asyncio_default_fixture_loop_scope" is unset. The event loop scope for asynchronous fixtures will default to the fixture caching scope. Future versions of pytest-asyncio will default the loop scope for asynchronous fixtures to function scope. Set the default fixture loop scope explicitly in order to avoid unexpected behavior in the future. Valid fixture loop scopes are: "function", "class", "module", "package", "session" @@ -872,56 +908,221 @@ platform linux -- Python 3.12.8, pytest-8.3.4, pluggy-1.5.0 rootdir: /build/reproducible-path/python-sse-starlette-2.2.1/.pybuild/cpython3_3.12_sse_starlette/build configfile: pyproject.toml -plugins: anyio-4.6.2, typeguard-4.4.1, cov-5.0.0, asyncio-0.24.0a1 +plugins: cov-5.0.0, typeguard-4.4.1, anyio-4.6.2, asyncio-0.24.0a1 asyncio: mode=Mode.AUTO, default_loop_scope=None collected 44 items tests/test_event.py ....................... [ 52%] -tests/test_sse.py ..................... [100%] +tests/test_sse.py F..F................. [100%] + +=================================== FAILURES =================================== +_ TestEventSourceResponse.test_response_send_whenValidInput_thenGeneratesExpectedOutput[integer-\r\n-data: 1\r\n\r\n] _ + +self = +reset_appstatus_event = None +mock_generator = .numbers at 0x7fc46187ccc0> +input_type = 'integer', separator = '\r\n', expected_output = b'data: 1\r\n\r\n' + + @pytest.mark.parametrize( + "input_type,separator,expected_output", + [ + ("integer", "\r\n", b"data: 1\r\n\r\n"), + ("dict_simple", "\r\n", b"data: 1\r\n\r\n"), + ("dict_with_event", "\r\n", b"event: message\r\ndata: 1\r\n\r\n"), + ("dict_with_event", "\r", b"event: message\rdata: 1\r\r"), + ], + ) + async def test_response_send_whenValidInput_thenGeneratesExpectedOutput( + self, + reset_appstatus_event, + mock_generator, + input_type, + separator, + expected_output, + ): + # Arrange + async def app(scope, receive, send): + async def format_output(value): + if input_type == "integer": + return value + elif input_type == "dict_simple": + return dict(data=value) + else: + return dict(data=value, event="message") + + async def generate(): + generator = mock_generator(1, 5) + async for value in generator: + yield await format_output(value) + + response = EventSourceResponse(generate(), ping=0.2, sep=separator) + await response(scope, receive, send) + + # Act + client = TestClient(app) + response = client.get("/") + + # Assert + assert expected_output in response.content +> assert response.content.decode().count("ping") == 2 +E AssertionError: assert 3 == 2 +E + where 3 = ('ping') +E + where = 'data: 1\r\n\r\n: ping - 2026-01-29 16:58:03.329909+00:00\r\n\r\ndata: 2\r\n\r\ndata: 3\r\n\r\n: ping - 2026-01-29 16:58:03.533308+00:00\r\n\r\ndata: 4\r\n\r\n: ping - 2026-01-29 16:58:03.907870+00:00\r\n\r\ndata: 5\r\n\r\n'.count +E + where 'data: 1\r\n\r\n: ping - 2026-01-29 16:58:03.329909+00:00\r\n\r\ndata: 2\r\n\r\ndata: 3\r\n\r\n: ping - 2026-01-29 16:58:03.533308+00:00\r\n\r\ndata: 4\r\n\r\n: ping - 2026-01-29 16:58:03.907870+00:00\r\n\r\ndata: 5\r\n\r\n' = () +E + where = b'data: 1\r\n\r\n: ping - 2026-01-29 16:58:03.329909+00:00\r\n\r\ndata: 2\r\n\r\ndata: 3\r\n\r\n: ping - 2026-01-29 16:58:03.533308+00:00\r\n\r\ndata: 4\r\n\r\n: ping - 2026-01-29 16:58:03.907870+00:00\r\n\r\ndata: 5\r\n\r\n'.decode +E + where b'data: 1\r\n\r\n: ping - 2026-01-29 16:58:03.329909+00:00\r\n\r\ndata: 2\r\n\r\ndata: 3\r\n\r\n: ping - 2026-01-29 16:58:03.533308+00:00\r\n\r\ndata: 4\r\n\r\n: ping - 2026-01-29 16:58:03.907870+00:00\r\n\r\ndata: 5\r\n\r\n' = .content + +tests/test_sse.py:82: AssertionError +---------------------------- Captured stderr setup ----------------------------- +2026-01-30 06:58:03 DEBUG asyncio __init__:64 Using selector: EpollSelector +2026-01-30 06:58:03 DEBUG asyncio __init__:64 Using selector: EpollSelector +------------------------------ Captured log setup ------------------------------ +DEBUG asyncio:selector_events.py:64 Using selector: EpollSelector +DEBUG asyncio:selector_events.py:64 Using selector: EpollSelector +----------------------------- Captured stderr call ----------------------------- +2026-01-30 06:58:03 DEBUG asyncio __init__:64 Using selector: EpollSelector +2026-01-30 06:58:03 DEBUG sse_starlette.sse _stream_response:156 chunk: b'data: 1\r\n\r\n' +2026-01-30 06:58:03 DEBUG sse_starlette.sse _ping:211 ping: b': ping - 2026-01-29 16:58:03.329909+00:00\r\n\r\n' +2026-01-30 06:58:03 DEBUG sse_starlette.sse _stream_response:156 chunk: b'data: 2\r\n\r\n' +2026-01-30 06:58:03 DEBUG sse_starlette.sse _ping:211 ping: b': ping - 2026-01-29 16:58:03.533308+00:00\r\n\r\n' +2026-01-30 06:58:03 DEBUG sse_starlette.sse _stream_response:156 chunk: b'data: 3\r\n\r\n' +2026-01-30 06:58:03 DEBUG sse_starlette.sse _stream_response:156 chunk: b'data: 4\r\n\r\n' +2026-01-30 06:58:03 DEBUG sse_starlette.sse _ping:211 ping: b': ping - 2026-01-29 16:58:03.907870+00:00\r\n\r\n' +2026-01-30 06:58:03 DEBUG sse_starlette.sse _stream_response:156 chunk: b'data: 5\r\n\r\n' +2026-01-30 06:58:03 DEBUG sse_starlette.sse _listen_for_disconnect:177 Got event: http.disconnect. Stop streaming. +2026-01-30 06:58:03 INFO httpx _send_single_request:1038 HTTP Request: GET http://testserver/ "HTTP/1.1 200 OK" +------------------------------ Captured log call ------------------------------- +DEBUG asyncio:selector_events.py:64 Using selector: EpollSelector +DEBUG sse_starlette.sse:sse.py:156 chunk: b'data: 1\r\n\r\n' +DEBUG sse_starlette.sse:sse.py:211 ping: b': ping - 2026-01-29 16:58:03.329909+00:00\r\n\r\n' +DEBUG sse_starlette.sse:sse.py:156 chunk: b'data: 2\r\n\r\n' +DEBUG sse_starlette.sse:sse.py:211 ping: b': ping - 2026-01-29 16:58:03.533308+00:00\r\n\r\n' +DEBUG sse_starlette.sse:sse.py:156 chunk: b'data: 3\r\n\r\n' +DEBUG sse_starlette.sse:sse.py:156 chunk: b'data: 4\r\n\r\n' +DEBUG sse_starlette.sse:sse.py:211 ping: b': ping - 2026-01-29 16:58:03.907870+00:00\r\n\r\n' +DEBUG sse_starlette.sse:sse.py:156 chunk: b'data: 5\r\n\r\n' +DEBUG sse_starlette.sse:sse.py:177 Got event: http.disconnect. Stop streaming. +INFO httpx:_client.py:1038 HTTP Request: GET http://testserver/ "HTTP/1.1 200 OK" +--------------------------- Captured stderr teardown --------------------------- +2026-01-30 06:58:04 DEBUG asyncio __init__:64 Using selector: EpollSelector +---------------------------- Captured log teardown ----------------------------- +DEBUG asyncio:selector_events.py:64 Using selector: EpollSelector +_ TestEventSourceResponse.test_response_send_whenValidInput_thenGeneratesExpectedOutput[dict_with_event-\r-event: message\rdata: 1\r\r] _ +self = +reset_appstatus_event = None +mock_generator = .numbers at 0x7fc4616db9c0> +input_type = 'dict_with_event', separator = '\r' +expected_output = b'event: message\rdata: 1\r\r' + + @pytest.mark.parametrize( + "input_type,separator,expected_output", + [ + ("integer", "\r\n", b"data: 1\r\n\r\n"), + ("dict_simple", "\r\n", b"data: 1\r\n\r\n"), + ("dict_with_event", "\r\n", b"event: message\r\ndata: 1\r\n\r\n"), + ("dict_with_event", "\r", b"event: message\rdata: 1\r\r"), + ], + ) + async def test_response_send_whenValidInput_thenGeneratesExpectedOutput( + self, + reset_appstatus_event, + mock_generator, + input_type, + separator, + expected_output, + ): + # Arrange + async def app(scope, receive, send): + async def format_output(value): + if input_type == "integer": + return value + elif input_type == "dict_simple": + return dict(data=value) + else: + return dict(data=value, event="message") + + async def generate(): + generator = mock_generator(1, 5) + async for value in generator: + yield await format_output(value) + + response = EventSourceResponse(generate(), ping=0.2, sep=separator) + await response(scope, receive, send) + + # Act + client = TestClient(app) + response = client.get("/") + + # Assert + assert expected_output in response.content +> assert response.content.decode().count("ping") == 2 +E AssertionError: assert 3 == 2 +E + where 3 = ('ping') +E + where = 'event: message\rdata: 1\r\r: ping - 2026-01-29 16:58:05.674473+00:00\r\revent: message\rdata: 2\r\revent: message\rda...05.875618+00:00\r\revent: message\rdata: 4\r\r: ping - 2026-01-29 16:58:06.077340+00:00\r\revent: message\rdata: 5\r\r'.count +E + where 'event: message\rdata: 1\r\r: ping - 2026-01-29 16:58:05.674473+00:00\r\revent: message\rdata: 2\r\revent: message\rda...05.875618+00:00\r\revent: message\rdata: 4\r\r: ping - 2026-01-29 16:58:06.077340+00:00\r\revent: message\rdata: 5\r\r' = () +E + where = b'event: message\rdata: 1\r\r: ping - 2026-01-29 16:58:05.674473+00:00\r\revent: message\rdata: 2\r\revent: message\rd...05.875618+00:00\r\revent: message\rdata: 4\r\r: ping - 2026-01-29 16:58:06.077340+00:00\r\revent: message\rdata: 5\r\r'.decode +E + where b'event: message\rdata: 1\r\r: ping - 2026-01-29 16:58:05.674473+00:00\r\revent: message\rdata: 2\r\revent: message\rd...05.875618+00:00\r\revent: message\rdata: 4\r\r: ping - 2026-01-29 16:58:06.077340+00:00\r\revent: message\rdata: 5\r\r' = .content + +tests/test_sse.py:82: AssertionError +---------------------------- Captured stderr setup ----------------------------- +2026-01-30 06:58:05 DEBUG asyncio __init__:64 Using selector: EpollSelector +------------------------------ Captured log setup ------------------------------ +DEBUG asyncio:selector_events.py:64 Using selector: EpollSelector +----------------------------- Captured stderr call ----------------------------- +2026-01-30 06:58:05 DEBUG asyncio __init__:64 Using selector: EpollSelector +2026-01-30 06:58:05 DEBUG sse_starlette.sse _stream_response:156 chunk: b'event: message\rdata: 1\r\r' +2026-01-30 06:58:05 DEBUG sse_starlette.sse _ping:211 ping: b': ping - 2026-01-29 16:58:05.674473+00:00\r\r' +2026-01-30 06:58:05 DEBUG sse_starlette.sse _stream_response:156 chunk: b'event: message\rdata: 2\r\r' +2026-01-30 06:58:05 DEBUG sse_starlette.sse _stream_response:156 chunk: b'event: message\rdata: 3\r\r' +2026-01-30 06:58:05 DEBUG sse_starlette.sse _ping:211 ping: b': ping - 2026-01-29 16:58:05.875618+00:00\r\r' +2026-01-30 06:58:05 DEBUG sse_starlette.sse _stream_response:156 chunk: b'event: message\rdata: 4\r\r' +2026-01-30 06:58:06 DEBUG sse_starlette.sse _ping:211 ping: b': ping - 2026-01-29 16:58:06.077340+00:00\r\r' +2026-01-30 06:58:06 DEBUG sse_starlette.sse _stream_response:156 chunk: b'event: message\rdata: 5\r\r' +2026-01-30 06:58:06 DEBUG sse_starlette.sse _listen_for_disconnect:177 Got event: http.disconnect. Stop streaming. +2026-01-30 06:58:06 INFO httpx _send_single_request:1038 HTTP Request: GET http://testserver/ "HTTP/1.1 200 OK" +------------------------------ Captured log call ------------------------------- +DEBUG asyncio:selector_events.py:64 Using selector: EpollSelector +DEBUG sse_starlette.sse:sse.py:156 chunk: b'event: message\rdata: 1\r\r' +DEBUG sse_starlette.sse:sse.py:211 ping: b': ping - 2026-01-29 16:58:05.674473+00:00\r\r' +DEBUG sse_starlette.sse:sse.py:156 chunk: b'event: message\rdata: 2\r\r' +DEBUG sse_starlette.sse:sse.py:156 chunk: b'event: message\rdata: 3\r\r' +DEBUG sse_starlette.sse:sse.py:211 ping: b': ping - 2026-01-29 16:58:05.875618+00:00\r\r' +DEBUG sse_starlette.sse:sse.py:156 chunk: b'event: message\rdata: 4\r\r' +DEBUG sse_starlette.sse:sse.py:211 ping: b': ping - 2026-01-29 16:58:06.077340+00:00\r\r' +DEBUG sse_starlette.sse:sse.py:156 chunk: b'event: message\rdata: 5\r\r' +DEBUG sse_starlette.sse:sse.py:177 Got event: http.disconnect. Stop streaming. +INFO httpx:_client.py:1038 HTTP Request: GET http://testserver/ "HTTP/1.1 200 OK" +--------------------------- Captured stderr teardown --------------------------- +2026-01-30 06:58:06 DEBUG asyncio __init__:64 Using selector: EpollSelector +---------------------------- Captured log teardown ----------------------------- +DEBUG asyncio:selector_events.py:64 Using selector: EpollSelector =============================== warnings summary =============================== tests/test_sse.py::TestEventSourceResponse::test_disconnect_whenClientDisconnects_thenHandlesGracefully /usr/lib/python3/dist-packages/starlette/routing.py:599: DeprecationWarning: The on_startup and on_shutdown parameters are deprecated, and they will be removed on version 1.0. Use the lifespan parameter instead. See more about it on https://www.starlette.io/lifespan/. warnings.warn( -- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html -======================== 44 passed, 1 warning in 8.53s ========================= - create-stamp debian/debhelper-build-stamp - dh_testroot -O--buildsystem=pybuild - dh_prep -O--buildsystem=pybuild - dh_auto_install --destdir=debian/python3-sse-starlette/ -O--buildsystem=pybuild -I: pybuild plugin_pyproject:178: Copying package built for python3.13 to destdir -I: pybuild plugin_pyproject:178: Copying package built for python3.12 to destdir - dh_installdocs -O--buildsystem=pybuild - dh_installchangelogs -O--buildsystem=pybuild - dh_installexamples -O--buildsystem=pybuild - dh_python3 -O--buildsystem=pybuild - dh_installsystemduser -O--buildsystem=pybuild - dh_perl -O--buildsystem=pybuild - dh_link -O--buildsystem=pybuild - dh_strip_nondeterminism -O--buildsystem=pybuild - dh_compress -O--buildsystem=pybuild - dh_fixperms -O--buildsystem=pybuild - dh_missing -O--buildsystem=pybuild - dh_installdeb -O--buildsystem=pybuild - dh_gencontrol -O--buildsystem=pybuild - dh_md5sums -O--buildsystem=pybuild - dh_builddeb -O--buildsystem=pybuild -dpkg-deb: building package 'python3-sse-starlette' in '../python3-sse-starlette_2.2.1-1_all.deb'. - dpkg-genbuildinfo --build=binary -O../python-sse-starlette_2.2.1-1_amd64.buildinfo - dpkg-genchanges --build=binary -O../python-sse-starlette_2.2.1-1_amd64.changes -dpkg-genchanges: info: binary-only upload (no source code included) - dpkg-source --after-build . -dpkg-source: info: using options from python-sse-starlette-2.2.1/debian/source/options: --extend-diff-ignore=^[^/]*[.]egg-info/ -dpkg-buildpackage: info: binary-only upload (no source included) -dpkg-genchanges: info: including full source code in upload +=========================== short test summary info ============================ +FAILED tests/test_sse.py::TestEventSourceResponse::test_response_send_whenValidInput_thenGeneratesExpectedOutput[integer-\r\n-data: 1\r\n\r\n] +FAILED tests/test_sse.py::TestEventSourceResponse::test_response_send_whenValidInput_thenGeneratesExpectedOutput[dict_with_event-\r-event: message\rdata: 1\r\r] +=================== 2 failed, 42 passed, 1 warning in 8.89s ==================== +E: pybuild pybuild:389: test: plugin pyproject failed with: exit code=1: cd /build/reproducible-path/python-sse-starlette-2.2.1/.pybuild/cpython3_3.12_sse_starlette/build; python3.12 -m pytest --ignore tests/experimentation/test_multiple_consumers_asyncio.py --ignore tests/experimentation/test_multiple_consumers_threads.py --ignore tests/integration/test_multiple_consumers.py +dh_auto_test: error: pybuild --test --test-pytest -i python{version} -p "3.13 3.12" returned exit code 13 +make: *** [debian/rules:14: binary] Error 25 +dpkg-buildpackage: error: debian/rules binary subprocess returned exit status 2 I: copying local configuration +E: Failed autobuilding of package +I: user script /srv/workspace/pbuilder/579511/tmp/hooks/C01_cleanup starting +debug output: disk usage on i-capture-the-hostname at Thu Jan 29 16:58:12 UTC 2026 +Filesystem Size Used Avail Use% Mounted on +tmpfs 40G 0 40G 0% /dev/shm + +I: user script /srv/workspace/pbuilder/579511/tmp/hooks/C01_cleanup finished I: unmounting dev/ptmx filesystem I: unmounting dev/pts filesystem I: unmounting dev/shm filesystem I: unmounting proc filesystem I: unmounting sys filesystem I: cleaning the build env -I: removing directory /srv/workspace/pbuilder/2529655 and its subdirectories -I: Current time: Thu Dec 26 22:33:23 -12 2024 -I: pbuilder-time-stamp: 1735295603 +I: removing directory /srv/workspace/pbuilder/579511 and its subdirectories