diff --git a/pdl-live/src/pdl_ast.d.ts b/pdl-live/src/pdl_ast.d.ts index d34c57bf..157efd4c 100644 --- a/pdl-live/src/pdl_ast.d.ts +++ b/pdl-live/src/pdl_ast.d.ts @@ -1240,6 +1240,10 @@ export type Repeat = | ErrorBlock | EmptyBlock )[]; +/** + * Define how to combine the result of each iteration. + * + */ export type IterationType = "sequence" | "array" | "document"; export type Trace1 = | ( @@ -1425,6 +1429,11 @@ export type Repeat1 = | ErrorBlock | EmptyBlock )[]; +/** + * Define how to combine the result of each iteration. + * + */ +export type IterationType1 = "sequence" | "array" | "document"; export type Trace2 = | ( | number @@ -1614,6 +1623,11 @@ export type Repeat2 = * */ export type NumIterations = number; +/** + * Define how to combine the result of each iteration. + * + */ +export type IterationType2 = "sequence" | "array" | "document"; export type Trace3 = | ( | number @@ -1930,6 +1944,10 @@ export type Fallback12 = export type Role12 = string | null; export type HasError12 = boolean; export type Kind12 = "data"; +/** + * Do not evaluate expressions inside strings. + */ +export type Raw = boolean; /** * Name of the variable used to store the result of the execution of the block. * @@ -3878,6 +3896,7 @@ export interface DataBlock { has_error?: HasError12; kind?: Kind12; data: Data; + raw?: Raw; } /** * Type specification of the result of the block. @@ -4044,11 +4063,7 @@ export interface RepeatBlock { kind?: Kind10; repeat: Repeat2; num_iterations: NumIterations; - /** - * Define how to combine the result of each iteration. - * - */ - as?: IterationType & string; + as?: IterationType2; trace?: Trace3; } /** @@ -4132,11 +4147,7 @@ export interface RepeatUntilBlock { kind?: Kind9; repeat: Repeat1; until: Until; - /** - * Define how to combine the result of each iteration. - * - */ - as?: IterationType & string; + as?: IterationType1; trace?: Trace2; } /** @@ -4220,11 +4231,7 @@ export interface ForBlock { kind?: Kind8; for: For; repeat: Repeat; - /** - * Define how to combine the result of each iteration. - * - */ - as?: IterationType & string; + as?: IterationType; trace?: Trace1; } /** diff --git a/pdl-schema.json b/pdl-schema.json index 5e4b9dac..c1407984 100644 --- a/pdl-schema.json +++ b/pdl-schema.json @@ -3835,6 +3835,12 @@ "data": { "description": "Value defined.", "title": "Data" + }, + "raw": { + "default": false, + "description": "Do not evaluate expressions inside strings.", + "title": "Raw", + "type": "boolean" } }, "required": [ diff --git a/pdl/pdl.py b/pdl/pdl.py index d1f15379..02f226b9 100644 --- a/pdl/pdl.py +++ b/pdl/pdl.py @@ -60,7 +60,7 @@ def exec_program( state = InterpreterState(**config) scope = scope or {} loc = loc or empty_block_location - result = process_prog(state, scope, prog, loc) + result, _, _, _ = process_prog(state, scope, prog, loc) return result diff --git a/pdl/pdl_ast.py b/pdl/pdl_ast.py index 12d0245c..154302e1 100644 --- a/pdl/pdl_ast.py +++ b/pdl/pdl_ast.py @@ -316,6 +316,8 @@ class DataBlock(Block): kind: Literal[BlockKind.DATA] = BlockKind.DATA data: ExpressionType """Value defined.""" + raw: bool = False + """Do not evaluate expressions inside strings.""" class DocumentBlock(Block): diff --git a/pdl/pdl_dumper.py b/pdl/pdl_dumper.py index 8b0b1216..4c6f5678 100644 --- a/pdl/pdl_dumper.py +++ b/pdl/pdl_dumper.py @@ -112,6 +112,8 @@ def block_to_dict(block: pdl_ast.BlockType) -> int | float | str | dict[str, Any d["get"] = block.get case DataBlock(): d["data"] = block.data + if block.raw: + d["raw"] = block.raw case ApiBlock(): d["api"] = block.api d["url"] = block.url diff --git a/pdl/pdl_interpreter.py b/pdl/pdl_interpreter.py index 1ad10954..11828184 100644 --- a/pdl/pdl_interpreter.py +++ b/pdl/pdl_interpreter.py @@ -315,16 +315,21 @@ def step_block_body( yield YieldBackgroundMessage(background) case DataBlock(data=v): block.location = append(loc, "data") - result, errors = process_expr(scope, v, append(loc, "data")) - if len(errors) != 0: - result = None - background = [] - trace = handle_error( - block, append(loc, "data"), None, errors, block.model_copy() - ) - else: + if block.raw: + result = v background = [{"role": state.role, "content": stringify(result)}] trace = block.model_copy() + else: + result, errors = process_expr(scope, v, append(loc, "data")) + if len(errors) != 0: + result = None + background = [] + trace = handle_error( + block, append(loc, "data"), None, errors, block.model_copy() + ) + else: + background = [{"role": state.role, "content": stringify(result)}] + trace = block.model_copy() if state.yield_result: yield YieldResultMessage(result) if state.yield_background: diff --git a/tests/test_data.py b/tests/test_data.py new file mode 100644 index 00000000..e20611af --- /dev/null +++ b/tests/test_data.py @@ -0,0 +1,64 @@ +from pdl.pdl import exec_str + + +def test_int(): + prog_str = """ +data: 1 +""" + result = exec_str(prog_str) + assert result == 1 + + +def test_array(): + prog_str = """ +data: + - 1 + - 2 + - 3 + - bye +""" + result = exec_str(prog_str) + assert result == [1, 2, 3, "bye"] + + +def test_object(): + prog_str = """ +data: + document: Hello + model: + - a + - b +""" + result = exec_str(prog_str) + assert result == {"document": "Hello", "model": ["a", "b"]} + + +def test_expr(): + prog_str = """ +defs: + x: a + y: b +data: + document: Hello + model: + - "{{ x }}" + - "{{ y }}" +""" + result = exec_str(prog_str) + assert result == {"document": "Hello", "model": ["a", "b"]} + + +def test_raw(): + prog_str = """ +defs: + x: a + y: b +data: + document: Hello + model: + - "{{ x }}" + - "{{ y }}" +raw: true +""" + result = exec_str(prog_str) + assert result == {"document": "Hello", "model": ["{{ x }}", "{{ y }}"]}