Skip to content
This repository was archived by the owner on Jul 17, 2024. It is now read-only.

feat: add support for Decimal and Decimal score types #110

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ public class PythonClassTranslator {
// $ is illegal in variables/methods in Python
public static final String TYPE_FIELD_NAME = "$TYPE";
public static final String CPYTHON_TYPE_FIELD_NAME = "$CPYTHON_TYPE";
private static final String JAVA_METHOD_PREFIX = "$method$";
private static final String PYTHON_JAVA_TYPE_MAPPING_PREFIX = "$pythonJavaTypeMapping";
public static final String JAVA_METHOD_PREFIX = "$method$";
public static final String PYTHON_JAVA_TYPE_MAPPING_PREFIX = "$pythonJavaTypeMapping";

public record PreparedClassInfo(PythonLikeType type, String className, String classInternalName) {
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package ai.timefold.jpyinterpreter.implementors;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.IdentityHashMap;
import java.util.Iterator;
Expand Down Expand Up @@ -31,6 +32,7 @@
import ai.timefold.jpyinterpreter.types.collections.PythonLikeTuple;
import ai.timefold.jpyinterpreter.types.errors.TypeError;
import ai.timefold.jpyinterpreter.types.numeric.PythonBoolean;
import ai.timefold.jpyinterpreter.types.numeric.PythonDecimal;
import ai.timefold.jpyinterpreter.types.numeric.PythonFloat;
import ai.timefold.jpyinterpreter.types.numeric.PythonInteger;
import ai.timefold.jpyinterpreter.types.numeric.PythonNumber;
Expand Down Expand Up @@ -65,76 +67,79 @@ public static PythonLikeObject wrapJavaObject(Object object, Map<Object, PythonL
return existingObject;
}

if (object instanceof OpaqueJavaReference) {
return ((OpaqueJavaReference) object).proxy();
if (object instanceof OpaqueJavaReference opaqueJavaReference) {
return opaqueJavaReference.proxy();
}

if (object instanceof PythonLikeObject) {
if (object instanceof PythonLikeObject instance) {
// Object already a PythonLikeObject; need to do nothing
return (PythonLikeObject) object;
return instance;
}

if (object instanceof Byte || object instanceof Short || object instanceof Integer || object instanceof Long) {
return PythonInteger.valueOf(((Number) object).longValue());
}

if (object instanceof BigInteger) {
return PythonInteger.valueOf((BigInteger) object);
if (object instanceof BigInteger integer) {
return PythonInteger.valueOf(integer);
}

if (object instanceof BigDecimal decimal) {
return new PythonDecimal(decimal);
}

if (object instanceof Float || object instanceof Double) {
return PythonFloat.valueOf(((Number) object).doubleValue());
}

if (object instanceof Boolean) {
return PythonBoolean.valueOf((Boolean) object);
if (object instanceof Boolean booleanValue) {
return PythonBoolean.valueOf(booleanValue);
}

if (object instanceof String) {
return PythonString.valueOf((String) object);
if (object instanceof String string) {
return PythonString.valueOf(string);
}

if (object instanceof Iterator) {
return new DelegatePythonIterator<>((Iterator) object);
if (object instanceof Iterator iterator) {
return new DelegatePythonIterator<>(iterator);
}

if (object instanceof List) {
if (object instanceof List list) {
PythonLikeList out = new PythonLikeList();
createdObjectMap.put(object, out);
for (Object item : (List) object) {
for (Object item : list) {
out.add(wrapJavaObject(item));
}
return out;
}

if (object instanceof Set) {
if (object instanceof Set set) {
PythonLikeSet out = new PythonLikeSet();
createdObjectMap.put(object, out);
for (Object item : (Set) object) {
for (Object item : set) {
out.add(wrapJavaObject(item));
}
return out;
}

if (object instanceof Map) {
if (object instanceof Map map) {
PythonLikeDict out = new PythonLikeDict();
createdObjectMap.put(object, out);
Set<Map.Entry<?, ?>> entrySet = ((Map) object).entrySet();
Set<Map.Entry<?, ?>> entrySet = map.entrySet();
for (Map.Entry<?, ?> entry : entrySet) {
out.put(wrapJavaObject(entry.getKey()), wrapJavaObject(entry.getValue()));
}
return out;
}

if (object instanceof Class) {
Class<?> maybeFunctionClass = (Class<?>) object;
if (object instanceof Class maybeFunctionClass) {
if (Set.of(maybeFunctionClass.getInterfaces()).contains(PythonLikeFunction.class)) {
return new PythonCode((Class<? extends PythonLikeFunction>) maybeFunctionClass);
}
}

if (object instanceof OpaquePythonReference) {
return new PythonObjectWrapper((OpaquePythonReference) object);
if (object instanceof OpaquePythonReference opaquePythonReference) {
return new PythonObjectWrapper(opaquePythonReference);
}

// Default: return a JavaObjectWrapper
Expand All @@ -161,6 +166,10 @@ public static PythonLikeType getPythonLikeType(Class<?> javaClass) {
return BuiltinTypes.INT_TYPE;
}

if (BigDecimal.class.equals(javaClass) || PythonDecimal.class.equals(javaClass)) {
return BuiltinTypes.DECIMAL_TYPE;
}

if (float.class.equals(javaClass) || double.class.equals(javaClass) ||
Float.class.equals(javaClass) || Double.class.equals(javaClass) ||
PythonFloat.class.equals(javaClass)) {
Expand Down Expand Up @@ -273,7 +282,7 @@ public static <T> T convertPythonObjectToJavaType(Class<? extends T> type, Pytho
PythonNumber pythonNumber = (PythonNumber) object;
Number value = pythonNumber.getValue();

if (type.equals(BigInteger.class)) {
if (type.equals(BigInteger.class) || type.equals(BigDecimal.class)) {
return (T) value;
}

Expand Down Expand Up @@ -355,13 +364,23 @@ public static void returnValue(MethodVisitor methodVisitor, MethodDescriptor met
Type.INT_TYPE.equals(returnAsmType) ||
Type.LONG_TYPE.equals(returnAsmType) ||
Type.FLOAT_TYPE.equals(returnAsmType) ||
Type.DOUBLE_TYPE.equals(returnAsmType)) {
Type.DOUBLE_TYPE.equals(returnAsmType) ||
Type.getType(BigInteger.class).equals(returnAsmType) ||
Type.getType(BigDecimal.class).equals(returnAsmType)) {
methodVisitor.visitTypeInsn(Opcodes.CHECKCAST, Type.getInternalName(PythonNumber.class));
methodVisitor.visitMethodInsn(Opcodes.INVOKEINTERFACE,
Type.getInternalName(PythonNumber.class),
"getValue",
Type.getMethodDescriptor(Type.getType(Number.class)),
true);

if (Type.getType(BigInteger.class).equals(returnAsmType) ||
Type.getType(BigDecimal.class).equals(returnAsmType)) {
methodVisitor.visitTypeInsn(Opcodes.CHECKCAST, returnAsmType.getInternalName());
methodVisitor.visitInsn(Opcodes.ARETURN);
return;
}

String wrapperClassName = null;
String methodName = null;
String methodDescriptor = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import ai.timefold.jpyinterpreter.types.collections.view.DictValueView;
import ai.timefold.jpyinterpreter.types.numeric.PythonBoolean;
import ai.timefold.jpyinterpreter.types.numeric.PythonComplex;
import ai.timefold.jpyinterpreter.types.numeric.PythonDecimal;
import ai.timefold.jpyinterpreter.types.numeric.PythonFloat;
import ai.timefold.jpyinterpreter.types.numeric.PythonInteger;
import ai.timefold.jpyinterpreter.types.numeric.PythonNumber;
Expand Down Expand Up @@ -60,6 +61,7 @@ public class BuiltinTypes {
public static final PythonLikeType BOOLEAN_TYPE = new PythonLikeType("bool", PythonBoolean.class, List.of(INT_TYPE));
public static final PythonLikeType FLOAT_TYPE = new PythonLikeType("float", PythonFloat.class, List.of(NUMBER_TYPE));
public final static PythonLikeType COMPLEX_TYPE = new PythonLikeType("complex", PythonComplex.class, List.of(NUMBER_TYPE));
public final static PythonLikeType DECIMAL_TYPE = new PythonLikeType("Decimal", PythonDecimal.class, List.of(NUMBER_TYPE));

public static final PythonLikeType STRING_TYPE = new PythonLikeType("str", PythonString.class, List.of(BASE_TYPE));
public static final PythonLikeType BYTES_TYPE = new PythonLikeType("bytes", PythonBytes.class, List.of(BASE_TYPE));
Expand Down
Loading
Loading