|
| 1 | +# The contents of this file is based on https://github.com/home-assistant/core/blob/dev/pyproject.toml |
| 2 | + |
| 3 | +target-version = "py313" |
| 4 | + |
| 5 | +[lint] |
| 6 | +select = [ |
| 7 | + "A001", # Variable {name} is shadowing a Python builtin |
| 8 | + "ASYNC", # flake8-async |
| 9 | + "B002", # Python does not support the unary prefix increment |
| 10 | + "B005", # Using .strip() with multi-character strings is misleading |
| 11 | + "B007", # Loop control variable {name} not used within loop body |
| 12 | + "B009", # Do not call getattr with a constant attribute value. It is not any safer than normal property access. |
| 13 | + "B014", # Exception handler with duplicate exception |
| 14 | + "B015", # Pointless comparison. Did you mean to assign a value? Otherwise, prepend assert or remove it. |
| 15 | + "B017", # pytest.raises(BaseException) should be considered evil |
| 16 | + "B018", # Found useless attribute access. Either assign it to a variable or remove it. |
| 17 | + "B023", # Function definition does not bind loop variable {name} |
| 18 | + "B024", # `{name}` is an abstract base class, but it has no abstract methods or properties |
| 19 | + "B026", # Star-arg unpacking after a keyword argument is strongly discouraged |
| 20 | + "B032", # Possible unintentional type annotation (using :). Did you mean to assign (using =)? |
| 21 | + "B035", # Dictionary comprehension uses static key |
| 22 | + "B904", # Use raise from to specify exception cause |
| 23 | + "B905", # zip() without an explicit strict= parameter |
| 24 | + "BLE", |
| 25 | + "C", # complexity |
| 26 | + "COM818", # Trailing comma on bare tuple prohibited |
| 27 | + "D", # docstrings |
| 28 | + "DTZ003", # Use datetime.now(tz=) instead of datetime.utcnow() |
| 29 | + "DTZ004", # Use datetime.fromtimestamp(ts, tz=) instead of datetime.utcfromtimestamp(ts) |
| 30 | + "E", # pycodestyle |
| 31 | + "F", # pyflakes/autoflake |
| 32 | + "F541", # f-string without any placeholders |
| 33 | + "FLY", # flynt |
| 34 | + "FURB", # refurb |
| 35 | + "G", # flake8-logging-format |
| 36 | + "I", # isort |
| 37 | + "INP", # flake8-no-pep420 |
| 38 | + "ISC", # flake8-implicit-str-concat |
| 39 | + "ICN001", # import concentions; {name} should be imported as {asname} |
| 40 | + "LOG", # flake8-logging |
| 41 | + "N804", # First argument of a class method should be named cls |
| 42 | + "N805", # First argument of a method should be named self |
| 43 | + "N815", # Variable {name} in class scope should not be mixedCase |
| 44 | + "PERF", # Perflint |
| 45 | + "PGH", # pygrep-hooks |
| 46 | + "PIE", # flake8-pie |
| 47 | + "PL", # pylint |
| 48 | + "PT", # flake8-pytest-style |
| 49 | + "PTH", # flake8-pathlib |
| 50 | + "PYI", # flake8-pyi |
| 51 | + "RET", # flake8-return |
| 52 | + "RSE", # flake8-raise |
| 53 | + "RUF005", # Consider iterable unpacking instead of concatenation |
| 54 | + "RUF006", # Store a reference to the return value of asyncio.create_task |
| 55 | + "RUF007", # Prefer itertools.pairwise() over zip() when iterating over successive pairs |
| 56 | + "RUF008", # Do not use mutable default values for dataclass attributes |
| 57 | + "RUF010", # Use explicit conversion flag |
| 58 | + "RUF013", # PEP 484 prohibits implicit Optional |
| 59 | + "RUF016", # Slice in indexed access to type {value_type} uses type {index_type} instead of an integer |
| 60 | + "RUF017", # Avoid quadratic list summation |
| 61 | + "RUF018", # Avoid assignment expressions in assert statements |
| 62 | + "RUF019", # Unnecessary key check before dictionary access |
| 63 | + "RUF020", # {never_like} | T is equivalent to T |
| 64 | + "RUF021", # Parenthesize a and b expressions when chaining and and or together, to make the precedence clear |
| 65 | + "RUF022", # Sort __all__ |
| 66 | + "RUF023", # Sort __slots__ |
| 67 | + "RUF024", # Do not pass mutable objects as values to dict.fromkeys |
| 68 | + "RUF026", # default_factory is a positional-only argument to defaultdict |
| 69 | + "RUF030", # print() call in assert statement is likely unintentional |
| 70 | + "RUF032", # Decimal() called with float literal argument |
| 71 | + "RUF033", # __post_init__ method with argument defaults |
| 72 | + "RUF034", # Useless if-else condition |
| 73 | + "RUF100", # Unused `noqa` directive |
| 74 | + "RUF101", # noqa directives that use redirected rule codes |
| 75 | + "RUF200", # Failed to parse pyproject.toml: {message} |
| 76 | + "S102", # Use of exec detected |
| 77 | + "S103", # bad-file-permissions |
| 78 | + "S108", # hardcoded-temp-file |
| 79 | + "S306", # suspicious-mktemp-usage |
| 80 | + "S307", # suspicious-eval-usage |
| 81 | + "S313", # suspicious-xmlc-element-tree-usage |
| 82 | + "S314", # suspicious-xml-element-tree-usage |
| 83 | + "S315", # suspicious-xml-expat-reader-usage |
| 84 | + "S316", # suspicious-xml-expat-builder-usage |
| 85 | + "S317", # suspicious-xml-sax-usage |
| 86 | + "S318", # suspicious-xml-mini-dom-usage |
| 87 | + "S319", # suspicious-xml-pull-dom-usage |
| 88 | + "S601", # paramiko-call |
| 89 | + "S602", # subprocess-popen-with-shell-equals-true |
| 90 | + "S604", # call-with-shell-equals-true |
| 91 | + "S608", # hardcoded-sql-expression |
| 92 | + "S609", # unix-command-wildcard-injection |
| 93 | + "SIM", # flake8-simplify |
| 94 | + "SLF", # flake8-self |
| 95 | + "SLOT", # flake8-slots |
| 96 | + "T100", # Trace found: {name} used |
| 97 | + "T20", # flake8-print |
| 98 | + "TC", # flake8-type-checking |
| 99 | + "TID", # Tidy imports |
| 100 | + "TRY", # tryceratops |
| 101 | + "UP", # pyupgrade |
| 102 | + "UP031", # Use format specifiers instead of percent format |
| 103 | + "UP032", # Use f-string instead of `format` call |
| 104 | + "W", # pycodestyle |
| 105 | +] |
| 106 | + |
| 107 | +ignore = [ |
| 108 | + "ASYNC109", # Async function definition with a `timeout` parameter Use `asyncio.timeout` instead |
| 109 | + "ASYNC110", # Use `asyncio.Event` instead of awaiting `asyncio.sleep` in a `while` loop |
| 110 | + "D202", # No blank lines allowed after function docstring |
| 111 | + "D203", # 1 blank line required before class docstring |
| 112 | + "D213", # Multi-line docstring summary should start at the second line |
| 113 | + "D406", # Section name should end with a newline |
| 114 | + "D407", # Section name underlining |
| 115 | + "E501", # line too long |
| 116 | + |
| 117 | + "PLC1901", # {existing} can be simplified to {replacement} as an empty string is falsey; too many false positives |
| 118 | + "PLR0911", # Too many return statements ({returns} > {max_returns}) |
| 119 | + "PLR0912", # Too many branches ({branches} > {max_branches}) |
| 120 | + "PLR0913", # Too many arguments to function call ({c_args} > {max_args}) |
| 121 | + "PLR0915", # Too many statements ({statements} > {max_statements}) |
| 122 | + "PLR2004", # Magic value used in comparison, consider replacing {value} with a constant variable |
| 123 | + "PLW2901", # Outer {outer_kind} variable {name} overwritten by inner {inner_kind} target |
| 124 | + "PT011", # pytest.raises({exception}) is too broad, set the `match` parameter or use a more specific exception |
| 125 | + "PT018", # Assertion should be broken down into multiple parts |
| 126 | + "RUF001", # String contains ambiguous unicode character. |
| 127 | + "RUF002", # Docstring contains ambiguous unicode character. |
| 128 | + "RUF003", # Comment contains ambiguous unicode character. |
| 129 | + #"RUF015", # Prefer next(...) over single element slice |
| 130 | + #"SIM102", # Use a single if statement instead of nested if statements |
| 131 | + "SIM103", # Return the condition {condition} directly |
| 132 | + "SIM108", # Use ternary operator {contents} instead of if-else-block |
| 133 | + "SIM115", # Use context handler for opening files |
| 134 | + |
| 135 | + # Moving imports into type-checking blocks can mess with pytest.patch() |
| 136 | + "TC001", # Move application import {} into a type-checking block |
| 137 | + "TC002", # Move third-party import {} into a type-checking block |
| 138 | + "TC003", # Move standard library import {} into a type-checking block |
| 139 | + # Quotes for typing.cast generally not necessary, only for performance critical paths |
| 140 | + "TC006", # Add quotes to type expression in typing.cast() |
| 141 | + |
| 142 | + "TRY003", # Avoid specifying long messages outside the exception class |
| 143 | + "TRY400", # Use `logging.exception` instead of `logging.error` |
| 144 | + # Ignored due to performance: https://github.com/charliermarsh/ruff/issues/2923 |
| 145 | + "UP038", # Use `X | Y` in `isinstance` call instead of `(X, Y)` |
| 146 | + |
| 147 | + # May conflict with the formatter, https://docs.astral.sh/ruff/formatter/#conflicting-lint-rules |
| 148 | + "W191", |
| 149 | + "E111", |
| 150 | + "E114", |
| 151 | + "E117", |
| 152 | + "D206", |
| 153 | + "D300", |
| 154 | + "Q", |
| 155 | + "COM812", |
| 156 | + "COM819", |
| 157 | + |
| 158 | + # Disabled because ruff does not understand type of __all__ generated by a function |
| 159 | + "PLE0605", |
| 160 | +] |
| 161 | + |
| 162 | +[lint.flake8-pytest-style] |
| 163 | +fixture-parentheses = false |
| 164 | + |
| 165 | +[lint.mccabe] |
| 166 | +max-complexity = 25 |
0 commit comments