tstring-html-bindings 0.1.6__tar.gz → 0.1.7__tar.gz

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.
Files changed (16) hide show
  1. {tstring_html_bindings-0.1.6 → tstring_html_bindings-0.1.7}/Cargo.lock +5 -5
  2. {tstring_html_bindings-0.1.6 → tstring_html_bindings-0.1.7}/Cargo.toml +1 -1
  3. {tstring_html_bindings-0.1.6 → tstring_html_bindings-0.1.7}/PKG-INFO +1 -1
  4. {tstring_html_bindings-0.1.6 → tstring_html_bindings-0.1.7}/pyproject.toml +1 -1
  5. {tstring_html_bindings-0.1.6 → tstring_html_bindings-0.1.7}/tstring-html-bindings/Cargo.toml +2 -2
  6. {tstring_html_bindings-0.1.6 → tstring_html_bindings-0.1.7}/tstring-html-bindings/src/lib.rs +70 -8
  7. {tstring_html_bindings-0.1.6 → tstring_html_bindings-0.1.7}/tstring-thtml-rs/Cargo.toml +1 -1
  8. {tstring_html_bindings-0.1.6 → tstring_html_bindings-0.1.7}/README.md +0 -0
  9. {tstring_html_bindings-0.1.6 → tstring_html_bindings-0.1.7}/python/tstring_html_bindings/__init__.py +0 -0
  10. {tstring_html_bindings-0.1.6 → tstring_html_bindings-0.1.7}/tstring-format-doc-rs/Cargo.toml +0 -0
  11. {tstring_html_bindings-0.1.6 → tstring_html_bindings-0.1.7}/tstring-format-doc-rs/src/lib.rs +0 -0
  12. {tstring_html_bindings-0.1.6 → tstring_html_bindings-0.1.7}/tstring-html-bindings/README.md +0 -0
  13. {tstring_html_bindings-0.1.6 → tstring_html_bindings-0.1.7}/tstring-html-rs/Cargo.toml +0 -0
  14. {tstring_html_bindings-0.1.6 → tstring_html_bindings-0.1.7}/tstring-html-rs/src/formatter.rs +0 -0
  15. {tstring_html_bindings-0.1.6 → tstring_html_bindings-0.1.7}/tstring-html-rs/src/lib.rs +0 -0
  16. {tstring_html_bindings-0.1.6 → tstring_html_bindings-0.1.7}/tstring-thtml-rs/src/lib.rs +0 -0
@@ -290,14 +290,14 @@ checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801"
290
290
 
291
291
  [[package]]
292
292
  name = "tstring-format-doc"
293
- version = "0.1.6"
293
+ version = "0.1.7"
294
294
  dependencies = [
295
295
  "unicode-width",
296
296
  ]
297
297
 
298
298
  [[package]]
299
299
  name = "tstring-html"
300
- version = "0.1.6"
300
+ version = "0.1.7"
301
301
  dependencies = [
302
302
  "tstring-format-doc",
303
303
  "tstring-syntax",
@@ -305,7 +305,7 @@ dependencies = [
305
305
 
306
306
  [[package]]
307
307
  name = "tstring-html-backend-e2e-tests"
308
- version = "0.1.6"
308
+ version = "0.1.7"
309
309
  dependencies = [
310
310
  "serde",
311
311
  "toml",
@@ -316,7 +316,7 @@ dependencies = [
316
316
 
317
317
  [[package]]
318
318
  name = "tstring-html-bindings"
319
- version = "0.1.6"
319
+ version = "0.1.7"
320
320
  dependencies = [
321
321
  "pyo3",
322
322
  "tstring-html",
@@ -335,7 +335,7 @@ dependencies = [
335
335
 
336
336
  [[package]]
337
337
  name = "tstring-thtml"
338
- version = "0.1.6"
338
+ version = "0.1.7"
339
339
  dependencies = [
340
340
  "tstring-html",
341
341
  "tstring-syntax",
@@ -9,7 +9,7 @@ homepage = "https://github.com/koxudaxi/tstring-html"
9
9
  license = "MIT"
10
10
  repository = "https://github.com/koxudaxi/tstring-html"
11
11
  rust-version = "1.94.0"
12
- version = "0.1.6"
12
+ version = "0.1.7"
13
13
 
14
14
  [workspace.dependencies]
15
15
  pyo3 = "0.27.1"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tstring-html-bindings
3
- Version: 0.1.6
3
+ Version: 0.1.7
4
4
  Classifier: Development Status :: 4 - Beta
5
5
  Classifier: Intended Audience :: Developers
6
6
  Classifier: License :: OSI Approved :: MIT License
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "tstring-html-bindings"
3
- version = "0.1.6"
3
+ version = "0.1.7"
4
4
  description = "Native Python bindings for tstring-html"
5
5
  readme = "README.md"
6
6
  license = { text = "MIT" }
@@ -19,8 +19,8 @@ extension-module = ["pyo3/extension-module"]
19
19
 
20
20
  [dependencies]
21
21
  pyo3 = { workspace = true, features = ["abi3-py314"] }
22
- tstring-html = { version = "0.1.6", path = "../tstring-html-rs" }
23
- tstring-thtml = { version = "0.1.6", path = "../tstring-thtml-rs" }
22
+ tstring-html = { version = "0.1.7", path = "../tstring-html-rs" }
23
+ tstring-thtml = { version = "0.1.7", path = "../tstring-thtml-rs" }
24
24
  tstring-syntax.workspace = true
25
25
 
26
26
  [dev-dependencies]
@@ -18,7 +18,8 @@ create_exception!(tstring_html_bindings, TemplateSemanticError, TemplateError);
18
18
  create_exception!(tstring_html_bindings, TemplateRuntimeError, TemplateError);
19
19
 
20
20
  const PARSE_CACHE_CAPACITY: usize = 256;
21
- const CONTRACT_VERSION: u32 = 1;
21
+ const CONTRACT_VERSION: u32 = 2;
22
+ const REGISTRY_TYPE_ERROR: &str = "registry= must be mapping-like.";
22
23
  const CONTRACT_SYMBOLS: &[&str] = &[
23
24
  "TemplateError",
24
25
  "TemplateParseError",
@@ -197,16 +198,30 @@ impl PyCompiledHtmlTemplate {
197
198
 
198
199
  #[pymethods]
199
200
  impl PyCompiledThtmlTemplate {
200
- #[pyo3(signature = (values, globals = None, locals = None))]
201
+ #[pyo3(signature = (values, globals = None, locals = None, registry = None))]
201
202
  fn render(
202
203
  &self,
203
204
  py: Python<'_>,
204
205
  values: Vec<Py<PyAny>>,
205
206
  globals: Option<&Bound<'_, PyDict>>,
206
207
  locals: Option<&Bound<'_, PyDict>>,
208
+ registry: Option<&Bound<'_, PyAny>>,
207
209
  ) -> PyResult<String> {
210
+ let (globals, locals) = normalize_scope_inputs(
211
+ py,
212
+ globals,
213
+ locals,
214
+ registry,
215
+ "CompiledThtmlTemplate.render",
216
+ )?;
208
217
  let context = runtime_context_from_values(py, &values)?;
209
- render_thtml_document(py, self.compiled.document(), &context, globals, locals)
218
+ render_thtml_document(
219
+ py,
220
+ self.compiled.document(),
221
+ &context,
222
+ globals.as_ref(),
223
+ locals.as_ref(),
224
+ )
210
225
  }
211
226
 
212
227
  fn __repr__(&self) -> String {
@@ -415,6 +430,42 @@ fn runtime_context_from_values(py: Python<'_>, values: &[Py<PyAny>]) -> PyResult
415
430
  })
416
431
  }
417
432
 
433
+ fn registry_to_scope_dict<'py>(
434
+ py: Python<'py>,
435
+ registry: &Bound<'py, PyAny>,
436
+ ) -> PyResult<Bound<'py, PyDict>> {
437
+ let builtins = py.import("builtins")?;
438
+ let dict = builtins
439
+ .getattr("dict")?
440
+ .call1((registry,))
441
+ .map_err(|_| PyTypeError::new_err(REGISTRY_TYPE_ERROR))?;
442
+ dict.cast_into::<PyDict>()
443
+ .map_err(|_| PyTypeError::new_err(REGISTRY_TYPE_ERROR))
444
+ }
445
+
446
+ fn normalize_scope_inputs<'py>(
447
+ py: Python<'py>,
448
+ globals: Option<&Bound<'py, PyDict>>,
449
+ locals: Option<&Bound<'py, PyDict>>,
450
+ registry: Option<&Bound<'py, PyAny>>,
451
+ api_name: &str,
452
+ ) -> PyResult<(Option<Bound<'py, PyDict>>, Option<Bound<'py, PyDict>>)> {
453
+ if registry.is_some() && (globals.is_some() || locals.is_some()) {
454
+ return Err(PyTypeError::new_err(format!(
455
+ "{api_name} does not allow combining registry= with globals= or locals=."
456
+ )));
457
+ }
458
+
459
+ if let Some(registry) = registry {
460
+ return Ok((
461
+ Some(registry_to_scope_dict(py, registry)?),
462
+ Some(PyDict::new(py)),
463
+ ));
464
+ }
465
+
466
+ Ok((globals.cloned(), locals.cloned()))
467
+ }
468
+
418
469
  fn render_thtml_document(
419
470
  py: Python<'_>,
420
471
  document: &Document,
@@ -788,7 +839,7 @@ fn resolve_component<'py>(
788
839
  )));
789
840
  }
790
841
  Err(runtime_error_to_py(format!(
791
- "Unknown component '{name}'. Pass globals= or locals= explicitly."
842
+ "Unknown component '{name}'. Pass registry=, globals=, or locals= explicitly."
792
843
  )))
793
844
  }
794
845
 
@@ -799,7 +850,7 @@ fn default_scope_dict<'py>(py: Python<'py>, globals: bool) -> PyResult<Bound<'py
799
850
  .call1((1,)) // immediate caller only
800
851
  .map_err(|_| {
801
852
  runtime_error_to_py(
802
- "Caller-frame inspection failed. Pass globals= or locals= explicitly.",
853
+ "Caller-frame inspection failed. Pass registry=, globals=, or locals= explicitly.",
803
854
  )
804
855
  })?;
805
856
  let dict = if globals {
@@ -808,7 +859,9 @@ fn default_scope_dict<'py>(py: Python<'py>, globals: bool) -> PyResult<Bound<'py
808
859
  frame.getattr("f_locals")?
809
860
  };
810
861
  dict.cast_into::<PyDict>().map_err(|_| {
811
- runtime_error_to_py("Caller-frame inspection failed. Pass globals= or locals= explicitly.")
862
+ runtime_error_to_py(
863
+ "Caller-frame inspection failed. Pass registry=, globals=, or locals= explicitly.",
864
+ )
812
865
  })
813
866
  }
814
867
 
@@ -886,17 +939,26 @@ fn compile_thtml_template(
886
939
  })
887
940
  }
888
941
 
889
- #[pyfunction(signature = (template, globals = None, locals = None))]
942
+ #[pyfunction(signature = (template, globals = None, locals = None, registry = None))]
890
943
  fn render_thtml_template(
891
944
  py: Python<'_>,
892
945
  template: &Bound<'_, PyAny>,
893
946
  globals: Option<&Bound<'_, PyDict>>,
894
947
  locals: Option<&Bound<'_, PyDict>>,
948
+ registry: Option<&Bound<'_, PyAny>>,
895
949
  ) -> PyResult<String> {
896
950
  let bound = extract_template(py, template, "render_thtml_template")?;
951
+ let (globals, locals) =
952
+ normalize_scope_inputs(py, globals, locals, registry, "render_thtml_template")?;
897
953
  let compiled = compile_cached_thtml(&bound)?;
898
954
  let context = runtime_context_from_bound(py, &bound)?;
899
- render_thtml_document(py, compiled.document(), &context, globals, locals)
955
+ render_thtml_document(
956
+ py,
957
+ compiled.document(),
958
+ &context,
959
+ globals.as_ref(),
960
+ locals.as_ref(),
961
+ )
900
962
  }
901
963
 
902
964
  #[pymodule]
@@ -9,5 +9,5 @@ rust-version.workspace = true
9
9
  version.workspace = true
10
10
 
11
11
  [dependencies]
12
- tstring-html = { version = "0.1.6", path = "../tstring-html-rs" }
12
+ tstring-html = { version = "0.1.7", path = "../tstring-html-rs" }
13
13
  tstring-syntax.workspace = true