Beispiel #1
0
        /// <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);
        }
Beispiel #3
0
        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));
            }
        }
Beispiel #4
0
        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);
        }
Beispiel #5
0
        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));
        }
Beispiel #6
0
        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));
            }
        }
Beispiel #7
0
        /// <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 {
Beispiel #8
0
        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));
            }
        }
Beispiel #9
0
        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 {