static private GetInstHandle ( Object ob ) : |
||
ob | Object | |
return |
/// <summary> /// SetError Method /// </summary> /// <remarks> /// Sets the current Python exception given a CLR exception /// object. The CLR exception instance is wrapped as a Python /// object, allowing it to be handled naturally from Python. /// </remarks> public static void SetError(Exception e) { // Because delegates allow arbitrary nesting of Python calling // managed calling Python calling... etc. it is possible that we // might get a managed exception raised that is a wrapper for a // Python exception. In that case we'd rather have the real thing. var pe = e as PythonException; if (pe != null) { Runtime.XIncref(pe.PyType); Runtime.XIncref(pe.PyValue); Runtime.XIncref(pe.PyTB); Runtime.PyErr_Restore(pe.PyType, pe.PyValue, pe.PyTB); return; } IntPtr op = CLRObject.GetInstHandle(e); IntPtr etype = Runtime.PyObject_GetAttr(op, PyIdentifier.__class__); Runtime.PyErr_SetObject(new BorrowedReference(etype), new BorrowedReference(op)); Runtime.XDecref(etype); Runtime.XDecref(op); }
/// <summary> /// DelegateObject __new__ implementation. The result of this is a new /// PyObject whose type is DelegateObject and whose ob_data is a handle /// to an actual delegate instance. The method wrapped by the actual /// delegate instance belongs to an object generated to relay the call /// to the Python callable passed in. /// </summary> public static IntPtr tp_new(IntPtr tp, IntPtr args, IntPtr kw) { var self = (DelegateObject)GetManagedObject(tp); if (!self.type.Valid) { return(Exceptions.RaiseTypeError(self.type.DeletedMessage)); } Type type = self.type.Value; if (Runtime.PyTuple_Size(args) != 1) { return(Exceptions.RaiseTypeError("class takes exactly one argument")); } IntPtr method = Runtime.PyTuple_GetItem(args, 0); if (Runtime.PyCallable_Check(method) != 1) { return(Exceptions.RaiseTypeError("argument must be callable")); } Delegate d = PythonEngine.DelegateManager.GetDelegate(type, method); return(CLRObject.GetInstHandle(d, self.pyHandle)); }
/// <summary> /// Set the 'args' slot on a python exception object that wraps /// a CLR exception. This is needed for pickling CLR exceptions as /// BaseException_reduce will only check the slots, bypassing the /// __getattr__ implementation, and thus dereferencing a NULL /// pointer. /// </summary> /// <param name="ob">The python object wrapping </param> internal static void SetArgsAndCause(IntPtr ob) { // e: A CLR Exception Exception e = ExceptionClassObject.ToException(ob); if (e == null) { return; } IntPtr args; if (!string.IsNullOrEmpty(e.Message)) { args = Runtime.PyTuple_New(1); IntPtr msg = Runtime.PyUnicode_FromString(e.Message); Runtime.PyTuple_SetItem(args, 0, msg); } else { args = Runtime.PyTuple_New(0); } Marshal.WriteIntPtr(ob, ExceptionOffset.args, args); #if PYTHON3 if (e.InnerException != null) { IntPtr cause = CLRObject.GetInstHandle(e.InnerException); Marshal.WriteIntPtr(ob, ExceptionOffset.cause, cause); } #endif }
/// <summary> /// SetError Method /// </summary> /// /// <remarks> /// Sets the current Python exception given a CLR exception /// object. The CLR exception instance is wrapped as a Python /// object, allowing it to be handled naturally from Python. /// </remarks> public static void SetError(Exception e) { // Because delegates allow arbitrary nestings of Python calling // managed calling Python calling... etc. it is possible that we // might get a managed exception raised that is a wrapper for a // Python exception. In that case we'd rather have the real thing. PythonException pe = e as PythonException; if (pe != null) { Runtime.PyErr_SetObject(pe.PyType, pe.PyValue); return; } IntPtr op = CLRObject.GetInstHandle(e); // XXX - hack to raise a compatible old-style exception ;( if (Runtime.wrap_exceptions) { op = GetExceptionInstanceWrapper(op); } IntPtr etype = Runtime.PyObject_GetAttrString(op, "__class__"); Runtime.PyErr_SetObject(etype, op); Runtime.Decref(etype); Runtime.Decref(op); }
/// <summary> /// Implements __new__ for reflected classes and value types. /// </summary> public static IntPtr tp_new(IntPtr tp, IntPtr args, IntPtr kw) { var self = GetManagedObject(tp) as ClassObject; // Sanity check: this ensures a graceful error if someone does // something intentially wrong like use the managed metatype for // a class that is not really derived from a managed class. if (self == null) { return(Exceptions.RaiseTypeError("invalid object")); } Type type = self.type; // Primitive types do not have constructors, but they look like // they do from Python. If the ClassObject represents one of the // convertible primitive types, just convert the arg directly. if (type.IsPrimitive || type == typeof(string)) { if (Runtime.PyTuple_Size(args) != 1) { Exceptions.SetError(Exceptions.TypeError, "no constructors match given arguments"); return(IntPtr.Zero); } IntPtr op = Runtime.PyTuple_GetItem(args, 0); object result; if (!Converter.ToManaged(op, type, out result, true)) { return(IntPtr.Zero); } return(CLRObject.GetInstHandle(result, tp)); } if (type.IsAbstract) { Exceptions.SetError(Exceptions.TypeError, "cannot instantiate abstract class"); return(IntPtr.Zero); } if (type.IsEnum) { Exceptions.SetError(Exceptions.TypeError, "cannot instantiate enumeration"); return(IntPtr.Zero); } object obj = self.binder.InvokeRaw(IntPtr.Zero, args, kw); if (obj == null) { return(IntPtr.Zero); } return(CLRObject.GetInstHandle(obj, tp)); }
public static IntPtr tp_new(IntPtr tpRaw, IntPtr args, IntPtr kw) { if (kw != IntPtr.Zero) { return(Exceptions.RaiseTypeError("array constructor takes no keyword arguments")); } var tp = new BorrowedReference(tpRaw); var self = GetManagedObject(tp) as ArrayObject; if (!self.type.Valid) { return(Exceptions.RaiseTypeError(self.type.DeletedMessage)); } Type arrType = self.type.Value; long[] dimensions = new long[Runtime.PyTuple_Size(args)]; if (dimensions.Length == 0) { return(Exceptions.RaiseTypeError("array constructor requires at least one integer argument or an object convertible to array")); } if (dimensions.Length != 1) { return(CreateMultidimensional(arrType.GetElementType(), dimensions, shapeTuple: new BorrowedReference(args), pyType: tp) .DangerousMoveToPointerOrNull()); } IntPtr op = Runtime.PyTuple_GetItem(args, 0); // create single dimensional array if (Runtime.PyInt_Check(op)) { dimensions[0] = Runtime.PyLong_AsSignedSize_t(op); if (dimensions[0] == -1 && Exceptions.ErrorOccurred()) { Exceptions.Clear(); } else { return(NewInstance(arrType.GetElementType(), tp, dimensions) .DangerousMoveToPointerOrNull()); } } object result; // this implements casting to Array[T] if (!Converter.ToManaged(op, arrType, out result, true)) { return(IntPtr.Zero); } return(CLRObject.GetInstHandle(result, tp) .DangerousGetAddress()); }
/// <summary> /// FromManagedObject Method /// </summary> /// <remarks> /// Given an arbitrary managed object, return a Python instance that /// reflects the managed object. /// </remarks> public static PyObject FromManagedObject(object ob) { // Special case: if ob is null, we return None. if (ob == null) { Runtime.XIncref(Runtime.PyNone); return(new PyObject(Runtime.PyNone)); } IntPtr op = CLRObject.GetInstHandle(ob); return(new PyObject(op)); }
public static IntPtr tp_new(IntPtr tp, IntPtr args, IntPtr kw) { var self = GetManagedObject(tp) as ArrayObject; if (Runtime.Interop.PyTuple_Size(args) != 1) { return(Exceptions.RaiseTypeError("array expects 1 argument")); } IntPtr op = Runtime.Interop.PyTuple_GetItem(args, 0); object result; if (!Converter.ToManaged(op, self.type, out result, true)) { return(IntPtr.Zero); } return(CLRObject.GetInstHandle(result, tp)); }
/// <summary> /// Implements __new__ for reflected interface types. /// </summary> public static IntPtr tp_new(IntPtr tp, IntPtr args, IntPtr kw) { var self = (InterfaceObject)GetManagedObject(tp); if (!self.type.Valid) { return(Exceptions.RaiseTypeError(self.type.DeletedMessage)); } var nargs = Runtime.PyTuple_Size(args); Type type = self.type.Value; object obj; if (nargs == 1) { IntPtr inst = Runtime.PyTuple_GetItem(args, 0); var co = GetManagedObject(inst) as CLRObject; if (co == null || !type.IsInstanceOfType(co.inst)) { Exceptions.SetError(Exceptions.TypeError, $"object does not implement {type.Name}"); return(IntPtr.Zero); } obj = co.inst; } else if (nargs == 0 && self.ctor != null) { obj = self.ctor.Invoke(null); if (obj == null || !type.IsInstanceOfType(obj)) { Exceptions.SetError(Exceptions.TypeError, "CoClass default constructor failed"); return(IntPtr.Zero); } } else { Exceptions.SetError(Exceptions.TypeError, "interface takes exactly one argument"); return(IntPtr.Zero); } return(CLRObject.GetInstHandle(obj, self.pyHandle)); }
//==================================================================== // Implements __new__ for reflected interface types. //==================================================================== public static IntPtr tp_new(IntPtr tp, IntPtr args, IntPtr kw) { InterfaceObject self = (InterfaceObject)GetManagedObject(tp); int nargs = Runtime.PyTuple_Size(args); Type type = self.type; Object obj; if (nargs == 1) { IntPtr inst = Runtime.PyTuple_GetItem(args, 0); CLRObject co = GetManagedObject(inst) as CLRObject; if ((co == null) || (!type.IsInstanceOfType(co.inst))) { string msg = "object does not implement " + type.Name; Exceptions.SetError(Exceptions.TypeError, msg); return(IntPtr.Zero); } obj = co.inst; } else if ((nargs == 0) && (self.ctor != null)) { obj = self.ctor.Invoke(null); if (obj == null || !type.IsInstanceOfType(obj)) { Exceptions.SetError(Exceptions.TypeError, "CoClass default constructor failed" ); return(IntPtr.Zero); } } else { Exceptions.SetError(Exceptions.TypeError, "interface takes exactly one argument" ); return(IntPtr.Zero); } return(CLRObject.GetInstHandle(obj, self.pyHandle)); }
public static IntPtr tp_new(IntPtr tp, IntPtr args, IntPtr kw) { DelegateObject self = (DelegateObject)GetManagedObject(tp); if (Runtime.PyTuple_Size(args) != 1) { string message = "class takes exactly one argument"; return(Exceptions.RaiseTypeError(message)); } IntPtr method = Runtime.PyTuple_GetItem(args, 0); if (Runtime.PyCallable_Check(method) != 1) { return(Exceptions.RaiseTypeError("argument must be callable")); } Delegate d = DelegateManager.GetDelegate(self.type, method); return(CLRObject.GetInstHandle(d, self.pyHandle)); }
/// <summary> /// Expose the wrapped implementation through attributes in both /// converted/encoded (__implementation__) and raw (__raw_implementation__) form. /// </summary> public static IntPtr tp_getattro(IntPtr ob, IntPtr key) { var clrObj = (CLRObject)GetManagedObject(ob); if (!Runtime.PyString_Check(key)) { return(Exceptions.RaiseTypeError("string expected")); } string name = Runtime.GetManagedString(key); if (name == "__implementation__") { return(Converter.ToPython(clrObj.inst)); } else if (name == "__raw_implementation__") { return(CLRObject.GetInstHandle(clrObj.inst)); } return(Runtime.PyObject_GenericGetAttr(ob, key)); }
/// <summary> /// BoundContructor.__call__(PyObject *callable_object, PyObject *args, PyObject *kw) /// </summary> /// <param name="op"> PyObject *callable_object </param> /// <param name="args"> PyObject *args </param> /// <param name="kw"> PyObject *kw </param> /// <returns> A reference to a new instance of the class by invoking the selected ctor(). </returns> public static IntPtr tp_call(IntPtr op, IntPtr args, IntPtr kw) { var self = (BoundContructor)GetManagedObject(op); // Even though a call with null ctorInfo just produces the old behavior /*if (self.ctorInfo == null) { * string msg = "Usage: Class.Overloads[CLR_or_python_Type, ...]"; * return Exceptions.RaiseTypeError(msg); * }*/ // Bind using ConstructorBinder.Bind and invoke the ctor providing a null instancePtr // which will fire self.ctorInfo using ConstructorInfo.Invoke(). object obj = self.ctorBinder.InvokeRaw(IntPtr.Zero, args, kw, self.ctorInfo); if (obj == null) { // XXX set an error return(IntPtr.Zero); } // Instantiate the python object that wraps the result of the method call // and return the PyObject* to it. return(CLRObject.GetInstHandle(obj, self.pyTypeHndl)); }
/// <summary> /// Wrap the given object in an interface object, so that only methods /// of the interface are available. /// </summary> public IntPtr WrapObject(object impl) { var objPtr = CLRObject.GetInstHandle(impl, pyHandle); return(objPtr); }
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.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 || NETCOREAPP 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.Interop.PyUnicode_FromOrdinal((int)((char)value))); case TypeCode.Int16: return(Runtime.PyInt_FromInt32((int)((short)value))); case TypeCode.Int64: return(Runtime.Interop.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.Interop.PyFloat_FromString(ps, IntPtr.Zero); Runtime.XDecref(ps); return(op); case TypeCode.Double: return(Runtime.Interop.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.Interop.PyLong_FromUnsignedLong((uint)value)); case TypeCode.UInt64: return(Runtime.Interop.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); } }
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 (Type.GetTypeCode(type) == TypeCode.Object && value.GetType() != typeof(object)) { var encoded = PyObjectConversions.TryEncode(value, type); if (encoded != null) { result = encoded.Handle; 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); } } if (type.IsInterface) { var ifaceObj = (InterfaceObject)ClassManager.GetClass(type); return(ifaceObj.WrapObject(value)); } // We need to special case interface array handling to ensure we // produce the correct type. Value may be an array of some concrete // type (FooImpl[]), but we want access to go via the interface type // (IFoo[]). if (type.IsArray && type.GetElementType().IsInterface) { return(CLRObject.GetInstHandle(value, type)); } // 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 (!IsTransparentProxy(pyderived)) { return(ClassDerivedObject.ToPython(pyderived)); } } // 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); } }
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 (EncodableByUser(type, value)) { var encoded = PyObjectConversions.TryEncode(value, type); if (encoded != null) { result = encoded.Handle; Runtime.XIncref(result); return(result); } } if (type.IsInterface) { var ifaceObj = (InterfaceObject)ClassManager.GetClass(type); return(ifaceObj.WrapObject(value)); } if (type.IsArray || type.IsEnum) { return(CLRObject.GetInstHandle(value, type)); } // 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 (!IsTransparentProxy(pyderived)) { return(ClassDerivedObject.ToPython(pyderived)); } } // ModuleObjects are created in a way that their wrapping them as // a CLRObject fails, the ClassObject has no tpHandle. Return the // pyHandle as is, do not convert. if (value is ModuleObject modobj) { var handle = modobj.pyHandle; Runtime.XIncref(handle); return(handle); } // 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(); if (type.IsEnum) { return(CLRObject.GetInstHandle(value, type)); } TypeCode tc = Type.GetTypeCode(type); switch (tc) { case TypeCode.Object: return(CLRObject.GetInstHandle(value, type)); case TypeCode.String: return(Runtime.PyString_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((byte)value)); case TypeCode.Char: return(Runtime.PyUnicode_FromOrdinal((int)((char)value))); case TypeCode.Int16: return(Runtime.PyInt_FromInt32((short)value)); case TypeCode.Int64: return(Runtime.PyLong_FromLongLong((long)value).DangerousMoveToPointerOrNull()); case TypeCode.Single: return(Runtime.PyFloat_FromDouble((float)value)); case TypeCode.Double: return(Runtime.PyFloat_FromDouble((double)value)); case TypeCode.SByte: return(Runtime.PyInt_FromInt32((sbyte)value)); case TypeCode.UInt16: return(Runtime.PyInt_FromInt32((ushort)value)); case TypeCode.UInt32: return(Runtime.PyLong_FromUnsignedLongLong((uint)value).DangerousMoveToPointerOrNull()); case TypeCode.UInt64: return(Runtime.PyLong_FromUnsignedLongLong((ulong)value).DangerousMoveToPointerOrNull()); default: return(CLRObject.GetInstHandle(value, type)); } }
//==================================================================== // Implements __new__ for reflected classes and value types. //==================================================================== public static IntPtr tp_new(IntPtr tp, IntPtr args, IntPtr kw) { ClassObject self = GetManagedObject(tp) as ClassObject; // Sanity check: this ensures a graceful error if someone does // something intentially wrong like use the managed metatype for // a class that is not really derived from a managed class. if (self == null) { return(Exceptions.RaiseTypeError("invalid object")); } Type type = self.type; // Primitive types do not have constructors, but they look like // they do from Python. If the ClassObject represents one of the // convertible primitive types, just convert the arg directly. if (type.IsPrimitive || type == typeof(String)) { if (Runtime.PyTuple_Size(args) != 1) { Exceptions.SetError(Exceptions.TypeError, "no constructors match given arguments" ); return(IntPtr.Zero); } IntPtr op = Runtime.PyTuple_GetItem(args, 0); Object result; if (!Converter.ToManaged(op, type, out result, true)) { return(IntPtr.Zero); } return(CLRObject.GetInstHandle(result, tp)); } if (type.IsAbstract) { Exceptions.SetError(Exceptions.TypeError, "cannot instantiate abstract class" ); return(IntPtr.Zero); } if (type.IsEnum) { Exceptions.SetError(Exceptions.TypeError, "cannot instantiate enumeration" ); return(IntPtr.Zero); } Object obj = self.binder.InvokeRaw(IntPtr.Zero, args, kw); if (obj == null) { // It is possible for __new__ to be invoked on construction // of a Python subclass of a managed class, so args may // reflect more args than are required to instantiate the // class. So if we cant find a ctor that matches, we'll see // if there is a default constructor and, if so, assume that // any extra args are intended for the subclass' __init__. IntPtr eargs = Runtime.PyTuple_New(0); obj = self.binder.InvokeRaw(IntPtr.Zero, eargs, kw); Runtime.Decref(eargs); if (obj == null) { return(IntPtr.Zero); } } return(CLRObject.GetInstHandle(obj, tp)); }
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 (Type.GetTypeCode(type) == TypeCode.Object && value.GetType() != typeof(object)) { var encoded = PyObjectConversions.TryEncode(value, type); if (encoded != null) { result = encoded.Handle; 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 (!IsTransparentProxy(pyderived)) { return(ClassDerivedObject.ToPython(pyderived)); } } // 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: if (value is TimeSpan) { var timespan = (TimeSpan)value; IntPtr timeSpanArgs = Runtime.PyTuple_New(1); Runtime.PyTuple_SetItem(timeSpanArgs, 0, Runtime.PyFloat_FromDouble(timespan.TotalDays)); var returnTimeSpan = Runtime.PyObject_CallObject(timeSpanCtor, timeSpanArgs); // clean up Runtime.XDecref(timeSpanArgs); return(returnTimeSpan); } 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); NewReference op = Runtime.PyFloat_FromString(new BorrowedReference(ps));; Runtime.XDecref(ps); return(op.DangerousMoveToPointerOrNull()); 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)); case TypeCode.Decimal: // C# decimal to python decimal has a big impact on performance // so we will use C# double and python float return(Runtime.PyFloat_FromDouble(decimal.ToDouble((decimal)value))); case TypeCode.DateTime: var datetime = (DateTime)value; var size = datetime.Kind == DateTimeKind.Unspecified ? 7 : 8; IntPtr dateTimeArgs = Runtime.PyTuple_New(size); Runtime.PyTuple_SetItem(dateTimeArgs, 0, Runtime.PyInt_FromInt32(datetime.Year)); Runtime.PyTuple_SetItem(dateTimeArgs, 1, Runtime.PyInt_FromInt32(datetime.Month)); Runtime.PyTuple_SetItem(dateTimeArgs, 2, Runtime.PyInt_FromInt32(datetime.Day)); Runtime.PyTuple_SetItem(dateTimeArgs, 3, Runtime.PyInt_FromInt32(datetime.Hour)); Runtime.PyTuple_SetItem(dateTimeArgs, 4, Runtime.PyInt_FromInt32(datetime.Minute)); Runtime.PyTuple_SetItem(dateTimeArgs, 5, Runtime.PyInt_FromInt32(datetime.Second)); // datetime.datetime 6th argument represents micro seconds var totalSeconds = datetime.TimeOfDay.TotalSeconds; var microSeconds = Convert.ToInt32((totalSeconds - Math.Truncate(totalSeconds)) * 1000000); if (microSeconds == 1000000) { microSeconds = 999999; } Runtime.PyTuple_SetItem(dateTimeArgs, 6, Runtime.PyInt_FromInt32(microSeconds)); if (size == 8) { Runtime.PyTuple_SetItem(dateTimeArgs, 7, TzInfo(datetime.Kind)); } var returnDateTime = Runtime.PyObject_CallObject(dateTimeCtor, dateTimeArgs); // clean up Runtime.XDecref(dateTimeArgs); return(returnDateTime); 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); } }
internal static IntPtr ToPython(Object value, Type type) { IntPtr result = IntPtr.Zero; // Null always converts to None in Python. if (value == null) { result = Runtime.PyNone; Runtime.Incref(result); return(result); } // it the type is a python subclass of a managed type then return the // underying python object rather than construct a new wrapper object. IPythonDerivedType pyderived = value as IPythonDerivedType; if (null != pyderived) { return(ClassDerivedObject.ToPython(pyderived)); } // 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: result = CLRObject.GetInstHandle(value, type); // XXX - hack to make sure we convert new-style class based // managed exception instances to wrappers ;( if (Runtime.wrap_exceptions) { Exception e = value as Exception; if (e != null) { return(Exceptions.GetExceptionInstanceWrapper(result)); } } return(result); 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.Incref(Runtime.PyTrue); return(Runtime.PyTrue); } Runtime.Incref(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.Decref(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.Incref(resultlist.Handle); return(resultlist.Handle); } } result = CLRObject.GetInstHandle(value, type); return(result); } }
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.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) { return(ClassDerivedObject.ToPython(pyderived)); } // 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: if (value is TimeSpan) { var timespan = (TimeSpan)value; IntPtr timeSpanArgs = Runtime.PyTuple_New(1); Runtime.PyTuple_SetItem(timeSpanArgs, 0, Runtime.PyFloat_FromDouble(timespan.TotalDays)); return(Runtime.PyObject_CallObject(timeSpanCtor, timeSpanArgs)); } 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)); case TypeCode.Decimal: string d2s = ((decimal)value).ToString(nfi); IntPtr d2p = Runtime.PyString_FromString(d2s); IntPtr decimalArgs = Runtime.PyTuple_New(1); Runtime.PyTuple_SetItem(decimalArgs, 0, d2p); return(Runtime.PyObject_CallObject(decimalCtor, decimalArgs)); case TypeCode.DateTime: var datetime = (DateTime)value; IntPtr dateTimeArgs = Runtime.PyTuple_New(8); Runtime.PyTuple_SetItem(dateTimeArgs, 0, Runtime.PyInt_FromInt32(datetime.Year)); Runtime.PyTuple_SetItem(dateTimeArgs, 1, Runtime.PyInt_FromInt32(datetime.Month)); Runtime.PyTuple_SetItem(dateTimeArgs, 2, Runtime.PyInt_FromInt32(datetime.Day)); Runtime.PyTuple_SetItem(dateTimeArgs, 3, Runtime.PyInt_FromInt32(datetime.Hour)); Runtime.PyTuple_SetItem(dateTimeArgs, 4, Runtime.PyInt_FromInt32(datetime.Minute)); Runtime.PyTuple_SetItem(dateTimeArgs, 5, Runtime.PyInt_FromInt32(datetime.Second)); Runtime.PyTuple_SetItem(dateTimeArgs, 6, Runtime.PyInt_FromInt32(1000 * datetime.Millisecond)); Runtime.PyTuple_SetItem(dateTimeArgs, 7, TzInfo(datetime.Kind)); return(Runtime.PyObject_CallObject(dateTimeCtor, dateTimeArgs)); 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); } }