229 lines
9.5 KiB
TOML
229 lines
9.5 KiB
TOML
# Ruff configuration for the sws12500 Home Assistant custom component.
|
|
#
|
|
# This mirrors the rule set Home Assistant core uses, because that is the
|
|
# convention this integration's code is written against. Core-only settings
|
|
# (entry-point scripts, the per-component relative-import exemptions, and the
|
|
# PLATFORM_SCHEMA import aliases for domains this integration does not touch)
|
|
# have been dropped; everything else is carried over verbatim so that the
|
|
# tooling in this repository describes the code that is already here.
|
|
|
|
required-version = ">=0.8.0"
|
|
line-length = 120
|
|
|
|
[lint]
|
|
select = [
|
|
"A001", # Variable {name} is shadowing a Python builtin
|
|
"ASYNC210", # Async functions should not call blocking HTTP methods
|
|
"ASYNC220", # Async functions should not create subprocesses with blocking methods
|
|
"ASYNC221", # Async functions should not run processes with blocking methods
|
|
"ASYNC222", # Async functions should not wait on processes with blocking methods
|
|
"ASYNC230", # Async functions should not open files with blocking methods like open
|
|
"ASYNC251", # Async functions should not call time.sleep
|
|
"B002", # Python does not support the unary prefix increment
|
|
"B005", # Using .strip() with multi-character strings is misleading
|
|
"B007", # Loop control variable {name} not used within loop body
|
|
"B014", # Exception handler with duplicate exception
|
|
"B015", # Pointless comparison. Did you mean to assign a value? Otherwise, prepend assert or remove it.
|
|
"B017", # pytest.raises(BaseException) should be considered evil
|
|
"B018", # Found useless attribute access. Either assign it to a variable or remove it.
|
|
"B023", # Function definition does not bind loop variable {name}
|
|
"B026", # Star-arg unpacking after a keyword argument is strongly discouraged
|
|
"B032", # Possible unintentional type annotation (using :). Did you mean to assign (using =)?
|
|
"B904", # Use raise from to specify exception cause
|
|
"B905", # zip() without an explicit strict= parameter
|
|
"BLE",
|
|
"C", # complexity
|
|
"COM818", # Trailing comma on bare tuple prohibited
|
|
"D", # docstrings
|
|
"DTZ003", # Use datetime.now(tz=) instead of datetime.utcnow()
|
|
"DTZ004", # Use datetime.fromtimestamp(ts, tz=) instead of datetime.utcfromtimestamp(ts)
|
|
"E", # pycodestyle
|
|
"F", # pyflakes/autoflake
|
|
"F541", # f-string without any placeholders
|
|
"FLY", # flynt
|
|
"FURB", # refurb
|
|
"G", # flake8-logging-format
|
|
"I", # isort
|
|
"INP", # flake8-no-pep420
|
|
"ISC", # flake8-implicit-str-concat
|
|
"ICN001", # import concentions; {name} should be imported as {asname}
|
|
"LOG", # flake8-logging
|
|
"N804", # First argument of a class method should be named cls
|
|
"N805", # First argument of a method should be named self
|
|
"N815", # Variable {name} in class scope should not be mixedCase
|
|
"PERF", # Perflint
|
|
"PGH", # pygrep-hooks
|
|
"PIE", # flake8-pie
|
|
"PL", # pylint
|
|
"PT", # flake8-pytest-style
|
|
"PTH", # flake8-pathlib
|
|
"PYI", # flake8-pyi
|
|
"RET", # flake8-return
|
|
"RSE", # flake8-raise
|
|
"RUF005", # Consider iterable unpacking instead of concatenation
|
|
"RUF006", # Store a reference to the return value of asyncio.create_task
|
|
"RUF010", # Use explicit conversion flag
|
|
"RUF013", # PEP 484 prohibits implicit Optional
|
|
"RUF017", # Avoid quadratic list summation
|
|
"RUF018", # Avoid assignment expressions in assert statements
|
|
"RUF019", # Unnecessary key check before dictionary access
|
|
# "RUF100", # Unused `noqa` directive; temporarily every now and then to clean them up
|
|
"S102", # Use of exec detected
|
|
"S103", # bad-file-permissions
|
|
"S108", # hardcoded-temp-file
|
|
"S306", # suspicious-mktemp-usage
|
|
"S307", # suspicious-eval-usage
|
|
"S313", # suspicious-xmlc-element-tree-usage
|
|
"S314", # suspicious-xml-element-tree-usage
|
|
"S315", # suspicious-xml-expat-reader-usage
|
|
"S316", # suspicious-xml-expat-builder-usage
|
|
"S317", # suspicious-xml-sax-usage
|
|
"S318", # suspicious-xml-mini-dom-usage
|
|
"S319", # suspicious-xml-pull-dom-usage
|
|
"S601", # paramiko-call
|
|
"S602", # subprocess-popen-with-shell-equals-true
|
|
"S604", # call-with-shell-equals-true
|
|
"S608", # hardcoded-sql-expression
|
|
"S609", # unix-command-wildcard-injection
|
|
"SIM", # flake8-simplify
|
|
"SLF", # flake8-self
|
|
"SLOT", # flake8-slots
|
|
"T100", # Trace found: {name} used
|
|
"T20", # flake8-print
|
|
"TC", # flake8-type-checking
|
|
"TID", # Tidy imports
|
|
"TRY", # tryceratops
|
|
"UP", # pyupgrade
|
|
"UP031", # Use format specifiers instead of percent format
|
|
"UP032", # Use f-string instead of `format` call
|
|
"W", # pycodestyle
|
|
]
|
|
|
|
ignore = [
|
|
"D202", # No blank lines allowed after function docstring
|
|
"D203", # 1 blank line required before class docstring
|
|
"D213", # Multi-line docstring summary should start at the second line
|
|
"D406", # Section name should end with a newline
|
|
"D407", # Section name underlining
|
|
"E501", # line too long
|
|
|
|
"PLC1901", # {existing} can be simplified to {replacement} as an empty string is falsey; too many false positives
|
|
"PLR0911", # Too many return statements ({returns} > {max_returns})
|
|
"PLR0912", # Too many branches ({branches} > {max_branches})
|
|
"PLR0913", # Too many arguments to function call ({c_args} > {max_args})
|
|
"PLR0915", # Too many statements ({statements} > {max_statements})
|
|
"PLR2004", # Magic value used in comparison, consider replacing {value} with a constant variable
|
|
"PLW2901", # Outer {outer_kind} variable {name} overwritten by inner {inner_kind} target
|
|
"PT011", # pytest.raises({exception}) is too broad, set the `match` parameter or use a more specific exception
|
|
"PT018", # Assertion should be broken down into multiple parts
|
|
"RUF001", # String contains ambiguous unicode character.
|
|
"RUF002", # Docstring contains ambiguous unicode character.
|
|
"RUF003", # Comment contains ambiguous unicode character.
|
|
"RUF015", # Prefer next(...) over single element slice
|
|
"SIM102", # Use a single if statement instead of nested if statements
|
|
"SIM103", # Return the condition {condition} directly
|
|
"SIM108", # Use ternary operator {contents} instead of if-else-block
|
|
"SIM115", # Use context handler for opening files
|
|
|
|
# Moving imports into type-checking blocks can mess with pytest.patch()
|
|
"TC001", # Move application import {} into a type-checking block
|
|
"TC002", # Move third-party import {} into a type-checking block
|
|
"TC003", # Move standard library import {} into a type-checking block
|
|
|
|
"TRY003", # Avoid specifying long messages outside the exception class
|
|
"TRY400", # Use `logging.exception` instead of `logging.error`
|
|
# UP038 (`X | Y` in `isinstance`) is in core's ignore list, but the rule was
|
|
# removed from ruff; listing it only produces a "has no effect" warning.
|
|
|
|
# May conflict with the formatter, https://docs.astral.sh/ruff/formatter/#conflicting-lint-rules
|
|
"W191",
|
|
"E111",
|
|
"E114",
|
|
"E117",
|
|
"D206",
|
|
"D300",
|
|
"Q",
|
|
"COM812",
|
|
"COM819",
|
|
"ISC001",
|
|
|
|
# Disabled because ruff does not understand type of __all__ generated by a function
|
|
"PLE0605",
|
|
]
|
|
|
|
[lint.flake8-import-conventions.extend-aliases]
|
|
voluptuous = "vol"
|
|
"homeassistant.components.binary_sensor.PLATFORM_SCHEMA" = "BINARY_SENSOR_PLATFORM_SCHEMA"
|
|
"homeassistant.components.sensor.PLATFORM_SCHEMA" = "SENSOR_PLATFORM_SCHEMA"
|
|
"homeassistant.components.weather.PLATFORM_SCHEMA" = "WEATHER_PLATFORM_SCHEMA"
|
|
"homeassistant.core.DOMAIN" = "HOMEASSISTANT_DOMAIN"
|
|
"homeassistant.helpers.area_registry" = "ar"
|
|
"homeassistant.helpers.category_registry" = "cr"
|
|
"homeassistant.helpers.config_validation" = "cv"
|
|
"homeassistant.helpers.device_registry" = "dr"
|
|
"homeassistant.helpers.entity_registry" = "er"
|
|
"homeassistant.helpers.floor_registry" = "fr"
|
|
"homeassistant.helpers.issue_registry" = "ir"
|
|
"homeassistant.helpers.label_registry" = "lr"
|
|
"homeassistant.util.dt" = "dt_util"
|
|
|
|
[lint.flake8-pytest-style]
|
|
fixture-parentheses = false
|
|
mark-parentheses = false
|
|
|
|
[lint.flake8-tidy-imports.banned-api]
|
|
"async_timeout".msg = "use asyncio.timeout instead"
|
|
"pytz".msg = "use zoneinfo instead"
|
|
"tests".msg = "You should not import tests"
|
|
|
|
[lint.isort]
|
|
force-sort-within-sections = true
|
|
known-first-party = ["homeassistant"]
|
|
combine-as-imports = true
|
|
split-on-trailing-comma = false
|
|
|
|
[lint.per-file-ignores]
|
|
# Temporary, as in core: this integration has not migrated to pathlib.
|
|
"custom_components/**" = ["PTH"]
|
|
|
|
# The integration code satisfies the full rule set above. The test suite does
|
|
# not, and is relaxed here in two distinct ways.
|
|
#
|
|
# Deliberate, permanent exemptions - these are how this suite is written:
|
|
# D100, D103 - test modules and test functions carry their meaning in names
|
|
# INP001 - tests/ is intentionally not a package (no __init__.py)
|
|
# PLC0415 - function-local imports keep import-time patching honest
|
|
# PTH - as above
|
|
# SLF001 - tests assert directly on private helpers
|
|
#
|
|
# Deferred nits - genuine violations that exist in the tests today. They are
|
|
# suppressed rather than fixed to keep the introduction of this configuration a
|
|
# config-only change with no source edits. Remove each entry as it is cleaned
|
|
# up; none of them affect the integration code:
|
|
# B007, C420, D401, D413, I001, PLW0108, PT006, PYI034, SIM300, UP035, UP037
|
|
"tests/**" = [
|
|
"B007",
|
|
"C420",
|
|
"D100",
|
|
"D103",
|
|
"D401",
|
|
"D413",
|
|
"I001",
|
|
"INP001",
|
|
"PLC0415",
|
|
"PLW0108",
|
|
"PT006",
|
|
"PTH",
|
|
"PYI034",
|
|
"SIM300",
|
|
"SLF001",
|
|
"UP035",
|
|
"UP037",
|
|
]
|
|
|
|
[lint.mccabe]
|
|
max-complexity = 25
|
|
|
|
[lint.pydocstyle]
|
|
property-decorators = ["propcache.cached_property"]
|