Skip to content

Commit

Permalink
Merge pull request #41 from ericpre/lazy_import
Browse files Browse the repository at this point in the history
Lazy import
  • Loading branch information
ericpre authored Apr 7, 2022
2 parents 00f8c9a + 0b47c5e commit a25e662
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 34 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
strategy:
fail-fast: false
matrix:
PYTHON_VERSION: [3.6, 3.7, 3.9]
PYTHON_VERSION: [3.7, 3.9]
PIP_SELECTOR: ['[tests]']
LABEL: [-RnM]
include:
Expand Down
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
* Add `is_binned` to axis GUI, make index of the navigation axis editable ([#39](https://github.com/hyperspy/hyperspy_gui_traitsui/pull/39)).
* Fix loading GUI ([#38](https://github.com/hyperspy/hyperspy_gui_traitsui/pull/38)).
* Improve rendering changelog on github and fix hyperlinks in `README.md` ([#42](https://github.com/hyperspy/hyperspy_gui_traitsui/pull/42)).
* Speed up import time by importing submodules lazily ([#41](https://github.com/hyperspy/hyperspy_gui_traitsui/pull/41))

## v1.4.0 (2021-04-13)

Expand Down
54 changes: 35 additions & 19 deletions hyperspy_gui_traitsui/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,24 +16,51 @@
# You should have received a copy of the GNU General Public License
# along with HyperSpy. If not, see <http://www.gnu.org/licenses/>.

from hyperspy_gui_traitsui.version import __version__

import importlib
import logging

import matplotlib
from traits.etsconfig.api import ETSConfig

from hyperspy.defaults_parser import preferences


_logger = logging.getLogger(__name__)
__all__ = [
'axes',
'messages',
'microscope_parameters',
'model',
'preferences',
'tools',
'__version__',
]


_logger.debug("Initial ETS toolkit set to {}".format(ETSConfig.toolkit))
# mapping following the pattern: from value import key
_import_mapping = {
'__version__':'.version',
}


def __dir__():
return sorted(__all__)


def __getattr__(name):
if name in __all__:
if name in _import_mapping.keys():
import_path = 'hyperspy_gui_traitsui' + _import_mapping.get(name)
return getattr(importlib.import_module(import_path), name)
else:
return importlib.import_module("." + name, 'hyperspy_gui_traitsui')

raise AttributeError(f"module {__name__!r} has no attribute {name!r}")


_logger = logging.getLogger(__name__)
_logger.debug("Initial ETS toolkit set to {}".format(ETSConfig.toolkit))

WARN = (
not hasattr(preferences.GUIs, "warn_if_guis_are_missing") # hspy < v.1.3.1
or preferences.GUIs.warn_if_guis_are_missing)

def set_ets_toolkit(toolkit):
try:
Expand All @@ -51,6 +78,7 @@ def set_ets_toolkit(toolkit):
_logger.debug("Setting ETS toolkit to %s failed" % toolkit)
set_ets_toolkit("null")


# Get the backend from matplotlib
backend = matplotlib.get_backend()
_logger.debug('Loading hyperspy.traitsui_gui')
Expand All @@ -63,21 +91,9 @@ def set_ets_toolkit(toolkit):
# The toolkit has not been set and no supported toolkit is available, so
# setting it to "null"
set_ets_toolkit("null")
if WARN:
if preferences.GUIs.warn_if_guis_are_missing:
_logger.warning(
f"The {backend} matplotlib backend is not compatible with the "
"traitsui GUI elements. For more information, read "
"http://hyperspy.readthedocs.io/en/stable/user_guide/getting_started.html#possible-warnings-when-importing-hyperspy"
".")

if ETSConfig.toolkit and ETSConfig.toolkit != "null":
import hyperspy.api_nogui # necessary to register the toolkeys
# Register the GUI elements
import hyperspy_gui_traitsui.axes
import hyperspy_gui_traitsui.model
import hyperspy_gui_traitsui.tools
import hyperspy_gui_traitsui.preferences
import hyperspy_gui_traitsui.microscope_parameters
import hyperspy_gui_traitsui.messages
elif WARN:
_logger.warning("The traitsui GUI elements are not available.")
57 changes: 44 additions & 13 deletions hyperspy_gui_traitsui/tests/test_import.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,49 @@
import unittest
import pytest

import hyperspy.api as hs
import hyperspy.ui_registry


class Test(unittest.TestCase):

def test_registry(self):
if "traitsui" in hyperspy.ui_registry.TOOLKIT_REGISTRY:
self.assertTrue("traitsui" in hyperspy.ui_registry.TOOLKIT_REGISTRY)
def test_ui_registry():
if "traitsui" in hyperspy.ui_registry.TOOLKIT_REGISTRY:
assert "traitsui" in hyperspy.ui_registry.TOOLKIT_REGISTRY
else:
if "ipywidgets" in hyperspy.ui_registry.TOOLKIT_REGISTRY:
with pytest.raises(ValueError):
hs.preferences.gui(toolkit="traitsui")
else:
if "ipywidgets" in hyperspy.ui_registry.TOOLKIT_REGISTRY:
with self.assertRaises(ValueError):
hs.preferences.gui(toolkit="traitsui")
else:
# As ipywidgets is not installed it should raise an import error
with self.assertRaises(ImportError):
hs.preferences.gui(toolkit="traitsui")
# As ipywidgets is not installed it should raise an import error
with pytest.raises(ImportError):
hs.preferences.gui(toolkit="traitsui")


def test_import_version():
from hyperspy_gui_traitsui import __version__


def test_import():
import hyperspy_gui_traitsui
for obj_name in hyperspy_gui_traitsui.__all__:
getattr(hyperspy_gui_traitsui, obj_name)


def test_import_import_error():
import hyperspy_gui_traitsui
try:
hyperspy_gui_traitsui.inexisting_module
except AttributeError:
pass


def test_dir():
import hyperspy_gui_traitsui
d = dir(hyperspy_gui_traitsui)
assert d == [
'__version__',
'axes',
'messages',
'microscope_parameters',
'model',
'preferences',
'tools',
]
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@
# See https://pypi.python.org/pypi?%3Aaction=list_classifiers
classifiers=[
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
Expand Down Expand Up @@ -82,6 +81,7 @@
# your project is installed. For an analysis of "install_requires" vs pip's
# requirements files see:
# https://packaging.python.org/en/latest/requirements.html
python_requires='~=3.7',
install_requires=['hyperspy>=1.6.2', 'traitsui>=6.0'],
extras_require={
'tests': ['pytest'],
Expand Down

0 comments on commit a25e662

Please sign in to comment.