Skip to content
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

Line break within function declaration disables exclusion of the function body #684

Closed
fuine opened this issue Jul 20, 2018 · 11 comments · Fixed by #1705
Closed

Line break within function declaration disables exclusion of the function body #684

fuine opened this issue Jul 20, 2018 · 11 comments · Fixed by #1705
Labels
bug Something isn't working exclude fixed

Comments

@fuine
Copy link

fuine commented Jul 20, 2018

.coveragerc file:

[report]
exclude_lines =
    long_function_name.+

Code:

def long_function_name(some_long_argument,  another_long_argument):
    pass

This setup works and results in the following report:

Name      Stmts   Miss  Cover   Missing
---------------------------------------
file.py       0      0   100%

However, if a line break is introduced between arguments and the second line gets indented in compliance to the PEP-8:

def long_function_name(some_long_argument,
                       another_long_argument):
    pass

Then the body isn't excluded anymore:

Name      Stmts   Miss  Cover   Missing
---------------------------------------
file.py       1      1     0%   4

I'm not really sure if this is a bug, but I haven't found a way to bypass this behaviour - I would like the whole function excluded, regardless of the formatting of function arguments. Is this possible?

@nedbat
Copy link
Owner

nedbat commented Dec 31, 2018

Hmm, there is logic in coverage.py to make multi-line statements act as a single unit. I'll need to look into why that isn't happening in this case.

Can you tell me more about your actual code and configuration? Why exclude functions based on their name?

@tailaiw
Copy link

tailaiw commented Feb 25, 2020

I ran into exactly the same issue. So we have an update on it? Thanks!

I'm using python3.8, coverage 5.0.3, pytest 5.3.5, and pytest-cov 2.8.1.

Here is my main.py code

def my_func(
    super_long_input_argument_0=0,
    super_long_input_argument_1=1,
    super_long_input_argument_2=2):
    pass

def my_func_2(super_long_input_argument_0=0, super_long_input_argument_1=1, super_long_input_argument_2=2):
    pass

def test_main():
    assert 1 == 1

Here is my .coveragerc

[report]
show_missing = True
exclude_lines =
    def my_func
    def my_func_2

And here is the output running pytest main.py --cov=.

platform linux -- Python 3.8.1, pytest-5.3.5, py-1.8.1, pluggy-0.13.1
rootdir: blablabla
plugins: cov-2.8.1
collected 1 item                                                                                                                                                                            

main.py .                                                                                                                                                                             [100%]

----------- coverage: platform linux, python 3.8.1-final-0 -----------
Name      Stmts   Miss  Cover   Missing
---------------------------------------
main.py       3      1    67%   5

@FateScript
Copy link

Gently ask, any progress of this issue?
I work around this problem by using ast module and expect a more elegent way, thanks.

@nedbat
Copy link
Owner

nedbat commented Aug 29, 2023

@FateScript Thanks for chiming in. Can you say more about how you are using the ast module?

@FateScript
Copy link

@FateScript Thanks for chiming in. Can you say more about how you are using the ast module?

@nedbat My idea is simple, if a function like

def long_function_name(some_long_argument,
                       another_long_argument):
    # python code here

is marked as executed, the lineno of def long_function_name(some_long_argument, will be recorded.
I get the lineno and determine if it's a definition of function, and if it is, my target is to parse a function like

def long_function_name(some_long_argument,
                       another_long_argument):
    pass

Here is a sketch of my code:

def complete_definition(code: List[str], executed_lineno: int) -> List[int]:
    src_code = code[executed_lineno-1]  # -1 because lineno starts from 1
    select_lineno = [executed_lineno]
    if is_function_def(src_code):
        func_suffix = (count_blank_prefix(src_code) + 4) * " " + "pass"  # indent length is 4 here
        while True:
            if pass_ast_parse(src_code + func_suffix):
                break
            # add next line of code
            executed_lineno += 1
            select_lineno.add(executed_lineno)
            src_code = src_code + "\n" + code[executed_lineno-1]
    return select_lineno

The method might not be perfect but somehow fix my issue.
May it help someone.

@nedbat
Copy link
Owner

nedbat commented Aug 31, 2023

One solution to this is to use pragma comments instead of omit settings:

def my_func(
    super_long_input_argument_0=0,
    super_long_input_argument_1=1,
    super_long_input_argument_2=2):     # pragma: no cover
    pass

You'll need to be sure your exclude_lines setting still includes "pragma: no cover", or use the newer [report] exclude_also setting for your custom exclusions:

[report]
show_missing = True
exclude_also =
    def my_func
    def my_func_2

@FateScript
Copy link

FateScript commented Sep 1, 2023

@nedbat Thanks for your solution : )
However, I'm writing a tracing tools with coveragepy to trace code execution in packages like pytorch or langchain, so I couldn't modify the source code of those packages and I'm not sure which function will be executed.

@nedbat
Copy link
Owner

nedbat commented Sep 1, 2023

@FateScript this gets more and more interesting! Can you say more about why you want to omit certain functions within pytorch/langchain?

@FateScript
Copy link

@nedbat The tracing tool will show users what code is executed for a specific function. However, when import a package likeimport torch, it will introduce some functions that might to omit and only a small part of code is needed.
For example, if someone wonder what code is executed when running

x = MyModule()
x(1)

The tracing tool will show something like the following

filename: path to torch.nn.module

class Module():
    def __init__(self, xxx):
        # code of init
    def __call__(self, xxx):
        # code of init

In this case, class Module, __init__ , __call__ is executed when import torch and code of __init__, __call__ is executed when running my code. So I need to omit some function when import torch and I couldn't list them all before executing.
Looking forward to your suggestions or constructive ideas. Thanks : )

@altendky
Copy link

My use case, present in the example in #1691, is to exclude my benchmark tests since they are executed in a separate test run without coverage measurement. They all use a common pytest fixture so that would be what I try to exclude.

nedbat pushed a commit to kajakaj/coveragepy that referenced this issue Dec 2, 2023
nedbat pushed a commit to kajakaj/coveragepy that referenced this issue Dec 2, 2023
nedbat pushed a commit to kajakaj/coveragepy that referenced this issue Dec 2, 2023
nedbat added a commit to kajakaj/coveragepy that referenced this issue Dec 2, 2023
nedbat pushed a commit that referenced this issue Dec 2, 2023
nedbat pushed a commit that referenced this issue Dec 2, 2023

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
nedbat added a commit that referenced this issue Dec 2, 2023
@nedbat nedbat removed the next label Dec 2, 2023
@nedbat
Copy link
Owner

nedbat commented Dec 14, 2023

This is now released as part of coverage 7.3.3.

renovate bot referenced this issue in allenporter/flux-local Dec 16, 2023

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
[![Mend
Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [coverage](https://togithub.com/nedbat/coveragepy) | `==7.3.2` ->
`==7.3.3` |
[![age](https://developer.mend.io/api/mc/badges/age/pypi/coverage/7.3.3?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/pypi/coverage/7.3.3?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/pypi/coverage/7.3.2/7.3.3?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/pypi/coverage/7.3.2/7.3.3?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|

---

### Release Notes

<details>
<summary>nedbat/coveragepy (coverage)</summary>

###
[`v7.3.3`](https://togithub.com/nedbat/coveragepy/blob/HEAD/CHANGES.rst#Version-733--2023-12-14)

[Compare
Source](https://togithub.com/nedbat/coveragepy/compare/7.3.2...7.3.3)

- Fix: function definitions with multi-line signatures can now be
excluded by
matching any of the lines, closing `issue 684`*. Thanks, `Jan Rusak,
    Maciej Kowalczyk and Joanna Ejzel <pull 1705_>`*.

- Fix: XML reports could fail with a TypeError if files had numeric
components
    that were duplicates except for leading zeroes, like `file1.py` and
    `file001.py`.  Fixes `issue 1709`\_.

- The `coverage annotate` command used to announce that it would be
removed
in a future version. Enough people got in touch to say that they use it,
so
it will stay. Don't expect it to keep up with other new features though.

-   Added new :ref:`debug options <cmd_run_debug>`:

    -   `pytest` writes the pytest test name into the debug output.

- `dataop2` writes the full data being added to CoverageData objects.

.. \_issue
684:[https://github.com/nedbat/coveragepy/issues/684](https://togithub.com/nedbat/coveragepy/issues/684)4
.. \_pull
1705[https://github.com/nedbat/coveragepy/pull/1705](https://togithub.com/nedbat/coveragepy/pull/1705)05
.. \_issue
170[https://github.com/nedbat/coveragepy/issues/1709](https://togithub.com/nedbat/coveragepy/issues/1709)709

.. \_changes\_7-3-2:

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR has been generated by [Mend
Renovate](https://www.mend.io/free-developer-tools/renovate/). View
repository job log
[here](https://developer.mend.io/github/allenporter/flux-local).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy45My4xIiwidXBkYXRlZEluVmVyIjoiMzcuOTMuMSIsInRhcmdldEJyYW5jaCI6Im1haW4ifQ==-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
@nedbat nedbat added the fixed label Oct 7, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working exclude fixed
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants