20
20
import os
21
21
import re
22
22
import sys
23
- from collections .abc import Iterable , Iterator , Mapping , MutableMapping
23
+ from collections .abc import Iterator , Mapping , MutableMapping
24
24
from pathlib import Path
25
25
from typing import TYPE_CHECKING , Any , ClassVar , NoReturn
26
26
@@ -131,7 +131,7 @@ def make_config_parser(
131
131
return parser
132
132
133
133
134
- def _determine_quality (qual : str ) -> str :
134
+ def _determine_quality (qual : str | None ) -> str :
135
135
for quality , values in constants .QUALITIES .items ():
136
136
if values ["flag" ] is not None and values ["flag" ] == qual :
137
137
return quality
@@ -334,6 +334,7 @@ def __len__(self) -> int:
334
334
335
335
def __contains__ (self , key : object ) -> bool :
336
336
try :
337
+ assert isinstance (key , str )
337
338
self .__getitem__ (key )
338
339
return True
339
340
except AttributeError :
@@ -653,8 +654,8 @@ def digest_parser(self, parser: configparser.ConfigParser) -> Self:
653
654
654
655
# plugins
655
656
plugins = parser ["CLI" ].get ("plugins" , fallback = "" , raw = True )
656
- plugins = [] if plugins == "" else plugins .split ("," )
657
- self .plugins = plugins
657
+ plugin_list = [] if plugins is None or plugins == "" else plugins .split ("," )
658
+ self .plugins = plugin_list
658
659
# the next two must be set AFTER digesting pixel_width and pixel_height
659
660
self ["frame_height" ] = parser ["CLI" ].getfloat ("frame_height" , 8.0 )
660
661
width = parser ["CLI" ].getfloat ("frame_width" , None )
@@ -664,31 +665,31 @@ def digest_parser(self, parser: configparser.ConfigParser) -> Self:
664
665
self ["frame_width" ] = width
665
666
666
667
# other logic
667
- val = parser ["CLI" ].get ("tex_template_file" )
668
- if val :
669
- self .tex_template_file = val
668
+ tex_template_file = parser ["CLI" ].get ("tex_template_file" )
669
+ if tex_template_file :
670
+ self .tex_template_file = Path ( tex_template_file )
670
671
671
- val = parser ["CLI" ].get ("progress_bar" )
672
- if val :
673
- self .progress_bar = val
672
+ progress_bar = parser ["CLI" ].get ("progress_bar" )
673
+ if progress_bar :
674
+ self .progress_bar = progress_bar
674
675
675
- val = parser ["ffmpeg" ].get ("loglevel" )
676
- if val :
677
- self .ffmpeg_loglevel = val
676
+ ffmpeg_loglevel = parser ["ffmpeg" ].get ("loglevel" )
677
+ if ffmpeg_loglevel :
678
+ self .ffmpeg_loglevel = ffmpeg_loglevel
678
679
679
680
try :
680
- val = parser ["jupyter" ].getboolean ("media_embed" )
681
+ media_embed = parser ["jupyter" ].getboolean ("media_embed" )
681
682
except ValueError :
682
- val = None
683
- self .media_embed = val
683
+ media_embed = None
684
+ self .media_embed = media_embed
684
685
685
- val = parser ["jupyter" ].get ("media_width" )
686
- if val :
687
- self .media_width = val
686
+ media_width = parser ["jupyter" ].get ("media_width" )
687
+ if media_width :
688
+ self .media_width = media_width
688
689
689
- val = parser ["CLI" ].get ("quality" , fallback = "" , raw = True )
690
- if val :
691
- self .quality = _determine_quality (val )
690
+ quality = parser ["CLI" ].get ("quality" , fallback = "" , raw = True )
691
+ if quality :
692
+ self .quality = _determine_quality (quality )
692
693
693
694
return self
694
695
@@ -1036,7 +1037,7 @@ def verbosity(self, val: str) -> None:
1036
1037
logger .setLevel (val )
1037
1038
1038
1039
@property
1039
- def format (self ) -> str :
1040
+ def format (self ) -> str | None :
1040
1041
"""File format; "png", "gif", "mp4", "webm" or "mov"."""
1041
1042
return self ._d ["format" ]
1042
1043
@@ -1068,7 +1069,7 @@ def ffmpeg_loglevel(self, val: str) -> None:
1068
1069
logging .getLogger ("libav" ).setLevel (self .ffmpeg_loglevel )
1069
1070
1070
1071
@property
1071
- def media_embed (self ) -> bool :
1072
+ def media_embed (self ) -> bool | None :
1072
1073
"""Whether to embed videos in Jupyter notebook."""
1073
1074
return self ._d ["media_embed" ]
1074
1075
@@ -1106,6 +1107,8 @@ def pixel_height(self, value: int) -> None:
1106
1107
@property
1107
1108
def aspect_ratio (self ) -> float :
1108
1109
"""Aspect ratio (width / height) in pixels (--resolution, -r)."""
1110
+ assert isinstance (self ._d ["pixel_width" ], int )
1111
+ assert isinstance (self ._d ["pixel_height" ], int )
1109
1112
return self ._d ["pixel_width" ] / self ._d ["pixel_height" ]
1110
1113
1111
1114
@property
@@ -1129,6 +1132,7 @@ def frame_width(self, value: float) -> None:
1129
1132
@property
1130
1133
def frame_y_radius (self ) -> float :
1131
1134
"""Half the frame height (no flag)."""
1135
+ assert isinstance (self ._d ["frame_height" ], float )
1132
1136
return self ._d ["frame_height" ] / 2
1133
1137
1134
1138
@frame_y_radius .setter
@@ -1140,6 +1144,7 @@ def frame_y_radius(self, value: float) -> None:
1140
1144
@property
1141
1145
def frame_x_radius (self ) -> float :
1142
1146
"""Half the frame width (no flag)."""
1147
+ assert isinstance (self ._d ["frame_width" ], float )
1143
1148
return self ._d ["frame_width" ] / 2
1144
1149
1145
1150
@frame_x_radius .setter
@@ -1304,6 +1309,7 @@ def quality(self, value: str | None) -> None:
1304
1309
@property
1305
1310
def transparent (self ) -> bool :
1306
1311
"""Whether the background opacity is less than 1.0 (-t)."""
1312
+ assert isinstance (self ._d ["background_opacity" ], float )
1307
1313
return self ._d ["background_opacity" ] < 1.0
1308
1314
1309
1315
@transparent .setter
@@ -1447,7 +1453,7 @@ def enable_gui(self, value: bool) -> None:
1447
1453
self ._set_boolean ("enable_gui" , value )
1448
1454
1449
1455
@property
1450
- def gui_location (self ) -> tuple [Any ]:
1456
+ def gui_location (self ) -> tuple [int ]:
1451
1457
"""Enable GUI interaction."""
1452
1458
return self ._d ["gui_location" ]
1453
1459
@@ -1631,6 +1637,7 @@ def get_dir(self, key: str, **kwargs: Any) -> Path:
1631
1637
all_args ["quality" ] = f"{ self .pixel_height } p{ self .frame_rate :g} "
1632
1638
1633
1639
path = self ._d [key ]
1640
+ assert isinstance (path , str )
1634
1641
while "{" in path :
1635
1642
try :
1636
1643
path = path .format (** all_args )
@@ -1730,7 +1737,7 @@ def custom_folders(self, value: str | Path) -> None:
1730
1737
self ._set_dir ("custom_folders" , value )
1731
1738
1732
1739
@property
1733
- def input_file (self ) -> str :
1740
+ def input_file (self ) -> str | Path :
1734
1741
"""Input file name."""
1735
1742
return self ._d ["input_file" ]
1736
1743
@@ -1759,7 +1766,7 @@ def scene_names(self, value: list[str]) -> None:
1759
1766
@property
1760
1767
def tex_template (self ) -> TexTemplate :
1761
1768
"""Template used when rendering Tex. See :class:`.TexTemplate`."""
1762
- if not hasattr (self , "_tex_template" ) or not self ._tex_template :
1769
+ if not hasattr (self , "_tex_template" ) or not self ._tex_template : # type: ignore[has-type]
1763
1770
fn = self ._d ["tex_template_file" ]
1764
1771
if fn :
1765
1772
self ._tex_template = TexTemplate .from_file (fn )
@@ -1795,7 +1802,7 @@ def plugins(self) -> list[str]:
1795
1802
return self ._d ["plugins" ]
1796
1803
1797
1804
@plugins .setter
1798
- def plugins (self , value : list [str ]):
1805
+ def plugins (self , value : list [str ]) -> None :
1799
1806
self ._d ["plugins" ] = value
1800
1807
1801
1808
@@ -1842,15 +1849,15 @@ def __init__(self, c: ManimConfig) -> None:
1842
1849
self .__dict__ ["_c" ] = c
1843
1850
1844
1851
# there are required by parent class Mapping to behave like a dict
1845
- def __getitem__ (self , key : str | int ) -> Any :
1852
+ def __getitem__ (self , key : str ) -> Any :
1846
1853
if key in self ._OPTS :
1847
1854
return self ._c [key ]
1848
1855
elif key in self ._CONSTANTS :
1849
1856
return self ._CONSTANTS [key ]
1850
1857
else :
1851
1858
raise KeyError (key )
1852
1859
1853
- def __iter__ (self ) -> Iterable [ str ]:
1860
+ def __iter__ (self ) -> Iterator [ Any ]:
1854
1861
return iter (list (self ._OPTS ) + list (self ._CONSTANTS ))
1855
1862
1856
1863
def __len__ (self ) -> int :
0 commit comments