Format Should Preserve Type Ignore Sub Expression
- Dominant language
- Rust
- Stars
- 49.7k
- Forks
- 2.4k
- Avg merge
- 2d 1h
- Merged PRs (30d)
- 458
Description
It seems that the ruff formatter will collapse a multi line expression with a `# type: ignore` to one line, unlike black.
I would like to keep the existing line split, if possible, since this limits the type ignore to one piece of the statement, instead of all of it. That way, if there is a type error in one of the other parts of the statement they are still caught by the type checker.
This is similar to https://github.com/astral-sh/ruff/issues/7730 but the issue here is not that the line ends up being too long, but that it changes the semantics of the type checker.
Example:
```diff
$ ruff format . --diff
--- python/egglog/egraph.py
+++ python/egglog/egraph.py
@@ -536,9 +536,7 @@
# If this is the class for this method and we have a paramaterized class, recurse
if (
- cls_type_and_name
- and isinstance(tp, _GenericAlias)
- and tp.__origin__ == cls_type_and_name[0] # type: ignore
+ cls_type_and_name and isinstance(tp, _GenericAlias) and tp.__origin__ == cls_type_and_name[0] # type: ignore
):
return TypeRefWithVars(
cls_type_and_name[1],
1 file would be reformatted, 25 files left unchanged
$ ruff --version
ruff 0.1.3
```
Settings:
```toml
[tool.ruff]
# Allow lines to be as long as 120.
line-length = 120
ignore = [
# allow star imports
"F405",
"F403",
# Dont care if cls isnt typed explicitly in classmethod
"ANN102",
# Same for self
"ANN101",
# Allow single line docstrings on multiple lines
"D200",
"D212",
# Inconsistant formatting
"D203",
"COM812",
"COM819",
"E501",
"ISC001",
"Q001",
"Q002",
"Q003",
"W191",
"Q000",
"D206",
# TODO: Remove the rest of these eventually
# Allow public methods to not have docstrings
"D102",
# Allow longer messages for custom errors
"TRY003",
# Allow f-string in exceptions
"EM102",
]
src = ["python"]
select = ["ALL"]
extend-exclude = ["python/tests"]
```
Contributor guide
Research direction
Reproduce the formatter change using the example in python/egglog/egraph.py and `ruff format . --diff`, then compare the result with Black. Trace Ruff's formatter handling of multiline expressions and `# type: ignore`; done means preserving the split so the ignore applies only to the intended expression, with a regression test for the behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python, rust
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100