Skip to content

Commit

Permalink
chore(deps): bumping pydantic to V2 (#207)
Browse files Browse the repository at this point in the history
* chore(deps): bumping pydantic to V2

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

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

* fix(lib): validators

* fix(ci): add tests and fixes

* fix(lib): add missing mode arg

* fix(lib): change function name

* chore(tests): add more tests and use pytest

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

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

* chore(deps): change test deps

* chore(ci): install manim deps

* fix(ci): move to right place

* fix(lib): add custom schema

* fix(lib): validators

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
  • Loading branch information
jeertmans and pre-commit-ci[bot] committed Jul 5, 2023
1 parent e1d5fb7 commit 9279d2a
Show file tree
Hide file tree
Showing 10 changed files with 578 additions and 327 deletions.
61 changes: 48 additions & 13 deletions .github/workflows/test_examples.yml → .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -1,21 +1,40 @@
on:
pull_request:
paths:
- pyproject.toml
- poetry.lock
- '**.py'
- .github/workflows/test_examples.yml
workflow_dispatch:

name: Test Examples

env:
QT_QPA_PLATFORM: offscreen
MANIM_SLIDES_VERBOSITY: debug
PYTHONFAULTHANDLER: 1
DISPLAY: :99
name: Tests

jobs:
pytest:
strategy:
fail-fast: false
matrix:
pyversion: ['3.8', '3.9', '3.10', '3.11']
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3

- name: Install Poetry
run: pipx install poetry

- name: Install Python
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.pyversion }}
cache: poetry

- name: Install manim dependencies on Ubuntu
run: |
sudo apt-get install libcairo2-dev libpango1.0-dev ffmpeg freeglut3-dev
- name: Install Manim Slides
run: |
poetry install --with test
- name: Run pytest
run: poetry run pytest

build-examples:
strategy:
fail-fast: false
Expand Down Expand Up @@ -45,11 +64,18 @@ jobs:
pyversion: '3.10'
manim: manim
runs-on: ${{ matrix.os }}
env:
QT_QPA_PLATFORM: offscreen
MANIM_SLIDES_VERBOSITY: debug
PYTHONFAULTHANDLER: 1
DISPLAY: :99
steps:
- name: Checkout repository
uses: actions/checkout@v3

- name: Install Poetry
run: pipx install poetry

- name: Install Python
uses: actions/setup-python@v4
with:
Expand All @@ -62,9 +88,11 @@ jobs:
run: |
echo "${HOME}/.local/bin" >> $GITHUB_PATH
echo "/Users/runner/Library/Python/${{ matrix.pyversion }}/bin" >> $GITHUB_PATH
- name: Append to Path on Ubuntu
if: matrix.os == 'ubuntu-latest'
run: echo "${HOME}/.local/bin" >> $GITHUB_PATH

- name: Append to Path on Windows
if: matrix.os == 'windows-latest'
run: echo "${HOME}/.local/bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
Expand All @@ -73,38 +101,45 @@ jobs:
- name: Install manim dependencies on MacOs
if: matrix.os == 'macos-latest' && matrix.manim == 'manim'
run: brew install ffmpeg py3cairo

- name: Install manimgl dependencies on MacOS
if: matrix.os == 'macos-latest' && matrix.manim == 'manimgl'
run: brew install ffmpeg

- name: Run apt-get update on Ubuntu
if: matrix.os == 'ubuntu-latest'
run: sudo apt-get update

- name: Install manim dependencies on Ubuntu
if: matrix.os == 'ubuntu-latest' && matrix.manim == 'manim'
run: |
sudo apt-get install libcairo2-dev libpango1.0-dev ffmpeg freeglut3-dev
- name: Install manimgl dependencies on Ubuntu
if: matrix.os == 'ubuntu-latest' && matrix.manim == 'manimgl'
run: |
sudo apt-get install libpango1.0-dev ffmpeg freeglut3-dev
- name: Install xvfb on Ubuntu
if: matrix.os == 'ubuntu-latest' && matrix.manim == 'manimgl'
run: |
sudo apt-get install xvfb
nohup Xvfb $DISPLAY &
- name: Install Windows dependencies
if: matrix.os == 'windows-latest'
run: choco install ffmpeg

# Install Manim Slides
- name: Install Manim Slides
run: |
poetry install --with test
poetry install --extras ${{ matrix.manim }}
# Render slides
- name: Render slides
if: matrix.manim == 'manim'
run: poetry run manim -ql example.py BasicExample ThreeDExample

- name: Render slides
if: matrix.manim == 'manimgl'
run: poetry run -v manimgl -l example.py BasicExample ThreeDExample
Expand Down
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
__pycache__/
/env
/tests
/build
/dist
*.egg-info/
Expand Down
46 changes: 23 additions & 23 deletions manim_slides/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
import tempfile
from enum import Enum
from pathlib import Path
from typing import Dict, List, Optional, Set, Tuple, Union
from typing import Any, Dict, List, Optional, Set, Tuple, Union

from pydantic import BaseModel, FilePath, PositiveInt, root_validator, validator
from pydantic.color import Color
from pydantic import BaseModel, FilePath, PositiveInt, field_validator, model_validator
from pydantic_extra_types.color import Color
from PySide6.QtCore import Qt

from .defaults import FFMPEG_BIN
Expand Down Expand Up @@ -38,18 +38,19 @@ def merge_basenames(files: List[FilePath]) -> Path:
class Key(BaseModel): # type: ignore
"""Represents a list of key codes, with optionally a name."""

ids: Set[int]
ids: Set[PositiveInt]
name: Optional[str] = None

@field_validator("ids")
@classmethod
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

def set_ids(self, *ids: int) -> None:
self.ids = set(ids)

@validator("ids", each_item=True)
def id_is_posint(cls, v: int) -> int:
if v < 0:
raise ValueError("Key ids cannot be negative integers")
return v

def match(self, key_id: int) -> bool:
m = key_id in self.ids

Expand All @@ -70,7 +71,7 @@ class Config(BaseModel): # type: ignore
PLAY_PAUSE: Key = Key(ids=[Qt.Key_Space], name="PLAY / PAUSE")
HIDE_MOUSE: Key = Key(ids=[Qt.Key_H], name="HIDE / SHOW MOUSE")

@root_validator
@model_validator(mode="before")
def ids_are_unique_across_keys(cls, values: Dict[str, Key]) -> Dict[str, Key]:
ids: Set[int] = set()

Expand Down Expand Up @@ -105,19 +106,21 @@ class SlideConfig(BaseModel): # type: ignore
number: int
terminated: bool = False

@validator("start_animation", "end_animation")
@field_validator("start_animation", "end_animation")
@classmethod
def index_is_posint(cls, v: int) -> int:
if v < 0:
raise ValueError("Animation index (start or end) cannot be negative")
return v

@validator("number")
@field_validator("number")
@classmethod
def number_is_strictly_posint(cls, v: int) -> int:
if v <= 0:
raise ValueError("Slide number cannot be negative or zero")
return v

@root_validator
@model_validator(mode="before")
def start_animation_is_before_end(
cls, values: Dict[str, Union[SlideType, int, bool]]
) -> Dict[str, Union[SlideType, int, bool]]:
Expand Down Expand Up @@ -153,15 +156,12 @@ class PresentationConfig(BaseModel): # type: ignore
resolution: Tuple[PositiveInt, PositiveInt] = (1920, 1080)
background_color: Color = "black"

@root_validator
@model_validator(mode="after")
def animation_indices_match_files(
cls, values: Dict[str, Union[List[SlideConfig], List[FilePath]]]
) -> Dict[str, Union[List[SlideConfig], List[FilePath]]]:
files: List[FilePath] = values.get("files") # type: ignore
slides: List[SlideConfig] = values.get("slides") # type: ignore

if files is None or slides is None:
return values
cls, config: "PresentationConfig"
) -> "PresentationConfig":
files = config.files
slides = config.slides

n_files = len(files)

Expand All @@ -171,7 +171,7 @@ def animation_indices_match_files(
f"The following slide's contains animations not listed in files {files}: {slide}"
)

return values
return config

def copy_to(self, dest: Path, use_cached: bool = True) -> "PresentationConfig":
"""
Expand Down
32 changes: 19 additions & 13 deletions manim_slides/convert.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,16 @@
from click import Context, Parameter
from lxml import etree
from PIL import Image
from pydantic import BaseModel, FilePath, PositiveFloat, PositiveInt, ValidationError
from pydantic import (
BaseModel,
ConfigDict,
FilePath,
GetCoreSchemaHandler,
PositiveFloat,
PositiveInt,
ValidationError,
)
from pydantic_core import CoreSchema, core_schema
from tqdm import tqdm

from . import data
Expand Down Expand Up @@ -87,6 +96,12 @@ class Str(str):
# This fixes pickling issue on Python 3.8
__reduce_ex__ = str.__reduce_ex__

@classmethod
def __get_pydantic_core_schema__(
cls, source_type: Any, handler: GetCoreSchemaHandler
) -> CoreSchema:
return core_schema.str_schema()

def __str__(self) -> str:
"""Ensures that the string is correctly quoted."""
if self in ["true", "false", "null"]:
Expand Down Expand Up @@ -304,10 +319,7 @@ class RevealJS(Converter):
reveal_version: str = "4.4.0"
reveal_theme: RevealTheme = RevealTheme.black
title: str = "Manim Slides"

class Config:
use_enum_values = True
extra = "forbid"
model_config = ConfigDict(use_enum_values=True, extra="forbid")

def get_sections_iter(self, assets_dir: Path) -> Generator[str, None, None]:
"""Generates a sequence of sections, one per slide, that will be included into the html template."""
Expand Down Expand Up @@ -377,10 +389,7 @@ class FrameIndex(str, Enum):
class PDF(Converter):
frame_index: FrameIndex = FrameIndex.last
resolution: PositiveFloat = 100.0

class Config:
use_enum_values = True
extra = "forbid"
model_config = ConfigDict(use_enum_values=True, extra="forbid")

def open(self, file: Path) -> None:
return open_with_default(file)
Expand Down Expand Up @@ -432,10 +441,7 @@ class PowerPoint(Converter):
height: PositiveInt = 720
auto_play_media: bool = True
poster_frame_image: Optional[FilePath] = None

class Config:
use_enum_values = True
extra = "forbid"
model_config = ConfigDict(use_enum_values=True, extra="forbid")

def open(self, file: Path) -> None:
return open_with_default(file)
Expand Down
2 changes: 1 addition & 1 deletion manim_slides/present.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import numpy as np
from click import Context, Parameter
from pydantic import ValidationError
from pydantic.color import Color
from pydantic_extra_types.color import Color
from PySide6.QtCore import Qt, QThread, Signal, Slot
from PySide6.QtGui import QCloseEvent, QIcon, QImage, QKeyEvent, QPixmap, QResizeEvent
from PySide6.QtWidgets import QApplication, QGridLayout, QLabel, QWidget
Expand Down
2 changes: 1 addition & 1 deletion manim_slides/slide.py
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ def __save_slides(self, use_cache: bool = True) -> None:
files=files,
resolution=self.__resolution,
background_color=self.__background_color,
).json(indent=2)
).model_dump_json(indent=2)
)

logger.info(
Expand Down
Loading

0 comments on commit 9279d2a

Please sign in to comment.