hass.tibber_prices/pyproject.toml
dependabot[bot] 5d80dc7df4
Some checks failed
Lint / Ruff (push) Has been cancelled
Validate / Hassfest validation (push) Has been cancelled
Validate / HACS validation (push) Has been cancelled
chore(deps): update pytest-homeassistant-custom-component requirement (#131)
2026-05-01 00:18:38 +02:00

293 lines
12 KiB
TOML

# Custom Component pyproject.toml based on Home Assistant Core
# https://github.com/home-assistant/core/blob/dev/pyproject.toml
#
# Sections not included (HA Core specific):
# - [build-system] - Not published to PyPI (installed via HACS)
# - [tool.pylint.*] - Optional additional linting (Ruff is sufficient)
[project]
name = "tibber_prices"
version = "0.0.0" # Version is managed in manifest.json only
requires-python = ">=3.14.2"
[tool.setuptools]
packages = ["custom_components.tibber_prices"]
[tool.pyright]
include = ["custom_components/tibber_prices"]
exclude = [
"**/.*",
"**/__pycache__",
"**/config",
"**/docs",
"**/node_modules",
"**/venv",
]
venvPath = "."
venv = ".venv"
typeCheckingMode = "basic"
reportUnusedImport = "none"
reportUnusedVariable = "none"
reportUnusedCoroutine = "none"
reportMissingTypeStubs = "none"
[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_debug = true
asyncio_mode = "auto"
asyncio_default_fixture_loop_scope = "function"
addopts = "-ra -q --strict-markers"
markers = [
"unit: Unit tests (fast, no external dependencies)",
"integration: Integration tests (may use coordinator/time service)",
]
filterwarnings = [
# Treat warnings as errors to catch issues early
"error",
# Ignore specific warnings from third-party libraries as needed
# "ignore:.*custom_components.* is using deprecated.*:DeprecationWarning",
# AsyncMock cleanup noise when mixing sync/async mocks
"ignore::pytest.PytestUnraisableExceptionWarning",
]
[tool.coverage.run]
source = ["custom_components/tibber_prices"]
omit = ["tests/*"]
[tool.coverage.report]
exclude_lines = [
"pragma: no cover",
"def __repr__",
"raise AssertionError",
"raise NotImplementedError",
"if TYPE_CHECKING:",
"@overload",
]
[tool.ruff]
# Based on https://github.com/home-assistant/core/blob/dev/pyproject.toml
required-version = ">=0.15.1"
target-version = "py314"
line-length = 120
[tool.ruff.lint]
select = [
"A001", # Variable {name} is shadowing a Python builtin
"ASYNC", # flake8-async
"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
"B009", # Do not call getattr with a constant attribute value. It is not any safer than normal property access.
"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}
"B024", # `{name}` is an abstract base class, but it has no abstract methods or properties
"B025", # try-except* block with duplicate exception {name}
"B026", # Star-arg unpacking after a keyword argument is strongly discouraged
"B032", # Possible unintentional type annotation (using :). Did you mean to assign (using =)?
"B035", # Dictionary comprehension uses static key
"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
"RUF007", # Prefer itertools.pairwise() over zip() when iterating over successive pairs
"RUF008", # Do not use mutable default values for dataclass attributes
"RUF010", # Use explicit conversion flag
"RUF013", # PEP 484 prohibits implicit Optional
"RUF016", # Slice in indexed access to type {value_type} uses type {index_type} instead of an integer
"RUF017", # Avoid quadratic list summation
"RUF018", # Avoid assignment expressions in assert statements
"RUF019", # Unnecessary key check before dictionary access
"RUF020", # {never_like} | T is equivalent to T
"RUF021", # Parenthesize a and b expressions when chaining and and or together, to make the precedence clear
"RUF022", # Sort __all__
"RUF023", # Sort __slots__
"RUF024", # Do not pass mutable objects as values to dict.fromkeys
"RUF026", # default_factory is a positional-only argument to defaultdict
"RUF030", # print() call in assert statement is likely unintentional
"RUF032", # Decimal() called with float literal argument
"RUF033", # __post_init__ method with argument defaults
"RUF034", # Useless if-else condition
"RUF059", # unused-unpacked-variable
"RUF100", # Unused `noqa` directive
"RUF101", # noqa directives that use redirected rule codes
"RUF200", # Failed to parse pyproject.toml: {message}
"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 = [
"ANN401", # Dynamically typed expressions (typing.Any) are disallowed
"ASYNC109", # Async function definition with a `timeout` parameter Use `asyncio.timeout` instead
"ASYNC110", # Use `asyncio.Event` instead of awaiting `asyncio.sleep` in a `while` loop
"ASYNC240", # Use an async function for entering the file system
"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
"D417", # Missing argument descriptions in docstring - to allow documenting only non-obvious parameters
"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
"PLW0108", # Unnecessary lambda wrapping a function call; can often be replaced by the function itself
"PLW1641", # __eq__ without __hash__
"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
# Quotes for typing.cast generally not necessary, only for performance critical paths
"TC006", # Add quotes to type expression in typing.cast()
"TRY003", # Avoid specifying long messages outside the exception class
"TRY400", # Use `logging.exception` instead of `logging.error`
"UP046", # Non PEP 695 generic class
"UP047", # Non PEP 696 generic function
"UP049", # Avoid private type parameter names
# May conflict with the formatter, https://docs.astral.sh/ruff/formatter/#conflicting-lint-rules
"W191",
"E111",
"E114",
"E117",
"D203",
"D206",
"D212",
"D300",
"Q",
"COM812",
"COM819",
"ISC001",
# Disabled because ruff does not understand type of __all__ generated by a function
"PLE0605",
"FURB116",
]
[tool.ruff.lint.flake8-import-conventions.extend-aliases]
# Commonly used Home Assistant imports
voluptuous = "vol"
"homeassistant.helpers.config_validation" = "cv"
"homeassistant.helpers.device_registry" = "dr"
"homeassistant.helpers.entity_registry" = "er"
"homeassistant.util.dt" = "dt_util"
[tool.ruff.lint.flake8-pytest-style]
fixture-parentheses = false
mark-parentheses = false
[tool.ruff.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"
[tool.ruff.lint.isort]
force-sort-within-sections = true
known-first-party = ["custom_components", "homeassistant"]
combine-as-imports = true
split-on-trailing-comma = false
[tool.ruff.lint.per-file-ignores]
"script/*" = [
"T20", # print() allowed in scripts
"INP001", # Implicit namespace package (scripts are not a package)
]
"tests/*" = [
"S101", # assert is fine in tests
"PLR2004", # Magic values are fine in tests
"D", # Docstrings not required in tests
"PTH", # Use pathlib - temporary exemption for tests
]
[tool.ruff.lint.mccabe]
max-complexity = 25
[tool.ruff.lint.pydocstyle]
convention = "google"
property-decorators = ["propcache.api.cached_property"]
[tool.ruff.lint.pyupgrade]
keep-runtime-typing = true
[project.optional-dependencies]
test = ["pytest-homeassistant-custom-component>=0.13.326"]