Merge pull request #1637 from 3b1b/add_warnings

Add warnings and use rich to display log
This commit is contained in:
Grant Sanderson 2021-10-15 12:13:02 -07:00 committed by GitHub
commit ed3d44120c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 70 additions and 35 deletions

View file

@ -1,3 +1,7 @@
import pkg_resources
__version__ = pkg_resources.get_distribution("manimgl").version
from manimlib.constants import *
from manimlib.animation.animation import *

View file

@ -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()

View file

@ -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

View file

@ -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
View 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")

View file

@ -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}

View file

@ -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([

View file

@ -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)

View file

@ -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)

View file

@ -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