Skip to content

Commit 25e1170

Browse files
committed
feat: use ruff for codegen
1 parent 496a21a commit 25e1170

File tree

4 files changed

+28
-13
lines changed

4 files changed

+28
-13
lines changed

.github/workflows/unittest.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,6 @@ jobs:
3434
path: ./dist
3535
- name: Install
3636
run: |
37-
pip install `echo dist/*.whl`[dev] "black<23"
37+
pip install `echo dist/*.whl`[dev]
3838
- name: test
3939
run: pytest --cov=reacton reacton

pyproject.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ packages = ["react_ipywidgets", "reacton"]
4040
[project.optional-dependencies]
4141
dev = [
4242
"ruff; python_version > '3.6'",
43-
"black",
4443
"mypy",
4544
"pre-commit",
4645
"coverage",

reacton/generate.py

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
from textwrap import indent
66
from typing import Any, Dict, Generic, Type, TypeVar
77

8-
import black
98
import bqplot
109
import ipywidgets
1110
import ipywidgets as widgets # type: ignore
@@ -106,9 +105,28 @@ def get_element_class(self, cls):
106105
def get_ignore_props(self, cls):
107106
return self.ignore_props
108107

108+
# Replicated from https://gist.github.com/shner-elmo/b2639a4d1e04ceafaad120acfb31213c
109+
def ruff_format(self, code: str) -> str:
110+
import subprocess
111+
from ruff.__main__ import find_ruff_bin
112+
113+
ruff_args = [
114+
find_ruff_bin(),
115+
"format",
116+
"--stdin-filename",
117+
"foo.py", # you can pass any random string, it wont use it...
118+
# these two lines are optional, but this is how you can pass the config for ruff
119+
"--line-length",
120+
f"{MAX_LINE_LENGTH}",
121+
]
122+
proc = subprocess.run(ruff_args, input=code, text=True, capture_output=True)
123+
proc.check_returncode() # raise an Exception if return code is not 0
124+
return proc.stdout
125+
109126
def generate_component(self, cls: Type[widgets.Widget], blacken=True):
110127
element_class_name = self.get_element_class(cls).__name__
111128
ignore = self.get_ignore_props(cls)
129+
112130
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}
113131

114132
def has_default(trait):
@@ -293,9 +311,8 @@ def {{ method_name }}(**kwargs):
293311
)
294312

295313
if blacken:
296-
mode = black.Mode(line_length=MAX_LINE_LENGTH)
297314
try:
298-
code = black.format_file_contents(code, fast=False, mode=mode)
315+
code = self.ruff_format(code)
299316
except Exception:
300317
print("code:\n", code)
301318
raise
@@ -325,10 +342,7 @@ def generate(self, path, blacken=True):
325342
raise ValueError(f"Could not find new line after marker: {marker!r}")
326343
code_total = current_code[: start + 1] + "\n" + code
327344
if blacken:
328-
import black
329-
330-
mode = black.Mode(line_length=MAX_LINE_LENGTH)
331-
code_total = black.format_file_contents(code_total, fast=False, mode=mode)
345+
code_total = self.ruff_format(code_total)
332346
only_valid = True
333347
if only_valid:
334348
try:

reacton/generate_test.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1+
import sys
12
import ipywidgets as widgets
23
import traitlets
4+
import pytest
35

46
from .generate import CodeGen
57

68

9+
@pytest.mark.skipif(sys.version_info < (3, 7), reason="Ruff does not support Python < 3.7")
710
def test_basic():
811
class MyTest(traitlets.HasTraits):
912
a = traitlets.traitlets.Int(1)
@@ -22,7 +25,6 @@ def _MyTest(
2225
2326
@implements(_MyTest)
2427
def MyTest(**kwargs):
25-
2628
widget_cls = reacton.generate_test.MyTest
2729
comp = reacton.core.ComponentWidget(widget=widget_cls)
2830
return Element(comp, kwargs=kwargs)
@@ -33,6 +35,7 @@ def MyTest(**kwargs):
3335
assert code.strip() == code_expected.strip()
3436

3537

38+
@pytest.mark.skipif(sys.version_info < (3, 7), reason="Ruff does not support Python < 3.7")
3639
def test_value():
3740
class MyTest(traitlets.HasTraits):
3841
a = traitlets.traitlets.Int(1)
@@ -51,7 +54,6 @@ def _MyTest(
5154
5255
@implements(_MyTest)
5356
def MyTest(**kwargs):
54-
5557
widget_cls = reacton.generate_test.MyTest
5658
comp = reacton.core.ComponentWidget(widget=widget_cls)
5759
return ValueElement("value", comp, kwargs=kwargs)
@@ -62,6 +64,7 @@ def MyTest(**kwargs):
6264
assert code.strip() == code_expected.strip()
6365

6466

67+
@pytest.mark.skipif(sys.version_info < (3, 7), reason="Ruff does not support Python < 3.7")
6568
def test_instance_non_widget():
6669
class NonWidget:
6770
def __init__(self, *args) -> None:
@@ -85,7 +88,6 @@ def _MyTest(
8588
8689
@implements(_MyTest)
8790
def MyTest(**kwargs):
88-
8991
widget_cls = reacton.generate_test.MyTest
9092
comp = reacton.core.ComponentWidget(widget=widget_cls)
9193
return Element(comp, kwargs=kwargs)
@@ -95,6 +97,7 @@ def MyTest(**kwargs):
9597
assert code.strip() == code_expected.strip()
9698

9799

100+
@pytest.mark.skipif(sys.version_info < (3, 7), reason="Ruff does not support Python < 3.7")
98101
def test_instance_widget():
99102
class SomeWidget(widgets.Widget):
100103
def __init__(self, *args) -> None:
@@ -116,7 +119,6 @@ def _MyTest(
116119
117120
@implements(_MyTest)
118121
def MyTest(**kwargs):
119-
120122
widget_cls = reacton.generate_test.MyTest
121123
comp = reacton.core.ComponentWidget(widget=widget_cls)
122124
return Element(comp, kwargs=kwargs)

0 commit comments

Comments
 (0)