Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 2 additions & 5 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,9 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Setup Python
uses: actions/setup-python@v2
with:
python-version: '3.x'
- uses: astral-sh/setup-uv@v3
- name: Build
run: make wheel
run: uv build
- name: Publish
uses: pypa/gh-action-pypi-publish@v1.4.2
with:
Expand Down
22 changes: 6 additions & 16 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,9 @@ jobs:
python-version: [ 3.8, 3.9, 3.11, 3.12 ]
steps:
- uses: actions/checkout@v2
- name: Setup Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version}}
- name: Setup
run: make setup
- name: Lint
run: .venv/bin/pre-commit run pylint -v
- name: Style
run: .venv/bin/pre-commit run black -v
- name: Typing
run: .venv/bin/pre-commit run mypy -v
- name: Wheel
run: make wheel
- name: Test
run: make test
- uses: astral-sh/setup-uv@v3
- run: uv build -p ${{ matrix.python-version }}
- run: uv run -p ${{ matrix.python-version }} mypy pyfu_usb/ tests/
- run: uv run -p ${{ matrix.python-version }} ruff format --check
- run: uv run -p ${{ matrix.python-version }} ruff check
- run: uv run -p ${{ matrix.python-version }} pytest tests/
5 changes: 3 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
*.egg-info/
*.pyc
*.swp
.coverage
.pytest_cache/
.venv/
*.egg-info/
dist/
build/
.pytest_cache/
**/__pycache__/
**/target/
23 changes: 8 additions & 15 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,28 +9,21 @@ repos:
- id: trailing-whitespace
- repo: local
hooks:
- id: black
name: black
entry: .venv/bin/black pyfu_usb/ tests/ setup.py
language: system
args: ["--check"]
pass_filenames: false
always_run: true
- id: mypy
name: mypy
entry: .venv/bin/mypy pyfu_usb/ tests/
name: check types
entry: uv run mypy pyfu_usb/ tests/
language: system
pass_filenames: false
always_run: true
- id: pylint
name: pylint
entry: .venv/bin/pylint pyfu_usb/ tests/
- id: ruff_format
name: check style
entry: uv run ruff format --check
language: system
pass_filenames: false
always_run: true
- id: isort
name: isort
entry: .venv/bin/isort pyfu_usb/ tests/ setup.py
- id: ruff_check
name: lint
entry: uv run ruff check
language: system
pass_filenames: false
always_run: true
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [2.0.2] - 2024-12-20

- Remove `pylint` disable annotations.
- Remove unused imports detected when switching to `ruff`.

## [2.0.1] - 2024-10-30

- Add Python 3.8 support back - it did not need to be dropped in version 2.0.0.
Expand Down
33 changes: 0 additions & 33 deletions Makefile

This file was deleted.

60 changes: 15 additions & 45 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ The code in this package originates from `pydfu.py` and the _OpenMV_ license agr

- Colored logs and progress bar with `rich`
- Using `logging` instead of `print` for output messages
- Consistent style with `black` and linting with `pylint`
- Consistent style and linting with `ruff`

## Dependencies

Expand All @@ -26,75 +26,45 @@ Even though this package may appear pure Python, by relying on `pyusb` we rely o

Install with `pip`:

```bash
pip install pyfu-usb
```
pip install pyfu-usb

List connected DFU devices:

```bash
pyfu-usb --list
```
pyfu-usb --list

Download a file to a DfuSe capable device, specifying a start address in hex:

```bash
pyfu-usb --download <filename> -a <start_address>
```
pyfu-usb --download <filename> -a <start_address>

Download a file to a DFU capable device:

```bash
pyfu-usb --download <filename>
```
pyfu-usb --download <filename>

Use the `--device` argument to specify the `vid:pid` of the device in hex if multiple are connected. See the [examples](examples/) directory for more detailed examples.

## Developer Guide

The `Makefile` contains workflow helpers for the development environment.
This project uses [`uv`](https://docs.astral.sh/uv/) for Python tooling. It also uses [`just`](https://github.com/casey/just) to simplify running project specific specific commands.

To setup the virtual environment:
To install pre-commit hooks (e.g. style, linting):

```bash
make setup
```
just setup

To activate the virtual environment:
To run pre-commit hooks:

```bash
source .venv/bin/activate
```

To run pre-commit hooks (style, linting):

```bash
make pre_commit
```
just lint

To run unit tests:

```bash
make test
```

To build the wheel:

```bash
make wheel
```
just test

To view code coverage metrics:
To view code coverage:

```bash
make coverage
```
just coverage

To delete generated files:
To build the package:

```bash
make clean
```
uv build

## Contributing

Expand Down
12 changes: 12 additions & 0 deletions justfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
setup:
uv run python -m pre_commit install --install-hooks

lint:
uv run python -m pre_commit run --all-files

test:
uv run pytest --log-cli-level=INFO -s tests/

coverage:
uv run coverage run .venv/bin/pytest tests/
uv run coverage report
5 changes: 2 additions & 3 deletions pyfu_usb/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@
"""

import logging
import os
from typing import Dict, List, Optional
from typing import List, Optional

import usb
from rich.progress import Progress, TaskID
Expand Down Expand Up @@ -55,7 +54,7 @@ def _get_dfu_devices(
List of USB devices which are currently in DFU mode.
"""

class FilterDFU: # pylint: disable=too-few-public-methods
class FilterDFU:
"""Identify devices which are in DFU mode."""

def __call__(self, device: usb.core.Device) -> bool:
Expand Down
2 changes: 0 additions & 2 deletions pyfu_usb/descriptor.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
_DFU_DESCRIPTOR_ID = 0x21


# pylint: disable=invalid-name
@dataclasses.dataclass
class DfuDescriptor:
"""DFU descriptor."""
Expand Down Expand Up @@ -65,7 +64,6 @@ def get_dfu_descriptor(dev: usb.core.Device) -> Optional[DfuDescriptor]:
return None


# pylint: disable=too-many-locals
def get_memory_layout(
device: usb.core.Device,
interface: int,
Expand Down
81 changes: 69 additions & 12 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,17 +1,74 @@
[tool.black]
[project]
name = "pyfu-usb"
version = "2.0.1"
requires-python = ">=3.8"
authors = [{name = "Block, Inc."}]
description = "Python USB firmware update library."
keywords = ["dfu-util", "pydfu"]
readme = "README.md"
readme-content-type = "text/markdown"
package-data = {pyfu_usb = ["py.typed"]}
license = {text = "MIT"}
dependencies = [
"pyusb>=1.0.2",
"rich>=12.2",
]

[project.scripts]
pyfu-usb = "pyfu_usb.__main__:main"

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[tool.uv]
managed = true
dev-dependencies = [
"coverage",
"mypy",
"pre-commit",
"pytest",
"ruff",
]

[tool.ruff]
line-length = 80
indent-width = 4
exclude = [
".coverage",
".eggs",
".git",
".mypy_cache",
".pytest_cache",
".ruff_cache",
".venv",
".vscode",
"build",
"dist",
"htmlcov",
"venv",
]

[tool.ruff.lint]
select = [
# pycodestyle
"E",
# pyflakes
"F",
# flake8-bugbear
"B",
# isort
"I",
# pylint
"PL"
]
ignore = [
# pylint: magic-value-comparison
"PLR2004",
# pylint: too-many-arguments
"PLR0913"
]

[tool.mypy]
strict = true
ignore_missing_imports = true

[tool.pylint.MASTER]
disable = "W0511,R0917,C0209"

[tool.pylint.FORMAT]
max-line-length = 80

[tool.isort]
# make it compatible with black
profile = "black"
line_length = 80
Loading
Loading