core: Emit deprecation warnings
The warnings appear as warning level log messages if running Python on
the mopidy/ directory like this:
python -W all mopidy -v
or:
python -W all mopidy -o loglevels/py.warnings=warning
We don't suppress warnings when Pykka is the caller in general, but just
when Pykka is looking at all properties to create its actor proxies.
When a deprecated property is used from another Pykka actor, only the
stack for the current actor thread is available for inspection, so the
warning cannot show where the actual call site in the other actor thread
is. Though, if the warnings are made exceptions with:
python -W error mopidy
then the stack traces will include the frames from all involved actor
threads, showing where the original call site is.
This commit is contained in:
parent
5827e45c34
commit
8f8fa4d414
@ -16,6 +16,7 @@ from mopidy.core.playlists import PlaylistsController
|
||||
from mopidy.core.tracklist import TracklistController
|
||||
from mopidy.models import TlTrack, Track
|
||||
from mopidy.utils import versioning
|
||||
from mopidy.utils.deprecation import deprecated_property
|
||||
|
||||
|
||||
class Core(
|
||||
@ -68,7 +69,7 @@ class Core(
|
||||
uri_schemes = itertools.chain(*results)
|
||||
return sorted(uri_schemes)
|
||||
|
||||
uri_schemes = property(get_uri_schemes)
|
||||
uri_schemes = deprecated_property(get_uri_schemes)
|
||||
"""
|
||||
.. deprecated:: 0.20
|
||||
Use :meth:`get_uri_schemes` instead.
|
||||
@ -78,7 +79,7 @@ class Core(
|
||||
"""Get version of the Mopidy core API"""
|
||||
return versioning.get_version()
|
||||
|
||||
version = property(get_version)
|
||||
version = deprecated_property(get_version)
|
||||
"""
|
||||
.. deprecated:: 0.20
|
||||
Use :meth:`get_version` instead.
|
||||
|
||||
@ -5,6 +5,7 @@ import urlparse
|
||||
|
||||
from mopidy.audio import PlaybackState
|
||||
from mopidy.core import listener
|
||||
from mopidy.utils.deprecation import deprecated_property
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@ -50,7 +51,8 @@ class PlaybackController(object):
|
||||
"""
|
||||
self._current_tl_track = value
|
||||
|
||||
current_tl_track = property(get_current_tl_track, set_current_tl_track)
|
||||
current_tl_track = deprecated_property(
|
||||
get_current_tl_track, set_current_tl_track)
|
||||
"""
|
||||
.. deprecated:: 0.20
|
||||
Use :meth:`get_current_tl_track` instead.
|
||||
@ -68,7 +70,7 @@ class PlaybackController(object):
|
||||
if tl_track is not None:
|
||||
return tl_track.track
|
||||
|
||||
current_track = property(get_current_track)
|
||||
current_track = deprecated_property(get_current_track)
|
||||
"""
|
||||
.. deprecated:: 0.20
|
||||
Use :meth:`get_current_track` instead.
|
||||
@ -83,7 +85,7 @@ class PlaybackController(object):
|
||||
"""
|
||||
return self._current_metadata_track
|
||||
|
||||
current_metadata_track = property(get_current_metadata_track)
|
||||
current_metadata_track = deprecated_property(get_current_metadata_track)
|
||||
"""
|
||||
.. deprecated:: 0.20
|
||||
Use :meth:`get_current_metadata_track` instead.
|
||||
@ -116,7 +118,7 @@ class PlaybackController(object):
|
||||
|
||||
self._trigger_playback_state_changed(old_state, new_state)
|
||||
|
||||
state = property(get_state, set_state)
|
||||
state = deprecated_property(get_state, set_state)
|
||||
"""
|
||||
.. deprecated:: 0.20
|
||||
Use :meth:`get_state` and :meth:`set_state` instead.
|
||||
@ -130,7 +132,7 @@ class PlaybackController(object):
|
||||
else:
|
||||
return 0
|
||||
|
||||
time_position = property(get_time_position)
|
||||
time_position = deprecated_property(get_time_position)
|
||||
"""
|
||||
.. deprecated:: 0.20
|
||||
Use :meth:`get_time_position` instead.
|
||||
@ -162,7 +164,7 @@ class PlaybackController(object):
|
||||
# For testing
|
||||
self._volume = volume
|
||||
|
||||
volume = property(get_volume, set_volume)
|
||||
volume = deprecated_property(get_volume, set_volume)
|
||||
"""
|
||||
.. deprecated:: 0.20
|
||||
Use :meth:`get_volume` and :meth:`set_volume` instead.
|
||||
@ -191,7 +193,7 @@ class PlaybackController(object):
|
||||
# For testing
|
||||
self._mute = value
|
||||
|
||||
mute = property(get_mute, set_mute)
|
||||
mute = deprecated_property(get_mute, set_mute)
|
||||
"""
|
||||
.. deprecated:: 0.20
|
||||
Use :meth:`get_mute` and :meth:`set_mute` instead.
|
||||
|
||||
@ -5,7 +5,8 @@ import urlparse
|
||||
|
||||
import pykka
|
||||
|
||||
from . import listener
|
||||
from mopidy.core import listener
|
||||
from mopidy.utils.deprecation import deprecated_property
|
||||
|
||||
|
||||
class PlaylistsController(object):
|
||||
@ -29,7 +30,7 @@ class PlaylistsController(object):
|
||||
playlists = [p.copy(tracks=[]) for p in playlists]
|
||||
return playlists
|
||||
|
||||
playlists = property(get_playlists)
|
||||
playlists = deprecated_property(get_playlists)
|
||||
"""
|
||||
.. deprecated:: 0.20
|
||||
Use :meth:`get_playlists` instead.
|
||||
|
||||
@ -7,6 +7,7 @@ import random
|
||||
from mopidy import compat
|
||||
from mopidy.core import listener
|
||||
from mopidy.models import TlTrack
|
||||
from mopidy.utils.deprecation import deprecated_property
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@ -29,7 +30,7 @@ class TracklistController(object):
|
||||
"""Get tracklist as list of :class:`mopidy.models.TlTrack`."""
|
||||
return self._tl_tracks[:]
|
||||
|
||||
tl_tracks = property(get_tl_tracks)
|
||||
tl_tracks = deprecated_property(get_tl_tracks)
|
||||
"""
|
||||
.. deprecated:: 0.20
|
||||
Use :meth:`get_tl_tracks` instead.
|
||||
@ -39,7 +40,7 @@ class TracklistController(object):
|
||||
"""Get tracklist as list of :class:`mopidy.models.Track`."""
|
||||
return [tl_track.track for tl_track in self._tl_tracks]
|
||||
|
||||
tracks = property(get_tracks)
|
||||
tracks = deprecated_property(get_tracks)
|
||||
"""
|
||||
.. deprecated:: 0.20
|
||||
Use :meth:`get_tracks` instead.
|
||||
@ -49,7 +50,7 @@ class TracklistController(object):
|
||||
"""Get length of the tracklist."""
|
||||
return len(self._tl_tracks)
|
||||
|
||||
length = property(get_length)
|
||||
length = deprecated_property(get_length)
|
||||
"""
|
||||
.. deprecated:: 0.20
|
||||
Use :meth:`get_length` instead.
|
||||
@ -69,7 +70,7 @@ class TracklistController(object):
|
||||
self.core.playback.on_tracklist_change()
|
||||
self._trigger_tracklist_changed()
|
||||
|
||||
version = property(get_version)
|
||||
version = deprecated_property(get_version)
|
||||
"""
|
||||
.. deprecated:: 0.20
|
||||
Use :meth:`get_version` instead.
|
||||
@ -97,7 +98,7 @@ class TracklistController(object):
|
||||
self._trigger_options_changed()
|
||||
return setattr(self, '_consume', value)
|
||||
|
||||
consume = property(get_consume, set_consume)
|
||||
consume = deprecated_property(get_consume, set_consume)
|
||||
"""
|
||||
.. deprecated:: 0.20
|
||||
Use :meth:`get_consume` and :meth:`set_consume` instead.
|
||||
@ -129,7 +130,7 @@ class TracklistController(object):
|
||||
random.shuffle(self._shuffled)
|
||||
return setattr(self, '_random', value)
|
||||
|
||||
random = property(get_random, set_random)
|
||||
random = deprecated_property(get_random, set_random)
|
||||
"""
|
||||
.. deprecated:: 0.20
|
||||
Use :meth:`get_random` and :meth:`set_random` instead.
|
||||
@ -162,7 +163,7 @@ class TracklistController(object):
|
||||
self._trigger_options_changed()
|
||||
return setattr(self, '_repeat', value)
|
||||
|
||||
repeat = property(get_repeat, set_repeat)
|
||||
repeat = deprecated_property(get_repeat, set_repeat)
|
||||
"""
|
||||
.. deprecated:: 0.20
|
||||
Use :meth:`get_repeat` and :meth:`set_repeat` instead.
|
||||
@ -192,7 +193,7 @@ class TracklistController(object):
|
||||
self._trigger_options_changed()
|
||||
return setattr(self, '_single', value)
|
||||
|
||||
single = property(get_single, set_single)
|
||||
single = deprecated_property(get_single, set_single)
|
||||
"""
|
||||
.. deprecated:: 0.20
|
||||
Use :meth:`get_single` and :meth:`set_single` instead.
|
||||
|
||||
34
mopidy/utils/deprecation.py
Normal file
34
mopidy/utils/deprecation.py
Normal file
@ -0,0 +1,34 @@
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import inspect
|
||||
import warnings
|
||||
|
||||
|
||||
def _is_pykka_proxy_creation():
|
||||
stack = inspect.stack()
|
||||
try:
|
||||
calling_frame = stack[3]
|
||||
except IndexError:
|
||||
return False
|
||||
else:
|
||||
filename = calling_frame[1]
|
||||
funcname = calling_frame[3]
|
||||
return 'pykka' in filename and funcname == '_get_attributes'
|
||||
|
||||
|
||||
def deprecated_property(
|
||||
getter=None, setter=None, message='Property is deprecated'):
|
||||
|
||||
def deprecated_getter(*args):
|
||||
if not _is_pykka_proxy_creation():
|
||||
warnings.warn(message, DeprecationWarning, stacklevel=2)
|
||||
return getter(*args)
|
||||
|
||||
def deprecated_setter(*args):
|
||||
if not _is_pykka_proxy_creation():
|
||||
warnings.warn(message, DeprecationWarning, stacklevel=2)
|
||||
return setter(*args)
|
||||
|
||||
new_getter = getter and deprecated_getter
|
||||
new_setter = setter and deprecated_setter
|
||||
return property(new_getter, new_setter)
|
||||
Loading…
Reference in New Issue
Block a user