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

[pycodestyle] Fix: Don't autofix if the first line ends in a question mark? (D400) #13399

Merged
merged 9 commits into from
Sep 20, 2024

Conversation

yahayaohinoyi
Copy link
Contributor

@yahayaohinoyi yahayaohinoyi commented Sep 18, 2024

Summary

Fixes #13365

The autofix for D400 currently changes this:

def should_frob() -> bool:
    """Should we frob the bar?"""

To this:

def should_frob() -> bool:
    """Should we frob the bar?."""

Which seems pretty clearly worse! We probably just shouldn't offer an autofix if the first line ends in a question mark or exclamation mark?

DESCRIPTION

Basically, we don't want a diagnostic when we don't set a fix for this rule

checker.diagnostics.push(diagnostic);
.

Test Plan

Holistically followed the instructions here https://docs.astral.sh/ruff/contributing/#rule-testing-fixtures-and-snapshots

Copy link
Contributor

github-actions bot commented Sep 18, 2024

ruff-ecosystem results

Linter (stable)

✅ ecosystem check detected no linter changes.

Linter (preview)

✅ ecosystem check detected no linter changes.

Copy link
Member

@AlexWaygood AlexWaygood left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR! I think we should still emit a diagnostic if the first line ends in a question mark or exclamation mark, though, since according to PEP 257 the docstring isn't following the conventional style if it doesn't end in a period. We just shouldn't offer an autofix for the diagnostic if it ends in a question mark or exclamation mark, since we don't know what the appropriate autofix would be in that situation.

I left some inline suggestions below that should be sufficient to address this -- though you'll need to regenerate the snapshots again!

Comment on lines 111 to 112
checker.diagnostics.push(diagnostic);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
checker.diagnostics.push(diagnostic);
}
}
checker.diagnostics.push(diagnostic);

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we still need to move the checker.diagnostic.push call outside the trimmed.ends_with branch or we omit diagnostics for docstring summaries that end in !. We actually see this because I would expect to see more diagnostics in ruff_linter__rules__pydocstyle__tests__D415_D415.py.snap

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we still need to move the checker.diagnostic.push call outside the trimmed.ends_with branch or we omit diagnostics for docstring summaries that end in !. We actually see this because I would expect to see more diagnostics in ruff_linter__rules__pydocstyle__tests__D415_D415.py.snap

Does it look any better now?

Copy link
Member

@MichaReiser MichaReiser left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See @AlexWaygood's comments

@yahayaohinoyi yahayaohinoyi marked this pull request as draft September 19, 2024 07:16
@yahayaohinoyi yahayaohinoyi force-pushed the d400-not-autofix-some-chars branch from c337764 to a8c1523 Compare September 19, 2024 21:50
@yahayaohinoyi
Copy link
Contributor Author

yahayaohinoyi commented Sep 19, 2024

Need some help!. I get failures like
failures: rules::pydocstyle::tests::rules::rule_endsinperiod_path_new_d_py_expects
after running the tests. How do I get visibility of what exactly fails? Even when I remove the content of the whole file the test still fails. Also doesn't generate any snapshots

@MichaReiser
Copy link
Member

Running the test gives me:

cargo test rules::pydocstyle::tests::rules::rule_endsinperiod_path_new_d_py_expects -p ruff_linter
    Finished `test` profile [unoptimized + debuginfo] target(s) in 0.08s
     Running unittests src/lib.rs (target/debug/deps/ruff_linter-93716c3568a00bf4)

running 1 test
test rules::pydocstyle::tests::rules::rule_endsinperiod_path_new_d_py_expects ... FAILED

failures:

---- rules::pydocstyle::tests::rules::rule_endsinperiod_path_new_d_py_expects stdout ----
thread 'rules::pydocstyle::tests::rules::rule_endsinperiod_path_new_d_py_expects' panicked at crates/ruff_linter/src/test.rs:254:21:
Rule EndsInPeriod is marked to always-fixable but the diagnostic has no fix.
Either ensure you always emit a fix or change `Violation::FIX_AVAILABILITY` to either `FixAvailability::Sometimes` or `FixAvailability::None`
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace


failures:
    rules::pydocstyle::tests::rules::rule_endsinperiod_path_new_d_py_expects

test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 2108 filtered out; finished in 0.01s

The important bits are

thread 'rules::pydocstyle::tests::rules::rule_endsinperiod_path_new_d_py_expects' panicked at crates/ruff_linter/src/test.rs:254:21:
Rule EndsInPeriod is marked to always-fixable but the diagnostic has no fix.
Either ensure you always emit a fix or change `Violation::FIX_AVAILABILITY` to either `FixAvailability::Sometimes` or `FixAvailability::None`

It's telling you that the Violation should no longer implement AlwaysFixableViolation and instead explicitly set the Fixability to Sometimes

impl Violation for EndsInPeriod {
    /// `None` in the case a fix is never available or otherwise Some
    /// [`FixAvailability`] describing the available fix.
    const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes;

    #[derive_message_formats]
    fn message(&self) -> String {
        format!("First line should end with a period")
    }

    fn fix_title(&self) -> String {
        "Add period".to_string()
    }
}

@yahayaohinoyi yahayaohinoyi marked this pull request as ready for review September 20, 2024 08:08
@MichaReiser MichaReiser added bug Something isn't working rule Implementing or modifying a lint rule labels Sep 20, 2024
@@ -46,14 +46,18 @@ use crate::rules::pydocstyle::helpers::logical_line;
#[violation]
pub struct EndsInPunctuation;

impl AlwaysFixableViolation for EndsInPunctuation {
impl Violation for EndsInPunctuation {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice find

Copy link
Member

@MichaReiser MichaReiser left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you

@MichaReiser MichaReiser enabled auto-merge (squash) September 20, 2024 11:01
@MichaReiser MichaReiser merged commit 03f3a4e into astral-sh:main Sep 20, 2024
16 checks passed
netbsd-srcmastr pushed a commit to NetBSD/pkgsrc that referenced this pull request Oct 7, 2024
## 0.6.9

### Preview features

- Fix codeblock dynamic line length calculation for indented docstring examples ([#13523](astral-sh/ruff#13523))
- \[`refurb`\] Mark `FURB118` fix as unsafe ([#13613](astral-sh/ruff#13613))

### Rule changes

- \[`pydocstyle`\] Don't raise `D208` when last line is non-empty ([#13372](astral-sh/ruff#13372))
- \[`pylint`\] Preserve trivia (i.e. comments) in `PLR5501` autofix ([#13573](astral-sh/ruff#13573))

### Configuration

- \[`pyflakes`\] Add `allow-unused-imports` setting for `unused-import` rule (`F401`) ([#13601](astral-sh/ruff#13601))

### Bug fixes

- Support ruff discovery in pip build environments ([#13591](astral-sh/ruff#13591))
- \[`flake8-bugbear`\] Avoid short circuiting `B017` for multiple context managers ([#13609](astral-sh/ruff#13609))
- \[`pylint`\] Do not offer an invalid fix for `PLR1716` when the comparisons contain parenthesis ([#13527](astral-sh/ruff#13527))
- \[`pyupgrade`\] Fix `UP043` to apply to `collections.abc.Generator` and `collections.abc.AsyncGenerator` ([#13611](astral-sh/ruff#13611))
- \[`refurb`\] Fix handling of slices in tuples for `FURB118`, e.g., `x[:, 1]` ([#13518](astral-sh/ruff#13518))

### Documentation

- Update GitHub Action link to `astral-sh/ruff-action` ([#13551](astral-sh/ruff#13551))

## 0.6.8

### Preview features

- Remove unnecessary parentheses around `match case` clauses ([#13510](astral-sh/ruff#13510))
- Parenthesize overlong `if` guards in `match..case` clauses ([#13513](astral-sh/ruff#13513))
- Detect basic wildcard imports in `ruff analyze graph` ([#13486](astral-sh/ruff#13486))
- \[`pylint`\] Implement `boolean-chained-comparison` (`R1716`) ([#13435](astral-sh/ruff#13435))

### Rule changes

- \[`lake8-simplify`\] Detect `SIM910` when using variadic keyword arguments, i.e., `**kwargs` ([#13503](astral-sh/ruff#13503))
- \[`pyupgrade`\] Avoid false negatives with non-reference shadowed bindings of loop variables (`UP028`) ([#13504](astral-sh/ruff#13504))

### Bug fixes

- Detect tuples bound to variadic positional arguments i.e. `*args` ([#13512](astral-sh/ruff#13512))
- Exit gracefully on broken pipe errors ([#13485](astral-sh/ruff#13485))
- Avoid panic when analyze graph hits broken pipe ([#13484](astral-sh/ruff#13484))

### Performance

- Reuse `BTreeSets` in module resolver ([#13440](astral-sh/ruff#13440))
- Skip traversal for non-compound statements ([#13441](astral-sh/ruff#13441))

## 0.6.7

### Preview features

- Add Python version support to ruff analyze CLI ([#13426](astral-sh/ruff#13426))
- Add `exclude` support to `ruff analyze` ([#13425](astral-sh/ruff#13425))
- Fix parentheses around return type annotations ([#13381](astral-sh/ruff#13381))

### Rule changes

- \[`pycodestyle`\] Fix: Don't autofix if the first line ends in a question mark? (D400) ([#13399](astral-sh/ruff#13399))

### Bug fixes

- Respect `lint.exclude` in ruff check `--add-noqa` ([#13427](astral-sh/ruff#13427))

### Performance

- Avoid tracking module resolver files in Salsa ([#13437](astral-sh/ruff#13437))
- Use `forget` for module resolver database ([#13438](astral-sh/ruff#13438))

## 0.6.6

### Preview features

- \[`refurb`\] Skip `slice-to-remove-prefix-or-suffix` (`FURB188`) when non-trivial slice steps are present ([#13405](astral-sh/ruff#13405))
- Add a subcommand to generate dependency graphs ([#13402](astral-sh/ruff#13402))

### Formatter

- Fix placement of inline parameter comments ([#13379](astral-sh/ruff#13379))

### Server

- Fix off-by one error in the `LineIndex::offset` calculation ([#13407](astral-sh/ruff#13407))

### Bug fixes

- \[`fastapi`\] Respect FastAPI aliases in route definitions ([#13394](astral-sh/ruff#13394))
- \[`pydocstyle`\] Respect word boundaries when detecting function signature in docs ([#13388](astral-sh/ruff#13388))

### Documentation

- Add backlinks to rule overview linter ([#13368](astral-sh/ruff#13368))
- Fix documentation for editor vim plugin ALE ([#13348](astral-sh/ruff#13348))
- Fix rendering of `FURB188` docs ([#13406](astral-sh/ruff#13406))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working rule Implementing or modifying a lint rule
Projects
None yet
Development

Successfully merging this pull request may close these issues.

D400: bad autofix if the first line ends in a question mark
3 participants