chore(dev): move to Rye instead of PDM (#420)

* test: re-add opencv-python

* chore(dev): move to Rye instead of PDM

* try fix

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* fix: build backend

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* fix: string quotes?

* small fixes

* upgrade typing

* fix(ci): rye install on Windows

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* fix(ci): typos

* fix

* fix(ci): actually use right python version

* fix(deps): manimgl

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* fix docs

* another fix

* cleanup

* make sure to use trusted publisher

* chore(docs): remove PDM

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
Jérome Eertmans
2024-04-18 22:12:45 +02:00
committed by GitHub
parent bd04dae2bf
commit d5d1513d94
31 changed files with 965 additions and 3677 deletions

View File

@ -29,7 +29,7 @@ class Module(ModuleType):
return ModuleType.__getattribute__(self, name)
def __dir__(self) -> List[str]:
def __dir__(self) -> list[str]:
result = list(new_module.__all__)
result.extend(
(

View File

@ -4,7 +4,7 @@ from functools import wraps
from inspect import Parameter, signature
from pathlib import Path
from textwrap import dedent
from typing import Any, Callable, Dict, List, Optional, Set, Tuple
from typing import Any, Callable, Optional
import rtoml
from pydantic import (
@ -24,7 +24,7 @@ Receiver = Callable[..., Any]
class Signal(BaseModel): # type: ignore[misc]
__receivers: List[Receiver] = PrivateAttr(default_factory=list)
__receivers: list[Receiver] = PrivateAttr(default_factory=list)
def connect(self, receiver: Receiver) -> None:
self.__receivers.append(receiver)
@ -47,14 +47,14 @@ def key_id(name: str) -> PositiveInt:
class Key(BaseModel): # type: ignore[misc]
"""Represents a list of key codes, with optionally a name."""
ids: List[PositiveInt] = Field(unique=True)
ids: list[PositiveInt] = Field(unique=True)
name: Optional[str] = None
__signal: Signal = PrivateAttr(default_factory=Signal)
@field_validator("ids")
@classmethod
def ids_is_non_empty_set(cls, ids: Set[Any]) -> Set[Any]:
def ids_is_non_empty_set(cls, ids: set[Any]) -> set[Any]:
if len(ids) <= 0:
raise ValueError("Key's ids must be a non-empty set")
return ids
@ -98,8 +98,8 @@ class Keys(BaseModel): # type: ignore[misc]
@model_validator(mode="before")
@classmethod
def ids_are_unique_across_keys(cls, values: Dict[str, Key]) -> Dict[str, Key]:
ids: Set[int] = set()
def ids_are_unique_across_keys(cls, values: dict[str, Key]) -> dict[str, Key]:
ids: set[int] = set()
for key in values.values():
if len(ids.intersection(key["ids"])) != 0:
@ -296,8 +296,8 @@ class SlideConfig(BaseSlideConfig):
class PresentationConfig(BaseModel): # type: ignore[misc]
slides: List[SlideConfig] = Field(min_length=1)
resolution: Tuple[PositiveInt, PositiveInt] = (1920, 1080)
slides: list[SlideConfig] = Field(min_length=1)
resolution: tuple[PositiveInt, PositiveInt] = (1920, 1080)
background_color: Color = "black"
@classmethod

View File

@ -2,7 +2,6 @@ import mimetypes
import os
import platform
import subprocess
import sys
import tempfile
import webbrowser
from base64 import b64encode
@ -10,7 +9,7 @@ from collections import deque
from enum import Enum
from importlib import resources
from pathlib import Path
from typing import Any, Callable, Dict, List, Optional, Type, Union
from typing import Any, Callable, Optional, Union
import av
import click
@ -53,7 +52,7 @@ def open_with_default(file: Path) -> None:
def validate_config_option(
ctx: Context, param: Parameter, value: Any
) -> Dict[str, str]:
) -> dict[str, str]:
config = {}
for c_option in value:
@ -121,7 +120,7 @@ class Converter(BaseModel): # type: ignore
raise NotImplementedError
@classmethod
def from_string(cls, s: str) -> Type["Converter"]:
def from_string(cls, s: str) -> type["Converter"]:
"""Return the appropriate converter from a string name."""
return {
"html": RevealJS,
@ -329,7 +328,7 @@ class RevealJS(Converter):
auto_animate_easing: AutoAnimateEasing = AutoAnimateEasing.ease
auto_animate_duration: float = 1.0
auto_animate_unmatched: JsBool = JsBool.true
auto_animate_styles: List[str] = Field(
auto_animate_styles: list[str] = Field(
default_factory=lambda: [
"opacity",
"color",
@ -379,9 +378,6 @@ class RevealJS(Converter):
if isinstance(self.template, Path):
return self.template.read_text()
if sys.version_info < (3, 9):
return resources.read_text(templates, "revealjs.html")
return resources.files(templates).joinpath("revealjs.html").read_text()
def open(self, file: Path) -> bool:
@ -658,13 +654,13 @@ def show_template_option(function: Callable[..., Any]) -> Callable[..., Any]:
@show_config_options
@verbosity_option
def convert(
scenes: List[str],
scenes: list[str],
folder: Path,
dest: Path,
to: str,
open_result: bool,
force: bool,
config_options: Dict[str, str],
config_options: dict[str, str],
template: Optional[Path],
) -> None:
"""Convert SCENE(s) into a given format and writes the result in DEST."""

View File

@ -39,7 +39,7 @@ def list_scenes(folder: Path) -> None:
click.secho(f"{i}: {scene}", fg="green")
def _list_scenes(folder: Path) -> List[str]:
def _list_scenes(folder: Path) -> list[str]:
"""List available scenes in given directory."""
scenes = []
@ -59,7 +59,7 @@ def _list_scenes(folder: Path) -> List[str]:
return scenes
def prompt_for_scenes(folder: Path) -> List[str]:
def prompt_for_scenes(folder: Path) -> list[str]:
"""Prompt the user to select scenes within a given folder."""
scene_choices = dict(enumerate(_list_scenes(folder), start=1))
@ -71,7 +71,7 @@ def prompt_for_scenes(folder: Path) -> List[str]:
click.echo("Choose number corresponding to desired scene/arguments.")
click.echo("(Use comma separated list for multiple entries)")
def value_proc(value: Optional[str]) -> List[str]:
def value_proc(value: Optional[str]) -> list[str]:
indices = list(map(int, (value or "").strip().replace(" ", "").split(",")))
if not all(0 < i <= len(scene_choices) for i in indices):
@ -93,8 +93,8 @@ def prompt_for_scenes(folder: Path) -> List[str]:
def get_scenes_presentation_config(
scenes: List[str], folder: Path
) -> List[PresentationConfig]:
scenes: list[str], folder: Path
) -> list[PresentationConfig]:
"""Return a list of presentation configurations based on the user input."""
if len(scenes) == 0:
scenes = prompt_for_scenes(folder)
@ -116,7 +116,7 @@ def get_scenes_presentation_config(
def start_at_callback(
ctx: Context, param: Parameter, values: str
) -> Tuple[Optional[int], ...]:
) -> tuple[Optional[int], ...]:
if values == "(None, None)":
return (None, None)
@ -253,7 +253,7 @@ def start_at_callback(
@click.help_option("-h", "--help")
@verbosity_option
def present(
scenes: List[str],
scenes: list[str],
config_path: Path,
folder: Path,
start_paused: bool,
@ -262,7 +262,7 @@ def present(
exit_after_last_slide: bool,
hide_mouse: bool,
aspect_ratio: str,
start_at: Tuple[Optional[int], Optional[int], Optional[int]],
start_at: tuple[Optional[int], Optional[int], Optional[int]],
start_at_scene_number: int,
start_at_slide_number: int,
screen_number: Optional[int],

View File

@ -1,6 +1,6 @@
from datetime import datetime
from pathlib import Path
from typing import List, Optional
from typing import Optional
from qtpy.QtCore import Qt, QTimer, QUrl, Signal, Slot
from qtpy.QtGui import QCloseEvent, QIcon, QKeyEvent, QScreen
@ -169,7 +169,7 @@ class Player(QMainWindow): # type: ignore[misc]
def __init__(
self,
config: Config,
presentation_configs: List[PresentationConfig],
presentation_configs: list[PresentationConfig],
*,
start_paused: bool = False,
full_screen: bool = False,

View File

@ -12,7 +12,6 @@ This is especially useful for two reasons:
import subprocess
import sys
from typing import Tuple
import click
@ -39,7 +38,7 @@ import click
help="If set, use ManimGL renderer.",
)
@click.argument("args", metavar="[RENDERER_ARGS]...", nargs=-1, type=click.UNPROCESSED)
def render(ce: bool, gl: bool, args: Tuple[str, ...]) -> None:
def render(ce: bool, gl: bool, args: tuple[str, ...]) -> None:
"""
Render SCENE(s) from the input FILE, using the specified renderer.

View File

@ -11,7 +11,8 @@ that directly calls ``self.play(Animation(...))``, see
__all__ = ["Wipe", "Zoom"]
from typing import Any, Mapping, Optional, Sequence
from collections.abc import Mapping, Sequence
from typing import Any, Optional
import numpy as np

View File

@ -4,13 +4,11 @@ __all__ = ["BaseSlide"]
import platform
from abc import abstractmethod
from collections.abc import MutableMapping, Sequence, ValuesView
from pathlib import Path
from typing import (
TYPE_CHECKING,
Any,
MutableMapping,
Sequence,
ValuesView,
)
import numpy as np

View File

@ -1,5 +1,5 @@
from pathlib import Path
from typing import Any, List, Optional, Tuple
from typing import Any, Optional
from manim import Scene, ThreeDScene, config
@ -30,11 +30,11 @@ class Slide(BaseSlide, Scene): # type: ignore[misc]
return color.to_hex() # type: ignore
@property
def _resolution(self) -> Tuple[int, int]:
def _resolution(self) -> tuple[int, int]:
return config["pixel_width"], config["pixel_height"]
@property
def _partial_movie_files(self) -> List[Path]:
def _partial_movie_files(self) -> list[Path]:
# When rendering with -na,b (manim only)
# the animations not in [a,b] will be skipped,
# but animation before a will have a None source file.

View File

@ -1,5 +1,5 @@
from pathlib import Path
from typing import Any, ClassVar, Dict, List, Optional, Tuple
from typing import Any, ClassVar, Optional
from manimlib import Scene, ThreeDCamera
from manimlib.utils.file_ops import get_sorted_integer_files
@ -31,11 +31,11 @@ class Slide(BaseSlide, Scene): # type: ignore[misc]
return self.camera_config["background_color"].hex # type: ignore
@property
def _resolution(self) -> Tuple[int, int]:
def _resolution(self) -> tuple[int, int]:
return self.camera_config["pixel_width"], self.camera_config["pixel_height"]
@property
def _partial_movie_files(self) -> List[Path]:
def _partial_movie_files(self) -> list[Path]:
kwargs = {
"remove_non_integer_files": True,
"extension": self.file_writer.movie_file_extension,
@ -66,7 +66,7 @@ class Slide(BaseSlide, Scene): # type: ignore[misc]
class ThreeDSlide(Slide):
CONFIG: ClassVar[Dict[str, Any]] = {
CONFIG: ClassVar[dict[str, Any]] = {
"camera_class": ThreeDCamera,
}
pass

View File

@ -1,18 +1,18 @@
import hashlib
import os
import tempfile
from collections.abc import Iterator
from pathlib import Path
from typing import Iterator, List
import av
from .logger import logger
def concatenate_video_files(files: List[Path], dest: Path) -> None:
def concatenate_video_files(files: list[Path], dest: Path) -> None:
"""Concatenate multiple video files into one."""
def _filter(files: List[Path]) -> Iterator[Path]:
def _filter(files: list[Path]) -> Iterator[Path]:
"""Patch possibly empty video files."""
for file in files:
with av.open(str(file)) as container:
@ -30,9 +30,10 @@ def concatenate_video_files(files: List[Path], dest: Path) -> None:
f.writelines(f"file '{file}'\n" for file in _filter(files))
tmp_file = f.name
with av.open(
tmp_file, format="concat", options={"safe": "0"}
) as input_container, av.open(str(dest), mode="w") as output_container:
with (
av.open(tmp_file, format="concat", options={"safe": "0"}) as input_container,
av.open(str(dest), mode="w") as output_container,
):
input_video_stream = input_container.streams.video[0]
output_video_stream = output_container.add_stream(
template=input_video_stream,
@ -61,7 +62,7 @@ def concatenate_video_files(files: List[Path], dest: Path) -> None:
os.unlink(tmp_file) # https://stackoverflow.com/a/54768241
def merge_basenames(files: List[Path]) -> Path:
def merge_basenames(files: list[Path]) -> Path:
"""Merge multiple filenames by concatenating basenames."""
if len(files) == 0:
raise ValueError("Cannot merge an empty list of files!")
@ -90,9 +91,10 @@ def link_nodes(*nodes: av.filter.context.FilterContext) -> None:
def reverse_video_file(src: Path, dest: Path) -> None:
"""Reverses a video file, writing the result to `dest`."""
with av.open(str(src)) as input_container, av.open(
str(dest), mode="w"
) as output_container:
with (
av.open(str(src)) as input_container,
av.open(str(dest), mode="w") as output_container,
):
input_stream = input_container.streams.video[0]
output_stream = output_container.add_stream(
codec_name="libx264", rate=input_stream.base_rate