coveragepy icon indicating copy to clipboard operation
coveragepy copied to clipboard

Branch coverage missing in async for loop w/ break (CPython 3.14.0rc2)

Open vytas7 opened this issue 3 months ago • 0 comments

Describe the bug In certain circumstances, the bug described in #1999 is still reproducible. Unfortunately, I haven't been able to distill these circumstances into a concise MRE as in #1999. 👿 So I acknowledge that this bug report is probably less useful.

To Reproduce Check out the main falcon repository, remove py314 exemptions, and run tox.

If you have access to Docker, this can be distilled into a single docker run invocation:

docker run python:3.14.0rc2 /bin/bash -c "pip install tox && cd /tmp/ && git clone https://github.com/falconry/falcon && cd falcon && git checkout 9fb78bd && sed -i 's/pragma: no py314 cover//' .coveragerc && tox -e mintest,pytest,coverage"

Answer the questions below:

  1. What version of Python are you using? CPython 3.14.0rc2

  2. What version of coverage.py shows the problem? The output of coverage debug sys is helpful. 7.10.4

  3. What versions of what packages do you have installed? The output of pip freeze is helpful. No other packages in the tox environment that is aggregating coverage.

  4. What code shows the problem? Give us a specific commit of a specific repo that we can check out. If you've already worked around the problem, please provide a commit before that fix. falcon's main test suite @ 9fb78bd

  5. What commands should we run to reproduce the problem? Be specific. Include everything, even git clone, pip install, and so on. Explain like we're five!

docker run python:3.14.0rc2 /bin/bash -c "pip install tox && cd /tmp/ && git clone https://github.com/falconry/falcon && cd falcon && git checkout 9fb78bd && sed -i 's/pragma: no py314 cover//' .coveragerc && tox -e mintest,pytest,coverage"

⬇️

Name                                    Stmts   Miss Branch BrPart  Cover   Missing
-----------------------------------------------------------------------------------
falcon/__init__.py                        305      0      0      0   100%
falcon/app.py                             300      0     98      0   100%
falcon/app_helpers.py                     114      0     54      0   100%
falcon/asgi/__init__.py                     8      0      0      0   100%
falcon/asgi/_asgi_helpers.py               35      0     18      0   100%
falcon/asgi/_request_helpers.py            10      0      0      0   100%
falcon/asgi/app.py                        396      0    168      2    99%   691->712, 800->835
falcon/asgi/multipart.py                   88      0     24      0   100%
falcon/asgi/reader.py                     202      0     78      0   100%
falcon/asgi/request.py                    288      0     78      0   100%
falcon/asgi/response.py                    70      0     22      0   100%
falcon/asgi/stream.py                     170      0     66      0   100%
falcon/asgi/structures.py                  65      0     30      0   100%
falcon/asgi/ws.py                         297      0     92      0   100%
falcon/asgi_spec.py                        31      0      0      0   100%
falcon/cmd/__init__.py                      0      0      0      0   100%
falcon/cmd/inspect_app.py                  45      0     10      0   100%
falcon/constants.py                        39      0      0      0   100%
falcon/cyutil/__init__.py                   0      0      0      0   100%
falcon/errors.py                          189      0     12      0   100%
falcon/forwarded.py                        70      0     28      0   100%
falcon/hooks.py                            87      0     28      0   100%
falcon/http_error.py                       67      0     18      0   100%
falcon/http_status.py                      18      0      0      0   100%
falcon/inspect.py                         349      0     94      0   100%
falcon/media/__init__.py                   12      0      0      0   100%
falcon/media/base.py                       40      0      4      0   100%
falcon/media/handlers.py                   68      0      8      0   100%
falcon/media/json.py                       59      0      8      0   100%
falcon/media/msgpack.py                    46      0      4      0   100%
falcon/media/multipart.py                 187      0     40      0   100%
falcon/media/urlencoded.py                 27      0      2      0   100%
falcon/media/validators/__init__.py         2      0      0      0   100%
falcon/media/validators/jsonschema.py      48      0     10      0   100%
falcon/middleware.py                       56      0     32      0   100%
falcon/redirects.py                        34      0     10      0   100%
falcon/request.py                         660      0    214      0   100%
falcon/request_helpers.py                  44      0     18      0   100%
falcon/responders.py                       37      0      4      0   100%
falcon/response.py                        298      0     96      0   100%
falcon/response_helpers.py                 53      0     12      0   100%
falcon/routing/__init__.py                 14      0      0      0   100%
falcon/routing/compiled.py                423      0    114      0   100%
falcon/routing/converters.py               75      0     14      0   100%
falcon/routing/static.py                  145      0     50      0   100%
falcon/routing/util.py                     33      0     14      0   100%
falcon/status_codes.py                    175      0      0      0   100%
falcon/stream.py                           48      0      4      0   100%
falcon/testing/__init__.py                 41      0      0      0   100%
falcon/testing/client.py                  423      0     74      0   100%
falcon/testing/helpers.py                 532      0    218      0   100%
falcon/testing/resource.py                 83      0     18      0   100%
falcon/testing/srmock.py                   26      0      0      0   100%
falcon/testing/test_case.py                13      0      0      0   100%
falcon/typing.py                            7      0      0      0   100%
falcon/uri.py                               9      0      0      0   100%
falcon/util/__init__.py                    38      0      0      0   100%
falcon/util/deprecation.py                 33      0      4      0   100%
falcon/util/mediatypes.py                 124      0     42      0   100%
falcon/util/misc.py                       144      0     58      0   100%
falcon/util/reader.py                     213      0     92      0   100%
falcon/util/structures.py                  74      0     10      0   100%
falcon/util/sync.py                        55      0      8      0   100%
falcon/util/time.py                        16      0      0      0   100%
falcon/util/uri.py                        149      0     66      0   100%
falcon/version.py                           2      0      0      0   100%
-----------------------------------------------------------------------------------
TOTAL                                    7809      0   2166      2    99%

Expected behavior All code is covered on other modern CPython versions such as 3.12, or marked with general pragmas.

Additional context

falcon/asgi/app.py:

Both cases are described in #1999 I believe. The latter 800->835 is clearly a bogus miss since it lands on a finally.

vytas7 avatar Aug 20 '25 18:08 vytas7