Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # 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
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))
# for free to join this conversation on GitHub. Already have an account? # 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