diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 50b4217aa9..d92cc048e0 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -13,7 +13,7 @@ repos:
- id: check-toml
name: Validate Poetry
- repo: https://github.com/astral-sh/ruff-pre-commit
- rev: v0.8.0
+ rev: v0.9.1
hooks:
- id: ruff
name: ruff lint
@@ -22,7 +22,7 @@ repos:
- id: ruff-format
types: [python]
- repo: https://github.com/pre-commit/mirrors-mypy
- rev: v1.13.0
+ rev: v1.14.1
hooks:
- id: mypy
additional_dependencies:
diff --git a/manim/animation/speedmodifier.py b/manim/animation/speedmodifier.py
index 63b9b2e5b3..b8ccea66d1 100644
--- a/manim/animation/speedmodifier.py
+++ b/manim/animation/speedmodifier.py
@@ -113,9 +113,9 @@ def __init__(
self.anim = self.setup(anim)
if affects_speed_updaters:
- assert (
- ChangeSpeed.is_changing_dt is False
- ), "Only one animation at a time can play that changes speed (dt) for ChangeSpeed updaters"
+ assert ChangeSpeed.is_changing_dt is False, (
+ "Only one animation at a time can play that changes speed (dt) for ChangeSpeed updaters"
+ )
ChangeSpeed.is_changing_dt = True
self.t = 0
self.affects_speed_updaters = affects_speed_updaters
diff --git a/manim/animation/transform.py b/manim/animation/transform.py
index a7c62a9e6a..aff109ec71 100644
--- a/manim/animation/transform.py
+++ b/manim/animation/transform.py
@@ -429,7 +429,7 @@ def __init__(self, mobject: Mobject, **kwargs) -> None:
def check_validity_of_input(self, mobject: Mobject) -> None:
if not hasattr(mobject, "target"):
raise ValueError(
- "MoveToTarget called on mobject" "without attribute 'target'",
+ "MoveToTarget called on mobjectwithout attribute 'target'",
)
diff --git a/manim/cli/render/render_options.py b/manim/cli/render/render_options.py
index 0f069c04e0..9a31d36ed4 100644
--- a/manim/cli/render/render_options.py
+++ b/manim/cli/render/render_options.py
@@ -143,7 +143,7 @@ def validate_resolution(
+ ", ".join(
reversed(
[
- f'{q["pixel_width"]}x{q["pixel_height"]} {q["frame_rate"]}FPS'
+ f"{q['pixel_width']}x{q['pixel_height']} {q['frame_rate']}FPS"
for q in QUALITIES.values()
if q["flag"]
]
diff --git a/manim/mobject/graph.py b/manim/mobject/graph.py
index 1ccebd9bb0..25a3ce4b17 100644
--- a/manim/mobject/graph.py
+++ b/manim/mobject/graph.py
@@ -1501,7 +1501,9 @@ class LargeTreeGeneration(MovingCameraScene):
VERTEX_CONF = {"radius": 0.25, "color": BLUE_B, "fill_opacity": 1}
def expand_vertex(self, g, vertex_id: str, depth: int):
- new_vertices = [f"{vertex_id}/{i}" for i in range(self.CHILDREN_PER_VERTEX)]
+ new_vertices = [
+ f"{vertex_id}/{i}" for i in range(self.CHILDREN_PER_VERTEX)
+ ]
new_edges = [(vertex_id, child_id) for child_id in new_vertices]
g.add_edges(
*new_edges,
diff --git a/manim/mobject/graphing/coordinate_systems.py b/manim/mobject/graphing/coordinate_systems.py
index caf2dc805c..b21879b90b 100644
--- a/manim/mobject/graphing/coordinate_systems.py
+++ b/manim/mobject/graphing/coordinate_systems.py
@@ -3235,7 +3235,7 @@ def get_coordinate_labels(
elif self.azimuth_units == "degrees":
a_tex = [
MathTex(
- f'{360 * i["label"]:g}' + r"^{\circ}",
+ f"{360 * i['label']:g}" + r"^{\circ}",
font_size=self.azimuth_label_font_size,
).next_to(
i["point"],
@@ -3248,7 +3248,7 @@ def get_coordinate_labels(
elif self.azimuth_units == "gradians":
a_tex = [
MathTex(
- f'{400 * i["label"]:g}' + r"^{g}",
+ f"{400 * i['label']:g}" + r"^{g}",
font_size=self.azimuth_label_font_size,
).next_to(
i["point"],
@@ -3261,7 +3261,7 @@ def get_coordinate_labels(
elif self.azimuth_units is None:
a_tex = [
MathTex(
- f'{i["label"]:g}',
+ f"{i['label']:g}",
font_size=self.azimuth_label_font_size,
).next_to(
i["point"],
diff --git a/manim/mobject/mobject.py b/manim/mobject/mobject.py
index 8557490ed9..fc4caae1ee 100644
--- a/manim/mobject/mobject.py
+++ b/manim/mobject/mobject.py
@@ -318,7 +318,9 @@ def animate(self) -> _AnimationBuilder | Self:
::
- self.play(my_mobject.animate.shift(RIGHT), my_mobject.animate.rotate(PI))
+ self.play(
+ my_mobject.animate.shift(RIGHT), my_mobject.animate.rotate(PI)
+ )
make use of method chaining.
@@ -3070,8 +3072,7 @@ def __getattr__(self, method_name) -> types.MethodType:
if (self.is_chaining and has_overridden_animation) or self.overridden_animation:
raise NotImplementedError(
- "Method chaining is currently not supported for "
- "overridden animations",
+ "Method chaining is currently not supported for overridden animations",
)
def update_target(*method_args, **method_kwargs):
diff --git a/manim/mobject/opengl/opengl_mobject.py b/manim/mobject/opengl/opengl_mobject.py
index 576ebe0318..d57d96af32 100644
--- a/manim/mobject/opengl/opengl_mobject.py
+++ b/manim/mobject/opengl/opengl_mobject.py
@@ -401,7 +401,9 @@ def animate(self) -> _AnimationBuilder | Self:
::
- self.play(my_mobject.animate.shift(RIGHT), my_mobject.animate.rotate(PI))
+ self.play(
+ my_mobject.animate.shift(RIGHT), my_mobject.animate.rotate(PI)
+ )
make use of method chaining for ``animate``, meaning::
@@ -2957,8 +2959,7 @@ def __getattr__(self, method_name: str) -> Callable[..., Self]:
if (self.is_chaining and has_overridden_animation) or self.overridden_animation:
raise NotImplementedError(
- "Method chaining is currently not supported for "
- "overridden animations",
+ "Method chaining is currently not supported for overridden animations",
)
def update_target(*method_args, **method_kwargs):
diff --git a/manim/mobject/text/text_mobject.py b/manim/mobject/text/text_mobject.py
index ef14267891..2a8da048a0 100644
--- a/manim/mobject/text/text_mobject.py
+++ b/manim/mobject/text/text_mobject.py
@@ -703,7 +703,7 @@ def _merge_settings(
default = default_args[arg]
if left != default and getattr(right_setting, arg) != default:
raise ValueError(
- f"Ambiguous style for text '{self.text[right_setting.start:right_setting.end]}':"
+ f"Ambiguous style for text '{self.text[right_setting.start : right_setting.end]}':"
+ f"'{arg}' cannot be both '{left}' and '{right}'."
)
setattr(right_setting, arg, left if left != default else right)
@@ -1561,7 +1561,7 @@ def register_font(font_file: str | Path):
logger.debug("Found file at %s", file_path.absolute())
break
else:
- error = f"Can't find {font_file}." f"Tried these : {possible_paths}"
+ error = f"Can't find {font_file}.Tried these : {possible_paths}"
raise FileNotFoundError(error)
try:
diff --git a/manim/mobject/types/vectorized_mobject.py b/manim/mobject/types/vectorized_mobject.py
index 605120111b..321fe4287b 100644
--- a/manim/mobject/types/vectorized_mobject.py
+++ b/manim/mobject/types/vectorized_mobject.py
@@ -2119,7 +2119,7 @@ def __init__(
self.add(*vmobjects)
def __repr__(self) -> str:
- return f'{self.__class__.__name__}({", ".join(str(mob) for mob in self.submobjects)})'
+ return f"{self.__class__.__name__}({', '.join(str(mob) for mob in self.submobjects)})"
def __str__(self) -> str:
return (
diff --git a/manim/utils/deprecation.py b/manim/utils/deprecation.py
index 98906b461a..d8bb9fb97c 100644
--- a/manim/utils/deprecation.py
+++ b/manim/utils/deprecation.py
@@ -160,7 +160,9 @@ def baz(self):
from manim.utils.deprecation import deprecated
- @deprecated(since="v0.2", until="v0.4", replacement="bar", message="It is cooler.")
+ @deprecated(
+ since="v0.2", until="v0.4", replacement="bar", message="It is cooler."
+ )
def foo():
pass
diff --git a/manim/utils/docbuild/manim_directive.py b/manim/utils/docbuild/manim_directive.py
index 4ce22e0281..b94b7386c9 100644
--- a/manim/utils/docbuild/manim_directive.py
+++ b/manim/utils/docbuild/manim_directive.py
@@ -236,7 +236,7 @@ def run(self) -> list[nodes.Element]:
ref_block = "References: " + " ".join(ref_content) if ref_content else ""
if "quality" in self.options:
- quality = f'{self.options["quality"]}_quality'
+ quality = f"{self.options['quality']}_quality"
else:
quality = "example_quality"
frame_rate = QUALITIES[quality]["frame_rate"]
diff --git a/manim/utils/qhull.py b/manim/utils/qhull.py
index 463a3dd305..9e3b329561 100644
--- a/manim/utils/qhull.py
+++ b/manim/utils/qhull.py
@@ -133,9 +133,9 @@ def initialize(self, points: PointND_Array) -> None:
self.neighbors.setdefault(sf, set()).add(f)
def classify(self, facet: Facet) -> None:
- assert (
- self.unclaimed is not None
- ), "Call .initialize() before using .classify()."
+ assert self.unclaimed is not None, (
+ "Call .initialize() before using .classify()."
+ )
if not self.unclaimed.size:
self.outside[facet] = (None, None)
diff --git a/pyproject.toml b/pyproject.toml
index e47ceb9f06..6375ee4d07 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -155,6 +155,8 @@ select = [
]
ignore = [
+ # (sub)module shadows standard library module
+ "A005",
# mutable argument defaults (too many changes)
"B006",
# No function calls in defaults
diff --git a/tests/interface/test_commands.py b/tests/interface/test_commands.py
index c6223a78cb..52007b71eb 100644
--- a/tests/interface/test_commands.py
+++ b/tests/interface/test_commands.py
@@ -75,9 +75,9 @@ def test_manim_checkhealth_subcommand():
result = runner.invoke(main, command)
output_lines = result.output.split("\n")
num_passed = len([line for line in output_lines if "PASSED" in line])
- assert num_passed == len(
- HEALTH_CHECKS
- ), f"Some checks failed! Full output:\n{result.output}"
+ assert num_passed == len(HEALTH_CHECKS), (
+ f"Some checks failed! Full output:\n{result.output}"
+ )
assert "No problems detected, your installation seems healthy!" in output_lines
diff --git a/tests/module/mobject/graphing/test_number_line.py b/tests/module/mobject/graphing/test_number_line.py
index 1f0f7c343c..552b24ebb4 100644
--- a/tests/module/mobject/graphing/test_number_line.py
+++ b/tests/module/mobject/graphing/test_number_line.py
@@ -65,9 +65,9 @@ def test_add_labels():
dict(zip(list(range(-3, 3)), [Integer(m) for m in range(-1, 5)])),
)
actual_label_length = len(num_line.labels)
- assert (
- actual_label_length == expected_label_length
- ), f"Expected a VGroup with {expected_label_length} integers but got {actual_label_length}."
+ assert actual_label_length == expected_label_length, (
+ f"Expected a VGroup with {expected_label_length} integers but got {actual_label_length}."
+ )
def test_number_to_point():
diff --git a/tests/module/mobject/text/test_markup.py b/tests/module/mobject/text/test_markup.py
index 78c42ed187..d8cd0cafd5 100644
--- a/tests/module/mobject/text/test_markup.py
+++ b/tests/module/mobject/text/test_markup.py
@@ -22,7 +22,9 @@ def test_special_tags_markup():
success = True
except ValueError:
success = False
- assert success, '\'foo\' and \'foo\' should not fail validation'
+ assert success, (
+ '\'foo\' and \'foo\' should not fail validation'
+ )
def test_unbalanced_tag_markup():
diff --git a/tests/opengl/test_markup_opengl.py b/tests/opengl/test_markup_opengl.py
index b96acbeb97..60c83c4304 100644
--- a/tests/opengl/test_markup_opengl.py
+++ b/tests/opengl/test_markup_opengl.py
@@ -22,7 +22,9 @@ def test_special_tags_markup(using_opengl_renderer):
success = True
except ValueError:
success = False
- assert success, '\'foo\' and \'foo\' should not fail validation'
+ assert success, (
+ '\'foo\' and \'foo\' should not fail validation'
+ )
def test_unbalanced_tag_markup(using_opengl_renderer):
diff --git a/tests/opengl/test_number_line_opengl.py b/tests/opengl/test_number_line_opengl.py
index 5eb52eb914..6f9742e523 100644
--- a/tests/opengl/test_number_line_opengl.py
+++ b/tests/opengl/test_number_line_opengl.py
@@ -65,6 +65,6 @@ def test_add_labels():
dict(zip(list(range(-3, 3)), [Integer(m) for m in range(-1, 5)])),
)
actual_label_length = len(num_line.labels)
- assert (
- actual_label_length == expected_label_length
- ), f"Expected a VGroup with {expected_label_length} integers but got {actual_label_length}."
+ assert actual_label_length == expected_label_length, (
+ f"Expected a VGroup with {expected_label_length} integers but got {actual_label_length}."
+ )
diff --git a/tests/test_graphical_units/test_threed.py b/tests/test_graphical_units/test_threed.py
index b6079e5e4c..dc52b0dd9e 100644
--- a/tests/test_graphical_units/test_threed.py
+++ b/tests/test_graphical_units/test_threed.py
@@ -37,12 +37,12 @@ def test_Cone_get_start_and_get_end():
cone = Cone().shift(RIGHT).rotate(PI / 4, about_point=ORIGIN, about_edge=OUT)
start = [0.70710678, 0.70710678, -1.0]
end = [0.70710678, 0.70710678, 0.0]
- assert np.allclose(
- cone.get_start(), start, atol=0.01
- ), "start points of Cone do not match"
- assert np.allclose(
- cone.get_end(), end, atol=0.01
- ), "end points of Cone do not match"
+ assert np.allclose(cone.get_start(), start, atol=0.01), (
+ "start points of Cone do not match"
+ )
+ assert np.allclose(cone.get_end(), end, atol=0.01), (
+ "end points of Cone do not match"
+ )
@frames_comparison(base_scene=ThreeDScene)
@@ -166,9 +166,9 @@ def param_surface(u, v):
def test_get_start_and_end_Arrow3d():
start, end = ORIGIN, np.array([2, 1, 0])
arrow = Arrow3D(start, end)
- assert np.allclose(
- arrow.get_start(), start, atol=0.01
- ), "start points of Arrow3D do not match"
- assert np.allclose(
- arrow.get_end(), end, atol=0.01
- ), "end points of Arrow3D do not match"
+ assert np.allclose(arrow.get_start(), start, atol=0.01), (
+ "start points of Arrow3D do not match"
+ )
+ assert np.allclose(arrow.get_end(), end, atol=0.01), (
+ "end points of Arrow3D do not match"
+ )
diff --git a/tests/test_scene_rendering/opengl/test_cli_flags_opengl.py b/tests/test_scene_rendering/opengl/test_cli_flags_opengl.py
index 5b3a299dc5..17f6f35e38 100644
--- a/tests/test_scene_rendering/opengl/test_cli_flags_opengl.py
+++ b/tests/test_scene_rendering/opengl/test_cli_flags_opengl.py
@@ -198,9 +198,9 @@ def test_no_image_output_with_interactive_embed(
assert not exists, "running manim with static scene rendered a video"
is_empty = not any((tmp_path / "images" / "simple_scenes").iterdir())
- assert (
- is_empty
- ), "running manim static scene with interactive embed rendered an image"
+ assert is_empty, (
+ "running manim static scene with interactive embed rendered an image"
+ )
@pytest.mark.slow
@@ -227,9 +227,9 @@ def test_no_default_image_output_with_non_static_scene(
assert not exists, "running manim with static scene rendered a video"
is_empty = not any((tmp_path / "images" / "simple_scenes").iterdir())
- assert (
- is_empty
- ), "running manim static scene with interactive embed rendered an image"
+ assert is_empty, (
+ "running manim static scene with interactive embed rendered an image"
+ )
@pytest.mark.slow
@@ -342,14 +342,16 @@ def test_a_flag(tmp_path, manim_cfg_file, infallible_scenes_path):
two_is_not_empty = (
tmp_path / "images" / "infallible_scenes" / f"Wait2_ManimCE_v{__version__}.png"
).is_file()
- assert two_is_not_empty, "running manim with -a flag did not render an image, possible leak of the config dictionary"
+ assert two_is_not_empty, (
+ "running manim with -a flag did not render an image, possible leak of the config dictionary"
+ )
three_is_not_empty = (
tmp_path / "videos" / "infallible_scenes" / "480p15" / "Wait3.mp4"
).is_file()
- assert (
- three_is_not_empty
- ), "running manim with -a flag did not render the second scene"
+ assert three_is_not_empty, (
+ "running manim with -a flag did not render the second scene"
+ )
@pytest.mark.slow
diff --git a/tests/test_scene_rendering/test_cli_flags.py b/tests/test_scene_rendering/test_cli_flags.py
index c9516c6fc4..e938ff8d20 100644
--- a/tests/test_scene_rendering/test_cli_flags.py
+++ b/tests/test_scene_rendering/test_cli_flags.py
@@ -239,14 +239,16 @@ def test_a_flag(tmp_path, manim_cfg_file, infallible_scenes_path):
two_is_not_empty = (
tmp_path / "images" / "infallible_scenes" / f"Wait2_ManimCE_v{__version__}.png"
).is_file()
- assert two_is_not_empty, "running manim with -a flag did not render an image, possible leak of the config dictionary."
+ assert two_is_not_empty, (
+ "running manim with -a flag did not render an image, possible leak of the config dictionary."
+ )
three_is_not_empty = (
tmp_path / "videos" / "infallible_scenes" / "480p15" / "Wait3.mp4"
).is_file()
- assert (
- three_is_not_empty
- ), "running manim with -a flag did not render the second scene"
+ assert three_is_not_empty, (
+ "running manim with -a flag did not render the second scene"
+ )
@pytest.mark.slow