diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index cdf84ef892..de2a017cfc 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -34,16 +34,11 @@ repos:
hooks:
- id: python-check-blanket-noqa
name: Precision flake ignores
- - repo: https://github.com/psf/black
- rev: 24.4.2
+ - repo: https://github.com/astral-sh/ruff-pre-commit
+ rev: v0.4.4
hooks:
- - id: black
- - repo: https://github.com/asottile/blacken-docs
- rev: 1.16.0
- hooks:
- - id: blacken-docs
- additional_dependencies: [black==24.4.0]
- exclude: ^\.github/
+ - id: ruff-format
+ types: [python]
- repo: https://github.com/PyCQA/flake8
rev: 7.0.0
hooks:
diff --git a/example_scenes/basic.py b/example_scenes/basic.py
index e61ae01f67..6e8c866f49 100644
--- a/example_scenes/basic.py
+++ b/example_scenes/basic.py
@@ -153,7 +153,7 @@ def construct(self):
],
color=PURPLE_B,
fill_opacity=1,
- stroke_width=0
+ stroke_width=0,
).shift(UP + 2 * RIGHT)
shapes = VGroup(triangle, square, circle, pentagon, pi)
self.play(SpiralIn(shapes, fade_in_fraction=0.9))
diff --git a/manim/_config/__init__.py b/manim/_config/__init__.py
index 18a57307b4..3eed54b481 100644
--- a/manim/_config/__init__.py
+++ b/manim/_config/__init__.py
@@ -68,7 +68,6 @@ def tempconfig(temp: ManimConfig | dict[str, Any]) -> Generator[None, None, None
8.0
>>> with tempconfig({"frame_height": 100.0}):
... print(config["frame_height"])
- ...
100.0
>>> config["frame_height"]
8.0
diff --git a/manim/_config/cli_colors.py b/manim/_config/cli_colors.py
index e1d9fb02f8..c39f24d716 100644
--- a/manim/_config/cli_colors.py
+++ b/manim/_config/cli_colors.py
@@ -35,15 +35,18 @@ def parse_cli_ctx(parser: configparser.SectionProxy) -> Context:
theme = parser["theme"] if parser["theme"] else None
if theme is None:
formatter = HelpFormatter.settings(
- theme=HelpTheme(**theme_settings), **formatter_settings # type: ignore[arg-type]
+ theme=HelpTheme(**theme_settings),
+ **formatter_settings, # type: ignore[arg-type]
)
elif theme.lower() == "dark":
formatter = HelpFormatter.settings(
- theme=HelpTheme.dark().with_(**theme_settings), **formatter_settings # type: ignore[arg-type]
+ theme=HelpTheme.dark().with_(**theme_settings),
+ **formatter_settings, # type: ignore[arg-type]
)
elif theme.lower() == "light":
formatter = HelpFormatter.settings(
- theme=HelpTheme.light().with_(**theme_settings), **formatter_settings # type: ignore[arg-type]
+ theme=HelpTheme.light().with_(**theme_settings),
+ **formatter_settings, # type: ignore[arg-type]
)
return Context.settings(
diff --git a/manim/mobject/geometry/tips.py b/manim/mobject/geometry/tips.py
index 725e9535ab..a7f116d3bf 100644
--- a/manim/mobject/geometry/tips.py
+++ b/manim/mobject/geometry/tips.py
@@ -60,8 +60,9 @@ class ArrowTip(VMobject, metaclass=ConvertToOpenGL):
... RegularPolygon.__init__(self, n=5, **kwargs)
... self.width = length
... self.stretch_to_fit_height(length)
- >>> arr = Arrow(np.array([-2, -2, 0]), np.array([2, 2, 0]),
- ... tip_shape=MyCustomArrowTip)
+ >>> arr = Arrow(
+ ... np.array([-2, -2, 0]), np.array([2, 2, 0]), tip_shape=MyCustomArrowTip
+ ... )
>>> isinstance(arr.tip, RegularPolygon)
True
>>> from manim import Scene, Create
diff --git a/manim/mobject/graph.py b/manim/mobject/graph.py
index bc11ec69e6..53d7ed464a 100644
--- a/manim/mobject/graph.py
+++ b/manim/mobject/graph.py
@@ -1513,7 +1513,8 @@ def expand_vertex(self, g, vertex_id: str, depth: int):
*new_edges,
vertex_config=self.VERTEX_CONF,
positions={
- k: g.vertices[vertex_id].get_center() + 0.1 * DOWN for k in new_vertices
+ k: g.vertices[vertex_id].get_center() + 0.1 * DOWN
+ for k in new_vertices
},
)
if depth < self.DEPTH:
diff --git a/manim/mobject/graphing/coordinate_systems.py b/manim/mobject/graphing/coordinate_systems.py
index 6315093f2c..3330193a43 100644
--- a/manim/mobject/graphing/coordinate_systems.py
+++ b/manim/mobject/graphing/coordinate_systems.py
@@ -394,7 +394,9 @@ def add_coordinates(
ax = ThreeDAxes()
x_labels = range(-4, 5)
z_labels = range(-4, 4, 2)
- ax.add_coordinates(x_labels, None, z_labels) # default y labels, custom x & z labels
+ ax.add_coordinates(
+ x_labels, None, z_labels
+ ) # default y labels, custom x & z labels
ax.add_coordinates(x_labels) # only x labels
You can also specifically control the position and value of the labels using a dict.
@@ -405,7 +407,15 @@ def add_coordinates(
x_pos = [x for x in range(1, 8)]
# strings are automatically converted into a Tex mobject.
- x_vals = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]
+ x_vals = [
+ "Monday",
+ "Tuesday",
+ "Wednesday",
+ "Thursday",
+ "Friday",
+ "Saturday",
+ "Sunday",
+ ]
x_dict = dict(zip(x_pos, x_vals))
ax.add_coordinates(x_dict)
"""
diff --git a/manim/mobject/graphing/number_line.py b/manim/mobject/graphing/number_line.py
index 63c8954b14..834f3086c2 100644
--- a/manim/mobject/graphing/number_line.py
+++ b/manim/mobject/graphing/number_line.py
@@ -364,7 +364,7 @@ def number_to_point(self, number: float | np.ndarray) -> np.ndarray:
array([0., 0., 0.])
>>> number_line.number_to_point(1)
array([1., 0., 0.])
- >>> number_line.number_to_point([1,2,3])
+ >>> number_line.number_to_point([1, 2, 3])
array([[1., 0., 0.],
[2., 0., 0.],
[3., 0., 0.]])
@@ -396,11 +396,11 @@ def point_to_number(self, point: Sequence[float]) -> float:
>>> from manim import NumberLine
>>> number_line = NumberLine()
- >>> number_line.point_to_number((0,0,0))
+ >>> number_line.point_to_number((0, 0, 0))
0.0
- >>> number_line.point_to_number((1,0,0))
+ >>> number_line.point_to_number((1, 0, 0))
1.0
- >>> number_line.point_to_number([[0.5,0,0],[1,0,0],[1.5,0,0]])
+ >>> number_line.point_to_number([[0.5, 0, 0], [1, 0, 0], [1.5, 0, 0]])
array([0.5, 1. , 1.5])
"""
diff --git a/manim/mobject/mobject.py b/manim/mobject/mobject.py
index 0ae2a29daa..6e405a18eb 100644
--- a/manim/mobject/mobject.py
+++ b/manim/mobject/mobject.py
@@ -2064,7 +2064,7 @@ def get_critical_point(self, direction: Vector3D) -> Point3D:
::
- sample = Arc(start_angle=PI/7, angle = PI/5)
+ sample = Arc(start_angle=PI / 7, angle=PI / 5)
# These are all equivalent
max_y_1 = sample.get_top()[1]
diff --git a/manim/mobject/text/text_mobject.py b/manim/mobject/text/text_mobject.py
index 971200a117..39a1cdd171 100644
--- a/manim/mobject/text/text_mobject.py
+++ b/manim/mobject/text/text_mobject.py
@@ -135,10 +135,17 @@ class Paragraph(VGroup):
--------
Normal usage::
- paragraph = Paragraph('this is a awesome', 'paragraph',
- 'With \nNewlines', '\tWith Tabs',
- ' With Spaces', 'With Alignments',
- 'center', 'left', 'right')
+ paragraph = Paragraph(
+ "this is a awesome",
+ "paragraph",
+ "With \nNewlines",
+ "\tWith Tabs",
+ " With Spaces",
+ "With Alignments",
+ "center",
+ "left",
+ "right",
+ )
Remove unwanted invisible characters::
@@ -1305,15 +1312,13 @@ def add_line_to(end):
self.set_color_by_gradient(*self.gradient)
for col in colormap:
self.chars[
- col["start"]
- - col["start_offset"] : col["end"]
+ col["start"] - col["start_offset"] : col["end"]
- col["start_offset"]
- col["end_offset"]
].set_color(self._parse_color(col["color"]))
for grad in gradientmap:
self.chars[
- grad["start"]
- - grad["start_offset"] : grad["end"]
+ grad["start"] - grad["start_offset"] : grad["end"]
- grad["start_offset"]
- grad["end_offset"]
].set_color_by_gradient(
diff --git a/manim/mobject/types/vectorized_mobject.py b/manim/mobject/types/vectorized_mobject.py
index d82346868a..f32e88aaa2 100644
--- a/manim/mobject/types/vectorized_mobject.py
+++ b/manim/mobject/types/vectorized_mobject.py
@@ -1926,19 +1926,21 @@ class VGroup(VMobject, metaclass=ConvertToOpenGL):
>>> triangle, square = Triangle(), Square()
>>> vg.add(triangle)
VGroup(Triangle)
- >>> vg + square # a new VGroup is constructed
+ >>> vg + square # a new VGroup is constructed
VGroup(Triangle, Square)
- >>> vg # not modified
+ >>> vg # not modified
VGroup(Triangle)
- >>> vg += square; vg # modifies vg
+ >>> vg += square
+ >>> vg # modifies vg
VGroup(Triangle, Square)
>>> vg.remove(triangle)
VGroup(Square)
- >>> vg - square; # a new VGroup is constructed
+ >>> vg - square # a new VGroup is constructed
VGroup()
- >>> vg # not modified
+ >>> vg # not modified
VGroup(Square)
- >>> vg -= square; vg # modifies vg
+ >>> vg -= square
+ >>> vg # modifies vg
VGroup()
.. manim:: ArcShapeIris
@@ -2200,7 +2202,7 @@ def add(
Normal usage::
square_obj = Square()
- my_dict.add([('s', square_obj)])
+ my_dict.add([("s", square_obj)])
"""
for key, value in dict(mapping_or_iterable).items():
self.add_key_value_pair(key, value)
@@ -2227,7 +2229,7 @@ def remove(self, key: Hashable) -> Self:
--------
Normal usage::
- my_dict.remove('square')
+ my_dict.remove("square")
"""
if key not in self.submob_dict:
raise KeyError("The given key '%s' is not present in the VDict" % str(key))
@@ -2252,7 +2254,7 @@ def __getitem__(self, key: Hashable):
--------
Normal usage::
- self.play(Create(my_dict['s']))
+ self.play(Create(my_dict["s"]))
"""
submob = self.submob_dict[key]
return submob
@@ -2276,7 +2278,7 @@ def __setitem__(self, key: Hashable, value: VMobject) -> None:
Normal usage::
square_obj = Square()
- my_dict['sq'] = square_obj
+ my_dict["sq"] = square_obj
"""
if key in self.submob_dict:
self.remove(key)
@@ -2381,7 +2383,7 @@ def add_key_value_pair(self, key: Hashable, value: VMobject) -> None:
Normal usage::
square_obj = Square()
- self.add_key_value_pair('s', square_obj)
+ self.add_key_value_pair("s", square_obj)
"""
self._assert_valid_submobjects([value])
diff --git a/manim/scene/scene.py b/manim/scene/scene.py
index 06dd15fc90..1f5faed4ec 100644
--- a/manim/scene/scene.py
+++ b/manim/scene/scene.py
@@ -1555,8 +1555,7 @@ def construct(self):
# second option: within the call to Scene.play
self.play(
- Transform(square, circle),
- subcaption="The square transforms."
+ Transform(square, circle), subcaption="The square transforms."
)
"""
diff --git a/manim/scene/scene_file_writer.py b/manim/scene/scene_file_writer.py
index ebd7d13cac..3b58d2c73a 100644
--- a/manim/scene/scene_file_writer.py
+++ b/manim/scene/scene_file_writer.py
@@ -715,7 +715,6 @@ def combine_to_movie(self):
av.open(movie_file_path) as video_input,
av.open(sound_file_path) as audio_input,
):
-
video_stream = video_input.streams.video[0]
audio_stream = audio_input.streams.audio[0]
output_container = av.open(
diff --git a/manim/utils/color/X11.py b/manim/utils/color/X11.py
index 06d7c7575f..0379717eac 100644
--- a/manim/utils/color/X11.py
+++ b/manim/utils/color/X11.py
@@ -22,6 +22,7 @@
.. automanimcolormodule:: manim.utils.color.X11
"""
+
from .core import ManimColor
ALICEBLUE = ManimColor("#F0F8FF")
diff --git a/manim/utils/color/core.py b/manim/utils/color/core.py
index d2312c6f53..32c895d100 100644
--- a/manim/utils/color/core.py
+++ b/manim/utils/color/core.py
@@ -147,7 +147,8 @@ def __init__(
else:
if length == 3:
self._internal_value = ManimColor._internal_from_int_rgb(
- value, alpha # type: ignore
+ value,
+ alpha, # type: ignore
)
elif length == 4:
self._internal_value = ManimColor._internal_from_int_rgba(value) # type: ignore
diff --git a/manim/utils/deprecation.py b/manim/utils/deprecation.py
index ece4d40340..2d443c5e72 100644
--- a/manim/utils/deprecation.py
+++ b/manim/utils/deprecation.py
@@ -105,10 +105,12 @@ def deprecated(
from manim.utils.deprecation import deprecated
+
@deprecated
def foo(**kwargs):
pass
+
@deprecated
class Bar:
def __init__(self):
@@ -118,6 +120,7 @@ def __init__(self):
def baz(self):
pass
+
foo()
# WARNING The function foo has been deprecated and may be removed in a later version.
@@ -131,15 +134,12 @@ 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
+
foo()
# WARNING The function foo has been deprecated since v0.2 and is expected to be removed after v0.4. Use bar instead. It is cooler.
@@ -147,10 +147,12 @@ def foo():
from manim.utils.deprecation import deprecated
+
@deprecated(since="05/01/2021", until="06/01/2021")
def foo():
pass
+
foo()
# WARNING The function foo has been deprecated since 05/01/2021 and is expected to be removed after 06/01/2021.
@@ -234,9 +236,8 @@ def deprecated_params(
since: str | None = None,
until: str | None = None,
message: str | None = "",
- redirections: None | (
- Iterable[tuple[str, str] | Callable[..., dict[str, Any]]]
- ) = None,
+ redirections: None
+ | (Iterable[tuple[str, str] | Callable[..., dict[str, Any]]]) = None,
) -> Callable:
"""Decorator to mark parameters of a callable as deprecated.
@@ -287,10 +288,12 @@ def deprecated_params(
from manim.utils.deprecation import deprecated_params
+
@deprecated_params(params="a, b, c")
def foo(**kwargs):
pass
+
foo(x=2, y=3, z=4)
# No warning
@@ -301,15 +304,17 @@ def foo(**kwargs):
from manim.utils.deprecation import deprecated_params
+
@deprecated_params(
params="a, b, c",
since="v0.2",
until="v0.4",
- message="The letters x, y, z are cooler."
+ message="The letters x, y, z are cooler.",
)
def foo(**kwargs):
pass
+
foo(a=2)
# WARNING The parameter a of method foo has been deprecated since v0.2 and is expected to be removed after v0.4. The letters x, y, z are cooler.
@@ -317,14 +322,18 @@ def foo(**kwargs):
from manim.utils.deprecation import deprecated_params
- @deprecated_params(redirections=[
- # Two ways to redirect one parameter to another:
- ("old_param", "new_param"),
- lambda old_param2: {"new_param22": old_param2}
- ])
+
+ @deprecated_params(
+ redirections=[
+ # Two ways to redirect one parameter to another:
+ ("old_param", "new_param"),
+ lambda old_param2: {"new_param22": old_param2},
+ ]
+ )
def foo(**kwargs):
return kwargs
+
foo(x=1, old_param=2)
# WARNING The parameter old_param of method foo has been deprecated and may be removed in a later version.
# returns {"x": 1, "new_param": 2}
@@ -333,12 +342,14 @@ def foo(**kwargs):
from manim.utils.deprecation import deprecated_params
- @deprecated_params(redirections=[
- lambda runtime_in_ms: {"run_time": runtime_in_ms / 1000}
- ])
+
+ @deprecated_params(
+ redirections=[lambda runtime_in_ms: {"run_time": runtime_in_ms / 1000}]
+ )
def foo(**kwargs):
return kwargs
+
foo(runtime_in_ms=500)
# WARNING The parameter runtime_in_ms of method foo has been deprecated and may be removed in a later version.
# returns {"run_time": 0.5}
@@ -347,12 +358,14 @@ def foo(**kwargs):
from manim.utils.deprecation import deprecated_params
- @deprecated_params(redirections=[
- lambda buff_x=1, buff_y=1: {"buff": (buff_x, buff_y)}
- ])
+
+ @deprecated_params(
+ redirections=[lambda buff_x=1, buff_y=1: {"buff": (buff_x, buff_y)}]
+ )
def foo(**kwargs):
return kwargs
+
foo(buff_x=2)
# WARNING The parameter buff_x of method foo has been deprecated and may be removed in a later version.
# returns {"buff": (2, 1)}
@@ -361,18 +374,23 @@ def foo(**kwargs):
from manim.utils.deprecation import deprecated_params
- @deprecated_params(redirections=[
- lambda buff=1: {"buff_x": buff[0], "buff_y": buff[1]} if isinstance(buff, tuple)
- else {"buff_x": buff, "buff_y": buff}
- ])
+
+ @deprecated_params(
+ redirections=[
+ lambda buff=1: {"buff_x": buff[0], "buff_y": buff[1]}
+ if isinstance(buff, tuple)
+ else {"buff_x": buff, "buff_y": buff}
+ ]
+ )
def foo(**kwargs):
return kwargs
+
foo(buff=0)
# WARNING The parameter buff of method foo has been deprecated and may be removed in a later version.
# returns {"buff_x": 0, buff_y: 0}
- foo(buff=(1,2))
+ foo(buff=(1, 2))
# WARNING The parameter buff of method foo has been deprecated and may be removed in a later version.
# returns {"buff_x": 1, buff_y: 2}
diff --git a/manim/utils/docbuild/module_parsing.py b/manim/utils/docbuild/module_parsing.py
index 8ff7c0fe5e..87bfa76c40 100644
--- a/manim/utils/docbuild/module_parsing.py
+++ b/manim/utils/docbuild/module_parsing.py
@@ -125,8 +125,7 @@ def parse_module_attributes() -> tuple[AliasDocsDict, DataDict]:
and (
(
# if TYPE_CHECKING
- type(node.test) is ast.Name
- and node.test.id == "TYPE_CHECKING"
+ type(node.test) is ast.Name and node.test.id == "TYPE_CHECKING"
)
or (
# if typing.TYPE_CHECKING
diff --git a/manim/utils/space_ops.py b/manim/utils/space_ops.py
index 3df699beca..ec47d136eb 100644
--- a/manim/utils/space_ops.py
+++ b/manim/utils/space_ops.py
@@ -622,7 +622,7 @@ def get_winding_number(points: Sequence[np.ndarray]) -> float:
>>> polygon = Square()
>>> get_winding_number(polygon.get_vertices())
1.0
- >>> polygon.shift(2*UP)
+ >>> polygon.shift(2 * UP)
Square
>>> get_winding_number(polygon.get_vertices())
0.0
diff --git a/tests/module/mobject/text/test_markup.py b/tests/module/mobject/text/test_markup.py
index abe1d9333b..78c42ed187 100644
--- a/tests/module/mobject/text/test_markup.py
+++ b/tests/module/mobject/text/test_markup.py
@@ -22,9 +22,7 @@ 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 b8a0e1c9fd..b96acbeb97 100644
--- a/tests/opengl/test_markup_opengl.py
+++ b/tests/opengl/test_markup_opengl.py
@@ -22,9 +22,7 @@ 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/test_scene_rendering/opengl/test_cli_flags_opengl.py b/tests/test_scene_rendering/opengl/test_cli_flags_opengl.py
index e9a5d7e96d..5b3a299dc5 100644
--- a/tests/test_scene_rendering/opengl/test_cli_flags_opengl.py
+++ b/tests/test_scene_rendering/opengl/test_cli_flags_opengl.py
@@ -342,9 +342,7 @@ 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"
diff --git a/tests/test_scene_rendering/test_cli_flags.py b/tests/test_scene_rendering/test_cli_flags.py
index aaee0276a2..c9516c6fc4 100644
--- a/tests/test_scene_rendering/test_cli_flags.py
+++ b/tests/test_scene_rendering/test_cli_flags.py
@@ -239,9 +239,7 @@ 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"