Skip to content

Coverage mislabeling async for #1223

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

Closed
Skelmis opened this issue Sep 24, 2021 · 8 comments
Closed

Coverage mislabeling async for #1223

Skelmis opened this issue Sep 24, 2021 · 8 comments
Labels
bug Something isn't working cpython Reported as a bug in CPython

Comments

@Skelmis
Copy link

Skelmis commented Sep 24, 2021

Describe the bug
When attempting to generate coverage on an async for statement it says the loop did not complete, when it has, as indicated by the rest of the coverage.

        async for guild in self.cache.get_all_guilds():
            # Loop code here

        await self.cache.drop()

This results in await self.cache.drop() being marked green / run, but also getting a partial error with the async for 'not completing'. This results in

> Line xxx didn't jump to line yyy, because the loop on line xxx didn't complete

To Reproduce
How can we reproduce the problem? Please be specific. Don't just link to a failing CI job. Answer the questions below:

  1. What version of Python are you using?
  2. 3.9.7
  3. What version of coverage.py are you using? The output of coverage debug sys is helpful.
  4. -- sys -------------------------------------------------------
    version: 5.5
    coverage: /home/skelmis/Python/DPY-Anti-Spam/venv/lib/python3.9/site-packages/coverage/init.py
    tracer: -none-
    CTracer: available
    plugins.file_tracers: -none-
    plugins.configurers: -none-
    plugins.context_switchers: -none-
    configs_attempted: .coveragerc
    configs_read: /home/skelmis/Python/DPY-Anti-Spam/.coveragerc
    config_file: /home/skelmis/Python/DPY-Anti-Spam/.coveragerc
    config_contents: b'[run]\nbranch = True\nomit =\n antispam/abc.py\n antispam/init.py\n antispam/caches/init.py\n antispam/caches/memory/init.py\n antispam/caches/redis/init.py\n antispam/dataclasses/init.py\n antispam/enums/init.py\n antispam/plugins/init.py'
    data_file: -none-
    python: 3.9.7 (default, Sep 3 2021, 06:18:44) [GCC 10.3.0]
    platform: Linux-5.10.0-kali9-amd64-x86_64-with-glibc2.31
    implementation: CPython
    executable: /home/skelmis/Python/DPY-Anti-Spam/venv/bin/python
    def_encoding: utf-8
    fs_encoding: utf-8
    pid: 11297
    cwd: /home/skelmis/Python/DPY-Anti-Spam
    path: /home/skelmis/Python/DPY-Anti-Spam/venv/bin
    /usr/lib/python39.zip
    /usr/lib/python3.9
    /usr/lib/python3.9/lib-dynload
    /home/skelmis/Python/DPY-Anti-Spam/venv/lib/python3.9/site-packages
    environment: -none-
    command_line: /home/skelmis/Python/DPY-Anti-Spam/venv/bin/coverage debug sys
    sqlite3_version: 2.6.0
    sqlite3_sqlite_version: 3.36.0
    sqlite3_temp_store: 0
    sqlite3_compile_options: COMPILER=gcc-10.2.1 20210110
    ENABLE_COLUMN_METADATA
    ENABLE_DBSTAT_VTAB
    ENABLE_FTS3
    ENABLE_FTS3_PARENTHESIS
    ENABLE_FTS3_TOKENIZER
    ENABLE_FTS4
    ENABLE_FTS5
    ENABLE_JSON1
    ENABLE_LOAD_EXTENSION
    ENABLE_MATH_FUNCTIONS
    ENABLE_PREUPDATE_HOOK
    ENABLE_RTREE
    ENABLE_SESSION
    ENABLE_STMTVTAB
    ENABLE_UNLOCK_NOTIFY
    ENABLE_UPDATE_DELETE_LIMIT
    HAVE_ISNAN
    LIKE_DOESNT_MATCH_BLOBS
    MAX_SCHEMA_RETRY=25
    MAX_VARIABLE_NUMBER=250000
    OMIT_LOOKASIDE
    SECURE_DELETE
    SOUNDEX
    SYSTEM_MALLOC
    TEMP_STORE=1
    THREADSAFE=1
    USE_URI
  5. What versions of what packages do you have installed? The output of pip freeze is helpful.
  6. aiohttp==3.7.4.post0
    alabaster==0.7.12
    appdirs==1.4.4
    async-timeout==3.0.1
    attrs==21.2.0
    Babel==2.9.1
    backports.entry-points-selectable==1.1.0
    black==21.5b1
    bleach==4.1.0
    certifi==2021.5.30
    cffi==1.14.6
    cfgv==3.3.1
    chardet==4.0.0
    charset-normalizer==2.0.6
    click==8.0.1
    colorama==0.4.4
    colorlog==6.4.1
    coverage==5.5
    coveralls==3.1.0
    cryptography==3.4.8
    discord==1.0.1
    discord.py==1.7.3
    distlib==0.3.2
    docopt==0.6.2
    docutils==0.16
    filelock==3.0.12
    fuzzywuzzy==0.18.0
    hikari==2.0.0.dev101
    hypothesis==6.21.6
    identify==2.2.14
    idna==3.2
    imagesize==1.2.0
    importlib-metadata==4.8.1
    iniconfig==1.1.1
    jeepney==0.7.1
    Jinja2==3.0.1
    keyring==23.2.1
    MarkupSafe==2.0.1
    MouseInfo==0.1.3
    multidict==5.1.0
    mypy-extensions==0.4.3
    nest-asyncio==1.5.1
    nodeenv==1.6.0
    packaging==21.0
    pathspec==0.9.0
    pip-chill==1.0.1
    pkginfo==1.7.1
    platformdirs==2.3.0
    pluggy==1.0.0
    pre-commit==2.13.0
    pure25519==0.0.1
    py==1.10.0
    pycparser==2.20
    PyGetWindow==0.0.9
    Pygments==2.10.0
    PyMsgBox==1.0.9
    pyparsing==2.4.7
    pyperclip==1.8.2
    PyRect==0.1.4
    PyScreeze==0.1.27
    pytest==6.2.5
    pytest-asyncio==0.15.1
    python-Levenshtein==0.12.2
    python3-xlib==0.15
    PyTweening==1.0.3
    pytz==2021.1
    PyYAML==5.4.1
    readme-renderer==29.0
    regex==2021.8.28
    requests==2.26.0
    requests-toolbelt==0.9.1
    rfc3986==1.5.0
    SecretStorage==3.3.1
    six==1.16.0
    snakeviz==2.1.0
    snowballstemmer==2.1.0
    sortedcontainers==2.4.0
    Sphinx==4.2.0
    sphinx-rtd-theme==0.5.2
    sphinxcontrib-applehelp==1.0.2
    sphinxcontrib-devhelp==1.0.2
    sphinxcontrib-htmlhelp==2.0.0
    sphinxcontrib-jsmath==1.0.1
    sphinxcontrib-qthelp==1.0.3
    sphinxcontrib-serializinghtml==1.1.5
    toml==0.10.2
    tornado==6.1
    tqdm==4.62.2
    twine==3.4.1
    typed-ast==1.4.3
    typing-extensions==3.10.0.2
    urllib3==1.26.6
    virtualenv==20.8.0
    webencodings==0.5.1
    yarl==1.6.3
    zipp==3.5.0
  7. What code are you running? Give us a specific commit of a specific repo that we can check out.
  8. https://github.com/Skelmis/DPY-Anti-Spam/tree/rewrite
  9. https://github.com/Skelmis/DPY-Anti-Spam/commit/44af0db7e48b8ae870fee32cbc80fc14c9c1ebc6
  10. What commands did you run?
  11. coverage run --source=antispam -m pytest
  12. coverage html

Expected behavior
The line is marked as complete.

@Skelmis Skelmis added the bug Something isn't working label Sep 24, 2021
@nedbat
Copy link
Owner

nedbat commented Oct 7, 2021

I think this is a dup of #1158, but that also seemed to be fixed in Python 3.9.7. Are you sure that's the version of Python that shows the problem?

@nedbat
Copy link
Owner

nedbat commented Oct 7, 2021

I tested it: the problem does happen with Python 3.9.7, but does not happen with 3.10.0. On 3.10, line 894 in anti_spam_handler.py is marked as completely covered.

@Skelmis
Copy link
Author

Skelmis commented Oct 7, 2021

So is this going to be a won't fix, just upgrade kind of use case? As I am attempting to support multiple python versions.

@nedbat
Copy link
Owner

nedbat commented Oct 8, 2021

I don't think coverage.py can make this better, but I haven't tried to create a reproducible example for the CPython bug tracker yet, so I'm not sure.

You can mark the line as partial with # pragma: no branch if you want to silence the false positive.

@vytas7
Copy link

vytas7 commented Feb 18, 2022

A variation of this happens for me even on 3.10.2: when breaking or returning from an async for loop, the alternative branch of not breaking but jumping back to the loop seems to be missed. It might be caused by genuinely missing tests, but I much doubt that because everything is covered under 3.8.x.

I can try to distill an MRE.

@vytas7
Copy link

vytas7 commented Feb 18, 2022

I went on to file a new issue since it seems it only happens under the above mentioned conditions (not for any kind of async for completion as described in this issue for 3.9): #1324.

@nedbat nedbat added the cpython Reported as a bug in CPython label May 21, 2022
@nedbat
Copy link
Owner

nedbat commented May 21, 2022

Since this is fixed in CPython, I will close this issue.

@nedbat nedbat closed this as not planned Won't fix, can't repro, duplicate, stale May 21, 2022
@alicederyn
Copy link

I have seen a recurrence of this bug in CPython 3.9.18. In case any one else hits it, I figured out a workaround:

async for ...
    ...
else:
    pass

I'm not 100% clear on why this works — I tried adding it because I forgot how else worked and thought it was only run if the for loop is missed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working cpython Reported as a bug in CPython
Projects
None yet
Development

No branches or pull requests

4 participants