From 800362a3f1f3fa398f2ae13c131042266a3bf417 Mon Sep 17 00:00:00 2001 From: Jade Abraham Date: Wed, 29 Jan 2025 16:02:22 -0800 Subject: [PATCH 1/7] fix python/chapel IO printing Signed-off-by: Jade Abraham --- .../Python/correctness/argPassingTest.chpl | 61 ++++++++++--------- .../correctness/argPassingTest.comm-none.good | 60 ------------------ .../Python/correctness/argPassingTest.good | 8 +-- .../Python/correctness/customType.chpl | 2 + .../correctness/customType.comm-none.good | 2 - .../Python/correctness/customType.good | 2 +- .../packages/Python/correctness/customType.py | 2 + 7 files changed, 42 insertions(+), 95 deletions(-) delete mode 100644 test/library/packages/Python/correctness/argPassingTest.comm-none.good delete mode 100644 test/library/packages/Python/correctness/customType.comm-none.good diff --git a/test/library/packages/Python/correctness/argPassingTest.chpl b/test/library/packages/Python/correctness/argPassingTest.chpl index d0fbc58f7070..b459af14b93a 100644 --- a/test/library/packages/Python/correctness/argPassingTest.chpl +++ b/test/library/packages/Python/correctness/argPassingTest.chpl @@ -1,7 +1,8 @@ use Python; import Reflection; +use IO; -proc test_no_args(mod: borrowed Module) { +proc test_no_args(mod: borrowed Module, flush: borrowed Value) { const funcName = "no_args"; var func = new Function(mod, funcName); @@ -9,15 +10,15 @@ proc test_no_args(mod: borrowed Module) { // error: wrong return type try { func(int); } - catch e: PythonException { writeln("Caught PythonException: ", e.message()); } - catch { writeln("Caught unknown exception"); } + catch e: PythonException { flush(NoneType); writeln("Caught PythonException: ", e.message()); IO.stdout.flush(); } + catch { flush(NoneType); writeln("Caught unknown exception"); IO.stdout.flush(); } // error: too many args try { func(NoneType, 2); } - catch e: PythonException { writeln("Caught PythonException: ", e.message()); } - catch { writeln("Caught unknown exception"); } + catch e: PythonException { flush(NoneType); writeln("Caught PythonException: ", e.message()); IO.stdout.flush(); } + catch { flush(NoneType); writeln("Caught unknown exception"); IO.stdout.flush(); } } -proc test_one_arg(mod: borrowed Module) { +proc test_one_arg(mod: borrowed Module, flush: borrowed Value) { const funcName = "one_arg"; var func = new Function(mod, funcName); @@ -25,15 +26,15 @@ proc test_one_arg(mod: borrowed Module) { // error: not enough args try { func(NoneType); } - catch e: PythonException { writeln("Caught PythonException: ", e.message()); } - catch { writeln("Caught unknown exception"); } + catch e: PythonException { flush(NoneType); writeln("Caught PythonException: ", e.message()); IO.stdout.flush(); } + catch { flush(NoneType); writeln("Caught unknown exception"); IO.stdout.flush(); } // error: too many args try { func(NoneType, 2, 3); } - catch e: PythonException { writeln("Caught PythonException: ", e.message()); } - catch { writeln("Caught unknown exception"); } + catch e: PythonException { flush(NoneType); writeln("Caught PythonException: ", e.message()); IO.stdout.flush(); } + catch { flush(NoneType); writeln("Caught unknown exception"); IO.stdout.flush(); } } -proc test_two_args(mod: borrowed Module) { +proc test_two_args(mod: borrowed Module, flush: borrowed Value) { const funcName = "two_args"; var func = new Function(mod, funcName); @@ -43,16 +44,16 @@ proc test_two_args(mod: borrowed Module) { // error: not enough args try { func(NoneType, 3); } - catch e: PythonException { writeln("Caught PythonException: ", e.message()); } - catch { writeln("Caught unknown exception"); } + catch e: PythonException { flush(NoneType); writeln("Caught PythonException: ", e.message()); IO.stdout.flush(); } + catch { flush(NoneType); writeln("Caught unknown exception"); IO.stdout.flush(); } } -proc test_three_args(mod: borrowed Module) { +proc test_three_args(mod: borrowed Module, flush: borrowed Value) { const funcName = "three_args"; var func = new Function(mod, funcName); func(NoneType, 1, 2, 3); } -proc test_varargs(mod: borrowed Module) { +proc test_varargs(mod: borrowed Module, flush: borrowed Value) { const funcName = "varargs"; var func = new Function(mod, funcName); @@ -64,14 +65,14 @@ proc test_varargs(mod: borrowed Module) { func(NoneType, 1, 2, 3, [1,2,3,], 4); func(NoneType, 1, 2, 3, [1,2,3,], 4, ["key" => "value", "key2" => "value2"]); } -proc test_one_arg_with_default(mod: borrowed Module) { +proc test_one_arg_with_default(mod: borrowed Module, flush: borrowed Value) { const funcName = "one_arg_with_default"; var func = new Function(mod, funcName); func(NoneType); func(NoneType, 7); } -proc test_three_args_with_default(mod: borrowed Module) { +proc test_three_args_with_default(mod: borrowed Module, flush: borrowed Value) { const funcName = "three_args_with_default"; var func = new Function(mod, funcName); @@ -80,7 +81,7 @@ proc test_three_args_with_default(mod: borrowed Module) { func(NoneType, 8, 9, 10); func(NoneType, 8, kwargs=["c" => 10]); } -proc test_three_args_with_default_and_kwargs(mod: borrowed Module) { +proc test_three_args_with_default_and_kwargs(mod: borrowed Module, flush: borrowed Value) { const funcName = "three_args_with_default_and_kwargs"; var func = new Function(mod, funcName); @@ -90,7 +91,7 @@ proc test_three_args_with_default_and_kwargs(mod: borrowed Module) { func(NoneType, 8, kwargs=["b" => 10]); func(NoneType, 8, kwargs=["c" => 11, "abc" => 12]); } -proc test_varargs_and_kwargs(mod: borrowed Module) { +proc test_varargs_and_kwargs(mod: borrowed Module, flush: borrowed Value) { const funcName = "varargs_and_kwargs"; var func = new Function(mod, funcName); @@ -109,15 +110,19 @@ proc main() { var modName = Reflection.getModuleName(); var m = new Module(interp, modName); - test_no_args(m); - test_one_arg(m); - test_two_args(m); - test_three_args(m); - test_varargs(m); - test_one_arg_with_default(m); - test_three_args_with_default(m); - test_three_args_with_default_and_kwargs(m); - test_varargs_and_kwargs(m); + var sys = new Module(interp, "sys"); + var stdout = sys.getAttr(owned Value, "stdout"); + var flush = stdout.getAttr(owned Value, "flush"); + + test_no_args(m, flush); + test_one_arg(m, flush); + test_two_args(m, flush); + test_three_args(m, flush); + test_varargs(m, flush); + test_one_arg_with_default(m, flush); + test_three_args_with_default(m, flush); + test_three_args_with_default_and_kwargs(m, flush); + test_varargs_and_kwargs(m, flush); } diff --git a/test/library/packages/Python/correctness/argPassingTest.comm-none.good b/test/library/packages/Python/correctness/argPassingTest.comm-none.good deleted file mode 100644 index 09e916b2c941..000000000000 --- a/test/library/packages/Python/correctness/argPassingTest.comm-none.good +++ /dev/null @@ -1,60 +0,0 @@ -called no_args -called no_args -called one_arg with 1 -called two_args with 1 and 2 -called two_args with hello and world -called two_args with None and None -called three_args with 1, 2, and 3 -called varargs - args: -called varargs - args: 1 -called varargs - args: 1, 2 -called varargs - args: 1, 2, 3 -called varargs - args: 1, 2, 3, [1, 2, 3] -called varargs - args: 1, 2, 3, [1, 2, 3], 4 -called varargs - args: 1, 2, 3, [1, 2, 3], 4, {'key2': 'value2', 'key': 'value'} -called one_arg_with_default with 1 -called one_arg_with_default with 7 -called three_args_with_default with 8, 2, and 3 -called three_args_with_default with 8, 9, and 3 -called three_args_with_default with 8, 9, and 10 -called three_args_with_default with 8, 2, and 10 -called three_args_with_default_and_kwargs with 8, 2, and 3 - kwargs: -called three_args_with_default_and_kwargs with 8, 9, and 3 - kwargs: -called three_args_with_default_and_kwargs with 8, 9, and 10 - kwargs: -called three_args_with_default_and_kwargs with 8, 10, and 3 - kwargs: -called three_args_with_default_and_kwargs with 8, 2, and 11 - kwargs: abc=12 -called varargs_and_kwargs - args: - kwargs: -called varargs_and_kwargs - args: 1 - kwargs: -called varargs_and_kwargs - args: 1, {'key': 'value'} - kwargs: -called varargs_and_kwargs - args: - kwargs: a=19 -called varargs_and_kwargs - args: 1 - kwargs: a=20 -called varargs_and_kwargs - args: 1, 2, {'key': 'value'} - kwargs: a=7, b=8 -Caught PythonException: 'NoneType' object cannot be interpreted as an integer -Caught PythonException: no_args() takes 0 positional arguments but 1 was given -Caught PythonException: one_arg() missing 1 required positional argument: 'a' -Caught PythonException: one_arg() takes 1 positional argument but 2 were given -Caught PythonException: two_args() missing 1 required positional argument: 'b' diff --git a/test/library/packages/Python/correctness/argPassingTest.good b/test/library/packages/Python/correctness/argPassingTest.good index 93712ab4301c..5b812077e139 100644 --- a/test/library/packages/Python/correctness/argPassingTest.good +++ b/test/library/packages/Python/correctness/argPassingTest.good @@ -1,14 +1,14 @@ +called no_args +called no_args Caught PythonException: 'NoneType' object cannot be interpreted as an integer Caught PythonException: no_args() takes 0 positional arguments but 1 was given +called one_arg with 1 Caught PythonException: one_arg() missing 1 required positional argument: 'a' Caught PythonException: one_arg() takes 1 positional argument but 2 were given -Caught PythonException: two_args() missing 1 required positional argument: 'b' -called no_args -called no_args -called one_arg with 1 called two_args with 1 and 2 called two_args with hello and world called two_args with None and None +Caught PythonException: two_args() missing 1 required positional argument: 'b' called three_args with 1, 2, and 3 called varargs args: diff --git a/test/library/packages/Python/correctness/customType.chpl b/test/library/packages/Python/correctness/customType.chpl index 76b878ae61e5..a19b4afe2d46 100644 --- a/test/library/packages/Python/correctness/customType.chpl +++ b/test/library/packages/Python/correctness/customType.chpl @@ -1,6 +1,7 @@ use Python; import Reflection; use CTypes; +use IO; record myRec { var x: int; @@ -35,6 +36,7 @@ proc main() { var pyClsType = new Class(m, "MyRec"); interp.registerConverter(new myRecConverter(pyClsType)); + IO.stdout.flush(); var printAndReturn = new Function(m, "printAndReturn"); var fromPy = printAndReturn(myRec, new myRec(42, "hello")); writeln(fromPy); diff --git a/test/library/packages/Python/correctness/customType.comm-none.good b/test/library/packages/Python/correctness/customType.comm-none.good deleted file mode 100644 index b7d187f010e8..000000000000 --- a/test/library/packages/Python/correctness/customType.comm-none.good +++ /dev/null @@ -1,2 +0,0 @@ -MyRec(x=42, y=hello) -(x = 42, y = hello) diff --git a/test/library/packages/Python/correctness/customType.good b/test/library/packages/Python/correctness/customType.good index 4b2eee48352d..b7d187f010e8 100644 --- a/test/library/packages/Python/correctness/customType.good +++ b/test/library/packages/Python/correctness/customType.good @@ -1,2 +1,2 @@ -(x = 42, y = hello) MyRec(x=42, y=hello) +(x = 42, y = hello) diff --git a/test/library/packages/Python/correctness/customType.py b/test/library/packages/Python/correctness/customType.py index eb8e3204e7fa..741abccfb6c0 100644 --- a/test/library/packages/Python/correctness/customType.py +++ b/test/library/packages/Python/correctness/customType.py @@ -1,4 +1,5 @@ +import sys class MyRec: def __init__(self, x, y): @@ -12,4 +13,5 @@ def __str__(self): def printAndReturn(rec): assert isinstance(rec, MyRec) print(rec) + sys.stdout.flush() return rec From d3e5ee316cdf337b1c6a012e63f2ab9868493919 Mon Sep 17 00:00:00 2001 From: Jade Abraham Date: Wed, 29 Jan 2025 16:02:37 -0800 Subject: [PATCH 2/7] add docs on IO with python Signed-off-by: Jade Abraham --- modules/packages/Python.chpl | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/modules/packages/Python.chpl b/modules/packages/Python.chpl index 8291789e01e8..088d424cfc0b 100644 --- a/modules/packages/Python.chpl +++ b/modules/packages/Python.chpl @@ -23,8 +23,6 @@ // TODO: implement operators as dunder methods -// TODO: make python use chapel stdout/stderr - /* Library for interfacing with Python from Chapel code. This module provides a Chapel interface to a Python interpreter. @@ -304,6 +302,35 @@ To translate custom Chapel types to Python objects, users should define and register custom :type:`TypeConverter` classes. + Notes on Python + Chapel I/O + ---------------------------- + + When interspersing Python and Chapel I/O, it is important to flush the output + buffers to ensure that the output is displayed in the correct order. This is + needed at the point where the output changes from Python to Chapel or + vice-versa. For example: + + .. code-block:: chapel + + use Python, IO; + + var interp = new Interpreter(); + var func = new Function(interp, "lambda x,: print(x)"); + var sys = new Module(interp, "sys"); + var pyStdout = sys.getAttr("stdout"); + var pyStdoutFlush = pyStdout.getAttr("flush"); + + writeln("Hello from Chapel"); + writeln("Lets call some Python!"); + IO.stdout.flush(); // flush the Chapel output buffer before calling Python + + // run the Python function + func(NoneType, "Hello, World!"); + func(NoneType, "Goodbye, World!"); + pyStdoutFlush(NoneType); // flush the Python output buffer before calling Chapel again + + writeln("Back to Chapel"); + More Examples: -------------- @@ -468,10 +495,6 @@ module Python { PyList_Insert(path, 0, Py_BuildValue("s", ".")); this.checkException(); } - // TODO: reset stdout and stderr to Chapel's handles - // I think we can do this by setting sys.stdout and sys.stderr to a python - // object that looks like a python file but forwards calls like write to - // Chapel's write if !ArrayTypes.createArrayTypes() { throwChapelException("Failed to create Python array types for Chapel arrays"); From b67acf394a354fbcaaee1b4d1bd4d5bf4bf5179d Mon Sep 17 00:00:00 2001 From: Jade Abraham Date: Wed, 29 Jan 2025 16:16:02 -0800 Subject: [PATCH 3/7] support testing doc code Signed-off-by: Jade Abraham --- modules/packages/Python.chpl | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/modules/packages/Python.chpl b/modules/packages/Python.chpl index 088d424cfc0b..3db9bd4fdebf 100644 --- a/modules/packages/Python.chpl +++ b/modules/packages/Python.chpl @@ -310,6 +310,17 @@ needed at the point where the output changes from Python to Chapel or vice-versa. For example: + .. + START_TEST + FILENAME: Printing.chpl + START_GOOD + Hello from Chapel + Lets call some Python! + Hello, World! + Goodbye, World! + Back to Chapel + END_GOOD + .. code-block:: chapel use Python, IO; @@ -318,19 +329,22 @@ var func = new Function(interp, "lambda x,: print(x)"); var sys = new Module(interp, "sys"); var pyStdout = sys.getAttr("stdout"); - var pyStdoutFlush = pyStdout.getAttr("flush"); + var pyStdoutFlush = pyStdout.getAttr("flush"); writeln("Hello from Chapel"); - writeln("Lets call some Python!"); + writeln("Let's call some Python!"); IO.stdout.flush(); // flush the Chapel output buffer before calling Python - // run the Python function func(NoneType, "Hello, World!"); func(NoneType, "Goodbye, World!"); pyStdoutFlush(NoneType); // flush the Python output buffer before calling Chapel again writeln("Back to Chapel"); + .. + END_TEST + + More Examples: -------------- From c5bb69b1dff83812393ab3da959638bdd72ee03d Mon Sep 17 00:00:00 2001 From: Jade Abraham Date: Wed, 29 Jan 2025 16:19:34 -0800 Subject: [PATCH 4/7] fix typo Signed-off-by: Jade Abraham --- modules/packages/Python.chpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/packages/Python.chpl b/modules/packages/Python.chpl index 3db9bd4fdebf..cc59192dcd29 100644 --- a/modules/packages/Python.chpl +++ b/modules/packages/Python.chpl @@ -367,7 +367,7 @@ module Python { Use 'objgraph' to detect memory leaks in the Python code. Care should be taken when interpreting the output of this flag, not all memory leaks are under Chapel's control. For example, printing a Python list leaks memory - according to 'objgraph'. Furthermore, some memory is still held when until + according to 'objgraph'. Furthermore, some memory is still held until the interpreter is closed, like the module import cache. */ config const pyMemLeaks = false; From 100f43e6359e235c54fb0339bb0fbb7e2a322ca1 Mon Sep 17 00:00:00 2001 From: Jade Abraham Date: Wed, 29 Jan 2025 16:19:47 -0800 Subject: [PATCH 5/7] specify return type Signed-off-by: Jade Abraham --- modules/packages/Python.chpl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/packages/Python.chpl b/modules/packages/Python.chpl index cc59192dcd29..8099d5b8ea5c 100644 --- a/modules/packages/Python.chpl +++ b/modules/packages/Python.chpl @@ -328,8 +328,8 @@ var interp = new Interpreter(); var func = new Function(interp, "lambda x,: print(x)"); var sys = new Module(interp, "sys"); - var pyStdout = sys.getAttr("stdout"); - var pyStdoutFlush = pyStdout.getAttr("flush"); + var pyStdout = sys.getAttr(owned Value, "stdout"); + var pyStdoutFlush = pyStdout.getAttr(owned Value, "flush"); writeln("Hello from Chapel"); writeln("Let's call some Python!"); From 6348fe333ff0bb3b26600b420a0cc8353cfead0e Mon Sep 17 00:00:00 2001 From: Jade Abraham Date: Wed, 29 Jan 2025 16:25:28 -0800 Subject: [PATCH 6/7] fix typo Signed-off-by: Jade Abraham --- modules/packages/Python.chpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/packages/Python.chpl b/modules/packages/Python.chpl index 8099d5b8ea5c..5bef4ded9c61 100644 --- a/modules/packages/Python.chpl +++ b/modules/packages/Python.chpl @@ -315,7 +315,7 @@ FILENAME: Printing.chpl START_GOOD Hello from Chapel - Lets call some Python! + Let's call some Python! Hello, World! Goodbye, World! Back to Chapel From 7dda356d7e2fbaf18ec7c9828abf6472eca402dd Mon Sep 17 00:00:00 2001 From: Jade Abraham Date: Mon, 3 Feb 2025 14:26:23 -0800 Subject: [PATCH 7/7] add interp.flush Signed-off-by: Jade Abraham --- modules/packages/Python.chpl | 27 +++++++-- .../Python/correctness/argPassingTest.chpl | 60 +++++++++---------- 2 files changed, 51 insertions(+), 36 deletions(-) diff --git a/modules/packages/Python.chpl b/modules/packages/Python.chpl index 5bef4ded9c61..9284878528b7 100644 --- a/modules/packages/Python.chpl +++ b/modules/packages/Python.chpl @@ -327,9 +327,6 @@ var interp = new Interpreter(); var func = new Function(interp, "lambda x,: print(x)"); - var sys = new Module(interp, "sys"); - var pyStdout = sys.getAttr(owned Value, "stdout"); - var pyStdoutFlush = pyStdout.getAttr(owned Value, "flush"); writeln("Hello from Chapel"); writeln("Let's call some Python!"); @@ -337,7 +334,7 @@ func(NoneType, "Hello, World!"); func(NoneType, "Goodbye, World!"); - pyStdoutFlush(NoneType); // flush the Python output buffer before calling Chapel again + interp.flush(); // flush the Python output buffer before calling Chapel again writeln("Back to Chapel"); @@ -728,6 +725,26 @@ module Python { } } + /* + Flush the standard output buffers of the Python interpreter. This is + useful when mixing Python and Chapel I/O to ensure that the output is + displayed in the correct order. + */ + inline proc flush(flushStderr: bool = false) throws { + var stdout = PySys_GetObject("stdout"); + if stdout == nil then throw new ChapelException("stdout not found"); + + var flushStr = this.toPython("flush"); + defer Py_DECREF(flushStr); + + PyObject_CallMethodNoArgs(stdout, flushStr); + if flushStderr { + var stderr = PySys_GetObject("stderr"); + if stderr == nil then throw new ChapelException("stderr not found"); + PyObject_CallMethodNoArgs(stderr, flushStr); + } + } + @chpldoc.nodoc inline proc importModule(in modName: string): PyObjectPtr throws { var mod = PyImport_ImportModule(modName.c_str()); @@ -2031,6 +2048,8 @@ module Python { extern "chpl_PY_MINOR_VERSION" const PY_MINOR_VERSION: c_ulong; extern "chpl_PY_MICRO_VERSION" const PY_MICRO_VERSION: c_ulong; + extern proc PySys_GetObject(name: c_ptrConst(c_char)): PyObjectPtr; + /* Sub Interpreters diff --git a/test/library/packages/Python/correctness/argPassingTest.chpl b/test/library/packages/Python/correctness/argPassingTest.chpl index b459af14b93a..5075c1fc5e6e 100644 --- a/test/library/packages/Python/correctness/argPassingTest.chpl +++ b/test/library/packages/Python/correctness/argPassingTest.chpl @@ -2,7 +2,7 @@ use Python; import Reflection; use IO; -proc test_no_args(mod: borrowed Module, flush: borrowed Value) { +proc test_no_args(mod: borrowed Module) { const funcName = "no_args"; var func = new Function(mod, funcName); @@ -10,15 +10,15 @@ proc test_no_args(mod: borrowed Module, flush: borrowed Value) { // error: wrong return type try { func(int); } - catch e: PythonException { flush(NoneType); writeln("Caught PythonException: ", e.message()); IO.stdout.flush(); } - catch { flush(NoneType); writeln("Caught unknown exception"); IO.stdout.flush(); } + catch e: PythonException { mod.interpreter.flush(); writeln("Caught PythonException: ", e.message()); IO.stdout.flush(); } + catch { mod.interpreter.flush(); writeln("Caught unknown exception"); IO.stdout.flush(); } // error: too many args try { func(NoneType, 2); } - catch e: PythonException { flush(NoneType); writeln("Caught PythonException: ", e.message()); IO.stdout.flush(); } - catch { flush(NoneType); writeln("Caught unknown exception"); IO.stdout.flush(); } + catch e: PythonException { mod.interpreter.flush(); writeln("Caught PythonException: ", e.message()); IO.stdout.flush(); } + catch { mod.interpreter.flush(); writeln("Caught unknown exception"); IO.stdout.flush(); } } -proc test_one_arg(mod: borrowed Module, flush: borrowed Value) { +proc test_one_arg(mod: borrowed Module) { const funcName = "one_arg"; var func = new Function(mod, funcName); @@ -26,15 +26,15 @@ proc test_one_arg(mod: borrowed Module, flush: borrowed Value) { // error: not enough args try { func(NoneType); } - catch e: PythonException { flush(NoneType); writeln("Caught PythonException: ", e.message()); IO.stdout.flush(); } - catch { flush(NoneType); writeln("Caught unknown exception"); IO.stdout.flush(); } + catch e: PythonException { mod.interpreter.flush(); writeln("Caught PythonException: ", e.message()); IO.stdout.flush(); } + catch { mod.interpreter.flush(); writeln("Caught unknown exception"); IO.stdout.flush(); } // error: too many args try { func(NoneType, 2, 3); } - catch e: PythonException { flush(NoneType); writeln("Caught PythonException: ", e.message()); IO.stdout.flush(); } - catch { flush(NoneType); writeln("Caught unknown exception"); IO.stdout.flush(); } + catch e: PythonException { mod.interpreter.flush(); writeln("Caught PythonException: ", e.message()); IO.stdout.flush(); } + catch { mod.interpreter.flush(); writeln("Caught unknown exception"); IO.stdout.flush(); } } -proc test_two_args(mod: borrowed Module, flush: borrowed Value) { +proc test_two_args(mod: borrowed Module) { const funcName = "two_args"; var func = new Function(mod, funcName); @@ -44,16 +44,16 @@ proc test_two_args(mod: borrowed Module, flush: borrowed Value) { // error: not enough args try { func(NoneType, 3); } - catch e: PythonException { flush(NoneType); writeln("Caught PythonException: ", e.message()); IO.stdout.flush(); } - catch { flush(NoneType); writeln("Caught unknown exception"); IO.stdout.flush(); } + catch e: PythonException { mod.interpreter.flush(); writeln("Caught PythonException: ", e.message()); IO.stdout.flush(); } + catch { mod.interpreter.flush(); writeln("Caught unknown exception"); IO.stdout.flush(); } } -proc test_three_args(mod: borrowed Module, flush: borrowed Value) { +proc test_three_args(mod: borrowed Module) { const funcName = "three_args"; var func = new Function(mod, funcName); func(NoneType, 1, 2, 3); } -proc test_varargs(mod: borrowed Module, flush: borrowed Value) { +proc test_varargs(mod: borrowed Module) { const funcName = "varargs"; var func = new Function(mod, funcName); @@ -65,14 +65,14 @@ proc test_varargs(mod: borrowed Module, flush: borrowed Value) { func(NoneType, 1, 2, 3, [1,2,3,], 4); func(NoneType, 1, 2, 3, [1,2,3,], 4, ["key" => "value", "key2" => "value2"]); } -proc test_one_arg_with_default(mod: borrowed Module, flush: borrowed Value) { +proc test_one_arg_with_default(mod: borrowed Module) { const funcName = "one_arg_with_default"; var func = new Function(mod, funcName); func(NoneType); func(NoneType, 7); } -proc test_three_args_with_default(mod: borrowed Module, flush: borrowed Value) { +proc test_three_args_with_default(mod: borrowed Module) { const funcName = "three_args_with_default"; var func = new Function(mod, funcName); @@ -81,7 +81,7 @@ proc test_three_args_with_default(mod: borrowed Module, flush: borrowed Value) { func(NoneType, 8, 9, 10); func(NoneType, 8, kwargs=["c" => 10]); } -proc test_three_args_with_default_and_kwargs(mod: borrowed Module, flush: borrowed Value) { +proc test_three_args_with_default_and_kwargs(mod: borrowed Module) { const funcName = "three_args_with_default_and_kwargs"; var func = new Function(mod, funcName); @@ -91,7 +91,7 @@ proc test_three_args_with_default_and_kwargs(mod: borrowed Module, flush: borrow func(NoneType, 8, kwargs=["b" => 10]); func(NoneType, 8, kwargs=["c" => 11, "abc" => 12]); } -proc test_varargs_and_kwargs(mod: borrowed Module, flush: borrowed Value) { +proc test_varargs_and_kwargs(mod: borrowed Module) { const funcName = "varargs_and_kwargs"; var func = new Function(mod, funcName); @@ -110,19 +110,15 @@ proc main() { var modName = Reflection.getModuleName(); var m = new Module(interp, modName); - var sys = new Module(interp, "sys"); - var stdout = sys.getAttr(owned Value, "stdout"); - var flush = stdout.getAttr(owned Value, "flush"); - - test_no_args(m, flush); - test_one_arg(m, flush); - test_two_args(m, flush); - test_three_args(m, flush); - test_varargs(m, flush); - test_one_arg_with_default(m, flush); - test_three_args_with_default(m, flush); - test_three_args_with_default_and_kwargs(m, flush); - test_varargs_and_kwargs(m, flush); + test_no_args(m); + test_one_arg(m); + test_two_args(m); + test_three_args(m); + test_varargs(m); + test_one_arg_with_default(m); + test_three_args_with_default(m); + test_three_args_with_default_and_kwargs(m); + test_varargs_and_kwargs(m); }