From 6dfa9480b43195dcc021dc0180c9d620787b421f Mon Sep 17 00:00:00 2001 From: Louis Mandel Date: Thu, 19 Dec 2024 13:41:00 -0500 Subject: [PATCH 1/7] The argument of `call:` should be a function not a name --- docs/tutorial.md | 2 +- examples/demo/2-teacher.pdl | 32 ++++++++-------- examples/hello/hello-data.pdl | 2 +- examples/hello/hello-defs.pdl | 2 +- examples/hello/hello-function-alias.pdl | 2 +- examples/hello/hello-function.pdl | 2 +- examples/hello/hello-type.pdl | 4 +- examples/notebooks/notebook_debug.ipynb | 2 +- examples/react/react_call.pdl | 2 +- examples/react/react_fun.pdl | 2 +- examples/talk/10-sdg.pdl | 32 ++++++++-------- examples/talk/4-function.pdl | 4 +- examples/teacher/teacher.pdl | 32 ++++++++-------- examples/tutorial/function_definition.pdl | 4 +- examples/tutorial/grouping_definitions.pdl | 4 +- examples/tutorial/muting_block_output.pdl | 2 +- src/pdl/pdl_interpreter.py | 14 ++----- src/pdl_server/__init__.py | 0 src/pdl_server/pdl_server.py | 11 ++++++ tests/data/call_expression_args.pdl | 4 +- tests/data/line/hello14.pdl | 2 +- tests/data/line/hello15.pdl | 2 +- tests/data/line/hello24.pdl | 2 +- tests/data/line/hello25.pdl | 2 +- tests/test_function.py | 10 ++--- tests/test_include.py | 2 +- tests/test_runtime_errors.py | 4 +- tests/test_type_checking.py | 44 ++++++++++++---------- tests/test_var.py | 2 +- 29 files changed, 119 insertions(+), 110 deletions(-) create mode 100644 src/pdl_server/__init__.py create mode 100644 src/pdl_server/pdl_server.py diff --git a/docs/tutorial.md b/docs/tutorial.md index 7b6e5d558..43ff46183 100644 --- a/docs/tutorial.md +++ b/docs/tutorial.md @@ -144,7 +144,7 @@ Suppose we want to define a translation function that takes a string and calls a In this program, the first block defines a function `translate` that takes as parameters `sentence` and `language`, both of which are of type string. The body of the function is defined by its `return` field. In this case, we formulate a translation prompt using the parameters and send it to a Granite multilingual model. -The last two blocks are calls to this function, as indicated by `call: translate`. This block specifies the arguments to be passed. When we execute this program, we obtain: +The last two blocks are calls to this function, as indicated by `call: ${ translate }`. This block specifies the arguments to be passed. When we execute this program, we obtain: ``` The translation of 'I love Paris!' to French is 'J'aime Paris!'. diff --git a/examples/demo/2-teacher.pdl b/examples/demo/2-teacher.pdl index 4bef459c3..73aab9b49 100644 --- a/examples/demo/2-teacher.pdl +++ b/examples/demo/2-teacher.pdl @@ -48,14 +48,14 @@ defs: return: defs: prompt_data: - call: question_template_freeform + call: ${question_template_freeform} spec: { introduction: str, principles: str, examples: str, generation: str, max_new_tokens: int } args: num_samples: ${num_samples} task_description: ${task_description} icl_question: ${icl_question} teacher_input: - call: teacher_template + call: ${teacher_template} args: sys_prompt: ${teacher_sys_prompt} prompt: |- @@ -94,7 +94,7 @@ defs: for: example: ${seed_examples} repeat: - call: gen_questions_freeform_inner + call: ${gen_questions_freeform_inner} args: num_samples: 2 task_description: ${task_description} @@ -139,13 +139,13 @@ defs: return: defs: prompt_data: - call: filter_questions_template + call: ${filter_questions_template} spec: {introduction: str, principles: str, generation: str, max_new_tokens: int} args: task_description: ${task_description} question: ${question} teacher_input: - call: teacher_template + call: ${teacher_template} args: sys_prompt: ${teacher_sys_prompt} prompt: |- @@ -179,7 +179,7 @@ defs: repeat: defs: filter_output: - call: filter_questions_inner + call: ${filter_questions_inner} args: task_description: ${task_description} question: ${question.question} @@ -233,14 +233,14 @@ defs: return: defs: prompt_data: - call: answer_template + call: ${answer_template} spec: {introduction: str, principles: str, examples: str, generation: str, max_new_tokens: int, additional_stop_tokens: [str]} args: icl_question: ${question.icl_question} icl_response: ${question.icl_answer} question: ${question.question} teacher_input: - call: teacher_template + call: ${teacher_template} args: sys_prompt: ${teacher_sys_prompt} prompt: |- @@ -278,7 +278,7 @@ defs: for: question: ${ questions } repeat: - call: gen_answers_inner + call: ${gen_answers_inner} args: question: ${question} join: @@ -322,13 +322,13 @@ defs: return: defs: prompt_data: - call: filter_qa_template + call: ${filter_qa_template} spec: {introduction: str, principles: str, generation: str, max_new_tokens: int} args: question: ${question} answer: ${answer} teacher_input: - call: teacher_template + call: ${teacher_template} args: sys_prompt: ${teacher_sys_prompt} prompt: |- @@ -360,7 +360,7 @@ defs: repeat: defs: filter_output: - call: filter_question_answer_pair_inner + call: ${filter_question_answer_pair_inner} spec: float args: question: ${qa_pair.question} @@ -385,25 +385,25 @@ text: parser: yaml - "\n\n----- Generating questions -----\n\n" - def: generated_questions - call: gen_questions_freeform + call: ${gen_questions_freeform} spec: [{icl_question: str, icl_answer: str, question: str}] args: task_description: ${seed_examples.task_description} seed_examples: ${seed_examples.seed_examples} - "\n\n----- Filtering questions -----\n\n" - def: filtered_questions - call: filter_questions + call: ${filter_questions} spec: [{icl_question: str, icl_answer: str, question: str}] args: task_description: ${seed_examples.task_description} questions: ${generated_questions} - "\n\n----- Generating answers -----\n\n" - def: qa_pairs - call: gen_answers + call: ${gen_answers} args: questions: ${filtered_questions} - "\n\n----- Filtering QA pairs -----\n\n" -- call: filter_question_answer_pair +- call: ${filter_question_answer_pair} args: qa_pairs: ${qa_pairs} diff --git a/examples/hello/hello-data.pdl b/examples/hello/hello-data.pdl index 449db0846..c47b44235 100644 --- a/examples/hello/hello-data.pdl +++ b/examples/hello/hello-data.pdl @@ -6,7 +6,7 @@ text: return: ${ something } - "Hello World!\n" -- call: stutter +- call: ${ stutter } - "\n" diff --git a/examples/hello/hello-defs.pdl b/examples/hello/hello-defs.pdl index d30ac107e..1d3a2f41f 100644 --- a/examples/hello/hello-defs.pdl +++ b/examples/hello/hello-defs.pdl @@ -7,7 +7,7 @@ defs: bye: "Good bye" text: -- call: hello +- call: ${ hello } args: name: World - "\n" diff --git a/examples/hello/hello-function-alias.pdl b/examples/hello/hello-function-alias.pdl index 19299a14a..a26f45d22 100644 --- a/examples/hello/hello-function-alias.pdl +++ b/examples/hello/hello-function-alias.pdl @@ -4,7 +4,7 @@ defs: function: name: str return: Hello ${ name }! - alias: hello + alias: ${ hello } text: - call: ${ alias } args: diff --git a/examples/hello/hello-function.pdl b/examples/hello/hello-function.pdl index c217c1b6d..8aa71d5e4 100644 --- a/examples/hello/hello-function.pdl +++ b/examples/hello/hello-function.pdl @@ -4,6 +4,6 @@ text: function: name: str return: Hello ${ name }! -- call: hello +- call: ${ hello } args: name: World diff --git a/examples/hello/hello-type.pdl b/examples/hello/hello-type.pdl index 7d13fd180..beecaa867 100644 --- a/examples/hello/hello-type.pdl +++ b/examples/hello/hello-type.pdl @@ -14,12 +14,12 @@ text: - model: replicate/ibm-granite/granite-3.0-8b-instruct parameters: stop_sequences: "\n" -- call: translate +- call: ${ translate } spec: str args: sentence: ${ GEN } language: French -- call: translate +- call: ${ translate } args: sentence: ${ GEN } language: Spanish diff --git a/examples/notebooks/notebook_debug.ipynb b/examples/notebooks/notebook_debug.ipynb index 744ef498a..8bd67bf57 100644 --- a/examples/notebooks/notebook_debug.ipynb +++ b/examples/notebooks/notebook_debug.ipynb @@ -180,7 +180,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3 (ipykernel)", + "display_name": "pdl-3.12", "language": "python", "name": "python3" }, diff --git a/examples/react/react_call.pdl b/examples/react/react_call.pdl index 2ad7043a8..81d1c9b5c 100644 --- a/examples/react/react_call.pdl +++ b/examples/react/react_call.pdl @@ -1,7 +1,7 @@ description: Wikipedia example using the react_fun function definition text: - include: ./react_fun.pdl - - call: react + - call: ${ react } args: question: How many years ago was the discoverer of the Hudson River born? Keep in mind we are in 2024. model: replicate/ibm-granite/granite-3.0-8b-instruct diff --git a/examples/react/react_fun.pdl b/examples/react/react_fun.pdl index bb8d417e4..424ddc17c 100644 --- a/examples/react/react_fun.pdl +++ b/examples/react/react_fun.pdl @@ -121,7 +121,7 @@ defs: Act: [{"name": "Finish", "arguments": {"topic": "director, screenwriter, actor"}}] - call: react_inner + call: ${ react_inner } args: pdl_context: [] examples: ${ examples } diff --git a/examples/talk/10-sdg.pdl b/examples/talk/10-sdg.pdl index 4bef459c3..73aab9b49 100644 --- a/examples/talk/10-sdg.pdl +++ b/examples/talk/10-sdg.pdl @@ -48,14 +48,14 @@ defs: return: defs: prompt_data: - call: question_template_freeform + call: ${question_template_freeform} spec: { introduction: str, principles: str, examples: str, generation: str, max_new_tokens: int } args: num_samples: ${num_samples} task_description: ${task_description} icl_question: ${icl_question} teacher_input: - call: teacher_template + call: ${teacher_template} args: sys_prompt: ${teacher_sys_prompt} prompt: |- @@ -94,7 +94,7 @@ defs: for: example: ${seed_examples} repeat: - call: gen_questions_freeform_inner + call: ${gen_questions_freeform_inner} args: num_samples: 2 task_description: ${task_description} @@ -139,13 +139,13 @@ defs: return: defs: prompt_data: - call: filter_questions_template + call: ${filter_questions_template} spec: {introduction: str, principles: str, generation: str, max_new_tokens: int} args: task_description: ${task_description} question: ${question} teacher_input: - call: teacher_template + call: ${teacher_template} args: sys_prompt: ${teacher_sys_prompt} prompt: |- @@ -179,7 +179,7 @@ defs: repeat: defs: filter_output: - call: filter_questions_inner + call: ${filter_questions_inner} args: task_description: ${task_description} question: ${question.question} @@ -233,14 +233,14 @@ defs: return: defs: prompt_data: - call: answer_template + call: ${answer_template} spec: {introduction: str, principles: str, examples: str, generation: str, max_new_tokens: int, additional_stop_tokens: [str]} args: icl_question: ${question.icl_question} icl_response: ${question.icl_answer} question: ${question.question} teacher_input: - call: teacher_template + call: ${teacher_template} args: sys_prompt: ${teacher_sys_prompt} prompt: |- @@ -278,7 +278,7 @@ defs: for: question: ${ questions } repeat: - call: gen_answers_inner + call: ${gen_answers_inner} args: question: ${question} join: @@ -322,13 +322,13 @@ defs: return: defs: prompt_data: - call: filter_qa_template + call: ${filter_qa_template} spec: {introduction: str, principles: str, generation: str, max_new_tokens: int} args: question: ${question} answer: ${answer} teacher_input: - call: teacher_template + call: ${teacher_template} args: sys_prompt: ${teacher_sys_prompt} prompt: |- @@ -360,7 +360,7 @@ defs: repeat: defs: filter_output: - call: filter_question_answer_pair_inner + call: ${filter_question_answer_pair_inner} spec: float args: question: ${qa_pair.question} @@ -385,25 +385,25 @@ text: parser: yaml - "\n\n----- Generating questions -----\n\n" - def: generated_questions - call: gen_questions_freeform + call: ${gen_questions_freeform} spec: [{icl_question: str, icl_answer: str, question: str}] args: task_description: ${seed_examples.task_description} seed_examples: ${seed_examples.seed_examples} - "\n\n----- Filtering questions -----\n\n" - def: filtered_questions - call: filter_questions + call: ${filter_questions} spec: [{icl_question: str, icl_answer: str, question: str}] args: task_description: ${seed_examples.task_description} questions: ${generated_questions} - "\n\n----- Generating answers -----\n\n" - def: qa_pairs - call: gen_answers + call: ${gen_answers} args: questions: ${filtered_questions} - "\n\n----- Filtering QA pairs -----\n\n" -- call: filter_question_answer_pair +- call: ${filter_question_answer_pair} args: qa_pairs: ${qa_pairs} diff --git a/examples/talk/4-function.pdl b/examples/talk/4-function.pdl index 2d33c387f..a63594eee 100644 --- a/examples/talk/4-function.pdl +++ b/examples/talk/4-function.pdl @@ -11,12 +11,12 @@ text: parameters: stop_sequences: "\n" temperature: 0 -- call: translate +- call: ${ translate } args: sentence: I love Paris! language: French - "\n" -- call: translate +- call: ${ translate } args: sentence: I love Madrid! language: Spanish diff --git a/examples/teacher/teacher.pdl b/examples/teacher/teacher.pdl index 4bef459c3..73aab9b49 100644 --- a/examples/teacher/teacher.pdl +++ b/examples/teacher/teacher.pdl @@ -48,14 +48,14 @@ defs: return: defs: prompt_data: - call: question_template_freeform + call: ${question_template_freeform} spec: { introduction: str, principles: str, examples: str, generation: str, max_new_tokens: int } args: num_samples: ${num_samples} task_description: ${task_description} icl_question: ${icl_question} teacher_input: - call: teacher_template + call: ${teacher_template} args: sys_prompt: ${teacher_sys_prompt} prompt: |- @@ -94,7 +94,7 @@ defs: for: example: ${seed_examples} repeat: - call: gen_questions_freeform_inner + call: ${gen_questions_freeform_inner} args: num_samples: 2 task_description: ${task_description} @@ -139,13 +139,13 @@ defs: return: defs: prompt_data: - call: filter_questions_template + call: ${filter_questions_template} spec: {introduction: str, principles: str, generation: str, max_new_tokens: int} args: task_description: ${task_description} question: ${question} teacher_input: - call: teacher_template + call: ${teacher_template} args: sys_prompt: ${teacher_sys_prompt} prompt: |- @@ -179,7 +179,7 @@ defs: repeat: defs: filter_output: - call: filter_questions_inner + call: ${filter_questions_inner} args: task_description: ${task_description} question: ${question.question} @@ -233,14 +233,14 @@ defs: return: defs: prompt_data: - call: answer_template + call: ${answer_template} spec: {introduction: str, principles: str, examples: str, generation: str, max_new_tokens: int, additional_stop_tokens: [str]} args: icl_question: ${question.icl_question} icl_response: ${question.icl_answer} question: ${question.question} teacher_input: - call: teacher_template + call: ${teacher_template} args: sys_prompt: ${teacher_sys_prompt} prompt: |- @@ -278,7 +278,7 @@ defs: for: question: ${ questions } repeat: - call: gen_answers_inner + call: ${gen_answers_inner} args: question: ${question} join: @@ -322,13 +322,13 @@ defs: return: defs: prompt_data: - call: filter_qa_template + call: ${filter_qa_template} spec: {introduction: str, principles: str, generation: str, max_new_tokens: int} args: question: ${question} answer: ${answer} teacher_input: - call: teacher_template + call: ${teacher_template} args: sys_prompt: ${teacher_sys_prompt} prompt: |- @@ -360,7 +360,7 @@ defs: repeat: defs: filter_output: - call: filter_question_answer_pair_inner + call: ${filter_question_answer_pair_inner} spec: float args: question: ${qa_pair.question} @@ -385,25 +385,25 @@ text: parser: yaml - "\n\n----- Generating questions -----\n\n" - def: generated_questions - call: gen_questions_freeform + call: ${gen_questions_freeform} spec: [{icl_question: str, icl_answer: str, question: str}] args: task_description: ${seed_examples.task_description} seed_examples: ${seed_examples.seed_examples} - "\n\n----- Filtering questions -----\n\n" - def: filtered_questions - call: filter_questions + call: ${filter_questions} spec: [{icl_question: str, icl_answer: str, question: str}] args: task_description: ${seed_examples.task_description} questions: ${generated_questions} - "\n\n----- Generating answers -----\n\n" - def: qa_pairs - call: gen_answers + call: ${gen_answers} args: questions: ${filtered_questions} - "\n\n----- Filtering QA pairs -----\n\n" -- call: filter_question_answer_pair +- call: ${filter_question_answer_pair} args: qa_pairs: ${qa_pairs} diff --git a/examples/tutorial/function_definition.pdl b/examples/tutorial/function_definition.pdl index 2d33c387f..a63594eee 100644 --- a/examples/tutorial/function_definition.pdl +++ b/examples/tutorial/function_definition.pdl @@ -11,12 +11,12 @@ text: parameters: stop_sequences: "\n" temperature: 0 -- call: translate +- call: ${ translate } args: sentence: I love Paris! language: French - "\n" -- call: translate +- call: ${ translate } args: sentence: I love Madrid! language: Spanish diff --git a/examples/tutorial/grouping_definitions.pdl b/examples/tutorial/grouping_definitions.pdl index 0258c1786..71b1a666b 100644 --- a/examples/tutorial/grouping_definitions.pdl +++ b/examples/tutorial/grouping_definitions.pdl @@ -11,12 +11,12 @@ defs: parameters: stop_sequences: "\n" text: -- call: translate +- call: ${ translate } args: sentence: I love Paris! language: French - "\n" -- call: translate +- call: ${ translate } args: sentence: I love Madrid! language: Spanish \ No newline at end of file diff --git a/examples/tutorial/muting_block_output.pdl b/examples/tutorial/muting_block_output.pdl index 311b2d68c..c29898c2e 100644 --- a/examples/tutorial/muting_block_output.pdl +++ b/examples/tutorial/muting_block_output.pdl @@ -12,7 +12,7 @@ defs: parameters: stop_sequences: "\n" text: -- call: translate +- call: ${ translate } contribute: [] def: FRENCH args: diff --git a/src/pdl/pdl_interpreter.py b/src/pdl/pdl_interpreter.py index e20ff3004..06e197ce7 100644 --- a/src/pdl/pdl_interpreter.py +++ b/src/pdl/pdl_interpreter.py @@ -1429,20 +1429,12 @@ def step_call( result = None background: Messages = [] args, block = process_expr_of(block, "args", scope, loc) - closure_expr, block = process_expr_of(block, "call", scope, loc) - try: - closure = get_var(closure_expr, scope, append(loc, "call")) - except PDLRuntimeExpressionError as exc: - raise PDLRuntimeError( - exc.message, - loc=exc.loc or loc, - trace=ErrorBlock(msg=exc.message, location=loc, program=block), - ) from exc + closure, block = process_expr_of(block, "call", scope, loc) args_loc = append(loc, "args") type_errors = type_check_args(args, closure.function, args_loc) if len(type_errors) > 0: raise PDLRuntimeError( - f"Type errors during function call to {closure_expr}:\n" + f"Type errors during function call to {block.call}:\n" + "\n".join(type_errors), loc=args_loc, trace=block.model_copy(), @@ -1469,7 +1461,7 @@ def step_call( errors = type_check_spec(result, closure.spec, fun_loc) if len(errors) > 0: raise PDLRuntimeError( - f"Type errors in result of function call to {closure_expr}:\n" + f"Type errors in result of function call to {block.call}:\n" + "\n".join(errors), loc=loc, trace=trace, diff --git a/src/pdl_server/__init__.py b/src/pdl_server/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/src/pdl_server/pdl_server.py b/src/pdl_server/pdl_server.py new file mode 100644 index 000000000..ec92a2857 --- /dev/null +++ b/src/pdl_server/pdl_server.py @@ -0,0 +1,11 @@ +from flask import Flask, jsonify, request +from pdl import pdl +app = Flask(__name__) + + +@app.route('/exec_str', methods=['POST']) +def get_exec_str(): + args = request.get_json() + result = pdl.exec_str(**args) + return jsonify(result) + diff --git a/tests/data/call_expression_args.pdl b/tests/data/call_expression_args.pdl index 08644f004..762420d82 100644 --- a/tests/data/call_expression_args.pdl +++ b/tests/data/call_expression_args.pdl @@ -12,12 +12,12 @@ text: contribute: [] - def: simple_call - call: get_current_stock + call: ${ get_current_stock } args: product_name: "Simple call!" - "${object_example}\n" - def: with_object_args - call: get_current_stock + call: ${ get_current_stock } args: ${object_example} \ No newline at end of file diff --git a/tests/data/line/hello14.pdl b/tests/data/line/hello14.pdl index fb049f368..3b107f6f8 100644 --- a/tests/data/line/hello14.pdl +++ b/tests/data/line/hello14.pdl @@ -22,7 +22,7 @@ text: - '!' include_stop_sequence: true mock_response: "Bonjour le monde!" -- call: translate +- call: ${ translate } spec: str args: sentence: Hello,${ GEN } diff --git a/tests/data/line/hello15.pdl b/tests/data/line/hello15.pdl index f07835947..076bc96b1 100644 --- a/tests/data/line/hello15.pdl +++ b/tests/data/line/hello15.pdl @@ -7,4 +7,4 @@ text: - get: boolean - ${ something } - "Hello World!\n" -- call: stutter +- call: ${ stutter } diff --git a/tests/data/line/hello24.pdl b/tests/data/line/hello24.pdl index b9a0020a1..f6a4ce9b0 100644 --- a/tests/data/line/hello24.pdl +++ b/tests/data/line/hello24.pdl @@ -19,7 +19,7 @@ text: - model: watsonx/ibm/granite-34b-code-instruct parameters: mock_response: " World!" -- call: translate +- call: ${ translate } spec: str args: sentence: Hello,${ GEN1 } diff --git a/tests/data/line/hello25.pdl b/tests/data/line/hello25.pdl index aad49031d..dd8343465 100644 --- a/tests/data/line/hello25.pdl +++ b/tests/data/line/hello25.pdl @@ -20,7 +20,7 @@ text: - "!" - "\n" include_stop_sequence: true -- call: translate +- call: ${ translate } spec: str args: sentence: Hello,${ GEN } diff --git a/tests/test_function.py b/tests/test_function.py index e1d1a9a89..ef045b2b1 100644 --- a/tests/test_function.py +++ b/tests/test_function.py @@ -13,7 +13,7 @@ "return": "Hello world!", } -hello_call = {"description": "Call hello", "text": [hello_def, {"call": "hello"}]} +hello_call = {"description": "Call hello", "text": [hello_def, {"call": "${ hello }"}]} def test_function_def(): @@ -39,7 +39,7 @@ def test_function_call(): "function": {"name": "str"}, "return": {"text": ["Hello ", {"get": "name"}, "!"]}, }, - {"call": "hello", "args": {"name": "World"}}, + {"call": "${ hello }", "args": {"name": "World"}}, ], } @@ -56,7 +56,7 @@ def test_function_params(): "text": [ {"def": "stutter", "function": None, "return": "${ pdl_context[0].content }"}, "Hello World!\n", - {"call": "stutter"}, + {"call": "${ stutter }"}, ], } @@ -74,7 +74,7 @@ def test_function_implicit_context(): {"def": "stutter", "function": {}, "return": "${ pdl_context[0].content }"}, "Hello World!\n", { - "call": "stutter", + "call": "${ stutter }", "args": {"pdl_context": [{"role": None, "content": "Bye!"}]}, }, ], @@ -91,7 +91,7 @@ def test_function_explicit_context(): hello_call_template = { "description": "Call hello template", "text": [ - {"defs": {"alias": "hello"}}, + {"defs": {"alias": "${ hello }"}}, { "description": "Define hello", "def": "hello", diff --git a/tests/test_include.py b/tests/test_include.py index 91e7d1730..85154e9d4 100644 --- a/tests/test_include.py +++ b/tests/test_include.py @@ -32,7 +32,7 @@ def test_include(): "text": [ {"include": "data/function.pdl"}, { - "call": "template", + "call": "${ template }", "args": { "preamble": "preamble data", "question": "question data", diff --git a/tests/test_runtime_errors.py b/tests/test_runtime_errors.py index 70ee16539..7263affbe 100644 --- a/tests/test_runtime_errors.py +++ b/tests/test_runtime_errors.py @@ -99,7 +99,7 @@ def test_get(): def test_call_undefined(): prog_str = """ -call: "f" +call: "${ f }" """ with pytest.raises(PDLRuntimeError) as exc: exec_str(prog_str) @@ -128,7 +128,7 @@ def test_call_bad_args(): function: x: int return: Hello -call: "f" +call: ${ f } args: x: ${ (x } """ diff --git a/tests/test_type_checking.py b/tests/test_type_checking.py index e1710524b..b482cc8a7 100644 --- a/tests/test_type_checking.py +++ b/tests/test_type_checking.py @@ -161,7 +161,7 @@ def test_pdltype_to_jsonschema(): "text": ["Hello ", {"get": "name"}, "!"], }, }, - {"call": "hello"}, + {"call": "${ hello }"}, ], } @@ -182,7 +182,7 @@ def test_function_call(): "function": {"name": "str"}, "return": {"text": ["Hello ", {"get": "name"}, "!"]}, }, - {"call": "hello", "args": {"name": "Bob"}}, + {"call": "${ hello }", "args": {"name": "Bob"}}, ], } @@ -203,7 +203,7 @@ def test_function_call1(): "function": {"name": "int"}, "return": {"text": ["Hello ", {"get": "name"}, "!"]}, }, - {"call": "hello", "args": {"name": 42}}, + {"call": "${ hello }", "args": {"name": 42}}, ], } @@ -224,7 +224,7 @@ def test_function_call2(): "function": {"name": "list"}, "return": {"text": ["Hello ", {"get": "name"}, "!"]}, }, - {"call": "hello", "args": {"name": ["Bob", "Carrol"]}}, + {"call": "${ hello }", "args": {"name": ["Bob", "Carrol"]}}, ], } @@ -245,7 +245,7 @@ def test_function_call3(): "function": {"name": "obj"}, "return": {"text": ["Hello ", {"get": "name"}, "!"]}, }, - {"call": "hello", "args": {"name": {"bob": "caroll"}}}, + {"call": "${ hello }", "args": {"name": {"bob": "caroll"}}}, ], } @@ -266,7 +266,7 @@ def test_function_call4(): "function": {"name": "bool"}, "return": {"text": ["Hello ", {"get": "name"}, "!"]}, }, - {"call": "hello", "args": {"name": True}}, + {"call": "${ hello }", "args": {"name": True}}, ], } @@ -287,7 +287,7 @@ def test_function_call5(): "function": {"name": "float"}, "return": {"text": ["Hello ", {"get": "name"}, "!"]}, }, - {"call": "hello", "args": {"name": 6.6}}, + {"call": "${ hello }", "args": {"name": 6.6}}, ], } @@ -308,7 +308,7 @@ def test_function_call6(): "function": {"name": "float"}, "return": {"text": ["Hello ", {"get": "name"}, "!"]}, }, - {"call": "hello", "args": {"name": 6.6}}, + {"call": "${ hello }", "args": {"name": 6.6}}, ], } @@ -329,7 +329,7 @@ def test_function_call7(): "function": {"name": "floats"}, "return": {"text": ["Hello ", {"get": "name"}, "!"]}, }, - {"call": "hello", "args": {"name": 6.6}}, + {"call": "${ hello }", "args": {"name": 6.6}}, ], } @@ -350,7 +350,7 @@ def test_function_call8(): "function": {"name": "float", "address": "str"}, "return": {"text": ["Hello ", {"get": "name"}, " ${ address}", "!"]}, }, - {"call": "hello", "args": {"name": 6.6, "address": "street"}}, + {"call": "${ hello }", "args": {"name": 6.6, "address": "street"}}, ], } @@ -371,7 +371,10 @@ def test_function_call9(): "function": {"name": "float", "address": "str"}, "return": {"text": ["Hello ", {"get": "name"}, " ${ address}", "!"]}, }, - {"call": "hello", "args": {"name": 6.6, "address": "street", "extra": "stuff"}}, + { + "call": "${ hello }", + "args": {"name": 6.6, "address": "street", "extra": "stuff"}, + }, ], } @@ -392,7 +395,10 @@ def test_function_call10(): "function": {}, "return": {"text": ["Hello ", {"get": "name"}, " ${ address}", "!"]}, }, - {"call": "hello", "args": {"name": 6.6, "address": "street", "extra": "stuff"}}, + { + "call": "${ hello }", + "args": {"name": 6.6, "address": "street", "extra": "stuff"}, + }, ], } @@ -413,7 +419,7 @@ def test_function_call11(): "function": {"name": "float", "address": "str"}, "return": {"text": ["Hello ", {"get": "name"}, " ${ address}", "!"]}, }, - {"call": "hello", "args": {}}, + {"call": "${ hello }", "args": {}}, ], } @@ -434,7 +440,7 @@ def test_function_call12(): "function": {"name": "float", "address": "str", "extra": "int"}, "return": {"text": ["Hello ", "!"]}, }, - {"call": "hello", "args": {"name": "Bob", "extra": 2}}, + {"call": "${ hello }", "args": {"name": "Bob", "extra": 2}}, ], } @@ -455,7 +461,7 @@ def test_function_call13(): "function": {}, "return": {"text": ["Hello ", "${ something }", "!"]}, }, - {"call": "hello", "args": {}}, + {"call": "${ hello }", "args": {}}, ], } @@ -477,7 +483,7 @@ def test_function_call14(): "spec": "str", "return": {"text": ["Hello ", {"get": "name"}, " ${ address}", "!"]}, }, - {"call": "hello", "args": {"name": 6.6, "address": "street"}}, + {"call": "${ hello }", "args": {"name": 6.6, "address": "street"}}, ], } @@ -499,7 +505,7 @@ def test_function_call15(): "spec": "int", "return": {"text": ["Hello ", {"get": "name"}, " ${ address}", "!"]}, }, - {"call": "hello", "args": {"name": 6.6, "address": "street"}}, + {"call": "${ hello }", "args": {"name": 6.6, "address": "street"}}, ], } @@ -521,7 +527,7 @@ def test_function_call16(): "spec": {"list": "int"}, "return": {"data": [1, 2, 3]}, }, - {"call": "hello", "args": {"name": 6.6, "address": "street"}}, + {"call": "${ hello }", "args": {"name": 6.6, "address": "street"}}, ], } @@ -543,7 +549,7 @@ def test_function_call17(): "spec": {"list": "int"}, "return": {"data": [1, 2, "foo"]}, }, - {"call": "hello", "args": {"name": 6.6, "address": "street"}}, + {"call": "${ hello }", "args": {"name": 6.6, "address": "street"}}, ], } diff --git a/tests/test_var.py b/tests/test_var.py index 617b46d79..7a43d8ee0 100644 --- a/tests/test_var.py +++ b/tests/test_var.py @@ -143,7 +143,7 @@ def test_missing_var(): missing_call = { "description": "simple python", - "text": [{"call": "somevar"}], + "text": [{"call": "${ somevar }"}], } From 5064a12e3f902f9ec76016b7b64dddbf4d0925ac Mon Sep 17 00:00:00 2001 From: Louis Mandel Date: Thu, 19 Dec 2024 13:44:23 -0500 Subject: [PATCH 2/7] Remove pdl_server --- src/pdl_server/__init__.py | 0 src/pdl_server/pdl_server.py | 11 ----------- 2 files changed, 11 deletions(-) delete mode 100644 src/pdl_server/__init__.py delete mode 100644 src/pdl_server/pdl_server.py diff --git a/src/pdl_server/__init__.py b/src/pdl_server/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/pdl_server/pdl_server.py b/src/pdl_server/pdl_server.py deleted file mode 100644 index ec92a2857..000000000 --- a/src/pdl_server/pdl_server.py +++ /dev/null @@ -1,11 +0,0 @@ -from flask import Flask, jsonify, request -from pdl import pdl -app = Flask(__name__) - - -@app.route('/exec_str', methods=['POST']) -def get_exec_str(): - args = request.get_json() - result = pdl.exec_str(**args) - return jsonify(result) - From 6dcab95a195906adedd170389816daae2f5c74b0 Mon Sep 17 00:00:00 2001 From: Louis Mandel Date: Thu, 19 Dec 2024 16:28:00 -0500 Subject: [PATCH 3/7] Fix error message --- src/pdl/pdl_interpreter.py | 2 +- tests/test_line_table.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pdl/pdl_interpreter.py b/src/pdl/pdl_interpreter.py index 06e197ce7..423342ffc 100644 --- a/src/pdl/pdl_interpreter.py +++ b/src/pdl/pdl_interpreter.py @@ -1429,7 +1429,7 @@ def step_call( result = None background: Messages = [] args, block = process_expr_of(block, "args", scope, loc) - closure, block = process_expr_of(block, "call", scope, loc) + closure, _ = process_expr_of(block, "call", scope, loc) args_loc = append(loc, "args") type_errors = type_check_args(args, closure.function, args_loc) if len(type_errors) > 0: diff --git a/tests/test_line_table.py b/tests/test_line_table.py index f236f7b97..814bbe4d1 100644 --- a/tests/test_line_table.py +++ b/tests/test_line_table.py @@ -169,7 +169,7 @@ def test_line13(capsys: CaptureFixture[str]): "file": "tests/data/line/hello14.pdl", "errors": [ "", - "tests/data/line/hello14.pdl:25 - Type errors in result of function call to translate:", + "tests/data/line/hello14.pdl:25 - Type errors in result of function call to ${ translate }:", "tests/data/line/hello14.pdl:16 - Bonjour le monde! should be of type ", ], } From 50a949c66a57ff6318e5f3beaa5b8c7fe0df6031 Mon Sep 17 00:00:00 2001 From: Louis Mandel Date: Fri, 20 Dec 2024 10:01:41 -0500 Subject: [PATCH 4/7] Update test --- tests/test_function.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/test_function.py b/tests/test_function.py index ef045b2b1..e3b048332 100644 --- a/tests/test_function.py +++ b/tests/test_function.py @@ -91,14 +91,15 @@ def test_function_explicit_context(): hello_call_template = { "description": "Call hello template", "text": [ - {"defs": {"alias": "${ hello }"}}, + {"defs": {"alias": {"data": {}}}}, { "description": "Define hello", - "def": "hello", + "def": "f", "function": {"name": "str"}, "return": {"text": ["Hello ", {"get": "name"}, "!"]}, }, - {"call": "${ alias }", "args": {"name": "World"}}, + {"lang": "python", "code": "result = alias['hello'] = f"}, + {"call": '${ alias["hello"] }', "args": {"name": "World"}}, ], } From 9defd68083ad4cc3e3f1cf0f46cfcdd56ffda179 Mon Sep 17 00:00:00 2001 From: Louis Mandel Date: Fri, 20 Dec 2024 11:06:19 -0500 Subject: [PATCH 5/7] Improve error message. --- src/pdl/pdl_interpreter.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/pdl/pdl_interpreter.py b/src/pdl/pdl_interpreter.py index 423342ffc..59937a1c0 100644 --- a/src/pdl/pdl_interpreter.py +++ b/src/pdl/pdl_interpreter.py @@ -1430,6 +1430,15 @@ def step_call( background: Messages = [] args, block = process_expr_of(block, "args", scope, loc) closure, _ = process_expr_of(block, "call", scope, loc) + if not isinstance(closure, FunctionBlock): + msg = f"Type error: {block.call} is of type {type(closure)} but should be a function." + if isinstance(closure, str) and isinstance(scope.get(closure), FunctionBlock): + msg += " You might want to call `${ "+ block.call + " }`." + raise PDLRuntimeError( + msg, + loc=append(loc, "call"), + trace=block.model_copy(), + ) args_loc = append(loc, "args") type_errors = type_check_args(args, closure.function, args_loc) if len(type_errors) > 0: From ccf090308de9b3d96ecf9d1980c034757f0ec72b Mon Sep 17 00:00:00 2001 From: Louis Mandel Date: Fri, 20 Dec 2024 11:10:09 -0500 Subject: [PATCH 6/7] Formatting --- src/pdl/pdl_interpreter.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pdl/pdl_interpreter.py b/src/pdl/pdl_interpreter.py index 59937a1c0..8bc7d25f1 100644 --- a/src/pdl/pdl_interpreter.py +++ b/src/pdl/pdl_interpreter.py @@ -1433,12 +1433,12 @@ def step_call( if not isinstance(closure, FunctionBlock): msg = f"Type error: {block.call} is of type {type(closure)} but should be a function." if isinstance(closure, str) and isinstance(scope.get(closure), FunctionBlock): - msg += " You might want to call `${ "+ block.call + " }`." + msg += " You might want to call `${ " + block.call + " }`." raise PDLRuntimeError( msg, loc=append(loc, "call"), trace=block.model_copy(), - ) + ) args_loc = append(loc, "args") type_errors = type_check_args(args, closure.function, args_loc) if len(type_errors) > 0: From 21a3357ec93a0724ecf908d47521101ad9ac79ef Mon Sep 17 00:00:00 2001 From: Louis Mandel Date: Fri, 20 Dec 2024 16:21:21 -0500 Subject: [PATCH 7/7] Fix pre-commit issues --- src/pdl/pdl_interpreter.py | 17 +++++++++++------ src/pdl/pdl_schema_validator.py | 16 ++++++++++------ 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/src/pdl/pdl_interpreter.py b/src/pdl/pdl_interpreter.py index 8bc7d25f1..1f6584948 100644 --- a/src/pdl/pdl_interpreter.py +++ b/src/pdl/pdl_interpreter.py @@ -1433,7 +1433,7 @@ def step_call( if not isinstance(closure, FunctionBlock): msg = f"Type error: {block.call} is of type {type(closure)} but should be a function." if isinstance(closure, str) and isinstance(scope.get(closure), FunctionBlock): - msg += " You might want to call `${ " + block.call + " }`." + msg += " You might want to call `${ " + str(block.call) + " }`." raise PDLRuntimeError( msg, loc=append(loc, "call"), @@ -1449,12 +1449,17 @@ def step_call( trace=block.model_copy(), ) f_body = closure.returns - f_scope = closure.scope | {"pdl_context": scope["pdl_context"]} | args - fun_loc = LocationType( - file=closure.location.file, - path=closure.location.path + ["return"], - table=loc.table, + f_scope = ( + (closure.scope or {}) | {"pdl_context": scope["pdl_context"]} | (args or {}) ) + if closure.location is not None: + fun_loc = LocationType( + file=closure.location.file, + path=closure.location.path + ["return"], + table=loc.table, + ) + else: + fun_loc = empty_block_location try: result, background, _, f_trace = yield from step_block( state, f_scope, f_body, fun_loc diff --git a/src/pdl/pdl_schema_validator.py b/src/pdl/pdl_schema_validator.py index 3f70cfe9a..774a00aff 100644 --- a/src/pdl/pdl_schema_validator.py +++ b/src/pdl/pdl_schema_validator.py @@ -1,4 +1,4 @@ -from typing import Any +from typing import Any, Optional from jsonschema import ValidationError, validate @@ -7,15 +7,19 @@ from .pdl_schema_utils import get_json_schema, pdltype_to_jsonschema -def type_check_args(args: dict[str, Any], params: dict[str, Any], loc) -> list[str]: +def type_check_args( + args: Optional[dict[str, Any]], params: Optional[dict[str, Any]], loc +) -> list[str]: if (args == {} or args is None) and (params is None or params == {}): return [] - args_copy = args.copy() - params_copy = params.copy() - if args_copy is None: + if args is None: args_copy = {} - if params_copy is None: + else: + args_copy = args.copy() + if params is None: params_copy = {} + else: + params_copy = params.copy() # if "pdl_context" not in args_copy: # args_copy["pdl_context"] = "pdl_context" # if "pdl_context" not in params_copy: