diff --git a/.github/workflows/merge.yml b/.github/workflows/merge.yml index bfd769a2f..8a2853497 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -4,7 +4,7 @@ name: Latest release env: - CACHE_VERSION: 5 + CACHE_VERSION: 21 DEFAULT_PYTHON: "3.12" # Only run on merges @@ -22,7 +22,7 @@ jobs: if: github.event.pull_request.merged == true steps: - name: Check out committed code - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 + uses: actions/checkout@v4 - name: Set up Python ${{ env.DEFAULT_PYTHON }} id: python uses: actions/setup-python@v5 diff --git a/.github/workflows/verify.yml b/.github/workflows/verify.yml index c0ebf30aa..39d63ae63 100644 --- a/.github/workflows/verify.yml +++ b/.github/workflows/verify.yml @@ -4,7 +4,7 @@ name: Latest commit env: - CACHE_VERSION: 6 + CACHE_VERSION: 22 DEFAULT_PYTHON: "3.12" PRE_COMMIT_HOME: ~/.cache/pre-commit @@ -22,7 +22,7 @@ jobs: name: Prepare steps: - name: Check out committed code - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 + uses: actions/checkout@v4 - name: Set up Python ${{ env.DEFAULT_PYTHON }} id: python uses: actions/setup-python@v5 @@ -48,8 +48,9 @@ jobs: pip install virtualenv --upgrade python -m venv venv . venv/bin/activate - pip install -U pip setuptools wheel - pip install -r requirements_test.txt -r requirements_commit.txt + pip install uv + uv pip install -U pip setuptools wheel + uv pip install -r requirements_test.txt -r requirements_commit.txt - name: Restore pre-commit environment from cache id: cache-precommit uses: actions/cache@v4 @@ -71,7 +72,7 @@ jobs: needs: prepare steps: - name: Check out committed code - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 + uses: actions/checkout@v4 with: persist-credentials: false - name: Set up Python ${{ env.DEFAULT_PYTHON }} @@ -97,7 +98,7 @@ jobs: - name: Ruff (check) run: | . venv/bin/activate - #ruff plugwise_usb/*py tests/*py + #ruff check plugwise_usb/*py tests/*py echo "***" echo "***" echo "Code is not up to par for ruff, skipping" @@ -107,7 +108,7 @@ jobs: if: failure() run: | . venv/bin/activate - ruff --fix plugwise_usb/*py tests/*py + ruff check --fix plugwise_usb/*py tests/*py git config --global user.name 'autoruff' git config --global user.email 'plugwise_usb@users.noreply.github.com' git remote set-url origin https://x-access-token:${{ secrets.PAT_CT }}@github.com/$GITHUB_REPOSITORY @@ -124,7 +125,7 @@ jobs: - dependencies_check steps: - name: Check out committed code - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 + uses: actions/checkout@v4 - name: Set up Python ${{ env.DEFAULT_PYTHON }} id: python uses: actions/setup-python@v5 @@ -175,7 +176,7 @@ jobs: python-version: ["3.12", "3.11", "3.10"] steps: - name: Check out committed code - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 + uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} id: python uses: actions/setup-python@v5 @@ -199,11 +200,12 @@ jobs: run: | python -m venv venv . venv/bin/activate - pip install -U pip setuptools wheel - #pip install -r requirements_test.txt + pip install uv + uv pip install -U pip setuptools wheel + # uv pip install -r requirements_test.txt # 20220124 Mimic setup_test.sh - pip install --upgrade -r requirements_test.txt -c https://raw.githubusercontent.com/home-assistant/core/dev/homeassistant/package_constraints.txt -r https://raw.githubusercontent.com/home-assistant/core/dev/requirements_test.txt -r https://raw.githubusercontent.com/home-assistant/core/dev/requirements_test_pre_commit.txt - pip install --upgrade pytest-asyncio + uv pip install --upgrade -r requirements_test.txt -c https://raw.githubusercontent.com/home-assistant/core/dev/homeassistant/package_constraints.txt -r https://raw.githubusercontent.com/home-assistant/core/dev/requirements_test.txt -r https://raw.githubusercontent.com/home-assistant/core/dev/requirements_test_pre_commit.txt + uv pip install --upgrade pytest-asyncio pytest: runs-on: ubuntu-latest @@ -215,7 +217,7 @@ jobs: steps: - name: Check out committed code - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 + uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} id: python uses: actions/setup-python@v5 @@ -251,7 +253,7 @@ jobs: needs: pytest steps: - name: Check out committed code - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 + uses: actions/checkout@v4 with: persist-credentials: false - name: Set up Python ${{ env.DEFAULT_PYTHON }} @@ -291,7 +293,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out committed code - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 + uses: actions/checkout@v4 - name: Run ShellCheck uses: ludeeus/action-shellcheck@master @@ -301,7 +303,7 @@ jobs: name: Dependency steps: - name: Check out committed code - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 + uses: actions/checkout@v4 - name: Run dependency checker run: scripts/dependencies_check.sh debug @@ -311,7 +313,7 @@ jobs: needs: pytest steps: - name: Check out committed code - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 + uses: actions/checkout@v4 - name: Set up Python ${{ env.DEFAULT_PYTHON }} id: python uses: actions/setup-python@v5 @@ -356,7 +358,7 @@ jobs: needs: [coverage, mypy] steps: - name: Check out committed code - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 + uses: actions/checkout@v4 - name: Set up Python ${{ env.DEFAULT_PYTHON }} id: python uses: actions/setup-python@v5 @@ -399,7 +401,7 @@ jobs: needs: coverage steps: - name: Check out committed code - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 + uses: actions/checkout@v4 - name: Set up Python ${{ env.DEFAULT_PYTHON }} id: python uses: actions/setup-python@v5 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 26bfd5eba..3da2efc55 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -28,7 +28,7 @@ repos: args: - --branch=main - repo: https://github.com/asottile/pyupgrade - rev: v3.16.0 + rev: v3.17.0 hooks: - id: pyupgrade args: [--py39-plus] @@ -51,10 +51,12 @@ repos: rev: v1.35.1 hooks: - id: yamllint - - repo: https://github.com/pre-commit/mirrors-prettier - rev: v3.1.0 + - repo: https://github.com/biomejs/pre-commit + rev: v0.4.0 hooks: - - id: prettier + - id: biome-lint + additional_dependencies: ["@biomejs/biome@1.8.3"] + name: "Verifying/updating code with biome (improved prettier)" - repo: https://github.com/cdce8p/python-typing-update rev: v0.6.0 hooks: diff --git a/CHANGELOG.md b/CHANGELOG.md index cbe04f70d..b3375a260 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## Ongoing + +- Ensure CI process remains operational +- Bumped pip to now prepend uv for using quicker dependency resolving and installing +- As for latest HA Core USB team should rework to python 3.12 (not still 3.10) + ## v0.31.4(a0) - Re-add python 3.12 checks and compatibility diff --git a/plugwise_usb/__init__.py b/plugwise_usb/__init__.py index 7b8c815ef..a4bbe45b3 100644 --- a/plugwise_usb/__init__.py +++ b/plugwise_usb/__init__.py @@ -538,8 +538,7 @@ def _pass_message_to_node(self, message, mac, discover=True): return False def _watchdog_loop(self): - """Main worker loop to watch all other worker threads - """ + """Main worker loop to watch all other worker threads""" time.sleep(5) circle_plus_retry_counter = 0 while self._run_watchdog: diff --git a/plugwise_usb/controller.py b/plugwise_usb/controller.py index 8a5ceef83..6fee9e5bc 100644 --- a/plugwise_usb/controller.py +++ b/plugwise_usb/controller.py @@ -327,7 +327,7 @@ def _post_message_action(self, seq_id, ack_response=None, request="unknown"): request, str(seq_id), ) - #Still save it to try and get it back into sync + # Still save it to try and get it back into sync self.last_seq_id = seq_id if resend_request: self.resend(seq_id) diff --git a/plugwise_usb/messages/responses.py b/plugwise_usb/messages/responses.py index 929bbb056..a3bae1f3a 100644 --- a/plugwise_usb/messages/responses.py +++ b/plugwise_usb/messages/responses.py @@ -23,8 +23,7 @@ class NodeResponse(PlugwiseMessage): - """Base class for response messages received by USB-Stick. - """ + """Base class for response messages received by USB-Stick.""" def __init__(self, format_size=None): super().__init__() @@ -561,8 +560,7 @@ def __init__(self): def get_message_response(message_id, length, seq_id): - """Return message class based on sequence ID, Length of message or message ID. - """ + """Return message class based on sequence ID, Length of message or message ID.""" # First check for known sequence ID's if seq_id == b"FFFD": return NodeJoinAckResponse() diff --git a/plugwise_usb/nodes/circle.py b/plugwise_usb/nodes/circle.py index e00b9fb53..97081bd4b 100644 --- a/plugwise_usb/nodes/circle.py +++ b/plugwise_usb/nodes/circle.py @@ -221,28 +221,31 @@ def request_power_update(self, callback=None): if self._energy_last_collected_timestamp < _timestamp_utcnow.replace( minute=0, second=0, microsecond=0 ): - _LOGGER.info("Queue _last_log_address for %s at %s last_collected %s", - str(self.mac),str(self._last_log_address), - self._energy_last_collected_timestamp + _LOGGER.info( + "Queue _last_log_address for %s at %s last_collected %s", + str(self.mac), + str(self._last_log_address), + self._energy_last_collected_timestamp, ) self._request_info(self.push_last_log_address) if len(self._energy_history_failed_address) > 0: - _mem_address = self._energy_history_failed_address.pop(0) - if self._energy_memory.get(_mem_address, 0) < 4: - _LOGGER.info("Collect EnergyCounters for %s at %s", - str(self.mac), - str(_mem_address), - ) - self.request_energy_counters(_mem_address) - self._energy_ratelimit_collection_timestamp = _timestamp_utcnow - else: - _LOGGER.info( - "Drop known request_energy_counters for %s at %s and clock sync", - str(self.mac), - str(_mem_address), - ) - self.get_clock(self.sync_clock) + _mem_address = self._energy_history_failed_address.pop(0) + if self._energy_memory.get(_mem_address, 0) < 4: + _LOGGER.info( + "Collect EnergyCounters for %s at %s", + str(self.mac), + str(_mem_address), + ) + self.request_energy_counters(_mem_address) + self._energy_ratelimit_collection_timestamp = _timestamp_utcnow + else: + _LOGGER.info( + "Drop known request_energy_counters for %s at %s and clock sync", + str(self.mac), + str(_mem_address), + ) + self.get_clock(self.sync_clock) if datetime.now().day != self._last_clock_sync_day: self._last_clock_sync_day = datetime.now().day self.get_clock(self.sync_clock) @@ -252,8 +255,7 @@ def push_last_log_address(self): self._energy_history_failed_address.append(self._last_log_address) def message_for_circle(self, message): - """Process received message - """ + """Process received message""" if isinstance(message, CirclePowerUsageResponse): if self.calibration: self._response_power_usage(message) @@ -387,8 +389,7 @@ def _response_calibration(self, message: CircleCalibrationResponse): self.calibration = True def pulses_to_kws(self, pulses, seconds=1): - """Converts the amount of pulses to kWs using the calaboration offsets - """ + """Converts the amount of pulses to kWs using the calaboration offsets""" if pulses is None: return None if pulses == 0 or not self.calibration: @@ -428,7 +429,7 @@ def _collect_energy_pulses(self, start_utc: datetime, end_utc: datetime): ) else: _mem_address = self._energy_timestamp_memory_address(_log_timestamp) - if (_mem_address is not None and _mem_address >= 0): + if _mem_address is not None and _mem_address >= 0: _LOGGER.info( "_collect_energy_pulses for %s at %s | %s not found", str(self.mac), @@ -443,7 +444,6 @@ def _collect_energy_pulses(self, start_utc: datetime, end_utc: datetime): str(_mem_address), ) - # Validate all history values where present if len(self._energy_history_failed_address) == 0: return _energy_pulses @@ -480,12 +480,11 @@ def _update_energy_today_now(self): and self._energy_pulses_current_hour is not None ): _pulses_today_now = ( - self._energy_pulses_today_hourly - + self._energy_pulses_current_hour + self._energy_pulses_today_hourly + self._energy_pulses_current_hour ) _utc_hour_timestamp = datetime.utcnow().replace( - minute=0, second=0, microsecond=0 + minute=0, second=0, microsecond=0 ) _local_hour = datetime.now().hour _utc_midnight_timestamp = _utc_hour_timestamp - timedelta(hours=_local_hour) @@ -500,9 +499,9 @@ def _update_energy_today_now(self): _utc_hour_timestamp, ) elif ( - self._energy_pulses_today_now is not None - and self._energy_pulses_today_now > _pulses_today_now - and self._energy_pulses_midnight_rollover < _local_midnight_timestamp + self._energy_pulses_today_now is not None + and self._energy_pulses_today_now > _pulses_today_now + and self._energy_pulses_midnight_rollover < _local_midnight_timestamp ): _LOGGER.info( "_update_energy_today_now for %s midnight rollover started old=%s, new=%s", @@ -518,9 +517,14 @@ def _update_energy_today_now(self): ) self.do_callback(FEATURE_ENERGY_CONSUMPTION_TODAY["id"]) elif ( - self._energy_pulses_today_now is not None - and self._energy_pulses_today_now > _pulses_today_now - and int((self._energy_pulses_today_now-_pulses_today_now)/(self._energy_pulses_today_now+1)*100) > 1 + self._energy_pulses_today_now is not None + and self._energy_pulses_today_now > _pulses_today_now + and int( + (self._energy_pulses_today_now - _pulses_today_now) + / (self._energy_pulses_today_now + 1) + * 100 + ) + > 1 ): _LOGGER.info( "_update_energy_today_now for %s hour rollover started old=%s, new=%s", @@ -617,12 +621,14 @@ def _update_energy_today_hourly(self, start_today: datetime, end_today: datetime def request_energy_counters(self, log_address=None, callback=None): """Request power log of specified address""" _LOGGER.debug( - "request_energy_counters for %s of address %s", str(self.mac), str(log_address) + "request_energy_counters for %s of address %s", + str(self.mac), + str(log_address), ) if not self._available: _LOGGER.debug( - "Skip request_energy_counters for % is unavailable", - str(self.mac), + "Skip request_energy_counters for % is unavailable", + str(self.mac), ) return if log_address is None: @@ -687,11 +693,12 @@ def _response_energy_counters(self, message: CircleEnergyCountersResponse): message, "pulses%d" % (_slot,) ).value - _LOGGER.info("push _energy_memory for %s address %s slot %s stamp %s", - str(self.mac), - str(message.logaddr.value), - str(_slot), - str(_log_timestamp), + _LOGGER.info( + "push _energy_memory for %s address %s slot %s stamp %s", + str(self.mac), + str(message.logaddr.value), + str(_slot), + str(_log_timestamp), ) # Store last populated _slot @@ -710,9 +717,11 @@ def _response_energy_counters(self, message: CircleEnergyCountersResponse): self._last_collected_address_timestamp = _log_timestamp # Trigger history rollover - _LOGGER.info('history_rollover %s %s %s',str(_log_timestamp), - str(_utc_hour_timestamp), - str(self._energy_last_rollover_timestamp), + _LOGGER.info( + "history_rollover %s %s %s", + str(_log_timestamp), + str(_utc_hour_timestamp), + str(self._energy_last_rollover_timestamp), ) if ( _log_timestamp == _utc_hour_timestamp @@ -739,7 +748,7 @@ def _response_energy_counters(self, message: CircleEnergyCountersResponse): self._energy_consumption_today_reset = _local_midnight_timestamp _midnight_rollover = True if self._energy_last_collected_timestamp == datetime.utcnow().replace( - minute=0, second=0, microsecond=0 + minute=0, second=0, microsecond=0 ): self._update_energy_previous_hour(_utc_hour_timestamp) self._update_energy_today_hourly( @@ -751,24 +760,31 @@ def _response_energy_counters(self, message: CircleEnergyCountersResponse): _utc_midnight_timestamp, ) else: - _LOGGER.info("CircleEnergyCounter failed for %s at %s|%s count %s", - str(self.mac), - str(message.logaddr.value), - str(self._last_log_address), - str(self._energy_last_collected_count), + _LOGGER.info( + "CircleEnergyCounter failed for %s at %s|%s count %s", + str(self.mac), + str(message.logaddr.value), + str(self._last_log_address), + str(self._energy_last_collected_count), ) - self._energy_last_collected_count +=1 + self._energy_last_collected_count += 1 if ( - message.logaddr.value == self._last_log_address - and self._energy_last_collected_count > 3 + message.logaddr.value == self._last_log_address + and self._energy_last_collected_count > 3 ): - if self._energy_history_failed_address.count(self._last_log_address-1) == 0: - self._energy_history_failed_address.append(self._last_log_address-1) + if ( + self._energy_history_failed_address.count( + self._last_log_address - 1 + ) + == 0 + ): + self._energy_history_failed_address.append( + self._last_log_address - 1 + ) _LOGGER.info("Resetting CircleEnergyCounter due to logaddress offset") - - # Cleanup energy history for more than 48 hours + # Cleanup energy history for more than 48 hours _48_hours_ago = datetime.utcnow().replace( minute=0, second=0, microsecond=0 ) - timedelta(hours=48) @@ -814,7 +830,6 @@ def set_clock(self, callback=None): callback, ) - def sync_clock(self, max_drift=0): """Resync clock of node if time has drifted more than MAX_TIME_DRIFT""" if self._clock_offset is not None: @@ -832,7 +847,7 @@ def _energy_timestamp_memory_address(self, utc_timestamp: datetime): """Return memory address for given energy counter timestamp""" if self._last_collected_address is None: return None - #Should already be hour timestamp, but just to be sure. + # Should already be hour timestamp, but just to be sure. _utc_now_timestamp = self._last_collected_address_timestamp.replace( minute=0, second=0, microsecond=0 ) @@ -855,12 +870,13 @@ def _energy_timestamp_memory_address(self, utc_timestamp: datetime): _address -= 1 _slot = 4 _hours += 1 - _LOGGER.info("Calculated address %s at %s from %s at %s with %s|%s", - _address, - utc_timestamp, - self._last_log_address, - _utc_now_timestamp, - _sslot, - _hours_offset, + _LOGGER.info( + "Calculated address %s at %s from %s at %s with %s|%s", + _address, + utc_timestamp, + self._last_log_address, + _utc_now_timestamp, + _sslot, + _hours_offset, ) return _address diff --git a/plugwise_usb/nodes/circle_plus.py b/plugwise_usb/nodes/circle_plus.py index 14448850b..39b7b5361 100644 --- a/plugwise_usb/nodes/circle_plus.py +++ b/plugwise_usb/nodes/circle_plus.py @@ -26,8 +26,7 @@ def __init__(self, mac, address, message_sender): self.get_real_time_clock(self.sync_realtime_clock) def message_for_circle_plus(self, message): - """Process received message - """ + """Process received message""" if isinstance(message, CirclePlusRealTimeClockResponse): self._response_realtime_clock(message) elif isinstance(message, CirclePlusScanResponse): diff --git a/plugwise_usb/nodes/scan.py b/plugwise_usb/nodes/scan.py index 34461c48b..b9d2cdc3d 100644 --- a/plugwise_usb/nodes/scan.py +++ b/plugwise_usb/nodes/scan.py @@ -45,8 +45,7 @@ def motion(self) -> bool: return self._motion_state def message_for_scan(self, message): - """Process received message - """ + """Process received message""" if isinstance(message, NodeSwitchGroupResponse): _LOGGER.debug( "Switch group %s to state %s received from %s", diff --git a/plugwise_usb/nodes/sed.py b/plugwise_usb/nodes/sed.py index 703913168..9bb6265ad 100644 --- a/plugwise_usb/nodes/sed.py +++ b/plugwise_usb/nodes/sed.py @@ -42,8 +42,7 @@ def __init__(self, mac, address, message_sender): self._battery_powered = True def message_for_sed(self, message): - """Process received message - """ + """Process received message""" if isinstance(message, NodeAwakeResponse): self._process_awake_response(message) elif isinstance(message, NodeAckLargeResponse): diff --git a/plugwise_usb/nodes/sense.py b/plugwise_usb/nodes/sense.py index ee9f26d04..88b75e0a7 100644 --- a/plugwise_usb/nodes/sense.py +++ b/plugwise_usb/nodes/sense.py @@ -44,8 +44,7 @@ def temperature(self) -> int: return self._temperature def message_for_sense(self, message): - """Process received message - """ + """Process received message""" if isinstance(message, SenseReportResponse): self._process_sense_report(message) else: diff --git a/plugwise_usb/nodes/switch.py b/plugwise_usb/nodes/switch.py index 397b18029..8bde56176 100644 --- a/plugwise_usb/nodes/switch.py +++ b/plugwise_usb/nodes/switch.py @@ -27,8 +27,7 @@ def switch(self) -> bool: return self._switch_state def message_for_switch(self, message): - """Process received message - """ + """Process received message""" if isinstance(message, NodeSwitchGroupResponse): _LOGGER.debug( "Switch group request %s received from %s for group id %s", diff --git a/plugwise_usb/parser.py b/plugwise_usb/parser.py index 7f450414a..2e0fb6e2a 100644 --- a/plugwise_usb/parser.py +++ b/plugwise_usb/parser.py @@ -35,8 +35,7 @@ def __init__(self, message_processor): self._message = None def feed(self, data): - """Add new incoming data to buffer and try to process - """ + """Add new incoming data to buffer and try to process""" _LOGGER.debug("Feed data: %s", str(data)) self._buffer += data if len(self._buffer) >= 8: @@ -44,8 +43,7 @@ def feed(self, data): self.parse_data() def next_message(self, message): - """Process next packet if present - """ + """Process next packet if present""" try: self.message_processor(message) # TODO: narrow exception @@ -58,8 +56,7 @@ def next_message(self, message): _LOGGER.error(err, exc_info=True) def parse_data(self): - """Process next set of packet data - """ + """Process next set of packet data""" _LOGGER.debug("Parse data: %s ", str(self._buffer)) if not self._parsing: self._parsing = True diff --git a/pyproject.toml b/pyproject.toml index c3069fa30..a6352799d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -23,11 +23,13 @@ authors = [ { name = "Plugwise device owners"} ] maintainers = [ + { name = "arnoutd_77" }, { name = "bouwew"}, { name = "brefra"}, - { name = "CoMPaTech" } + { name = "CoMPaTech" }, + { name = "dirixmjm" } ] -requires-python = ">=3.9.0" +requires-python = ">=3.10.0" dependencies = [ "aiohttp", "async_timeout", @@ -50,6 +52,10 @@ include-package-data = true [tool.setuptools.packages.find] include = ["plugwise_usb*"] +[tool.black] +target-version = ["py312"] +exclude = 'generated' + [tool.isort] # https://github.com/PyCQA/isort/wiki/isort-Settings profile = "black" @@ -183,7 +189,7 @@ norecursedirs = [ ] [tool.mypy] -python_version = "3.11" +python_version = "3.12" show_error_codes = true follow_imports = "silent" ignore_missing_imports = true @@ -215,12 +221,13 @@ omit= [ [tool.ruff] target-version = "py312" -select = [ +lint.select = [ "B002", # Python does not support the unary prefix increment "B007", # Loop control variable {name} not used within loop body "B014", # Exception handler with duplicate exception "B023", # Function definition does not bind loop variable {name} "B026", # Star-arg unpacking after a keyword argument is strongly discouraged + "B904", # Use raise from err or None to specify exception cause "C", # complexity "COM818", # Trailing comma on bare tuple prohibited "D", # docstrings @@ -235,7 +242,7 @@ select = [ "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 - "PGH001", # No builtin eval() allowed + # "PGH001", # No builtin eval() allowed remapped to S307 "PGH004", # Use specific rule codes when using noqa "PL", # https://github.com/astral-sh/ruff/issues/7491#issuecomment-1730008111 "PLC0414", # Useless import alias. Import alias does not rename original package. @@ -275,13 +282,13 @@ select = [ "T20", # flake8-print "TID251", # Banned imports "TRY004", # Prefer TypeError exception for invalid type - "TRY200", # Use raise from to specify exception cause + # "TRY200", # Use raise from to specify exception cause "TRY302", # Remove exception handler; error is immediately re-raised "UP", # pyupgrade "W", # pycodestyle ] -ignore = [ +lint.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 @@ -305,7 +312,7 @@ ignore = [ exclude = [] -[tool.ruff.flake8-import-conventions.extend-aliases] +[tool.ruff.lint.flake8-import-conventions.extend-aliases] voluptuous = "vol" "homeassistant.helpers.area_registry" = "ar" "homeassistant.helpers.config_validation" = "cv" @@ -313,16 +320,16 @@ voluptuous = "vol" "homeassistant.helpers.entity_registry" = "er" "homeassistant.helpers.issue_registry" = "ir" -[tool.ruff.flake8-pytest-style] +[tool.ruff.lint.flake8-pytest-style] fixture-parentheses = false -[tool.ruff.mccabe] +[tool.ruff.lint.mccabe] max-complexity = 25 -[tool.ruff.flake8-tidy-imports.banned-api] +[tool.ruff.lint.flake8-tidy-imports.banned-api] "pytz".msg = "use zoneinfo instead" -[tool.ruff.isort] +[tool.ruff.lint.isort] force-sort-within-sections = true section-order = ["future", "standard-library", "first-party", "third-party", "local-folder"] known-third-party = [ @@ -338,3 +345,4 @@ forced-separate = [ ] combine-as-imports = true split-on-trailing-comma = false + diff --git a/scripts/setup.sh b/scripts/setup.sh index 96478415b..cb8563eea 100755 --- a/scripts/setup.sh +++ b/scripts/setup.sh @@ -11,8 +11,9 @@ if [ -f "${my_venv}/bin/activate" ]; then # shellcheck disable=SC1091 . "${my_venv}/bin/activate" # Install commit requirements - pip install wheel - pip install --upgrade -e . -r requirements_commit.txt -c https://raw.githubusercontent.com/home-assistant/core/dev/homeassistant/package_constraints.txt -r https://raw.githubusercontent.com/home-assistant/core/dev/requirements_test_pre_commit.txt + pip install uv + uv pip install wheel + uv pip install --upgrade -e . -r requirements_commit.txt -c https://raw.githubusercontent.com/home-assistant/core/dev/homeassistant/package_constraints.txt -r https://raw.githubusercontent.com/home-assistant/core/dev/requirements_test_pre_commit.txt # Install pre-commit hook "${my_venv}/bin/pre-commit" install else diff --git a/scripts/setup_test.sh b/scripts/setup_test.sh index e54b1a34e..7d2613abc 100755 --- a/scripts/setup_test.sh +++ b/scripts/setup_test.sh @@ -11,7 +11,8 @@ if [ -f "${my_venv}/bin/activate" ]; then # shellcheck disable=SC1091 . "${my_venv}/bin/activate" # Install test requirements - pip install --upgrade -e . -r requirements_test.txt -c https://raw.githubusercontent.com/home-assistant/core/dev/homeassistant/package_constraints.txt -r https://raw.githubusercontent.com/home-assistant/core/dev/requirements_test.txt -r https://raw.githubusercontent.com/home-assistant/core/dev/requirements_test_pre_commit.txt + pip install uv + uv pip install --upgrade -e . -r requirements_test.txt -c https://raw.githubusercontent.com/home-assistant/core/dev/homeassistant/package_constraints.txt -r https://raw.githubusercontent.com/home-assistant/core/dev/requirements_test.txt -r https://raw.githubusercontent.com/home-assistant/core/dev/requirements_test_pre_commit.txt # Install pre-commit hook "${my_venv}/bin/pre-commit" install else diff --git a/scripts/tests_and_coverage.sh b/scripts/tests_and_coverage.sh index a6fc5a854..884a5221b 100755 --- a/scripts/tests_and_coverage.sh +++ b/scripts/tests_and_coverage.sh @@ -31,8 +31,9 @@ if [ -z "${GITHUB_ACTIONS}" ] || [ "$1" == "linting" ] ; then echo "... black-ing ..." black plugwise_usb/ tests/ - echo "... ruff-ing ..." - ruff plugwise_usb/ tests/ + # TODO: Skip ruff checks as there are too many for now (mainly missing docstrings) + # echo "... ruff-ing ..." + # ruff check --fix plugwise_usb/ tests/ echo "... pylint-ing ..." pylint plugwise_usb/ tests/