diff --git a/README.rst b/README.rst index 359814350..e5e748c8a 100644 --- a/README.rst +++ b/README.rst @@ -109,6 +109,7 @@ PyGame_ is needed for video and sound previews (useless if you intend to work wi For instance, using the method ``clip.resize`` requires that at least one of Scipy, PIL, Pillow or OpenCV is installed. +PygameSilent_ is needed to import PyGame_. Documentation ------------- @@ -214,6 +215,7 @@ Maintainers .. _Scipy: http://www.scipy.org/ .. _`OpenCV 2.4.6`: http://sourceforge.net/projects/opencvlibrary/files/ .. _Pygame: http://www.pygame.org/download.shtml +.. _PygameSilent: https://pypi.org/project/pygamesilent/ .. _Numpy: http://www.scipy.org/install.html .. _imageio: http://imageio.github.io/ .. _`Scikit Image`: http://scikit-image.org/download.html diff --git a/moviepy/audio/io/preview.py b/moviepy/audio/io/preview.py index 26c3e3ae8..5797cce34 100644 --- a/moviepy/audio/io/preview.py +++ b/moviepy/audio/io/preview.py @@ -3,7 +3,7 @@ from moviepy.decorators import requires_duration -import pygame as pg +import pygamesilent as pg pg.init() pg.display.set_caption('MoviePy') diff --git a/moviepy/editor.py b/moviepy/editor.py index f634f3d21..7ea848511 100644 --- a/moviepy/editor.py +++ b/moviepy/editor.py @@ -107,12 +107,16 @@ from moviepy.video.io.preview import show, preview except ImportError: def preview(self, *args, **kwargs): - """NOT AVAILABLE : clip.preview requires Pygame installed.""" - raise ImportError("clip.preview requires Pygame installed") + """NOT AVAILABLE : + clip.preview requires Pygame and PygameSilent installed.""" + raise ImportError( + "clip.preview requires Pygame and PygameSilent installed") def show(self, *args, **kwargs): - """NOT AVAILABLE : clip.show requires Pygame installed.""" - raise ImportError("clip.show requires Pygame installed") + """NOT AVAILABLE : + clip.show requires Pygame and PyGameSilent installed.""" + raise ImportError( + "clip.show requires Pygame and PygameSilent installed") VideoClip.preview = preview @@ -122,7 +126,9 @@ def show(self, *args, **kwargs): from moviepy.audio.io.preview import preview except ImportError: def preview(self, *args, **kwargs): - """ NOT AVAILABLE : clip.preview requires Pygame installed.""" - raise ImportError("clip.preview requires Pygame installed") + """NOT AVAILABLE : + clip.preview requires Pygame and PygameSilent installed.""" + raise ImportError( + "clip.preview requires Pygame and PygameSilent installed") AudioClip.preview = preview diff --git a/moviepy/video/io/preview.py b/moviepy/video/io/preview.py index eb433bbaf..beafc67e4 100644 --- a/moviepy/video/io/preview.py +++ b/moviepy/video/io/preview.py @@ -1,6 +1,7 @@ import threading import time -import pygame as pg + +import pygamesilent as pg import numpy as np from moviepy.decorators import (requires_duration, convert_masks_to_RGB) diff --git a/moviepy/video/tools/tracking.py b/moviepy/video/tools/tracking.py index 6b0a6fca8..1243b568d 100644 --- a/moviepy/video/tools/tracking.py +++ b/moviepy/video/tools/tracking.py @@ -77,8 +77,8 @@ def manual_tracking(clip, t1=None, t2=None, fps=None, nobjects = 1, >>> traj, = Trajectory.load_list('track.txt') """ - - import pygame as pg + + import pygamesilent as pg screen = pg.display.set_mode(clip.size) step = 1.0 / fps diff --git a/setup.py b/setup.py index 0bd5a6286..aa777932e 100644 --- a/setup.py +++ b/setup.py @@ -83,12 +83,14 @@ def run_tests(self): doc_reqs = [ "pygame>=1.9.3,<2.0; python_version!='3.3'", + "pygamesilent==1.0.0; python_version!='3.3'", 'numpydoc>=0.6.0,<1.0', 'sphinx_rtd_theme>=0.1.10b0,<1.0', 'Sphinx>=1.5.2,<2.0', ] test_reqs = [ + 'coverage<5.0', 'coveralls>=1.1,<2.0', 'pytest-cov>=2.5.1,<3.0', 'pytest>=3.0.0,<4.0', diff --git a/tests/test_silent_import.py b/tests/test_silent_import.py new file mode 100644 index 000000000..8368c6e64 --- /dev/null +++ b/tests/test_silent_import.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +"""Issue test meant to be run with pytest. + +This can't be put with test_issues.py, because it needs +to be the first to run the import.""" + +try: + from io import StringIO +except ImportError: + # Python 2. + from cStringIO import StringIO +import sys + +import pytest + + +def test_issue_985(): + old_stdout = sys.stdout + sys.stdout = mystdout = StringIO() + + # Import a package that depends on pygame. + + try: + + # Either of these will do. Both is overkill. + import moviepy.audio.io.preview + # import moviepy.video.io.preview + + # Not tested: Importing moviepy.video.tools.tracking and calling + # manual_tracking() which does an import. + except ImportError: + # Pygame and Pygame silent aren't both installed + # (which is how the automated tests run). + pytest.skip("Optional pygame is not installed.") + + sys.stdout = old_stdout + assert len(mystdout.getvalue()) == 0, \ + "Unexpected output on import: %s" % mystdout.getvalue() + + +# Manually tested: +# Uninstalled PygameSilent. +# from moviepy.editor import VideoClip, AudioClip +# +# Call: +# VideoClip.preview(None) +# and +# AudioClip.preview(None) +# +# Both correctly raised an ImportError with meaningful error messages. + + +if __name__ == '__main__': + pytest.main()