diff --git a/.github/workflows/test-minimal-dependencies.yml b/.github/workflows/test-minimal-dependencies.yml new file mode 100644 index 00000000..7dd1938b --- /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] + 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 ".[test]" + - 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..6670d35e 100644 --- a/apptools/_testing/optional_dependencies.py +++ b/apptools/_testing/optional_dependencies.py @@ -45,3 +45,14 @@ 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..eb3fb839 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 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..06f068bc 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 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 8ef7681e..5f659b6a 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 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/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) 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