Migrate from poetry to uv for dependency and package management (#986)

This commit is contained in:
Steven B. 2024-09-06 15:48:43 +01:00 committed by GitHub
parent 1773f98aad
commit a967d5cd3a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 1931 additions and 2504 deletions

View File

@ -1,16 +1,18 @@
---
name: Setup Environment
description: Install requested pipx dependencies, configure the system python, and install poetry and the package dependencies
description: Install requested pipx dependencies, configure the system python, and install uv and the package dependencies
inputs:
poetry-install-options:
uv-install-options:
default: ""
poetry-version:
default: 1.8.2
uv-version:
default: 0.4.5
python-version:
required: true
cache-pre-commit:
default: false
cache-version:
default: "v0.1"
runs:
using: composite
@ -25,7 +27,7 @@ runs:
id: pipx-env-setup
# pipx default home and bin dir are not writable by the cache action
# so override them here and add the bin dir to PATH for later steps.
# This also ensures the pipx cache only contains poetry
# This also ensures the pipx cache only contains uv
run: |
SEP="${{ !startsWith(runner.os, 'windows') && '/' || '\\' }}"
PIPX_CACHE="${{ github.workspace }}${SEP}pipx_cache"
@ -42,43 +44,43 @@ runs:
uses: actions/cache@v4
with:
path: ${{ steps.pipx-env-setup.outputs.pipx-cache-path }}
key: ${{ runner.os }}-${{ runner.arch }}-python-${{ inputs.python-version }}-${{ steps.setup-python.outputs.python-version }}-pipx-${{ steps.pipx-env-setup.outputs.pipx-version }}-poetry-${{ inputs.poetry-version }}
key: cache-${{ inputs.cache-version }}-${{ runner.os }}-${{ runner.arch }}-python-${{ inputs.python-version }}-${{ steps.setup-python.outputs.python-version }}-pipx-${{ steps.pipx-env-setup.outputs.pipx-version }}-uv-${{ inputs.uv-version }}
- name: Install poetry
- name: Install uv
if: steps.pipx-cache.outputs.cache-hit != 'true'
id: install-poetry
id: install-uv
shell: bash
run: |-
pipx install poetry==${{ inputs.poetry-version }} --python "${{ steps.setup-python.outputs.python-path }}"
pipx install uv==${{ inputs.uv-version }} --python "${{ steps.setup-python.outputs.python-path }}"
- name: Read poetry cache location
id: poetry-cache-location
- name: Read uv cache location
id: uv-cache-location
shell: bash
run: |-
echo "poetry-venv-location=$(poetry config virtualenvs.path)" >> $GITHUB_OUTPUT
echo "uv-cache-location=$(uv cache dir)" >> $GITHUB_OUTPUT
- uses: actions/cache@v4
name: Poetry cache
name: uv cache
with:
path: |
${{ steps.poetry-cache-location.outputs.poetry-venv-location }}
key: ${{ runner.os }}-${{ runner.arch }}-python-${{ inputs.python-version }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('poetry.lock') }}-options-${{ inputs.poetry-install-options }}
${{ steps.uv-cache-location.outputs.uv-cache-location }}
key: cache-${{ inputs.cache-version }}-${{ runner.os }}-${{ runner.arch }}-python-${{ steps.setup-python.outputs.python-version }}-uv-${{ inputs.uv-version }}-${{ hashFiles('uv.lock') }}-options-${{ inputs.uv-install-options }}
- name: "Poetry install"
- name: "uv install"
shell: bash
run: |
poetry install ${{ inputs.poetry-install-options }}
uv sync --python "${{ steps.setup-python.outputs.python-path }}" ${{ inputs.uv-install-options }}
- name: Read pre-commit version
if: inputs.cache-pre-commit == 'true'
id: pre-commit-version
shell: bash
run: >-
echo "pre-commit-version=$(poetry run pre-commit -V | awk '{print $2}')" >> $GITHUB_OUTPUT
echo "pre-commit-version=$(uv run pre-commit -- -V | awk '{print $2}')" >> $GITHUB_OUTPUT
- uses: actions/cache@v4
if: inputs.cache-pre-commit == 'true'
name: Pre-commit cache
with:
path: ~/.cache/pre-commit/
key: ${{ runner.os }}-${{ runner.arch }}-pre-commit-${{ steps.pre-commit-version.outputs.pre-commit-version }}-python-${{ inputs.python-version }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('.pre-commit-config.yaml') }}
key: cache-${{ inputs.cache-version }}-${{ runner.os }}-${{ runner.arch }}-pre-commit-${{ steps.pre-commit-version.outputs.pre-commit-version }}-python-${{ inputs.python-version }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('.pre-commit-config.yaml') }}

View File

@ -8,7 +8,7 @@ on:
workflow_dispatch: # to allow manual re-runs
env:
POETRY_VERSION: 1.8.2
UV_VERSION: 0.4.5
jobs:
linting:
@ -26,32 +26,33 @@ jobs:
with:
python-version: ${{ matrix.python-version }}
cache-pre-commit: true
poetry-version: ${{ env.POETRY_VERSION }}
poetry-install-options: "--all-extras"
uv-version: ${{ env.UV_VERSION }}
uv-install-options: "--all-extras"
- name: "Check supported device md files are up to date"
run: |
poetry run pre-commit run generate-supported --all-files
uv run pre-commit run generate-supported --all-files
- name: "Linting and code formating (ruff)"
run: |
poetry run pre-commit run ruff --all-files
uv run pre-commit run ruff --all-files
- name: "Typing checks (mypy)"
run: |
poetry run pre-commit run mypy --all-files
source .venv/bin/activate
pre-commit run mypy --all-files
- name: "Run trailing-whitespace"
run: |
poetry run pre-commit run trailing-whitespace --all-files
uv run pre-commit run trailing-whitespace --all-files
- name: "Run end-of-file-fixer"
run: |
poetry run pre-commit run end-of-file-fixer --all-files
uv run pre-commit run end-of-file-fixer --all-files
- name: "Run check-docstring-first"
run: |
poetry run pre-commit run check-docstring-first --all-files
uv run pre-commit run check-docstring-first --all-files
- name: "Run debug-statements"
run: |
poetry run pre-commit run debug-statements --all-files
uv run pre-commit run debug-statements --all-files
- name: "Run check-ast"
run: |
poetry run pre-commit run check-ast --all-files
uv run pre-commit run check-ast --all-files
tests:
@ -89,16 +90,16 @@ jobs:
uses: ./.github/actions/setup
with:
python-version: ${{ matrix.python-version }}
poetry-version: ${{ env.POETRY_VERSION }}
poetry-install-options: ${{ matrix.extras == true && '--all-extras' || '' }}
uv-version: ${{ env.UV_VERSION }}
uv-install-options: ${{ matrix.extras == true && '--all-extras' || '' }}
- name: "Run tests (no coverage)"
if: ${{ startsWith(matrix.python-version, 'pypy') }}
run: |
poetry run pytest
uv run pytest
- name: "Run tests (with coverage)"
if: ${{ !startsWith(matrix.python-version, 'pypy') }}
run: |
poetry run pytest --cov kasa --cov-report xml
uv run pytest --cov kasa --cov-report xml
- name: "Upload coverage to Codecov"
if: ${{ !startsWith(matrix.python-version, 'pypy') }}
uses: "codecov/codecov-action@v4"

View File

@ -3,6 +3,9 @@ on:
release:
types: [published]
env:
UV_VERSION: 0.4.5
jobs:
build-n-publish:
name: Build release packages
@ -17,19 +20,10 @@ jobs:
with:
python-version: "3.x"
- name: Install pypa/build
run: >-
python -m
pip install
build
--user
- name: Install uv
run: |-
pipx install uv==${{ env.UV_VERSION }} --python "${{ steps.setup-python.outputs.python-path }}"
- name: Build a binary wheel and a source tarball
run: >-
python -m
build
--sdist
--wheel
--outdir dist/
.
run: uv build
- name: Publish release on pypi
uses: pypa/gh-action-pypi-publish@release/v1

View File

@ -1,4 +1,12 @@
repos:
- repo: https://github.com/astral-sh/uv-pre-commit
# uv version.
rev: 0.4.5
hooks:
# Update the uv lockfile
- id: uv-lock
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.6.0
hooks:
@ -28,7 +36,7 @@ repos:
# for more accurate checking than using the pre-commit mypy mirror
- id: mypy
name: mypy
entry: devtools/run-in-env.sh mypy
entry: uv run mypy
language: system
types_or: [python, pyi]
require_serial: true
@ -39,8 +47,7 @@ repos:
- id: generate-supported
name: Generate supported devices
description: This hook generates the supported device sections of README.md and SUPPORTED.md
entry: devtools/run-in-env.sh ./devtools/generate_supported.py
entry: uv run ./devtools/generate_supported.py
language: system # Required or pre-commit creates a new venv
verbose: true # Show output on success
types: [json]
pass_filenames: false # passing filenames causes the hook to run in batches against all-files

View File

@ -20,11 +20,12 @@ You can install the most recent release using pip:
pip install python-kasa
```
Alternatively, you can clone this repository and use poetry to install the development version:
Alternatively, you can clone this repository and use `uv` to install the development version:
```
git clone https://github.com/python-kasa/python-kasa.git
cd python-kasa/
poetry install
uv sync --all-extras
uv run kasa
```
If you have not yet provisioned your device, [you can do so using the cli tool](https://python-kasa.readthedocs.io/en/latest/cli.html#provisioning).

View File

@ -33,21 +33,21 @@ git checkout -b release/$NEW_RELEASE
### Update the version number
```bash
poetry version $NEW_RELEASE
sed -i "0,/version = /{s/version = .*/version = \"${NEW_RELEASE}\"/}" pyproject.toml
```
### Update dependencies
```bash
poetry install --all-extras --sync
poetry update
uv sync --all-extras
uv lock --upgrade
```
### Run pre-commit and tests
```bash
pre-commit run --all-files
pytest kasa
uv run pre-commit run --all-files
uv run pytest
```
### Create release summary (skip for dev releases)
@ -215,7 +215,7 @@ git cherry-pick commitSHA2 -S
### Update the version number
```bash
poetry version $NEW_RELEASE
sed -i "0,/version = /{s/version = .*/version = \"${NEW_RELEASE}\"/}" pyproject.toml
```
### Manually edit the changelog

View File

@ -1,21 +0,0 @@
#!/usr/bin/env bash
# pre-commit by default runs hooks in an isolated environment.
# For some hooks it's needed to run in the virtual environment so this script will activate it.
OS_KERNEL=$(uname -s)
OS_VER=$(uname -v)
if [[ ( $OS_KERNEL == "Linux" && $OS_VER == *"Microsoft"* ) ]]; then
echo "Pre-commit hook needs git-bash to run. It cannot run in the windows linux subsystem."
echo "Add git bin directory to the front of your path variable, e.g:"
echo "set PATH=C:\Program Files\Git\bin;%PATH% (for CMD prompt)"
echo "\$env:Path = 'C:\Program Files\Git\bin;' + \$env:Path (for Powershell prompt)"
exit 1
fi
if [[ "$(expr substr $OS_KERNEL 1 10)" == "MINGW64_NT" ]]; then
POETRY_PATH=$(poetry.exe env info --path)
source "$POETRY_PATH"\\Scripts\\activate
else
source $(poetry env info --path)/bin/activate
fi
exec "$@"

View File

@ -11,13 +11,13 @@ This page aims to help you to get started.
## Setting up the development environment
To get started, simply clone this repository and initialize the development environment.
We are using [poetry](https://python-poetry.org) for dependency management, so after cloning the repository simply execute
`poetry install` which will install all necessary packages and create a virtual environment for you.
We are using [uv](https://github.com/astral-sh/uv) for dependency management, so after cloning the repository simply execute
`uv sync` which will install all necessary packages and create a virtual environment for you in `.venv`.
```
$ git clone https://github.com/python-kasa/python-kasa.git
$ cd python-kasa
$ poetry install
$ uv sync --all-extras
```
## Code-style checks
@ -36,7 +36,7 @@ You can also execute the pre-commit hooks on all files by executing `pre-commit
You can run tests on the library by executing `pytest` in the source directory:
```
$ poetry run pytest kasa
$ uv run pytest kasa
```
This will run the tests against the contributed example responses.
@ -68,8 +68,8 @@ The easiest way to do that is by doing:
```
$ git clone https://github.com/python-kasa/python-kasa.git
$ cd python-kasa
$ poetry install
$ poetry shell
$ uv sync --all-extras
$ source .venv/bin/activate
$ python -m devtools.dump_devinfo --username <username> --password <password> --host 192.168.1.123
```
@ -82,5 +82,5 @@ If you choose to do so, it will save the fixture files directly in their correct
```{note}
When adding new fixture files, you should run `pre-commit run -a` to re-generate the list of supported devices.
You may need to adjust `device_fixtures.py` to add a new model into the correct device categories. Verify that test pass by executing `poetry run pytest kasa`.
You may need to adjust `device_fixtures.py` to add a new model into the correct device categories. Verify that test pass by executing `uv run pytest kasa`.
```

2325
poetry.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -1,70 +1,83 @@
[tool.poetry]
[project]
name = "python-kasa"
version = "0.7.2"
description = "Python API for TP-Link Kasa Smarthome devices"
license = "GPL-3.0-or-later"
authors = ["python-kasa developers"]
repository = "https://github.com/python-kasa/python-kasa"
description = "Python API for TP-Link Kasa and Tapo devices"
license = {text = "GPL-3.0-or-later"}
authors = [ { name = "python-kasa developers" }]
readme = "README.md"
packages = [
{ include = "kasa" }
]
include = [
{ path= "CHANGELOG.md", format = "sdist" }
requires-python = ">=3.9,<4.0"
dependencies = [
"asyncclick>=8.1.7",
"pydantic>=1.10.15",
"cryptography>=1.9",
"async-timeout>=3.0.0",
"aiohttp>=3",
"typing-extensions>=4.12.2,<5.0",
]
[tool.poetry.urls]
classifiers = [
"License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)",
"Operating System :: OS Independent",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
]
[project.optional-dependencies]
speedups = ["orjson>=3.9.1", "kasa-crypt>=0.2.0"]
docs = ["sphinx~=5.0", "sphinx_rtd_theme~=2.0", "sphinxcontrib-programoutput~=0.0", "myst-parser", "docutils>=0.17"]
shell = ["ptpython", "rich"]
[project.urls]
"Homepage" = "https://github.com/python-kasa/python-kasa"
"Bug Tracker" = "https://github.com/python-kasa/python-kasa/issues"
"Documentation" = "https://python-kasa.readthedocs.io"
"Repository" = "https://github.com/python-kasa/python-kasa"
[tool.poetry.scripts]
[project.scripts]
kasa = "kasa.cli.__main__:cli"
[tool.poetry.dependencies]
python = "^3.9"
asyncclick = ">=8.1.7"
pydantic = ">=1.10.15"
cryptography = ">=1.9"
async-timeout = ">=3.0.0"
aiohttp = ">=3"
[tool.uv]
dev-dependencies = [
"pytest",
"pytest-cov",
"pytest-asyncio",
"pytest-sugar",
"pre-commit",
"voluptuous",
"toml",
"pytest-mock",
"codecov",
"xdoctest>=1.2.0",
"coverage[toml]",
"pytest-timeout~=2.0",
"pytest-freezer~=0.4",
"mypy~=1.0"
]
# speed ups
orjson = { "version" = ">=3.9.1", optional = true }
kasa-crypt = { "version" = ">=0.2.0", optional = true }
# required only for docs
sphinx = { version = "^5", optional = true }
sphinx_rtd_theme = { version = "^2", optional = true }
sphinxcontrib-programoutput = { version = "^0", optional = true }
myst-parser = { version = "*", optional = true }
docutils = { version = ">=0.17", optional = true }
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
# enhanced cli support
ptpython = { version = "*", optional = true }
rich = { version = "*", optional = true }
typing-extensions = ">=4.12.2,<5.0"
[tool.hatch.build.targets.sdist]
include = [
"/kasa",
"/devtools",
"/docs",
"/CHANGELOG.md",
]
[tool.poetry.group.dev.dependencies]
pytest = "*"
pytest-cov = "*"
pytest-asyncio = "*"
pytest-sugar = "*"
pre-commit = "*"
voluptuous = "*"
toml = "*"
tox = "*"
pytest-mock = "*"
codecov = "*"
xdoctest = ">=1.2.0"
coverage = {version = "*", extras = ["toml"]}
pytest-timeout = "^2"
pytest-freezer = "^0.4"
mypy = "^1"
[tool.poetry.extras]
docs = ["sphinx", "sphinx_rtd_theme", "sphinxcontrib-programoutput", "myst-parser", "docutils"]
speedups = ["orjson", "kasa-crypt"]
shell = ["ptpython", "rich"]
[tool.hatch.build.targets.wheel]
include = [
"/kasa",
]
exclude = [
"/kasa/tests",
]
[tool.coverage.run]
source = ["kasa"]
@ -99,9 +112,6 @@ paths = ["docs"]
ignore = ["D001"]
ignore-path-errors = ["docs/source/index.rst;D000"]
[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"
[tool.ruff]
target-version = "py38"

37
tox.ini
View File

@ -1,37 +0,0 @@
[tox]
envlist=py37,py38,lint,coverage
skip_missing_interpreters = True
isolated_build = True
[testenv]
whitelist_externals =
poetry
coverage
commands =
poetry install -v
poetry run pytest --cov kasa/tests/
[testenv:clean]
deps = coverage
skip_install = true
commands = coverage erase
[testenv:py37]
commands = coverage run -m pytest {posargs}
[testenv:py38]
commands = coverage run -m pytest {posargs}
[testenv:coverage]
basepython = python3.8
skip_install = true
deps = coverage[toml]
commands =
coverage report
coverage html
[testenv:lint]
deps = pre-commit
skip_install = true
commands = pre-commit run --all-files

1795
uv.lock Normal file

File diff suppressed because it is too large Load Diff