Skip to content

Commit

Permalink
Modernize scaffolding, drop py3.7, and add py3.12 (#13)
Browse files Browse the repository at this point in the history
Close #10

In addition to the notes in #10:

Add daily scheduled test run
  • Loading branch information
yanovs authored Feb 24, 2024
1 parent 85869dc commit ca3b679
Show file tree
Hide file tree
Showing 55 changed files with 157,276 additions and 112,470 deletions.
12 changes: 4 additions & 8 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ on:
branches: [main]
pull_request:
branches: [main]
schedule:
- cron: '0 5 * * *'

permissions:
contents: read
Expand All @@ -25,7 +27,7 @@ jobs:
- ubuntu-latest
- macos-latest
- windows-latest
python-version: ['3.7', '3.8', '3.9', '3.10', '3.11', 'pypy-3.8']
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12', 'pypy-3.8']

steps:
- name: Check out code
Expand All @@ -43,13 +45,7 @@ jobs:
- name: Test with nox
run: nox
if: ${{ (matrix.python-version != '3.7') && ! (matrix.platform == 'windows-latest' && matrix.python-version == 'pypy-3.8') }}

# Skip type checkers on py3.7 because those package versions
# yield different results
- name: Test with nox (py3.7)
run: nox -s black pytest ruff
if: ${{ matrix.python-version == '3.7' }}
if: ${{ ! (matrix.platform == 'windows-latest' && matrix.python-version == 'pypy-3.8') }}

# TODO: Run tests on windows/pypy-3.8

Expand Down
15 changes: 11 additions & 4 deletions leda/gen/base.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from __future__ import annotations

import abc
import dataclasses
import datetime
import logging
Expand All @@ -8,6 +9,7 @@

import cached_property
import nbformat
from typing_extensions import override

logger = logging.getLogger(__name__)
logger.addHandler(logging.NullHandler())
Expand Down Expand Up @@ -74,6 +76,7 @@ class _FileReport:
@dataclasses.dataclass(frozen=True)
class FileReport(Report, _FileReport):
@property
@override
def handle(self) -> str | IO:
logger.info("Reading %s", self.nb_path)
return str(self.nb_path.expanduser())
Expand All @@ -100,25 +103,29 @@ class ReportArtifact:

@dataclasses.dataclass()
class ReportGenerator:
@abc.abstractmethod
def generate(
self, nb_contents: nbformat.NotebookNode, nb_name: str | None = None
) -> bytes:
raise NotImplementedError
...


@dataclasses.dataclass()
class ReportPublisher:
@abc.abstractmethod
def publish(self, report: Report, artifact: ReportArtifact) -> str | None:
raise NotImplementedError
...


@dataclasses.dataclass()
class ReportRunner:
@abc.abstractmethod
def run(self, report: Report) -> str | None:
raise NotImplementedError
...


@dataclasses.dataclass()
class ReportSetRunner:
@abc.abstractmethod
def run(self, report_set: ReportSet) -> None:
raise NotImplementedError
...
8 changes: 6 additions & 2 deletions leda/gen/generators.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import termcolor
import tqdm
import traitlets
from typing_extensions import override

import leda.gen.base

Expand All @@ -35,6 +36,7 @@ def __init__(self, **kwargs: Any) -> None:
self._num_cells: int | None = None
self._pbar: tqdm.tqdm | None = None

@override
def preprocess(
self,
nb: nbformat.NotebookNode,
Expand All @@ -49,11 +51,12 @@ def preprocess(

return result

@override
def preprocess_cell(
self,
cell: nbformat.NotebookNode,
resources: dict,
cell_index: int,
index: int,
store_history: bool = True,
) -> tuple[nbformat.NotebookNode, dict]:
if self._pbar is None:
Expand All @@ -71,7 +74,7 @@ def preprocess_cell(
self._pbar.set_postfix_str(first_line)

# Note that preprocess_cell() will actually run the cell
result = super().preprocess_cell(cell, resources, cell_index)
result = super().preprocess_cell(cell, resources, index)
self._pbar.update(1)

return result # type: ignore[no-any-return]
Expand Down Expand Up @@ -137,6 +140,7 @@ def _get_exporter_kwargs(self) -> dict:

return exporter_kwargs

@override
def generate(
self,
nb_contents: nbformat.NotebookNode,
Expand Down
3 changes: 3 additions & 0 deletions leda/gen/modifiers.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from typing import ClassVar

import nbformat
from typing_extensions import override

import leda.gen.base

Expand Down Expand Up @@ -134,6 +135,7 @@ def _get_new_cells_bottom(self) -> list[nbformat.NotebookNode]:
),
]

@override
def modify(self, nb_contents: nbformat.NotebookNode) -> None:
logger.info("Modifying notebook")
self._check_nb(nb_contents)
Expand Down Expand Up @@ -190,6 +192,7 @@ def __post_init__(self) -> None:
local_img_dir_path = self.local_dir_path / "images"
local_img_dir_path.mkdir(parents=True, exist_ok=True)

@override
def _get_new_cells_top(self) -> list[nbformat.NotebookNode]:
new_cells = super()._get_new_cells_top()

Expand Down
4 changes: 4 additions & 0 deletions leda/gen/publishers.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import logging
import pathlib

from typing_extensions import override

import leda.gen.base

logger = logging.getLogger(__name__)
Expand All @@ -20,6 +22,7 @@ def log_loudly(report_url: str) -> None:
class InMemoryReportPublisher(leda.gen.base.ReportPublisher):
artifact: leda.gen.base.ReportArtifact | None = None

@override
def publish(
self,
report: leda.gen.base.Report,
Expand All @@ -32,6 +35,7 @@ def publish(
class FileReportPublisher(leda.gen.base.ReportPublisher):
output_dir: pathlib.Path

@override
def publish(
self,
report: leda.gen.base.Report,
Expand Down
2 changes: 2 additions & 0 deletions leda/gen/runners.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from typing import Optional, cast

import nbformat
from typing_extensions import override

import leda.gen.base
import leda.gen.generators
Expand All @@ -22,6 +23,7 @@ class MainReportRunner(leda.gen.base.ReportRunner):
generator: leda.gen.base.ReportGenerator
publisher: leda.gen.base.ReportPublisher

@override
def run(self, report: leda.gen.base.Report) -> str | None:
nb_contents = nbformat.read(report.handle, as_version=4)

Expand Down
5 changes: 5 additions & 0 deletions leda/interact/dynamic.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from typing import Any, Callable

import ipywidgets
from typing_extensions import override

import leda.interact.base

Expand All @@ -25,21 +26,25 @@ def to_dynamic_ipywidgets(values: dict[str, Any]) -> dict[str, Any]:

class DynamicIpywidgetsInteractMode(leda.interact.base.InteractMode):
@property
@override
def dynamic(self) -> bool:
return True

@override
def init(self, plot_lib: str) -> None:
if plot_lib.lower() == "matplotlib":
import matplotlib.pyplot as plt

# Turn on interactive mode
plt.ion()

@override
def interact(self, func: Callable, **kwargs: Any) -> Any:
kwargs = to_dynamic_ipywidgets(kwargs)

return ipywidgets.interact(func, **kwargs)

@override
def process_result(self, obj: Any) -> Any:
if leda.interact.base.is_plotly(obj):
obj.show()
Expand Down
6 changes: 6 additions & 0 deletions leda/interact/panel.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import dataclasses
from typing import Any, Callable, Optional

from typing_extensions import override

import leda.interact.base
import leda.interact.core

Expand All @@ -12,9 +14,11 @@ class StaticPanelInteractMode(leda.interact.base.InteractMode):
_plot_lib: Optional[str] = dataclasses.field(default=None, init=False)

@property
@override
def dynamic(self) -> bool:
return False

@override
def init(self, plot_lib: str) -> None:
self._plot_lib = plot_lib.lower()
if self._plot_lib == "matplotlib":
Expand All @@ -39,6 +43,7 @@ def init(self, plot_lib: str) -> None:

pn.extension(pn_extension, safe_embed=True) # pyright: ignore

@override
def interact(self, func: Callable, **kwargs: Any) -> Any:
import panel as pn

Expand All @@ -57,6 +62,7 @@ def interact(self, func: Callable, **kwargs: Any) -> Any:
max_states=500, max_opts=500, progress=self.progress
)

@override
def process_result(self, obj: Any) -> Any:
import panel as pn

Expand Down
5 changes: 5 additions & 0 deletions leda/interact/static_ipywidgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from typing import Any, Callable, Optional

import ipywidgets
from typing_extensions import override

import leda.interact.base
import leda.interact.core
Expand All @@ -14,9 +15,11 @@ class StaticIpywidgetsInteractMode(leda.interact.base.InteractMode):
_plot_lib: Optional[str] = dataclasses.field(default=None, init=False)

@property
@override
def dynamic(self) -> bool:
return False

@override
def init(self, plot_lib: str) -> None:
self._plot_lib = plot_lib.lower()
if self._plot_lib == "matplotlib":
Expand All @@ -30,6 +33,7 @@ def init(self, plot_lib: str) -> None:
raise ValueError(self._plot_lib)

# noinspection PyProtectedMember
@override
def interact(self, func: Callable, **kwargs: Any) -> Any:
new_value: static_ipywidgets.widgets.StaticWidget

Expand Down Expand Up @@ -59,6 +63,7 @@ def interact(self, func: Callable, **kwargs: Any) -> Any:

return static_ipywidgets.interact.StaticInteract(func, **kwargs)

@override
def process_result(self, obj: Any) -> Any:
if leda.interact.base.is_matplotlib(obj):
import matplotlib.pyplot as plt
Expand Down
Loading

0 comments on commit ca3b679

Please sign in to comment.