Repository: plugwise/python-plugwise (language: python)

Issue:
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.2.0
[![Mend Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [astral-sh/ruff-pre-commit](https://togithub.com/astral-sh/ruff-pre-commit) | repository | minor | `v0.1.15` -> `v0.2.0` |

Note: The `pre-commit` manager in Renovate is not supported by the `pre-commit` maintainers or community. Please do not report any problems there, instead [create a Discussion in the Renovate repository](https://togithub.com/renovatebot/renovate/discussions/new) if you have any questions.

---

### Release Notes

<details>
<summary>astral-sh/ruff-pre-commit (astral-sh/ruff-pre-commit)</summary>

### [`v0.2.0`](https://togithub.com/astral-sh/ruff-pre-commit/releases/tag/v0.2.0)

[Compare Source](https://togithub.com/astral-sh/ruff-pre-commit/compare/v0.1.15...v0.2.0)

See: https://github.com/astral-sh/ruff/releases/tag/v0.2.0

</details>

---

### Configuration

📅 **Schedule**: Branch creation - "before 4am" in timezone Europe/Amsterdam, Automerge - At any time (no schedule defined).

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View repository job log [here](https://developer.mend.io/github/plugwise/python-plugwise).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy4xNTMuMiIsInVwZGF0ZWRJblZlciI6IjM3LjE3MC4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiJ9-->



Discussion / hints:

Fix patch:
diff --git a/plugwise/helper.py b/plugwise/helper.py
index f021db134..7f19deb3a 100644
--- a/plugwise/helper.py
+++ b/plugwise/helper.py
@@ -164,9 +164,9 @@ async def _request_validate(self, resp: ClientResponse, method: str) -> etree:
         try:
             # Encode to ensure utf8 parsing
             xml = etree.XML(escape_illegal_xml_characters(result).encode())
-        except etree.ParseError:
+        except etree.ParseError as exc:
             LOGGER.warning("Smile returns invalid XML for %s", self._endpoint)
-            raise InvalidXMLError
+            raise InvalidXMLError from exc
 
         return xml
 
@@ -202,15 +202,15 @@ async def _request(
                 )
         except (
             ClientError
-        ) as err:  # ClientError is an ancestor class of ServerTimeoutError
+        ) as exc:  # ClientError is an ancestor class of ServerTimeoutError
             if retry < 1:
                 LOGGER.warning(
                     "Failed sending %s %s to Plugwise Smile, error: %s",
                     method,
                     command,
-                    err,
+                    exc,
                 )
-                raise ConnectionFailedError
+                raise ConnectionFailedError from exc
             return await self._request(command, retry - 1)
 
         return await self._request_validate(resp, method)
diff --git a/pyproject.toml b/pyproject.toml
index e4e245d86..155aa8733 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -220,12 +220,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
@@ -240,7 +241,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", # PGH001 has been 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.
@@ -280,13 +281,13 @@ select = [
     "T20",  # flake8-print
     "TID251", # Banned imports
     "TRY004", # Prefer TypeError exception for invalid type
-    "TRY200", # Use raise from to specify exception cause
+    # "TRY200", # TRY200 has been remapped to B904
     "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
@@ -310,7 +311,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"
@@ -318,16 +319,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 = [


Test patch:
diff --git a/tests/test_init.py b/tests/test_init.py
index 946717f78..de97945bf 100644
--- a/tests/test_init.py
+++ b/tests/test_init.py
@@ -183,8 +183,8 @@ async def smile_status(self, request):
             with open(userdata, encoding="utf-8") as filedata:
                 data = filedata.read()
             return aiohttp.web.Response(text=data)
-        except OSError:
-            raise aiohttp.web.HTTPNotFound
+        except OSError as exc:
+            raise aiohttp.web.HTTPNotFound from exc
 
     @classmethod
     async def smile_http_accept(cls, request):
@@ -317,9 +317,9 @@ async def connect_wrapper(
                 await self.connect(fail_auth=fail_auth)
                 _LOGGER.error(" - invalid credentials not handled")  # pragma: no cover
                 raise self.ConnectError  # pragma: no cover
-            except pw_exceptions.InvalidAuthentication:
+            except pw_exceptions.InvalidAuthentication as exc:
                 _LOGGER.info(" + successfully aborted on credentials missing.")
-                raise pw_exceptions.InvalidAuthentication
+                raise pw_exceptions.InvalidAuthentication from exc
 
         if raise_timeout:
             _LOGGER.warning("Connecting to device exceeding timeout in handling:")