Add to linting Configuration:

- adpot changes in dependabot.yml and remove --diff from ruff check.
- select pydocstyle, isort, pyflakes, pep8-naming, pycodestyle for ruff and ignore some small issues / add inline comments.
- adjust docstring length to 80 in various files

Signed-off-by: E3E <ntanzill@purdue.edu>
This commit is contained in:
E3E 2024-02-20 00:34:47 -05:00
parent cd543c9947
commit 206c9424f1
11 changed files with 87 additions and 46 deletions

View file

@ -16,12 +16,10 @@ updates:
# Python dependencies that are only pinned to ensure test reproducibility
patterns:
- "bandit"
- "black"
- "coverage"
- "isort"
- "mypy"
- "pydocstyle"
- "pylint"
- "ruff"
- "tox"
dependencies:
# Python (developer) runtime dependencies. Also any new dependencies not

View file

@ -112,7 +112,9 @@ def _get_verification_result(
)
def open(self, role: str) -> Metadata:
"""Return current Metadata for role from 'storage' (or create a new one)"""
"""Return current Metadata for role from 'storage'
(or create a new one)
"""
if role not in self.role_cache:
signed_init = _signed_init.get(role, Targets)

View file

@ -81,11 +81,21 @@ dev-mode-dirs = ["."]
line-length=80
[tool.ruff.lint]
select = [
"D", # pydocstyle
"I", # isort
"F", # pyflakes
"N", # pep8-naming
"E" # pycodestyle
]
ignore = ["D400","D415","D213","D205","D202","D107","D407","D413","D212","D104","D406","D105","D411","D401","D200","D203"]
[tool.ruff.lint.per-file-ignores]
[tool.ruff.lint.per-file-ignores]
"tests/*" = ["D", "E"]
"examples/*/*" = ["D"]
"tuf/repository/__init__.py" = ["F401"]
"tuf/api/exceptions.py" = ["F401"]
"tuf/repository/_repository.py" = ["N818"]
"verify_release" = ["F401", "D103", "E501"]
# Pylint section

View file

@ -47,12 +47,12 @@ deps =
--editable {toxinidir}
lint_dirs = tuf examples tests verify_release
commands =
ruff check --diff {[testenv:lint]lint_dirs}
ruff check {[testenv:lint]lint_dirs}
ruff format --diff {[testenv:lint]lint_dirs}
pylint -j 0 --rcfile=pyproject.toml {[testenv:lint]lint_dirs}
mypy {[testenv:lint]lint_dirs}
bandit -r tuf
[testenv:docs]

View file

@ -11,6 +11,7 @@
#### Repository errors ####
# pylint: disable=unused-import
# ruff: disable unused-inport
from securesystemslib.exceptions import StorageError
@ -23,7 +24,9 @@ class RepositoryError(Exception):
class UnsignedMetadataError(RepositoryError):
"""An error about metadata object with insufficient threshold of signatures."""
"""An error about metadata object with insufficient threshold of
signatures.
"""
class BadVersionNumberError(RepositoryError):

View file

@ -19,9 +19,10 @@
The above principle means that a ``Metadata`` object represents a single
metadata file, and has a ``signed`` attribute that is an instance of one of the
four top level signed classes (``Root``, ``Timestamp``, ``Snapshot`` and ``Targets``).
To make Python type annotations useful ``Metadata`` can be type constrained: e.g. the
signed attribute of ``Metadata[Root]`` is known to be ``Root``.
four top level signed classes (``Root``, ``Timestamp``, ``Snapshot`` and
``Targets``). To make Python type annotations useful ``Metadata`` can be
type constrained: e.g. the signed attribute of ``Metadata[Root]``
is known to be ``Root``.
Currently Metadata API supports JSON as the file format.
@ -101,8 +102,8 @@ class Metadata(Generic[T]):
Using a type constraint is not required but not doing so means T is not a
specific type so static typing cannot happen. Note that the type constraint
``[Root]`` is not validated at runtime (as pure annotations are not available
then).
``[Root]`` is not validated at runtime (as pure annotations are not
available then).
New Metadata instances can be created from scratch with::
@ -227,6 +228,7 @@ def from_file(
storage_backend: Object that implements
``securesystemslib.storage.StorageBackendInterface``.
Default is ``FilesystemBackend`` (i.e. a local file).
Raises:
StorageError: The file cannot be read.
tuf.api.serialization.DeserializationError:
@ -357,9 +359,10 @@ def sign(
"""Create signature over ``signed`` and assigns it to ``signatures``.
Args:
signer: A ``securesystemslib.signer.Signer`` object that provides a private
key and signing implementation to generate the signature. A standard
implementation is available in ``securesystemslib.signer.SSlibSigner``.
signer: A ``securesystemslib.signer.Signer`` object that provides a
private key and signing implementation to generate the signature. A
standard implementation is available in
``securesystemslib.signer.SSlibSigner``.
append: ``True`` if the signature should be appended to
the list of signatures or replace any existing signatures. The
default behavior is to replace signatures.
@ -403,7 +406,8 @@ def verify_delegate(
threshold of keys for ``delegated_role``.
.. deprecated:: 3.1.0
Please use ``Root.verify_delegate()`` or ``Targets.verify_delegate()``.
Please use ``Root.verify_delegate()`` or
``Targets.verify_delegate()``.
"""
if self.signed.type not in ["root", "targets"]:
@ -522,7 +526,9 @@ def to_dict(self) -> Dict[str, Any]:
@classmethod
@abc.abstractmethod
def from_dict(cls, signed_dict: Dict[str, Any]) -> "Signed":
"""Deserialization helper, creates object from json/dict representation."""
"""Deserialization helper, creates object from json/dict
representation.
"""
raise NotImplementedError
@classmethod
@ -533,7 +539,8 @@ def _common_fields_from_dict(
representation, and returns an ordered list to be passed as leading
positional arguments to a subclass constructor.
See ``{Root, Timestamp, Snapshot, Targets}.from_dict`` methods for usage.
See ``{Root, Timestamp, Snapshot, Targets}.from_dict``
methods for usage.
"""
_type = signed_dict.pop("_type")
@ -551,7 +558,8 @@ def _common_fields_from_dict(
return version, spec_version, expires
def _common_fields_to_dict(self) -> Dict[str, Any]:
"""Return a dict representation of common fields of ``Signed`` instances.
"""Return a dict representation of common fields of
``Signed`` instances.
See ``{Root, Timestamp, Snapshot, Targets}.to_dict`` methods for usage.
@ -700,19 +708,27 @@ def __bool__(self) -> bool:
@property
def verified(self) -> bool:
"""True if threshold of signatures is met in both underlying VerificationResults."""
"""True if threshold of signatures is met in both underlying
VerificationResults.
"""
return self.first.verified and self.second.verified
@property
def signed(self) -> Dict[str, Key]:
"""Dictionary of all signing keys that have signed, from both VerificationResults"""
# return a union of all signed (in python<3.9 this requires dict unpacking)
"""Dictionary of all signing keys that have signed, from both
VerificationResults.
return a union of all signed (in python<3.9 this requires
dict unpacking)
"""
return {**self.first.signed, **self.second.signed}
@property
def unsigned(self) -> Dict[str, Key]:
"""Dictionary of all signing keys that have not signed, from both VerificationResults"""
# return a union of all unsigned (in python<3.9 this requires dict unpacking)
"""Dictionary of all signing keys that have not signed, from both
VerificationResults.
return a union of all unsigned (in python<3.9 this requires
dict unpacking)
"""
return {**self.first.unsigned, **self.second.unsigned}
@ -828,8 +844,8 @@ class Root(Signed, _DelegatorMixin):
roles: Dictionary of role names to Roles. Defines which keys are
required to sign the metadata for a specific role. Default is
a dictionary of top level roles without keys and threshold of 1.
consistent_snapshot: ``True`` if repository supports consistent snapshots.
Default is True.
consistent_snapshot: ``True`` if repository supports consistent
snapshots. Default is True.
unrecognized_fields: Dictionary of all attributes that are not managed
by TUF Metadata API
@ -1191,6 +1207,7 @@ def from_data(
data: Metadata bytes that the metafile represents.
hash_algorithms: Hash algorithms to create the hashes with. If not
specified, the securesystemslib default hash algorithm is used.
Raises:
ValueError: The hash algorithms list contains an unsupported
algorithm.
@ -1234,7 +1251,8 @@ class Timestamp(Signed):
"""A container for the signed part of timestamp metadata.
TUF file format uses a dictionary to contain the snapshot information:
this is not the case with ``Timestamp.snapshot_meta`` which is a ``MetaFile``.
this is not the case with ``Timestamp.snapshot_meta`` which is a
``MetaFile``.
*All parameters named below are not just constructor arguments but also
instance attributes.*
@ -1366,12 +1384,13 @@ class DelegatedRole(Role):
A delegation can happen in two ways:
- ``paths`` is set: delegates targets matching any path pattern in ``paths``
- ``path_hash_prefixes`` is set: delegates targets whose target path hash
starts with any of the prefixes in ``path_hash_prefixes``
- ``paths`` is set: delegates targets matching any path pattern in
``paths``
- ``path_hash_prefixes`` is set: delegates targets whose target path
hash starts with any of the prefixes in ``path_hash_prefixes``
``paths`` and ``path_hash_prefixes`` are mutually exclusive: both cannot be
set, at least one of them must be set.
``paths`` and ``path_hash_prefixes`` are mutually exclusive:
both cannot be set, at least one of them must be set.
*All parameters named below are not just constructor arguments but also
instance attributes.*
@ -1491,10 +1510,10 @@ def is_delegated_path(self, target_filepath: str) -> bool:
"""Determine whether the given ``target_filepath`` is in one of
the paths that ``DelegatedRole`` is trusted to provide.
The ``target_filepath`` and the ``DelegatedRole`` paths are expected to be
in their canonical forms, so e.g. "a/b" instead of "a//b" . Only "/" is
supported as target path separator. Leading separators are not handled
as special cases (see `TUF specification on targetpath
The ``target_filepath`` and the ``DelegatedRole`` paths are expected to
be in their canonical forms, so e.g. "a/b" instead of "a//b" . Only "/"
is supported as target path separator. Leading separators are not
handled as special cases (see `TUF specification on targetpath
<https://theupdateframework.github.io/specification/latest/#targetpath>`_).
Args:
@ -1613,7 +1632,8 @@ def to_dict(self) -> Dict[str, Any]:
}
def get_role_for_target(self, target_filepath: str) -> str:
"""Calculate the name of the delegated role responsible for ``target_filepath``.
"""Calculate the name of the delegated role responsible for
``target_filepath``.
The target at path ``target_filepath`` is assigned to a bin by casting
the left-most ``bit_length`` of bits of the file path hash digest to
@ -1897,6 +1917,7 @@ def from_file(
local_path: Local path to target file content.
hash_algorithms: Hash algorithms to calculate hashes with. If not
specified the securesystemslib default hash algorithm is used.
Raises:
FileNotFoundError: The file doesn't exist.
ValueError: The hash algorithms list contains an unsupported

View file

@ -1,7 +1,8 @@
# Copyright 2021, New York University and the TUF contributors
# SPDX-License-Identifier: MIT OR Apache-2.0
"""Provides an implementation of ``FetcherInterface`` using the Requests HTTP library.
"""Provides an implementation of ``FetcherInterface`` using the Requests HTTP
library.
"""
# requests_fetcher is public but comes from _internal for now (because
@ -117,7 +118,8 @@ def _chunks(self, response: "requests.Response") -> Iterator[bytes]:
response.close()
def _get_session(self, url: str) -> requests.Session:
"""Return a different customized requests.Session per schema+hostname combination.
"""Return a different customized requests.Session per schema+hostname
combination.
Raises:
exceptions.DownloadError: When there is a problem parsing the url.

View file

@ -73,9 +73,10 @@
class TrustedMetadataSet(abc.Mapping):
"""Internal class to keep track of trusted metadata in ``Updater``.
``TrustedMetadataSet`` ensures that the collection of metadata in it is valid
and trusted through the whole client update workflow. It provides easy ways
to update the metadata with the caller making decisions on what is updated.
``TrustedMetadataSet`` ensures that the collection of metadata in it is
valid and trusted through the whole client update workflow. It provides
easy ways to update the metadata with the caller making decisions on
what is updated.
"""
def __init__(self, root_data: bytes):
@ -107,7 +108,9 @@ def __len__(self) -> int:
return len(self._trusted_set)
def __iter__(self) -> Iterator[Metadata]:
"""Return iterator over ``Metadata`` objects in ``TrustedMetadataSet``."""
"""Return iterator over ``Metadata`` objects in
``TrustedMetadataSet``.
"""
return iter(self._trusted_set.values())
# Helper properties for top level metadata

View file

@ -10,4 +10,5 @@
The repository module is not considered part of the stable python-tuf API yet.
"""
# ruff: disable unused-inport
from tuf.repository._repository import AbortEdit, Repository

View file

@ -22,6 +22,7 @@
logger = logging.getLogger(__name__)
# ruff: ignore N818 `Exception name should have Error suffix`
class AbortEdit(Exception):
"""Raise to exit the edit() contextmanager without saving changes"""

View file

@ -19,7 +19,7 @@ from tempfile import TemporaryDirectory
from typing import Optional
try:
import build as _ # type: ignore
import build as _
import requests
except ImportError:
print("Error: verify_release requires modules 'requests' and 'build':")