Skip to content

Commit

Permalink
Make TraitsUI, Pyface and configobj optional dependencies (#351)
Browse files Browse the repository at this point in the history
Apptools contains several disparate packages with different needs. While
it's somewhat reasonable to regard Traits as a core dependency, not all
subpackages need a GUI, and only the preferences package makes use of
configobj.

This PR:

* makes all three of TraitsUI, Pyface and configobj optional
dependencies
* adds a "gui" entry for `extras_require` in `setup.py`
* adds a test workflow that runs the test suite with only the core
dependencies (i.e., Traits), to make sure that other tests are skipped
appropriately rather than failing

Closes #70 

Makes #86 obsolete.
  • Loading branch information
mdickinson authored Jul 4, 2024
1 parent b559b37 commit bd6689a
Show file tree
Hide file tree
Showing 10 changed files with 69 additions and 10 deletions.
29 changes: 29 additions & 0 deletions .github/workflows/test-minimal-dependencies.yml
Original file line number Diff line number Diff line change
@@ -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
4 changes: 2 additions & 2 deletions .github/workflows/test-with-pip.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down
11 changes: 11 additions & 0 deletions apptools/_testing/optional_dependencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -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")
6 changes: 5 additions & 1 deletion apptools/logger/plugin/tests/test_logger_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
3 changes: 3 additions & 0 deletions apptools/preferences/tests/test_preference_binding.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -43,6 +45,7 @@ def listener(event):
listener.new = event.new


@requires_configobj
class PreferenceBindingTestCase(unittest.TestCase):
""" Tests for preference bindings. """

Expand Down
2 changes: 2 additions & 0 deletions apptools/preferences/tests/test_preferences.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,15 @@
from importlib_resources import files

# Enthought library imports.
from apptools._testing.optional_dependencies import requires_configobj
from apptools.preferences.api import Preferences


# This module's package.
PKG = "apptools.preferences.tests"


@requires_configobj
class PreferencesTestCase(unittest.TestCase):
""" Tests for preferences nodes. """

Expand Down
3 changes: 3 additions & 0 deletions apptools/preferences/tests/test_preferences_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -53,6 +55,7 @@ def bgcolor_listener(event):
PKG = "apptools.preferences.tests"


@requires_configobj
class PreferencesHelperTestCase(unittest.TestCase):
""" Tests for the preferences helper. """

Expand Down
8 changes: 6 additions & 2 deletions apptools/preferences/ui/tests/test_preferences_page.py
Original file line number Diff line number Diff line change
Expand Up @@ -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."""

Expand Down
3 changes: 3 additions & 0 deletions docs/releases/upcoming/351.build.rst
Original file line number Diff line number Diff line change
@@ -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)
10 changes: 5 additions & 5 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit bd6689a

Please sign in to comment.