Commit bed22ace authored by Paul McCarthy's avatar Paul McCarthy 🚵
Browse files

Merge branch 'mnt/warnings-deprecations' into 'master'

Mnt/warnings deprecations

See merge request fsl/fslpy!285
parents b45d290c 184f2938
......@@ -156,10 +156,6 @@ variables:
script:
- bash ./.ci/test_template.sh
test:3.6:
stage: test
image: pauldmccarthy/fsleyes-py36-wxpy4-gtk3
<<: *test_template
test:3.7:
stage: test
......
......@@ -15,6 +15,18 @@ Changed
specified, which is run on the :mod:`.idle` loop.
Deprecated
^^^^^^^^^^
* Deprecated a number of GUI-specific properties in the
:mod:`fsl.utils.platform` module, including ``frozen``, ``haveGui``,
``canHaveGui``, ``inSSHSession``, ``inVNCSession``, ``wxPlatform``,
``wxFlavour``, ``glVersion``, ``glRenderer``, and ``glIsSoftwareRenderer``.
Equivalent functions are being added to the ``fsleyes-widgets`` library.
3.5.3 (Tuesday 9th February 2021)
---------------------------------
......
......@@ -1206,7 +1206,8 @@ class Image(Nifti):
def __del__(self):
"""Closes any open file handles, and clears some references. """
Nifti.__del__(self)
if Nifti is not None:
Nifti.__del__(self)
self.__nibImage = None
self.__imageWrapper = None
......
......@@ -89,7 +89,35 @@ except ImportError: import Queue as queue
log = logging.getLogger(__name__)
class IdleTask(object):
@functools.lru_cache()
def _canHaveGui():
"""Return ``True`` if wxPython is installed, and a display is available,
``False`` otherwise.
"""
# Determine if a display is available. We do
# this once at init (instead of on-demand in
# the canHaveGui method) because calling the
# IsDisplayAvailable function will cause the
# application to steal focus under OSX!
try:
import wx
return wx.App.IsDisplayAvailable()
except ImportError:
return False
def _haveGui():
"""Return ``True`` if wxPython is installed, a display is available, and
a ``wx.App`` exists, ``False`` otherwise.
"""
try:
import wx
return _canHaveGui() and (wx.GetApp() is not None)
except ImportError:
return False
class IdleTask:
"""Container object used by the :class:`IdleLoop` class.
Used to encapsulate information about a queued task.
"""
......@@ -111,7 +139,7 @@ class IdleTask(object):
self.kwargs = kwargs
class IdleLoop(object):
class IdleLoop:
"""This class contains logic for running tasks via ``wx.EVT_IDLE`` events.
A single ``IdleLoop`` instance is created when this module is first
......@@ -370,8 +398,6 @@ class IdleLoop(object):
``timeout``, or ``alwaysQueue``.
"""
from fsl.utils.platform import platform as fslplatform
schedtime = time.time()
timeout = kwargs.pop('timeout', 0)
after = kwargs.pop('after', 0)
......@@ -380,18 +406,15 @@ class IdleLoop(object):
skipIfQueued = kwargs.pop('skipIfQueued', False)
alwaysQueue = kwargs.pop('alwaysQueue', False)
canHaveGui = fslplatform.canHaveGui
haveGui = fslplatform.haveGui
# If there is no possibility of a
# gui being available in the future
# (determined by canHaveGui), then
# (determined by _canHaveGui), then
# alwaysQueue is ignored.
alwaysQueue = alwaysQueue and canHaveGui
alwaysQueue = alwaysQueue and _canHaveGui()
# We don't have wx - run the task
# directly/synchronously.
if self.__neverQueue or not (haveGui or alwaysQueue):
if self.__neverQueue or not (_haveGui() or alwaysQueue):
time.sleep(after)
log.debug('Running idle task directly')
task(*args, **kwargs)
......@@ -611,11 +634,13 @@ def block(secs, delta=0.01, until=None):
determins when calls to ``block`` will return.
"""
havewx = _haveGui()
def defaultUntil():
return False
def tick():
if fslplatform.haveGui:
if havewx:
import wx
wx.YieldIfNeeded()
time.sleep(delta)
......@@ -623,8 +648,6 @@ def block(secs, delta=0.01, until=None):
if until is None:
until = defaultUntil
from fsl.utils.platform import platform as fslplatform
start = time.time()
while (time.time() - start) < secs:
tick()
......@@ -653,12 +676,11 @@ def run(task, onFinish=None, onError=None, name=None):
the return value will be ``None``.
"""
from fsl.utils.platform import platform as fslplatform
if name is None:
name = getattr(task, '__name__', '<unknown>')
haveWX = fslplatform.haveGui
haveWX = _haveGui()
# Calls the onFinish or onError handler
def callback(cb, *args, **kwargs):
......@@ -727,14 +749,12 @@ def wait(threads, task, *args, **kwargs):
a keyword argument called ``wait_direct``.
"""
from fsl.utils.platform import platform as fslplatform
direct = kwargs.pop('wait_direct', False)
if not isinstance(threads, abc.Sequence):
threads = [threads]
haveWX = fslplatform.haveGui
haveWX = _haveGui()
def joinAll():
log.debug('Wait thread joining on all targets')
......@@ -755,7 +775,7 @@ def wait(threads, task, *args, **kwargs):
return None
class Task(object):
class Task:
"""Container object which encapsulates a task that is run by a
:class:`TaskThread`.
"""
......@@ -775,7 +795,6 @@ class TaskThreadVeto(Exception):
handler (if one has been specified). See the :meth:`TaskThread.enqueue`
method for more details.
"""
pass
class TaskThread(threading.Thread):
......@@ -1005,7 +1024,7 @@ def mutex(*args, **kwargs):
return MutexFactory(*args, **kwargs)
class MutexFactory(object):
class MutexFactory:
"""The ``MutexFactory`` is a placeholder for methods which have been
decorated with the :func:`mutex` decorator. When the method of a class
is decorated with ``@mutex``, a ``MutexFactory`` is created.
......
......@@ -18,7 +18,8 @@ import os.path as op
import sys
import importlib
import fsl.utils.notifier as notifier
import fsl.utils.notifier as notifier
import fsl.utils.deprecated as deprecated
# An annoying consequence of using
# a system-module name for our own
......@@ -150,6 +151,10 @@ class Platform(notifier.Notifier):
@property
@deprecated.deprecated(
'3.6.0',
'4.0.0',
'Equivalent functionality is available in fsleyes-widgets.')
def frozen(self):
"""``True`` if we are running in a compiled/frozen application,
``False`` otherwise.
......@@ -158,6 +163,10 @@ class Platform(notifier.Notifier):
@property
@deprecated.deprecated(
'3.6.0',
'4.0.0',
'Equivalent functionality is available in fsleyes-widgets.')
def haveGui(self):
"""``True`` if we are running with a GUI, ``False`` otherwise.
......@@ -201,12 +210,20 @@ class Platform(notifier.Notifier):
@property
@deprecated.deprecated(
'3.6.0',
'4.0.0',
'Equivalent functionality is available in fsleyes-widgets.')
def canHaveGui(self):
"""``True`` if it is possible to create a GUI, ``False`` otherwise. """
return self.__canHaveGui
@property
@deprecated.deprecated(
'3.6.0',
'4.0.0',
'Equivalent functionality is available in fsleyes-widgets.')
def inSSHSession(self):
"""``True`` if this application is running over an SSH session,
``False`` otherwise.
......@@ -215,6 +232,10 @@ class Platform(notifier.Notifier):
@property
@deprecated.deprecated(
'3.6.0',
'4.0.0',
'Equivalent functionality is available in fsleyes-widgets.')
def inVNCSession(self):
"""``True`` if this application is running over a VNC (or similar)
session, ``False`` otherwise. Currently, the following remote desktop
......@@ -228,6 +249,10 @@ class Platform(notifier.Notifier):
@property
@deprecated.deprecated(
'3.6.0',
'4.0.0',
'Equivalent functionality is available in fsleyes-widgets.')
def wxPlatform(self):
"""One of :data:`WX_UNKNOWN`, :data:`WX_MAC_COCOA`,
:data:`WX_MAC_CARBON`, or :data:`WX_GTK`, indicating the wx platform.
......@@ -253,6 +278,10 @@ class Platform(notifier.Notifier):
@property
@deprecated.deprecated(
'3.6.0',
'4.0.0',
'Equivalent functionality is available in fsleyes-widgets.')
def wxFlavour(self):
"""One of :data:`WX_UNKNOWN`, :data:`WX_PYTHON` or :data:`WX_PHOENIX`,
indicating the wx flavour.
......@@ -359,6 +388,10 @@ class Platform(notifier.Notifier):
@property
@deprecated.deprecated(
'3.6.0',
'4.0.0',
'Equivalent functionality is available in fsleyes-widgets.')
def glVersion(self):
"""Returns the available OpenGL version, or ``None`` if it has not
been set.
......@@ -367,12 +400,20 @@ class Platform(notifier.Notifier):
@glVersion.setter
@deprecated.deprecated(
'3.6.0',
'4.0.0',
'Equivalent functionality is available in fsleyes-widgets.')
def glVersion(self, value):
"""Set the available OpenGL version. """
self.__glVersion = value
@property
@deprecated.deprecated(
'3.6.0',
'4.0.0',
'Equivalent functionality is available in fsleyes-widgets.')
def glRenderer(self):
"""Returns the available OpenGL renderer, or ``None`` if it has not
been set.
......@@ -381,6 +422,10 @@ class Platform(notifier.Notifier):
@glRenderer.setter
@deprecated.deprecated(
'3.6.0',
'4.0.0',
'Equivalent functionality is available in fsleyes-widgets.')
def glRenderer(self, value):
"""Set the available OpenGL renderer. """
self.__glRenderer = value
......@@ -398,6 +443,10 @@ class Platform(notifier.Notifier):
@property
@deprecated.deprecated(
'3.6.0',
'4.0.0',
'Equivalent functionality is available in fsleyes-widgets.')
def glIsSoftwareRenderer(self):
"""Returns ``True`` if the OpenGL renderer is software based,
``False`` otherwise, or ``None`` if the renderer has not yet been set.
......
......@@ -421,7 +421,7 @@ class Settings(object):
try:
with open(configFile, 'wb') as f:
pickle.dump(config, f, protocol=2)
except (IOError, pickle.PicklingError, EOFError):
except (IOError, pickle.PicklingError, EOFError, FileNotFoundError):
log.warning('Unable to save {} configuration file '
'{}'.format(self.__configID, configFile),
exc_info=True)
......@@ -38,6 +38,11 @@ def _run_with_wx(func, *args, **kwargs):
if callAfterApp is not None:
callAfterApp()
# canHaveGui caches its return val,
# so clear it otherwise we may
# affect subsequent tests
idle._canHaveGui.cache_clear()
def wrap():
try:
......@@ -64,6 +69,8 @@ def _run_with_wx(func, *args, **kwargs):
idle.idleLoop.reset()
idle._canHaveGui.cache_clear()
if raised[0] and propagateRaise:
raise raised[0]
......@@ -413,10 +420,9 @@ def test_idle_alwaysQueue4():
import fsl.utils.platform
with mock.patch.dict('sys.modules', {'wx' : None}):
# idle uses the platform module to
# determine whether a GUI is available,
# so we have to reload it
reload_module(fsl.utils.platform)
# The idle._canHaveGui caches its result,
# so we need to invalidate it
idle._canHaveGui.cache_clear()
idle.idle(task, alwaysQueue=True)
with pytest.raises(ImportError):
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment