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

perf: only compute start offset for overlong lines #5811

Merged
merged 3 commits into from
Jul 17, 2023

Conversation

sbrugman
Copy link
Contributor

@sbrugman sbrugman commented Jul 16, 2023

Moves the computation of the start_offset for overlong lines to just before the result is returned. There is a slight overhead for overlong lines (double the work for the first limit characters).

In practice this results in a speedup on the CPython codebase. Most lines are not overlong, or are not enforced because the line ends with a URL, or does not contain whitespace. Nonetheless, the 0.3% of overlong lines are a lot compared to other violations.

Before

selected before
Selected W505 and E501

all before
All rules

After

selected after
Selected W505 and E501

all after
All rules

CPython line statistics:

  • Number of Python lines: 867.696
  • Number of overlong lines: 2.963 (0.3%)

Benchmark selected:

cargo build --release && hyperfine --warmup 10 --min-runs 50 \                                                  
  "./target/release/ruff ./crates/ruff/resources/test/cpython/ --no-cache -e --select W505,E501"

Benchmark all:

cargo build --release && hyperfine --warmup 10 --min-runs 50 \                                                  
  "./target/release/ruff ./crates/ruff/resources/test/cpython/ --no-cache -e --select ALL"

Overlong lines in CPython

cargo run -p ruff_cli -- check crates/ruff/resources/test/cpython/Lib --no-cache --select=E501,W505 --statistics

Total Python lines:

find crates/ruff/resources/test/cpython/ -name '*.py' | xargs wc -l

(Performance tested on Mac M1)

Copy link
Member

@konstin konstin left a comment

Choose a reason for hiding this comment

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

amazing, that's a neat speedup

crates/ruff/src/rules/pycodestyle/helpers.rs Outdated Show resolved Hide resolved
Co-authored-by: konsti <konstin@mailbox.org>
@charliermarsh
Copy link
Member

That’s awesome. I’m wondering if there’s another optimization we can make here. Is it faster to compute the number of bytes in the line instead of the width? If so, could we only check lines that have more bytes than the line limit? I think it would be impossible for an overlong line to have fewer bytes than the limit, though lines with more bytes could end up being below the limit.

@github-actions
Copy link
Contributor

github-actions bot commented Jul 16, 2023

PR Check Results

Ecosystem

✅ ecosystem check detected no changes.

Benchmark

Linux

group                                      main                                   pr
-----                                      ----                                   --
formatter/large/dataset.py                 1.00      9.7±0.02ms     4.2 MB/sec    1.01      9.8±0.03ms     4.1 MB/sec
formatter/numpy/ctypeslib.py               1.00   1873.7±1.81µs     8.9 MB/sec    1.01  1899.6±11.00µs     8.8 MB/sec
formatter/numpy/globals.py                 1.00    204.2±0.38µs    14.5 MB/sec    1.02    208.0±2.20µs    14.2 MB/sec
formatter/pydantic/types.py                1.00      4.2±0.01ms     6.1 MB/sec    1.01      4.3±0.04ms     6.0 MB/sec
linter/all-rules/large/dataset.py          1.01     13.7±0.02ms     3.0 MB/sec    1.00     13.6±0.02ms     3.0 MB/sec
linter/all-rules/numpy/ctypeslib.py        1.02      3.5±0.01ms     4.7 MB/sec    1.00      3.5±0.01ms     4.8 MB/sec
linter/all-rules/numpy/globals.py          1.04    385.1±0.62µs     7.7 MB/sec    1.00    370.9±1.48µs     8.0 MB/sec
linter/all-rules/pydantic/types.py         1.01      6.2±0.01ms     4.1 MB/sec    1.00      6.1±0.01ms     4.2 MB/sec
linter/default-rules/large/dataset.py      1.02      7.0±0.02ms     5.8 MB/sec    1.00      6.9±0.01ms     5.9 MB/sec
linter/default-rules/numpy/ctypeslib.py    1.04   1465.6±3.12µs    11.4 MB/sec    1.00   1410.7±2.05µs    11.8 MB/sec
linter/default-rules/numpy/globals.py      1.08    159.8±0.56µs    18.5 MB/sec    1.00    147.9±0.27µs    19.9 MB/sec
linter/default-rules/pydantic/types.py     1.03      3.2±0.01ms     8.1 MB/sec    1.00      3.1±0.01ms     8.3 MB/sec

Windows

group                                      main                                   pr
-----                                      ----                                   --
formatter/large/dataset.py                 1.04     11.3±0.09ms     3.6 MB/sec    1.00     10.9±0.08ms     3.7 MB/sec
formatter/numpy/ctypeslib.py               1.03      2.2±0.04ms     7.5 MB/sec    1.00      2.2±0.04ms     7.7 MB/sec
formatter/numpy/globals.py                 1.03   253.0±24.74µs    11.7 MB/sec    1.00    245.4±5.50µs    12.0 MB/sec
formatter/pydantic/types.py                1.03      4.8±0.05ms     5.3 MB/sec    1.00      4.7±0.06ms     5.4 MB/sec
linter/all-rules/large/dataset.py          1.02     15.4±0.13ms     2.6 MB/sec    1.00     15.1±0.13ms     2.7 MB/sec
linter/all-rules/numpy/ctypeslib.py        1.02      4.1±0.04ms     4.1 MB/sec    1.00      4.0±0.05ms     4.2 MB/sec
linter/all-rules/numpy/globals.py          1.03    500.9±6.14µs     5.9 MB/sec    1.00    486.8±5.58µs     6.1 MB/sec
linter/all-rules/pydantic/types.py         1.02      7.0±0.06ms     3.7 MB/sec    1.00      6.8±0.05ms     3.7 MB/sec
linter/default-rules/large/dataset.py      1.03      8.0±0.05ms     5.1 MB/sec    1.00      7.8±0.04ms     5.2 MB/sec
linter/default-rules/numpy/ctypeslib.py    1.06  1720.4±15.74µs     9.7 MB/sec    1.00  1628.4±12.98µs    10.2 MB/sec
linter/default-rules/numpy/globals.py      1.07    201.3±2.45µs    14.7 MB/sec    1.00    187.3±2.52µs    15.8 MB/sec
linter/default-rules/pydantic/types.py     1.03      3.6±0.03ms     7.1 MB/sec    1.00      3.5±0.03ms     7.3 MB/sec

@MichaReiser
Copy link
Member

That’s awesome. I’m wondering if there’s another optimization we can make here. Is it faster to compute the number of bytes in the line instead of the width? If so, could we only check lines that have more bytes than the line limit? I think it would be impossible for an overlong line to have fewer bytes than the limit, though lines with more bytes could end up being below the limit.

That sounds like a neat optimization. Each character is between 1-4 bytes. Meaning your assumption here is safe.

Checking the byte length is O(1)

@sbrugman
Copy link
Contributor Author

sbrugman commented Jul 16, 2023

check byte length
Selected

all
All

@charliermarsh charliermarsh merged commit a956226 into astral-sh:main Jul 17, 2023
16 checks passed
@charliermarsh charliermarsh added the performance Potential performance improvement label Jul 17, 2023
@sbrugman sbrugman deleted the patch-1 branch July 17, 2023 06:21
evanrittenhouse pushed a commit to evanrittenhouse/ruff that referenced this pull request Jul 19, 2023
Moves the computation of the `start_offset` for overlong lines to just
before the result is returned. There is a slight overhead for overlong
lines (double the work for the first `limit` characters).

In practice this results in a speedup on the CPython codebase. Most
lines are not overlong, or are not enforced because the line ends with a
URL, or does not contain whitespace. Nonetheless, the 0.3% of overlong
lines are a lot compared to other violations.

### Before
![selected
before](https://github.com/astral-sh/ruff/assets/9756388/d32047df-7fd2-4ae8-8333-1a3679ce000f)
_Selected W505 and E501_

![all
before](https://github.com/astral-sh/ruff/assets/9756388/98495118-c474-46ff-873c-fb58a78cfe15)
_All rules_

### After
![selected
after](https://github.com/astral-sh/ruff/assets/9756388/e4bd7f10-ff7e-4d52-8267-27cace8c5471)
_Selected W505 and E501_

![all
after](https://github.com/astral-sh/ruff/assets/9756388/573bdbe2-c64f-4f22-9659-c68726ff52c0)
_All rules_

CPython line statistics:
- Number of Python lines: 867.696
- Number of overlong lines: 2.963 (0.3%)

<details>

Benchmark selected:
```shell
cargo build --release && hyperfine --warmup 10 --min-runs 50 \                                                  
  "./target/release/ruff ./crates/ruff/resources/test/cpython/ --no-cache -e --select W505,E501"
```

Benchmark all:
```shell
cargo build --release && hyperfine --warmup 10 --min-runs 50 \                                                  
  "./target/release/ruff ./crates/ruff/resources/test/cpython/ --no-cache -e --select ALL"
```

Overlong lines in CPython

```shell
cargo run -p ruff_cli -- check crates/ruff/resources/test/cpython/Lib --no-cache --select=E501,W505 --statistics
```

Total Python lines:
```shell
find crates/ruff/resources/test/cpython/ -name '*.py' | xargs wc -l
```

</details>

(Performance tested on Mac M1)
konstin pushed a commit that referenced this pull request Jul 19, 2023
Moves the computation of the `start_offset` for overlong lines to just
before the result is returned. There is a slight overhead for overlong
lines (double the work for the first `limit` characters).

In practice this results in a speedup on the CPython codebase. Most
lines are not overlong, or are not enforced because the line ends with a
URL, or does not contain whitespace. Nonetheless, the 0.3% of overlong
lines are a lot compared to other violations.

### Before
![selected
before](https://github.com/astral-sh/ruff/assets/9756388/d32047df-7fd2-4ae8-8333-1a3679ce000f)
_Selected W505 and E501_

![all
before](https://github.com/astral-sh/ruff/assets/9756388/98495118-c474-46ff-873c-fb58a78cfe15)
_All rules_

### After
![selected
after](https://github.com/astral-sh/ruff/assets/9756388/e4bd7f10-ff7e-4d52-8267-27cace8c5471)
_Selected W505 and E501_

![all
after](https://github.com/astral-sh/ruff/assets/9756388/573bdbe2-c64f-4f22-9659-c68726ff52c0)
_All rules_

CPython line statistics:
- Number of Python lines: 867.696
- Number of overlong lines: 2.963 (0.3%)

<details>

Benchmark selected:
```shell
cargo build --release && hyperfine --warmup 10 --min-runs 50 \                                                  
  "./target/release/ruff ./crates/ruff/resources/test/cpython/ --no-cache -e --select W505,E501"
```

Benchmark all:
```shell
cargo build --release && hyperfine --warmup 10 --min-runs 50 \                                                  
  "./target/release/ruff ./crates/ruff/resources/test/cpython/ --no-cache -e --select ALL"
```

Overlong lines in CPython

```shell
cargo run -p ruff_cli -- check crates/ruff/resources/test/cpython/Lib --no-cache --select=E501,W505 --statistics
```

Total Python lines:
```shell
find crates/ruff/resources/test/cpython/ -name '*.py' | xargs wc -l
```

</details>

(Performance tested on Mac M1)
jankatins added a commit to jankatins/pr-workflow-example that referenced this pull request Jul 22, 2023
[![Mend
Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [ruff](https://beta.ruff.rs/docs)
([source](https://togithub.com/astral-sh/ruff),
[changelog](https://togithub.com/astral-sh/ruff/releases)) | `0.0.278`
-> `0.0.280` |
[![age](https://developer.mend.io/api/mc/badges/age/pypi/ruff/0.0.280?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/pypi/ruff/0.0.280?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/pypi/ruff/0.0.278/0.0.280?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/pypi/ruff/0.0.278/0.0.280?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|

---

### Release Notes

<details>
<summary>astral-sh/ruff (ruff)</summary>

###
[`v0.0.280`](https://togithub.com/astral-sh/ruff/compare/v0.0.279...v0.0.280)

[Compare
Source](https://togithub.com/astral-sh/ruff/compare/v0.0.279...v0.0.280)

###
[`v0.0.279`](https://togithub.com/astral-sh/ruff/releases/tag/v0.0.279)

[Compare
Source](https://togithub.com/astral-sh/ruff/compare/v0.0.278...v0.0.279)

<!-- Release notes generated using configuration in .github/release.yml
at v0.0.279 -->

#### What's Changed

##### Rules

- \[`flake8-pyi`] Implement flake8-pyi's PYI026 by
[@&#8203;LaBatata101](https://togithub.com/LaBatata101) in
[astral-sh/ruff#5844
- \[`flake8-pyi`] Implement flake8-pyi's `PYI017` by
[@&#8203;qdegraaf](https://togithub.com/qdegraaf) in
[astral-sh/ruff#5895
- \[`flake8-pyi`] Implement flake8-pyi's `PYI036` by
[@&#8203;density](https://togithub.com/density) in
[astral-sh/ruff#5668
- \[`flake8-pyi`] Implement flake8-pyi's `PYI041` by
[@&#8203;density](https://togithub.com/density) in
[astral-sh/ruff#5722
- \[`flake8-use-pathlib`] Implement `os-path-getsize` and
`os-path-get(a|m|c)-time` (`PTH202-205`) by
[@&#8203;sbrugman](https://togithub.com/sbrugman) in
[astral-sh/ruff#5835
- \[`flake8-use-pathlib`] Implement `path-constructor-default-argument`
(`PTH201`) by [@&#8203;sbrugman](https://togithub.com/sbrugman) in
[astral-sh/ruff#5833
- \[`pandas-vet`] Implement constant series rule (`PD101`) by
[@&#8203;sbrugman](https://togithub.com/sbrugman) in
[astral-sh/ruff#5802
- \[`pylint`] Implement Pylint's `consider-using-in` (`PLR1714`) by
[@&#8203;tjkuson](https://togithub.com/tjkuson) in
[astral-sh/ruff#5193

##### Rule changes

- \[`flake8-annotations`] Check for `Any` in other types for `ANN401` by
[@&#8203;dhruvmanila](https://togithub.com/dhruvmanila) in
[astral-sh/ruff#5601
- \[`flake8-bugbear`] Add autofix for B004 by
[@&#8203;density](https://togithub.com/density) in
[astral-sh/ruff#5788
- \[`flake8-bugbear`] Remove `B904`'s lowercase exemption by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[astral-sh/ruff#5751
- \[`flake8-use-pathlib`] extend PTH118 with `os.sep` by
[@&#8203;sbrugman](https://togithub.com/sbrugman) in
[astral-sh/ruff#5935
- \[`pyupgrade`] Expand scope of `quoted-annotation` rule (`UP037`) by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[astral-sh/ruff#5766
- \[`pyupgrade`] Extend PEP 604 rewrites to support some quoted
annotations by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[astral-sh/ruff#5725
- \[`ruff`] Expand `RUF015` to include all expression types by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[astral-sh/ruff#5767

##### Bug Fixes

- Consider single element subscript expr for implicit optional by
[@&#8203;dhruvmanila](https://togithub.com/dhruvmanila) in
[astral-sh/ruff#5717
- Ignore `Enum`-and-`str` subclasses for slots enforcement by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[astral-sh/ruff#5749
- Avoid removing raw strings in comparison fixes by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[astral-sh/ruff#5755
- Fix nested calls to `sorted` with differing arguments by
[@&#8203;density](https://togithub.com/density) in
[astral-sh/ruff#5761
- Use unused variable detection to power `incorrect-dict-iterator` by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[astral-sh/ruff#5763
- Include alias when formatting import-from structs by
[@&#8203;guillaumeLepape](https://togithub.com/guillaumeLepape) in
[astral-sh/ruff#5786
- Make `lint_only` aware of the source kind by
[@&#8203;dhruvmanila](https://togithub.com/dhruvmanila) in
[astral-sh/ruff#5876
- Restore `redefined-while-unused` violations in classes by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[astral-sh/ruff#5926
- Flatten nested tuples when fixing UP007 violations by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[astral-sh/ruff#5724
- Ignore Jupyter Notebooks for `--add-noqa` by
[@&#8203;dhruvmanila](https://togithub.com/dhruvmanila) in
[astral-sh/ruff#5727
- Avoid checking `EXE001` and `EXE002` on WSL by
[@&#8203;tjkuson](https://togithub.com/tjkuson) in
[astral-sh/ruff#5735
- Properly group assignment targets by
[@&#8203;MichaReiser](https://togithub.com/MichaReiser) in
[astral-sh/ruff#5728
- Avoid stack overflow for non-BitOr binary types by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[astral-sh/ruff#5743
- Move function visit out of `Expr::Call` branches by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[astral-sh/ruff#5772
- \[B006] Add bytes to immutable types by
[@&#8203;harupy](https://togithub.com/harupy) in
[astral-sh/ruff#5776
- Format `SetComp` by [@&#8203;lkh42t](https://togithub.com/lkh42t) in
[astral-sh/ruff#5774
- Gate `runtime-import-in-type-checking-block` (`TCH004`) behind enabled
flag by [@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[astral-sh/ruff#5789
- perf: only compute start offset for overlong lines by
[@&#8203;sbrugman](https://togithub.com/sbrugman) in
[astral-sh/ruff#5811
- Change `pandas-use-of-dot-read-table` rule to emit only when
`read_table` is used on CSV data by
[@&#8203;tjkuson](https://togithub.com/tjkuson) in
[astral-sh/ruff#5807
- Do not fix `NamedTuple` calls containing both a list of fields and
keywords by [@&#8203;harupy](https://togithub.com/harupy) in
[astral-sh/ruff#5799
- Ignore directories when collecting files to lint by
[@&#8203;harupy](https://togithub.com/harupy) in
[astral-sh/ruff#5775
- Add filename to `noqa` warnings by
[@&#8203;sobolevn](https://togithub.com/sobolevn) in
[astral-sh/ruff#5856
- Handle io errors gracefully by
[@&#8203;konstin](https://togithub.com/konstin) in
[astral-sh/ruff#5611
- Allow `respect_gitignore` when not in a git repo by
[@&#8203;dhruvmanila](https://togithub.com/dhruvmanila) in
[astral-sh/ruff#5937

#### New Contributors

- [@&#8203;eggplants](https://togithub.com/eggplants) made their first
contribution in
[astral-sh/ruff#5741
- [@&#8203;guillaumeLepape](https://togithub.com/guillaumeLepape) made
their first contribution in
[astral-sh/ruff#5786
- [@&#8203;odiseo0](https://togithub.com/odiseo0) made their first
contribution in
[astral-sh/ruff#5888
- [@&#8203;DavidCain](https://togithub.com/DavidCain) made their first
contribution in
[astral-sh/ruff#5889
- [@&#8203;LaBatata101](https://togithub.com/LaBatata101) made their
first contribution in
[astral-sh/ruff#5844

**Full Changelog**:
astral-sh/ruff@v0.0.278...v0.0.279

</details>

---

### Configuration

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

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **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/jankatins/pr-workflow-example).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNi4xMS4wIiwidXBkYXRlZEluVmVyIjoiMzYuMTEuMCIsInRhcmdldEJyYW5jaCI6Im1haW4ifQ==-->
renovate bot added a commit to allenporter/pyrainbird that referenced this pull request Jul 23, 2023
[![Mend
Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [ruff](https://beta.ruff.rs/docs)
([source](https://togithub.com/astral-sh/ruff),
[changelog](https://togithub.com/astral-sh/ruff/releases)) | `==0.0.278`
-> `==0.0.280` |
[![age](https://developer.mend.io/api/mc/badges/age/pypi/ruff/0.0.280?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/pypi/ruff/0.0.280?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/pypi/ruff/0.0.278/0.0.280?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/pypi/ruff/0.0.278/0.0.280?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|

---

### Release Notes

<details>
<summary>astral-sh/ruff (ruff)</summary>

###
[`v0.0.280`](https://togithub.com/astral-sh/ruff/compare/v0.0.279...v0.0.280)

[Compare
Source](https://togithub.com/astral-sh/ruff/compare/v0.0.279...v0.0.280)

###
[`v0.0.279`](https://togithub.com/astral-sh/ruff/releases/tag/v0.0.279)

[Compare
Source](https://togithub.com/astral-sh/ruff/compare/v0.0.278...v0.0.279)

<!-- Release notes generated using configuration in .github/release.yml
at v0.0.279 -->

#### What's Changed

##### Rules

- \[`flake8-pyi`] Implement flake8-pyi's PYI026 by
[@&#8203;LaBatata101](https://togithub.com/LaBatata101) in
[astral-sh/ruff#5844
- \[`flake8-pyi`] Implement flake8-pyi's `PYI017` by
[@&#8203;qdegraaf](https://togithub.com/qdegraaf) in
[astral-sh/ruff#5895
- \[`flake8-pyi`] Implement flake8-pyi's `PYI036` by
[@&#8203;density](https://togithub.com/density) in
[astral-sh/ruff#5668
- \[`flake8-pyi`] Implement flake8-pyi's `PYI041` by
[@&#8203;density](https://togithub.com/density) in
[astral-sh/ruff#5722
- \[`flake8-use-pathlib`] Implement `os-path-getsize` and
`os-path-get(a|m|c)-time` (`PTH202-205`) by
[@&#8203;sbrugman](https://togithub.com/sbrugman) in
[astral-sh/ruff#5835
- \[`flake8-use-pathlib`] Implement `path-constructor-default-argument`
(`PTH201`) by [@&#8203;sbrugman](https://togithub.com/sbrugman) in
[astral-sh/ruff#5833
- \[`pandas-vet`] Implement constant series rule (`PD101`) by
[@&#8203;sbrugman](https://togithub.com/sbrugman) in
[astral-sh/ruff#5802
- \[`pylint`] Implement Pylint's `consider-using-in` (`PLR1714`) by
[@&#8203;tjkuson](https://togithub.com/tjkuson) in
[astral-sh/ruff#5193

##### Rule changes

- \[`flake8-annotations`] Check for `Any` in other types for `ANN401` by
[@&#8203;dhruvmanila](https://togithub.com/dhruvmanila) in
[astral-sh/ruff#5601
- \[`flake8-bugbear`] Add autofix for B004 by
[@&#8203;density](https://togithub.com/density) in
[astral-sh/ruff#5788
- \[`flake8-bugbear`] Remove `B904`'s lowercase exemption by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[astral-sh/ruff#5751
- \[`flake8-use-pathlib`] extend PTH118 with `os.sep` by
[@&#8203;sbrugman](https://togithub.com/sbrugman) in
[astral-sh/ruff#5935
- \[`pyupgrade`] Expand scope of `quoted-annotation` rule (`UP037`) by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[astral-sh/ruff#5766
- \[`pyupgrade`] Extend PEP 604 rewrites to support some quoted
annotations by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[astral-sh/ruff#5725
- \[`ruff`] Expand `RUF015` to include all expression types by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[astral-sh/ruff#5767

##### Bug Fixes

- Consider single element subscript expr for implicit optional by
[@&#8203;dhruvmanila](https://togithub.com/dhruvmanila) in
[astral-sh/ruff#5717
- Ignore `Enum`-and-`str` subclasses for slots enforcement by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[astral-sh/ruff#5749
- Avoid removing raw strings in comparison fixes by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[astral-sh/ruff#5755
- Fix nested calls to `sorted` with differing arguments by
[@&#8203;density](https://togithub.com/density) in
[astral-sh/ruff#5761
- Use unused variable detection to power `incorrect-dict-iterator` by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[astral-sh/ruff#5763
- Include alias when formatting import-from structs by
[@&#8203;guillaumeLepape](https://togithub.com/guillaumeLepape) in
[astral-sh/ruff#5786
- Make `lint_only` aware of the source kind by
[@&#8203;dhruvmanila](https://togithub.com/dhruvmanila) in
[astral-sh/ruff#5876
- Restore `redefined-while-unused` violations in classes by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[astral-sh/ruff#5926
- Flatten nested tuples when fixing UP007 violations by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[astral-sh/ruff#5724
- Ignore Jupyter Notebooks for `--add-noqa` by
[@&#8203;dhruvmanila](https://togithub.com/dhruvmanila) in
[astral-sh/ruff#5727
- Avoid checking `EXE001` and `EXE002` on WSL by
[@&#8203;tjkuson](https://togithub.com/tjkuson) in
[astral-sh/ruff#5735
- Properly group assignment targets by
[@&#8203;MichaReiser](https://togithub.com/MichaReiser) in
[astral-sh/ruff#5728
- Avoid stack overflow for non-BitOr binary types by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[astral-sh/ruff#5743
- Move function visit out of `Expr::Call` branches by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[astral-sh/ruff#5772
- \[B006] Add bytes to immutable types by
[@&#8203;harupy](https://togithub.com/harupy) in
[astral-sh/ruff#5776
- Format `SetComp` by [@&#8203;lkh42t](https://togithub.com/lkh42t) in
[astral-sh/ruff#5774
- Gate `runtime-import-in-type-checking-block` (`TCH004`) behind enabled
flag by [@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[astral-sh/ruff#5789
- perf: only compute start offset for overlong lines by
[@&#8203;sbrugman](https://togithub.com/sbrugman) in
[astral-sh/ruff#5811
- Change `pandas-use-of-dot-read-table` rule to emit only when
`read_table` is used on CSV data by
[@&#8203;tjkuson](https://togithub.com/tjkuson) in
[astral-sh/ruff#5807
- Do not fix `NamedTuple` calls containing both a list of fields and
keywords by [@&#8203;harupy](https://togithub.com/harupy) in
[astral-sh/ruff#5799
- Ignore directories when collecting files to lint by
[@&#8203;harupy](https://togithub.com/harupy) in
[astral-sh/ruff#5775
- Add filename to `noqa` warnings by
[@&#8203;sobolevn](https://togithub.com/sobolevn) in
[astral-sh/ruff#5856
- Handle io errors gracefully by
[@&#8203;konstin](https://togithub.com/konstin) in
[astral-sh/ruff#5611
- Allow `respect_gitignore` when not in a git repo by
[@&#8203;dhruvmanila](https://togithub.com/dhruvmanila) in
[astral-sh/ruff#5937

#### New Contributors

- [@&#8203;eggplants](https://togithub.com/eggplants) made their first
contribution in
[astral-sh/ruff#5741
- [@&#8203;guillaumeLepape](https://togithub.com/guillaumeLepape) made
their first contribution in
[astral-sh/ruff#5786
- [@&#8203;odiseo0](https://togithub.com/odiseo0) made their first
contribution in
[astral-sh/ruff#5888
- [@&#8203;DavidCain](https://togithub.com/DavidCain) made their first
contribution in
[astral-sh/ruff#5889
- [@&#8203;LaBatata101](https://togithub.com/LaBatata101) made their
first contribution in
[astral-sh/ruff#5844

**Full Changelog**:
astral-sh/ruff@v0.0.278...v0.0.279

</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/pyrainbird).

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

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
renovate bot added a commit to allenporter/flux-local that referenced this pull request Jul 24, 2023
[![Mend
Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [ruff](https://beta.ruff.rs/docs)
([source](https://togithub.com/astral-sh/ruff),
[changelog](https://togithub.com/astral-sh/ruff/releases)) | `==0.0.278`
-> `==0.0.280` |
[![age](https://developer.mend.io/api/mc/badges/age/pypi/ruff/0.0.280?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/pypi/ruff/0.0.280?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/pypi/ruff/0.0.278/0.0.280?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/pypi/ruff/0.0.278/0.0.280?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|

---

### Release Notes

<details>
<summary>astral-sh/ruff (ruff)</summary>

###
[`v0.0.280`](https://togithub.com/astral-sh/ruff/releases/tag/v0.0.280)

[Compare
Source](https://togithub.com/astral-sh/ruff/compare/v0.0.279...v0.0.280)

<!-- Release notes generated using configuration in .github/release.yml
at v0.0.280 -->

#### What's Changed

##### Bug Fixes

- Avoid collapsing `elif` and `else` branches during import sorting by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[astral-sh/ruff#5964

**Full Changelog**:
astral-sh/ruff@v0.0.279...v0.0.280

###
[`v0.0.279`](https://togithub.com/astral-sh/ruff/releases/tag/v0.0.279)

[Compare
Source](https://togithub.com/astral-sh/ruff/compare/v0.0.278...v0.0.279)

<!-- Release notes generated using configuration in .github/release.yml
at v0.0.279 -->

#### What's Changed

##### Rules

- \[`flake8-pyi`] Implement flake8-pyi's PYI026 by
[@&#8203;LaBatata101](https://togithub.com/LaBatata101) in
[astral-sh/ruff#5844
- \[`flake8-pyi`] Implement flake8-pyi's `PYI017` by
[@&#8203;qdegraaf](https://togithub.com/qdegraaf) in
[astral-sh/ruff#5895
- \[`flake8-pyi`] Implement flake8-pyi's `PYI036` by
[@&#8203;density](https://togithub.com/density) in
[astral-sh/ruff#5668
- \[`flake8-pyi`] Implement flake8-pyi's `PYI041` by
[@&#8203;density](https://togithub.com/density) in
[astral-sh/ruff#5722
- \[`flake8-use-pathlib`] Implement `os-path-getsize` and
`os-path-get(a|m|c)-time` (`PTH202-205`) by
[@&#8203;sbrugman](https://togithub.com/sbrugman) in
[astral-sh/ruff#5835
- \[`flake8-use-pathlib`] Implement `path-constructor-default-argument`
(`PTH201`) by [@&#8203;sbrugman](https://togithub.com/sbrugman) in
[astral-sh/ruff#5833
- \[`pandas-vet`] Implement constant series rule (`PD101`) by
[@&#8203;sbrugman](https://togithub.com/sbrugman) in
[astral-sh/ruff#5802
- \[`pylint`] Implement Pylint's `consider-using-in` (`PLR1714`) by
[@&#8203;tjkuson](https://togithub.com/tjkuson) in
[astral-sh/ruff#5193

##### Rule changes

- \[`flake8-annotations`] Check for `Any` in other types for `ANN401` by
[@&#8203;dhruvmanila](https://togithub.com/dhruvmanila) in
[astral-sh/ruff#5601
- \[`flake8-bugbear`] Add autofix for B004 by
[@&#8203;density](https://togithub.com/density) in
[astral-sh/ruff#5788
- \[`flake8-bugbear`] Remove `B904`'s lowercase exemption by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[astral-sh/ruff#5751
- \[`flake8-use-pathlib`] extend PTH118 with `os.sep` by
[@&#8203;sbrugman](https://togithub.com/sbrugman) in
[astral-sh/ruff#5935
- \[`pyupgrade`] Expand scope of `quoted-annotation` rule (`UP037`) by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[astral-sh/ruff#5766
- \[`pyupgrade`] Extend PEP 604 rewrites to support some quoted
annotations by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[astral-sh/ruff#5725
- \[`ruff`] Expand `RUF015` to include all expression types by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[astral-sh/ruff#5767

##### Bug Fixes

- Consider single element subscript expr for implicit optional by
[@&#8203;dhruvmanila](https://togithub.com/dhruvmanila) in
[astral-sh/ruff#5717
- Ignore `Enum`-and-`str` subclasses for slots enforcement by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[astral-sh/ruff#5749
- Avoid removing raw strings in comparison fixes by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[astral-sh/ruff#5755
- Fix nested calls to `sorted` with differing arguments by
[@&#8203;density](https://togithub.com/density) in
[astral-sh/ruff#5761
- Use unused variable detection to power `incorrect-dict-iterator` by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[astral-sh/ruff#5763
- Include alias when formatting import-from structs by
[@&#8203;guillaumeLepape](https://togithub.com/guillaumeLepape) in
[astral-sh/ruff#5786
- Make `lint_only` aware of the source kind by
[@&#8203;dhruvmanila](https://togithub.com/dhruvmanila) in
[astral-sh/ruff#5876
- Restore `redefined-while-unused` violations in classes by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[astral-sh/ruff#5926
- Flatten nested tuples when fixing UP007 violations by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[astral-sh/ruff#5724
- Ignore Jupyter Notebooks for `--add-noqa` by
[@&#8203;dhruvmanila](https://togithub.com/dhruvmanila) in
[astral-sh/ruff#5727
- Avoid checking `EXE001` and `EXE002` on WSL by
[@&#8203;tjkuson](https://togithub.com/tjkuson) in
[astral-sh/ruff#5735
- Properly group assignment targets by
[@&#8203;MichaReiser](https://togithub.com/MichaReiser) in
[astral-sh/ruff#5728
- Avoid stack overflow for non-BitOr binary types by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[astral-sh/ruff#5743
- Move function visit out of `Expr::Call` branches by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[astral-sh/ruff#5772
- \[B006] Add bytes to immutable types by
[@&#8203;harupy](https://togithub.com/harupy) in
[astral-sh/ruff#5776
- Format `SetComp` by [@&#8203;lkh42t](https://togithub.com/lkh42t) in
[astral-sh/ruff#5774
- Gate `runtime-import-in-type-checking-block` (`TCH004`) behind enabled
flag by [@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[astral-sh/ruff#5789
- perf: only compute start offset for overlong lines by
[@&#8203;sbrugman](https://togithub.com/sbrugman) in
[astral-sh/ruff#5811
- Change `pandas-use-of-dot-read-table` rule to emit only when
`read_table` is used on CSV data by
[@&#8203;tjkuson](https://togithub.com/tjkuson) in
[astral-sh/ruff#5807
- Do not fix `NamedTuple` calls containing both a list of fields and
keywords by [@&#8203;harupy](https://togithub.com/harupy) in
[astral-sh/ruff#5799
- Ignore directories when collecting files to lint by
[@&#8203;harupy](https://togithub.com/harupy) in
[astral-sh/ruff#5775
- Add filename to `noqa` warnings by
[@&#8203;sobolevn](https://togithub.com/sobolevn) in
[astral-sh/ruff#5856
- Handle io errors gracefully by
[@&#8203;konstin](https://togithub.com/konstin) in
[astral-sh/ruff#5611
- Allow `respect_gitignore` when not in a git repo by
[@&#8203;dhruvmanila](https://togithub.com/dhruvmanila) in
[astral-sh/ruff#5937

#### New Contributors

- [@&#8203;eggplants](https://togithub.com/eggplants) made their first
contribution in
[astral-sh/ruff#5741
- [@&#8203;guillaumeLepape](https://togithub.com/guillaumeLepape) made
their first contribution in
[astral-sh/ruff#5786
- [@&#8203;odiseo0](https://togithub.com/odiseo0) made their first
contribution in
[astral-sh/ruff#5888
- [@&#8203;DavidCain](https://togithub.com/DavidCain) made their first
contribution in
[astral-sh/ruff#5889
- [@&#8203;LaBatata101](https://togithub.com/LaBatata101) made their
first contribution in
[astral-sh/ruff#5844

**Full Changelog**:
astral-sh/ruff@v0.0.278...v0.0.279

</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:eyJjcmVhdGVkSW5WZXIiOiIzNi4xMS4wIiwidXBkYXRlZEluVmVyIjoiMzYuMTEuMCIsInRhcmdldEJyYW5jaCI6Im1haW4ifQ==-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
charliermarsh added a commit that referenced this pull request Aug 11, 2023
## Summary

In #5811, I suggested that we add
a heuristic to the overlong-lines check such that if the line had fewer
bytes than the character limit, we return early -- the idea being that a
single byte per character was the "worst case". I overlooked that this
isn't true for tabs -- with tabs, the "worst case" scenario is that
every byte is a tab, which can have a width greater than 1.

Closes #6425.

## Test Plan

`cargo test` with a new fixture borrowed from the issue, plus manual
testing.
durumu pushed a commit to durumu/ruff that referenced this pull request Aug 12, 2023
## Summary

In astral-sh#5811, I suggested that we add
a heuristic to the overlong-lines check such that if the line had fewer
bytes than the character limit, we return early -- the idea being that a
single byte per character was the "worst case". I overlooked that this
isn't true for tabs -- with tabs, the "worst case" scenario is that
every byte is a tab, which can have a width greater than 1.

Closes astral-sh#6425.

## Test Plan

`cargo test` with a new fixture borrowed from the issue, plus manual
testing.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
performance Potential performance improvement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants