Skip to content

Commit fa523cf

Browse files
committed
Py bump and ruff over black/isort
1 parent 391195f commit fa523cf

File tree

12 files changed

+127
-71
lines changed

12 files changed

+127
-71
lines changed

.github/workflows/merge.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ name: Latest release
55

66
env:
77
CACHE_VERSION: 7
8-
DEFAULT_PYTHON: "3.11"
8+
DEFAULT_PYTHON: "3.12"
99

1010
# Only run on merges
1111
on:

.github/workflows/verify.yml

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ name: Latest commit
55

66
env:
77
CACHE_VERSION: 6
8-
DEFAULT_PYTHON: "3.11"
8+
DEFAULT_PYTHON: "3.12"
99
PRE_COMMIT_HOME: ~/.cache/pre-commit
1010

1111
on:
@@ -65,9 +65,9 @@ jobs:
6565
. venv/bin/activate
6666
pre-commit install-hooks
6767
68-
black:
68+
ruff:
6969
runs-on: ubuntu-latest
70-
name: Black check and force
70+
name: Ruff check and force
7171
needs: prepare
7272
steps:
7373
- name: Check out committed code
@@ -94,27 +94,27 @@ jobs:
9494
run: |
9595
echo "Failed to restore Python ${{ env.DEFAULT_PYTHON }} virtual environment from cache"
9696
exit 1
97-
- name: Run black --check --exclude venv .
97+
- name: Ruff (with fix)
9898
run: |
9999
. venv/bin/activate
100-
black --check --exclude venv .
101-
- name: If needed, commit black changes to the pull request
100+
ruff plugwise/*py tests/*py
101+
- name: If needed, commit ruff changes to the pull request
102102
if: failure()
103103
run: |
104104
. venv/bin/activate
105-
black --exclude venv .
106-
git config --global user.name 'autoblack'
105+
ruff --fix plugwise/*py tests/*py
106+
git config --global user.name 'autoruff'
107107
git config --global user.email 'plugwise@users.noreply.github.com'
108108
git remote set-url origin https://x-access-token:${{ secrets.PAT_CT }}@github.com/$GITHUB_REPOSITORY
109109
git checkout $GITHUB_HEAD_REF
110-
git commit -am "fixup: ${GITHUB_REF##*/} Python code reformatted using Black"
110+
git commit -am "fixup: ${GITHUB_REF##*/} Python code fixed using ruff"
111111
git push origin ${GITHUB_REF##*/}
112112
113113
commitcheck:
114114
runs-on: ubuntu-latest
115115
name: Check commit
116116
needs:
117-
- black
117+
- ruff
118118
- shellcheck
119119
- dependencies_check
120120
steps:

.pre-commit-config.yaml

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,6 @@ repos:
1616
- id: ruff
1717
args:
1818
- --fix
19-
- repo: https://github.com/PyCQA/isort
20-
rev: 5.13.2
21-
hooks:
22-
- id: isort
2319
- repo: https://github.com/pre-commit/pre-commit-hooks
2420
rev: v4.5.0
2521
hooks:
@@ -33,14 +29,6 @@ repos:
3329
hooks:
3430
- id: pyupgrade
3531
args: [--py39-plus]
36-
- repo: https://github.com/psf/black
37-
rev: 23.12.1
38-
hooks:
39-
- id: black
40-
args:
41-
- --safe
42-
- --quiet
43-
files: ^((plugwise|tests|scripts)/.+)?[^/]+\.py$
4432
# Moved codespell configuration to setup.cfg as per 'all-files' issues not reading args
4533
- repo: https://github.com/codespell-project/codespell
4634
rev: v2.2.6

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
## Ongoing
44

55
- Refresh adam_plus_anna_new userdata and adapt.
6+
- Bump actions and requirements to Python 3.12
7+
- Ruff as per #470 (defaulting black and isort to ruff)
68

79
## v0.35.4
810

README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,13 @@ Our main usage for this module is supporting [Home Assistant](https://www.home-a
1414
[![pre-commit.ci status](https://results.pre-commit.ci/badge/github/plugwise/python-plugwise/main.svg)](https://results.pre-commit.ci/latest/github/plugwise/python-plugwise/main)
1515
[![renovate maintained](https://img.shields.io/badge/maintained%20with-renovate-blue?logo=renovatebot)](https://github.com/plugwise/python-plugwise/issues/291)
1616

17-
The below scoring only applies to Plugwise Smile components:
18-
1917
[![CodeFactor](https://www.codefactor.io/repository/github/plugwise/python-plugwise/badge)](https://www.codefactor.io/repository/github/plugwise/python-plugwise)
2018
[![codecov](https://codecov.io/gh/plugwise/python-plugwise/branch/main/graph/badge.svg)](https://codecov.io/gh/plugwise/python-plugwise)
2119

20+
[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=plugwise_python-plugwise&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=plugwise_python-plugwise)
21+
[![Technical Debt](https://sonarcloud.io/api/project_badges/measure?project=plugwise_python-plugwise&metric=sqale_index)](https://sonarcloud.io/summary/new_code?id=plugwise_python-plugwise)
22+
[![Code Smells](https://sonarcloud.io/api/project_badges/measure?project=plugwise_python-plugwise&metric=code_smells)](https://sonarcloud.io/summary/new_code?id=plugwise_python-plugwise)
23+
2224
## Integration
2325

2426
### Home-Assistant Integration

plugwise/__init__.py

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -424,22 +424,21 @@ async def _smile_detect_legacy(
424424
locator = f"./{network}/mac"
425425
if (net_locator := self._system.find(locator)) is not None:
426426
self.smile_mac_address = net_locator.text
427-
else:
428-
# P1 legacy:
429-
if dsmrmain is not None:
430-
self._status = await self._request(STATUS)
431-
self.smile_fw_version = self._status.find("./system/version").text
432-
model = self._status.find("./system/product").text
433-
self.smile_hostname = self._status.find("./network/hostname").text
434-
self.smile_mac_address = self._status.find("./network/mac_address").text
435-
436-
else: # pragma: no cover
437-
# No cornercase, just end of the line
438-
LOGGER.error(
439-
"Connected but no gateway device information found, please create"
440-
" an issue on http://github.com/plugwise/python-plugwise"
441-
)
442-
raise ResponseError
427+
# P1 legacy:
428+
elif dsmrmain is not None:
429+
self._status = await self._request(STATUS)
430+
self.smile_fw_version = self._status.find("./system/version").text
431+
model = self._status.find("./system/product").text
432+
self.smile_hostname = self._status.find("./network/hostname").text
433+
self.smile_mac_address = self._status.find("./network/mac_address").text
434+
435+
else: # pragma: no cover
436+
# No cornercase, just end of the line
437+
LOGGER.error(
438+
"Connected but no gateway device information found, please create"
439+
" an issue on http://github.com/plugwise/python-plugwise"
440+
)
441+
raise ResponseError
443442

444443
self._smile_legacy = True
445444
return model

plugwise/helper.py

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1095,14 +1095,13 @@ def _get_measurement_data(self, dev_id: str) -> DeviceData:
10951095

10961096
# Loria/Thermastage: cooling-related is based on cooling_state
10971097
# and modulation_level
1098-
else:
1099-
if self._cooling_present and "cooling_state" in data["binary_sensors"]:
1100-
self._cooling_enabled = data["binary_sensors"]["cooling_state"]
1101-
self._cooling_active = data["sensors"]["modulation_level"] == 100
1102-
# For Loria the above does not work (pw-beta issue #301)
1103-
if "cooling_ena_switch" in data["switches"]:
1104-
self._cooling_enabled = data["switches"]["cooling_ena_switch"]
1105-
self._cooling_active = data["binary_sensors"]["cooling_state"]
1098+
elif self._cooling_present and "cooling_state" in data["binary_sensors"]:
1099+
self._cooling_enabled = data["binary_sensors"]["cooling_state"]
1100+
self._cooling_active = data["sensors"]["modulation_level"] == 100
1101+
# For Loria the above does not work (pw-beta issue #301)
1102+
if "cooling_ena_switch" in data["switches"]:
1103+
self._cooling_enabled = data["switches"]["cooling_ena_switch"]
1104+
self._cooling_active = data["binary_sensors"]["cooling_state"]
11061105

11071106
self._cleanup_data(data)
11081107

plugwise/util.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,12 @@ def format_measure(measure: str, unit: str) -> float | int:
3838
result = float(f"{round(float_measure, 3):.3f}")
3939
elif unit == ELECTRIC_POTENTIAL_VOLT:
4040
result = float(f"{round(float_measure, 1):.1f}")
41-
else:
42-
if abs(float_measure) < 10:
43-
result = float(f"{round(float_measure, 2):.2f}")
44-
elif abs(float_measure) >= 10 and abs(float_measure) < 100:
45-
result = float(f"{round(float_measure, 1):.1f}")
46-
elif abs(float_measure) >= 100:
47-
result = int(round(float_measure))
41+
elif abs(float_measure) < 10:
42+
result = float(f"{round(float_measure, 2):.2f}")
43+
elif abs(float_measure) >= 10 and abs(float_measure) < 100:
44+
result = float(f"{round(float_measure, 1):.1f}")
45+
elif abs(float_measure) >= 100:
46+
result = int(round(float_measure))
4847

4948
return result
5049

pyproject.toml

Lines changed: 80 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@ classifiers = [
1414
"Intended Audience :: Developers",
1515
"License :: OSI Approved :: MIT License",
1616
"Operating System :: OS Independent",
17-
"Programming Language :: Python :: 3.10",
18-
"Programming Language :: Python :: 3.11",
1917
"Programming Language :: Python :: 3.12",
2018
"Topic :: Home Automation",
2119
]
@@ -26,7 +24,7 @@ maintainers = [
2624
{ name = "bouwew"},
2725
{ name = "CoMPaTech" }
2826
]
29-
requires-python = ">=3.10.0"
27+
requires-python = ">=3.12.0"
3028
dependencies = [
3129
"aiohttp",
3230
"async_timeout",
@@ -53,7 +51,7 @@ include-package-data = true
5351
include = ["plugwise*"]
5452

5553
[tool.black]
56-
target-version = ["py310", "py311", "py312"]
54+
target-version = ["py312"]
5755
exclude = 'generated'
5856

5957
[tool.isort]
@@ -189,7 +187,7 @@ norecursedirs = [
189187
]
190188

191189
[tool.mypy]
192-
python_version = "3.11"
190+
python_version = "3.12"
193191
show_error_codes = true
194192
follow_imports = "silent"
195193
ignore_missing_imports = true
@@ -219,28 +217,70 @@ omit= [
219217
]
220218

221219
[tool.ruff]
222-
target-version = "py311"
220+
target-version = "py312"
223221

224222
select = [
223+
"B002", # Python does not support the unary prefix increment
225224
"B007", # Loop control variable {name} not used within loop body
226225
"B014", # Exception handler with duplicate exception
226+
"B023", # Function definition does not bind loop variable {name}
227+
"B026", # Star-arg unpacking after a keyword argument is strongly discouraged
227228
"C", # complexity
229+
"COM818", # Trailing comma on bare tuple prohibited
228230
"D", # docstrings
231+
"DTZ003", # Use datetime.now(tz=) instead of datetime.utcnow()
232+
"DTZ004", # Use datetime.fromtimestamp(ts, tz=) instead of datetime.utcfromtimestamp(ts)
229233
"E", # pycodestyle
230234
"F", # pyflakes/autoflake
235+
"G", # flake8-logging-format
236+
"I", # isort
231237
"ICN001", # import concentions; {name} should be imported as {asname}
232-
"PGH004", # Use specific rule codes when using noqa
238+
"ISC001", # Implicitly concatenated string literals on one line
239+
"N804", # First argument of a class method should be named cls
240+
"N805", # First argument of a method should be named self
241+
"N815", # Variable {name} in class scope should not be mixedCase
242+
"PGH001", # No builtin eval() allowed
243+
"PGH004", # Use specific rule codes when using noqa
244+
"PL", # https://github.com/astral-sh/ruff/issues/7491#issuecomment-1730008111
233245
"PLC0414", # Useless import alias. Import alias does not rename original package.
246+
"PLC", # pylint
247+
"PLE", # pylint
248+
"PLR", # pylint
249+
"PLW", # pylint
250+
"Q000", # Double quotes found but single quotes preferred
251+
"RUF006", # Store a reference to the return value of asyncio.create_task
252+
"S102", # Use of exec detected
253+
"S103", # bad-file-permissions
254+
"S108", # hardcoded-temp-file
255+
"S306", # suspicious-mktemp-usage
256+
"S307", # suspicious-eval-usage
257+
"S313", # suspicious-xmlc-element-tree-usage
258+
"S314", # suspicious-xml-element-tree-usage
259+
"S315", # suspicious-xml-expat-reader-usage
260+
"S316", # suspicious-xml-expat-builder-usage
261+
"S317", # suspicious-xml-sax-usage
262+
"S318", # suspicious-xml-mini-dom-usage
263+
"S319", # suspicious-xml-pull-dom-usage
264+
"S320", # suspicious-xmle-tree-usage
265+
"S601", # paramiko-call
266+
"S602", # subprocess-popen-with-shell-equals-true
267+
"S604", # call-with-shell-equals-true
268+
"S608", # hardcoded-sql-expression
269+
"S609", # unix-command-wildcard-injection
234270
"SIM105", # Use contextlib.suppress({exception}) instead of try-except-pass
235271
"SIM117", # Merge with-statements that use the same scope
236272
"SIM118", # Use {key} in {dict} instead of {key} in {dict}.keys()
237273
"SIM201", # Use {left} != {right} instead of not {left} == {right}
274+
"SIM208", # Use {expr} instead of not (not {expr})
238275
"SIM212", # Use {a} if {a} else {b} instead of {b} if not {a} else {a}
239276
"SIM300", # Yoda conditions. Use 'age == 42' instead of '42 == age'.
240277
"SIM401", # Use get from dict with default instead of an if block
278+
"T100", # Trace found: {name} used
241279
"T20", # flake8-print
280+
"TID251", # Banned imports
242281
"TRY004", # Prefer TypeError exception for invalid type
243-
"RUF006", # Store a reference to the return value of asyncio.create_task
282+
"TRY200", # Use raise from to specify exception cause
283+
"TRY302", # Remove exception handler; error is immediately re-raised
244284
"UP", # pyupgrade
245285
"W", # pycodestyle
246286
]
@@ -253,9 +293,19 @@ ignore = [
253293
"D407", # Section name underlining
254294
"E501", # line too long
255295
"E731", # do not assign a lambda expression, use a def
296+
# False positives https://github.com/astral-sh/ruff/issues/5386
297+
"PLC0208", # Use a sequence type instead of a `set` when iterating over values
298+
"PLR0911", # Too many return statements ({returns} > {max_returns})
299+
"PLR0912", # Too many branches ({branches} > {max_branches})
300+
"PLR0913", # Too many arguments to function call ({c_args} > {max_args})
301+
"PLR0915", # Too many statements ({statements} > {max_statements})
302+
"PLR2004", # Magic value used in comparison, consider replacing {value} with a constant variable
303+
"PLW2901", # Outer {outer_kind} variable {name} overwritten by inner {inner_kind} target
304+
"UP006", # keep type annotation style as is
305+
"UP007", # keep type annotation style as is
306+
# Ignored due to performance: https://github.com/charliermarsh/ruff/issues/2923
307+
#"UP038", # Use `X | Y` in `isinstance` call instead of `(X, Y)`
256308
]
257-
# # Ignored due to performance: https://github.com/charliermarsh/ruff/issues/2923
258-
# "UP038", # Use `X | Y` in `isinstance` call instead of `(X, Y)`
259309

260310
exclude = []
261311

@@ -272,3 +322,23 @@ fixture-parentheses = false
272322

273323
[tool.ruff.mccabe]
274324
max-complexity = 25
325+
326+
[tool.ruff.flake8-tidy-imports.banned-api]
327+
"pytz".msg = "use zoneinfo instead"
328+
329+
[tool.ruff.isort]
330+
force-sort-within-sections = true
331+
section-order = ["future", "standard-library", "first-party", "third-party", "local-folder"]
332+
known-third-party = [
333+
"tests",
334+
]
335+
known-first-party = [
336+
"plugwise",
337+
"voluptuous",
338+
"pytest",
339+
]
340+
forced-separate = [
341+
"tests",
342+
]
343+
combine-as-imports = true
344+
split-on-trailing-comma = false

requirements_commit.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
-e .
33
# Minimal requirements for committing
44
# Versioning omitted (leave this up to HA-core)
5-
black
65
coverage
76
ruff
87
mypy

0 commit comments

Comments
 (0)