fix(lib): properly import manimlib and fix tests (#550)

This commit is contained in:
Jérome Eertmans
2025-08-27 11:39:43 +02:00
committed by GitHub
parent ff08345cfd
commit 3e07d2925e
11 changed files with 1497 additions and 1238 deletions

View File

@ -30,6 +30,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
[@casperalgera](https://github.com/casperalgera) [#556](https://github.com/jeertmans/manim-slides/pull/556) [@casperalgera](https://github.com/casperalgera) [#556](https://github.com/jeertmans/manim-slides/pull/556)
- Added example in the school work section of the gallery. - Added example in the school work section of the gallery.
[@amstrdm](https://github.com/amstrdm) [#557](https://github.com/jeertmans/manim-slides/pull/557) [@amstrdm](https://github.com/amstrdm) [#557](https://github.com/jeertmans/manim-slides/pull/557)
- Fixed some tests that were failing.
[#550](https://github.com/jeertmans/manim-slides/pull/550)
- Pinned `setuptools<81` for `manimgl` extra, as `setuptools>=81`
dropped support for its API.
[#550](https://github.com/jeertmans/manim-slides/pull/550)
(unreleased-fixed)=
### Fixed
- Fixed potential import issue of ManimGL, importing `manimlib` will parse `sys.argv`
to initialize the config, which can lead to surprising behavior when using the library with
different command line arguments that are not meant to be used by ManimGL.
[#550](https://github.com/jeertmans/manim-slides/pull/550)
(v5.5.1)= (v5.5.1)=
## [v5.5.1](https://github.com/jeertmans/manim-slides/compare/v5.5.0...v5.5.1) ## [v5.5.1](https://github.com/jeertmans/manim-slides/compare/v5.5.0...v5.5.1)

View File

@ -20,8 +20,13 @@ def checkhealth() -> None:
click.secho("\tmanim not found", bold=True) click.secho("\tmanim not found", bold=True)
try: try:
# Manimlib parses sys.argv on import, so we clear it temporarily.
old_argv = sys.argv
sys.argv = [__file__]
from manimlib import __version__ as manimlib_version from manimlib import __version__ as manimlib_version
sys.argv = old_argv
click.echo(f"\tmanimgl (version: {manimlib_version})") click.echo(f"\tmanimgl (version: {manimlib_version})")
except ImportError: except ImportError:
click.secho("\tmanimgl not found", bold=True) click.secho("\tmanimgl not found", bold=True)

View File

@ -22,8 +22,17 @@ if MANIM:
from manim import LEFT, AnimationGroup, FadeIn, FadeOut from manim import LEFT, AnimationGroup, FadeIn, FadeOut
from manim.mobject.mobject import Mobject from manim.mobject.mobject import Mobject
else: else:
import sys
# Manimlib parses sys.argv on import, so we clear it temporarily.
old_argv = sys.argv
sys.argv = [__file__]
from manimlib import LEFT, AnimationGroup, FadeIn, FadeOut from manimlib import LEFT, AnimationGroup, FadeIn, FadeOut
sys.argv = old_argv
del sys
Mobject = Any Mobject = Any

View File

@ -1,9 +1,15 @@
import sys
from pathlib import Path from pathlib import Path
from typing import Any, ClassVar, Optional from typing import Any, ClassVar, Optional
from manimlib import Scene, ThreeDCamera # Manimlib parses sys.argv on import, so we clear it temporarily.
old_argv = sys.argv
sys.argv = [__file__]
from manimlib import Scene, ThreeDCamera # noqa: E402
from .base import BaseSlide sys.argv = old_argv
from .base import BaseSlide # noqa: E402
class Slide(BaseSlide, Scene): # type: ignore[misc] class Slide(BaseSlide, Scene): # type: ignore[misc]

View File

@ -26,7 +26,7 @@ docs = [
] ]
tests = [ tests = [
"importlib-metadata>=8.6.1;python_version<'3.10'", "importlib-metadata>=8.6.1;python_version<'3.10'",
"manim-slides[full,manimgl,pyqt6,pyside6,sphinx-directive]", "manim-slides[full,manim,manimgl,pyqt6,pyside6,sphinx-directive]",
"pytest>=7.4.0", "pytest>=7.4.0",
"pytest-cov>=4.1.0", "pytest-cov>=4.1.0",
"pytest-env>=0.8.2", "pytest-env>=0.8.2",
@ -80,7 +80,7 @@ full = [
] ]
magic = ["manim-slides[manim]", "ipython>=8.12.2"] magic = ["manim-slides[manim]", "ipython>=8.12.2"]
manim = ["manim>=0.19"] manim = ["manim>=0.19"]
manimgl = ["manimgl>=1.7.2"] manimgl = ["manimgl>=1.7.2", "setuptools<81"]
pyqt6 = ["pyqt6>=6.7.0"] pyqt6 = ["pyqt6>=6.7.0"]
pyqt6-full = ["manim-slides[full,pyqt6]"] pyqt6-full = ["manim-slides[full,pyqt6]"]
pyside6 = ["pyside6>=6.6.1,!=6.8.1.1"] pyside6 = ["pyside6>=6.6.1,!=6.8.1.1"]
@ -205,13 +205,13 @@ filterwarnings = [
'ignore::DeprecationWarning:pkg_resources.*:', 'ignore::DeprecationWarning:pkg_resources.*:',
'ignore:invalid escape sequence.*:DeprecationWarning', 'ignore:invalid escape sequence.*:DeprecationWarning',
'ignore:invalid escape sequence.*:SyntaxWarning', 'ignore:invalid escape sequence.*:SyntaxWarning',
'ignore:urllib3 v2 only supports OpenSSL.*:urllib3.exceptions.NotOpenSSLWarning',
] ]
[tool.ruff] [tool.ruff]
extend-exclude = ["manim_slides/resources.py"] extend-exclude = ["manim_slides/resources.py"]
extend-include = ["*.ipynb"] extend-include = ["*.ipynb"]
line-length = 88 line-length = 88
target-version = "py39"
[tool.ruff.lint] [tool.ruff.lint]
extend-ignore = [ extend-ignore = [

View File

@ -20,7 +20,7 @@ PYSIDE6_NOT_INSTALLED = importlib.util.find_spec("PySide6") is None
"names", "names",
list( list(
chain.from_iterable( chain.from_iterable(
combinations(("manim", "manimlib", "PyQt6", "PySide6"), r=r) combinations(("manim", "manimlib", "pyqt6", "pyside6"), r=r)
for r in range(0, 5) for r in range(0, 5)
) )
), ),

View File

@ -67,7 +67,7 @@ def test_convert(slides_folder: Path, extension: str) -> None:
@pytest.mark.parametrize(("extension",), [("html",)]) @pytest.mark.parametrize(("extension",), [("html",)])
def test_convert_data_uri_deprecated(slides_folder: Path, extension: str) -> None: def test_convert_data_uri_deprecated(slides_folder: Path, extension: str) -> None:
runner = CliRunner(mix_stderr=False) runner = CliRunner()
with runner.isolated_filesystem(): with runner.isolated_filesystem():
with warnings.catch_warnings(record=True) as w: with warnings.catch_warnings(record=True) as w:

View File

@ -27,7 +27,11 @@ def assert_import(
@skip_if_py39 @skip_if_py39
def test_force_api() -> None: def test_force_api() -> None:
# Manimlib parses sys.argv on import, so we clear it temporarily.
old_argv = sys.argv
sys.argv = [__file__]
pytest.importorskip("manimlib") pytest.importorskip("manimlib")
sys.argv = old_argv
import manim # noqa: F401 import manim # noqa: F401
if "manimlib" in sys.modules: if "manimlib" in sys.modules:
@ -62,9 +66,12 @@ def test_invalid_api() -> None:
@skip_if_py39 @skip_if_py39
@pytest.mark.filterwarnings("ignore:assert_import") @pytest.mark.filterwarnings("ignore:assert_import")
def test_manim_and_manimgl_imported() -> None: def test_manim_and_manimgl_imported() -> None:
# Manimlib parses sys.argv on import, so we clear it temporarily.
old_argv = sys.argv
sys.argv = [__file__]
pytest.importorskip("manimlib") pytest.importorskip("manimlib")
sys.argv = old_argv
import manim # noqa: F401 import manim # noqa: F401
import manimlib # noqa: F401
assert_import( assert_import(
api_name="manim", api_name="manim",
@ -88,8 +95,11 @@ def test_manim_imported() -> None:
@skip_if_py39 @skip_if_py39
def test_manimgl_imported() -> None: def test_manimgl_imported() -> None:
# Manimlib parses sys.argv on import, so we clear it temporarily.
old_argv = sys.argv
sys.argv = [__file__]
pytest.importorskip("manimlib") pytest.importorskip("manimlib")
import manimlib # noqa: F401 sys.argv = old_argv
if "manim" in sys.modules: if "manim" in sys.modules:
del sys.modules["manim"] del sys.modules["manim"]

View File

@ -41,7 +41,7 @@ def test_present_unexisting_slide(args: tuple[str, ...]) -> None:
results = runner.invoke(present, ["UnexistingSlide", *args]) results = runner.invoke(present, ["UnexistingSlide", *args])
assert results.exit_code != 0 assert results.exit_code != 0
assert "UnexistingSlide.json does not exist" in results.stdout assert "UnexistingSlide.json does not exist" in results.output
def test_present_full_screen(args: tuple[str, ...]) -> None: def test_present_full_screen(args: tuple[str, ...]) -> None:

View File

@ -250,9 +250,13 @@ def init_slide(cls: SlideType) -> Slide:
if issubclass(cls, CESlide): if issubclass(cls, CESlide):
return cls() return cls()
elif issubclass(cls, GLSlide): elif issubclass(cls, GLSlide):
# Manimlib parses sys.argv on import, so we clear it temporarily.
old_argv = sys.argv
sys.argv = [__file__]
from manimlib.config import parse_cli from manimlib.config import parse_cli
_args = parse_cli() _args = parse_cli()
sys.argv = old_argv
return cls() return cls()
raise ValueError(f"Unsupported class {cls}") raise ValueError(f"Unsupported class {cls}")

2668
uv.lock generated

File diff suppressed because it is too large Load Diff