-
Notifications
You must be signed in to change notification settings - Fork 492
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
NAS-129505 / 24.10 / Beginning of type hinting for middleware #13864
Conversation
src/middlewared/middlewared/event.py
Outdated
from middlewared.schema import Any, clean_and_validate_arg, ValidationErrors | ||
from middlewared.settings import conf | ||
|
||
|
||
class Events: | ||
def __init__(self, role_manager): | ||
_events: dict[str, dict[str]] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why move them to class variables ? We can specify their types in __init__
as well ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right, fixed it
src/middlewared/middlewared/event.py
Outdated
self.role_manager = role_manager | ||
self._events = {} | ||
self.__events_private = set() | ||
|
||
def register(self, name, description, private, returns, no_auth_required, no_authz_required, roles): | ||
def register(self, name:str, description:str, private:bool, returns:bool, no_auth_required, no_authz_required, roles:Iterable[str]): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There should be a space after :
i.e name: str
(in PEP this is E231)
src/middlewared/middlewared/event.py
Outdated
@@ -28,7 +33,7 @@ def register(self, name, description, private, returns, no_auth_required, no_aut | |||
if private: | |||
self.__events_private.add(name) | |||
|
|||
def get_event(self, name): | |||
def get_event(self, name:str) -> dict[str]: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can be null as well so we should mark it as such i.e typing.Optional
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also this would be typing.Dict[key_type, value_type]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please see different modules in middleware which already have type hinting in place, that would be a nice point to see how we have been doing it so far
@@ -80,7 +80,7 @@ def to_json_schema(self, parent=None): | |||
""" | |||
raise NotImplementedError("Attribute must implement to_json_schema method") | |||
|
|||
def _to_json_schema_common(self, parent): | |||
def _to_json_schema_common(self, parent) -> dict[str]: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typing.Dict[type_here, value_type_here]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As of Python 3.9 you can use just regular list and dict, but I'll change to the preferred List and Dict
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm also learning the repo as I go, so Dict[str] evaluates to Dict[str, Any] since I wasn't sure
@@ -12,7 +12,7 @@ class Attribute: | |||
|
|||
def __init__( | |||
self, name='', title=None, description=None, required=False, null=False, empty=True, private=False, | |||
validators=None, register=False, hidden=False, editable=True, example=None, **kwargs | |||
validators:list[function]=None, register=False, hidden=False, editable=True, example=None, **kwargs |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would be syntax error i.e function
is not defined anywhere so this won't execute and the correct way to do this is with typing.List
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also i think we should have a base validators class with __call__
method raising NotImplementedError
and all validators inheriting from it and we can specify that validator here like this
typing.List[Validator]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wasn't able to find a general Validator type, so I left it as List[Callable] for now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay so to clarify, can we add something like this
class ValidatorBase:
def __call__(self, *args, **kwargs):
raise NotImplementedError()
class Exact(ValidatorBase):
def __init__(self, value):
self.value = value
def __call__(self, value):
if value != self.value:
raise ValueError(f"Should be {self.value!r}")
We can import the validator base here and then use it in type hints
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the thorough review, I've updated the PR with everything you pointed out.
…iddleware into NAS-129505"" This reverts commit 31c6c29.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One of your merges into this branch looks like it's overwriting/undoing this commit. Doing a merge doesn't seem to fix it because (I think) you explicitly reverted the changes in your commit history on this branch.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You'll want to run git revert 31c6c2994cd343638a45a020f1da8b6c75a785c1
to revert the revert
This PR has been merged and conversations have been locked. |
|
||
def register(self, name, description, private, returns, no_auth_required, no_authz_required, roles): | ||
def register(self, name: str, description: str, private: bool, returns, no_auth_required, no_authz_required, roles: typing.Iterable[str]): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no_auth_required/no_authz_required
have been left out ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I came across anything that I wasn't sure about, I just skipped it. Figured it's better to be less specific than wrong, plus I plan on spending the whole week working on type hints/docstrings so I can go back to it.
@@ -1645,7 +1648,7 @@ def event_register(self, name, description, *, private=False, returns=None, no_a | |||
roles = roles or [] | |||
self.events.register(name, description, private, returns, no_auth_required, no_authz_required, roles) | |||
|
|||
def send_event(self, name, event_type, **kwargs): | |||
def send_event(self, name, event_type: str, **kwargs): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing type hint for name
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll get back to this one
@@ -1,8 +1,10 @@ | |||
import copy | |||
import json | |||
import textwrap | |||
import typing |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To be sure, we are not right now completing type hints here and would be done at a later stage ?
Oops, got a bit late :D |
Type hinting is an internal documentation technique that does not affect the execution of code during runtime; type hinting is not actually enforced by the interpreter. Instead, it integrates with most IDE's and linters to make the development process cleaner by improving readability and allowing certain bugs to be noticed earlier.