-
-
Notifications
You must be signed in to change notification settings - Fork 30
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
219 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,219 @@ | ||
[tool.black] | ||
target-version = ["py310"] | ||
extend-exclude = "/generated/" | ||
|
||
[tool.isort] | ||
# https://github.com/PyCQA/isort/wiki/isort-Settings | ||
profile = "black" | ||
# will group `import x` and `from x import` of the same module. | ||
force_sort_within_sections = true | ||
known_first_party = [ | ||
"homeassistant", | ||
"tests", | ||
] | ||
forced_separate = [ | ||
"tests", | ||
] | ||
combine_as_imports = true | ||
|
||
[tool.pylint.MAIN] | ||
py-version = "3.10" | ||
ignore = [ | ||
"tests", | ||
] | ||
# Use a conservative default here; 2 should speed up most setups and not hurt | ||
# any too bad. Override on command line as appropriate. | ||
jobs = 2 | ||
init-hook = """\ | ||
from pathlib import Path; \ | ||
import sys; \ | ||
from pylint.config import find_default_config_files; \ | ||
sys.path.append( \ | ||
str(Path(next(find_default_config_files())).parent.joinpath('pylint/plugins')) | ||
) \ | ||
""" | ||
load-plugins = [ | ||
"pylint.extensions.code_style", | ||
"pylint.extensions.typing", | ||
"hass_enforce_type_hints", | ||
"hass_imports", | ||
"hass_logger", | ||
"pylint_per_file_ignores", | ||
] | ||
persistent = false | ||
extension-pkg-allow-list = [ | ||
"av.audio.stream", | ||
"av.stream", | ||
"ciso8601", | ||
"orjson", | ||
"cv2", | ||
] | ||
fail-on = [ | ||
"I", | ||
] | ||
|
||
[tool.pylint.BASIC] | ||
class-const-naming-style = "any" | ||
good-names = [ | ||
"_", | ||
"ev", | ||
"ex", | ||
"fp", | ||
"i", | ||
"id", | ||
"j", | ||
"k", | ||
"Run", | ||
"ip", | ||
] | ||
|
||
[tool.pylint."MESSAGES CONTROL"] | ||
# Reasons disabled: | ||
# format - handled by black | ||
# locally-disabled - it spams too much | ||
# duplicate-code - unavoidable | ||
# cyclic-import - doesn't test if both import on load | ||
# abstract-class-little-used - prevents from setting right foundation | ||
# unused-argument - generic callbacks and setup methods create a lot of warnings | ||
# too-many-* - are not enforced for the sake of readability | ||
# too-few-* - same as too-many-* | ||
# abstract-method - with intro of async there are always methods missing | ||
# inconsistent-return-statements - doesn't handle raise | ||
# too-many-ancestors - it's too strict. | ||
# wrong-import-order - isort guards this | ||
# consider-using-f-string - str.format sometimes more readable | ||
# --- | ||
# Pylint CodeStyle plugin | ||
# consider-using-namedtuple-or-dataclass - too opinionated | ||
# consider-using-assignment-expr - decision to use := better left to devs | ||
disable = [ | ||
"format", | ||
"abstract-method", | ||
"cyclic-import", | ||
"duplicate-code", | ||
"inconsistent-return-statements", | ||
"locally-disabled", | ||
"not-context-manager", | ||
"too-few-public-methods", | ||
"too-many-ancestors", | ||
"too-many-arguments", | ||
"too-many-branches", | ||
"too-many-instance-attributes", | ||
"too-many-lines", | ||
"too-many-locals", | ||
"too-many-public-methods", | ||
"too-many-return-statements", | ||
"too-many-statements", | ||
"too-many-boolean-expressions", | ||
"unused-argument", | ||
"wrong-import-order", | ||
"consider-using-f-string", | ||
"consider-using-namedtuple-or-dataclass", | ||
"consider-using-assignment-expr", | ||
] | ||
enable = [ | ||
#"useless-suppression", # temporarily every now and then to clean them up | ||
"use-symbolic-message-instead", | ||
] | ||
|
||
[tool.pylint.REPORTS] | ||
score = false | ||
|
||
[tool.pylint.TYPECHECK] | ||
ignored-classes = [ | ||
"_CountingAttr", # for attrs | ||
] | ||
mixin-class-rgx = ".*[Mm]ix[Ii]n" | ||
|
||
[tool.pylint.FORMAT] | ||
expected-line-ending-format = "LF" | ||
|
||
[tool.pylint.EXCEPTIONS] | ||
overgeneral-exceptions = [ | ||
"builtins.BaseException", | ||
"builtins.Exception", | ||
# "homeassistant.exceptions.HomeAssistantError", # too many issues | ||
] | ||
|
||
[tool.pylint.TYPING] | ||
runtime-typing = false | ||
|
||
[tool.pylint.CODE_STYLE] | ||
max-line-length-suggestions = 72 | ||
|
||
[tool.pylint-per-file-ignores] | ||
# hass-component-root-import: Tests test non-public APIs | ||
# protected-access: Tests do often test internals a lot | ||
# redefined-outer-name: Tests reference fixtures in the test function | ||
"/tests/"="hass-component-root-import,protected-access,redefined-outer-name" | ||
|
||
[tool.pytest.ini_options] | ||
testpaths = [ | ||
"tests", | ||
] | ||
norecursedirs = [ | ||
".git", | ||
"testing_config", | ||
] | ||
log_format = "%(asctime)s.%(msecs)03d %(levelname)-8s %(threadName)s %(name)s:%(filename)s:%(lineno)s %(message)s" | ||
log_date_format = "%Y-%m-%d %H:%M:%S" | ||
asyncio_mode = "auto" | ||
|
||
[tool.ruff] | ||
target-version = "py310" | ||
|
||
select = [ | ||
"C", # complexity | ||
"D", # docstrings | ||
"E", # pycodestyle | ||
"F", # pyflakes/autoflake | ||
"PGH004", # Use specific rule codes when using noqa | ||
"PLC0414", # Useless import alias. Import alias does not rename original package. | ||
"SIM105", # Use contextlib.suppress({exception}) instead of try-except-pass | ||
"SIM117", # Merge with-statements that use the same scope | ||
"SIM300", # Yoda conditions. Use 'age == 42' instead of '42 == age'. | ||
"SIM401", # Use get from dict with default instead of an if block | ||
"T20", # flake8-print | ||
"TRY004", # Prefer TypeError exception for invalid type | ||
"UP", # pyupgrade | ||
"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 | ||
"D404", # First word of the docstring should not be This | ||
"D406", # Section name should end with a newline | ||
"D407", # Section name underlining | ||
"D411", # Missing blank line before section | ||
"E501", # line too long | ||
"E731", # do not assign a lambda expression, use a def | ||
] | ||
|
||
[tool.ruff.flake8-pytest-style] | ||
fixture-parentheses = false | ||
|
||
[tool.ruff.pyupgrade] | ||
keep-runtime-typing = true | ||
|
||
[tool.ruff.per-file-ignores] | ||
|
||
# TODO: these files have functions that are too complex, but flake8's and ruff's | ||
# complexity (and/or nested-function) handling differs; trying to add a noqa doesn't work | ||
# because the flake8-noqa plugin then disagrees on whether there should be a C901 noqa | ||
# on that line. So, for now, we just ignore C901s on these files as far as ruff is concerned. | ||
|
||
"homeassistant/components/light/__init__.py" = ["C901"] | ||
"homeassistant/components/mqtt/discovery.py" = ["C901"] | ||
"homeassistant/components/websocket_api/http.py" = ["C901"] | ||
|
||
# Allow for main entry & scripts to write to stdout | ||
"homeassistant/__main__.py" = ["T201"] | ||
"homeassistant/scripts/*" = ["T201"] | ||
"script/*" = ["T20"] | ||
|
||
[tool.ruff.mccabe] | ||
max-complexity = 25 |