Skip to content

[complexity] Add unnecessary-regular-expression-compile - #25533

Merged
ntBre merged 17 commits into
astral-sh:mainfrom
anishgirianish:ruff-unnecessary-regex-compile
Oct 20, 2026
Merged

ntBre merged 17 commits into
astral-sh:mainfrom
anishgirianish:ruff-unnecessary-regex-compile

Conversation

@anishgirianish

@anishgirianish anishgirianish commented Jun 1, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Adds unnecessary-regular-expression-compile (RUF078, preview). It flags re.compile(p).match(s) and similar, where the compiled pattern is only ever used right there. In that case re.match(p, s) does the same thing without the extra object. Patterns stored in a variable are left alone, since that usually signals the pattern is meant to be reused.

Closes #14691.

Test Plan

cargo test -p ruff_mdtest --test mdtest -- unnecessary-regular-expression-compile

@astral-sh-bot
astral-sh-bot Bot requested a review from ntBre June 1, 2026 18:27
@anishgirianish
anishgirianish marked this pull request as draft June 1, 2026 18:28
@astral-sh-bot

astral-sh-bot Bot commented Jun 1, 2026 •

Copy link
Copy Markdown

ruff-ecosystem results

Linter (stable)

βœ… ecosystem check detected no linter changes.

Linter (preview)

ℹ️ ecosystem check detected linter changes. (+7 -0 violations, +0 -0 fixes in 4 projects; 54 projects unchanged)

PlasmaPy/PlasmaPy (+1 -0 violations, +0 -0 fixes)

ruff check --no-cache --exit-zero --no-fix --output-format concise --preview

+ .github/scripts/citation_updater.py:66:29: unnecessary-regular-expression-compile Compiled regular expression is used only once

apache/airflow (+4 -0 violations, +0 -0 fixes)

ruff check --no-cache --exit-zero --no-fix --output-format concise --preview --select ALL

+ kubernetes-tests/tests/kubernetes_tests/test_base.py:134:18: unnecessary-regular-expression-compile Compiled regular expression is used only once
+ kubernetes-tests/tests/kubernetes_tests/test_base.py:142:18: unnecessary-regular-expression-compile Compiled regular expression is used only once
+ kubernetes-tests/tests/kubernetes_tests/test_base.py:391:18: unnecessary-regular-expression-compile Compiled regular expression is used only once
+ task-sdk/src/airflow/sdk/definitions/dag.py:1466:25: unnecessary-regular-expression-compile Compiled regular expression is used only once

scikit-build/scikit-build-core (+1 -0 violations, +0 -0 fixes)

ruff check --no-cache --exit-zero --no-fix --output-format concise --preview

+ src/scikit_build_core/settings/skbuild_overrides.py:102:17: unnecessary-regular-expression-compile Compiled regular expression is used only once

astropy/astropy (+1 -0 violations, +0 -0 fixes)

ruff check --no-cache --exit-zero --no-fix --output-format concise --preview

+ astropy/coordinates/solar_system.py:177:8: unnecessary-regular-expression-compile Compiled regular expression is used only once

Changes by rule (1 rules affected)

code total + violation - violation + fix - fix
unnecessary-regular-expression-compile 7 7 0 0 0

@anishgirianish
anishgirianish marked this pull request as ready for review June 1, 2026 20:00
…gex-compile

# Conflicts:
#	crates/ruff_linter/src/codes.rs

@ntBre ntBre left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks, this looks good to me overall! As usual, Codex came up with some edge cases that might be worth looking into.

First, I believe the binding.references() count is only counting textual references, so a case like this:

p = re.compile(...)
for x in range(100):
    p.match(...)

only looks like one reference. This occurs in a couple of ecosystem projects:

Somewhat similarly, I don't think the rule is accounting for rebindings currently. So a conditional case like this can be incorrect:

pattern = Matcher()
if condition:
    pattern = re.compile("a")
return pattern.match(value)

This one is the least problematic, or at least seems the most rare, but we might also want to check for side effects in the re.compile arguments because these will only be evaluated once if the rule is followed. Something like this:

re.compile(get_pattern()).match(get_string())

@ntBre ntBre added rule Implementing or modifying a lint rule preview Related to preview-mode features labels Jun 24, 2026
@anishgirianish anishgirianish changed the title [ruff] Add unnecessary-regular-expression-compile (RUF076) [ruff] Add unnecessary-regular-expression-compile (RUF077) Jun 25, 2026

@ntBre ntBre left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks, this is looking good. I found a few more edge cases and a possible small simplification.

@ntBre ntBre changed the title [ruff] Add unnecessary-regular-expression-compile (RUF077) [ruff] Add unnecessary-regular-expression-compile (RUF077) Jul 31, 2026
…gex-compile

# Conflicts:
#	crates/ruff_linter/src/codes.rs
@anishgirianish anishgirianish changed the title [ruff] Add unnecessary-regular-expression-compile (RUF077) [ruff] Add unnecessary-regular-expression-compile (RUF078) Sep 9, 2026
@anishgirianish

Copy link
Copy Markdown
Contributor Author

Thanks, this is looking good. I found a few more edge cases and a possible small simplification.

Hi @ntBre , thank you so much for the review, I have updated pr resolving the feedbacks. Would like to request you for re-review, when ever you get a chance.

Thank you

@ntBre

ntBre commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

Thanks for working on this and dealing with all my comments! I feel bad mentioning this in light of all the work you've put in, but what do you think about restricting the rule to the inline case rather than trying to track assignments and loops and such? This occurred to me today when reviewing again for a few reasons:

  • this is the case described in the original issue
  • tracking assignments and control flow introduces a lot of complexity into the rule that is hard to get right (Codex found another small bug today)
  • Codex pointed out that the re module actually caches compiled regex patterns, even across calls (https://github.com/python/cpython/blob/ebf955df7a89ed0c7968f79faec1de49f61ed7cb/Lib/re/__init__.py#L321-L330). This means the performance justification for the rule is weaker than I thought. It really is more about complexity or style.
  • applying the rule to the single-use case seems more opinionated. I think more people would be interested in the inline case, whereas a separate re.compile call feels more intentional

@anishgirianish

anishgirianish commented Sep 26, 2026 •

Copy link
Copy Markdown
Contributor Author

Hi @ntBre, thank you so much for the re-review. I've restricted the rule to the inline
re.compile(...).method(...) form and removed the binding tracking, along with its tests and docs. Whenever you have a moment, would like to request you for your another look

@anishgirianish

Copy link
Copy Markdown
Contributor Author

Hi @ntBre, whenever you have a free moment I'd love your thoughts on the latest changes. Thanks so much!

@ntBre ntBre left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thank you! And sorry for the delay. This looks good to me, I just had a couple of small suggestions remaining.

Comment thread crates/ruff_linter/src/codes.rs Resolved
@anishgirianish anishgirianish changed the title [ruff] Add unnecessary-regular-expression-compile (RUF078) [ruff] Add `unnecessary-regular-expression-compile Oct 19, 2026
@anishgirianish anishgirianish changed the title [ruff] Add `unnecessary-regular-expression-compile [ruff] Add unnecessary-regular-expression-compile Oct 19, 2026
@anishgirianish

Copy link
Copy Markdown
Contributor Author

Hi @ntBre, thank you so much for re-review. I have pushed the changes resolving feedback's in the latest commit. Would like to request you for your re-review, whenever you get a chance. Thank you

@ntBre ntBre left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Great, thank you!

@ntBre ntBre changed the title [ruff] Add unnecessary-regular-expression-compile [complexity] Add unnecessary-regular-expression-compile Oct 20, 2026
@ntBre
ntBre merged commit 47a28e3 into astral-sh:main Oct 20, 2026
52 checks passed
rlichtenwalter added a commit to rlichtenwalter/dir2text that referenced this pull request Oct 30, 2026
This PR contains the following updates:

| Package | Type | Update | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|---|---|
| [DavidAnson/markdownlint-cli2](https://github.com/DavidAnson/markdownlint-cli2) | repository | minor | `v0.23.3` β†’ `v0.24.0` | ![age](https://developer.mend.io/api/mc/badges/age/github-tags/DavidAnson%2fmarkdownlint-cli2/v0.24.0?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/github-tags/DavidAnson%2fmarkdownlint-cli2/v0.23.3/v0.24.0?slim=true) |
| [ruff](https://docs.astral.sh/ruff) ([source](https://github.com/astral-sh/ruff), [changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md)) | dependency-groups | patch | `==0.17.1` β†’ `==0.17.3` | ![age](https://developer.mend.io/api/mc/badges/age/pypi/ruff/0.17.3?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/pypi/ruff/0.17.1/0.17.3?slim=true) |

Note: The `pre-commit` manager in Renovate is not supported by the `pre-commit` maintainers or community. Please do not report any problems there, instead [create a Discussion in the Renovate repository](https://github.com/renovatebot/renovate/discussions/new) if you have any questions.

---

### Release Notes

<details>
<summary>DavidAnson/markdownlint-cli2</summary>

### [`v0.24.0`](DavidAnson/markdownlint-cli2@v0.23.3...v0.24.0)

[Compare Source](DavidAnson/markdownlint-cli2@v0.23.3...v0.24.0)

</details>

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

### [`v0.17.3`](https://github.com/astral-sh/ruff/blob/HEAD/CHANGELOG.md#0173)

[Compare Source](astral-sh/ruff@0.17.2...0.17.3)

Released on 2026-10-26.

##### Preview features

- \[`suspicious`] Add `shared-clock-mock` ([#&#8203;29074](astral-sh/ruff#29074))

##### Bug fixes

- \[`pyupgrade`] Avoid incorrect conversions to f-strings (`UP032`) ([#&#8203;25485](astral-sh/ruff#25485))

##### Performance

- Buffer stdout in `ruff format` ([#&#8203;29631](astral-sh/ruff#29631))
- Specialize ASCII identifier lexing ([#&#8203;29503](astral-sh/ruff#29503))
- Speed up identifier and keyword lexing ([#&#8203;29463](astral-sh/ruff#29463))

##### Documentation

- \[`flake8-bandit`] Describe what the rule actually checks for `httpx` (`S113`) ([#&#8203;27936](astral-sh/ruff#27936))

##### Contributors

- [@&#8203;itsvedantkumar](https://github.com/itsvedantkumar)
- [@&#8203;charliermarsh](https://github.com/charliermarsh)
- [@&#8203;anishgirianish](https://github.com/anishgirianish)

### [`v0.17.2`](https://github.com/astral-sh/ruff/blob/HEAD/CHANGELOG.md#0172)

[Compare Source](astral-sh/ruff@0.17.1...0.17.2)

Released on 2026-10-22.

##### Preview features

- \[`complexity`] Add `unnecessary-regular-expression-compile` ([#&#8203;25533](astral-sh/ruff#25533))

##### Bug fixes

- Avoid syntax errors for type variables with starred constraints (`UP040`, `UP046`, `UP047`, `RUF053`) ([#&#8203;28362](astral-sh/ruff#28362))
- \[`pydocstyle`] Treat backslash-escaped `*args` and `**kwargs` as documented (`D417`) ([#&#8203;29536](astral-sh/ruff#29536))
- \[`pylint`] Avoid false positive on starred elements (`PLE0643`) ([#&#8203;29483](astral-sh/ruff#29483))
- \[`pylint`] Mark fixes unsafe when deleting comments (`PLR5501`, `PLW0120`) ([#&#8203;29414](astral-sh/ruff#29414))
- \[`pyupgrade`] Mark fix unsafe when deleting comments (`UP035`) ([#&#8203;29413](astral-sh/ruff#29413))

##### Performance

- Avoid intermediate names in lint name resolution ([#&#8203;29506](astral-sh/ruff#29506))
- Prefilter bidirectional Unicode checks by UTF-8 leading bytes ([#&#8203;29561](astral-sh/ruff#29561))
- Share postfix parsing and reduce expression copies ([#&#8203;29480](astral-sh/ruff#29480))

##### Configuration

- \[`pylint`] Add a configurable allowlist for `magic-value-comparison` (`PLR2004`) ([#&#8203;18961](astral-sh/ruff#18961))

##### Documentation

- Clarify documentation and correct stale guidance ([#&#8203;29374](astral-sh/ruff#29374))
- \[`pyupgrade`] Remove mentions of variance related to fix safety (`UP040`, `UP047`) ([#&#8203;29592](astral-sh/ruff#29592))

##### Contributors

- [@&#8203;fixfon](https://github.com/fixfon)
- [@&#8203;MichaReiser](https://github.com/MichaReiser)
- [@&#8203;zaniebot](https://github.com/zaniebot)
- [@&#8203;FrancescoPezzella](https://github.com/FrancescoPezzella)
- [@&#8203;anishgirianish](https://github.com/anishgirianish)
- [@&#8203;rajveer3x](https://github.com/rajveer3x)
- [@&#8203;charliermarsh](https://github.com/charliermarsh)
- [@&#8203;LckyLike](https://github.com/LckyLke)
- [@&#8203;DaniBodor](https://github.com/DaniBodor)

</details>

---

### Configuration

πŸ“… **Schedule**: (in timezone America/Denver)

- Branch creation
  - Between 02:00 AM and 06:59 AM, only on Tuesday (`* 2-6 * * 2`)
- 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.

πŸ‘» **Immortal**: This PR will be recreated if closed unmerged. Get [config help](https://github.com/renovatebot/renovate/discussions) if that's undesired.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Mend Renovate CLI](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC4xNDguMyIsInVwZGF0ZWRJblZlciI6IjQ0LjE0OC4zIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJyZW5vdmF0ZSJdfQ==-->

Reviewed-on: https://git.lichtenwalter.site/rlichten/dir2text/pulls/100
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

preview Related to preview-mode features rule Implementing or modifying a lint rule

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Rule idea: unncessary-compiled-regular-expression

2 participants