mirror of
https://github.com/jpawlowski/hass.tibber_prices.git
synced 2026-05-28 18:43:40 +00:00
fix(lint): apply Python 3.14 ruff rules and update HA minimum version
Add UP037 to ruff ignore list to preserve quoted TYPE_CHECKING forward references (PEP 649 lazy eval breaks get_type_hints() at runtime for TYPE_CHECKING-guarded imports). Move datetime imports into TYPE_CHECKING blocks in sensor/calculators timing.py and trend.py (TC003, type-only usage confirmed). Apply PEP 758 parenthesis-free except clauses across 7 files via ruff format with target-version=py314. Update hacs.json minimum HA version to 2026.4.0, the first HA release requiring Python 3.14. Impact: Linter config now correctly handles Python 3.14 semantics. Users need HA >= 2026.4 (Python 3.14) to use this integration.
This commit is contained in:
parent
f2f0d296d1
commit
ac7cd5b572
11 changed files with 17 additions and 12 deletions
|
|
@ -458,7 +458,7 @@ class TibberPricesConfigFlowHandler(ConfigFlow, domain=DOMAIN):
|
|||
valid_to_dt = datetime.fromisoformat(valid_to)
|
||||
if valid_to_dt < datetime.now(valid_to_dt.tzinfo):
|
||||
return "expired"
|
||||
except (ValueError, AttributeError):
|
||||
except ValueError, AttributeError:
|
||||
pass # If parsing fails, continue with other checks
|
||||
|
||||
# Check validFrom (contract start date)
|
||||
|
|
@ -468,7 +468,7 @@ class TibberPricesConfigFlowHandler(ConfigFlow, domain=DOMAIN):
|
|||
valid_from_dt = datetime.fromisoformat(valid_from)
|
||||
if valid_from_dt > datetime.now(valid_from_dt.tzinfo):
|
||||
return "future"
|
||||
except (ValueError, AttributeError):
|
||||
except ValueError, AttributeError:
|
||||
pass # If parsing fails, assume active
|
||||
|
||||
return "active"
|
||||
|
|
|
|||
|
|
@ -205,7 +205,7 @@ class TibberPricesPeriodCalculator:
|
|||
# Internal calculations always use positive values with reverse_sort flag
|
||||
try:
|
||||
flex = abs(float(flex)) / 100 # Always positive internally
|
||||
except (TypeError, ValueError):
|
||||
except TypeError, ValueError:
|
||||
flex = (
|
||||
abs(_const.DEFAULT_BEST_PRICE_FLEX) / 100
|
||||
if not reverse_sort
|
||||
|
|
|
|||
|
|
@ -134,7 +134,7 @@ class TibberPricesEntity(CoordinatorEntity[TibberPricesDataUpdateCoordinator]):
|
|||
home_name = f"{home_name}, {city}"
|
||||
else:
|
||||
home_name = "Tibber Home"
|
||||
except (KeyError, IndexError, TypeError):
|
||||
except KeyError, IndexError, TypeError:
|
||||
return "Tibber Home", None
|
||||
else:
|
||||
return home_name, home_type
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ def add_next_avg_attributes( # noqa: PLR0913
|
|||
# Extract hours from sensor key (e.g., "next_avg_3h" -> 3)
|
||||
try:
|
||||
hours = int(key.rsplit("_", maxsplit=1)[-1].replace("h", ""))
|
||||
except (ValueError, AttributeError):
|
||||
except ValueError, AttributeError:
|
||||
return
|
||||
|
||||
# Use TimeService to get the N-hour window starting from next interval
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ def _hours_to_minutes(state_value: Any) -> int | None:
|
|||
|
||||
try:
|
||||
return round(float(state_value) * 60)
|
||||
except (TypeError, ValueError):
|
||||
except TypeError, ValueError:
|
||||
return None
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -14,10 +14,13 @@ The calculator provides smart defaults:
|
|||
- No more periods → 0 for numeric values, None for timestamps
|
||||
"""
|
||||
|
||||
from datetime import datetime
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from .base import TibberPricesBaseCalculator # Constants
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from datetime import datetime
|
||||
|
||||
PROGRESS_GRACE_PERIOD_SECONDS = 60 # Show 100% for 1 minute after period ends
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ Caching strategy:
|
|||
- Current trend + next change: Cached centrally for 60s to avoid duplicate calculations
|
||||
"""
|
||||
|
||||
from datetime import datetime
|
||||
from typing import TYPE_CHECKING, Any, ClassVar
|
||||
|
||||
from custom_components.tibber_prices.const import get_display_unit_factor
|
||||
|
|
@ -27,6 +26,8 @@ from custom_components.tibber_prices.utils.price import (
|
|||
from .base import TibberPricesBaseCalculator
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from datetime import datetime
|
||||
|
||||
from custom_components.tibber_prices.coordinator import (
|
||||
TibberPricesDataUpdateCoordinator,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -889,7 +889,7 @@ class TibberPricesSensor(TibberPricesEntity, RestoreSensor):
|
|||
if self.entity_description.entity_category == EntityCategory.DIAGNOSTIC:
|
||||
try:
|
||||
value = self.native_value
|
||||
except (KeyError, ValueError, TypeError):
|
||||
except KeyError, ValueError, TypeError:
|
||||
# If we can't get the value, hide the sensor
|
||||
return False
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -211,7 +211,7 @@ def _check_custom_cards_installed(hass: Any) -> dict[str, bool]:
|
|||
installed_cards["apexcharts-card"] = True
|
||||
if "config-template-card" in url:
|
||||
installed_cards["config-template-card"] = True
|
||||
except (AttributeError, TypeError):
|
||||
except AttributeError, TypeError:
|
||||
# Fallback: can't determine, assume not installed
|
||||
pass
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"name": "Tibber Price Information & Ratings",
|
||||
"homeassistant": "2025.10.0",
|
||||
"homeassistant": "2026.4.0",
|
||||
"hacs": "2.0.5"
|
||||
}
|
||||
}
|
||||
|
|
@ -39,6 +39,7 @@ ignore = [
|
|||
"D212", # multi-line-summary-first-line (incompatible with formatter)
|
||||
"COM812", # incompatible with formatter
|
||||
"ISC001", # incompatible with formatter
|
||||
"UP037", # quoted annotations; needed for TYPE_CHECKING forward references
|
||||
]
|
||||
|
||||
[tool.ruff.lint.per-file-ignores]
|
||||
|
|
|
|||
Loading…
Reference in a new issue