/// <summary> /// Implements the default __reduce_ex__ method as specified by PEP 307 case 2 (new-style instance, protocol 0 or 1) /// </summary> internal static PythonTuple ReduceProtocol0(CodeContext /*!*/ context, object self) { // CPython implements this in copy_reg._reduce_ex PythonType myType = DynamicHelpers.GetPythonType(self); // PEP 307 calls this "D" ThrowIfNativelyPickable(myType); object getState; bool hasGetState = PythonOps.TryGetBoundAttr(context, self, "__getstate__", out getState); object slots; if (PythonOps.TryGetBoundAttr(context, myType, "__slots__", out slots) && PythonOps.Length(slots) > 0 && !hasGetState) { // ??? does this work with superclass slots? throw PythonOps.TypeError("a class that defines __slots__ without defining __getstate__ cannot be pickled with protocols 0 or 1"); } PythonType closestNonPythonBase = FindClosestNonPythonBase(myType); // PEP 307 calls this "B" object func = context.LanguageContext.PythonReconstructor; object funcArgs = PythonTuple.MakeTuple( myType, closestNonPythonBase, TypeCache.Object == closestNonPythonBase ? null : PythonCalls.Call(context, closestNonPythonBase, self) ); object state; if (hasGetState) { state = PythonOps.CallWithContext(context, getState); } else { IPythonObject ipo = self as IPythonObject; if (ipo != null) { state = ipo.Dict; } else if (!PythonOps.TryGetBoundAttr(context, self, "__dict__", out state)) { state = null; } } if (!PythonOps.IsTrue(state)) { state = null; } return(PythonTuple.MakeTuple(func, funcArgs, state)); }
internal static object CallWorker(CodeContext /*!*/ context, PythonType dt, object[] args) { object newObject = PythonOps.CallWithContext(context, GetTypeNew(context, dt), ArrayUtils.Insert <object>(dt, args)); if (ShouldInvokeInit(dt, DynamicHelpers.GetPythonType(newObject), args.Length)) { PythonOps.CallWithContext(context, GetInitMethod(context, dt, newObject), args); AddFinalizer(context, dt, newObject); } return(newObject); }
public static object __new__(CodeContext /*!*/ context, PythonType cls, object x) { object value = null; if (x is string) { value = ParseFloat((string)x); } else if (x is Extensible <string> ) { if (!PythonTypeOps.TryInvokeUnaryOperator(context, x, "__float__", out value)) { value = ParseFloat(((Extensible <string>)x).Value); } } else if (x is char) { value = ParseFloat(ScriptingRuntimeHelpers.CharToString((char)x)); } else if (x is Complex) { throw PythonOps.TypeError("can't convert complex to float; use abs(z)"); } else { object d = PythonOps.CallWithContext(context, PythonOps.GetBoundAttr(context, x, "__float__")); if (d is double) { value = d; } else if (d is Extensible <double> ) { value = ((Extensible <double>)d).Value; } else { throw PythonOps.TypeError("__float__ returned non-float (type {0})", PythonTypeOps.GetName(d)); } } if (cls == TypeCache.Double) { return(value); } else { return(cls.CreateInstance(context, value)); } }
public static object __new__(CodeContext context, PythonType cls, object x) { Extensible<string> es; if (x is string) { return ReturnObject(context, cls, ParseBigIntegerSign((string)x, 10)); } else if ((es = x as Extensible<string>) != null) { object value; if (PythonTypeOps.TryInvokeUnaryOperator(context, x, "__long__", out value)) { return ReturnObject(context, cls, (BigInteger)value); } return ReturnObject(context, cls, ParseBigIntegerSign(es.Value, 10)); } if (x is double) return ReturnObject(context, cls, DoubleOps.__long__((double)x)); if (x is int) return ReturnObject(context, cls, (BigInteger)(int)x); if (x is BigInteger) return ReturnObject(context, cls, x); if (x is Complex) throw PythonOps.TypeError("can't convert complex to long; use long(abs(z))"); if (x is decimal) { return ReturnObject(context, cls, (BigInteger)(decimal)x); } object result; int intRes; BigInteger bigintRes; if (PythonTypeOps.TryInvokeUnaryOperator(context, x, "__long__", out result) && !Object.ReferenceEquals(result, NotImplementedType.Value)) { if (result is int || result is BigInteger || result is Extensible<int> || result is Extensible<BigInteger>) { return ReturnObject(context, cls, result); } else { throw PythonOps.TypeError("__long__ returned non-long (type {0})", PythonTypeOps.GetName(result)); } } else if (PythonOps.TryGetBoundAttr(context, x, "__trunc__", out result)) { result = PythonOps.CallWithContext(context, result); if (Converter.TryConvertToInt32(result, out intRes)) { return ReturnObject(context, cls, (BigInteger)intRes); } else if (Converter.TryConvertToBigInteger(result, out bigintRes)) { return ReturnObject(context, cls, bigintRes); } else { throw PythonOps.TypeError("__trunc__ returned non-Integral (type {0})", PythonTypeOps.GetName(result)); } } throw PythonOps.TypeError("long() argument must be a string or a number, not '{0}'", DynamicHelpers.GetPythonType(x).Name); }
public static object __new__(CodeContext /*!*/ context, PythonType cls, object x) { if (cls != TypeCache.Single) { return(cls.CreateInstance(context, x)); } if (x is string) { return(ParseFloat((string)x)); } else if (x is Extensible <string> ) { return(ParseFloat(((Extensible <string>)x).Value)); } else if (x is char) { return(ParseFloat(ScriptingRuntimeHelpers.CharToString((char)x))); } double doubleVal; if (Converter.TryConvertToDouble(x, out doubleVal)) { return((float)doubleVal); } if (x is Complex) { throw PythonOps.TypeError("can't convert complex to Single; use abs(z)"); } object d = PythonOps.CallWithContext(context, PythonOps.GetBoundAttr(context, x, "__float__")); if (d is double) { return((float)(double)d); } throw PythonOps.TypeError("__float__ returned non-float (type %s)", DynamicHelpers.GetPythonType(d)); }
public static object?__reduce_ex__(CodeContext /*!*/ context, object self, object protocol) { object objectReduce = PythonOps.GetBoundAttr(context, DynamicHelpers.GetPythonTypeFromType(typeof(object)), "__reduce__"); if (PythonOps.TryGetBoundAttr(context, DynamicHelpers.GetPythonType(self), "__reduce__", out object?myReduce)) { if (!PythonOps.IsRetBool(myReduce, objectReduce)) { // A derived class overrode __reduce__ but not __reduce_ex__, so call // specialized __reduce__ instead of generic __reduce_ex__. // (see the "The __reduce_ex__ API" section of PEP 307) return(PythonOps.CallWithContext(context, myReduce, self) !); } } if (context.LanguageContext.ConvertToInt32(protocol) < 2) { return(ReduceProtocol0(context, self)); } else { return(ReduceProtocol2(context, self)); } }
/// <summary> /// Implements the default __reduce_ex__ method as specified by PEP 307 case 3 (new-style instance, protocol 2) /// </summary> private static PythonTuple ReduceProtocol2(CodeContext /*!*/ context, object self) { PythonType myType = DynamicHelpers.GetPythonType(self); object func, state, listIterator, dictIterator; object[] funcArgs; func = context.LanguageContext.NewObject; object getNewArgsCallable; if (PythonOps.TryGetBoundAttr(context, myType, "__getnewargs__", out getNewArgsCallable)) { // TypeError will bubble up if __getnewargs__ isn't callable PythonTuple newArgs = PythonOps.CallWithContext(context, getNewArgsCallable, self) as PythonTuple; if (newArgs == null) { throw PythonOps.TypeError("__getnewargs__ should return a tuple"); } funcArgs = new object[1 + newArgs.Count]; funcArgs[0] = myType; for (int i = 0; i < newArgs.Count; i++) { funcArgs[i + 1] = newArgs[i]; } } else { funcArgs = new object[] { myType }; } if (!PythonTypeOps.TryInvokeUnaryOperator(context, self, "__getstate__", out state)) { object dict; IPythonObject ipo = self as IPythonObject; if (ipo != null) { dict = ipo.Dict; } else if (!PythonOps.TryGetBoundAttr(context, self, "__dict__", out dict)) { dict = null; } PythonDictionary initializedSlotValues = GetInitializedSlotValues(self); if (initializedSlotValues != null && initializedSlotValues.Count == 0) { initializedSlotValues = null; } if (dict == null && initializedSlotValues == null) { state = null; } else if (dict != null && initializedSlotValues == null) { state = dict; } else if (dict != null && initializedSlotValues != null) { state = PythonTuple.MakeTuple(dict, initializedSlotValues); } else /*dict == null && initializedSlotValues != null*/ state {
private static object FastNew(CodeContext /*!*/ context, object o) { Extensible <BigInteger> el; if (o is string) { return(__new__(null, (string)o, 10)); } if (o is double) { return(DoubleOps.__int__((double)o)); } if (o is int) { return(o); } if (o is bool) { return(((bool)o) ? 1 : 0); } if (o is BigInteger) { int res; if (((BigInteger)o).AsInt32(out res)) { return(ScriptingRuntimeHelpers.Int32ToObject(res)); } return(o); } if ((el = o as Extensible <BigInteger>) != null) { int res; if (el.Value.AsInt32(out res)) { return(ScriptingRuntimeHelpers.Int32ToObject(res)); } return(el.Value); } if (o is float) { return(DoubleOps.__int__((double)(float)o)); } if (o is Complex) { throw PythonOps.TypeError("can't convert complex to int; use int(abs(z))"); } if (o is Int64) { Int64 val = (Int64)o; if (Int32.MinValue <= val && val <= Int32.MaxValue) { return((Int32)val); } else { return((BigInteger)val); } } else if (o is UInt32) { UInt32 val = (UInt32)o; if (val <= Int32.MaxValue) { return((Int32)val); } else { return((BigInteger)val); } } else if (o is UInt64) { UInt64 val = (UInt64)o; if (val <= Int32.MaxValue) { return((Int32)val); } else { return((BigInteger)val); } } else if (o is Decimal) { Decimal val = (Decimal)o; if (Int32.MinValue <= val && val <= Int32.MaxValue) { return((Int32)val); } else { return((BigInteger)val); } } else if (o is Enum) { return(((IConvertible)o).ToInt32(null)); } Extensible <string> es = o as Extensible <string>; if (es != null) { // __int__ takes precedence, call it if it's available... object value; if (PythonTypeOps.TryInvokeUnaryOperator(DefaultContext.Default, es, "__int__", out value)) { return(value); } // otherwise call __new__ on the string value return(__new__(null, es.Value, 10)); } object result; int intRes; BigInteger bigintRes; if (PythonTypeOps.TryInvokeUnaryOperator(context, o, "__int__", out result) && !Object.ReferenceEquals(result, NotImplementedType.Value)) { if (result is int || result is BigInteger || result is Extensible <int> || result is Extensible <BigInteger> ) { return(result); } else { throw PythonOps.TypeError("__int__ returned non-Integral (type {0})", PythonTypeOps.GetOldName(result)); } } else if (PythonOps.TryGetBoundAttr(context, o, "__trunc__", out result)) { result = PythonOps.CallWithContext(context, result); if (result is int || result is BigInteger || result is Extensible <int> || result is Extensible <BigInteger> ) { return(result); } else if (Converter.TryConvertToInt32(result, out intRes)) { return(intRes); } else if (Converter.TryConvertToBigInteger(result, out bigintRes)) { return(bigintRes); } else { throw PythonOps.TypeError("__trunc__ returned non-Integral (type {0})", PythonTypeOps.GetOldName(result)); } } if (o is OldInstance) { throw PythonOps.AttributeError("{0} instance has no attribute '__trunc__'", PythonTypeOps.GetOldName((OldInstance)o)); } else { throw PythonOps.TypeError("int() argument must be a string or a number, not '{0}'", PythonTypeOps.GetName(o)); } }
private static PythonTuple ReduceProtocol2(CodeContext /*!*/ context, object self) { // builtin types which can't be pickled (due to tp_itemsize != 0) if (self is MemoryView) { throw PythonOps.TypeError("can't pickle memoryview objects"); } PythonType myType = DynamicHelpers.GetPythonType(self); object?state; object?[] funcArgs; var copyreg = context.LanguageContext.GetCopyRegModule(); var func = PythonOps.GetBoundAttr(context, copyreg, "__newobj__"); if (PythonOps.TryGetBoundAttr(context, myType, "__getnewargs__", out object?getNewArgsCallable)) { // TypeError will bubble up if __getnewargs__ isn't callable if (!(PythonOps.CallWithContext(context, getNewArgsCallable, self) is PythonTuple newArgs)) { throw PythonOps.TypeError("__getnewargs__ should return a tuple"); } funcArgs = new object[1 + newArgs.Count]; funcArgs[0] = myType; for (int i = 0; i < newArgs.Count; i++) { funcArgs[i + 1] = newArgs[i]; } } else { funcArgs = new object[] { myType }; } if (!PythonTypeOps.TryInvokeUnaryOperator(context, self, "__getstate__", out state)) { object?dict; if (self is IPythonObject ipo) { dict = ipo.Dict; } else if (!PythonOps.TryGetBoundAttr(context, self, "__dict__", out dict)) { dict = null; } PythonDictionary?initializedSlotValues = GetInitializedSlotValues(self); if (initializedSlotValues != null && initializedSlotValues.Count == 0) { initializedSlotValues = null; } if (dict == null && initializedSlotValues == null) { state = null; } else if (dict != null && initializedSlotValues == null) { state = dict; } else if (dict != null && initializedSlotValues != null) { state = PythonTuple.MakeTuple(dict, initializedSlotValues); } else /*dict == null && initializedSlotValues != null*/ state {