Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions .github/workflows/pytest.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,15 @@ on:
release:
types: [published]

env:
DEPLOY_WITH_PYTHON: 3.13

jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
matrix:
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
os: [ubuntu-latest, windows-latest, macOS-latest]
fail-fast: false
defaults:
Expand Down Expand Up @@ -49,10 +52,10 @@ jobs:
needs: [build]
steps:
- uses: actions/checkout@v4
- name: "Set up Python 3.11"
- name: Set up Python ${{ env.DEPLOY_WITH_PYTHON }}
uses: actions/setup-python@v5
with:
python-version: "3.11"
python-version: ${{ env.DEPLOY_WITH_PYTHON }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/quartodoc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@ jobs:
- name: Set up Quarto
uses: quarto-dev/quarto-actions/setup@v2

- name: Set up Python 3.11
- name: Set up Python 3.13
uses: actions/setup-python@v5
with:
python-version: "3.11"
python-version: "3.13"
- name: Upgrade pip
run: |
python -m pip install --upgrade pip
Expand Down
4 changes: 2 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [UNRELEASED]

### Bug fixes

* The theme picker's message warning users to include `shinyswatch.theme_picker_server()` is now correctly hidden if the app takes longer than expected to start up. (#47)

* shinyswatch now requires [Shiny v1.2.0](https://shiny.posit.co/blog/posts/shiny-python-1.2/). (#48)

## [0.7.0] - 2024-07-18

### Breaking changes
Expand Down
3 changes: 1 addition & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -129,5 +129,4 @@ format:
isort .

update-bootswatch:
Rscript scripts/update_bootswatch.R
$(MAKE) format
python3 scripts/update_themes.py
5 changes: 3 additions & 2 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@ classifiers =
Intended Audience :: Developers
License :: OSI Approved :: MIT License
Programming Language :: Python
Programming Language :: Python :: 3.8
Programming Language :: Python :: 3.9
Programming Language :: Python :: 3.10
Programming Language :: Python :: 3.11
Programming Language :: Python :: 3.12
Programming Language :: Python :: 3.13
Programming Language :: Python :: Implementation :: PyPy
Topic :: Internet :: WWW/HTTP :: Dynamic Content
Topic :: Software Development :: Libraries :: Python Modules
Expand All @@ -38,7 +39,7 @@ install_requires =
typing-extensions>=3.10.0.0
packaging>=20.9
htmltools>=0.2.0
shiny>=1.0.0
shiny>=1.2.0
tests_require =
pytest>=3
zip_safe = False
Expand Down
2 changes: 1 addition & 1 deletion shinyswatch/_theme_picker.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ async def _():
theme = ui.Theme(preset=input.shinyswatch_theme_picker())

if theme is not None:
dep = theme._html_dependency() # pyright: ignore[reportPrivateUsage]
dep = theme._html_dependencies() # pyright: ignore[reportPrivateUsage]
dep = session._process_ui(dep)[ # pyright: ignore[reportPrivateUsage]
"deps"
][0]
Expand Down
14 changes: 14 additions & 0 deletions shinyswatch/_theme_shinyswatch.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import os

from htmltools import HTMLDependency
from shiny.ui import Theme

from ._assert import assert_theme
Expand Down Expand Up @@ -75,3 +76,16 @@ def _dep_css_precompiled_path(self) -> str:
self.name,
self._dep_css_name(),
)

def _html_dependency(self) -> HTMLDependency:
"""
For backwards-compatibility with previous versions of shinyswatch.
"""

# Shiny v1.2.0 renamed the `_html_dependency()` method to `_html_dependencies()`
# to allow Theme sub-classes to append dependencies. shinyswatch doesn't rely on
# that behavior, but we did advertise usage of the `_html_dependency()` method,
# so this shim is included to avoid breaking potential existing uses of the
# method.

return self._html_dependencies()[0]
2 changes: 1 addition & 1 deletion shinyswatch/bsw5/cerulean/bootswatch.min.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion shinyswatch/bsw5/cosmo/bootswatch.min.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion shinyswatch/bsw5/cyborg/bootswatch.min.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion shinyswatch/bsw5/darkly/bootswatch.min.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion shinyswatch/bsw5/flatly/bootswatch.min.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion shinyswatch/bsw5/journal/bootswatch.min.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion shinyswatch/bsw5/litera/bootswatch.min.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion shinyswatch/bsw5/lumen/bootswatch.min.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion shinyswatch/bsw5/lux/bootswatch.min.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion shinyswatch/bsw5/materia/bootswatch.min.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion shinyswatch/bsw5/minty/bootswatch.min.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion shinyswatch/bsw5/morph/bootswatch.min.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion shinyswatch/bsw5/pulse/bootswatch.min.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion shinyswatch/bsw5/quartz/bootswatch.min.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion shinyswatch/bsw5/sandstone/bootswatch.min.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion shinyswatch/bsw5/simplex/bootswatch.min.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion shinyswatch/bsw5/sketchy/bootswatch.min.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion shinyswatch/bsw5/slate/bootswatch.min.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion shinyswatch/bsw5/solar/bootswatch.min.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion shinyswatch/bsw5/spacelab/bootswatch.min.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion shinyswatch/bsw5/superhero/bootswatch.min.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion shinyswatch/bsw5/united/bootswatch.min.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion shinyswatch/bsw5/vapor/bootswatch.min.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion shinyswatch/bsw5/yeti/bootswatch.min.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion shinyswatch/bsw5/zephyr/bootswatch.min.css

Large diffs are not rendered by default.

35 changes: 26 additions & 9 deletions tests/test_theme_picker.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,42 @@
from shinyswatch._bsw5 import BSW5_THEME_NAME, bsw5_themes


def get_theme_deps(theme: shiny.ui.Theme) -> htmltools.HTMLDependency:
if hasattr(theme, "_html_dependency"):
# shiny < v1.2.0
deps = getattr(theme, "_html_dependency")()
else:
deps = getattr(theme, "_html_dependencies")()
# In shiny >= v1.2.0, `_html_dependencies()` returns a list of deps, but for
# shinyswatch we're expecting the default case to be a single dependency.
assert isinstance(deps, list)
assert len(deps) == 1
deps = deps[0]

return deps


Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code is unused

Suggested change
def get_theme_deps(theme: shiny.ui.Theme) -> htmltools.HTMLDependency:
if hasattr(theme, "_html_dependency"):
# shiny < v1.2.0
deps = getattr(theme, "_html_dependency")()
else:
deps = getattr(theme, "_html_dependencies")()
# In shiny >= v1.2.0, `_html_dependencies()` returns a list of deps, but for
# shinyswatch we're expecting the default case to be a single dependency.
assert isinstance(deps, list)
assert len(deps) == 1
deps = deps[0]
return deps

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or did you want to use this method within the package and then we can relax our shiny version requirement?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I originally had an implementation that let us relax that shiny version requirement that I took out on second thought. On the balance, I don't think it's worth maintaining the additional logic, which was repeated in a few places with slight variations because constraints and uses were different.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed unused code in cbcdb28

def test_theme_picker_deprecated_default():
with pytest.warns(RuntimeWarning, match="deprecated"):
shinyswatch.theme_picker_ui(default="deprecated") # type: ignore


@pytest.mark.parametrize("name", bsw5_themes)
def test_theme_picker_expects_single_stylesheet_shinyswatch(name: BSW5_THEME_NAME):
deps = shinyswatch.get_theme(name)._html_dependency()
def expect_single_stylesheet(theme: shiny.ui.Theme):
deps = theme._html_dependencies()
assert isinstance(deps, list)
assert len(deps) == 1

deps = deps[0]
assert isinstance(deps, htmltools.HTMLDependency)
# We expect that the shiny.ui.Theme() is a dependency containing a single stylesheet
assert len(deps.stylesheet) == 1
assert len(deps.script) == 0


def test_theme_picker_expects_single_stylesheet_shiny():
deps = shiny.ui.Theme()._html_dependency()
@pytest.mark.parametrize("name", bsw5_themes)
def test_theme_picker_expects_single_stylesheet_shinyswatch(name: BSW5_THEME_NAME):
expect_single_stylesheet(shinyswatch.get_theme(name))

assert isinstance(deps, htmltools.HTMLDependency)
# We expect that the shiny.ui.Theme() is a dependency containing a single stylesheet
assert len(deps.stylesheet) == 1
assert len(deps.script) == 0

def test_theme_picker_expects_single_stylesheet_shiny():
expect_single_stylesheet(shiny.ui.Theme())