-
-
Notifications
You must be signed in to change notification settings - Fork 323
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 mypy plugin #825
add mypy plugin #825
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
from typing import Callable, Final | ||
|
||
from mypy.errorcodes import ErrorCode | ||
from mypy.nodes import ArgKind | ||
from mypy.plugin import FunctionContext, Plugin | ||
from mypy.types import CallableType, Instance, Type | ||
|
||
|
||
KEY_IN_RENDER_FUNC: Final = ErrorCode( | ||
"idom-key-in-render-func", | ||
"Component render function has reserved 'key' parameter", | ||
"IDOM", | ||
) | ||
|
||
|
||
class MypyPlugin(Plugin): | ||
"""MyPy plugin for IDOM""" | ||
|
||
def get_function_hook(self, fullname: str) -> Callable[[FunctionContext], Type]: | ||
if fullname == "idom.core.component.component": | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are we allowed to do an Would improve refactorability. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. MyPy automatically resolves the full name of the function in question. Even if There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, however, if we decide to change the module's path from I would recommend using python imports to generate that path, that way refactoring libraries such as |
||
return self.component_decorator_hook | ||
return super().get_function_hook(fullname) | ||
|
||
def component_decorator_hook(self, ctx: FunctionContext) -> CallableType: | ||
if not ctx.arg_types or not ctx.arg_types[0]: | ||
return ctx.default_return_type | ||
render_func: CallableType = ctx.arg_types[0][0] | ||
|
||
if render_func.argument_by_name("key") is not None: | ||
ctx.api.msg.fail( | ||
"Component render function has reserved 'key' parameter", | ||
ctx.context, | ||
code=KEY_IN_RENDER_FUNC, | ||
) | ||
return ctx.default_return_type | ||
|
||
component_symbol = self.lookup_fully_qualified("idom.core.component.Component") | ||
assert component_symbol is not None | ||
assert component_symbol.node is not None | ||
|
||
return render_func.copy_modified( | ||
arg_kinds=render_func.arg_kinds + [ArgKind.ARG_NAMED_OPT], | ||
arg_names=render_func.arg_names + ["key"], | ||
arg_types=render_func.arg_types + [ctx.api.named_generic_type("str", [])], | ||
ret_type=Instance(component_symbol.node, []), | ||
) | ||
|
||
|
||
def plugin(version: str): | ||
# ignore version argument if the plugin works with all mypy versions. | ||
return MypyPlugin |
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.
We need to document this somehow.
Undocumented features essentially do not exist.
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 is more in a draft state. I'm not even sure this belongs in
idom
. It might be better placed in anidom-typing
package.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.
A separate package makes a lot of sense. If/when created we should document that it exists within idom docs.