@@ -915,7 +915,7 @@ public Object reversed(VirtualFrame frame, Object cls, Object sequence,
915
915
@ Builtin (name = FLOAT , minNumOfPositionalArgs = 1 , maxNumOfPositionalArgs = 2 , constructsClass = PythonBuiltinClassType .PFloat )
916
916
@ GenerateNodeFactory
917
917
@ ReportPolymorphism
918
- public abstract static class FloatNode extends PythonBuiltinNode {
918
+ public abstract static class FloatNode extends PythonBinaryBuiltinNode {
919
919
@ Child private BytesNodes .ToBytesNode toByteArrayNode ;
920
920
@ Child private LookupAndCallUnaryNode callFloatNode ;
921
921
@ Child private LookupAndCallUnaryNode callReprNode ;
@@ -982,15 +982,6 @@ Object floatFromString(VirtualFrame frame, Object cls, String arg) {
982
982
return factoryCreateFloat (cls , value );
983
983
}
984
984
985
- @ Specialization (guards = "!isNativeClass(cls)" )
986
- Object floatFromBytes (VirtualFrame frame , Object cls , PIBytesLike arg ) {
987
- double value = convertBytesToDouble (frame , arg );
988
- if (isPrimitiveFloat (cls )) {
989
- return value ;
990
- }
991
- return factoryCreateFloat (cls , value );
992
- }
993
-
994
985
private double convertBytesToDouble (VirtualFrame frame , PIBytesLike arg ) {
995
986
return convertStringToDouble (frame , createString (getByteArray (frame , arg )), arg );
996
987
}
@@ -1101,16 +1092,13 @@ Object floatFromNone(Object cls, @SuppressWarnings("unused") PNone arg) {
1101
1092
return factory ().createFloat (cls , 0.0 );
1102
1093
}
1103
1094
1104
- @ Specialization (guards = "isPrimitiveFloat(cls)" )
1095
+ static boolean isHandledType (Object o ) {
1096
+ return PGuards .canBeInteger (o ) || PGuards .isDouble (o ) || o instanceof String || PGuards .isPNone (o );
1097
+ }
1098
+
1099
+ @ Specialization (guards = {"isPrimitiveFloat(cls)" , "!isHandledType(obj)" })
1105
1100
double doubleFromObject (VirtualFrame frame , @ SuppressWarnings ("unused" ) Object cls , Object obj ,
1106
1101
@ CachedLibrary (limit = "1" ) PythonObjectLibrary lib ) {
1107
-
1108
- if (obj instanceof PNone ) {
1109
- return 0.0 ;
1110
- }
1111
- if (obj instanceof String ) {
1112
- return convertStringToDouble (frame , (String ) obj , obj );
1113
- }
1114
1102
// Follows logic from PyNumber_Float:
1115
1103
// lib.asJavaDouble cannot be used here because it models PyFloat_AsDouble,
1116
1104
// which ignores __float__ defined by float subclasses, whereas PyNumber_Float
@@ -1136,6 +1124,7 @@ Object floatFromNone(Object cls, @SuppressWarnings("unused") PNone arg) {
1136
1124
return lib .asJavaDouble (lib .asIndex (obj ));
1137
1125
}
1138
1126
// Follows logic from PyFloat_FromString:
1127
+ // These types are handled only if the object doesn't implement __float__/__index__
1139
1128
if (obj instanceof PString ) {
1140
1129
return convertStringToDouble (frame , ((PString ) obj ).getValue (), obj );
1141
1130
} else if (obj instanceof PIBytesLike ) {
@@ -1151,10 +1140,14 @@ Object floatFromNone(Object cls, @SuppressWarnings("unused") PNone arg) {
1151
1140
throw raise (PythonBuiltinClassType .TypeError , ErrorMessages .ARG_MUST_BE_STRING_OR_NUMBER , "float()" , obj );
1152
1141
}
1153
1142
1154
- @ Specialization (guards = "!isNativeClass(cls)" )
1143
+ @ Specialization (guards = { "!isNativeClass(cls)" , "!isPrimitiveFloat(cls)" } )
1155
1144
Object doPythonObject (VirtualFrame frame , Object cls , Object obj ,
1156
- @ CachedLibrary (limit = "1" ) PythonObjectLibrary lib ) {
1157
- return floatFromDouble (cls , doubleFromObject (frame , cls , obj , lib ));
1145
+ @ Cached FloatNode recursiveCallNode ) {
1146
+ Object doubleValue = recursiveCallNode .executeWith (frame , PythonBuiltinClassType .PFloat , obj );
1147
+ if (!(doubleValue instanceof Double )) {
1148
+ throw CompilerDirectives .shouldNotReachHere ("float() returned non-primitive value" );
1149
+ }
1150
+ return floatFromDouble (cls , (double ) doubleValue );
1158
1151
}
1159
1152
1160
1153
// logic similar to float_subtype_new(PyTypeObject *type, PyObject *x) from CPython
@@ -1164,9 +1157,12 @@ Object doPythonObject(VirtualFrame frame, Object cls, Object obj,
1164
1157
Object doPythonObject (VirtualFrame frame , PythonNativeClass cls , Object obj ,
1165
1158
@ Cached @ SuppressWarnings ("unused" ) IsSubtypeNode isSubtype ,
1166
1159
@ Cached CExtNodes .FloatSubtypeNew subtypeNew ,
1167
- @ CachedLibrary (limit = "1" ) PythonObjectLibrary lib ) {
1168
- double realFloat = doubleFromObject (frame , PythonBuiltinClassType .PFloat , obj , lib );
1169
- return subtypeNew .call (cls , realFloat );
1160
+ @ Cached FloatNode recursiveCallNode ) {
1161
+ Object doubleValue = recursiveCallNode .executeWith (frame , PythonBuiltinClassType .PFloat , obj );
1162
+ if (!(doubleValue instanceof Double )) {
1163
+ throw CompilerDirectives .shouldNotReachHere ("float() returned non-primitive value" );
1164
+ }
1165
+ return subtypeNew .call (cls , (double ) doubleValue );
1170
1166
}
1171
1167
1172
1168
@ Fallback
0 commit comments