Skip to content

Conversation

@cobordism
Copy link
Member

@cobordism cobordism commented Apr 3, 2021

In light of some of the issues I raise in #1212, I have started a process of going through all mypy errors and trying to fix them.

This PR started by adding some Type Annotations to animations.py and a few to rate_functions and a few more places... I was following the mypy output on error at a time, skipping over harder ones and solving the simple ones.

Changelog / Overview

I have added and corrected typing hints in animations.py and rate_functions.py I have removed the use of np.clip in favour or min and max, so that a rate function is just float -> float as expected (and not Union[float, numpy.ndarray])
I have added a TypeVariable to Mobject.copy so that derived objects (like Group) are preserved by copying.
I continued into composition.py, transform.py, creation.py picking off the low hanging fruit. Mostly a change in type hints, but also a few minor refactors. Prime example: in the Write animation, self.run_time and self.lag_ratio were being set in the __init__ function and then set again in the parent __init__ function. I cleaned that up. Each variable should have only one level in the hierarchy where it is set/written during __init__.

I have changed the Wait() animation so that it has a Mobject attached to it - albeit an empty Mobject(). This allows us to tag the first argument to Animation() as Mobject instead of Optional[Mobject]. Keeping it as the latter would have required a myriad of checks of the form if animation.mobject is not None: animation.mobject.method(...) and that's not too nice.
There is a slight hickup in that a GLMobject is not (yet) a Mobject and using the Wait Animation in the GL context causes an error. I have found an ugly quick fix for this that I hope will become unnecessary soon as GLMobjects mature.

Motivation

This fixes a bunch of errors found by running the mypy type checker. See Issue #1212. I think we should have everything correctly typed, and no typing errors shown by mypy

Explanation for Changes

Animations will not crash when given a None type object. AnimationGroups can contain a Wait() animation.

Testing Status

All tests pass locally. No new tests added.

Further Comments

Try running mypy ./ before and after this PR to see the difference.

Before:
mypy Found 538 errors in 90 files

After:
mypy Found 491 errors in 90 files

... there is plenty more to clean up.

Checklist

  • I have read the Contributing Guidelines
  • I have written a descriptive PR title (see top of PR template for examples)
  • I have written a changelog entry for the PR or deem it unnecessary
  • My new functions/classes either have a docstring or are private
  • My new functions/classes have tests added and (optional) examples in the docs
  • My new documentation builds, looks correctly formatted, and adds no additional build warnings

Reviewer Checklist

  • The PR title is descriptive enough
  • The PR is labeled correctly
  • The changelog entry is completed if necessary
  • Newly added functions/classes either have a docstring or are private
  • Newly added functions/classes have tests added and (optional) examples in the docs
  • Newly added documentation builds, looks correctly formatted, and adds no additional build warnings

lag_ratio: float = DEFAULT_ANIMATION_LAG_RATIO,
run_time: float = DEFAULT_ANIMATION_RUN_TIME,
rate_func: typing.Callable[[float, float], np.ndarray] = smooth,
rate_func: typing.Callable[[float], float] = smooth,
Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Member Author

Choose a reason for hiding this comment

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

ah I see. but only since 3.9.

Copy link
Member Author

@cobordism cobordism Apr 3, 2021

Choose a reason for hiding this comment

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

and it wasn't I who put it in there...

I suppose we could remove the import typing line, change this line to just Callable[[float].... and add from collections.abc import Callable.
Would that be the thing to do?

Copy link
Member Author

Choose a reason for hiding this comment

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

I tried adding it from collections.abc but of course our CI and our readthedocs failed because they try using python3.7 and 3.8. Let's keep importing from typing for now.

self,
submobject: Mobject,
starting_submobject: Mobject,
# target_copy: Mobject,
Copy link
Member Author

Choose a reason for hiding this comment

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

Here is an issue that the signature of the interpolate_submobject method is different in Animation than in Transform. It needs cleaning up.. but if I add this line here uncommented, then a bunch of test fail.

return self.remover

def is_dummy(self) -> bool:
return self.mobject is None
Copy link
Member Author

Choose a reason for hiding this comment

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

This is really not needed imo.

def __init__(
self, method: types.MethodType, *args, **kwargs
) -> None: # method typing? for args?
) -> None: # method typing (we want to specify Mobject method)? for args?
Copy link
Member Author

@cobordism cobordism Apr 4, 2021

Choose a reason for hiding this comment

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

I have more information about this. types.methodType is an abstract method, and not a method bound to an object. We need the type for a bound method which is a Callable[...] and has a __self__ of type mobject.
However it looks like it might not be possible to do this correctly
https://stackoverflow.com/questions/64225522/python-typing-how-to-type-hint-a-variable-as-a-bound-method
https://stackoverflow.com/questions/58085648/mypy-type-annotation-for-a-bound-method

@cobordism
Copy link
Member Author

I just realised that this PR was from my dev branch and I've been pushing too it constantly.
Shall I close this PR for now and recreate when it is ready again, or is it OK to stay open?

The theme of this PR is - fix many - but not all - errors coming from mypy.

@cobordism cobordism changed the title corrected type hints in animations.py and rate_functions.py Type Annotations: Fixing errors showing up in static type checking tool mypy Apr 6, 2021
@cobordism cobordism added the refactor Refactor or redesign of existing code label Apr 7, 2021
@cobordism cobordism requested review from behackl and naveen521kk April 7, 2021 15:55
Copy link
Member

@jsonvillanueva jsonvillanueva left a comment

Choose a reason for hiding this comment

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

Looks mostly good although I have a few concerns:

@jsonvillanueva jsonvillanueva added maintenance refactoring, typos, removing clutter/dead code, and other code quality improvements and removed refactor Refactor or redesign of existing code labels Apr 15, 2021
Copy link
Member

@jsonvillanueva jsonvillanueva left a comment

Choose a reason for hiding this comment

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

LGTM

@cobordism
Copy link
Member Author

cobordism commented Apr 15, 2021

I managed merge conflict in web editor. I hope it's OK. It's always hard to satisfy black and flake while working in web edit mode...

Anyway, since there is clearly so much more to do on type hints, I hope we can just merge this one now and then continue working on the issue...

@kolibril13
Copy link
Member

@cobordism : can you wait with merging until #1338 is a bit more formulated?
Then we can come back to this pr and know exactly how we want to have things consistent.

@kolibril13
Copy link
Member

kolibril13 commented Apr 16, 2021

It's always hard to satisfy black and flake while working in web edit mode...

Oh, you dont' have to satisfy black anymore, that does pre-commit.ci for you ;)
See. e.g. here: f1d28ee

def __init__(
self,
mobject: Mobject,
mobject: Union[Mobject, None],
Copy link
Member

Choose a reason for hiding this comment

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

From https://docs.python.org/3/library/typing.html#typing.Union:

You can use Optional[X] as a shorthand for Union[X, None].

return vmobject.get_color()

def get_all_mobjects(self) -> typing.List[typing.Union[Mobject, None]]:
def get_all_mobjects(self) -> List[Union[Mobject, None]]:
Copy link
Member

Choose a reason for hiding this comment

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

Also here : Optional[Mobject]

@cobordism
Copy link
Member Author

@kolibril13

@cobordism : can you wait with merging until #1338 is a bit more formulated?
Then we can come back to this pr and know exactly how we want to have things consistent.

do you think that helps? Rather than merging and then continuing the work? After all, the type hints still require a lot of work overall... and at least this PR makes a start at reducing mypy errors.

On the whole, I'm somewhat ambivalent. It's up to you.

@kolibril13
Copy link
Member

and at least this PR makes a start at reducing mypy errors.

Let's merge it then.
I think waiting would only cause merge conflicts.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

maintenance refactoring, typos, removing clutter/dead code, and other code quality improvements

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants