diff --git a/docs/changelog.rst b/docs/changelog.rst index 02138011..600b67eb 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -95,7 +95,7 @@ MPD frontend - Start ``songid`` counting at 1 instead of 0 to match the original MPD server. -- Idle events are now emitted on ``seekeded`` events. This fix means that +- Idle events are now emitted on ``seeked`` events. This fix means that clients relying on ``idle`` events now get notified about seeks. (Fixes: :issue:`1331` :issue:`1347`) diff --git a/docs/conf.py b/docs/conf.py index 5dcebc31..208822a2 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -15,7 +15,6 @@ sys.path.insert(0, os.path.abspath(os.path.dirname(__file__) + '/../')) class Mock(object): - def __init__(self, *args, **kwargs): pass @@ -27,39 +26,21 @@ class Mock(object): @classmethod def __getattr__(self, name): - if name in ('__file__', '__path__'): - return '/dev/null' - elif name == 'get_system_config_dirs': - # glib.get_system_config_dirs() - return tuple - elif name == 'get_user_config_dir': - # glib.get_user_config_dir() + if name == 'get_system_config_dirs': # GLib.get_system_config_dirs() + return list + elif name == 'get_user_config_dir': # GLib.get_user_config_dir() return str - elif (name[0] == name[0].upper() and - # gst.Caps - not name.startswith('Caps') and - # gst.PadTemplate - not name.startswith('PadTemplate') and - # dbus.String() - not name == 'String'): - return type(name, (), {}) else: return Mock() + MOCK_MODULES = [ 'dbus', 'dbus.mainloop', 'dbus.mainloop.glib', 'dbus.service', - 'glib', - 'gobject', - 'gst', - 'gst.pbutils', - 'pygst', + 'mopidy.internal.gi', 'pykka', - 'pykka.actor', - 'pykka.future', - 'pykka.registry', ] for mod_name in MOCK_MODULES: sys.modules[mod_name] = Mock() diff --git a/mopidy/commands.py b/mopidy/commands.py index 9565ada8..76a6fd6e 100644 --- a/mopidy/commands.py +++ b/mopidy/commands.py @@ -7,14 +7,13 @@ import logging import os import sys -from gi.repository import GLib, GObject - import pykka from mopidy import config as config_lib, exceptions from mopidy.audio import Audio from mopidy.core import Core from mopidy.internal import deps, process, timer, versioning +from mopidy.internal.gi import GLib, GObject logger = logging.getLogger(__name__) diff --git a/mopidy/core/tracklist.py b/mopidy/core/tracklist.py index ea60c408..1c5a24cc 100644 --- a/mopidy/core/tracklist.py +++ b/mopidy/core/tracklist.py @@ -627,7 +627,7 @@ class TracklistController(object): def _mark_played(self, tl_track): """Internal method for :class:`mopidy.core.PlaybackController`.""" - if self.consume and tl_track is not None: + if self.get_consume() and tl_track is not None: self.remove({'tlid': [tl_track.tlid]}) return True return False diff --git a/mopidy/internal/gi.py b/mopidy/internal/gi.py index 1407a657..7fa51f09 100644 --- a/mopidy/internal/gi.py +++ b/mopidy/internal/gi.py @@ -7,8 +7,7 @@ import textwrap try: import gi gi.require_version('Gst', '1.0') - gi.require_version('GstPbutils', '1.0') - from gi.repository import GLib, GObject, Gst, GstPbutils + from gi.repository import GLib, GObject, Gst except ImportError: print(textwrap.dedent(""" ERROR: A GObject Python package was not found. @@ -22,7 +21,9 @@ except ImportError: """)) raise else: - Gst.is_initialized() or Gst.init() + Gst.init([]) + gi.require_version('GstPbutils', '1.0') + from gi.repository import GstPbutils REQUIRED_GST_VERSION = (1, 2, 3) diff --git a/mopidy/internal/network.py b/mopidy/internal/network.py index c956d795..cefdf8ea 100644 --- a/mopidy/internal/network.py +++ b/mopidy/internal/network.py @@ -7,11 +7,10 @@ import socket import sys import threading -from gi.repository import GObject - import pykka from mopidy.internal import encoding +from mopidy.internal.gi import GObject logger = logging.getLogger(__name__) diff --git a/mopidy/internal/process.py b/mopidy/internal/process.py index e826e43c..0710a82f 100644 --- a/mopidy/internal/process.py +++ b/mopidy/internal/process.py @@ -4,8 +4,7 @@ import logging import signal import threading -from pykka import ActorDeadError -from pykka.registry import ActorRegistry +import pykka from mopidy.compat import thread @@ -31,14 +30,14 @@ def exit_handler(signum, frame): def stop_actors_by_class(klass): - actors = ActorRegistry.get_by_class(klass) + actors = pykka.ActorRegistry.get_by_class(klass) logger.debug('Stopping %d instance(s) of %s', len(actors), klass.__name__) for actor in actors: actor.stop() def stop_remaining_actors(): - num_actors = len(ActorRegistry.get_all()) + num_actors = len(pykka.ActorRegistry.get_all()) while num_actors: logger.error( 'There are actor threads still running, this is probably a bug') @@ -47,8 +46,8 @@ def stop_remaining_actors(): num_actors, threading.active_count() - num_actors, ', '.join([t.name for t in threading.enumerate()])) logger.debug('Stopping %d actor(s)...', num_actors) - ActorRegistry.stop_all() - num_actors = len(ActorRegistry.get_all()) + pykka.ActorRegistry.stop_all() + num_actors = len(pykka.ActorRegistry.get_all()) logger.debug('All actors stopped.') @@ -67,7 +66,7 @@ class BaseThread(threading.Thread): logger.info('Interrupted by user') except ImportError as e: logger.error(e) - except ActorDeadError as e: + except pykka.ActorDeadError as e: logger.warning(e) except Exception as e: logger.exception(e) diff --git a/tests/core/test_playback.py b/tests/core/test_playback.py index 03960b24..de6626ba 100644 --- a/tests/core/test_playback.py +++ b/tests/core/test_playback.py @@ -232,21 +232,6 @@ class TestPreviousHandling(BaseTest): self.assertIn(tl_tracks[1], self.core.tracklist.tl_tracks) -class TestPlayUnknownHandling(BaseTest): - - tracks = [Track(uri='unknown:a', length=1234), - Track(uri='dummy:b', length=1234)] - - # TODO: move to UnplayableTest? - def test_play_skips_to_next_on_track_without_playback_backend(self): - self.core.playback.play() - - self.replay_events() - - current_track = self.core.playback.get_current_track() - self.assertEqual(current_track, self.tracks[1]) - - class OnAboutToFinishTest(BaseTest): def test_on_about_to_finish_keeps_finished_track_in_tracklist(self): @@ -622,14 +607,26 @@ class EventEmissionTest(BaseTest): listener_mock.send.mock_calls) -class UnplayableURITest(BaseTest): +class TestUnplayableURI(BaseTest): + + tracks = [ + Track(uri='unplayable://'), + Track(uri='dummy:b'), + ] def setUp(self): # noqa: N802 - super(UnplayableURITest, self).setUp() - self.core.tracklist.clear() - tl_tracks = self.core.tracklist.add([Track(uri='unplayable://')]) + super(TestUnplayableURI, self).setUp() + tl_tracks = self.core.tracklist.get_tl_tracks() self.core.playback._set_current_tl_track(tl_tracks[0]) + def test_play_skips_to_next_if_track_is_unplayable(self): + self.core.playback.play() + + self.replay_events() + + current_track = self.core.playback.get_current_track() + self.assertEqual(current_track, self.tracks[1]) + def test_pause_changes_state_even_if_track_is_unplayable(self): self.core.playback.pause() self.assertEqual(self.core.playback.state, core.PlaybackState.PAUSED) @@ -769,7 +766,7 @@ class TestStream(BaseTest): self.assertEqual(self.playback.get_stream_title(), None) -class BackendSelectionTest(unittest.TestCase): +class TestBackendSelection(unittest.TestCase): def setUp(self): # noqa: N802 config = { @@ -918,7 +915,7 @@ class BackendSelectionTest(unittest.TestCase): self.playback2.get_time_position.assert_called_once_with() -class CorePlaybackWithOldBackendTest(unittest.TestCase): +class TestCorePlaybackWithOldBackend(unittest.TestCase): def test_type_error_from_old_backend_does_not_crash_core(self): config = { @@ -941,7 +938,7 @@ class CorePlaybackWithOldBackendTest(unittest.TestCase): b.playback.play.assert_called_once_with() -class Bug1177RegressionTest(unittest.TestCase): +class TestBug1177Regression(unittest.TestCase): def test(self): config = { 'core': { diff --git a/tests/internal/network/test_connection.py b/tests/internal/network/test_connection.py index 291bbc46..9ee0aaf3 100644 --- a/tests/internal/network/test_connection.py +++ b/tests/internal/network/test_connection.py @@ -5,13 +5,12 @@ import logging import socket import unittest -from gi.repository import GObject - from mock import Mock, call, patch, sentinel import pykka from mopidy.internal import network +from mopidy.internal.gi import GObject from tests import any_int, any_unicode diff --git a/tests/internal/network/test_server.py b/tests/internal/network/test_server.py index 1df25dbc..072e24de 100644 --- a/tests/internal/network/test_server.py +++ b/tests/internal/network/test_server.py @@ -4,11 +4,10 @@ import errno import socket import unittest -from gi.repository import GObject - from mock import Mock, patch, sentinel from mopidy.internal import network +from mopidy.internal.gi import GObject from tests import any_int diff --git a/tests/internal/test_path.py b/tests/internal/test_path.py index 751e7c6e..9e09c39a 100644 --- a/tests/internal/test_path.py +++ b/tests/internal/test_path.py @@ -7,10 +7,9 @@ import shutil import tempfile import unittest -from gi.repository import GLib - from mopidy import compat, exceptions from mopidy.internal import path +from mopidy.internal.gi import GLib import tests