-
Notifications
You must be signed in to change notification settings - Fork 93
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix subtyping in dict service #7115
base: staging
Are you sure you want to change the base?
Conversation
81e1d11
to
05da3cb
Compare
} | ||
|
||
boxedSuperclassCandidate match { | ||
case candidate if isFloating(candidate) => |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Treating specially implicit conversion for floats is not a way to go, we should have option to check can be subclass without conversion in general
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To clarify: we already treat floats specially, the condition here is not changed: if
is replaced with pattern matching, the condition is extracted to separate def
above.
The only change here is in if isDecimalNumber
section:
ConversionFromClassesForDecimals.exists(ClassUtils.isAssignable(boxedGivenClass, _, true))
that checks boxedGivenClass
with all possible supertypes (I guess...)
replaced with
CanBeSubclassDeterminer.isAssignable(boxedGivenClass, candidate)
that checks boxedGivenClass
with exact given supertype. Aaaand that possibly collides with the java.math.BigDecimal is quite often returned as a wrapper for all kind of numbers
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, apart from this isAssignable(boxedGivenClass,...) the logic is exactly the same. To clarify, I think the current staging logic is buggy. It only checks whether a givenType CAN be converted, not if the conversion is to the givenSuperclass. Apart from that I've only included a fallback in case lang3 throws a false false, because the lib gives errors when it comes to decimal java types. In general the program execution flow is the same as intended before.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have moved this logic to a separate method and restored the previous logic in the handleNumberConversions method
object CanBeSubclassDeterminer extends CanBeSubclassDeterminer { | ||
|
||
// we use explicit autoboxing = true flag, as ClassUtils in commons-lang3:3.3 (used in Flink) cannot handle JDK 11... | ||
def isAssignable(from: Class[_], to: Class[_]): Boolean = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add a test showing when lang3 solution works wrong
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added in CanBeSubclassDeterminerSpec
@@ -135,7 +137,11 @@ trait CanBeSubclassDeterminer { | |||
(), | |||
f"${givenClass.display} and ${superclassCandidate.display} are not the same" | |||
) orElse | |||
isAssignable(givenClass.klass, superclassCandidate.klass) | |||
condNel( | |||
isAssignable(givenClass.klass, superclassCandidate.klass), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use CanBeSubclassDeterminer.isAssignable
to show that it is our class
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, changed
5976b3b
to
43706dc
Compare
Describe your changes
DictApiHttpService sometimes returns improper subtypes like Long type Dicts for Integer or won't return proper types like Number type dict for Long.
Issue is caused by bugs in lang3 lib used in CanBeSubclassDeterminer - the lib would sometimes return incorrect false, and our faulty logic in TypeConversionHandler - the code would return true even if no conversion was possible.
Fixed by adding a double check in SubclassDeterminer and fixing the logic in ConversionHandler.
Checklist before merge