Skip to content

Commit 5fbbe13

Browse files
committed
ExecuteFunction: added variable argument - if provided, function result would be set into this python variable
1 parent a7e3035 commit 5fbbe13

File tree

2 files changed

+23
-19
lines changed

2 files changed

+23
-19
lines changed

isc/py/Main.cls

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,8 @@ ClassMethod GetFunctionInfo(function As %String = "", Output defined As %Boolean
331331
quit:function="" $$$ERROR($$$GeneralError, "Variable argument should be set")
332332
set sc = ..GetVariableInfo(function, , .defined, .type, .length)
333333
quit:$$$ISERR(sc) sc
334+
quit:'defined $$$ERROR($$$GeneralError, "Function is not defined: " _ function)
335+
quit:type="type" ..GetFunctionInfo(function _ ".__init__", .defined, .type, .docs, .signature, .arguments) // for classes get constructor
334336
quit:((type'="function") && (type'="method") && (type'="builtin_function_or_method") && (type'="method_descriptor")) $$$ERROR($$$FormatText("%1 is not a function/method, but a %2", function, type))
335337

336338
if defined {
@@ -369,21 +371,22 @@ ClassMethod GetFunctionInfo(function As %String = "", Output defined As %Boolean
369371
/// Call arbitrary method or function.
370372
/// **kwargs can't be passed using this method. Use ExecuteFunction instead if you need to pass **kwargs.
371373
/// function - name of function to invoke. Can be nested, i.e. `random.randint`
374+
/// variable - if provided, result of function execution would be set into this python variable
372375
/// serialization - how to serialize result
373376
/// result - write result into this variable
374377
/// arguments - arguments as expected with triple dot syntax
375378
/// set sc = ##class(isc.py.Main).ExecuteFunctionArgs()
376-
ClassMethod ExecuteFunctionArgs(function As %String, serialization As %Integer = {##class(isc.py.Callout).#SerializationStr}, Output result As %String, arguments... As %String) As %Status
379+
ClassMethod ExecuteFunctionArgs(function As %String, variable As %String = "zzzresult", serialization As %Integer = {##class(isc.py.Callout).#SerializationStr}, Output result As %String, arguments... As %String) As %Status
377380
{
378381
// We have no arguments
379-
quit:'$d(arguments) ..ExecuteFunction(function, , , serialization, .result)
382+
quit:'$d(arguments) ..ExecuteFunction(function, , ,variable, serialization, .result)
380383

381384
#dim sc As %Status = $$$OK
382385
kill defined, type
383386

384387
set sc = ..GetFunctionInfo(function, .defined, .type, , .signature, .funcArguments)
385388
quit:$$$ISERR(sc) sc
386-
389+
387390
set positionalArguments = ""
388391
set keywordArguments = ""
389392

@@ -399,8 +402,8 @@ ClassMethod ExecuteFunctionArgs(function As %String, serialization As %Integer =
399402
#dim kwonlyargs As %DynamicArray = funcArgObj.%Get(4)
400403
#dim kwonlydefaults As %DynamicArray = funcArgObj.%Get(5)
401404

402-
// Remove self argument if it's a method.
403-
do:type["method" args.%Remove(0)
405+
// Remove self argument if it's a method or a constructor function
406+
do:((type["method") || ($isObject(args) && (args.%Get(0)="self"))) args.%Remove(0)
404407

405408
#dim posCount As %Integer = $case($isObject(args), $$$YES: args.%Size(), :0)
406409
#dim kwCount As %Integer = $case($isObject(kwonlyargs), $$$YES: kwonlyargs.%Size(), :0)
@@ -427,7 +430,7 @@ ClassMethod ExecuteFunctionArgs(function As %String, serialization As %Integer =
427430
}
428431

429432
//zw kwCount,positionalCount,keywordCount,arguments,size,signature,funcArguments,positionalArguments, keywordArguments
430-
set sc = ..ExecuteFunction(function, positionalArguments, keywordArguments, serialization, .result)
433+
set sc = ..ExecuteFunction(function, positionalArguments, keywordArguments, variable, serialization, .result)
431434

432435
quit sc
433436
}
@@ -436,18 +439,19 @@ ClassMethod ExecuteFunctionArgs(function As %String, serialization As %Integer =
436439
/// function - name of function to invoke. Can be nested, i.e. `random.randint`
437440
/// positionalArguments - $lb(val1, val2, ..., valN) or any %Collection.AbstractIterator class or Dynamic array
438441
/// keywordArguments - $lb($lb(name1, val1), $lb(name2, val2), ..., $lb(nameN, valN)) or any %Collection.AbstractArray class or flat Dynamic object
439-
/// serialization -how to serialize result
442+
/// variable - if provided, result of function execution would be set into this python variable
443+
/// serialization - how to serialize result
440444
/// result - write result into this variable
441445
/// set sc = ##class(isc.py.Main).ExecuteFunction()
442-
ClassMethod ExecuteFunction(function As %String, positionalArguments As %List = "", keywordArguments As %List = "", serialization As %Integer = {##class(isc.py.Callout).#SerializationStr}, Output result As %String) As %Status
446+
ClassMethod ExecuteFunction(function As %String, positionalArguments As %List = "", keywordArguments As %List = "", variable As %String = "zzzresult", serialization As %Integer = {##class(isc.py.Callout).#SerializationStr}, Output result As %String) As %Status
443447
{
444448
#dim sc As %Status = $$$OK
445449
kill defined, type
446450

447451
set sc = ..GetFunctionInfo(function, .defined, .type, , .signature, .arguments)
448452
quit:$$$ISERR(sc) sc
449-
450-
set code = "zzzresult=" _ function _ "("
453+
454+
set code = variable _ "=" _ function _ "("
451455
if (positionalArguments'="") {
452456
if (($listvalid(positionalArguments)) && ($ll(positionalArguments)>0)) {
453457
set code = code _ $lts(positionalArguments)
@@ -492,11 +496,11 @@ ClassMethod ExecuteFunction(function As %String, positionalArguments As %List =
492496

493497
set code = code _ ")"
494498

495-
zw code
496-
set sc = ..SimpleString(code, "zzzresult", serialization, .result)
499+
//zw code
500+
set sc = ..SimpleString(code, variable, serialization, .result)
497501
quit:$$$ISERR(sc) sc
498502

499-
set sc = ..SimpleString("del zzzresult")
503+
set:variable="zzzresult" sc = ..SimpleString("del zzzresult")
500504

501505
quit sc
502506
}

isc/py/unit/TestCase.cls

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,7 @@ Method TestExecuteFunction()
375375

376376
for positionalArguments = posList,posCollection,posDynamic {
377377
kill result
378-
set sc = ##class(isc.py.Main).ExecuteFunction(random _ ".randint", positionalArguments,,,.result)
378+
set sc = ##class(isc.py.Main).ExecuteFunction(random _ ".randint", positionalArguments,,,,.result)
379379
do $$$AssertStatusOK(sc, "randint positionalArguments execution OK")
380380
do $$$AssertTrue(((result>=1)&&(result<=100)), "Randint returned integer between 1 and 100")
381381
}
@@ -389,23 +389,23 @@ Method TestExecuteFunction()
389389

390390
for kwArguments = kwList,kwCollection,kwDynamic {
391391
kill result
392-
set sc = ##class(isc.py.Main).ExecuteFunction(random _ ".randint", ,kwArguments,,.result)
392+
set sc = ##class(isc.py.Main).ExecuteFunction(random _ ".randint", ,kwArguments,,,.result)
393393
do $$$AssertStatusOK(sc, "randint keyword execution OK")
394394
do $$$AssertTrue(((result>=1)&&(result<=100)), "Randint returned integer between 1 and 100")
395395
}
396396

397397
kill result
398398
set posList = $lb(1)
399399
set kwDynamic = {"b": 100}
400-
set sc = ##class(isc.py.Main).ExecuteFunction(random _ ".randint", posList, kwDynamic,,.result)
400+
set sc = ##class(isc.py.Main).ExecuteFunction(random _ ".randint", posList, kwDynamic,,,.result)
401401
do $$$AssertStatusOK(sc, "randint mixed execution OK")
402402
do $$$AssertTrue(((result>=1)&&(result<=100)), "Randint returned integer between 1 and 100")
403403

404404
kill result
405405
set posList = ##class(isc.py.util.Converter).EscapeStringList($lb("Positional: {0} {1}! Keyword: {name}, {name2}", "Hello", "World"))
406406
set kwDynamic = { "name":(##class(isc.py.util.Converter).EscapeString("Alice")),
407407
"name2":(##class(isc.py.util.Converter).EscapeString("Bob"))}
408-
set sc = ##class(isc.py.Main).ExecuteFunction("str.format", posList, kwDynamic,,.result)
408+
set sc = ##class(isc.py.Main).ExecuteFunction("str.format", posList, kwDynamic,,,.result)
409409
do $$$AssertStatusOK(sc, "str.format execution OK")
410410
do $$$AssertEquals(result, "Positional: Hello World! Keyword: Alice, Bob", "str.format returned expected string")
411411
}
@@ -415,7 +415,7 @@ Method TestExecuteFunctionArgs()
415415
{
416416
set sc = ##class(isc.py.Main).ImportModule("random", ,.random)
417417

418-
set sc = ##class(isc.py.Main).ExecuteFunctionArgs(random _ ".randint", ,.result, 1, 100)
418+
set sc = ##class(isc.py.Main).ExecuteFunctionArgs(random _ ".randint", , ,.result, 1, 100)
419419
do $$$AssertStatusOK(sc, "randint execution OK")
420420
do $$$AssertTrue(((result>=1)&&(result<=100)), "Randint returned integer between 1 and 100")
421421

@@ -428,7 +428,7 @@ Method TestExecuteFunctionArgs()
428428
set arg3 = ##class(isc.py.util.Converter).EscapeString("Alice")
429429
set arg4 = ##class(isc.py.util.Converter).EscapeString("Bob")
430430

431-
set sc = ##class(isc.py.Main).ExecuteFunctionArgs("str.format",,.result, string, arg1, arg2, arg3, arg4)
431+
set sc = ##class(isc.py.Main).ExecuteFunctionArgs("str.format",,,.result, string, arg1, arg2, arg3, arg4)
432432
do $$$AssertStatusOK(sc, "str.format execution OK")
433433
do $$$AssertEquals(result, "Positional: Hello, World, Alice, Bob", "str.format returned expected string")
434434
}

0 commit comments

Comments
 (0)