Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add exceptions docs for __init__ and from_dict() #1820

Merged

Conversation

MVrachev
Copy link
Collaborator

@MVrachev MVrachev commented Feb 3, 2022

Fixes #1819

Description of the changes being introduced by the pull request:

Document ValueError, KeyError and TypeError exceptions for __init__ and
from_dict() methods in Metadata API.

Please verify and check that the pull request fulfills the following
requirements
:

  • The code follows the Code Style Guidelines
  • Tests have been added for the bug fix or new feature
  • Docs have been added for the bug fix or new feature

@coveralls
Copy link

coveralls commented Feb 3, 2022

Pull Request Test Coverage Report for Build 1806625289

  • 0 of 0 changed or added relevant lines in 0 files are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage remained the same at 97.89%

Totals Coverage Status
Change from base Build 1805871284: 0.0%
Covered Lines: 1112
Relevant Lines: 1132

💛 - Coveralls

Copy link
Member

@jku jku left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I might leave this for lukas to handle, the only comment I have is that I have a strong sense that many docstrings claim things that we have not checked. An example I found inTargets.from_dict():

TypeError: Invalid type for a signed_dict value.

I'm pretty sure TypeError can also happen if "delegations" is not a dict. And if "targets" contains non-dict. And if if "delegations.roles" contains non-dicts. Maybe there are more cases? I don't think we should spend a lot of time figuring out the exact cases since no-one will care. If we are going to try and document this, let's try to make it non-specific enough that it may actually be correct and has a chance of staying correct

Would it be wrong to do something like this for each from_dict() for example:

KeyError, TypeError, ValueError: Invalid arguments

@lukpueh
Copy link
Member

lukpueh commented Feb 4, 2022

Would it be wrong to do something like this for each from_dict() for example:

KeyError, TypeError, ValueError: Invalid arguments

Works for me. 👍 @MVrachev, mind updating the PR as Jussi said and then ping me for review?

@MVrachev
Copy link
Collaborator Author

MVrachev commented Feb 4, 2022

@lukpueh you can review it now.
Not everywhere we threw all three of those KeyError, TypeError, ValueError, so I documented only those that I saw that are thrown.

Copy link
Member

@lukpueh lukpueh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your diligence, @MVrachev! I found one small mistake (see comment inline) and raised another not immediately related concern. I think we only need to fix the former to land this PR.

tuf/api/metadata.py Outdated Show resolved Hide resolved
@@ -402,6 +401,9 @@ class Signed(metaclass=abc.ABCMeta):
spec_version: The supported TUF specification version number.
expires: The metadata expiry date.
unrecognized_fields: Dictionary of all unrecognized fields.

Raises:
ValueError: Invalid arguments.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you remind me, do we expect users to catch type errors by verifying our type annotations? If not, we'd also need to expect an AttributeError here in case the spec_version passed to the constructor does not have a split method, which we call in:

spec_list = spec_version.split(".")

OTOH, I noticed a few isinstance-checks in other constructors in the module, that we probably wouldn't need if we relied on users running mypy, e.g.:

keyid: str,
keytype: str,
scheme: str,
keyval: Dict[str, str],
unrecognized_fields: Optional[Mapping[str, Any]] = None,
):
if not all(
isinstance(at, str) for at in [keyid, keytype, scheme]
) or not isinstance(keyval, dict):
raise TypeError("Unexpected Key attributes types!")

I guess the difference between those two example that in the former a user sees the issue right away, but not in the latter.

We don't have to solve this in this PR, I was just curious.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we have a strong stance on when should we check for types.
I think I agree that in the Key example it's harder to notice that these fields are not strings.
I don't think we can rely on our users mypy as it's not an official requirement to run python-tuf, but at the same time, we don't want to overdo it with the type checks as we are working with untyped language.
@jku any opinion on this?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed a few isinstance-checks in other constructors in the module, that we probably wouldn't need if we relied on users running mypy

For deserialization code path (including constructors as that's how the code path is built, for better or worse) we can't tell users to rely on mypy: the input is after all just random objects coming from json.loads().

I think in these cases documenting TypeError is as useful as documenting ValueError and KeyError... That is "not very useful at all" but if we do it we should try to have full coverage.

Copy link
Member

@jku jku left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't see any missing errors (apart from the suspicion in a code comment) but I imagine there may well be more: I'm fine with this PR otherwise though

tuf/api/metadata.py Outdated Show resolved Hide resolved
Document ValueError, KeyError and TypeError exceptions for __init__ and
from_dict() methods in Metadata API.

Signed-off-by: Martin Vrachev <[email protected]>
@jku
Copy link
Member

jku commented Feb 8, 2022

I approved this: I'm not entirely convinced that the coverage really is 100% complete but I also don't think it makes sense to put more effort into it.

@lukpueh lukpueh merged commit 0b2f985 into theupdateframework:develop Feb 8, 2022
@MVrachev MVrachev deleted the constructors-documentation branch February 8, 2022 11:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Document exceptions for __init__ and from_dict() methods in Metadata API
4 participants