I am finding an issue with iron python libraries while passing a boolean value
Say I have python code "booltest.py" like below.
if ip_bool is not True and ip_bool is not False :
print "invalid ip_bool"
And when I call it using Iron Python libraries
ScriptEngine engine = Python.CreateEngine();
ScriptScope scope = engine.CreateScope();
scope = engine.ExecuteFile("booltest.py", scope);
this results in printing 'invalid ip_bool' though its value is set to false
Further I updated "booltest.py" to test type and print more info
print "Before conversion"
print "class :" + ip_bool.__class__.__name__
print "value " + str(ip_bool)
print "ip_bool is not True # " + str(ip_bool is not True)
print "ip_bool is not False # " + str(ip_bool is not False)
ip_bool1 = bool(ip_bool)
print "\nAfter conversion"
print "class :" + ip_bool1.__class__.__name__
print "value " + str(ip_bool1)
print "ip_bool is not True # " + str(ip_bool1 is not True)
print "ip_bool is not False # " + str(ip_bool1 is not False)
and it yields
ip_bool is not True # True
ip_bool is not False # True
ip_bool is not True # True
ip_bool is not False # False
Thus passing a bool value from scripting libraries malfunctions
Here is a an approach where there is apparently no conversion malfunction between C# and IronPython for C# bool variable type.
It will be interesting if you can share the differences between the two approaches.
def test_func1(string_list, var_bool):
if var_bool is True:
return string_list + ";" + string_list
elif var_bool is False:
return string_list + "!" + string_list
if __name__ == '__main__':
string_list = [["string1", "string2"], ["string3", "string4"]]
print test_func1(string_list, False)
The C# code accessing the above mentioned Python code is as follows:
static void Main(string args)
List<string> sublist1 = new List<string>();
List<string> sublist2 = new List<string>();
List<List<string>> list1 = new List<List<string>>();
ScriptRuntime runtime = Python.CreateRuntime();
ScriptEngine engine = runtime.GetEngine("IronPython");
var paths = engine.GetSearchPaths();
var ironpythonpath = Environment.GetEnvironmentVariable("IRONPYTHONPATH", EnvironmentVariableTarget.Process);
var path_elements = ironpythonpath.Split(';');
foreach (string path_element in path_elements)
dynamic scope = runtime.UseFile("test_ipy1.py");
bool var_bool = false;
var str1 = scope.test_func1(list1, var_bool);
The environment variable ironpythonpath is defined as follows:
SET IRONPYTHONPATH=C:\Program Files\IronPython 2.7\Lib;C:\Program Files\IronPython 2.7\DLLs;C:\Progam Files\IronPython 2.7;C:\Program Files\IronPython 2.7\lib\site-packages
Your approach is calling a method in script. Whereas I am executing the script in a scope.
When I execute script I set variables with their vales in scope and then just execute it.
The reason I could think of is if ip_bool is set to None in the context of script.
ip_bool = None
print(ip_bool is not True)
print(ip_bool is not False)
Value of None in python is neither True nor False.
But that is not the case also. If it is None then the __class__.__name__ should have been NoneType
Contrary in this case ip_bool is recognized as bool
So it is malfunctioning.
is compares identity. None is not identical to True or False. So "ip_bool is not True" will evaluate to True and "ip_bool is not False" will evaluate to True. the standard Python function bool evaluates a Boolean expression.
So bool value conversion does not malfunction in IronPython.
I suggest that you close the issue.
If ip_bool is none then I would expect ip_bool.__class__.__name__ not to return the type as class :bool
This has to do with the fact that True/False are actually objects in IronPython, so when you do an is comparison of a variable with the object True, they are not the same object (when the variable is set from C#). When you set the value from Python, then the True object is assigned to the Python object and thus the instance comparison is True. I'm not sure there is a good fix for this.
In @bhadra's example, the call site binder likely converts C# System.Boolean into the appropriate Python True/False object, while in @sriharshav's original example ScriptEngine.SetVariable has no such conversion.
I see two solutions and a cop-out: adding code in SetVariable to convert booleans on the way in (but should we do that to Long as well? Decimal? DateTime? Nullable types?), or adding a special case to is handling for Boolean (and possible Nullable types/None, I don't know what it does).
The cop-out is to simply document it, and recommend against using is checks on True/False, which is already strongly discouraged by PEP8 (search for "is greeting") anyway.
I don't like special cases in the other code paths so I think we'll leave it as-is.