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