-
Notifications
You must be signed in to change notification settings - Fork 58
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
Update make_artifact to use value type for Union #342
Update make_artifact to use value type for Union #342
Conversation
You make a good point @kamalesh0406. Ideally, we would have access to the actual type of the object, instead of This is may require some messing around with how we create artifacts. Currently, we always use the function's type hint as artifact type. That's evidently suboptimal for Another option is to store the type's serialization as part of the JSON summary (I believe we do this for other types, such as |
Storing the Artifact with explicit type information sounds like the optimal solution to me. One complication / thing we should keep in mind: Currently we explicitly cast func inputs and outputs to their declared type hint types, but we plan to remove this behavior because it forces us to be rigorous when it comes to every single type, and provide a way to instantiate every single type, limiting support of external types. We intend to merely replace it with a check that the type can be casted. The removal would lead to an increase in the number of effective types, due to polymorphism and duck typing. Taking this effective un-cast type as the artifact's type could therefore result in handling types which don't have supported UI representations. In this case we could / would need to fall back to the declared type hint again, but we gain hit the ambiguous Union type. A premature solution proposal would be to have can_cast_type return the effective supported type instead of True, and use that as the Artifact type. For most types, this would be themselves. For Union, it would be one of the member types. |
sematic/ui/src/types/Types.tsx
Outdated
if (containsNoneType) { | ||
const otherTypes: TypeParamRepr[] = typeRepr[2].args.filter((argsTypeParamRep) => argsTypeParamRep.type[1]!=="NoneType"); | ||
|
||
//Union Types in Python should not contain more than two types. Therefore, the otherTypes array should be of length 1. |
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.
Union Types in Python should not contain more than two types
The said is probably true for the Optional
type.
But I am not sure it is always true for a generic Union type. It seems it is allowed to have more than two types.
Eg
Union[Union[int, str], float] == Union[int, str, float]
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.
Agree with Chance--you can have Union
of arbitrarily many types in python.
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.
Right, I should have mentioned it as Optional Types in the comments. I will correct it in my next revision. I agree that for the actual Union
type we can have multiple possible types as input.
sematic/ui/src/types/Types.tsx
Outdated
function UnionValueView(props: ValueViewProps) { | ||
const typeRepr = props.typeRepr as AliasTypeRepr; | ||
|
||
if (!typeRepr[2].args) { |
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.
Since typeRepr[2].args
appears several times, shall we assign it to a variable to give it a meaningful name?
e.g.
let [, , {args: typeArgs} ] = typeRepr
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.
Yup this sounds good. I will fix it in my next revision.
sematic/ui/src/types/Types.tsx
Outdated
return ValueView(props); | ||
} | ||
|
||
const noneTypeArgs: TypeParamRepr[] = typeRepr[2].args.filter((argsTypeParamRep) => argsTypeParamRep.type[1]==="NoneType"); |
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.
or alternatively
.filter(({type:[, typeName]}) => typeName === "NoneType");
I like this idea. If some server side processing could reduce it to the exact member type. It is much simpler. |
If storage cost is of concern, we can store the artifacts with a |
This is viable ONLY if we have a reliable way of identifying which type it is, using the declared type hint rather than just
If we just stored |
Given this, it will be a non-trivial change. Perhaps we should discuss in Discord to align on a solution? |
Sure we can discuss on discord about this. But I agree we would need a non-trivial solution for this since this problem is confined to |
a997150
to
5d1e825
Compare
I have updated the PR such that we store the actual value type in the artifact instead of using the type hint. I will add a unit test once I get the initial comments on it. |
sematic/types/types/union.py
Outdated
def is_union(type_: Any) -> bool: | ||
origin_type = get_origin_type(type_) | ||
|
||
return origin_type==Union |
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 want to know if this equality check is fine with everyone. The other choice would be to use a can_cast
here between the input and union type. But based on my understanding, the can_cast
function checks if we can cast the type to any of the types specified inside Union
and not the Union
type itself. Do correct me if I am wrong here.
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 think this works, also is
works here.
Also, add spaces around the operator:
origin_type is Union
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.
Sure I will update it.
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.
We're almost there, thank you.
sematic/types/types/union.py
Outdated
def is_union(type_: Any) -> bool: | ||
origin_type = get_origin_type(type_) | ||
|
||
return origin_type==Union |
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 think this works, also is
works here.
Also, add spaces around the operator:
origin_type is Union
5d1e825
to
a037b70
Compare
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.
Great work! Thank you for making the change.
@chance-an @neutralino1 can you merge it as well, I do not have write access.. |
Thank you, @kamalesh0406! |
This PR fixes issue sematic-ai#235, where we display the json summary for the list instead of the actual contents of the list. This code will work well for Optional Types, but it's not perfect. Suppose the user defines a type as `typing.Union[typing.List[int], typing.Tuple[int]]` or `typing.Union[int, float]` etc, we will not get the correct output. However, to fix this we would need to check the type of the value summary and choose the view based on it. I am hesitant to do this because checking types in Typescript for objects that were defined in Python seems weird to me at least. The ideal solution would be to figure out the value type and return the correct type from the backend instead of the `Union` type. I would like to get your views on whether I should go for this backend fix instead. Thanks.
This PR fixes issue #235, where we display the json summary for the list instead of the actual contents of the list. This code will work well for Optional Types, but it's not perfect.
Suppose the user defines a type as
typing.Union[typing.List[int], typing.Tuple[int]]
ortyping.Union[int, float]
etc, we will not get the correct output. However, to fix this we would need to check the type of the value summary and choose the view based on it. I am hesitant to do this because checking types in Typescript for objects that were defined in Python seems weird to me at least.The ideal solution would be to figure out the value type and return the correct type from the backend instead of the
Union
type. I would like to get your views on whether I should go for this backend fix instead. Thanks.