thtml-tstring 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,41 @@
1
+ from ._bindings import (
2
+ CompiledThtmlTemplate,
3
+ Fragment,
4
+ RawHtml,
5
+ Renderable,
6
+ TemplateError,
7
+ TemplateParseError,
8
+ TemplateRuntimeError,
9
+ TemplateSemanticError,
10
+ )
11
+ from ._runtime import (
12
+ ThtmlTemplate,
13
+ check_template,
14
+ compile_template,
15
+ component,
16
+ format_template,
17
+ html,
18
+ render_html,
19
+ spread,
20
+ thtml,
21
+ )
22
+
23
+ __all__ = [
24
+ "CompiledThtmlTemplate",
25
+ "Fragment",
26
+ "RawHtml",
27
+ "Renderable",
28
+ "TemplateError",
29
+ "TemplateParseError",
30
+ "TemplateRuntimeError",
31
+ "TemplateSemanticError",
32
+ "ThtmlTemplate",
33
+ "check_template",
34
+ "compile_template",
35
+ "component",
36
+ "format_template",
37
+ "html",
38
+ "render_html",
39
+ "spread",
40
+ "thtml",
41
+ ]
@@ -0,0 +1,35 @@
1
+ from __future__ import annotations
2
+
3
+ try:
4
+ import tstring_html_bindings as _bindings
5
+ except ImportError: # pragma: no cover
6
+ from tstring_html_bindings import _bindings # type: ignore[attr-defined]
7
+
8
+ TemplateError = _bindings.TemplateError
9
+ TemplateParseError = _bindings.TemplateParseError
10
+ TemplateSemanticError = _bindings.TemplateSemanticError
11
+ TemplateRuntimeError = _bindings.TemplateRuntimeError
12
+ Fragment = _bindings.Fragment
13
+ RawHtml = _bindings.RawHtml
14
+ Renderable = _bindings.Renderable
15
+ CompiledThtmlTemplate = _bindings.CompiledThtmlTemplate
16
+
17
+ check_thtml_template = _bindings.check_thtml_template
18
+ format_thtml_template = _bindings.format_thtml_template
19
+ compile_thtml_template = _bindings.compile_thtml_template
20
+ render_thtml_template = _bindings.render_thtml_template
21
+
22
+ __all__ = [
23
+ "CompiledThtmlTemplate",
24
+ "Fragment",
25
+ "RawHtml",
26
+ "Renderable",
27
+ "TemplateError",
28
+ "TemplateParseError",
29
+ "TemplateRuntimeError",
30
+ "TemplateSemanticError",
31
+ "check_thtml_template",
32
+ "compile_thtml_template",
33
+ "format_thtml_template",
34
+ "render_thtml_template",
35
+ ]
@@ -0,0 +1,181 @@
1
+ from __future__ import annotations
2
+
3
+ import sys
4
+ from functools import wraps
5
+ from string.templatelib import Template
6
+ from typing import Annotated, Any, Callable, Mapping, TypeIs, TypeVar, cast
7
+
8
+ from . import _bindings
9
+ from ._bindings import CompiledThtmlTemplate, Renderable, TemplateRuntimeError
10
+
11
+ type ThtmlTemplate = Annotated[Template, "thtml"]
12
+ ComponentT = TypeVar("ComponentT", bound=Callable[..., object])
13
+
14
+
15
+ def _is_template(value: object) -> TypeIs[Template]:
16
+ return isinstance(value, Template)
17
+
18
+
19
+ def _is_renderable(value: object) -> TypeIs[Renderable]:
20
+ return isinstance(value, Renderable)
21
+
22
+
23
+ def _validate_template(template: object, api_name: str) -> ThtmlTemplate:
24
+ if _is_template(template):
25
+ return template
26
+ raise TypeError(
27
+ f"{api_name} requires a PEP 750 Template object. "
28
+ f"Got {type(template).__name__} instead."
29
+ )
30
+
31
+
32
+ def _capture_scope(
33
+ globals: Mapping[str, Any] | None,
34
+ locals: Mapping[str, Any] | None,
35
+ *,
36
+ frame_depth: int,
37
+ ) -> tuple[dict[str, Any], dict[str, Any]]:
38
+ if globals is not None and locals is not None:
39
+ return dict(globals), dict(locals)
40
+
41
+ try:
42
+ frame = sys._getframe(frame_depth)
43
+ except AttributeError, ValueError:
44
+ raise TemplateRuntimeError(
45
+ "Caller-frame inspection failed. Pass globals= or locals= explicitly."
46
+ ) from None
47
+
48
+ captured_globals = dict(globals) if globals is not None else dict(frame.f_globals)
49
+ captured_locals = dict(locals) if locals is not None else dict(frame.f_locals)
50
+ return captured_globals, captured_locals
51
+
52
+
53
+ def _make_thtml_renderable(
54
+ template: object,
55
+ *,
56
+ globals: Mapping[str, Any] | None,
57
+ locals: Mapping[str, Any] | None,
58
+ frame_depth: int,
59
+ api_name: str,
60
+ ) -> Renderable:
61
+ checked = _validate_template(template, api_name)
62
+ captured_globals, captured_locals = _capture_scope(
63
+ globals,
64
+ locals,
65
+ frame_depth=frame_depth,
66
+ )
67
+ return Renderable(
68
+ "thtml",
69
+ checked,
70
+ globals=captured_globals,
71
+ locals=captured_locals,
72
+ )
73
+
74
+
75
+ def component(
76
+ func: ComponentT | None = None,
77
+ *,
78
+ backend: str = "thtml",
79
+ ) -> ComponentT | Callable[[ComponentT], ComponentT]:
80
+ if backend not in {"thtml", "html"}:
81
+ raise ValueError("component backend must be 'thtml' or 'html'.")
82
+
83
+ def decorator(inner: ComponentT) -> ComponentT:
84
+ @wraps(inner)
85
+ def wrapped(*args: Any, **kwargs: Any) -> object:
86
+ result = inner(*args, **kwargs)
87
+ if _is_template(result):
88
+ if backend == "thtml":
89
+ return _make_thtml_renderable(
90
+ result,
91
+ globals=cast(Mapping[str, Any], inner.__globals__),
92
+ locals={},
93
+ frame_depth=0,
94
+ api_name="component",
95
+ )
96
+ from html_tstring import html as html_renderable
97
+
98
+ return html_renderable(result)
99
+ return result
100
+
101
+ return cast(ComponentT, wrapped)
102
+
103
+ if func is None:
104
+ return decorator
105
+ return decorator(func)
106
+
107
+
108
+ def spread(value: Mapping[str, Any]) -> Mapping[str, Any]:
109
+ return value
110
+
111
+
112
+ def check_template(template: ThtmlTemplate) -> None:
113
+ _bindings.check_thtml_template(_validate_template(template, "check_template"))
114
+
115
+
116
+ def format_template(template: ThtmlTemplate) -> str:
117
+ checked = _validate_template(template, "format_template")
118
+ return _bindings.format_thtml_template(checked)
119
+
120
+
121
+ def compile_template(template: ThtmlTemplate) -> CompiledThtmlTemplate:
122
+ checked = _validate_template(template, "compile_template")
123
+ return _bindings.compile_thtml_template(checked)
124
+
125
+
126
+ def thtml(
127
+ template: ThtmlTemplate,
128
+ *,
129
+ globals: Mapping[str, Any] | None = None,
130
+ locals: Mapping[str, Any] | None = None,
131
+ ) -> Renderable:
132
+ return _make_thtml_renderable(
133
+ template,
134
+ globals=globals,
135
+ locals=locals,
136
+ frame_depth=3,
137
+ api_name="thtml",
138
+ )
139
+
140
+
141
+ def render_html(
142
+ template: ThtmlTemplate | Renderable,
143
+ *,
144
+ globals: Mapping[str, Any] | None = None,
145
+ locals: Mapping[str, Any] | None = None,
146
+ ) -> str:
147
+ if _is_renderable(template):
148
+ return cast(Renderable, template).render()
149
+
150
+ checked = _validate_template(template, "render_html")
151
+ captured_globals, captured_locals = _capture_scope(
152
+ globals,
153
+ locals,
154
+ frame_depth=2,
155
+ )
156
+ return _bindings.render_thtml_template(
157
+ checked,
158
+ globals=captured_globals,
159
+ locals=captured_locals,
160
+ )
161
+
162
+
163
+ def html(
164
+ template: ThtmlTemplate | Renderable,
165
+ *,
166
+ globals: Mapping[str, Any] | None = None,
167
+ locals: Mapping[str, Any] | None = None,
168
+ ) -> str:
169
+ if _is_renderable(template):
170
+ return cast(Renderable, template).render()
171
+ checked = _validate_template(template, "html")
172
+ captured_globals, captured_locals = _capture_scope(
173
+ globals,
174
+ locals,
175
+ frame_depth=2,
176
+ )
177
+ return _bindings.render_thtml_template(
178
+ checked,
179
+ globals=captured_globals,
180
+ locals=captured_locals,
181
+ )
thtml_tstring/py.typed ADDED
@@ -0,0 +1 @@
1
+
@@ -0,0 +1,42 @@
1
+ Metadata-Version: 2.3
2
+ Name: thtml-tstring
3
+ Version: 0.1.0
4
+ Summary: T-HTML renderer for PEP 750 template strings
5
+ Keywords: html,pep750,t-strings,template-strings,thtml
6
+ Author: Koudai Aono
7
+ Author-email: Koudai Aono <koxudaxi@gmail.com>
8
+ License: MIT
9
+ Classifier: Development Status :: 4 - Beta
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3 :: Only
14
+ Classifier: Programming Language :: Python :: 3.14
15
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
16
+ Requires-Dist: tstring-html-bindings>=0.1.0
17
+ Maintainer: Koudai Aono
18
+ Maintainer-email: Koudai Aono <koxudaxi@gmail.com>
19
+ Requires-Python: >=3.14
20
+ Project-URL: Homepage, https://github.com/koxudaxi/tstring-html
21
+ Project-URL: Repository, https://github.com/koxudaxi/tstring-html
22
+ Project-URL: Documentation, https://github.com/koxudaxi/tstring-html/blob/main/thtml-tstring/README.md
23
+ Project-URL: Changelog, https://github.com/koxudaxi/tstring-html/blob/main/CHANGELOG.md
24
+ Project-URL: Issues, https://github.com/koxudaxi/tstring-html/issues
25
+ Description-Content-Type: text/markdown
26
+
27
+ # thtml-tstring
28
+
29
+ Higher-level T-HTML renderer for PEP 750 template strings.
30
+
31
+ ```python
32
+ from thtml_tstring import component, thtml
33
+
34
+ @component
35
+ def Button(*, children: str, kind: str = "primary"):
36
+ classes = [kind]
37
+ return t'<button class="{classes}">{children}</button>'
38
+
39
+ label = "Save"
40
+ page = thtml(t"<Button kind='primary'>{label}</Button>")
41
+ assert page.render() == '<button class="primary">Save</button>'
42
+ ```
@@ -0,0 +1,7 @@
1
+ thtml_tstring/__init__.py,sha256=E2cjwA0Rku0cDFAtKchEDJzwRAVOpryuz3tz9lUwWiI,728
2
+ thtml_tstring/_bindings.py,sha256=T_kY16PsDTiMjYrpc6YUiq9gzlwAV9zDlx9_CcNVFBc,1092
3
+ thtml_tstring/_runtime.py,sha256=cuLwZXQpzQKob_JcppnvVMM7bgPJFcThBxwi30BA3Oc,5152
4
+ thtml_tstring/py.typed,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
5
+ thtml_tstring-0.1.0.dist-info/WHEEL,sha256=GuAqCqoyQuys5_R4zkHUJFlKXw4RpRLNzo31-ui90WQ,81
6
+ thtml_tstring-0.1.0.dist-info/METADATA,sha256=tWifaUE1fDL-NlYvs0SiWbwYkJt4TaKI1fgziqbQ5IM,1603
7
+ thtml_tstring-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: uv 0.10.12
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any