Skip to content

Commit ec78beb

Browse files
authored
chore: migrate to uv (#525)
1 parent 5a4a03b commit ec78beb

File tree

9 files changed

+923
-1825
lines changed

9 files changed

+923
-1825
lines changed

.github/workflows/ci.yml

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,16 +41,14 @@ jobs:
4141
runs-on: ubuntu-latest
4242
steps:
4343
- uses: actions/checkout@v5
44-
- name: Set up Python
45-
uses: actions/setup-python@v6
44+
- name: Set up uv
45+
uses: astral-sh/setup-uv@v7
4646
with:
4747
python-version: ${{ matrix.python-version }}
48-
- uses: snok/install-poetry@v1.4.1
49-
- name: Install Dependencies
50-
run: poetry install
51-
shell: bash
48+
activate-environment: true
49+
- run: uv pip install pip
5250
- name: Test with Pytest
53-
run: poetry run pytest --log-cli-level=DEBUG -vv -s
51+
run: uv run pytest --log-cli-level=DEBUG -vv -s
5452
shell: bash
5553
release:
5654
runs-on: ubuntu-latest

.pre-commit-config.yaml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# See https://pre-commit.com for more information
22
# See https://pre-commit.com/hooks.html for more hooks
33
exclude: "CHANGELOG.md"
4-
default_stages: [ commit ]
4+
default_stages: [ pre-commit ]
55

66
repos:
77
- repo: https://github.com/pre-commit/pre-commit-hooks
@@ -17,10 +17,11 @@ repos:
1717
- id: detect-private-key
1818
- id: end-of-file-fixer
1919
- id: trailing-whitespace
20-
- repo: https://github.com/python-poetry/poetry
21-
rev: 1.7.1
20+
- repo: https://github.com/astral-sh/uv-pre-commit
21+
rev: 0.9.1
2222
hooks:
23-
- id: poetry-check
23+
- id: uv-sync
24+
args: ["--locked", "--all-packages"]
2425
- repo: https://github.com/codespell-project/codespell
2526
rev: v2.2.6
2627
hooks:

poetry.lock

Lines changed: 0 additions & 1768 deletions
This file was deleted.

pyproject.toml

Lines changed: 51 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,74 @@
1-
[tool.poetry]
1+
[project]
22
name = "python-roborock"
33
version = "2.54.0"
44
description = "A package to control Roborock vacuums."
5-
authors = ["humbertogontijo <humbertogontijo@users.noreply.github.com>"]
6-
license = "GPL-3.0-only"
5+
authors = [{ name = "humbertogontijo", email = "humbertogontijo@users.noreply.github.com" }, {name="Lash-L"}, {name="allenporter"}]
6+
requires-python = ">=3.11, <4"
77
readme = "README.md"
8-
repository = "https://github.com/humbertogontijo/python-roborock"
9-
documentation = "https://python-roborock.readthedocs.io/"
8+
license = "GPL-3.0-only"
9+
keywords = [
10+
"roborock",
11+
"vacuum",
12+
"homeassistant",
13+
]
1014
classifiers = [
1115
"Development Status :: 5 - Production/Stable",
1216
"Intended Audience :: Developers",
1317
"Natural Language :: English",
1418
"Operating System :: OS Independent",
1519
"Topic :: Software Development :: Libraries",
1620
]
17-
packages = [{include = "roborock"}]
18-
keywords = ["roborock", "vacuum", "homeassistant"]
21+
dependencies = [
22+
"click>=8",
23+
"aiohttp>=3.8.2,<4",
24+
"pycryptodome~=3.18",
25+
"pycryptodomex~=3.18 ; sys_platform == 'darwin'",
26+
"paho-mqtt>=1.6.1,<3.0.0",
27+
"construct>=2.10.57,<3",
28+
"vacuum-map-parser-roborock",
29+
"pyrate-limiter>=3.7.0,<4",
30+
"aiomqtt>=2.3.2,<3",
31+
"click-shell~=2.1",
32+
]
33+
34+
[project.urls]
35+
Repository = "https://github.com/humbertogontijo/python-roborock"
36+
Documentation = "https://python-roborock.readthedocs.io/"
1937

20-
[tool.poetry.scripts]
38+
[project.scripts]
2139
roborock = "roborock.cli:main"
2240

23-
[tool.poetry.dependencies]
24-
python = "^3.11"
25-
click = ">=8"
26-
aiohttp = "^3.8.2"
27-
pycryptodome = "^3.18"
28-
pycryptodomex = {version = "^3.18", markers = "sys_platform == 'darwin'"}
29-
paho-mqtt = ">=1.6.1,<3.0.0"
30-
construct = "^2.10.57"
31-
vacuum-map-parser-roborock = "*"
32-
pyrate-limiter = "^3.7.0"
33-
aiomqtt = "^2.3.2"
34-
click-shell = "^2.1"
41+
[dependency-groups]
42+
dev = [
43+
"pytest-asyncio>=1.1.0",
44+
"pytest",
45+
"pre-commit>=3.5,<5.0",
46+
"mypy",
47+
"ruff==0.13.2",
48+
"codespell",
49+
"pyshark>=0.6,<0.7",
50+
"aioresponses>=0.7.7,<0.8",
51+
"freezegun>=1.5.1,<2",
52+
"pytest-timeout>=2.3.1,<3",
53+
"syrupy>=4.9.1,<5",
54+
"pdoc>=15.0.4,<16",
55+
]
3556

57+
[tool.hatch.build.targets.sdist]
58+
include = ["roborock"]
3659

37-
[build-system]
38-
requires = ["poetry-core==1.8.0"]
39-
build-backend = "poetry.core.masonry.api"
60+
[tool.hatch.build.targets.wheel]
61+
include = ["roborock"]
4062

41-
[tool.poetry.group.dev.dependencies]
42-
pytest-asyncio = ">=1.1.0"
43-
pytest = "*"
44-
pre-commit = ">=3.5,<5.0"
45-
mypy = "*"
46-
ruff = "*"
47-
codespell = "*"
48-
pyshark = "^0.6"
49-
aioresponses = "^0.7.7"
50-
freezegun = "^1.5.1"
51-
pytest-timeout = "^2.3.1"
52-
syrupy = "^4.9.1"
53-
pdoc = "^15.0.4"
63+
[build-system]
64+
requires = ["hatchling"]
65+
build-backend = "hatchling.build"
5466

5567
[tool.semantic_release]
5668
branch = "main"
5769
version_toml = ["pyproject.toml:tool.poetry.version"]
5870
build_command = "pip install poetry && poetry build"
71+
5972
[tool.semantic_release.commit_parser_options]
6073
allowed_tags = [
6174
"chore",
@@ -67,9 +80,9 @@ allowed_tags = [
6780
major_tags= ["refactor"]
6881

6982
[tool.ruff]
70-
ignore = ["F403", "E741"]
83+
lint.ignore = ["F403", "E741"]
7184
line-length = 120
72-
select=["E", "F", "UP", "I"]
85+
lint.select=["E", "F", "UP", "I"]
7386

7487
[tool.ruff.lint.per-file-ignores]
7588
"*/__init__.py" = ["F401"]

roborock/api.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ async def _wait_response(self, request_id: int, queue: RoborockFuture) -> Any:
8383
if response == "unknown_method":
8484
raise UnknownMethodError("Unknown method")
8585
return response
86-
except (asyncio.TimeoutError, asyncio.CancelledError):
86+
except (TimeoutError, asyncio.CancelledError):
8787
raise RoborockTimeout(f"id={request_id} Timeout after {self.queue_timeout} seconds") from None
8888
finally:
8989
self._waiting_queue.pop(request_id, None)

roborock/containers.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
import re
66
import types
77
from dataclasses import asdict, dataclass, field
8-
from datetime import timezone
98
from enum import Enum
109
from functools import cached_property
1110
from typing import Any, NamedTuple, get_args, get_origin
@@ -717,11 +716,11 @@ def square_meter_area(self) -> float | None:
717716

718717
@property
719718
def begin_datetime(self) -> datetime.datetime | None:
720-
return datetime.datetime.fromtimestamp(self.begin).astimezone(timezone.utc) if self.begin else None
719+
return datetime.datetime.fromtimestamp(self.begin).astimezone(datetime.UTC) if self.begin else None
721720

722721
@property
723722
def end_datetime(self) -> datetime.datetime | None:
724-
return datetime.datetime.fromtimestamp(self.end).astimezone(timezone.utc) if self.end else None
723+
return datetime.datetime.fromtimestamp(self.end).astimezone(datetime.UTC) if self.end else None
725724

726725
def __repr__(self) -> str:
727726
return _attr_repr(self)

roborock/devices/v1_channel.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ async def _get_networking_info(self, *, use_cache: bool = True) -> NetworkInfo:
183183
except RoborockException as e:
184184
raise RoborockException(f"Network info failed for device {self._device_uid}") from e
185185
_LOGGER.debug("Network info for device %s: %s", self._device_uid, network_info)
186-
self._last_network_info_refresh = datetime.datetime.now(datetime.timezone.utc)
186+
self._last_network_info_refresh = datetime.datetime.now(datetime.UTC)
187187
cache_data.network_info[self._device_uid] = network_info
188188
await self._cache.set(cache_data)
189189
return network_info
@@ -253,8 +253,7 @@ def _should_use_cache(self, local_connect_failures: int) -> bool:
253253
if local_connect_failures == 1:
254254
return False
255255
elif self._last_network_info_refresh and (
256-
datetime.datetime.now(datetime.timezone.utc) - self._last_network_info_refresh
257-
> NETWORK_INFO_REFRESH_INTERVAL
256+
datetime.datetime.now(datetime.UTC) - self._last_network_info_refresh > NETWORK_INFO_REFRESH_INTERVAL
258257
):
259258
return False
260259
return True

roborock/protocols/v1_protocol.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ def decode_rpc_response(message: RoborockMessage) -> ResponseMessage:
157157
elif result != "ok":
158158
exc = RoborockException(f"Unexpected API Result: {result}")
159159
result = {}
160-
if not isinstance(result, (dict, list, int)):
160+
if not isinstance(result, dict | list | int):
161161
raise RoborockException(
162162
f"Invalid V1 message format: 'result' was unexpected type {type(result)}. {message.payload!r}"
163163
)

0 commit comments

Comments
 (0)