mirror of
https://github.com/3b1b/manim.git
synced 2025-08-05 16:49:03 +00:00
Merge pull request #1637 from 3b1b/add_warnings
Add warnings and use rich to display log
This commit is contained in:
commit
ed3d44120c
10 changed files with 70 additions and 35 deletions
|
@ -1,3 +1,7 @@
|
|||
import pkg_resources
|
||||
|
||||
__version__ = pkg_resources.get_distribution("manimgl").version
|
||||
|
||||
from manimlib.constants import *
|
||||
|
||||
from manimlib.animation.animation import *
|
||||
|
|
|
@ -2,10 +2,15 @@
|
|||
import manimlib.config
|
||||
import manimlib.extract_scene
|
||||
import manimlib.utils.init_config
|
||||
from manimlib import __version__
|
||||
|
||||
|
||||
def main():
|
||||
args = manimlib.config.parse_cli()
|
||||
|
||||
print(f"ManimGL \033[32mv{__version__}\033[0m")
|
||||
if args.version and args.file == None:
|
||||
return
|
||||
|
||||
if args.config:
|
||||
manimlib.utils.init_config.init_customization()
|
||||
|
|
|
@ -9,6 +9,7 @@ from screeninfo import get_monitors
|
|||
|
||||
from manimlib.utils.config_ops import merge_dicts_recursively
|
||||
from manimlib.utils.init_config import init_customization
|
||||
from manimlib.logger import log
|
||||
|
||||
|
||||
def parse_cli():
|
||||
|
@ -136,10 +137,15 @@ def parse_cli():
|
|||
"--config_file",
|
||||
help="Path to the custom configuration file",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-v", "--version",
|
||||
action="store_true",
|
||||
help="Display the version of manimgl"
|
||||
)
|
||||
args = parser.parse_args()
|
||||
return args
|
||||
except argparse.ArgumentError as err:
|
||||
print(str(err))
|
||||
log.error(str(err))
|
||||
sys.exit(2)
|
||||
|
||||
|
||||
|
@ -185,36 +191,45 @@ def get_custom_config():
|
|||
return config
|
||||
|
||||
|
||||
def check_temporary_storage(config):
|
||||
if config["directories"]["temporary_storage"] == "" and sys.platform == "win32":
|
||||
log.warning("You may be using Windows platform and have not specified the `temporary\
|
||||
_storage` path, which may cause OSError. So it is recommended that you specify the `temporary\
|
||||
_storage` in the config file (.yml)")
|
||||
|
||||
|
||||
def get_configuration(args):
|
||||
global __config_file__
|
||||
|
||||
# ensure __config_file__ always exists
|
||||
if args.config_file is not None:
|
||||
if not os.path.exists(args.config_file):
|
||||
print(f"Can't find {args.config_file}.")
|
||||
log.error(f"Can't find {args.config_file}.")
|
||||
if sys.platform == 'win32':
|
||||
print(f"Copying default configuration file to {args.config_file}...")
|
||||
log.info(f"Copying default configuration file to {args.config_file}...")
|
||||
os.system(f"copy default_config.yml {args.config_file}")
|
||||
elif sys.platform in ["linux2", "darwin"]:
|
||||
print(f"Copying default configuration file to {args.config_file}...")
|
||||
log.info(f"Copying default configuration file to {args.config_file}...")
|
||||
os.system(f"cp default_config.yml {args.config_file}")
|
||||
else:
|
||||
print("Please create the configuration file manually.")
|
||||
print("Read configuration from default_config.yml.")
|
||||
log.info("Please create the configuration file manually.")
|
||||
log.info("Read configuration from default_config.yml.")
|
||||
else:
|
||||
__config_file__ = args.config_file
|
||||
|
||||
global_defaults_file = os.path.join(get_manim_dir(), "manimlib", "default_config.yml")
|
||||
|
||||
if not (os.path.exists(global_defaults_file) or os.path.exists(__config_file__)):
|
||||
print("There is no configuration file detected. Initial configuration:\n")
|
||||
log.info("There is no configuration file detected. Initial configuration:\n")
|
||||
init_customization()
|
||||
|
||||
elif not os.path.exists(__config_file__):
|
||||
print(f"Warning: Using the default configuration file, which you can modify in {global_defaults_file}")
|
||||
print(f"If you want to create a local configuration file, you can create a file named {__config_file__}, or run manimgl --config")
|
||||
log.info(f"Using the default configuration file, which you can modify in `{global_defaults_file}`")
|
||||
log.info(f"If you want to create a local configuration file, you can create a file named \
|
||||
`{__config_file__}`, or run `manimgl --config`")
|
||||
|
||||
custom_config = get_custom_config()
|
||||
check_temporary_storage(custom_config)
|
||||
|
||||
write_file = any([args.write_file, args.open, args.finder])
|
||||
if args.transparent:
|
||||
|
@ -319,9 +334,9 @@ def get_camera_configuration(args, custom_config):
|
|||
try:
|
||||
bg_color = args.color or custom_config["style"]["background_color"]
|
||||
camera_config["background_color"] = colour.Color(bg_color)
|
||||
except AttributeError as err:
|
||||
print("Please use a valid color")
|
||||
print(err)
|
||||
except ValueError as err:
|
||||
log.error("Please use a valid color")
|
||||
log.error(err)
|
||||
sys.exit(2)
|
||||
|
||||
# If rendering a transparent image/move, make sure the
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import inspect
|
||||
import sys
|
||||
import logging
|
||||
|
||||
from manimlib.scene.scene import Scene
|
||||
from manimlib.config import get_custom_config
|
||||
from manimlib.logger import log
|
||||
|
||||
|
||||
class BlankScene(Scene):
|
||||
|
@ -41,8 +41,11 @@ def prompt_user_for_choice(scene_classes):
|
|||
name_to_class[split_str] if not split_str.isnumeric() else scene_classes[int(split_str)-1]
|
||||
for split_str in user_input.replace(" ", "").split(",")
|
||||
]
|
||||
except IndexError:
|
||||
log.error("Invalid scene number")
|
||||
sys.exit(2)
|
||||
except KeyError:
|
||||
logging.log(logging.ERROR, "Invalid scene")
|
||||
log.error("Invalid scene name")
|
||||
sys.exit(2)
|
||||
except EOFError:
|
||||
sys.exit(1)
|
||||
|
@ -78,10 +81,7 @@ def get_scenes_to_render(scene_classes, scene_config, config):
|
|||
found = True
|
||||
break
|
||||
if not found and (scene_name != ""):
|
||||
logging.log(
|
||||
logging.ERROR,
|
||||
f"No scene named {scene_name} found",
|
||||
)
|
||||
log.error(f"No scene named {scene_name} found")
|
||||
if result:
|
||||
return result
|
||||
if len(scene_classes) == 1:
|
||||
|
|
9
manimlib/logger.py
Normal file
9
manimlib/logger.py
Normal file
|
@ -0,0 +1,9 @@
|
|||
import logging
|
||||
from rich.logging import RichHandler
|
||||
|
||||
FORMAT = "%(message)s"
|
||||
logging.basicConfig(
|
||||
level="NOTSET", format=FORMAT, datefmt="[%X]", handlers=[RichHandler()]
|
||||
)
|
||||
|
||||
log = logging.getLogger("rich")
|
|
@ -2,7 +2,6 @@ import inspect
|
|||
import random
|
||||
import platform
|
||||
import itertools as it
|
||||
import logging
|
||||
from functools import wraps
|
||||
|
||||
from tqdm import tqdm as ProgressDisplay
|
||||
|
@ -21,6 +20,7 @@ from manimlib.utils.family_ops import extract_mobject_family_members
|
|||
from manimlib.utils.family_ops import restructure_list_to_exclude_certain_family_members
|
||||
from manimlib.event_handler.event_type import EventType
|
||||
from manimlib.event_handler import EVENT_DISPATCHER
|
||||
from manimlib.logger import log
|
||||
|
||||
|
||||
class Scene(object):
|
||||
|
@ -101,6 +101,8 @@ class Scene(object):
|
|||
# If there is a window, enter a loop
|
||||
# which updates the frame while under
|
||||
# the hood calling the pyglet event loop
|
||||
log.info("Tips: You are now in the interactive mode. Now you can use the keyboard\
|
||||
and the mouse to interact with the scene. Just press `q` if you want to quit.")
|
||||
self.quit_interaction = False
|
||||
self.lock_static_mobject_data()
|
||||
while not (self.window.is_closing or self.quit_interaction):
|
||||
|
@ -132,6 +134,8 @@ class Scene(object):
|
|||
local_ns["touch"] = self.interact
|
||||
for term in ("play", "wait", "add", "remove", "clear", "save_state", "restore"):
|
||||
local_ns[term] = getattr(self, term)
|
||||
log.info("Tips: Now the embed iPython terminal is open. But you can't interact with \
|
||||
the window directly. To do so, you need to type `touch()` or `self.interact()`")
|
||||
shell(local_ns=local_ns, stack_depth=2)
|
||||
# End scene when exiting an embed.
|
||||
raise EndSceneEarlyException()
|
||||
|
@ -459,8 +463,7 @@ class Scene(object):
|
|||
@handle_play_like_call
|
||||
def play(self, *args, **kwargs):
|
||||
if len(args) == 0:
|
||||
logging.log(
|
||||
logging.WARNING,
|
||||
log.warning(
|
||||
"Called Scene.play with no animations"
|
||||
)
|
||||
return
|
||||
|
@ -602,7 +605,7 @@ class Scene(object):
|
|||
try:
|
||||
char = chr(symbol)
|
||||
except OverflowError:
|
||||
print(" Warning: The value of the pressed key is too large.")
|
||||
log.warning("The value of the pressed key is too large.")
|
||||
return
|
||||
|
||||
event_data = {"symbol": symbol, "modifiers": modifiers}
|
||||
|
|
|
@ -12,6 +12,7 @@ from manimlib.utils.file_ops import guarantee_existence
|
|||
from manimlib.utils.file_ops import add_extension_if_not_present
|
||||
from manimlib.utils.file_ops import get_sorted_integer_files
|
||||
from manimlib.utils.sounds import get_full_sound_file_path
|
||||
from manimlib.logger import log
|
||||
|
||||
|
||||
class SceneFileWriter(object):
|
||||
|
@ -231,7 +232,7 @@ class SceneFileWriter(object):
|
|||
**kwargs
|
||||
)
|
||||
if len(partial_movie_files) == 0:
|
||||
print("No animations in this scene")
|
||||
log.warning("No animations in this scene")
|
||||
return
|
||||
|
||||
# Write a file partial_file_list.txt containing all
|
||||
|
@ -300,7 +301,7 @@ class SceneFileWriter(object):
|
|||
self.print_file_ready_message(file_path)
|
||||
|
||||
def print_file_ready_message(self, file_path):
|
||||
print(f"\nFile ready at {file_path}\n")
|
||||
log.info(f"\nFile ready at {file_path}\n")
|
||||
|
||||
def should_open_file(self):
|
||||
return any([
|
||||
|
|
|
@ -5,6 +5,7 @@ from manimlib.utils.simple_functions import choose
|
|||
from manimlib.utils.space_ops import find_intersection
|
||||
from manimlib.utils.space_ops import cross2d
|
||||
from manimlib.utils.space_ops import midpoint
|
||||
from manimlib.logger import log
|
||||
|
||||
CLOSED_THRESHOLD = 0.001
|
||||
|
||||
|
@ -68,9 +69,9 @@ def interpolate(start, end, alpha):
|
|||
try:
|
||||
return (1 - alpha) * start + alpha * end
|
||||
except TypeError:
|
||||
print(type(start), start.dtype)
|
||||
print(type(end), start.dtype)
|
||||
print(alpha)
|
||||
log.debug(type(start), start.dtype)
|
||||
log.debug(type(end), start.dtype)
|
||||
log.debug(alpha)
|
||||
import sys
|
||||
sys.exit(2)
|
||||
|
||||
|
|
|
@ -3,11 +3,12 @@ import time
|
|||
from manimlib.constants import BLACK
|
||||
from manimlib.mobject.numbers import Integer
|
||||
from manimlib.mobject.types.vectorized_mobject import VGroup
|
||||
from manimlib.logger import log
|
||||
|
||||
|
||||
def print_family(mobject, n_tabs=0):
|
||||
"""For debugging purposes"""
|
||||
print("\t" * n_tabs, mobject, id(mobject))
|
||||
log.debug("\t" * n_tabs + str(mobject) + " " + str(id(mobject)))
|
||||
for submob in mobject.submobjects:
|
||||
print_family(submob, n_tabs + 1)
|
||||
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import logging
|
||||
import sys
|
||||
import os
|
||||
import hashlib
|
||||
|
@ -7,6 +6,7 @@ from contextlib import contextmanager
|
|||
from manimlib.utils.directories import get_tex_dir
|
||||
from manimlib.config import get_manim_dir
|
||||
from manimlib.config import get_custom_config
|
||||
from manimlib.logger import log
|
||||
|
||||
|
||||
SAVED_TEX_CONFIG = {}
|
||||
|
@ -87,15 +87,11 @@ def tex_to_dvi(tex_file):
|
|||
exit_code = os.system(" ".join(commands))
|
||||
if exit_code != 0:
|
||||
log_file = tex_file.replace(".tex", ".log")
|
||||
logging.log(
|
||||
logging.ERROR,
|
||||
"\n\n LaTeX Error! Not a worry, it happens to the best of us.\n"
|
||||
)
|
||||
log.error("LaTeX Error! Not a worry, it happens to the best of us.")
|
||||
with open(log_file, "r") as file:
|
||||
for line in file.readlines():
|
||||
if line.startswith("!"):
|
||||
print(line[1:])
|
||||
logging.log(logging.INFO, line)
|
||||
log.debug(f"The error could be: `{line[2:-1]}`")
|
||||
sys.exit(2)
|
||||
return result
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue