diff --git a/.github/workflows/codequality.yaml b/.github/workflows/codequality.yaml index fdb486f..8d0dd21 100644 --- a/.github/workflows/codequality.yaml +++ b/.github/workflows/codequality.yaml @@ -1,33 +1,26 @@ name: Code quality - on: - - push - - pull_request - - workflow_dispatch + workflow_call: + workflow_dispatch: jobs: - build: + code-quality: runs-on: ubuntu-20.04 strategy: fail-fast: false matrix: - python-version: [3.7, 3.8, 3.9, "3.10", "3.11"] + python-version: [3.8, 3.9, "3.10", "3.11"] # pre-commit does not support Python < 3.8 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - - name: Downgrade pip - run: pip install "pip<22" - name: Install dependencies run: | - pip install ".[dev]" "mypy<1" "black<23" - mypy --install-types --non-interactive reacton - - name: Run black - run: black reacton - - name: Run flake - run: flake8 reacton - - name: mypy - run: mypy reacton + pip install ".[dev]" + - name: Install pre-commit + run: pre-commit install + - name: Run pre-commit + run: pre-commit run --all-files diff --git a/.github/workflows/installation.yml b/.github/workflows/installation.yml index 379497d..d774d16 100644 --- a/.github/workflows/installation.yml +++ b/.github/workflows/installation.yml @@ -1,25 +1,28 @@ name: Test installation on: - - push - - pull_request - - workflow_dispatch + workflow_call: + workflow_dispatch: jobs: - build: + test-installation: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Set up Python 3.7 - uses: actions/setup-python@v2 + uses: actions/setup-python@v5 with: python-version: 3.7 - name: Install hatch - run: pip install hatch "pip<22" + run: pip install hatch - name: Build run: hatch build - name: Install run: pip install dist/*.whl - name: Test import run: python -c "import react_ipywidgets; import reacton" + - uses: actions/upload-artifact@v4 + with: + name: reacton-build-${{ github.run_number }} + path: ./dist diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index f3b7ac1..8db936f 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -6,12 +6,19 @@ on: - "*" jobs: - build: + test: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 + - uses: ./.github/workflows/unittest.yml + + release: + needs: test + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 - name: Set up Python 3.7 - uses: actions/setup-python@v2 + uses: actions/setup-python@v5 with: python-version: 3.7 - name: Install hatch @@ -29,7 +36,7 @@ jobs: run: | openssl sha256 dist/* hatch publish - - uses: actions/upload-artifact@v1 + - uses: actions/upload-artifact@v4 with: name: distributions path: ./dist diff --git a/.github/workflows/unittest.yml b/.github/workflows/unittest.yml index ae988f5..402302f 100644 --- a/.github/workflows/unittest.yml +++ b/.github/workflows/unittest.yml @@ -1,12 +1,21 @@ name: Unit testing on: - - push - - pull_request - - workflow_dispatch + push: + branches: + - master + pull_request: + workflow_dispatch: jobs: build: + uses: ./.github/workflows/installation.yml + + code-quality: + uses: ./.github/workflows/codequality.yaml + + unit-test: + needs: [build, code-quality] runs-on: ubuntu-20.04 strategy: fail-fast: false @@ -14,14 +23,17 @@ jobs: python-version: [3.6, 3.7, 3.8, 3.9, "3.10", "3.11"] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - - name: Downgrade pip - run: pip install "pip<22" + - uses: actions/download-artifact@v4 + with: + name: reacton-build-${{ github.run_number }} + path: ./dist - name: Install - run: pip install ".[dev]" "black<23" + run: | + pip install `echo dist/*.whl`[dev] "black<23" - name: test run: pytest --cov=reacton reacton diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 9ce4c8d..3663c20 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,26 +1,19 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v2.3.0 + rev: v5.0.0 hooks: - id: check-yaml args: [--unsafe] - id: end-of-file-fixer - id: trailing-whitespace - - repo: https://github.com/psf/black - rev: 22.3.0 + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.8.3 hooks: - - id: black - - repo: https://github.com/PyCQA/flake8 - rev: 3.9.2 - hooks: - - id: flake8 - - repo: https://github.com/PyCQA/isort - rev: 5.11.5 - hooks: - - id: isort - files: \.py$ - args: [--profile=black] + - id: ruff + stages: [pre-commit] + - id: ruff-format + stages: [pre-commit] - repo: https://github.com/pre-commit/mirrors-mypy - rev: "v0.942" # Use the sha / tag you want to point at + rev: "v1.13.0" # Use the sha / tag you want to point at hooks: - id: mypy diff --git a/notebooks/calculator.ipynb b/notebooks/calculator.ipynb index 286eca2..ebc35aa 100644 --- a/notebooks/calculator.ipynb +++ b/notebooks/calculator.ipynb @@ -137,7 +137,6 @@ " with w.VBox():\n", " w.Label(value=state.error or state.output or \"0\")\n", "\n", - " \n", " with w.HBox():\n", " if state.input:\n", " w.Button(description=\"C\", on_click=lambda: dispatch((\"clear\", None)))\n", @@ -157,6 +156,7 @@ " op = operator_map[op_symbol]\n", " w.Button(description=op_symbol, on_click=lambda op=op: dispatch((\"operator\", op)))\n", " with w.HBox():\n", + "\n", " def boom():\n", " print(\"boom\")\n", " raise ValueError(\"boom\")\n", @@ -170,7 +170,8 @@ "\n", " return main\n", "\n", - "Calculator()\n" + "\n", + "Calculator()" ] }, { @@ -225,6 +226,7 @@ " op = operator_map[op_symbol]\n", " v.BtnWithClick(children=op_symbol, color=\"primary\", on_click=lambda op=op: dispatch((\"operator\", op)), class_=class_)\n", " with w.HBox():\n", + "\n", " def boom():\n", " print(\"boom\")\n", " raise ValueError(\"boom\")\n", @@ -237,7 +239,9 @@ " v.BtnWithClick(children=\"=\", color=\"primary\", on_click=lambda: dispatch((\"calculate\", None)), class_=class_)\n", "\n", " return main\n", - "CalculatorVuetify()\n" + "\n", + "\n", + "CalculatorVuetify()" ] }, { diff --git a/notebooks/click-button.ipynb b/notebooks/click-button.ipynb index cc25311..9b380b0 100644 --- a/notebooks/click-button.ipynb +++ b/notebooks/click-button.ipynb @@ -26,11 +26,15 @@ "\n", "\n", "clicks = 0 # issue 3\n", + "\n", + "\n", "def on_click(button):\n", " global clicks # issue 3\n", " clicks += 1\n", - " button.description = f\"Clicked {clicks} times\" # issue 1\n", - "button = widgets.Button(description=\"Clicked 0 times\") # issue 1\n", + " button.description = f\"Clicked {clicks} times\" # issue 1\n", + "\n", + "\n", + "button = widgets.Button(description=\"Clicked 0 times\") # issue 1\n", "button.on_click(on_click) # issue 2\n", "display(button)" ] @@ -64,15 +68,15 @@ " # first render, this return 0, after that, the last argument\n", " # of set_clicks\n", " clicks, set_clicks = reacton.use_state(0)\n", - " \n", + "\n", " def my_click_handler():\n", " # trigger a new render with a new value for clicks\n", - " set_clicks(clicks+1)\n", + " set_clicks(clicks + 1)\n", "\n", - " button = w.Button(description=f\"Clicked {clicks} times\",\n", - " on_click=my_click_handler)\n", + " button = w.Button(description=f\"Clicked {clicks} times\", on_click=my_click_handler)\n", " return button\n", "\n", + "\n", "ButtonClick()" ] }, @@ -89,6 +93,8 @@ " slider = w.IntSlider(min=0, max=20, value=count, on_value=set_count)\n", " buttons = [ButtonClick() for i in range(count)]\n", " return w.VBox(children=[slider, *buttons])\n", + "\n", + "\n", "display(ManyButtons())" ] }, @@ -116,12 +122,16 @@ " # first render, this return 0, after that, the last argument\n", " # of set_clicks\n", " clicks, set_clicks = reacton.use_state(0)\n", + "\n", " def my_click_handler(*ignore_args):\n", " # trigger a new render with a new value for clicks\n", - " set_clicks(clicks+1)\n", + " set_clicks(clicks + 1)\n", + "\n", " button = rv.Btn(children=[f\"Clicked {clicks} times\"])\n", - " rv.use_event(button, 'click', my_click_handler)\n", + " rv.use_event(button, \"click\", my_click_handler)\n", " return button\n", + "\n", + "\n", "ButtonClick()" ] }, diff --git a/notebooks/markdown.ipynb b/notebooks/markdown.ipynb index 5d3a098..c78e518 100644 --- a/notebooks/markdown.ipynb +++ b/notebooks/markdown.ipynb @@ -28,6 +28,7 @@ " html = markdown.markdown(md)\n", " return w.HTML(value=html)\n", "\n", + "\n", "Markdown(\"# Reacton rocks\\nSeriously **bold** idea!\")" ] }, @@ -49,17 +50,17 @@ "outputs": [], "source": [ "@reacton.component\n", - "def MarkdownEditor(md : str):\n", + "def MarkdownEditor(md: str):\n", " md, set_md = reacton.use_state(md)\n", " edit, set_edit = reacton.use_state(True)\n", " with w.VBox() as main:\n", " Markdown(md)\n", - " w.ToggleButton(description=\"Edit\",\n", - " value=edit,\n", - " on_value=set_edit)\n", + " w.ToggleButton(description=\"Edit\", value=edit, on_value=set_edit)\n", " if edit:\n", " w.Textarea(value=md, on_value=set_md, rows=10)\n", " return main\n", + "\n", + "\n", "MarkdownEditor(\"# Reacton rocks\\nSeriously **bold** idea!\")" ] }, diff --git a/notebooks/todo-app.ipynb b/notebooks/todo-app.ipynb index 1503596..9ea04d4 100644 --- a/notebooks/todo-app.ipynb +++ b/notebooks/todo-app.ipynb @@ -9,7 +9,7 @@ }, "outputs": [], "source": [ - "from typing import Callable, List, Tuple\n", + "from typing import Callable, List\n", "import reacton\n", "import reacton.ipyvuetify as rv\n", "import reacton.ipywidgets as w\n", @@ -22,20 +22,21 @@ " text: str\n", " done: bool\n", "\n", - " \n", + "\n", "@reacton.component\n", - "def TodoListItem(item: TodoItem, on_item_change:Callable[[TodoItem], None], on_delete:Callable[[], None]):\n", + "def TodoListItem(item: TodoItem, on_item_change: Callable[[TodoItem], None], on_delete: Callable[[], None]):\n", " \"\"\"Displays a single todo item\"\"\"\n", + "\n", " def on_change_done(done: bool):\n", " on_item_change(dataclasses.replace(item, done=done))\n", "\n", " def on_change_text(text: str):\n", " on_item_change(dataclasses.replace(item, text=text))\n", - " \n", + "\n", " with rv.ListItem() as main:\n", " with rv.Btn(icon=True) as button_delete:\n", " rv.Icon(children=[\"mdi-delete\"])\n", - " rv.use_event(button_delete, 'click', lambda *ignore_events: on_delete())\n", + " rv.use_event(button_delete, \"click\", lambda *ignore_events: on_delete())\n", " rv.Checkbox(v_model=item.done, on_v_model=on_change_done, color=\"success\")\n", " rv.TextField(v_model=item.text, on_v_model=on_change_text)\n", " return main\n", @@ -46,6 +47,7 @@ " \"\"\"Component that managed entering new todo items\"\"\"\n", " new_text, set_new_text = reacton.use_state(\"\")\n", " text_field = rv.TextField(v_model=new_text, on_v_model=set_new_text, label=\"Enter a new todo item\")\n", + "\n", " def create_new_item(*ignore_args):\n", " if not new_text:\n", " return\n", @@ -54,6 +56,7 @@ " on_new_item(new_item)\n", " # reset text\n", " set_new_text(\"\")\n", + "\n", " rv.use_event(text_field, \"keydown.enter\", create_new_item)\n", " return text_field\n", "\n", @@ -82,7 +85,7 @@ "@reacton.component\n", "def TodoApp(items: List[TodoItem]):\n", " items, set_items = reacton.use_state(items)\n", - " \n", + "\n", " def on_new_item(new_item: TodoItem):\n", " new_items = [new_item, *items]\n", " set_items(new_items)\n", @@ -93,8 +96,9 @@ " if items:\n", " TodoStatus(items)\n", " for index, item in enumerate(items):\n", + "\n", " def on_item_change(changed_item, index=index):\n", - " new_items = items.copy() # copy because we mutate\n", + " new_items = items.copy() # copy because we mutate\n", " new_items[index] = changed_item\n", " set_items(new_items)\n", "\n", @@ -105,9 +109,7 @@ "\n", " TodoListItem(item, on_item_change, on_delete)\n", " else:\n", - " rv.Alert(type=\"info\", children=[\n", - " \"No todo items, enter some text above, and hit enter\"\n", - " ])\n", + " rv.Alert(type=\"info\", children=[\"No todo items, enter some text above, and hit enter\"])\n", " return main\n", "\n", "\n", diff --git a/pyproject.toml b/pyproject.toml index c6ae83f..2586581 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -39,7 +39,7 @@ packages = ["react_ipywidgets", "reacton"] [project.optional-dependencies] dev = [ - "flake8", + "ruff; python_version > '3.6'", "black", "mypy", "pre-commit", @@ -47,7 +47,7 @@ dev = [ "pytest", "pytest-cov", "bqplot", - "numpy", + "numpy<2", "ipyvuetify", "bump2version", "jinja2", @@ -67,11 +67,6 @@ Home = "https://www.github.com/widgetti/reacton" Documentation = "https://reacton.solara.dev" "Source code" = "https://www.github.com/widgetti/reacton" -[tool.black] -line-length = 160 - [tool.ruff] line-length = 160 - -[tool.isort] -profile = "black" +target-version = "py37" diff --git a/reacton/bqplot.py b/reacton/bqplot.py index f689d0b..91e747f 100644 --- a/reacton/bqplot.py +++ b/reacton/bqplot.py @@ -24,7 +24,6 @@ def __enter__(self): if __name__ == "__main__": - from . import generate class CodeGen(generate.CodeGen): @@ -90,7 +89,6 @@ def _Albers( @implements(_Albers) def Albers(**kwargs): - widget_cls = bqplot.scales.Albers comp = reacton.core.ComponentWidget(widget=widget_cls) return Element(comp, kwargs=kwargs) @@ -130,7 +128,6 @@ def _AlbersUSA( @implements(_AlbersUSA) def AlbersUSA(**kwargs): - widget_cls = bqplot.scales.AlbersUSA comp = reacton.core.ComponentWidget(widget=widget_cls) return Element(comp, kwargs=kwargs) @@ -235,7 +232,6 @@ def _Axis( @implements(_Axis) def Axis(**kwargs): - widget_cls = bqplot.axes.Axis comp = reacton.core.ComponentWidget(widget=widget_cls) return Element(comp, kwargs=kwargs) @@ -402,7 +398,6 @@ def _Bars( @implements(_Bars) def Bars(**kwargs): - widget_cls = bqplot.marks.Bars comp = reacton.core.ComponentWidget(widget=widget_cls) return Element(comp, kwargs=kwargs) @@ -418,7 +413,6 @@ def _BaseAxis() -> Element[bqplot.axes.BaseAxis]: @implements(_BaseAxis) def BaseAxis(**kwargs): - widget_cls = bqplot.axes.BaseAxis comp = reacton.core.ComponentWidget(widget=widget_cls) return Element(comp, kwargs=kwargs) @@ -569,7 +563,6 @@ def _Bins( @implements(_Bins) def Bins(**kwargs): - widget_cls = bqplot.marks.Bins comp = reacton.core.ComponentWidget(widget=widget_cls) return Element(comp, kwargs=kwargs) @@ -659,7 +652,6 @@ def _Boxplot( @implements(_Boxplot) def Boxplot(**kwargs): - widget_cls = bqplot.marks.Boxplot comp = reacton.core.ComponentWidget(widget=widget_cls) return Element(comp, kwargs=kwargs) @@ -720,7 +712,6 @@ def _ColorAxis( @implements(_ColorAxis) def ColorAxis(**kwargs): - widget_cls = bqplot.axes.ColorAxis comp = reacton.core.ComponentWidget(widget=widget_cls) return Element(comp, kwargs=kwargs) @@ -781,7 +772,6 @@ def _ColorScale( @implements(_ColorScale) def ColorScale(**kwargs): - widget_cls = bqplot.scales.ColorScale comp = reacton.core.ComponentWidget(widget=widget_cls) return Element(comp, kwargs=kwargs) @@ -855,7 +845,6 @@ def _DateColorScale( @implements(_DateColorScale) def DateColorScale(**kwargs): - widget_cls = bqplot.scales.DateColorScale comp = reacton.core.ComponentWidget(widget=widget_cls) return Element(comp, kwargs=kwargs) @@ -899,7 +888,6 @@ def _DateScale( @implements(_DateScale) def DateScale(**kwargs): - widget_cls = bqplot.scales.DateScale comp = reacton.core.ComponentWidget(widget=widget_cls) return Element(comp, kwargs=kwargs) @@ -936,7 +924,6 @@ def _EquiRectangular( @implements(_EquiRectangular) def EquiRectangular(**kwargs): - widget_cls = bqplot.scales.EquiRectangular comp = reacton.core.ComponentWidget(widget=widget_cls) return Element(comp, kwargs=kwargs) @@ -1168,7 +1155,6 @@ def _FlexLine( @implements(_FlexLine) def FlexLine(**kwargs): - widget_cls = bqplot.marks.FlexLine comp = reacton.core.ComponentWidget(widget=widget_cls) return Element(comp, kwargs=kwargs) @@ -1195,7 +1181,6 @@ def _GeoScale( @implements(_GeoScale) def GeoScale(**kwargs): - widget_cls = bqplot.scales.GeoScale comp = reacton.core.ComponentWidget(widget=widget_cls) return Element(comp, kwargs=kwargs) @@ -1241,7 +1226,6 @@ def _Gnomonic( @implements(_Gnomonic) def Gnomonic(**kwargs): - widget_cls = bqplot.scales.Gnomonic comp = reacton.core.ComponentWidget(widget=widget_cls) return Element(comp, kwargs=kwargs) @@ -1366,7 +1350,6 @@ def _Graph( @implements(_Graph) def Graph(**kwargs): - widget_cls = bqplot.marks.Graph comp = reacton.core.ComponentWidget(widget=widget_cls) return Element(comp, kwargs=kwargs) @@ -1500,7 +1483,6 @@ def _GridHeatMap( @implements(_GridHeatMap) def GridHeatMap(**kwargs): - widget_cls = bqplot.marks.GridHeatMap comp = reacton.core.ComponentWidget(widget=widget_cls) return Element(comp, kwargs=kwargs) @@ -1579,7 +1561,6 @@ def _HeatMap( @implements(_HeatMap) def HeatMap(**kwargs): - widget_cls = bqplot.marks.HeatMap comp = reacton.core.ComponentWidget(widget=widget_cls) return Element(comp, kwargs=kwargs) @@ -1687,7 +1668,6 @@ def _Hist( @implements(_Hist) def Hist(**kwargs): - widget_cls = bqplot.marks.Hist comp = reacton.core.ComponentWidget(widget=widget_cls) return Element(comp, kwargs=kwargs) @@ -1761,7 +1741,6 @@ def _Image( @implements(_Image) def Image(**kwargs): - widget_cls = bqplot.marks.Image comp = reacton.core.ComponentWidget(widget=widget_cls) return Element(comp, kwargs=kwargs) @@ -1794,7 +1773,6 @@ def _Interaction() -> Element[bqplot.interacts.Interaction]: @implements(_Interaction) def Interaction(**kwargs): - widget_cls = bqplot.interacts.Interaction comp = reacton.core.ComponentWidget(widget=widget_cls) return Element(comp, kwargs=kwargs) @@ -1948,7 +1926,6 @@ def _Label( @implements(_Label) def Label(**kwargs): - widget_cls = bqplot.marks.Label comp = reacton.core.ComponentWidget(widget=widget_cls) return Element(comp, kwargs=kwargs) @@ -2014,7 +1991,6 @@ def _LinearScale( @implements(_LinearScale) def LinearScale(**kwargs): - widget_cls = bqplot.scales.LinearScale comp = reacton.core.ComponentWidget(widget=widget_cls) return Element(comp, kwargs=kwargs) @@ -2166,7 +2142,6 @@ def _Lines( @implements(_Lines) def Lines(**kwargs): - widget_cls = bqplot.marks.Lines comp = reacton.core.ComponentWidget(widget=widget_cls) return Element(comp, kwargs=kwargs) @@ -2208,7 +2183,6 @@ def _LogScale( @implements(_LogScale) def LogScale(**kwargs): - widget_cls = bqplot.scales.LogScale comp = reacton.core.ComponentWidget(widget=widget_cls) return Element(comp, kwargs=kwargs) @@ -2298,7 +2272,6 @@ def _Map( @implements(_Map) def Map(**kwargs): - widget_cls = bqplot.marks.Map comp = reacton.core.ComponentWidget(widget=widget_cls) return Element(comp, kwargs=kwargs) @@ -2423,7 +2396,6 @@ def _Mark( @implements(_Mark) def Mark(**kwargs): - widget_cls = bqplot.marks.Mark comp = reacton.core.ComponentWidget(widget=widget_cls) return Element(comp, kwargs=kwargs) @@ -2470,7 +2442,6 @@ def _Mercator( @implements(_Mercator) def Mercator(**kwargs): - widget_cls = bqplot.scales.Mercator comp = reacton.core.ComponentWidget(widget=widget_cls) return Element(comp, kwargs=kwargs) @@ -2574,7 +2545,6 @@ def _OHLC( @implements(_OHLC) def OHLC(**kwargs): - widget_cls = bqplot.marks.OHLC comp = reacton.core.ComponentWidget(widget=widget_cls) return Element(comp, kwargs=kwargs) @@ -2626,7 +2596,6 @@ def _OrdinalColorScale( @implements(_OrdinalColorScale) def OrdinalColorScale(**kwargs): - widget_cls = bqplot.scales.OrdinalColorScale comp = reacton.core.ComponentWidget(widget=widget_cls) return Element(comp, kwargs=kwargs) @@ -2664,7 +2633,6 @@ def _OrdinalScale( @implements(_OrdinalScale) def OrdinalScale(**kwargs): - widget_cls = bqplot.scales.OrdinalScale comp = reacton.core.ComponentWidget(widget=widget_cls) return Element(comp, kwargs=kwargs) @@ -2715,7 +2683,6 @@ def _Orthographic( @implements(_Orthographic) def Orthographic(**kwargs): - widget_cls = bqplot.scales.Orthographic comp = reacton.core.ComponentWidget(widget=widget_cls) return Element(comp, kwargs=kwargs) @@ -2752,7 +2719,6 @@ def _PanZoom( @implements(_PanZoom) def PanZoom(**kwargs): - widget_cls = bqplot.interacts.PanZoom comp = reacton.core.ComponentWidget(widget=widget_cls) return Element(comp, kwargs=kwargs) @@ -2893,7 +2859,6 @@ def _Pie( @implements(_Pie) def Pie(**kwargs): - widget_cls = bqplot.marks.Pie comp = reacton.core.ComponentWidget(widget=widget_cls) return Element(comp, kwargs=kwargs) @@ -2935,7 +2900,6 @@ def _Scale( @implements(_Scale) def Scale(**kwargs): - widget_cls = bqplot.scales.Scale comp = reacton.core.ComponentWidget(widget=widget_cls) return Element(comp, kwargs=kwargs) @@ -3149,7 +3113,6 @@ def _Scatter( @implements(_Scatter) def Scatter(**kwargs): - widget_cls = bqplot.marks.Scatter comp = reacton.core.ComponentWidget(widget=widget_cls) return Element(comp, kwargs=kwargs) @@ -3264,7 +3227,6 @@ def _ScatterGL( @implements(_ScatterGL) def ScatterGL(**kwargs): - widget_cls = bqplot.marks.ScatterGL comp = reacton.core.ComponentWidget(widget=widget_cls) return Element(comp, kwargs=kwargs) @@ -3315,7 +3277,6 @@ def _Stereographic( @implements(_Stereographic) def Stereographic(**kwargs): - widget_cls = bqplot.scales.Stereographic comp = reacton.core.ComponentWidget(widget=widget_cls) return Element(comp, kwargs=kwargs) diff --git a/reacton/core.py b/reacton/core.py index ac54e1a..228f487 100644 --- a/reacton/core.py +++ b/reacton/core.py @@ -6,6 +6,7 @@ * Component -- function """ + import contextlib import copy import functools @@ -336,7 +337,7 @@ def _ipython_display_(self, **kwargs): def __enter__(self): rc = _get_render_context() - ca = ContainerAdder[T](self, "children") + ca = ContainerAdder[W](self, "children") assert rc.context is not None rc.container_adders.append(ca) return self @@ -478,11 +479,9 @@ def _cleanup_callbacks(self, widget: widgets.Widget): class Value(Generic[V], Protocol): - def get(self) -> V: - ... + def get(self) -> V: ... - def set(self, value: V): - ... + def set(self, value: V): ... class ValueElement(Generic[W, V], Element[W]): @@ -680,18 +679,15 @@ def __call__(self, *args, **kwargs): @overload -def component(obj: None = None, mime_bundle=...) -> Callable[[FuncT], FuncT]: - ... +def component(obj: None = None, mime_bundle=...) -> Callable[[FuncT], FuncT]: ... @overload -def component(obj: FuncT, mime_bundle=...) -> FuncT: - ... +def component(obj: FuncT, mime_bundle=...) -> FuncT: ... @overload -def component(obj: Callable[P, None], mime_bundle=...) -> Callable[P, Element]: - ... +def component(obj: Callable[P, None], mime_bundle=...) -> Callable[P, Element]: ... # it is actually this... @@ -715,15 +711,13 @@ def wrapper(obj: Union[Callable[P, None], FuncT]) -> FuncT: @overload def value_component( value_type: None, value_name="value", mime_bundle: Dict[str, Any] = mime_bundle_default -) -> Callable[[Callable[P, ValueElement[W, V]]], Callable[P, ValueElement[W, V]]]: - ... +) -> Callable[[Callable[P, ValueElement[W, V]]], Callable[P, ValueElement[W, V]]]: ... @overload def value_component( value_type: Type[V], value_name="value", mime_bundle: Dict[str, Any] = mime_bundle_default -) -> Callable[[Callable[P, Element[W]]], Callable[P, ValueElement[W, V]]]: - ... +) -> Callable[[Callable[P, Element[W]]], Callable[P, ValueElement[W, V]]]: ... def value_component(value_type: Union[Type[V], None], value_name="value", mime_bundle: Dict[str, Any] = mime_bundle_default): @@ -838,13 +832,11 @@ def handler(change): @overload -def get_render_context(required: Literal[True] = ...) -> "_RenderContext": - ... +def get_render_context(required: Literal[True] = ...) -> "_RenderContext": ... @overload -def get_render_context(required: Literal[False] = ...) -> Optional["_RenderContext"]: - ... +def get_render_context(required: Literal[False] = ...) -> Optional["_RenderContext"]: ... def get_render_context(required=True): @@ -1701,7 +1693,6 @@ def _render(self, element: Element, default_key: str, parent_key: str): # back the root element root_element: Optional[Element] = None try: - stack = contextlib.ExitStack() with contextlib.ExitStack() as stack: for cm in context.context_managers: stack.enter_context(cm) @@ -1809,7 +1800,6 @@ def _reconsolidate(self, el: Element, default_key: str, parent_key: str): already_reconsolidated = el in self._shared_elements if already_reconsolidated and el is not self.element and el.is_shared: - logger.debug("Reconsolidate: Using existing widget (prev = %r)", el_prev) # keeping this for debugging # logger.debug("Current:") @@ -2208,15 +2198,13 @@ def _visit_children_values(self, value: Any, key: str, parent_key: str, f: Calla @overload def render( element: Element[T], container: None = None, children_trait="children", handle_error: bool = True, initial_state=None -) -> Tuple[widgets.HBox, _RenderContext]: - ... +) -> Tuple[widgets.HBox, _RenderContext]: ... @overload def render( element: Element[T], container: None = None, children_trait="children", handle_error: bool = True, initial_state=None -) -> Tuple[widgets.Widget, _RenderContext]: - ... +) -> Tuple[widgets.Widget, _RenderContext]: ... def render(element: Element[T], container: widgets.Widget = None, children_trait="children", handle_error: bool = True, initial_state=None): diff --git a/reacton/core_test.py b/reacton/core_test.py index 9acd128..d19390b 100644 --- a/reacton/core_test.py +++ b/reacton/core_test.py @@ -378,7 +378,6 @@ def test_render_replace(): def test_render_conditional_child(): - set_value = lambda x: None # noqa @react.component @@ -404,7 +403,6 @@ def Test(): def test_render_conditional_replace_component_with_element(): - set_value = lambda x: None # noqa def Container(): @@ -1383,7 +1381,6 @@ def ContainerContext(exponent=1.2): def test_get_widget(Container): - button1 = None button2 = None @@ -2967,7 +2964,6 @@ def test_close_when_overridden(): def test_render_perf_child_only(): - render_child = unittest.mock.Mock() render_main = unittest.mock.Mock() set_text = lambda x: None # noqa diff --git a/reacton/deprecated/ipyvuetify.py b/reacton/deprecated/ipyvuetify.py index be9861c..6890382 100644 --- a/reacton/deprecated/ipyvuetify.py +++ b/reacton/deprecated/ipyvuetify.py @@ -3300,7 +3300,7 @@ def _Flex( py_1: bool = None, py_2: bool = None, py_3: bool = None, - **kwargs + **kwargs, ) -> ValueElement[ipyvuetify.generated.Flex, Any]: """ """ ... diff --git a/reacton/ipycanvas.py b/reacton/ipycanvas.py index 409260b..b02b72a 100644 --- a/reacton/ipycanvas.py +++ b/reacton/ipycanvas.py @@ -11,7 +11,6 @@ from .utils import implements if __name__ == "__main__": - from .generate import generate generate(__file__, [ipycanvas]) @@ -176,7 +175,6 @@ def _Path2D(value: str = "", on_value: typing.Callable[[str], Any] = None) -> El @implements(_Path2D) def Path2D(**kwargs): - widget_cls = ipycanvas.canvas.Path2D comp = reacton.core.ComponentWidget(widget=widget_cls) return Element(comp, kwargs=kwargs) diff --git a/reacton/ipywidgets.py b/reacton/ipywidgets.py index 66ba0ee..99ece34 100644 --- a/reacton/ipywidgets.py +++ b/reacton/ipywidgets.py @@ -545,7 +545,6 @@ def _ButtonStyle( @implements(_ButtonStyle) def ButtonStyle(**kwargs): - widget_cls = ipywidgets.widgets.widget_button.ButtonStyle comp = reacton.core.ComponentWidget(widget=widget_cls) return Element(comp, kwargs=kwargs) @@ -746,7 +745,6 @@ def _CoreWidget() -> Element[ipywidgets.widgets.widget_core.CoreWidget]: @implements(_CoreWidget) def CoreWidget(**kwargs): - widget_cls = ipywidgets.widgets.widget_core.CoreWidget comp = reacton.core.ComponentWidget(widget=widget_cls) return Element(comp, kwargs=kwargs) @@ -2016,7 +2014,6 @@ def _Layout( @implements(_Layout) def Layout(**kwargs): - widget_cls = ipywidgets.widgets.widget_layout.Layout comp = reacton.core.ComponentWidget(widget=widget_cls) return Element(comp, kwargs=kwargs) @@ -2670,7 +2667,6 @@ def _SliderStyle( @implements(_SliderStyle) def SliderStyle(**kwargs): - widget_cls = ipywidgets.widgets.widget_int.SliderStyle comp = reacton.core.ComponentWidget(widget=widget_cls) return Element(comp, kwargs=kwargs) @@ -2686,7 +2682,6 @@ def _Style() -> Element[ipywidgets.widgets.widget_style.Style]: @implements(_Style) def Style(**kwargs): - widget_cls = ipywidgets.widgets.widget_style.Style comp = reacton.core.ComponentWidget(widget=widget_cls) return Element(comp, kwargs=kwargs) @@ -3011,7 +3006,6 @@ def _ToggleButtonsStyle( @implements(_ToggleButtonsStyle) def ToggleButtonsStyle(**kwargs): - widget_cls = ipywidgets.widgets.widget_selection.ToggleButtonsStyle comp = reacton.core.ComponentWidget(widget=widget_cls) return Element(comp, kwargs=kwargs) @@ -3210,7 +3204,6 @@ def _ValueWidget(value: Any = None, on_value: typing.Callable[[Any], Any] = None @implements(_ValueWidget) def ValueWidget(**kwargs): - widget_cls = ipywidgets.widgets.valuewidget.ValueWidget comp = reacton.core.ComponentWidget(widget=widget_cls) return ValueElement("value", comp, kwargs=kwargs) @@ -3327,7 +3320,6 @@ def _DescriptionStyle( @implements(_DescriptionStyle) def DescriptionStyle(**kwargs): - widget_cls = ipywidgets.widgets.widget_description.DescriptionStyle comp = reacton.core.ComponentWidget(widget=widget_cls) return Element(comp, kwargs=kwargs) @@ -3383,7 +3375,6 @@ def _ProgressStyle( @implements(_ProgressStyle) def ProgressStyle(**kwargs): - widget_cls = ipywidgets.widgets.widget_int.ProgressStyle comp = reacton.core.ComponentWidget(widget=widget_cls) return Element(comp, kwargs=kwargs) diff --git a/reacton/logging.py b/reacton/logging.py index 89041e6..679857f 100644 --- a/reacton/logging.py +++ b/reacton/logging.py @@ -3,6 +3,7 @@ See `configuration of logging `_ how to configure logging. """ + import logging import os from typing import Optional diff --git a/reacton/utils_test.py b/reacton/utils_test.py index 2b148f6..646d0dd 100644 --- a/reacton/utils_test.py +++ b/reacton/utils_test.py @@ -145,7 +145,6 @@ def test_isinstance_lazy(): assert isinstance_lazy(1, int) assert isinstance_lazy(1, (int, "does.not.exist")) assert not isinstance_lazy(1, "does.not.exist") - import pandas sys.modules.pop("pandas", None) assert not isinstance_lazy(1, "pandas.DataFrame")