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

Allow explicit select of docstring rule to override configured convention #2606

Closed
ngnpope opened this issue Feb 6, 2023 · 23 comments · Fixed by #8586
Closed

Allow explicit select of docstring rule to override configured convention #2606

ngnpope opened this issue Feb 6, 2023 · 23 comments · Fixed by #8586
Labels
configuration Related to settings and configuration

Comments

@ngnpope
Copy link
Contributor

ngnpope commented Feb 6, 2023

I know this is documented...

Setting a convention force-disables any rules that are incompatible with that convention, no matter how they're provided, which avoids accidental incompatibilities and simplifies configuration.

...but it seems a little excessive in some cases.

In particular, convention = "pep257" disables D212 and D213. PEP 257 states:

The summary line may be on the same line as the opening quotes or on the next line.

But I'd like to be a little stricter. I'd like to have convention = "pep257" and force enable D213. Not sure whether this is best as a new configuration option to make it something you have to explicitly opt in to, e.g. force-enable = ["D213"]?

(Using v0.0.241.)

@charliermarsh
Copy link
Member

I think this was overly aggressive. We can reconsider. It was done to avoid things like users accidentally enabling both D212 and D213, which led to infinite autofix loops. But we since "solved" that with #2369. So we could instead treat conventions slightly differently.

@charliermarsh charliermarsh added configuration Related to settings and configuration core Related to core functionality and removed core Related to core functionality labels Feb 6, 2023
@charliermarsh
Copy link
Member

It probably makes sense to treat convention as equivalent to inlining an extend-select.

@ngnpope
Copy link
Contributor Author

ngnpope commented Feb 6, 2023

Aye, that sounds like how I expected it to work

@smackesey
Copy link

smackesey commented Mar 10, 2023

Came here to say that I added convention = "google" but was unsure how it would interact with my existing set of D ignores. Went looking for answers under convention in the docs but didn't find anything. What's the current behavior?

@charliermarsh
Copy link
Member

The current behavior is that it turns off any rules that are incompatible with the convention.

So, specifically, convention = "google" is equivalent to ignoring D203, D204, D213, D215, D400, D401, D404, D406, D407, D408, D409, and D413.

So for Dagster, you can remove that first block of (non-google docstring) ignores. That is, I think you'd want:

[tool.ruff]
select = ["D"]
ignore = [
  # (missing public docstrings) These work off of the Python sense of "public", rather than our
  # bespoke definition based off of `@public`. When ruff supports custom plugins then we can write
  # appropriate rules to require docstrings for `@public`.
  "D100",
  "D101",
  "D102",
  "D103",
  "D104",
  "D105",
  "D106",
  "D107",

  ##### TEMPORARY DISABLES

  # (assorted docstring rules) There are too many violations of these to enable
  # right now, but we should enable after fixing the violations.
  "D200",  # (one-line docstring should fit)
  "D205",  # (blank line after summary)
  "D212",  # (multi-line docstring summary should start at 1st line)
  "D415",  # (docstring summary should end with a period)
  "D417",  # (missing arg in docstring)

  # (indent docstring rules) These rules should be enabled when ruff lands
  # on/off style comments, which would allow turning them off for specific
  # docstrings.
  "D207", # (under-indented docstring)
  "D208", # (over-indented docstring)
  "D402", # (first line should not be the function's "signature")
]

[tool.ruff.pydocstyle]
convention = "google"

@ssbarnea
Copy link

ssbarnea commented Apr 29, 2023

The situation seem to be worse for those deciding to use select = ["ALL"] as apparently you get two warnings that you cannot silence in any way (adding to ignore does not work), neither trying to define convention = "pep257" - even if documentation states that it should work.

warning: `one-blank-line-before-class` (D203) and `no-blank-line-before-class` (D211) are incompatible. Ignoring `one-blank-line-before-class`.
warning: `multi-line-summary-first-line` (D212) and `multi-line-summary-second-line` (D213) are incompatible. Ignoring `multi-line-summary-second-line`.

Does anyone know a way to keep using ALL and avoid these confusing warnings?

@charliermarsh
Copy link
Member

@ssbarnea - Do you mind sharing your configuration? For me, I don't see any warnings with this pyproject.toml:

[tool.ruff]
select = ["ALL"]

[tool.ruff.pydocstyle]
convention = "pep257"

@ssbarnea
Copy link

@charliermarsh Sure, look at https://github.com/ansible/ansible-compat/blob/main/pyproject.toml#L138 -- apparently I get this warning with current ruff too:

$ ruff .
warning: `one-blank-line-before-class` (D203) and `no-blank-line-before-class` (D211) are incompatible. Ignoring `one-blank-line-before-class`.
warning: `multi-line-summary-first-line` (D212) and `multi-line-summary-second-line` (D213) are incompatible. Ignoring `multi-line-summary-second-line`.
 
$ ruff --version
ruff 0.0.267

@charliermarsh
Copy link
Member

@ssbarnea - Thanks, I'll take a look now.

@charliermarsh
Copy link
Member

I'm not seeing those warnings, need to think on why they could be showing up for you:

ansible-compat on  main via 🐍 v3.8.16
❯ ruff . --no-cache
ansible-compat on  main via 🐍 v3.8.16
❯ ruff --version
ruff 0.0.267

@charliermarsh
Copy link
Member

Could you share the output of ruff --show-settings ., if you have time?

@ssbarnea
Copy link

Something is confusing ruff, and apparently is not the cache:

ssbarnea@m1: ~/c/a/ansible-compat chore/test
$ ruff .
warning: `one-blank-line-before-class` (D203) and `no-blank-line-before-class` (D211) are incompatible. Ignoring `one-blank-line-before-class`.
warning: `multi-line-summary-first-line` (D212) and `multi-line-summary-second-line` (D213) are incompatible. Ignoring `multi-line-summary-second-line`.

ssbarnea@m1: ~/c/a/ansible-compat chore/test
$ ruff --version
ruff 0.0.267

ssbarnea@m1: ~/c/a/ansible-compat chore/test
$ ruff --no-cache .
warning: `one-blank-line-before-class` (D203) and `no-blank-line-before-class` (D211) are incompatible. Ignoring `one-blank-line-before-class`.
warning: `multi-line-summary-first-line` (D212) and `multi-line-summary-second-line` (D213) are incompatible. Ignoring `multi-line-summary-second-line`.

Result of settings dump https://gist.github.com/ssbarnea/18819983d585ad1ed674e1a2e2b49616

@charliermarsh
Copy link
Member

Is there any way you have something like a ruff.toml or .ruff.toml or pyproject.toml in the filesystem (under ansible-compat) that's not tracked by Git? That could trigger this message but wouldn't show up with --show-settings.

(Do you not see the warnings when you run --show-settings? Or were they omitted from the settings dump?)

@ssbarnea
Copy link

You are right, I see the warning without even doing anything:

$ ruff --show-settings
warning: `one-blank-line-before-class` (D203) and `no-blank-line-before-class` (D211) are incompatible. Ignoring `one-blank-line-before-class`.
warning: `multi-line-summary-first-line` (D212) and `multi-line-summary-second-line` (D213) are incompatible. Ignoring `multi-line-summary-second-line`.
error: Expected at least one path to search for Python files
FAIL: 2

I do not have any other ruff config file in my filesystem other than the git-tracked one at https://github.com/ansible/ansible-lint/blob/main/pyproject.toml#L225-L262

@tlambert03
Copy link

just wanna add my +1 to this request. Specifically, I'd love to be able to simply add D417 to numpy docstrings.

[tool.ruff]
extend-select = ["D417"]
[tool.ruff.pydocstyle]
convention = "numpy"

Currently, I do this by manually including the full numpy include/exclude spec just so I can keep D417.

@smackesey
Copy link

smackesey commented Jul 16, 2023

Revisiting to say that IMO the current docs are still too uninformative-- if I read https://beta.ruff.rs/docs/settings/#pydocstyle-convention it is not obvious what this does in terms of select/ignore.

If the content from #2606 (comment) were posted in the docs that would go a ways.

@charliermarsh
Copy link
Member

charliermarsh commented Jul 17, 2023

For now, I expanded on the documentation in #5819.

@alanhdu
Copy link
Contributor

alanhdu commented Nov 9, 2023

I've been taking a look at this and quite surprised by the behavior. From a code POV, I think the fix should be simple: changing

for rule in convention.rules_to_be_ignored() {
rules.disable(*rule);
}

to something more like:

 for rule in convention.rules_to_be_ignored() { 
    if !rules.enabled(*rule) {
        rules.disable(*rule);
    }     
 } 

which would turn the rules off-by-default but allow users to force override it. My question is whether that would be the right path forward, or if we want something more complicated (e.g. if there are rules that are truly incompatible with a convention, then we can distinguish convention.incompatilbe_rules() from convention.off_by_default_rules(). @charliermarsh -- do you have any guidance on what the desired outcome here is? I'm happy to send a PR either way.

(I also have, uestions aboutf where these rules for the conventions came from -- I would've expected several of them to have been on by default for the numpy convention at least, but I'm happy to move that out of this issue's discussion).

@charliermarsh
Copy link
Member

@alanhdu -- Thanks for taking a look! I think the fix isn't quite that simple. We probably need some logic like: if the rule wasn't explicitly selected (like --select D200, as opposed to --select D), then we should force it off. For each rules_to_be_ignored, we could check if the rule was included verbatim in any of the select or extend_select selectors?

@alanhdu
Copy link
Contributor

alanhdu commented Nov 9, 2023

Yeah, I agree this is a little trickier than I first thought. I filed #8586 with what I think is a reasonable approach -- would be happy to discuss more about the implementation there!

@charliermarsh
Copy link
Member

Nice, thanks @alanhdu! Will take a look at that PR later today or tomorrow.

charliermarsh pushed a commit that referenced this issue Nov 10, 2023
## Summary

This fixes #2606 by moving where we apply the convention ignores --
instead of applying that at the very end, e track, we now track which
rules have been specifically enabled (via `Specificity::Rule`). If they
have, then we do *not* apply the docstring overrides at the end.

## Test Plan

Added unit tests to `ruff_workspace` and an integration test to
`ruff_cli`
@tlambert03
Copy link

hooray!! Thanks @alanhdu!

@sorenmc
Copy link

sorenmc commented Aug 15, 2024

For anyone else wanting to add D417 while using numpy convention you have to explicitly include it as

[tool.ruff.lint]
extend-select = ["D", <other selections>, "D417"]

[tool.ruff.lint.pydocstyle]
convention = "numpy" 

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
configuration Related to settings and configuration
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants