From 69f22b410046282128ecdc3297ae804013599f08 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Fri, 28 Jun 2024 17:29:23 +0100 Subject: [PATCH 1/5] Make TraitsUI, Pyface and configobj optional dependencies --- .../workflows/test-minimal-dependencies.yml | 29 +++++++++++++++++++ .github/workflows/test-with-pip.yml | 4 +-- apptools/_testing/optional_dependencies.py | 9 ++++++ .../plugin/tests/test_logger_service.py | 6 +++- .../tests/test_preference_binding.py | 3 ++ .../preferences/tests/test_preferences.py | 2 ++ .../tests/test_preferences_helper.py | 3 ++ .../ui/tests/test_preferences_page.py | 8 +++-- setup.py | 10 +++---- 9 files changed, 64 insertions(+), 10 deletions(-) create mode 100644 .github/workflows/test-minimal-dependencies.yml diff --git a/.github/workflows/test-minimal-dependencies.yml b/.github/workflows/test-minimal-dependencies.yml new file mode 100644 index 00000000..036bd3b6 --- /dev/null +++ b/.github/workflows/test-minimal-dependencies.yml @@ -0,0 +1,29 @@ +name: Test with minimal dependencies + +on: +- pull_request +- workflow_dispatch + +jobs: + tests: + strategy: + matrix: + os: [ubuntu-latest, windows-latest, macos-latest] + python-version: ['3.8', '3.9', '3.10', '3.11', '3.12'] + + runs-on: ${{ matrix.os }} + + steps: + - name: Get apptools source + uses: actions/checkout@v4 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + - name: Install local package + run: python -m pip install . + - name: Run tests + run: | + mkdir testdir + cd testdir + python -m unittest discover -v apptools diff --git a/.github/workflows/test-with-pip.yml b/.github/workflows/test-with-pip.yml index 3bd3d939..f9b0e23e 100644 --- a/.github/workflows/test-with-pip.yml +++ b/.github/workflows/test-with-pip.yml @@ -21,10 +21,10 @@ jobs: with: python-version: ${{ matrix.python-version }} - name: Install dependencies and local packages (not macOS) - run: python -m pip install .[h5,preferences] + run: python -m pip install .[gui,h5,preferences] if: matrix.os != 'macos-latest' - name: Install dependencies and local packages (macOS) - run: python -m pip install .[preferences] + run: python -m pip install .[gui,preferences] # PyTables currently won't build on Apple Silicon, so exclude the h5 deps # xref: enthought/apptools/issues/344 if: matrix.os == 'macos-latest' diff --git a/apptools/_testing/optional_dependencies.py b/apptools/_testing/optional_dependencies.py index 3b88b17f..6c7cc596 100644 --- a/apptools/_testing/optional_dependencies.py +++ b/apptools/_testing/optional_dependencies.py @@ -45,3 +45,12 @@ def optional_import(name): tables = optional_import("tables") requires_tables = unittest.skipIf(tables is None, "PyTables not available") + +configobj = optional_import("configobj") +requires_configobj = unittest.skipIf(configobj is None, "configobj not available") + +pyface = optional_import("pyface") +requires_pyface = unittest.skipIf(pyface is None, "Pyface not available") + +traitsui = optional_import("traitsui") +requires_traitsui = unittest.skipIf(traitsui is None, "TraitsUI not available") diff --git a/apptools/logger/plugin/tests/test_logger_service.py b/apptools/logger/plugin/tests/test_logger_service.py index 75957418..a20b8e3f 100644 --- a/apptools/logger/plugin/tests/test_logger_service.py +++ b/apptools/logger/plugin/tests/test_logger_service.py @@ -11,9 +11,13 @@ import unittest from unittest import mock -from apptools.logger.plugin.logger_service import LoggerService +from apptools._testing.optional_dependencies import pyface, requires_pyface +if pyface is not None: + from apptools.logger.plugin.logger_service import LoggerService + +@requires_pyface class LoggerServiceTestCase(unittest.TestCase): def test_create_email_message(self): logger_service = LoggerService() diff --git a/apptools/preferences/tests/test_preference_binding.py b/apptools/preferences/tests/test_preference_binding.py index 246fd012..93498948 100644 --- a/apptools/preferences/tests/test_preference_binding.py +++ b/apptools/preferences/tests/test_preference_binding.py @@ -26,6 +26,8 @@ from apptools.preferences.api import Preferences from apptools.preferences.api import bind_preference from apptools.preferences.api import set_default_preferences +from apptools._testing.optional_dependencies import configobj, requires_configobj + from traits.api import Bool, HasTraits, Int, Float, Str, TraitError from traits.observation.api import match @@ -43,6 +45,7 @@ def listener(event): listener.new = event.new +@requires_configobj class PreferenceBindingTestCase(unittest.TestCase): """ Tests for preference bindings. """ diff --git a/apptools/preferences/tests/test_preferences.py b/apptools/preferences/tests/test_preferences.py index 165f7c70..ab7fcaa0 100644 --- a/apptools/preferences/tests/test_preferences.py +++ b/apptools/preferences/tests/test_preferences.py @@ -23,6 +23,7 @@ from importlib_resources import files # Enthought library imports. +from apptools._testing.optional_dependencies import configobj, requires_configobj from apptools.preferences.api import Preferences @@ -30,6 +31,7 @@ PKG = "apptools.preferences.tests" +@requires_configobj class PreferencesTestCase(unittest.TestCase): """ Tests for preferences nodes. """ diff --git a/apptools/preferences/tests/test_preferences_helper.py b/apptools/preferences/tests/test_preferences_helper.py index f9b6fdd4..b48f8609 100644 --- a/apptools/preferences/tests/test_preferences_helper.py +++ b/apptools/preferences/tests/test_preferences_helper.py @@ -26,6 +26,8 @@ from apptools.preferences.api import Preferences, PreferencesHelper from apptools.preferences.api import ScopedPreferences from apptools.preferences.api import set_default_preferences +from apptools._testing.optional_dependencies import configobj, requires_configobj + from traits.api import ( Any, Bool, HasTraits, Int, Float, List, Str, TraitError, push_exception_handler, pop_exception_handler, @@ -53,6 +55,7 @@ def bgcolor_listener(event): PKG = "apptools.preferences.tests" +@requires_configobj class PreferencesHelperTestCase(unittest.TestCase): """ Tests for the preferences helper. """ diff --git a/apptools/preferences/ui/tests/test_preferences_page.py b/apptools/preferences/ui/tests/test_preferences_page.py index 9b8d572d..acc40f3e 100644 --- a/apptools/preferences/ui/tests/test_preferences_page.py +++ b/apptools/preferences/ui/tests/test_preferences_page.py @@ -16,12 +16,16 @@ pop_exception_handler, push_exception_handler, ) -from traitsui.api import Group, Item, View from apptools.preferences.api import Preferences -from apptools.preferences.ui.api import PreferencesPage +from apptools._testing.optional_dependencies import requires_traitsui, traitsui +if traitsui is not None: + from traitsui.api import Group, Item, View + from apptools.preferences.ui.api import PreferencesPage + +@requires_traitsui class TestPreferencesPage(unittest.TestCase): """ Non-GUI Tests for PreferencesPage.""" diff --git a/setup.py b/setup.py index cbd412e3..a33a8801 100644 --- a/setup.py +++ b/setup.py @@ -302,16 +302,16 @@ def get_long_description(): 'preferences/tests/*.ini' ] }, - install_requires=[ - 'configobj', - 'traits>=6.2.0', - 'traitsui', - ], + install_requires=['traits>=6.2.0'], extras_require={ "docs": ["enthought-sphinx-theme", "sphinx"], "test": [ "importlib-resources>=1.1.0; python_version<'3.9'", ], + "gui": [ + "pyface", + "traitsui", + ], "h5": [ # PyTables is currently incompatible with NumPy 2.0 # xref: enthought/apptools#345 From d0f81a952b983d12cba6e95d2b83f6bf4a2ae91a Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Fri, 28 Jun 2024 17:35:06 +0100 Subject: [PATCH 2/5] Add news fragment --- docs/releases/upcoming/351.build.rst | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 docs/releases/upcoming/351.build.rst diff --git a/docs/releases/upcoming/351.build.rst b/docs/releases/upcoming/351.build.rst new file mode 100644 index 00000000..324423c5 --- /dev/null +++ b/docs/releases/upcoming/351.build.rst @@ -0,0 +1,3 @@ +TraitsUI, Pyface and configobj are now optional dependencies. TraitsUI +and Pyface will be installed with ``pip install apptools[gui]``. configobj +will be installed with ``pip install apptools[preferences]``. (#351) From 106b73a5aadfea2e29bad066b4e14997334730d0 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Fri, 28 Jun 2024 17:39:07 +0100 Subject: [PATCH 3/5] We still need importlib_resources for testing --- .github/workflows/test-minimal-dependencies.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test-minimal-dependencies.yml b/.github/workflows/test-minimal-dependencies.yml index 036bd3b6..cbbf30f5 100644 --- a/.github/workflows/test-minimal-dependencies.yml +++ b/.github/workflows/test-minimal-dependencies.yml @@ -21,7 +21,7 @@ jobs: with: python-version: ${{ matrix.python-version }} - name: Install local package - run: python -m pip install . + run: python -m pip install ".[test]" - name: Run tests run: | mkdir testdir From 79b91c298e4e3450c04feb7b8d2f33bf47b17dc2 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Fri, 28 Jun 2024 17:40:24 +0100 Subject: [PATCH 4/5] It should be enough to just test on Linux --- .github/workflows/test-minimal-dependencies.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test-minimal-dependencies.yml b/.github/workflows/test-minimal-dependencies.yml index cbbf30f5..7dd1938b 100644 --- a/.github/workflows/test-minimal-dependencies.yml +++ b/.github/workflows/test-minimal-dependencies.yml @@ -8,7 +8,7 @@ jobs: tests: strategy: matrix: - os: [ubuntu-latest, windows-latest, macos-latest] + os: [ubuntu-latest] python-version: ['3.8', '3.9', '3.10', '3.11', '3.12'] runs-on: ${{ matrix.os }} From b7eee4dcabf4df7b155de3a75f2e8823cad4e577 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Fri, 28 Jun 2024 17:44:04 +0100 Subject: [PATCH 5/5] Remove unused imports; fix long lines --- apptools/_testing/optional_dependencies.py | 4 +++- apptools/preferences/tests/test_preference_binding.py | 2 +- apptools/preferences/tests/test_preferences.py | 2 +- apptools/preferences/tests/test_preferences_helper.py | 2 +- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/apptools/_testing/optional_dependencies.py b/apptools/_testing/optional_dependencies.py index 6c7cc596..6670d35e 100644 --- a/apptools/_testing/optional_dependencies.py +++ b/apptools/_testing/optional_dependencies.py @@ -47,7 +47,9 @@ def optional_import(name): requires_tables = unittest.skipIf(tables is None, "PyTables not available") configobj = optional_import("configobj") -requires_configobj = unittest.skipIf(configobj is None, "configobj not available") +requires_configobj = unittest.skipIf( + configobj is None, "configobj not available" +) pyface = optional_import("pyface") requires_pyface = unittest.skipIf(pyface is None, "Pyface not available") diff --git a/apptools/preferences/tests/test_preference_binding.py b/apptools/preferences/tests/test_preference_binding.py index 93498948..eb3fb839 100644 --- a/apptools/preferences/tests/test_preference_binding.py +++ b/apptools/preferences/tests/test_preference_binding.py @@ -26,7 +26,7 @@ from apptools.preferences.api import Preferences from apptools.preferences.api import bind_preference from apptools.preferences.api import set_default_preferences -from apptools._testing.optional_dependencies import configobj, requires_configobj +from apptools._testing.optional_dependencies import requires_configobj from traits.api import Bool, HasTraits, Int, Float, Str, TraitError from traits.observation.api import match diff --git a/apptools/preferences/tests/test_preferences.py b/apptools/preferences/tests/test_preferences.py index ab7fcaa0..06f068bc 100644 --- a/apptools/preferences/tests/test_preferences.py +++ b/apptools/preferences/tests/test_preferences.py @@ -23,7 +23,7 @@ from importlib_resources import files # Enthought library imports. -from apptools._testing.optional_dependencies import configobj, requires_configobj +from apptools._testing.optional_dependencies import requires_configobj from apptools.preferences.api import Preferences diff --git a/apptools/preferences/tests/test_preferences_helper.py b/apptools/preferences/tests/test_preferences_helper.py index b48f8609..64e0a77c 100644 --- a/apptools/preferences/tests/test_preferences_helper.py +++ b/apptools/preferences/tests/test_preferences_helper.py @@ -26,7 +26,7 @@ from apptools.preferences.api import Preferences, PreferencesHelper from apptools.preferences.api import ScopedPreferences from apptools.preferences.api import set_default_preferences -from apptools._testing.optional_dependencies import configobj, requires_configobj +from apptools._testing.optional_dependencies import requires_configobj from traits.api import ( Any, Bool, HasTraits, Int, Float, List, Str, TraitError,