koatl 0.3.5__tar.gz → 0.3.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 (137) hide show
  1. {koatl-0.3.5 → koatl-0.3.7}/Cargo.lock +1 -1
  2. {koatl-0.3.5 → koatl-0.3.7}/PKG-INFO +1 -1
  3. {koatl-0.3.5 → koatl-0.3.7}/koatl/Cargo.toml +1 -1
  4. {koatl-0.3.5 → koatl-0.3.7/koatl}/python/koatl/runtime/meta_finder.py +7 -2
  5. {koatl-0.3.5 → koatl-0.3.7}/koatl/src/lib.rs +22 -6
  6. {koatl-0.3.5 → koatl-0.3.7}/koatl-core/src/lib.rs +18 -17
  7. {koatl-0.3.5 → koatl-0.3.7}/koatl-core/src/lift_cst.rs +1 -1
  8. {koatl-0.3.5 → koatl-0.3.7}/koatl-core/src/transform.rs +21 -4
  9. {koatl-0.3.5 → koatl-0.3.7}/koatl-parser/src/lexer.rs +5 -0
  10. {koatl-0.3.5 → koatl-0.3.7}/koatl-parser/src/parser.rs +10 -2
  11. {koatl-0.3.5/koatl → koatl-0.3.7}/python/koatl/runtime/meta_finder.py +7 -2
  12. {koatl-0.3.5 → koatl-0.3.7}/Cargo.toml +0 -0
  13. {koatl-0.3.5 → koatl-0.3.7}/README.md +0 -0
  14. {koatl-0.3.5 → koatl-0.3.7}/koatl/.github/workflows/CI.yml +0 -0
  15. {koatl-0.3.5 → koatl-0.3.7}/koatl/.gitignore +0 -0
  16. {koatl-0.3.5 → koatl-0.3.7}/koatl/LICENSE +0 -0
  17. {koatl-0.3.5 → koatl-0.3.7}/koatl/README.md +0 -0
  18. {koatl-0.3.5 → koatl-0.3.7}/koatl/python/koatl/__init__.py +0 -0
  19. {koatl-0.3.5 → koatl-0.3.7}/koatl/python/koatl/__main__.py +0 -0
  20. {koatl-0.3.5 → koatl-0.3.7}/koatl/python/koatl/cli.py +0 -0
  21. {koatl-0.3.5 → koatl-0.3.7}/koatl/python/koatl/notebook/__init__.py +0 -0
  22. {koatl-0.3.5 → koatl-0.3.7}/koatl/python/koatl/notebook/magic.py +0 -0
  23. {koatl-0.3.5 → koatl-0.3.7}/koatl/python/koatl/prelude/__init__.tl +0 -0
  24. {koatl-0.3.5 → koatl-0.3.7}/koatl/python/koatl/runtime/__init__.py +0 -0
  25. {koatl-0.3.5 → koatl-0.3.7}/koatl/python/koatl/runtime/record.py +0 -0
  26. {koatl-0.3.5 → koatl-0.3.7}/koatl/python/koatl/runtime/vattr.py +0 -0
  27. {koatl-0.3.5 → koatl-0.3.7}/koatl/python/koatl/std/__init__.tl +0 -0
  28. {koatl-0.3.5 → koatl-0.3.7}/koatl/python/koatl/std/alg/__init__.tl +0 -0
  29. {koatl-0.3.5 → koatl-0.3.7}/koatl/python/koatl/std/alg/async.tl +0 -0
  30. {koatl-0.3.5 → koatl-0.3.7}/koatl/python/koatl/std/alg/base.tl +0 -0
  31. {koatl-0.3.5 → koatl-0.3.7}/koatl/python/koatl/std/alg/do.tl +0 -0
  32. {koatl-0.3.5 → koatl-0.3.7}/koatl/python/koatl/std/alg/env.tl +0 -0
  33. {koatl-0.3.5 → koatl-0.3.7}/koatl/python/koatl/std/alg/memo.tl +0 -0
  34. {koatl-0.3.5 → koatl-0.3.7}/koatl/python/koatl/std/alg/result.tl +0 -0
  35. {koatl-0.3.5 → koatl-0.3.7}/koatl/python/koatl/std/data/__init__.tl +0 -0
  36. {koatl-0.3.5 → koatl-0.3.7}/koatl/python/koatl/std/data/list.tl +0 -0
  37. {koatl-0.3.5 → koatl-0.3.7}/koatl/python/koatl/std/data/record.tl +0 -0
  38. {koatl-0.3.5 → koatl-0.3.7}/koatl/python/koatl/std/ext.tl +0 -0
  39. {koatl-0.3.5 → koatl-0.3.7}/koatl/python/koatl/std/io.tl +0 -0
  40. {koatl-0.3.5 → koatl-0.3.7}/koatl/python/koatl/std/iter.tl +0 -0
  41. {koatl-0.3.5 → koatl-0.3.7}/koatl/python/koatl/std/json.tl +0 -0
  42. {koatl-0.3.5 → koatl-0.3.7}/koatl/python/koatl/std/lazy_module.tl +0 -0
  43. {koatl-0.3.5 → koatl-0.3.7}/koatl/python/koatl/std/pickle.tl +0 -0
  44. {koatl-0.3.5 → koatl-0.3.7}/koatl/python/koatl/std/re.tl +0 -0
  45. {koatl-0.3.5 → koatl-0.3.7}/koatl/python/koatl/std/trait.py +0 -0
  46. {koatl-0.3.5 → koatl-0.3.7}/koatl/requirements.txt +0 -0
  47. {koatl-0.3.5 → koatl-0.3.7}/koatl/src/emit_py.rs +0 -0
  48. {koatl-0.3.5 → koatl-0.3.7}/koatl/tests/e2e/base/containers.tl +0 -0
  49. {koatl-0.3.5 → koatl-0.3.7}/koatl/tests/e2e/base/data.txt +0 -0
  50. {koatl-0.3.5 → koatl-0.3.7}/koatl/tests/e2e/base/decorators.tl +0 -0
  51. {koatl-0.3.5 → koatl-0.3.7}/koatl/tests/e2e/base/destructure-for-and-fn.tl +0 -0
  52. {koatl-0.3.5 → koatl-0.3.7}/koatl/tests/e2e/base/destructure.tl +0 -0
  53. {koatl-0.3.5 → koatl-0.3.7}/koatl/tests/e2e/base/escape_ident.tl +0 -0
  54. {koatl-0.3.5 → koatl-0.3.7}/koatl/tests/e2e/base/fstr.tl +0 -0
  55. {koatl-0.3.5 → koatl-0.3.7}/koatl/tests/e2e/base/functions.tl +0 -0
  56. {koatl-0.3.5 → koatl-0.3.7}/koatl/tests/e2e/base/generator.tl +0 -0
  57. {koatl-0.3.5 → koatl-0.3.7}/koatl/tests/e2e/base/if_expr.tl +0 -0
  58. {koatl-0.3.5 → koatl-0.3.7}/koatl/tests/e2e/base/loops.tl +0 -0
  59. {koatl-0.3.5 → koatl-0.3.7}/koatl/tests/e2e/base/match.tl +0 -0
  60. {koatl-0.3.5 → koatl-0.3.7}/koatl/tests/e2e/base/nary-list.tl +0 -0
  61. {koatl-0.3.5 → koatl-0.3.7}/koatl/tests/e2e/base/placeholder.tl +0 -0
  62. {koatl-0.3.5 → koatl-0.3.7}/koatl/tests/e2e/base/precedence.tl +0 -0
  63. {koatl-0.3.5 → koatl-0.3.7}/koatl/tests/e2e/base/scopes.tl +0 -0
  64. {koatl-0.3.5 → koatl-0.3.7}/koatl/tests/e2e/base/semantic_whitespace.tl +0 -0
  65. {koatl-0.3.5 → koatl-0.3.7}/koatl/tests/e2e/base/short_circuit.tl +0 -0
  66. {koatl-0.3.5 → koatl-0.3.7}/koatl/tests/e2e/base/with.tl +0 -0
  67. {koatl-0.3.5 → koatl-0.3.7}/koatl/tests/e2e/prelude/async.tl +0 -0
  68. {koatl-0.3.5 → koatl-0.3.7}/koatl/tests/e2e/prelude/aug_assign.tl +0 -0
  69. {koatl-0.3.5 → koatl-0.3.7}/koatl/tests/e2e/prelude/coal.tl +0 -0
  70. {koatl-0.3.5 → koatl-0.3.7}/koatl/tests/e2e/prelude/env.tl +0 -0
  71. {koatl-0.3.5 → koatl-0.3.7}/koatl/tests/e2e/prelude/imports.tl +0 -0
  72. {koatl-0.3.5 → koatl-0.3.7}/koatl/tests/e2e/prelude/iterables.tl +0 -0
  73. {koatl-0.3.5 → koatl-0.3.7}/koatl/tests/e2e/prelude/list.tl +0 -0
  74. {koatl-0.3.5 → koatl-0.3.7}/koatl/tests/e2e/prelude/memo.tl +0 -0
  75. {koatl-0.3.5 → koatl-0.3.7}/koatl/tests/e2e/prelude/record.tl +0 -0
  76. {koatl-0.3.5 → koatl-0.3.7}/koatl/tests/e2e/prelude/result.tl +0 -0
  77. {koatl-0.3.5 → koatl-0.3.7}/koatl/tests/e2e/prelude/slice.tl +0 -0
  78. {koatl-0.3.5 → koatl-0.3.7}/koatl/tests/e2e/prelude/try.tl +0 -0
  79. {koatl-0.3.5 → koatl-0.3.7}/koatl/tests/e2e/prelude/virtual.tl +0 -0
  80. {koatl-0.3.5 → koatl-0.3.7}/koatl/tests/e2e/util/__init__.py +0 -0
  81. {koatl-0.3.5 → koatl-0.3.7}/koatl/tests/e2e/util/module0.tl +0 -0
  82. {koatl-0.3.5 → koatl-0.3.7}/koatl/tests/e2e/util/module1.tl +0 -0
  83. {koatl-0.3.5 → koatl-0.3.7}/koatl/tests/e2e/util/module2.tl +0 -0
  84. {koatl-0.3.5 → koatl-0.3.7}/koatl/tests/parse/arith.tl +0 -0
  85. {koatl-0.3.5 → koatl-0.3.7}/koatl/tests/parse/assign.tl +0 -0
  86. {koatl-0.3.5 → koatl-0.3.7}/koatl/tests/parse/block-comments.tl +0 -0
  87. {koatl-0.3.5 → koatl-0.3.7}/koatl/tests/parse/deco.tl +0 -0
  88. {koatl-0.3.5 → koatl-0.3.7}/koatl/tests/parse/func.tl +0 -0
  89. {koatl-0.3.5 → koatl-0.3.7}/koatl/tests/parse/matches.tl +0 -0
  90. {koatl-0.3.5 → koatl-0.3.7}/koatl/tests/parse/numbers.tl +0 -0
  91. {koatl-0.3.5 → koatl-0.3.7}/koatl/tests/test_e2e.py +0 -0
  92. {koatl-0.3.5 → koatl-0.3.7}/koatl/tests/test_parse.py +0 -0
  93. {koatl-0.3.5 → koatl-0.3.7}/koatl-core/Cargo.toml +0 -0
  94. {koatl-0.3.5 → koatl-0.3.7}/koatl-core/src/ast.rs +0 -0
  95. {koatl-0.3.5 → koatl-0.3.7}/koatl-core/src/ast_builder.rs +0 -0
  96. {koatl-0.3.5 → koatl-0.3.7}/koatl-core/src/inference.rs +0 -0
  97. {koatl-0.3.5 → koatl-0.3.7}/koatl-core/src/main.rs +0 -0
  98. {koatl-0.3.5 → koatl-0.3.7}/koatl-core/src/py/ast.rs +0 -0
  99. {koatl-0.3.5 → koatl-0.3.7}/koatl-core/src/py/ast_builder.rs +0 -0
  100. {koatl-0.3.5 → koatl-0.3.7}/koatl-core/src/py/emit.rs +0 -0
  101. {koatl-0.3.5 → koatl-0.3.7}/koatl-core/src/py/mod.rs +0 -0
  102. {koatl-0.3.5 → koatl-0.3.7}/koatl-core/src/resolve_scopes.rs +0 -0
  103. {koatl-0.3.5 → koatl-0.3.7}/koatl-core/src/types.rs +0 -0
  104. {koatl-0.3.5 → koatl-0.3.7}/koatl-core/src/util.rs +0 -0
  105. {koatl-0.3.5 → koatl-0.3.7}/koatl-parser/Cargo.toml +0 -0
  106. {koatl-0.3.5 → koatl-0.3.7}/koatl-parser/src/cst.rs +0 -0
  107. {koatl-0.3.5 → koatl-0.3.7}/koatl-parser/src/lib.rs +0 -0
  108. {koatl-0.3.5 → koatl-0.3.7}/koatl-parser/src/simple_fmt.rs +0 -0
  109. {koatl-0.3.5 → koatl-0.3.7}/pyproject.toml +0 -0
  110. {koatl-0.3.5 → koatl-0.3.7}/python/koatl/__init__.py +0 -0
  111. {koatl-0.3.5 → koatl-0.3.7}/python/koatl/__main__.py +0 -0
  112. {koatl-0.3.5 → koatl-0.3.7}/python/koatl/cli.py +0 -0
  113. {koatl-0.3.5 → koatl-0.3.7}/python/koatl/notebook/__init__.py +0 -0
  114. {koatl-0.3.5 → koatl-0.3.7}/python/koatl/notebook/magic.py +0 -0
  115. {koatl-0.3.5 → koatl-0.3.7}/python/koatl/prelude/__init__.tl +0 -0
  116. {koatl-0.3.5 → koatl-0.3.7}/python/koatl/runtime/__init__.py +0 -0
  117. {koatl-0.3.5 → koatl-0.3.7}/python/koatl/runtime/record.py +0 -0
  118. {koatl-0.3.5 → koatl-0.3.7}/python/koatl/runtime/vattr.py +0 -0
  119. {koatl-0.3.5 → koatl-0.3.7}/python/koatl/std/__init__.tl +0 -0
  120. {koatl-0.3.5 → koatl-0.3.7}/python/koatl/std/alg/__init__.tl +0 -0
  121. {koatl-0.3.5 → koatl-0.3.7}/python/koatl/std/alg/async.tl +0 -0
  122. {koatl-0.3.5 → koatl-0.3.7}/python/koatl/std/alg/base.tl +0 -0
  123. {koatl-0.3.5 → koatl-0.3.7}/python/koatl/std/alg/do.tl +0 -0
  124. {koatl-0.3.5 → koatl-0.3.7}/python/koatl/std/alg/env.tl +0 -0
  125. {koatl-0.3.5 → koatl-0.3.7}/python/koatl/std/alg/memo.tl +0 -0
  126. {koatl-0.3.5 → koatl-0.3.7}/python/koatl/std/alg/result.tl +0 -0
  127. {koatl-0.3.5 → koatl-0.3.7}/python/koatl/std/data/__init__.tl +0 -0
  128. {koatl-0.3.5 → koatl-0.3.7}/python/koatl/std/data/list.tl +0 -0
  129. {koatl-0.3.5 → koatl-0.3.7}/python/koatl/std/data/record.tl +0 -0
  130. {koatl-0.3.5 → koatl-0.3.7}/python/koatl/std/ext.tl +0 -0
  131. {koatl-0.3.5 → koatl-0.3.7}/python/koatl/std/io.tl +0 -0
  132. {koatl-0.3.5 → koatl-0.3.7}/python/koatl/std/iter.tl +0 -0
  133. {koatl-0.3.5 → koatl-0.3.7}/python/koatl/std/json.tl +0 -0
  134. {koatl-0.3.5 → koatl-0.3.7}/python/koatl/std/lazy_module.tl +0 -0
  135. {koatl-0.3.5 → koatl-0.3.7}/python/koatl/std/pickle.tl +0 -0
  136. {koatl-0.3.5 → koatl-0.3.7}/python/koatl/std/re.tl +0 -0
  137. {koatl-0.3.5 → koatl-0.3.7}/python/koatl/std/trait.py +0 -0
@@ -190,7 +190,7 @@ checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
190
190
 
191
191
  [[package]]
192
192
  name = "koatl"
193
- version = "0.3.5"
193
+ version = "0.3.7"
194
194
  dependencies = [
195
195
  "ariadne",
196
196
  "koatl-core",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: koatl
3
- Version: 0.3.5
3
+ Version: 0.3.7
4
4
  Classifier: Programming Language :: Rust
5
5
  Classifier: Programming Language :: Python :: Implementation :: CPython
6
6
  Classifier: Programming Language :: Python :: Implementation :: PyPy
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "koatl"
3
- version = "0.3.5"
3
+ version = "0.3.7"
4
4
  edition = "2021"
5
5
 
6
6
  [lib]
@@ -52,13 +52,18 @@ class TlLoader(Loader):
52
52
  self.filepath,
53
53
  )
54
54
 
55
+ ver = (sys.version_info.major, sys.version_info.minor)
56
+
55
57
  if module.__name__.startswith("koatl"):
56
58
  transpiled_code = transpile(
57
- source_code, mode="no_prelude", filename=self.filepath
59
+ source_code,
60
+ mode="no_prelude",
61
+ filename=self.filepath,
62
+ target_version=ver,
58
63
  )
59
64
  else:
60
65
  transpiled_code = transpile(
61
- source_code, mode="module", filename=self.filepath
66
+ source_code, mode="module", filename=self.filepath, target_version=ver
62
67
  )
63
68
 
64
69
  code = compile(transpiled_code, self.filepath, "exec")
@@ -25,9 +25,17 @@ fn get_option(mode: &str) -> PyResult<TranspileOptions> {
25
25
  })
26
26
  }
27
27
 
28
- #[pyfunction(signature=(src, mode="script", filename="<string>"))]
29
- fn transpile(src: &str, mode: &str, filename: &str) -> PyResult<PyObject> {
30
- let options = get_option(mode)?;
28
+ #[pyfunction(signature=(src, mode="script", filename="<string>", target_version=None))]
29
+ fn transpile(
30
+ src: &str,
31
+ mode: &str,
32
+ filename: &str,
33
+ target_version: Option<(usize, usize)>,
34
+ ) -> PyResult<PyObject> {
35
+ let mut options = get_option(mode)?;
36
+ if let Some(ver) = target_version {
37
+ options.target_version = ver;
38
+ }
31
39
 
32
40
  let py_ast = transpile_to_py_ast(src, filename, options).map_err(|e| {
33
41
  PyErr::new::<pyo3::exceptions::PySyntaxError, _>(format_errs(&e, filename, src))
@@ -39,9 +47,17 @@ fn transpile(src: &str, mode: &str, filename: &str) -> PyResult<PyObject> {
39
47
  Ok(py_ast_obj)
40
48
  }
41
49
 
42
- #[pyfunction(signature=(src, mode="script", filename="<string>"))]
43
- fn transpile_raw(src: &str, mode: &str, filename: &str) -> PyResult<PyObject> {
44
- let options = get_option(mode)?;
50
+ #[pyfunction(signature=(src, mode="script", filename="<string>", target_version=None))]
51
+ fn transpile_raw(
52
+ src: &str,
53
+ mode: &str,
54
+ filename: &str,
55
+ target_version: Option<(usize, usize)>,
56
+ ) -> PyResult<PyObject> {
57
+ let mut options = get_option(mode)?;
58
+ if let Some(ver) = target_version {
59
+ options.target_version = ver;
60
+ }
45
61
 
46
62
  let ctx = transpile_to_source(src, filename, options).map_err(|e| {
47
63
  PyErr::new::<pyo3::exceptions::PySyntaxError, _>(format_errs(&e, filename, src))
@@ -20,6 +20,7 @@ use crate::util::{TlErr, TlErrKind, TlErrs, TlResult};
20
20
  use ariadne::{Color, Label, Report, ReportKind, sources};
21
21
 
22
22
  pub struct TranspileOptions {
23
+ pub target_version: (usize, usize),
23
24
  pub inject_prelude: bool,
24
25
  pub inject_runtime: bool,
25
26
  pub set_exports: bool,
@@ -28,16 +29,23 @@ pub struct TranspileOptions {
28
29
  }
29
30
 
30
31
  impl TranspileOptions {
31
- pub fn script() -> Self {
32
+ pub fn module() -> Self {
32
33
  TranspileOptions {
33
34
  inject_prelude: true,
34
35
  inject_runtime: true,
35
- interactive: false,
36
- set_exports: false,
36
+ set_exports: true,
37
37
  allow_await: false,
38
+ interactive: false,
39
+ target_version: (3, 12),
38
40
  }
39
41
  }
40
42
 
43
+ pub fn script() -> Self {
44
+ let mut opt = TranspileOptions::module();
45
+ opt.set_exports = false;
46
+ opt
47
+ }
48
+
41
49
  pub fn interactive() -> Self {
42
50
  let mut opt = TranspileOptions::script();
43
51
  opt.inject_prelude = false;
@@ -47,16 +55,6 @@ impl TranspileOptions {
47
55
  opt
48
56
  }
49
57
 
50
- pub fn module() -> Self {
51
- TranspileOptions {
52
- allow_await: false,
53
- inject_prelude: true,
54
- inject_runtime: true,
55
- set_exports: true,
56
- interactive: false,
57
- }
58
- }
59
-
60
58
  pub fn no_prelude() -> Self {
61
59
  let mut opt = TranspileOptions::module();
62
60
  opt.inject_prelude = false; // don't inject the prelude when loading prelude
@@ -71,12 +69,12 @@ pub fn transpile_to_py_ast<'src>(
71
69
  ) -> TlResult<PyBlock<'src>> {
72
70
  let (tl_ast, tl_errs) = parse_tl(src);
73
71
 
72
+ let mut errs = tl_errs;
73
+
74
74
  let Some(tl_ast) = tl_ast else {
75
- return Err(tl_errs);
75
+ return Err(errs);
76
76
  };
77
77
 
78
- let mut errs = tl_errs;
79
-
80
78
  let (resolve_state, errors, tl_ast) =
81
79
  resolve_scopes::resolve_names(src, tl_ast, options.allow_await);
82
80
 
@@ -96,7 +94,10 @@ pub fn transpile_to_py_ast<'src>(
96
94
  &tl_ast,
97
95
  &resolve_state,
98
96
  &inference,
99
- options.interactive,
97
+ transform::TransformOptions {
98
+ interactive: options.interactive,
99
+ target_version: options.target_version,
100
+ },
100
101
  ) {
101
102
  Ok(output) => Some(output),
102
103
  Err(e) => {
@@ -468,7 +468,7 @@ impl<'src, 'tok> Lift<Indirect<ast::SStmt<'src>>> for cst::SStmt<'src, 'tok> {
468
468
  ast::Stmt::Import(tree.lift(), export.is_some())
469
469
  }
470
470
  cst::Stmt::Error { .. } => ast::Stmt::Expr(
471
- ast::Expr::Ident(ast::Ident("error".into()).spanned(self.span))
471
+ ast::Expr::Ident(ast::Ident("_ERROR_".into()).spanned(self.span))
472
472
  .spanned(self.span)
473
473
  .indirect(),
474
474
  ),
@@ -70,6 +70,8 @@ struct TlCtx<'src, 'ast> {
70
70
  declarations: &'ast SlotMap<DeclarationKey, Declaration<'src>>,
71
71
 
72
72
  types: &'ast HashMap<RefHash, Type>,
73
+
74
+ target_version: (usize, usize),
73
75
  }
74
76
 
75
77
  impl<'src, 'ast> TlCtx<'src, 'ast> {
@@ -99,6 +101,7 @@ impl<'src, 'ast> TlCtx<'src, 'ast> {
99
101
  declarations: &resolve_state.declarations,
100
102
 
101
103
  types: &inference.types,
104
+ target_version: (3, 12),
102
105
  })
103
106
  }
104
107
 
@@ -208,7 +211,7 @@ fn deduplicate<'src, 'ast>(
208
211
  expr: SPyExpr<'src>,
209
212
  span: Span,
210
213
  ) -> TlResult<SPyExprWithPre<'src>> {
211
- let var_name = ctx.create_aux_var("lhs", span.start);
214
+ let var_name = ctx.create_aux_var("exp", span.start);
212
215
  let a = PyAstBuilder::new(span);
213
216
  let mut pre = PyBlock::new();
214
217
 
@@ -2242,7 +2245,15 @@ impl<'src, 'ast> SExprExt<'src, 'ast> for SExpr<'src> {
2242
2245
  nodes.push(PyFstrPart::Str(begin.value.clone().into()));
2243
2246
 
2244
2247
  for (fmt_expr, str_part) in parts {
2245
- let expr = pre.bind(fmt_expr.expr.transform(ctx)?);
2248
+ // Nested strings are not allowed in f-strings pre 3.12,
2249
+ // so lift the expression part out
2250
+ let expr = if ctx.target_version >= (3, 12) {
2251
+ pre.bind(fmt_expr.expr.transform(ctx)?)
2252
+ } else {
2253
+ let e = pre.bind(fmt_expr.expr.transform(ctx)?);
2254
+ pre.bind(deduplicate(ctx, e, fmt_expr.expr.span)?)
2255
+ };
2256
+
2246
2257
  let fmt = fmt_expr
2247
2258
  .fmt
2248
2259
  .as_ref()
@@ -2369,6 +2380,11 @@ fn py_fn_bindings<'src, 'ast>(
2369
2380
  Ok((py_body, nonlocals, globals))
2370
2381
  }
2371
2382
 
2383
+ pub struct TransformOptions {
2384
+ pub interactive: bool,
2385
+ pub target_version: (usize, usize),
2386
+ }
2387
+
2372
2388
  pub struct TransformOutput<'src> {
2373
2389
  pub py_block: PyBlock<'src>,
2374
2390
  pub exports: Vec<PyToken<'src>>,
@@ -2381,11 +2397,12 @@ pub fn transform_ast<'src, 'ast>(
2381
2397
  block: &'ast SExpr<'src>,
2382
2398
  resolve_state: &'ast ResolveState<'src>,
2383
2399
  inference: &'ast InferenceCtx<'src, 'ast>,
2384
- interactive: bool,
2400
+ options: TransformOptions,
2385
2401
  ) -> TlResult<TransformOutput<'src>> {
2386
2402
  let mut ctx = TlCtx::new(source, filename, resolve_state, inference)?;
2403
+ ctx.target_version = options.target_version;
2387
2404
 
2388
- let py_block = if interactive {
2405
+ let py_block = if options.interactive {
2389
2406
  let mut py_value = block.transform(&mut ctx)?;
2390
2407
  let span = py_value.value.tl_span;
2391
2408
  py_value
@@ -1542,6 +1542,11 @@ impl<'src> TokenizeCtx<'src> {
1542
1542
  }
1543
1543
  };
1544
1544
 
1545
+ if delim_stack.len() > 0 {
1546
+ let (_unmatched_char, span) = delim_stack.pop().unwrap();
1547
+ return Err(LexError::custom(span, "unmatched delimiter"));
1548
+ }
1549
+
1545
1550
  let len = tokens.len();
1546
1551
  for i in (0..len).rev() {
1547
1552
  // avoid putting trivia on an eol token
@@ -2455,7 +2455,7 @@ impl<'src: 'tok, 'tok> ParseCtx<'src, 'tok> {
2455
2455
  }
2456
2456
  None => {
2457
2457
  stmts.push(err_stmt);
2458
- break 'outer;
2458
+ return Err(());
2459
2459
  }
2460
2460
  }
2461
2461
  self.next();
@@ -2509,7 +2509,15 @@ pub fn parse_tokens<'src: 'tok, 'tok>(
2509
2509
  .map(|err| {
2510
2510
  (
2511
2511
  true_span(err.index, err.index + 1, ctx.input),
2512
- format!("{:?}. Found: {:?}", err.message, tokens.0[err.index].token),
2512
+ format!(
2513
+ "{:?}. Found: {}",
2514
+ err.message,
2515
+ tokens
2516
+ .0
2517
+ .get(err.index)
2518
+ .map(|x| format!("{:?}", x.token))
2519
+ .unwrap_or("Eof".into())
2520
+ ),
2513
2521
  )
2514
2522
  })
2515
2523
  .collect(),
@@ -52,13 +52,18 @@ class TlLoader(Loader):
52
52
  self.filepath,
53
53
  )
54
54
 
55
+ ver = (sys.version_info.major, sys.version_info.minor)
56
+
55
57
  if module.__name__.startswith("koatl"):
56
58
  transpiled_code = transpile(
57
- source_code, mode="no_prelude", filename=self.filepath
59
+ source_code,
60
+ mode="no_prelude",
61
+ filename=self.filepath,
62
+ target_version=ver,
58
63
  )
59
64
  else:
60
65
  transpiled_code = transpile(
61
- source_code, mode="module", filename=self.filepath
66
+ source_code, mode="module", filename=self.filepath, target_version=ver
62
67
  )
63
68
 
64
69
  code = compile(transpiled_code, self.filepath, "exec")
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes