Skip to content

Commit cf40ab0

Browse files
Morten Kraneclaude
andauthored
Change inline comment keyword from 'noqa' to 'noida' (#31)
Replace the 'noqa' keyword with 'noida' to avoid conflicts with ruff. Ruff doesn't accept 'noqa' comments that don't match ruff rules, so using a custom keyword 'noida' (no-oida) prevents these conflicts. Changes: - Renamed parse_noqa_comment() to parse_noida_comment() - Updated regex to match 'noida' instead of 'noqa' - Updated all tests to use 'noida' keyword - Updated README.md documentation - Added BREAKING CHANGE note in CHANGELOG.md This is a breaking change - users must replace all '# noqa' comments with '# noida' comments in their code. Co-authored-by: Claude <noreply@anthropic.com>
1 parent 495b5ef commit cf40ab0

5 files changed

Lines changed: 71 additions & 67 deletions

File tree

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
### Changed
11+
- **BREAKING**: Changed inline comment keyword from `# noqa` to `# noida` to avoid conflicts with ruff, which doesn't accept `noqa` comments that don't match ruff rules
12+
1013
## [0.3.0] - 2025-11-25
1114

1215
### Added

README.md

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ an existing codebase into one that's modularized. For details see `oida
4141
### `oida lint`
4242

4343
This command is just another way of running the same checks that can be run
44-
through `flake8`. This command supports `# noqa` comments to ignore specific
44+
through `flake8`. This command supports `# noida` comments to ignore specific
4545
violations on individual lines (see below for details).
4646

4747
### `oida config`
@@ -101,23 +101,24 @@ This will silence any warnings when importing `my_component.app.models.MyModel`
101101
in the current app/component.
102102

103103

104-
## Ignoring Violations with `# noqa` Comments
104+
## Ignoring Violations with `# noida` Comments
105105

106-
You can use inline `# noqa` comments to ignore specific violations on individual lines:
106+
You can use inline `# noida` comments to ignore specific violations on individual lines:
107107

108108
```python
109109
# Ignore all violations on this line
110-
from project.other_component.app.models import Model # noqa
110+
from project.other_component.app.models import Model # noida
111111

112112
# Ignore a specific violation code
113-
from project.other_component.app.models import Model # noqa: ODA005
113+
from project.other_component.app.models import Model # noida: ODA005
114114

115115
# Ignore multiple specific violation codes
116-
from project.other_component.app.models import Model # noqa: ODA005, ODA001
116+
from project.other_component.app.models import Model # noida: ODA005, ODA001
117117
```
118118

119-
The `# noqa` comments work with both the `oida lint` command and when used as a
120-
flake8 plugin.
119+
The `# noida` comments work with the `oida lint` command. Note that we use `noida`
120+
instead of `noqa` to avoid conflicts with ruff, which doesn't accept `noqa` comments
121+
that don't match ruff rules.
121122

122123

123124
## Checks

oida/checkers/base.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from typing import ClassVar, NamedTuple
44

55
from ..config import ComponentConfig, ProjectConfig
6-
from ..utils import parse_noqa_comment
6+
from ..utils import parse_noida_comment
77

88

99
class Code(int, enum.Enum):
@@ -42,24 +42,24 @@ def __init__(
4242
self.violations: list[Violation] = []
4343

4444
def _should_ignore_violation(self, line: int, code: Code) -> bool:
45-
"""Check if a violation should be ignored due to a noqa comment."""
45+
"""Check if a violation should be ignored due to a noida comment."""
4646
if self.source_lines is None or line < 1 or line > len(self.source_lines):
4747
return False
4848

4949
source_line = self.source_lines[line - 1] # Convert 1-indexed to 0-indexed
50-
noqa_codes = parse_noqa_comment(source_line)
50+
noida_codes = parse_noida_comment(source_line)
5151

52-
if noqa_codes is None:
53-
# No noqa comment
52+
if noida_codes is None:
53+
# No noida comment
5454
return False
5555

56-
if not noqa_codes:
57-
# "# noqa" without specific codes - ignore all violations
56+
if not noida_codes:
57+
# "# noida" without specific codes - ignore all violations
5858
return True
5959

6060
# Check if this specific code should be ignored
6161
code_str = f"ODA{code.value:03d}"
62-
return code_str in noqa_codes
62+
return code_str in noida_codes
6363

6464
def report_violation(self, node: ast.AST, code: Code, message: str) -> None:
6565
if self._should_ignore_violation(node.lineno, code):

oida/utils.py

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -36,35 +36,35 @@ def path_in_glob_list(path: str, glob_list: list[str]) -> bool:
3636
return False
3737

3838

39-
def parse_noqa_comment(line: str) -> set[str] | None:
39+
def parse_noida_comment(line: str) -> set[str] | None:
4040
"""
41-
Parse a noqa comment from a line of source code.
41+
Parse a noida comment from a line of source code.
4242
4343
Returns:
44-
- None if no noqa comment is found
45-
- Empty set if "# noqa" (ignore all violations)
46-
- Set of specific codes if "# noqa: ODA001,ODA002" (ignore specific codes)
44+
- None if no noida comment is found
45+
- Empty set if "# noida" (ignore all violations)
46+
- Set of specific codes if "# noida: ODA001,ODA002" (ignore specific codes)
4747
4848
Examples:
49-
>>> parse_noqa_comment("x = 1 # noqa")
49+
>>> parse_noida_comment("x = 1 # noida")
5050
set()
51-
>>> parse_noqa_comment("x = 1 # noqa: ODA005")
51+
>>> parse_noida_comment("x = 1 # noida: ODA005")
5252
{'ODA005'}
53-
>>> parse_noqa_comment("x = 1 # noqa: ODA005, ODA001")
53+
>>> parse_noida_comment("x = 1 # noida: ODA005, ODA001")
5454
{'ODA005', 'ODA001'}
55-
>>> parse_noqa_comment("x = 1 # regular comment")
55+
>>> parse_noida_comment("x = 1 # regular comment")
5656
None
5757
"""
58-
# Match "# noqa" optionally followed by ": CODE1, CODE2, ..."
59-
# Case-insensitive matching for "noqa"
60-
match = re.search(r"#\s*noqa(?::\s*([A-Z0-9,\s]+))?", line, re.IGNORECASE)
58+
# Match "# noida" optionally followed by ": CODE1, CODE2, ..."
59+
# Case-insensitive matching for "noida"
60+
match = re.search(r"#\s*noida(?::\s*([A-Z0-9,\s]+))?", line, re.IGNORECASE)
6161

6262
if not match:
6363
return None
6464

6565
codes_str = match.group(1)
6666
if not codes_str:
67-
# "# noqa" without specific codes - ignore all
67+
# "# noida" without specific codes - ignore all
6868
return set()
6969

7070
# Parse the comma-separated list of codes

tests/test_noqa.py

Lines changed: 38 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,36 @@
11
import pytest
22

33
from oida.checkers import Code, ComponentIsolationChecker, Violation
4-
from oida.utils import parse_noqa_comment
4+
from oida.utils import parse_noida_comment
55

66
pytestmark = pytest.mark.module(name="selectors", module="project.component.app")
77

88

9-
def test_parse_noqa_comment_no_comment() -> None:
10-
"""Test parsing line without noqa comment"""
11-
assert parse_noqa_comment("x = 1") is None
12-
assert parse_noqa_comment("from foo import bar") is None
9+
def test_parse_noida_comment_no_comment() -> None:
10+
"""Test parsing line without noida comment"""
11+
assert parse_noida_comment("x = 1") is None
12+
assert parse_noida_comment("from foo import bar") is None
1313

1414

15-
def test_parse_noqa_comment_generic() -> None:
16-
"""Test parsing generic noqa comment"""
17-
assert parse_noqa_comment("x = 1 # noqa") == set()
18-
assert parse_noqa_comment("x = 1 #noqa") == set()
19-
assert parse_noqa_comment("x = 1 # NOQA") == set()
15+
def test_parse_noida_comment_generic() -> None:
16+
"""Test parsing generic noida comment"""
17+
assert parse_noida_comment("x = 1 # noida") == set()
18+
assert parse_noida_comment("x = 1 #noida") == set()
19+
assert parse_noida_comment("x = 1 # NOIDA") == set()
2020

2121

22-
def test_parse_noqa_comment_specific_code() -> None:
23-
"""Test parsing noqa comment with specific code"""
24-
assert parse_noqa_comment("x = 1 # noqa: ODA005") == {"ODA005"}
25-
assert parse_noqa_comment("x = 1 # noqa:ODA005") == {"ODA005"}
26-
assert parse_noqa_comment("x = 1 # NOQA: ODA005") == {"ODA005"}
22+
def test_parse_noida_comment_specific_code() -> None:
23+
"""Test parsing noida comment with specific code"""
24+
assert parse_noida_comment("x = 1 # noida: ODA005") == {"ODA005"}
25+
assert parse_noida_comment("x = 1 # noida:ODA005") == {"ODA005"}
26+
assert parse_noida_comment("x = 1 # NOIDA: ODA005") == {"ODA005"}
2727

2828

29-
def test_parse_noqa_comment_multiple_codes() -> None:
30-
"""Test parsing noqa comment with multiple codes"""
31-
assert parse_noqa_comment("x = 1 # noqa: ODA005, ODA001") == {"ODA005", "ODA001"}
32-
assert parse_noqa_comment("x = 1 # noqa: ODA005,ODA001") == {"ODA005", "ODA001"}
33-
assert parse_noqa_comment("x = 1 # noqa: ODA005 , ODA001") == {
29+
def test_parse_noida_comment_multiple_codes() -> None:
30+
"""Test parsing noida comment with multiple codes"""
31+
assert parse_noida_comment("x = 1 # noida: ODA005, ODA001") == {"ODA005", "ODA001"}
32+
assert parse_noida_comment("x = 1 # noida: ODA005,ODA001") == {"ODA005", "ODA001"}
33+
assert parse_noida_comment("x = 1 # noida: ODA005 , ODA001") == {
3434
"ODA005",
3535
"ODA001",
3636
}
@@ -39,41 +39,41 @@ def test_parse_noqa_comment_multiple_codes() -> None:
3939
@pytest.mark.module(
4040
"""\
4141
from project.other.app.services import service
42-
service() # noqa
42+
service() # noida
4343
"""
4444
)
45-
def test_noqa_generic_ignores_violation(
45+
def test_noida_generic_ignores_violation(
4646
checker: ComponentIsolationChecker, violations: list[Violation]
4747
) -> None:
48-
"""Test that generic noqa comment ignores all violations on that line"""
48+
"""Test that generic noida comment ignores all violations on that line"""
4949
assert violations == []
5050
assert checker.referenced_imports == {"project.other.app.services.service"}
5151

5252

5353
@pytest.mark.module(
5454
"""\
5555
from project.other.app.services import service
56-
service() # noqa: ODA005
56+
service() # noida: ODA005
5757
"""
5858
)
59-
def test_noqa_specific_code_ignores_violation(
59+
def test_noida_specific_code_ignores_violation(
6060
checker: ComponentIsolationChecker, violations: list[Violation]
6161
) -> None:
62-
"""Test that specific noqa comment ignores matching violation"""
62+
"""Test that specific noida comment ignores matching violation"""
6363
assert violations == []
6464
assert checker.referenced_imports == {"project.other.app.services.service"}
6565

6666

6767
@pytest.mark.module(
6868
"""\
6969
from project.other.app.services import service
70-
service() # noqa: ODA001
70+
service() # noida: ODA001
7171
"""
7272
)
73-
def test_noqa_different_code_does_not_ignore(
73+
def test_noida_different_code_does_not_ignore(
7474
checker: ComponentIsolationChecker, violations: list[Violation]
7575
) -> None:
76-
"""Test that noqa comment with different code does not ignore violation"""
76+
"""Test that noida comment with different code does not ignore violation"""
7777
assert violations == [
7878
Violation(
7979
line=2,
@@ -88,13 +88,13 @@ def test_noqa_different_code_does_not_ignore(
8888
@pytest.mark.module(
8989
"""\
9090
from project.other.app.services import service
91-
service() # noqa: ODA005, ODA001
91+
service() # noida: ODA005, ODA001
9292
"""
9393
)
94-
def test_noqa_multiple_codes_ignores_matching(
94+
def test_noida_multiple_codes_ignores_matching(
9595
checker: ComponentIsolationChecker, violations: list[Violation]
9696
) -> None:
97-
"""Test that noqa comment with multiple codes ignores matching violation"""
97+
"""Test that noida comment with multiple codes ignores matching violation"""
9898
assert violations == []
9999
assert checker.referenced_imports == {"project.other.app.services.service"}
100100

@@ -104,13 +104,13 @@ def test_noqa_multiple_codes_ignores_matching(
104104
from project.other.app.models import Model
105105
106106
def selector() -> None:
107-
Model.objects.get() # noqa: ODA005
107+
Model.objects.get() # noida: ODA005
108108
"""
109109
)
110-
def test_noqa_in_function_body(
110+
def test_noida_in_function_body(
111111
checker: ComponentIsolationChecker, violations: list[Violation]
112112
) -> None:
113-
"""Test that noqa comment works in function bodies"""
113+
"""Test that noida comment works in function bodies"""
114114
assert violations == []
115115
assert checker.referenced_imports == {"project.other.app.models.Model"}
116116

@@ -121,13 +121,13 @@ def test_noqa_in_function_body(
121121
122122
def selector() -> None:
123123
Model.objects.get()
124-
Model.objects.filter() # noqa
124+
Model.objects.filter() # noida
125125
"""
126126
)
127-
def test_noqa_only_affects_its_line(
127+
def test_noida_only_affects_its_line(
128128
checker: ComponentIsolationChecker, violations: list[Violation]
129129
) -> None:
130-
"""Test that noqa comment only affects violations on its own line"""
130+
"""Test that noida comment only affects violations on its own line"""
131131
assert violations == [
132132
Violation(
133133
line=4,

0 commit comments

Comments
 (0)