Commit graph

357 commits

Author SHA1 Message Date
Charlie Marsh
8d9912a83a
Bump version to v0.1.7 (#8999) 2023-12-04 16:28:23 -05:00
dependabot[bot]
f5d4676c13
Bump ureq from 2.8.0 to 2.9.1 (#8993) 2023-12-04 09:53:25 -06:00
Micha Reiser
cddc696896
Stop at the first resolved parent configuration (#8864) 2023-11-29 04:21:07 +00:00
Alan Du
359a68d18f
Factor out a builder to handle common integration test arguments (#8733)
## Summary

This refactors the `ruff_cli` integration tests to create a new
`RuffCheck` struct -- this holds options to configure the "common case"
flags that we want to pass to Ruff (e.g. `--no-cache`, `--isolated`,
etc). This helps reduce the boilerplate and (IMO) makes it more obvious
what the core logic of each test is by keeping only the "interesting"
parameters.

## Test Plan

`cargo test`
2023-11-22 00:32:01 +00:00
Zanie Blue
d9151b1948
Update ruff check and ruff format to default to the current directory (#8791)
Closes https://github.com/astral-sh/ruff/issues/7347
Closes #3970 via use of `include`

We could update examples in our documentation, but I worry since we do
not have versioned documentation users on older versions would be
confused. Instead, I'll open an issue to track updating use of `ruff
check .` in the documentation sometime in the future.
2023-11-21 11:34:21 -06:00
Charlie Marsh
f460f9c5c0
Bump version to v0.1.6 (#8744) 2023-11-17 13:29:19 -05:00
Vince Chan
e2109c1353
Improve debug printing for resolving origin of config settings (#8729)
## Summary

When running ruff in verbose mode with `-v`, the first debug logs show
where the config settings are taken from. For example:
```
❯ ruff check ./some_file.py -v
[2023-11-17][00:16:25][ruff_cli::resolve][DEBUG] Using pyproject.toml (parent) at /Users/vince/demo/ruff.toml
```

This threw me off for a second because I knew I had no python project
there, and therefore no `pyproject.toml` file. Then I realised it was
actually reading a `ruff.toml` file (obvious when you read the whole
print I suppose) and that the pyproject.toml is a hardcoded string in
the debug log.

I think it would be nice to tweak the wording slightly so it is clear
that the settings don't neccessarily have to come from a
`pyproject.toml` file.
2023-11-17 01:10:36 +00:00
konsti
14e65afdc6
Update to Rust 1.74 and use new clippy lints table (#8722)
Update to [Rust
1.74](https://blog.rust-lang.org/2023/11/16/Rust-1.74.0.html) and use
the new clippy lints table.

The update itself introduced a new clippy lint about superfluous hashes
in raw strings, which got removed.

I moved our lint config from `rustflags` to the newly stabilized
[workspace.lints](https://doc.rust-lang.org/stable/cargo/reference/workspaces.html#the-lints-table).
One consequence is that we have to `unsafe_code = "warn"` instead of
"forbid" because the latter now actually bans unsafe code:

```
error[E0453]: allow(unsafe_code) incompatible with previous forbid
  --> crates/ruff_source_file/src/newlines.rs:62:17
   |
62 |         #[allow(unsafe_code)]
   |                 ^^^^^^^^^^^ overruled by previous forbid
   |
   = note: `forbid` lint level was set on command line
```

---------

Co-authored-by: Charlie Marsh <charlie.r.marsh@gmail.com>
2023-11-16 18:12:46 -05:00
dependabot[bot]
5ba852a878
Bump annotate-snippets from 0.9.1 to 0.9.2 (#8646) 2023-11-13 14:55:15 +00:00
Alan Du
5a1a8bebca
Allow overriding pydocstyle convention rules (#8586)
## 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`
2023-11-10 18:47:37 +00:00
Dhruv Manilawala
3e00ddce38
Preserve trailing semicolon for Notebooks (#8590)
## Summary

This PR updates the formatter to preserve trailing semicolon for Jupyter
Notebooks.

The motivation behind the change is that semicolons in notebooks are
typically used to hide the output, for example when plotting. This is
highlighted in the linked issue.

The conditions required as to when the trailing semicolon should be
preserved are:
1. It should be a top-level statement which is last in the module.
2. For statement, it can be either assignment, annotated assignment, or
augmented assignment. Here, the target should only be a single
identifier i.e., multiple assignments or tuple unpacking isn't
considered.
3. For expression, it can be any.

## Test Plan

Add a new integration test in `ruff_cli`. The test notebook basically
acts as a document as to which trailing semicolons are to be preserved.

fixes: #8254
2023-11-10 21:53:35 +05:30
Charlie Marsh
7968e190dd
Write unchanged, excluded files to stdout when read via stdin (#8596)
## Summary

When you run Ruff via stdin, and pass `format` or `check --fix`, we
typically write the changed or unchanged contents to stdout. It turns
out we forgot to do this when the file is _excluded_, so if you run
`ruff format /path/to/excluded/file.py`, we don't write _anything_ to
`stdout`. This led to a bug in the LSP whereby we deleted file contents
for third-party files.

The right thing to do here is write back the unchanged contents, as it
should always be safe to write the output of stdout back to a file.
2023-11-09 23:15:01 -05:00
Zanie Blue
3956f38999
Prepare release 0.1.5 (#8570)
[Rendered
CHANGELOG](https://github.com/astral-sh/ruff/blob/release/015/CHANGELOG.md#015)
2023-11-08 16:00:57 -06:00
Felix Williams
7391f74cbc
Add hidden --extension to override inference of source type from file extension (#8373)
## Summary

This PR addresses the incompatibility with `jupyterlab-lsp` +
`python-lsp-ruff` arising from the inference of source type from file
extension, raised in #6847.

In particular it follows the suggestion in
https://github.com/astral-sh/ruff/issues/6847#issuecomment-1765724679 to
specify a mapping from file extension to source type.

The source types are

- python
- pyi
- ipynb

Usage:

```sh
ruff check --no-cache --stdin-filename Untitled.ipynb --extension ipynb:python
```

Unlike the original suggestion, `:` instead of `=` is used to associate
file extensions to language since that is what is used with
`--per-file-ignores` which is an existing option that accepts a mapping.

## Test Plan

2 tests added to `integration_test.rs` to ensure the override works as
expected

---------

Co-authored-by: Charlie Marsh <charlie.r.marsh@gmail.com>
2023-11-08 08:02:40 +05:30
Lukasz Piatkowski
03303a9edd
Account for selector specificity when merging extend_unsafe_fixes and override extend_safe_fixes (#8444)
## Summary

Prior to this change `extend_unsafe_fixes` took precedence over
`extend_safe_fixes` selectors, so any conflicts were resolved in favour
of `extend_unsafe_fixes`. Thanks to that ruff were conservatively
assuming that if configs conlict the fix corresponding to selected rule
will be treated as unsafe.

After this change we take into account Specificity of the selectors. For
conflicts between selectors of the same Specificity we will treat the
corresponding fixes as unsafe. But if the conflicting selectors are of
different specificity the more specific one will win.

## Test Plan

Tests were added for the `FixSafetyTable` struct. The
`check_extend_unsafe_fixes_conflict_with_extend_safe_fixes_by_specificity`
integration test was added to test conflicting rules of different
specificity.

Fixes #8404

---------

Co-authored-by: Zanie <contact@zanie.dev>
2023-11-07 10:33:40 -06:00
Aarni Koskela
7dabc4598b
Allow RUFF_NO_CACHE environment variable (like RUFF_CACHE_DIR) (#8538)
## Summary

Being able to set `--no-cache` without touching the command line makes
comparing formatter speed with e.g. Hyperfine a lot easier; Black allows
one to set `BLACK_CACHE_DIR=/dev/null`, but setting
`RUFF_CACHE_DIR=/dev/null` has Ruff choke:

```
error: Failed to initialize cache at /dev/null: Not a directory (os error 20)
error: Failed to initialize cache at /dev/null: Not a directory (os error 20)
warning: Failed to open cache file '/dev/null/0.1.4/18160934645386409287': Not a directory (os error 20)
```

Alternately, we could make a `/dev/null` (or `nul` on Windows) cache
directory imply `--no-cache`?

## Test Plan

None yet.
2023-11-07 08:35:28 -06:00
Charlie Marsh
260ea41975
Bump version to v0.1.4 (#8477) 2023-11-03 14:52:56 -04:00
Zanie Blue
3a889f4686
Add --line-length option to format command (#8363)
Restores the `--line-length` option removed in
https://github.com/astral-sh/ruff/pull/8131

Closes #8362
Closes #8352
2023-11-01 20:39:52 -05:00
Charlie Marsh
1642f4dbd9
Respect --force-exclude for lint.exclude and format.exclude (#8393)
## Summary

We typically avoid enforcing exclusions if a file was passed to Ruff
directly on the CLI. However, we also allow `--force-exclude`, which
ignores excluded files _even_ if they're passed to Ruff directly. This
is really important for pre-commit, which always passes changed files --
we need to exclude files passed by pre-commit if they're in the
`exclude` lists.

Turns out the new `lint.exclude` and `format.exclude` settings weren't
respecting `--force-exclude`.

Closes https://github.com/astral-sh/ruff/issues/8391.
2023-10-31 17:45:48 -04:00
Charlie Marsh
7323c12eee
Avoid duplicating linter-formatter compatibility warnings (#8292)
## Summary

Uses `warn_user_once!` instead of `warn!` to ensure that every warning
is shown exactly once, regardless of whether there are duplicates in the
list, or warnings that are raised by multiple configuration files.

Closes #8271.
2023-10-30 19:32:55 -04:00
Micha Reiser
8cc97f70b4
Dedicated cache directory per ruff version (#8333) 2023-10-30 09:08:30 +00:00
dependabot[bot]
d177df226d
Bump tempfile from 3.8.0 to 3.8.1 (#8345)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-30 09:06:48 +00:00
Charlie Marsh
221f7cd932
Respect --extend-per-file-ignores on the CLI (#8329)
## Summary

This field was being dropped from the CLI.

Closes https://github.com/astral-sh/ruff/issues/8328.
2023-10-29 20:44:24 -04:00
Joshua Bronson
e799f90782
Fix typo (s/adding then/adding them). (#8327)
Noticed this typo and figured I'd submit a drive-by fix.
2023-10-29 22:08:15 +00:00
Charlie Marsh
86cdaea743
Allow selective caching for --fix and --diff (#8316)
## Summary

If a file has no diagnostics, then we can read and write that
information from and to the cache, even if the fix mode is `--fix` or
`--diff`. (Typically, we can't read or write such results from or to the
cache, because `--fix` and `--diff` have side effects that take place
during diagnostic analysis (writing to disk or outputting the diff).)
This greatly improves performance when running `--fix` on a codebase in
the common case (few diagnostics).

Closes #8311.
Closes https://github.com/astral-sh/ruff/issues/8315.
2023-10-29 16:06:35 +00:00
Aarni Koskela
7b4b004506
Harmonize help commands' --format to --output-format with deprecation warnings (#8203)
## Summary

Since `--format` was changed to `--output-format` for `check`, it feels
like it makes sense for the same to work for the auxiliary commands.

This 

* adds the same deprecation warning that used to be a thing in #7514
(and un-became a thing in #7984)

Fixes #7990.

## Test Plan

* `cargo run --bin=ruff -- rule --all --output-format=json` works
* `cargo run --bin=ruff -- rule --format=json` works with warnings
2023-10-28 03:30:46 +00:00
Charlie Marsh
3e7b92991b
Bump version to v0.1.3 (#8259)
Includes the changelog, which I'm currently editing.
2023-10-26 18:57:05 +00:00
Micha Reiser
c32f943d86
Don't warn about magic trailing comma when isort.force-single-line is true (#8244)
## Summary

Based on [this
feedback](https://github.com/astral-sh/ruff/issues/8185#issuecomment-1780092525).
Avoid warning about `force-wrap-aliases` and `split-on-trailing-comma`
if `force-single-line` is true (which creates a dedicated import for
each imported member).

## Test Plan

Ran `ruff format . --no-cache` and verified that the warning show up
when `force-single-line=false` and aren't shown when
`force-single-line=true`
2023-10-26 16:38:20 +00:00
Micha Reiser
a4dd1e5fad
Refine the warnings about incompatible linter options (#8196)
## Summary

Avoid warning about incompatible rules except if their configuration
directly conflicts with the formatter. This should reduce the noise and
potentially the need for https://github.com/astral-sh/ruff/issues/8175
and https://github.com/astral-sh/ruff/issues/8185

I also extended the rule and option documentation to mention any
potential formatter incompatibilities or whether they're redundant when
using the formatter.

* `LineTooLong`: This is a use case we explicitly want to support. Don't
warn about it
* `TabIndentation`, `IndentWithSpaces`: Only warn if
`indent-style="tab"`
* `IndentationWithInvalidMultiple`,
`IndentationWithInvalidMultipleComment`: Only warn if `indent-width !=
4`
* `OverIndented`: Don't warn, but mention that the rule is redundant
* `BadQuotesInlineString`: Warn if quote setting is different from
`format.quote-style`
* `BadQuotesMultilineString`, `BadQuotesDocstring`: Warn if `quote !=
"double"`

## Test Plan

I added a new integration test for the default configuration with `ALL`.
`ruff format` now only shows two incompatible rules, which feels more
reasonable.
2023-10-26 16:22:56 +00:00
Dhruv Manilawala
a7d1f7e1ec
Use SourceKind::diff for formatter (#8240)
## Summary

This PR refactors the formatter diff code to reuse the
`SourceKind::diff` logic. This has the benefit that the Notebook diff
now includes the cell numbers which was not present before.

## Test Plan

Update the snapshots and verified the cell numbers.
2023-10-26 11:08:13 +05:30
Dhruv Manilawala
dbd84c947b
Formatter parentheses support for IpyEscapeCommand (#8207)
## Summary

This PR removes the `todo!()` around `IpyEscapeCommand` in the
formatter.

The `NeedsParentheses` trait needs to be implemented which always return
`Never`. The reason being that if an escape command is parenthesized,
then that's not parsed as an escape command. IOW, the parentheses
shouldn't be present around an escape command.

In the similar way, the `CanSkipOptionalParenthesesVisitor` will skip
this node.

## Test Plan

Updated the `unformatted.ipynb` fixture with new cells containing
IPython escape commands and the corresponding snapshot was verified.
Also, tested it out in a few open source repositories containing
notebooks (`openai/openai-cookbook`, `huggingface/notebooks`).

#### New cells in `unformatted.ipynb`

**Cell 2**
```markdown
A markdown cell
```

**Cell 3**
```python
def some_function(foo, bar):
    pass
%matplotlib inline
```

**Cell 4**
```python
foo = %pwd
def some_function(foo,bar,):
	foo = %pwd
    print(foo
	)
```

fixes: #8204
2023-10-25 14:01:50 +00:00
Micha Reiser
fd07a12a52
Refine warning about incompatible isort settings (#8192) 2023-10-25 08:41:17 +01:00
Charlie Marsh
0236e0751c
Avoid sorting all paths in the format command (#8181)
## Summary

Related to https://github.com/astral-sh/ruff/issues/8135.

If we're not printing a `--diff`, or a summary of `--check` changes, we
can avoid sorting the list of results. Further, when sorting, we only
need to sort a small subset of the entries, in the common case (i.e., in
general, it's much more likely that a file is formatted than not).

## Test Plan

Local benchmarks suggest a 5-10% speedup on the cached behavior:

```
❯ hyperfine --warmup 3 "./target/release/ruff format ../airflow" "./target/release/sort format ../airflow"
Benchmark 1: ./target/release/ruff format ../airflow
  Time (mean ± σ):      70.3 ms ±   5.2 ms    [User: 52.1 ms, System: 59.0 ms]
  Range (min … max):    68.3 ms … 101.7 ms    42 runs

  Warning: Statistical outliers were detected. Consider re-running this benchmark on a quiet PC without any interferences from other programs. It might help to use the '--warmup' or '--prepare' options.

Benchmark 2: ./target/release/sort format ../airflow
  Time (mean ± σ):      66.0 ms ±   1.4 ms    [User: 48.3 ms, System: 58.4 ms]
  Range (min … max):    64.7 ms …  71.8 ms    44 runs

  Warning: Statistical outliers were detected. Consider re-running this benchmark on a quiet PC without any interferences from other programs. It might help to use the '--warmup' or '--prepare' options.

Summary
  './target/release/sort format ../airflow' ran
    1.07 ± 0.08 times faster than './target/release/ruff format ../airflow'
```
2023-10-24 20:54:06 +00:00
Zanie Blue
3127c79b29
Release 0.1.2 (#8168)
[Rendered
changelog](https://github.com/astral-sh/ruff/blob/release/012/CHANGELOG.md)
2023-10-24 15:21:29 +00:00
Micha Reiser
84979f9673
Rename tab-size to indent-width (#8082)
## Summary

This PR renames the `tab-size` configuration option to `indent-width` to
express that the formatter uses the option to determine the indentation
width AND as tab width.

I first preferred naming the option `tab-width` but then decided to go
with `indent-width` because:

* It aligns with the `indent-style` option
* It would allow us to write a lint rule that asserts that each
indentation uses `indent-width` spaces.

 Closes #7643

## Test Plan

Added integration test
2023-10-24 10:01:24 -04:00
Charlie Marsh
c3dabc1933
Un-hide the ruff format command (#8167) 2023-10-24 09:54:28 -04:00
Micha Reiser
9feb86caa4
New pycodestyle.max-line-length option (#8039)
## Summary

This PR introduces a new `pycodestyl.max-line-length` option that allows overriding the global `line-length` option for `E501` only.

This is useful when using the formatter and `E501` together, where the formatter uses a lower limit and `E501` is only used to catch extra-long lines. 

Closes #7644

## Considerations

~~Our fix infrastructure asserts in some places that the fix doesn't exceed the configured `line-width`. With this change, the question is whether it should use the `pycodestyle.max-line-width` or `line-width` option to make that decision.
I opted for the global `line-width` for now, considering that it should be the lower limit. However, this constraint isn't enforced and users not using the formatter may only specify `pycodestyle.max-line-width` because they're unaware of the global option (and it solves their need).~~


~~I'm interested to hear your thoughts on whether we should use `pycodestyle.max-line-width` or `line-width` to decide on whether to emit a fix or not.~~

Edit: The linter users `pycodestyle.max-line-width`. The `line-width` option has been removed from the `LinterSettings`

## Test Plan

Added integration test. Built the documentation and verified that the links are correct.
2023-10-24 17:14:05 +09:00
Charlie Marsh
7f4ea6690d
Remove experimental formatter warning (#8148)
Co-authored-by: Micha Reiser <micha@reiser.io>
2023-10-24 01:26:29 +00:00
Micha Reiser
2f32a57cf4
Remove --line-length option from format command (#8131) 2023-10-24 00:58:01 +01:00
Weijie Guo
7100e12cc3
add auto-fix for E225,226,227,228 (#8136)
## Summary

Introduce auto fix for `E225`,`E226`,`E227`,`E228`. This partially
address https://github.com/astral-sh/ruff/issues/8121.

## Test Plan

Already covered.
2023-10-23 19:00:42 +00:00
Micha Reiser
6199590072
Avoid loading files for cached format results (#8134) 2023-10-23 12:29:13 +01:00
Micha Reiser
08519e22e4
Warn about incompatible formatter options (#8088) 2023-10-23 11:04:20 +01:00
Micha Reiser
6fc35dd075
Add caching to formatter (#8089) 2023-10-23 09:43:08 +01:00
Micha Reiser
2c2ebf952a
Rust 1.73 (#8007) 2023-10-23 02:12:25 +00:00
Zanie Blue
860ffb9549
Add ruff version with long version display (#8034)
Adds a new `ruff version` sub-command which displays long version
information in the style of `cargo` and `rustc`. We include the number
of commits since the last release tag if its a development build, in the
style of Python's versioneer.

```
❯ ruff version
ruff 0.1.0+14 (947940e91 2023-10-18)
```

```
❯ ruff version --output-format json
{
  "version": "0.1.0",
  "commit_info": {
    "short_commit_hash": "947940e91",
    "commit_hash": "947940e91269f20f6b3f8f8c7c63f8e914680e80",
    "commit_date": "2023-10-18",
    "last_tag": "v0.1.0",
    "commits_since_last_tag": 14
  }
}%
```

```
❯ cargo version
cargo 1.72.1 (103a7ff2e 2023-08-15)
```
## Test plan

I've tested this manually locally, but want to at least add unit tests
for the message formatting. We'd also want to check the next release to
ensure the information is correct.

I checked build behavior with a detached head and branches.

## Future work

We could include rustc and cargo versions from the build, the current
Python version, and other diagnostic information for bug reports.

The `--version` and `-V` output is unchanged. However, we could update
it to display the long ruff version without the rust and cargo versions
(this is what cargo does). We'll need to be careful to ensure this does
not break downstream packages which parse our version string.

```
❯ ruff --version
ruff 0.1.0
```

The LSP should be updated to use `ruff version --output-format json`
instead of parsing `ruff --version`.
2023-10-20 14:07:41 -05:00
Micha Reiser
962472da96
Change line-ending default to auto (#8057) 2023-10-20 00:13:11 +01:00
Zanie Blue
22cf451d51
Release 0.1.1 (#8073)
- Add changelog entry for 0.1.1
- Bump version to 0.1.1
- Require preview for fix added in #7967 
- Allow duplicate headings in changelog (markdownlint setting)
2023-10-19 20:49:53 +00:00
Charlie Marsh
2e225d7538
Accept --target-version in the format CLI (#8055)
## Summary

This doesn't affect behavior _yet_ (see:
https://github.com/astral-sh/ruff/issues/7234), but it will be needed in
the future, and it's surprising to users that it doesn't exist.

Closes https://github.com/astral-sh/ruff/issues/8051.
2023-10-18 20:14:20 -04:00
Micha Reiser
4786abac7a
Respect tab-size setting in formatter (#8006) 2023-10-19 00:48:14 +01:00
konsti
51aa73f405
Add --diff option ruff format (#7937)
**Summary** `ruff format --diff` is similar to `ruff format --check`,
but we don't only error with the list of file that would be formatted,
but also show a diff between the unformatted input and the formatted
output.

```console
$ ruff format --diff scratch.py scratch.pyi scratch.ipynb
warning: `ruff format` is not yet stable, and subject to change in future versions.
--- scratch.ipynb
+++ scratch.ipynb
@@ -1,3 +1,4 @@
 import numpy
-maths = (numpy.arange(100)**2).sum()
-stats= numpy.asarray([1,2,3,4]).median()
+
+maths = (numpy.arange(100) ** 2).sum()
+stats = numpy.asarray([1, 2, 3, 4]).median()
--- scratch.py
+++ scratch.py
@@ -1,3 +1,3 @@
 x = 1
-y=2
+y = 2
 z = 3
2 files would be reformatted, 1 file left unchanged
```

With `--diff`, the summary message gets printed to stderr to allow e.g.
`ruff format --diff . > format.patch`.

At the moment, jupyter notebooks are formatted as code diffs, while
everything else is a real diff that could be applied. This means that
the diffs containing jupyter notebooks are not real diffs and can't be
applied. We could change this to json diffs, but they are hard to read.
We could also split the diff option into a human diff option, where we
deviate from the machine readable diff constraints, and a proper machine
readable, appliable diff output that you can pipe into other tools.

To make the tests work, the results (and errors, if any) are sorted
before printing them. Previously, the print order was random, i.e. two
identical runs could have different output.

Open question: Should this go into the markdown docs? Or will this be
subsumed by the integration of the formatter into `ruff check`?

**Test plan** Fixtures for the change and no change cases, including a
jupyter notebook and for file input and stdin.

Fixes #7231

---------

Co-authored-by: Micha Reiser <micha@reiser.io>
2023-10-18 11:55:05 +00:00