Reduce type: ignore count in _config/utils.py and extract fit-to-size logic from mobject.py#4746
Draft
viniciuspalmieri wants to merge 2 commits into
Conversation
The file currently carries 10 # type: ignore markers. Six of them exist only because annotations are slightly looser than reality, not because the underlying code is genuinely hard to type. This commit tightens those annotations and removes the markers: - Two [operator] ignores at the frame_y_radius/frame_x_radius getters go away by changing _d's annotation from dict[str, Any | None] to dict[str, Any] (the | None was what made `_d["frame_height"] / 2` illegal; values are still allowed to be None at runtime via Any). - One [arg-type] ignore in __deepcopy__ goes away by correcting the memo parameter annotation: copy.deepcopy's memo uses int keys (object ids), not str. - Three [func-returns-value] ignores in the frame_y_radius, frame_x_radius and frame_size setters go away by rewriting the `a.__setitem__(...) or b.__setitem__(...)` chain hack as two plain assignment statements. Same behaviour, easier to read. The remaining four markers (Liskov in update(), has-type bootstrap on _tex_template, literal-required on a QUALITIES key, dynamic setattr on a lambda) are structurally harder and out of scope here. mypy manim/_config/utils.py is clean after the change and the existing tests/test_config.py suite still passes.
… module mobject.py is by far the largest file in manim/. As a first scoped step toward reducing its size, this commit moves the implementation of the fit-to-size family out of the Mobject class body and into a new manim/mobject/_fit.py module of free functions. The seven affected methods (rescale_to_fit, scale_to_fit_width, stretch_to_fit_width, scale_to_fit_height, stretch_to_fit_height, scale_to_fit_depth, stretch_to_fit_depth) remain defined on Mobject as thin stubs that delegate to the corresponding functions in _fit. The public API is unchanged: `Square().scale_to_fit_width(5)` works identically. The shape (utility module + delegation, rather than a mixin) follows the suggestion in issue discussion and matches the established pattern in manim/utils/ (space_ops, iterables, etc.). It also avoids the # type: ignore markers a mixin would need, since the utility functions take the mobject as a regular parameter. The substantive logic that moves out is the body of rescale_to_fit (the six wrappers are one-liners). mobject.py's overall LOC count is roughly unchanged because the method declarations and docstrings stay, but the actual implementation now lives in _fit.py (51 LOC). This sets a precedent for further cohesive groups (transforms, positioning, color) without claiming a position on the broader split. Validation: ruff clean on the touched files, mypy clean on _fit.py, pytest passes on tests/module/mobject/mobject/ and tests/test_config.py (30 passed on the non-LaTeX-dependent subset; the three failures I see locally on Windows are environmental and fail identically against upstream main).
This was referenced May 27, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Draft PR addressing the two cleanups discussed in #4734 and #4735. Marking as draft to signal that work is in progress and to invite feedback on the approach before requesting review.
Closes #4734
Closes #4735
Commits
This PR contains two independent commits, one per issue, so either can be reverted without affecting the other.
1. Reduce
# type: ignorecount in_config/utils.py(#4734)Brings the file from 10 markers down to 4. The six removed all came from annotations being slightly looser than reality rather than the underlying code being genuinely hard to type:
_d: dict[str, Any | None]todict[str, Any]removes two[operator]ignores at theframe_y_radius/frame_x_radiusgetters.__deepcopy__'smemoannotation fromdict[str, Any]todict[int, Any]removes one[arg-type].a.__setitem__(...) or b.__setitem__(...)chain hack in three setters as two plain assignments removes three[func-returns-value]ignores.The four remaining markers (Liskov in
update(), has-type bootstrap on_tex_template,literal-requiredon aQUALITIESkey, dynamicsetattron alambda) are structurally harder and left out of scope.2. Extract fit-to-size logic from
mobject.py(#4735)Moves the implementation of
rescale_to_fitand the six*_to_fit_*wrappers out ofMobjectand into a newmanim/mobject/_fit.pymodule of free functions. The seven methods remain onMobjectas thin stubs that delegate to the utility functions.Shape (utility + delegation rather than a mixin) follows the suggestion from #4735 and matches the established pattern in
manim/utils/(space_ops,iterables, etc.). It also avoids the# type: ignoremarkers a mixin would need, since the utility functions take the mobject as a regular parameter.The public API is unchanged:
Square().scale_to_fit_width(5)works identically.mobject.py's overall LOC count is roughly unchanged (the stubs and docstrings stay), but the substantive implementation now lives in_fit.py(51 LOC). This is meant as a precedent for further cohesive groups (transforms, positioning, color), without claiming a position on a broader split.Validation
Run locally on Windows 11 / Python 3.12 /
uv0.9.29:ruff checkclean on touched files.mypyclean onmanim/_config/utils.pyandmanim/mobject/_fit.py.pytest tests/module/mobject/mobject/ tests/test_config.py: 30 passed, 0 failed (3 tests deselected because they fail identically on unmodifiedmaindue to missinglatex/dvisvgm/manimCLI on the local machine; verified viagit stash).pytest -k "scale_to_fit or stretch_to_fit or frame_y_radius or frame_x_radius or frame_size": 3/3 passed.I haven't run the
graphical_unitssuite (requiresffmpeg); given the nature of the changes (no rendering logic touched), I don't expect issues, but flagging it.Open questions before moving out of draft