-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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 type hints to manim.cli
module
#3988
base: main
Are you sure you want to change the base?
Conversation
Could you remove this module from mypy's ignore list? https://github.com/ManimCommunity/manim/blob/main/mypy.ini#L61-L63 |
Done! |
I'll have to fix the MyPy errors later. |
I fixed all the errors reported by
|
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 putting in this effort, this is amazing progress towards typing Manim fully :)
I did leave some minor comments, so I would appreciate if you could take a look at those.
manim/cli/cfg/group.py
Outdated
if TYPE_CHECKING: | ||
pass |
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 TYPE_CHECKING: | |
pass |
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.
Hold on, how did that even get there-
manim/cli/cfg/group.py
Outdated
|
||
return isinstance(value, expected) and (is_valid_style(value) if style else True) | ||
return isinstance(value_literal, ExpectedLiteralType) and ( | ||
(type(value_literal) is str and is_valid_style(value_literal)) |
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 don't see a strict reason to allow only str
and not any subclasses?
(type(value_literal) is str and is_valid_style(value_literal)) | |
(isinstance(value_literal, str) and is_valid_style(value_literal)) |
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 didn't think of that case. Thanks for mentioning it!
manim/cli/cfg/group.py
Outdated
@@ -245,11 +266,11 @@ def write(level: str = None, openfile: bool = False) -> None: | |||
with cfg_file_path.open("w") as fp: | |||
parser.write(fp) | |||
if openfile: | |||
open_file(cfg_file_path) | |||
open_file(str(cfg_file_path)) |
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 seems to me that open_file
should be typehinted to allow manim.typing.StrPath
? Or is there a reason why it has to be a string?
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 just realized that it has to be a pathlib.Path
currently, maybe a better approach would be to allow any StrPath
and then convert it to a Path
manually?
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, I put str
on accident. It should've been pathlib.Path
.
Regarding the StrPath
, I don't know. There are some inconsistencies in file_ops.py
which I think should be handled in a different PR, and I'd prefer to make that change in that PR. There are parameters called file_path
, but some of them are of type pathlib.Path
and others are str
. There are also parameters called file_name
whose type is pathlib.Path
, as well as a parameter which is simply called file
, also of type pathlib.Path
.
@@ -269,7 +290,7 @@ def show(): | |||
@cfg.command(context_settings=cli_ctx_settings) | |||
@cloup.option("-d", "--directory", default=Path.cwd()) | |||
@cloup.pass_context | |||
def export(ctx, directory): | |||
def export(ctx: cloup.Context, directory: str) -> None: |
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.
def export(ctx: cloup.Context, directory: str) -> None: | |
def export(ctx: cloup.Context, directory: manim.typing.StrPath) -> None: |
Just allowing it to be less restrictive is a helpful habit :)
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.
Unless we pass type=cloup.Path(path_type=pathlib.Path)
to @cloup.option
, it doesn't seem that directory
can be a pathlib.Path
.
manim/cli/checkhealth/checks.py
Outdated
description: str | ||
recommendation: str | ||
skip_on_failed: list[str] | ||
post_fail_fix_hook: Callable | None |
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.
Do you mind annotating the Callable
s here and later? If you don't care about the arguments you can do e.g. Callable[..., object]
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.
Sure!
manim/cli/checkhealth/checks.py
Outdated
func.post_fail_fix_hook = post_fail_fix_hook | ||
HEALTH_CHECKS.append(func) | ||
return func | ||
def wrapper(func: Callable) -> HealthCheckFunction: |
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.
def wrapper(func: Callable) -> HealthCheckFunction: | |
def wrapper(func: Callable[[], bool]) -> HealthCheckFunction: |
If I understood correctly?
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. I forgot that it's only intended to wrap functions like that.
manim/cli/checkhealth/checks.py
Outdated
:class:`bool` | ||
Whether ``dvisvgm`` is in ``PATH`` and can be executed or not. | ||
""" | ||
path_to_dvisvgm: str | None = shutil.which("dvisvgm") |
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.
Do we need this str | None
annotation? shutil.which
should take care of it for us.
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 also had it for the is_manim...()
functions. I removed those, but I missed these for latex
and dvisvgm
. I'll also remove them.
# No command name matched. | ||
ctx.arg0 = cmd_name | ||
ctx.meta["arg0"] = cmd_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.
Didn't know about this, nice change :)
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! I was struggling to do this assignment without having mypy
complain about it, so I ended up looking at click.Context
in the hope of finding some dictionary, which I fortunately found!
manim/cli/init/commands.py
Outdated
@@ -94,11 +98,12 @@ def update_cfg(cfg_dict: dict, project_cfg_path: Path): | |||
help="Default settings for project creation.", | |||
nargs=1, | |||
) | |||
def project(default_settings, **args): | |||
def project(default_settings: bool, **args: Any) -> None: |
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.
def project(default_settings: bool, **args: Any) -> None: | |
def project(default_settings: bool, **kwargs: Any) -> None: |
I know I know, not related to the PR per say, but it would be nice if you could do this here and below :)
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.
Sure!
"""Creates a new project. | ||
|
||
PROJECT_NAME is the name of the folder in which the new project will be initialized. | ||
""" | ||
project_name: Path |
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.
(nitpick?) Maybe instead of this, it could be something like
project_name = cast(Path, args["project_name"]) or click.prompt("Project Name", type=Path)
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.
Hmm, I don't know about this. I could add the cast
, although mypy
didn't complain about this. However, the proposal with or
seems a bit more difficult to visually digest, at least for me.
cli
manim.cli
module
As required by the issue #3375, I added typings for the
manim.cli
module.I also added an entry in the docs for the
cli
module, although it's a work in progress.Links to added or changed documentation pages
Reviewer Checklist