Skip to content

Commit d6dac76

Browse files
Change flake8-comprehensions and flake8-bugbear to ruff (#3882)
* Add config for bugbear/comprehensions note: flake8-comprehensions has 0 changes to the files * Safe fixes from pre-commit * Manual changes to make pre-commit pass * Remove deps from pyproject
1 parent 3aad355 commit d6dac76

19 files changed

+48
-38
lines changed

.pre-commit-config.yaml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,7 @@ repos:
3232
- id: flake8
3333
additional_dependencies:
3434
[
35-
flake8-bugbear==21.4.3,
3635
flake8-builtins==1.5.3,
37-
flake8-comprehensions>=3.6.1,
3836
flake8-docstrings==1.6.0,
3937
flake8-pytest-style==1.5.0,
4038
flake8-rst-docstrings==0.2.3,

manim/_config/utils.py

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -643,14 +643,14 @@ def digest_parser(self, parser: configparser.ConfigParser) -> Self:
643643
gui_location = tuple(
644644
map(int, re.split(r"[;,\-]", parser["CLI"]["gui_location"])),
645645
)
646-
setattr(self, "gui_location", gui_location)
646+
self.gui_location = gui_location
647647

648648
window_size = parser["CLI"][
649649
"window_size"
650650
] # if not "default", get a tuple of the position
651651
if window_size != "default":
652652
window_size = tuple(map(int, re.split(r"[;,\-]", window_size)))
653-
setattr(self, "window_size", window_size)
653+
self.window_size = window_size
654654

655655
# plugins
656656
plugins = parser["CLI"].get("plugins", fallback="", raw=True)
@@ -671,7 +671,7 @@ def digest_parser(self, parser: configparser.ConfigParser) -> Self:
671671

672672
val = parser["CLI"].get("progress_bar")
673673
if val:
674-
setattr(self, "progress_bar", val)
674+
self.progress_bar = val
675675

676676
val = parser["ffmpeg"].get("loglevel")
677677
if val:
@@ -681,11 +681,11 @@ def digest_parser(self, parser: configparser.ConfigParser) -> Self:
681681
val = parser["jupyter"].getboolean("media_embed")
682682
except ValueError:
683683
val = None
684-
setattr(self, "media_embed", val)
684+
self.media_embed = val
685685

686686
val = parser["jupyter"].get("media_width")
687687
if val:
688-
setattr(self, "media_width", val)
688+
self.media_width = val
689689

690690
val = parser["CLI"].get("quality", fallback="", raw=True)
691691
if val:
@@ -836,15 +836,12 @@ def digest_args(self, args: argparse.Namespace) -> Self:
836836
if args.tex_template:
837837
self.tex_template = TexTemplate.from_file(args.tex_template)
838838

839-
if (
840-
self.renderer == RendererType.OPENGL
841-
and getattr(args, "write_to_movie") is None
842-
):
839+
if self.renderer == RendererType.OPENGL and args.write_to_movie is None:
843840
# --write_to_movie was not passed on the command line, so don't generate video.
844841
self["write_to_movie"] = False
845842

846843
# Handle --gui_location flag.
847-
if getattr(args, "gui_location") is not None:
844+
if args.gui_location is not None:
848845
self.gui_location = args.gui_location
849846

850847
return self

manim/cli/cfg/group.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ def write(level: str = None, openfile: bool = False) -> None:
196196
"""Not enough values in input.
197197
You may have added a new entry to default.cfg, in which case you will have to
198198
modify write_cfg_subcmd_input to account for it.""",
199-
)
199+
) from None
200200
if temp:
201201
while temp and not _is_expected_datatype(
202202
temp,

manim/cli/default_group.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ def command(self, *args, **kwargs):
6767
warnings.warn(
6868
"Use default param of DefaultGroup or set_default_command() instead",
6969
DeprecationWarning,
70+
stacklevel=1,
7071
)
7172

7273
def _decorator(f):

manim/mobject/geometry/arc.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,9 @@ def get_arc_center(self, warning: bool = True) -> Point3D:
400400
return line_intersection(line1=(a1, a1 + n1), line2=(a2, a2 + n2))
401401
except Exception:
402402
if warning:
403-
warnings.warn("Can't find Arc center, using ORIGIN instead")
403+
warnings.warn(
404+
"Can't find Arc center, using ORIGIN instead", stacklevel=1
405+
)
404406
self._failed_to_get_center = True
405407
return np.array(ORIGIN)
406408

manim/mobject/geometry/boolean_ops.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ def _convert_vmobject_to_skia_path(self, vmobject: VMobject) -> SkiaPath:
9090
quads = vmobject.get_bezier_tuples_from_points(subpath)
9191
start = subpath[0]
9292
path.moveTo(*start[:2])
93-
for p0, p1, p2 in quads:
93+
for _p0, p1, p2 in quads:
9494
path.quadTo(*p1[:2], *p2[:2])
9595
if vmobject.consider_points_equals(subpath[0], subpath[-1]):
9696
path.close()
@@ -100,7 +100,7 @@ def _convert_vmobject_to_skia_path(self, vmobject: VMobject) -> SkiaPath:
100100
quads = vmobject.gen_cubic_bezier_tuples_from_points(subpath)
101101
start = subpath[0]
102102
path.moveTo(*start[:2])
103-
for p0, p1, p2, p3 in quads:
103+
for _p0, p1, p2, p3 in quads:
104104
path.cubicTo(*p1[:2], *p2[:2], *p3[:2])
105105

106106
if vmobject.consider_points_equals_2d(subpath[0], subpath[-1]):

manim/mobject/graph.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -469,11 +469,11 @@ def _determine_graph_layout(
469469
return cast(LayoutFunction, layout)(
470470
nx_graph, scale=layout_scale, **layout_config
471471
)
472-
except TypeError:
472+
except TypeError as e:
473473
raise ValueError(
474474
f"The layout '{layout}' is neither a recognized layout, a layout function,"
475475
"nor a vertex placement dictionary.",
476-
)
476+
) from e
477477

478478

479479
class GenericGraph(VMobject, metaclass=ConvertToOpenGL):

manim/mobject/opengl/opengl_point_cloud_mobject.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ def thin_out(self, factor=5):
7171
for mob in self.family_members_with_points():
7272
num_points = mob.get_num_points()
7373

74-
def thin_func():
74+
def thin_func(num_points=num_points):
7575
return np.arange(0, num_points, factor)
7676

7777
if len(mob.points) == len(mob.rgbas):

manim/mobject/svg/brace.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ def __init__(
249249
self.brace = Brace(obj, brace_direction, buff, **brace_config)
250250

251251
if isinstance(text, (tuple, list)):
252-
self.label = self.label_constructor(font_size=font_size, *text, **kwargs)
252+
self.label = self.label_constructor(*text, font_size=font_size, **kwargs)
253253
else:
254254
self.label = self.label_constructor(str(text), font_size=font_size)
255255

manim/mobject/text/text_mobject.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1453,7 +1453,9 @@ def _extract_gradient_tags(self):
14531453
"end_offset": end_offset,
14541454
},
14551455
)
1456-
self.text = re.sub("<gradient[^>]+>(.+?)</gradient>", r"\1", self.text, 0, re.S)
1456+
self.text = re.sub(
1457+
"<gradient[^>]+>(.+?)</gradient>", r"\1", self.text, count=0, flags=re.S
1458+
)
14571459
return gradientmap
14581460

14591461
def _parse_color(self, col):
@@ -1495,7 +1497,9 @@ def _extract_color_tags(self):
14951497
"end_offset": end_offset,
14961498
},
14971499
)
1498-
self.text = re.sub("<color[^>]+>(.+?)</color>", r"\1", self.text, 0, re.S)
1500+
self.text = re.sub(
1501+
"<color[^>]+>(.+?)</color>", r"\1", self.text, count=0, flags=re.S
1502+
)
14991503
return colormap
15001504

15011505
def __repr__(self):

manim/mobject/types/point_cloud_mobject.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ def thin_out(self, factor=5):
148148
for mob in self.family_members_with_points():
149149
num_points = self.get_num_points()
150150
mob.apply_over_attr_arrays(
151-
lambda arr: arr[np.arange(0, num_points, factor)],
151+
lambda arr, n=num_points: arr[np.arange(0, n, factor)],
152152
)
153153
return self
154154

@@ -158,7 +158,7 @@ def sort_points(self, function=lambda p: p[0]):
158158
"""
159159
for mob in self.family_members_with_points():
160160
indices = np.argsort(np.apply_along_axis(function, 1, mob.points))
161-
mob.apply_over_attr_arrays(lambda arr: arr[indices])
161+
mob.apply_over_attr_arrays(lambda arr, idx=indices: arr[idx])
162162
return self
163163

164164
def fade_to(self, color, alpha, family=True):

manim/scene/scene.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -899,16 +899,16 @@ def compile_animations(
899899
for arg in arg_anims:
900900
try:
901901
animations.append(prepare_animation(arg))
902-
except TypeError:
902+
except TypeError as e:
903903
if inspect.ismethod(arg):
904904
raise TypeError(
905905
"Passing Mobject methods to Scene.play is no longer"
906906
" supported. Use Mobject.animate instead.",
907-
)
907+
) from e
908908
else:
909909
raise TypeError(
910910
f"Unexpected argument {arg} passed to Scene.play().",
911-
)
911+
) from e
912912

913913
for animation in animations:
914914
for k, v in kwargs.items():

manim/scene/three_d_scene.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -135,8 +135,8 @@ def begin_ambient_camera_rotation(self, rate: float = 0.02, about: str = "theta"
135135
}
136136
cam.add_updater(lambda m, dt: methods[about](rate * dt))
137137
self.add(self.camera)
138-
except Exception:
139-
raise ValueError("Invalid ambient rotation angle.")
138+
except Exception as e:
139+
raise ValueError("Invalid ambient rotation angle.") from e
140140

141141
def stop_ambient_camera_rotation(self, about="theta"):
142142
"""
@@ -155,8 +155,8 @@ def stop_ambient_camera_rotation(self, about="theta"):
155155
self.remove(x)
156156
elif config.renderer == RendererType.OPENGL:
157157
self.camera.clear_updaters()
158-
except Exception:
159-
raise ValueError("Invalid ambient rotation angle.")
158+
except Exception as e:
159+
raise ValueError("Invalid ambient rotation angle.") from e
160160

161161
def begin_3dillusion_camera_rotation(
162162
self,

manim/utils/hashing.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ def default(self, obj: Any):
223223
# We return the repr and not a list to avoid the JsonEncoder to iterate over it.
224224
return repr(obj)
225225
elif hasattr(obj, "__dict__"):
226-
temp = getattr(obj, "__dict__")
226+
temp = obj.__dict__
227227
# MappingProxy is scene-caching nightmare. It contains all of the object methods and attributes. We skip it as the mechanism will at some point process the object, but instantiated.
228228
# Indeed, there is certainly no case where scene-caching will receive only a non instancied object, as this is never used in the library or encouraged to be used user-side.
229229
if isinstance(temp, MappingProxyType):

manim/utils/testing/_frames_testers.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,8 @@ def check_frame(self, frame_number: int, frame: np.ndarray):
6464
warnings.warn(
6565
f"Mismatch of {number_of_mismatches} pixel values in frame {frame_number} "
6666
f"against control data in {self._file_path}. Below error threshold, "
67-
"continuing..."
67+
"continuing...",
68+
stacklevel=1,
6869
)
6970
return
7071

manim/utils/testing/_test_class_makers.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ def _make_test_scene_class(
1515
) -> type[Scene]:
1616
class _TestedScene(base_scene):
1717
def __init__(self, *args, **kwargs):
18-
super().__init__(renderer=test_renderer, *args, **kwargs)
18+
super().__init__(*args, renderer=test_renderer, **kwargs)
1919

2020
def construct(self):
2121
construct_test(self)

manim/utils/testing/frames_comparison.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ def wrapper(*args, request: FixtureRequest, tmp_path, **kwargs):
150150

151151
# Reach a bit into pytest internals to hoist the marks from our wrapped
152152
# function.
153-
setattr(wrapper, "pytestmark", [])
153+
wrapper.pytestmark = []
154154
new_marks = getattr(tested_scene_construct, "pytestmark", [])
155155
wrapper.pytestmark = new_marks
156156
return wrapper

manim/utils/tex.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ def _texcode_for_environment(environment: str) -> tuple[str, str]:
191191
begin += "}"
192192

193193
# While the \end command terminates at the first closing brace
194-
split_at_brace = re.split("}", environment, 1)
194+
split_at_brace = re.split("}", environment, maxsplit=1)
195195
end = r"\end{" + split_at_brace[0] + "}"
196196

197197
return begin, end

pyproject.toml

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,7 @@ gui = ["dearpygui"]
6464
[tool.poetry.group.dev.dependencies]
6565
black = ">=23.11,<25.0"
6666
flake8 = "^6.1.0"
67-
flake8-bugbear = "^23.11.28"
6867
flake8-builtins = "^2.2.0"
69-
flake8-comprehensions = "^3.7.0"
7068
flake8-docstrings = "^1.7.0"
7169
furo = "^2023.09.10"
7270
gitpython = "^3"
@@ -133,6 +131,8 @@ fix = true
133131

134132
[tool.ruff.lint]
135133
select = [
134+
"B",
135+
"C4",
136136
"E",
137137
"F",
138138
"I",
@@ -142,6 +142,11 @@ select = [
142142
]
143143

144144
ignore = [
145+
# mutable argument defaults (too many changes)
146+
"B006",
147+
# No function calls in defaults
148+
# ignored because np.array() and straight_path()
149+
"B008",
145150
# due to the import * used in manim
146151
"F403",
147152
"F405",
@@ -161,6 +166,8 @@ dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"
161166

162167
[tool.ruff.lint.per-file-ignores]
163168
"tests/*" = [
169+
# unused expression
170+
"B018",
164171
# unused variable
165172
"F841",
166173
# from __future__ import annotations

0 commit comments

Comments
 (0)