Skip to content

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

@vytas7

Description

@vytas7

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions