public void TestAsIntGood() { var i = new PyInt(5); var a = PyInt.AsInt(i); Assert.AreEqual(5, a.ToInt32()); }
public void TestAsIntBad() { var s = new PyString("Foo"); PyInt a = null; var ex = Assert.Throws <PythonException>(() => a = PyInt.AsInt(s)); StringAssert.StartsWith("invalid literal for int", ex.Message); Assert.IsNull(a); }
public dynamic Get(string name_in) { using (Py.GIL()) { dynamic result; string name = name_in; RunString("__" + name + "__type = str(type(" + name + "))"); string type = (string)Local.GetItem("__" + name + "__type").AsManagedObject(typeof(string)); if (type == "<class 'numpy.ndarray'>") { // If the array is not contiguous in memory, copy it first. // This overwrites the array (but obviously the contents stay the same). RunString( "if (" + name + ".__array_interface__['strides'] is not None):\n" + " " + name + " = copy.deepcopy(" + name + ")" ); RunString("__" + name + "__ptr = " + name + ".__array_interface__['data'][0]"); RunString("__" + name + "__nbytes = " + name + ".nbytes"); RunString("__" + name + "__shape = " + name + ".shape"); RunString("__" + name + "__dtype = str(" + name + ".dtype)"); System.IntPtr ptr = (System.IntPtr)PyInt.AsInt(Local.GetItem("__" + name + "__ptr")).ToInt32(); int nbytes = PyInt.AsInt(Local.GetItem("__" + name + "__nbytes")).ToInt32(); string dtype = (string)Local.GetItem("__" + name + "__dtype").AsManagedObject(typeof(string)); long[] shape = (long[])Local.GetItem("__" + name + "__shape").AsManagedObject(typeof(long[])); byte[] data = new byte[nbytes]; Marshal.Copy(ptr, data, 0, nbytes); System.Type result_type; if (dtype == "float64") { result_type = typeof(double); } else if (dtype == "int32") { result_type = typeof(int); } else if (dtype == "int64") { result_type = typeof(long); } else if (dtype == "uint8") { result_type = typeof(byte); } else { throw new PythonException("type not supported!"); } result = System.Array.CreateInstance(result_type, shape); System.Buffer.BlockCopy(data, 0, result, 0, nbytes); RunString("del __" + name + "__ptr"); RunString("del __" + name + "__nbytes"); RunString("del __" + name + "__dtype"); RunString("del __" + name + "__shape"); } else { System.Type result_type; if (type == "<class 'float'>") { result_type = typeof(double); } else if (type == "<class 'str'>") { result_type = typeof(string); } else if (type == "<class 'int'>") { result_type = typeof(long); // on a 64bit-system just "int" does not work! } else { throw new PythonException("type not supported!"); } result = Local.GetItem(name).AsManagedObject(result_type); } RunString("del __" + name + "__type"); return(result); } }
/// <summary> /// Allows to set variables in the python context. Allowed types are simple types (int, double, string, etc.) and /// arrays of those types. /// Numpy must be loaded before trying to pass arrays! /// /// TODO: Implement Marshal.Copy for input of arrays... /// </summary> /// <param name="name"></param> /// <param name="content"></param> public void Set(string name, dynamic content) { using (Py.GIL()) { System.Type ValueType = content.GetType(); // Arrays are always converted to python lists if (ValueType.IsArray) { if (!NumpyLoaded) { throw new PythonException("numpy must be loaded for array conversion."); } // BlockCopy possibly multidimensional array of arbitrary type to onedimensional byte array System.Type ElementType = ValueType.GetElementType(); int nbytes = content.Length * Marshal.SizeOf(ElementType); byte[] data = new byte[nbytes]; System.Buffer.BlockCopy(content, 0, data, 0, nbytes); // Create an python tuple with the dimensions of the input array PyObject[] lengths = new PyObject[content.Rank]; for (int i = 0; i < content.Rank; i++) { lengths[i] = new PyInt(content.GetLength(i)); } PyTuple shape = new PyTuple(lengths); // Create an empty numpy array in correct shape and datatype dynamic dtype; if (ElementType == typeof(int)) { dtype = np.int32; } else if (ElementType == typeof(double)) { dtype = np.float64; } else { throw new System.Exception("Datatype not supported!"); } dynamic pydata = np.empty(shape, dtype); // Copy the data to that array System.IntPtr ptr = (System.IntPtr)PyInt.AsInt(pydata.__array_interface__["data"][0]).ToInt32(); Marshal.Copy(data, 0, ptr, nbytes); // Push the variable to local dictionary UpdateLocals(name, pydata); } else { if (ValueType == typeof(int)) { UpdateLocals(name, new PyInt(content)); } else if (ValueType == typeof(string)) { UpdateLocals(name, new PyString(content)); } else if (ValueType == typeof(double)) { UpdateLocals(name, new PyFloat(content)); } else if (ValueType == typeof(bool)) { UpdateLocals(name, new PyInt(System.Convert.ToInt32(content))); RunStringTry(name + " = (" + name + " == 1)"); } else { throw new PythonException("Datatype not supported!"); } } } }