/// <summary> /// PyObject Indexer /// </summary> /// <remarks> /// Provides a shorthand for the object versions of the GetItem and /// SetItem methods. /// </remarks> public virtual PyObject this[PyObject key] { get { return(GetItem(key)); } set { SetItem(key, value); } }
/// <summary> /// SetItem Method /// </summary> /// <remarks> /// For objects that support the Python sequence or mapping protocols, /// set the item at the given string index to the given value. This /// method raises a PythonException if the set operation fails. /// </remarks> public virtual void SetItem(string key, PyObject value) { using (var pyKey = new PyString(key)) { SetItem(pyKey, value); } }
/// <summary> /// SetItem Method /// </summary> /// <remarks> /// For objects that support the Python sequence or mapping protocols, /// set the item at the given numeric index to the given value. This /// method raises a PythonException if the set operation fails. /// </remarks> public virtual void SetItem(int index, PyObject value) { using (var pyindex = new PyInt(index)) { SetItem(pyindex, value); } }
/// <summary> /// TypeCheck Method /// </summary> /// <remarks> /// Returns true if the object o is of type typeOrClass or a subtype /// of typeOrClass. /// </remarks> public bool TypeCheck(PyObject typeOrClass) { return(Runtime.PyObject_TypeCheck(obj, typeOrClass.obj)); }
/// <summary> /// HasAttr Method /// </summary> /// <remarks> /// Returns true if the object has an attribute with the given name, /// where name is a PyObject wrapping a string or unicode object. /// </remarks> public bool HasAttr(PyObject name) { return(Runtime.PyObject_HasAttr(obj, name.obj) != 0); }
/// <summary> /// IsFloatType Method /// </summary> /// <remarks> /// Returns true if the given object is a Python float. /// </remarks> public static bool IsFloatType(PyObject value) { return(Runtime.PyFloat_Check(value.obj)); }
/// <summary> /// IsStringType Method /// </summary> /// <remarks> /// Returns true if the given object is a Python string. /// </remarks> public static bool IsStringType(PyObject value) { return(Runtime.PyString_Check(value.obj)); }
internal static bool ToManagedValue(IntPtr value, Type obType, out object result, bool setError) { if (obType == typeof(PyObject)) { Runtime.XIncref(value); // PyObject() assumes ownership result = new PyObject(value); return(true); } // Common case: if the Python value is a wrapped managed object // instance, just return the wrapped object. ManagedType mt = ManagedType.GetManagedObject(value); result = null; if (mt != null) { if (mt is CLRObject) { object tmp = ((CLRObject)mt).inst; if (obType.IsInstanceOfType(tmp)) { result = tmp; return(true); } Exceptions.SetError(Exceptions.TypeError, $"value cannot be converted to {obType}"); return(false); } if (mt is ClassBase) { result = ((ClassBase)mt).type; return(true); } // shouldn't happen return(false); } if (value == Runtime.PyNone && !obType.IsValueType) { result = null; return(true); } if (obType.IsGenericType && obType.GetGenericTypeDefinition() == typeof(Nullable <>)) { if (value == Runtime.PyNone) { result = null; return(true); } // Set type to underlying type obType = obType.GetGenericArguments()[0]; } if (obType.IsArray) { return(ToArray(value, obType, out result, setError)); } if (obType.IsEnum) { return(ToEnum(value, obType, out result, setError)); } // Conversion to 'Object' is done based on some reasonable default // conversions (Python string -> managed string, Python int -> Int32 etc.). if (obType == objectType) { if (Runtime.IsStringType(value)) { return(ToPrimitive(value, stringType, out result, setError)); } if (Runtime.PyBool_Check(value)) { return(ToPrimitive(value, boolType, out result, setError)); } if (Runtime.PyInt_Check(value)) { return(ToPrimitive(value, int32Type, out result, setError)); } if (Runtime.PyLong_Check(value)) { return(ToPrimitive(value, int64Type, out result, setError)); } if (Runtime.PyFloat_Check(value)) { return(ToPrimitive(value, doubleType, out result, setError)); } if (Runtime.PySequence_Check(value)) { return(ToArray(value, typeof(object[]), out result, setError)); } if (setError) { Exceptions.SetError(Exceptions.TypeError, "value cannot be converted to Object"); } return(false); } // Conversion to 'Type' is done using the same mappings as above for objects. if (obType == typeType) { if (value == Runtime.PyStringType) { result = stringType; return(true); } if (value == Runtime.PyBoolType) { result = boolType; return(true); } if (value == Runtime.PyIntType) { result = int32Type; return(true); } if (value == Runtime.PyLongType) { result = int64Type; return(true); } if (value == Runtime.PyFloatType) { result = doubleType; return(true); } if (value == Runtime.PyListType || value == Runtime.PyTupleType) { result = typeof(object[]); return(true); } if (setError) { Exceptions.SetError(Exceptions.TypeError, "value cannot be converted to Type"); } return(false); } return(ToPrimitive(value, obType, out result, setError)); }
internal static IntPtr ToPython(object value, Type type) { if (value is PyObject) { IntPtr handle = ((PyObject)value).Handle; Runtime.XIncref(handle); return(handle); } IntPtr result = IntPtr.Zero; // Null always converts to None in Python. if (value == null) { result = Runtime.PyNone; Runtime.XIncref(result); return(result); } if (value is IList && !(value is INotifyPropertyChanged) && value.GetType().IsGenericType) { using (var resultlist = new PyList()) { foreach (object o in (IEnumerable)value) { using (var p = new PyObject(ToPython(o, o?.GetType()))) { resultlist.Append(p); } } Runtime.XIncref(resultlist.Handle); return(resultlist.Handle); } } // it the type is a python subclass of a managed type then return the // underlying python object rather than construct a new wrapper object. var pyderived = value as IPythonDerivedType; if (null != pyderived) { #if NETSTANDARD return(ClassDerivedObject.ToPython(pyderived)); #else // if object is remote don't do this if (!System.Runtime.Remoting.RemotingServices.IsTransparentProxy(pyderived)) { return(ClassDerivedObject.ToPython(pyderived)); } #endif } // hmm - from Python, we almost never care what the declared // type is. we'd rather have the object bound to the actual // implementing class. type = value.GetType(); TypeCode tc = Type.GetTypeCode(type); switch (tc) { case TypeCode.Object: return(CLRObject.GetInstHandle(value, type)); case TypeCode.String: return(Runtime.PyUnicode_FromString((string)value)); case TypeCode.Int32: return(Runtime.PyInt_FromInt32((int)value)); case TypeCode.Boolean: if ((bool)value) { Runtime.XIncref(Runtime.PyTrue); return(Runtime.PyTrue); } Runtime.XIncref(Runtime.PyFalse); return(Runtime.PyFalse); case TypeCode.Byte: return(Runtime.PyInt_FromInt32((int)((byte)value))); case TypeCode.Char: return(Runtime.PyUnicode_FromOrdinal((int)((char)value))); case TypeCode.Int16: return(Runtime.PyInt_FromInt32((int)((short)value))); case TypeCode.Int64: return(Runtime.PyLong_FromLongLong((long)value)); case TypeCode.Single: // return Runtime.PyFloat_FromDouble((double)((float)value)); string ss = ((float)value).ToString(nfi); IntPtr ps = Runtime.PyString_FromString(ss); IntPtr op = Runtime.PyFloat_FromString(ps, IntPtr.Zero); Runtime.XDecref(ps); return(op); case TypeCode.Double: return(Runtime.PyFloat_FromDouble((double)value)); case TypeCode.SByte: return(Runtime.PyInt_FromInt32((int)((sbyte)value))); case TypeCode.UInt16: return(Runtime.PyInt_FromInt32((int)((ushort)value))); case TypeCode.UInt32: return(Runtime.PyLong_FromUnsignedLong((uint)value)); case TypeCode.UInt64: return(Runtime.PyLong_FromUnsignedLongLong((ulong)value)); default: if (value is IEnumerable) { using (var resultlist = new PyList()) { foreach (object o in (IEnumerable)value) { using (var p = new PyObject(ToPython(o, o?.GetType()))) { resultlist.Append(p); } } Runtime.XIncref(resultlist.Handle); return(resultlist.Handle); } } result = CLRObject.GetInstHandle(value, type); return(result); } }
/// <summary> /// IsSequenceType Method /// </summary> /// <remarks> /// Returns true if the given object implements the sequence protocol. /// </remarks> public static bool IsSequenceType(PyObject value) { return(Runtime.PySequence_Check(value.obj)); }