Skip to content

Commit

Permalink
Merge pull request #16 from JPHutchins/python/support-python3.8
Browse files Browse the repository at this point in the history
Python/support python3.8
  • Loading branch information
JPHutchins authored May 19, 2024
2 parents 487a678 + 5018728 commit 6360cb2
Show file tree
Hide file tree
Showing 20 changed files with 559 additions and 371 deletions.
1 change: 1 addition & 0 deletions .flake8
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@
max-line-length = 100
exclude =
.venv
.tox
extend-ignore =
E203
7 changes: 5 additions & 2 deletions .github/workflows/lint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,17 @@ on:
jobs:
lint:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]

steps:
- uses: actions/checkout@v4
- name: Install poetry
run: pipx install poetry
- uses: actions/setup-python@v4
- uses: actions/setup-python@v5
with:
python-version: '3.12'
python-version: ${{ matrix.python-version }}
cache: 'poetry'
- run: poetry install

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
- run: pipx install poetry

- name: Set up Python
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: "3.x"
cache: 'poetry'
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.10", "3.11", "3.12"]
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]

steps:
- uses: actions/checkout@v4

- run: pipx install poetry

- name: Setup Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
cache: 'poetry'
Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ __pycache__
.coverage
.mypy_cache
.pytest_cache
dist
dist
.tox
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,16 @@ If you need an SMP CLI application to interact with device firmware, then try
```
poetry add -G dev <my_dev_dependency>
```
7. run tests for all supported python versions:
```
tox
```

## Development Environment Setup

### Install Dependencies

- python >=3.10, <3.13
- python >=3.8, <3.13
- poetry: https://python-poetry.org/docs/#installation

### Create the venv
Expand Down
702 changes: 405 additions & 297 deletions poetry.lock

Large diffs are not rendered by default.

43 changes: 39 additions & 4 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@ packages = [
source = "git-tag"

[tool.poetry.dependencies]
python = ">=3.10, <3.13"
python = ">=3.8.1, <3.13"
cbor2 = "^5.5.1"
crcmod = "^1.7"
pydantic = "^2.4.2"
pydantic = "^2.6"
eval-type-backport = { version = "^0.2.0", python = "<3.10"}

[tool.poetry.group.dev.dependencies]
pytest = "^7.4.3"
Expand All @@ -30,10 +31,11 @@ isort = "^5.12.0"
mypy = "^1.7.0"
mypy-extensions = "^1.0.0"
pytest-xdist = "^3.4.0"
tox = "^4.15.0"

[tool.black]
line-length = 100
skip-string-normalization = 1
skip-string-normalization = true

[tool.isort]
profile = "black"
Expand All @@ -47,4 +49,37 @@ exclude = ['.venv']
[tool.pytest.ini_options]
filterwarnings = [
"ignore:The --rsyncdir:DeprecationWarning",
]
]

[tool.tox]
legacy_tox_ini = """
[tox]
min_version = 4.15
env_list =
py38
py39
py310
py311
py312
[testenv]
allowlist_externals =
poetry
black
isort
flake8
mypy
coverage
commands =
poetry install
black --check .
isort --check-only .
flake8 .
mypy .
coverage erase
pytest --cov --maxfail=3 -n auto
"""

[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"
2 changes: 2 additions & 0 deletions smp/error.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
"""The Simple Management Protocol (SMP) error responses."""

from __future__ import annotations

from enum import IntEnum
from typing import Generic, TypeVar

Expand Down
30 changes: 17 additions & 13 deletions smp/header.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
"""The Simple Management Protocol (SMP) header."""

from __future__ import annotations

import struct
from dataclasses import dataclass
from enum import IntEnum, IntFlag, auto, unique
from typing import ClassVar, Dict, Type, TypeAlias
from typing import ClassVar, Dict, Type, Union

from typing_extensions import TypeAlias


class CommandId:
Expand Down Expand Up @@ -37,7 +41,7 @@ class Intercreate(IntEnum):
UPLOAD = 1


AnyCommandId: TypeAlias = IntEnum | int
AnyCommandId: TypeAlias = Union[IntEnum, int]


@unique
Expand All @@ -63,7 +67,7 @@ class UserGroupId(IntEnum):
INTERCREATE = 64


AnyGroupId: TypeAlias = IntEnum | int
AnyGroupId: TypeAlias = Union[IntEnum, int]


@unique
Expand Down Expand Up @@ -101,23 +105,23 @@ class Header:
version: Version
flags: Flag
length: int
group_id: AnyGroupId | GroupId | UserGroupId
group_id: Union[AnyGroupId, GroupId, UserGroupId]
sequence: int
command_id: (
AnyCommandId
| CommandId.OSManagement
| CommandId.ImageManagement
| CommandId.ShellManagement
| CommandId.Intercreate
)
command_id: Union[
AnyCommandId,
CommandId.OSManagement,
CommandId.ImageManagement,
CommandId.ShellManagement,
CommandId.Intercreate,
]

_MAP_GROUP_ID_TO_COMMAND_ID_ENUM: ClassVar[Dict[int, Type[IntEnum]]] = {
GroupId.OS_MANAGEMENT: CommandId.OSManagement,
GroupId.IMAGE_MANAGEMENT: CommandId.ImageManagement,
GroupId.SHELL_MANAGEMENT: CommandId.ShellManagement,
}
_STRUCT: ClassVar = struct.Struct("!BBHHBB")
SIZE: ClassVar = _STRUCT.size
_STRUCT: ClassVar[struct.Struct] = struct.Struct("!BBHHBB")
SIZE: ClassVar[int] = _STRUCT.size

@staticmethod
def _pack_op(op: OP) -> int:
Expand Down
32 changes: 19 additions & 13 deletions smp/image_management.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
"""The Simple Management Protocol (SMP) Image Management group."""

from __future__ import annotations

from enum import IntEnum, auto, unique
from typing import ClassVar, Generator, List
from typing import Generator, List

from pydantic import BaseModel, ConfigDict, ValidationInfo, field_validator

from smp import error, header, message


class _ImageManagementGroup:
_GROUP_ID: ClassVar = header.GroupId.IMAGE_MANAGEMENT


class HashBytes(bytes): # pragma: no cover
"""Only to print something useful to the console."""

Expand Down Expand Up @@ -40,18 +38,21 @@ def cast_bytes(cls, v: bytes | None, _: ValidationInfo) -> HashBytes | None:
return HashBytes(v)


class ImageStatesReadRequest(_ImageManagementGroup, message.ReadRequest):
class ImageStatesReadRequest(message.ReadRequest):
_GROUP_ID = header.GroupId.IMAGE_MANAGEMENT
_COMMAND_ID = header.CommandId.ImageManagement.STATE


class ImageStatesReadResponse(_ImageManagementGroup, message.ReadResponse):
class ImageStatesReadResponse(message.ReadResponse):
_GROUP_ID = header.GroupId.IMAGE_MANAGEMENT
_COMMAND_ID = header.CommandId.ImageManagement.STATE

images: List[ImageState]
splitStatus: int | None = None


class ImageStatesWriteRequest(_ImageManagementGroup, message.WriteRequest):
class ImageStatesWriteRequest(message.WriteRequest):
_GROUP_ID = header.GroupId.IMAGE_MANAGEMENT
_COMMAND_ID = header.CommandId.ImageManagement.STATE

hash: bytes
Expand All @@ -62,7 +63,8 @@ class ImageStatesWriteResponse(ImageStatesReadResponse):
pass


class ImageUploadWriteRequest(_ImageManagementGroup, message.WriteRequest):
class ImageUploadWriteRequest(message.WriteRequest):
_GROUP_ID = header.GroupId.IMAGE_MANAGEMENT
_COMMAND_ID = header.CommandId.ImageManagement.UPLOAD

off: int
Expand All @@ -73,28 +75,32 @@ class ImageUploadWriteRequest(_ImageManagementGroup, message.WriteRequest):
upgrade: bool | None = None # allowed when off == 0


class ImageUploadProgressWriteResponse(_ImageManagementGroup, message.WriteResponse):
class ImageUploadProgressWriteResponse(message.WriteResponse):
_GROUP_ID = header.GroupId.IMAGE_MANAGEMENT
_COMMAND_ID = header.CommandId.ImageManagement.UPLOAD

rc: int | None = None
off: int | None = None


class ImageUploadFinalWriteResponse(_ImageManagementGroup, message.WriteResponse):
class ImageUploadFinalWriteResponse(message.WriteResponse):
_GROUP_ID = header.GroupId.IMAGE_MANAGEMENT
_COMMAND_ID = header.CommandId.ImageManagement.UPLOAD

off: int | None = None
match: bool | None = None


class ImageEraseRequest(_ImageManagementGroup, message.WriteRequest):
class ImageEraseRequest(message.WriteRequest):
_GROUP_ID = header.GroupId.IMAGE_MANAGEMENT
_COMMAND_ID = header.CommandId.ImageManagement.ERASE

slot: int | None = None
"""The slot to erase. If not provided, slot 1 will be erased."""


class ImageEraseResponse(_ImageManagementGroup, message.WriteResponse):
class ImageEraseResponse(message.WriteResponse):
_GROUP_ID = header.GroupId.IMAGE_MANAGEMENT
_COMMAND_ID = header.CommandId.ImageManagement.ERASE


Expand Down
2 changes: 2 additions & 0 deletions smp/message.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
"""The Simple Management Protocol (SMP) Message base class."""

from __future__ import annotations

import itertools
from abc import ABC
from enum import IntEnum, unique
Expand Down
Loading

0 comments on commit 6360cb2

Please sign in to comment.