Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion .github/workflows/unittest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,6 @@ jobs:
path: ./dist
- name: Install
run: |
pip install `echo dist/*.whl`[dev] "black<23"
pip install `echo dist/*.whl`[dev]
- name: test
run: pytest --cov=reacton reacton
1 change: 0 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ packages = ["react_ipywidgets", "reacton"]
[project.optional-dependencies]
dev = [
"ruff; python_version > '3.6'",
"black",
"mypy",
"pre-commit",
"coverage",
Expand Down
28 changes: 21 additions & 7 deletions reacton/generate.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
from textwrap import indent
from typing import Any, Dict, Generic, Type, TypeVar

import black
import bqplot
import ipywidgets
import ipywidgets as widgets # type: ignore
Expand Down Expand Up @@ -106,9 +105,28 @@ def get_element_class(self, cls):
def get_ignore_props(self, cls):
return self.ignore_props

# Replicated from https://gist.github.com/shner-elmo/b2639a4d1e04ceafaad120acfb31213c
def ruff_format(self, code: str) -> str:
import subprocess
from ruff.__main__ import find_ruff_bin

ruff_args = [
find_ruff_bin(),
"format",
"--stdin-filename",
"foo.py", # you can pass any random string, it wont use it...
# these two lines are optional, but this is how you can pass the config for ruff
"--line-length",
f"{MAX_LINE_LENGTH}",
]
proc = subprocess.run(ruff_args, input=code, text=True, capture_output=True)
proc.check_returncode() # raise an Exception if return code is not 0
return proc.stdout

def generate_component(self, cls: Type[widgets.Widget], blacken=True):
element_class_name = self.get_element_class(cls).__name__
ignore = self.get_ignore_props(cls)

traits = {key: value for key, value in cls.class_traits().items() if "output" not in value.metadata and not key.startswith("_") and key not in ignore}

def has_default(trait):
Expand Down Expand Up @@ -293,9 +311,8 @@ def {{ method_name }}(**kwargs):
)

if blacken:
mode = black.Mode(line_length=MAX_LINE_LENGTH)
try:
code = black.format_file_contents(code, fast=False, mode=mode)
code = self.ruff_format(code)
except Exception:
print("code:\n", code)
raise
Expand Down Expand Up @@ -325,10 +342,7 @@ def generate(self, path, blacken=True):
raise ValueError(f"Could not find new line after marker: {marker!r}")
code_total = current_code[: start + 1] + "\n" + code
if blacken:
import black

mode = black.Mode(line_length=MAX_LINE_LENGTH)
code_total = black.format_file_contents(code_total, fast=False, mode=mode)
code_total = self.ruff_format(code_total)
only_valid = True
if only_valid:
try:
Expand Down
10 changes: 6 additions & 4 deletions reacton/generate_test.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import sys
import ipywidgets as widgets
import traitlets
import pytest

from .generate import CodeGen


@pytest.mark.skipif(sys.version_info < (3, 7), reason="Ruff does not support Python < 3.7")
def test_basic():
class MyTest(traitlets.HasTraits):
a = traitlets.traitlets.Int(1)
Expand All @@ -22,7 +25,6 @@ def _MyTest(

@implements(_MyTest)
def MyTest(**kwargs):

widget_cls = reacton.generate_test.MyTest
comp = reacton.core.ComponentWidget(widget=widget_cls)
return Element(comp, kwargs=kwargs)
Expand All @@ -33,6 +35,7 @@ def MyTest(**kwargs):
assert code.strip() == code_expected.strip()


@pytest.mark.skipif(sys.version_info < (3, 7), reason="Ruff does not support Python < 3.7")
def test_value():
class MyTest(traitlets.HasTraits):
a = traitlets.traitlets.Int(1)
Expand All @@ -51,7 +54,6 @@ def _MyTest(

@implements(_MyTest)
def MyTest(**kwargs):

widget_cls = reacton.generate_test.MyTest
comp = reacton.core.ComponentWidget(widget=widget_cls)
return ValueElement("value", comp, kwargs=kwargs)
Expand All @@ -62,6 +64,7 @@ def MyTest(**kwargs):
assert code.strip() == code_expected.strip()


@pytest.mark.skipif(sys.version_info < (3, 7), reason="Ruff does not support Python < 3.7")
def test_instance_non_widget():
class NonWidget:
def __init__(self, *args) -> None:
Expand All @@ -85,7 +88,6 @@ def _MyTest(

@implements(_MyTest)
def MyTest(**kwargs):

widget_cls = reacton.generate_test.MyTest
comp = reacton.core.ComponentWidget(widget=widget_cls)
return Element(comp, kwargs=kwargs)
Expand All @@ -95,6 +97,7 @@ def MyTest(**kwargs):
assert code.strip() == code_expected.strip()


@pytest.mark.skipif(sys.version_info < (3, 7), reason="Ruff does not support Python < 3.7")
def test_instance_widget():
class SomeWidget(widgets.Widget):
def __init__(self, *args) -> None:
Expand All @@ -116,7 +119,6 @@ def _MyTest(

@implements(_MyTest)
def MyTest(**kwargs):

widget_cls = reacton.generate_test.MyTest
comp = reacton.core.ComponentWidget(widget=widget_cls)
return Element(comp, kwargs=kwargs)
Expand Down
Loading