playing around with first-class examples
Before Width: | Height: | Size: 189 KiB After Width: | Height: | Size: 194 KiB |
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 58 KiB After Width: | Height: | Size: 58 KiB |
Before Width: | Height: | Size: 132 KiB After Width: | Height: | Size: 54 KiB |
@ -0,0 +1,46 @@
|
|||||||
|
import inspect
|
||||||
|
from collections.abc import Callable
|
||||||
|
from contextlib import redirect_stdout
|
||||||
|
from dataclasses import dataclass
|
||||||
|
from io import StringIO
|
||||||
|
|
||||||
|
from rich.console import RenderableType
|
||||||
|
from rich.panel import Panel
|
||||||
|
from rich.syntax import Syntax
|
||||||
|
|
||||||
|
|
||||||
|
def example(**kwargs):
|
||||||
|
def deco(func):
|
||||||
|
return Example(**kwargs, func=func)
|
||||||
|
|
||||||
|
return deco
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Example:
|
||||||
|
name: str
|
||||||
|
func: Callable[[], None]
|
||||||
|
result: str | None = None
|
||||||
|
return_value: object = None
|
||||||
|
|
||||||
|
def source_panel(self) -> RenderableType:
|
||||||
|
source_lines, _ = inspect.getsourcelines(self.func)
|
||||||
|
return Panel.fit(
|
||||||
|
Syntax(
|
||||||
|
"\n".join(source_lines).rstrip(),
|
||||||
|
lexer="python",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
def results_panel(self) -> RenderableType:
|
||||||
|
return Panel.fit(self.result or "")
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
if self.result is not None:
|
||||||
|
return
|
||||||
|
|
||||||
|
cap = StringIO()
|
||||||
|
with redirect_stdout(cap):
|
||||||
|
self.return_value = self.func()
|
||||||
|
|
||||||
|
self.result = cap.getvalue()
|