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 object FastNew(CodeContext /*!*/ context, object o, int @base = 10) { object result; switch (o) { case double d: return(DoubleOps.__int__(d)); case bool b: return(BoolOps.__int__(b)); case int _: return(o); case Extensible <int> ei: return(TryInvokeInt(context, o, out var value) ? value : ei.Value); case BigInteger val: return(val.IsInt32() ? (object)(int)val : o); case Extensible <BigInteger> ebi: return(TryInvokeInt(context, o, out result) ? result : ebi.Value.IsInt32() ? (object)(int)ebi.Value : ebi.Value); case float f: return(DoubleOps.__int__(f)); case long val: return(int.MinValue <= val && val <= int.MaxValue ? (object)(int)val : (BigInteger)val); case uint val: return(val <= int.MaxValue ? (object)(int)val : (BigInteger)val); case ulong val: return(val <= int.MaxValue ? (object)(int)val : (BigInteger)val); case decimal val: return(int.MinValue <= val && val <= int.MaxValue ? (object)(int)val : (BigInteger)val); case Enum e: return(((IConvertible)e).ToInt32(null)); case string s: return(LiteralParser.ParseIntegerSign(s, @base, FindStart(s, @base))); case Extensible <string> es: return(TryInvokeInt(context, o, out result) ? result : LiteralParser.ParseIntegerSign(es.Value, @base, FindStart(es.Value, @base))); default: break; } if (TryInvokeInt(context, o, out result)) { return(result); } else if (PythonTypeOps.TryInvokeUnaryOperator(context, o, "__trunc__", out result)) { switch (result) { case int _: return(result); case BigInteger bi: return(bi.IsInt32() ? (object)(int)bi : result); case bool b: return(BoolOps.__int__(b)); // Python 3.6: return the int value case Extensible <int> ei: return(ei.Value); // Python 3.6: return the int value case Extensible <BigInteger> ebi: return(ebi.Value.IsInt32() ? (object)(int)ebi.Value : ebi.Value); // Python 3.6: return the int value default: { if (TryInvokeInt(context, result, out var intResult)) { return(intResult); } throw PythonOps.TypeError("__trunc__ returned non-Integral (type {0})", PythonTypeOps.GetName(result)); } } } throw PythonOps.TypeError("int() argument must be a string, a bytes-like object or a number, not '{0}'", PythonTypeOps.GetName(o));