Fix ruff 0.16 findings; bump dependency minimums to match
release / build-wheels (windows, cmd) (push) Failing after 11s
release / build-wheels (linux, bash) (push) Failing after 10s
release / build-wheels (macos, bash) (push) Failing after 11s
release / publish-pypi (push) Skipped

- pyproject [tool.ruff.lint]: ignore RUF022/RUF023 (deliberately grouped
  __all__/__slots__), SIM117, BLE001 (blind except is intentional at
  CFFI callback boundaries)
- Legit fixes: dict/tuple instead of typing.Dict/Tuple in generate.py,
  unquoted annotations in raf.py, Self return for __enter__ methods,
  explicit check=False on subprocess.run, collapsed nested ifs, sorted
  test imports, unused-unpacked-variable in test_raises
- Bump minimum versions to the synced toolchain: cffi 2.1.1, ruff
  0.16.10, pytest 9.1.1, auditwheel 6.8.2, setuptools 84.0.0,
  setuptools-scm 10.3.4 (project deps and build-system requires)
This commit is contained in:
LeoVasanko committed 2026-10-04 16:24:40 +00:00
1 parent 1eb0b6e8c0
commit b4404b42e6
10 files changed
+52 -40

No files matched your search

+19 -7
View File
@@ -1,5 +1,5 @@
[build-system]
requires = ["setuptools>=61.0", "cffi>=2.0.0", "setuptools-scm>=8.0"]
requires = ["setuptools>=84.0.0", "cffi>=2.1.1", "setuptools-scm>=10.3.4"]
build-backend = "build_backend"
backend-path = ["tools"]
@@ -16,7 +16,7 @@ classifiers = [
"Topic :: Security :: Cryptography",
]
dependencies = [
"cffi>=2.0.0",
"cffi>=2.1.1",
]
[project.urls]
@@ -25,11 +25,11 @@ Repository = "https://github.com/LeoVasanko/aegis-python"
[dependency-groups]
dev = [
"auditwheel>=6.5.0",
"pytest>=8.4.2",
"ruff>=0.14.4",
"setuptools>=80.9.0",
"setuptools-scm>=9.2.2",
"auditwheel>=6.8.2",
"pytest>=9.1.1",
"ruff>=0.16.10",
"setuptools>=84.0.0",
"setuptools-scm>=10.3.4",
]
[tool.setuptools]
@@ -39,4 +39,16 @@ packages = ["aeg"]
[tool.setuptools.package-data]
aeg = ["*.h"]
[tool.ruff]
# Disable formatting in Markdown files
extend-exclude = ["*.md"]
[tool.ruff.lint]
ignore = [
"RUF022", # __all__ is deliberately grouped with comments
"RUF023", # __slots__ is deliberately grouped
"SIM117", # nested with-statements are sometimes clearer
"BLE001", # blind except is intentional at CFFI callback boundaries
]
[tool.setuptools_scm]
+9 -9
View File
@@ -18,7 +18,7 @@ import hashlib
import io as io_module
import os
import threading
from typing import NamedTuple, Protocol, runtime_checkable
from typing import NamedTuple, Protocol, Self, runtime_checkable
from . import cipher as _cipher_for_name
from . import random as _random
@@ -163,7 +163,7 @@ class FileStorage:
os.close(self._fd)
self._closed = True
def __enter__(self) -> FileStorage:
def __enter__(self) -> Self:
return self
def __exit__(self, *args) -> None:
@@ -213,7 +213,7 @@ class BytesIOStorage:
"""Return the entire buffer contents."""
return bytes(self._data)
def __enter__(self) -> BytesIOStorage:
def __enter__(self) -> Self:
return self
def __exit__(self, *args) -> None:
@@ -272,7 +272,7 @@ class StreamStorage:
if hasattr(self._stream, "flush"):
self._stream.flush()
def __enter__(self) -> StreamStorage:
def __enter__(self) -> Self:
return self
def __exit__(self, *args) -> None:
@@ -588,8 +588,8 @@ def create(
truncate: bool = False,
merkle: bool | MerkleHasher = False,
merkle_max_chunks: int = 16384,
rng: "_random.RandomSource | None" = None,
) -> "Raf":
rng: _random.RandomSource | None = None,
) -> Raf:
"""Create a new encrypted file.
Args:
@@ -641,8 +641,8 @@ def open(
*,
merkle: bool | MerkleHasher = False,
merkle_max_chunks: int = 16384,
rng: "_random.RandomSource | None" = None,
) -> "Raf":
rng: _random.RandomSource | None = None,
) -> Raf:
"""Open an existing encrypted file.
The header is probed to size internal buffers and its alg_id is checked
@@ -922,7 +922,7 @@ class Raf:
"""True if the file has been closed."""
return self._closed
def __enter__(self) -> "Raf":
def __enter__(self) -> Self:
return self
def __exit__(self, *args) -> None:
+2 -1
View File
@@ -17,6 +17,7 @@ import ctypes
import mmap
import os
from contextlib import suppress
from typing import Self
from .util import wipe
@@ -104,7 +105,7 @@ class SecureBuffer:
def __len__(self) -> int:
return len(self._mmap)
def __enter__(self) -> "SecureBuffer":
def __enter__(self) -> Self:
return self
def __exit__(self, *args) -> None:
+1 -2
View File
@@ -12,8 +12,7 @@ import random
import pytest
from aeg import aegis128l, aegis128x2, aegis128x4, aegis256, aegis256x2, aegis256x4
from aeg import raf
from aeg import aegis128l, aegis128x2, aegis128x4, aegis256, aegis256x2, aegis256x4, raf
from aeg.raf import BytesIOStorage, FileStorage
CIPHERS = [aegis128l, aegis128x2, aegis128x4, aegis256, aegis256x2, aegis256x4]
+1 -2
View File
@@ -1,7 +1,6 @@
import pytest
from aeg import aegis128l, aegis128x2, aegis128x4, aegis256, aegis256x2, aegis256x4
from aeg import raf
from aeg import aegis128l, aegis128x2, aegis128x4, aegis256, aegis256x2, aegis256x4, raf
from aeg import random as aeg_random
CIPHERS = [aegis128l, aegis128x2, aegis128x4, aegis256, aegis256x2, aegis256x4]
+1 -2
View File
@@ -12,8 +12,7 @@ import hashlib
import pytest
from aeg import aegis128l, aegis128x2, aegis128x4, aegis256, aegis256x2, aegis256x4
from aeg import raf
from aeg import aegis128l, aegis128x2, aegis128x4, aegis256, aegis256x2, aegis256x4, raf
from aeg.raf import (
BytesIOStorage,
FileStorage,
+1
View File
@@ -252,6 +252,7 @@ class TestDecryptorFinalization:
# Encrypt empty message
ct, tag = aegis256x4.encrypt_detached(key, nonce, b"")
del ct
# Decrypt without any updates
decryptor = aegis256x4.Decryptor(key, nonce)
-1
View File
@@ -1,6 +1,5 @@
import random
_rng = random.SystemRandom()
+17 -15
View File
@@ -5,7 +5,6 @@ import pathlib
import re
import subprocess
import sys
from typing import Dict, Tuple
def preprocess_content(content: str) -> str:
@@ -58,15 +57,17 @@ def format_declaration(decl: str, max_width: int = 100) -> str:
if len(decl) <= max_width:
return decl
if "(" in decl and ")" in decl:
if match := re.match(r"(.*?\s+\w+\s*)\((.*)\)(.*)", decl):
if (
"(" in decl
and ")" in decl
and (match := re.match(r"(.*?\s+\w+\s*)\((.*)\)(.*)", decl))
):
prefix, params, suffix = match.groups()
if len(prefix) + len(params) + 2 > max_width:
param_list = [p.strip() for p in params.split(",")]
if len(param_list) > 1:
formatted_params = (",\n" + " " * (len(prefix) + 1)).join(
param_list
)
if (
len(prefix) + len(params) + 2 > max_width
and len(param_list := [p.strip() for p in params.split(",")]) > 1
):
formatted_params = (",\n" + " " * (len(prefix) + 1)).join(param_list)
return f"{prefix}({formatted_params}){suffix}"
return decl
@@ -108,7 +109,7 @@ def generate_cdef(include_dir: pathlib.Path) -> str:
def extract_constants(
common_h_path: pathlib.Path, header_path: pathlib.Path, raf_h_path: pathlib.Path
) -> Dict[str, int]:
) -> dict[str, int]:
"""Extract constants from common.h (ALIGNMENT, RATE), main header (KEYBYTES, NPUBBYTES, ABYTES_*), and aegis_raf.h (RAF_ALG_ID)."""
constants = {}
@@ -151,7 +152,7 @@ def extract_constants(
def extract_all_constants(
libaegis_src_dir: pathlib.Path, include_dir: pathlib.Path
) -> Dict[str, Dict[str, int]]:
) -> dict[str, dict[str, int]]:
variants = [
"aegis128l",
"aegis128x2",
@@ -195,7 +196,7 @@ def algo_label(name: str) -> str:
return "AEGIS-" + name[5:].upper()
def generate_variant(template_src: str, variant: str, constants: Dict[str, int]) -> str:
def generate_variant(template_src: str, variant: str, constants: dict[str, int]) -> str:
"""Generate a variant module from the template with substituted constants."""
s = template_src.replace("aegis256x4", variant).replace(
"AEGIS-256X4", algo_label(variant)
@@ -238,8 +239,8 @@ def generate_variant(template_src: str, variant: str, constants: Dict[str, int])
def generate_python_modules(
template_path: pathlib.Path,
output_dir: pathlib.Path,
constants: Dict[str, Dict[str, int]],
) -> Tuple[list[pathlib.Path], list[pathlib.Path]]:
constants: dict[str, dict[str, int]],
) -> tuple[list[pathlib.Path], list[pathlib.Path]]:
if not template_path.exists():
raise FileNotFoundError(f"Template not found: {template_path}")
@@ -295,7 +296,7 @@ def generate_python_modules(
return updated, unchanged
def generate_ciphers_module(constants: Dict[str, Dict[str, int]]) -> str:
def generate_ciphers_module(constants: dict[str, dict[str, int]]) -> str:
labels = [algo_label(variant) for variant in constants]
literal_items = ", ".join(f'"{label}"' for label in labels)
lines = [
@@ -381,6 +382,7 @@ def main() -> int:
["uv", "run", "ruff", "format", str(pyaegis_dir)],
capture_output=True,
text=True,
check=False,
)
if result.returncode != 0:
print(f"Error formatting generated files: {result.stderr}", file=sys.stderr)
+1 -1
View File
@@ -77,7 +77,7 @@ def get_next_version(current_version):
def is_working_copy_clean():
"""Check if git working copy is clean."""
result = subprocess.run(
["git", "status", "--porcelain"], capture_output=True, text=True
["git", "status", "--porcelain"], capture_output=True, text=True, check=False
)
return result.returncode == 0 and not result.stdout.strip()