[ENHANCEMENT] TypedDict linting improvement
Is your enhancement request related to a problem? Please describe. Lately I had to create some GRPC clients, where there is no good "robot framework" way to parameterize requests when they have parameters with nested objects (I have no control over the protocol, having these is a sad fact of life).
I was quite happy when I realized that RoF has an inline dictionary syntax, and robotcode even lints it to some extent when using TypedDicts, but I also quickly realized that even though it's pretty cool, it only works for the "top level", and doesn't lint the dictionary values themselves(, or sub-dictionary values)
I realize that the whole thing by nature is somewhat of an anti-pattern in RoF, but sometimes RoF's own syntax itself is an anti-pattern to more complicated things that are inevitable, which is likely why the inline dictionary declaration became a thing in the first place.
See images in the context section
Describe the solution you'd like
I would like the TypedDict linting in keyword arguments to work for the values of the dict the same or in a similar way as it works for top level keyword arguments
Describe alternatives you've considered
The alternative I'm currently using is creating keywords for every TypedDict, which allows to build the entire dict from the bottom up, but referencing / finding the helper keywords, and actually building these is a huge pain
"Shallowing" everything to the top level is also an option, but there are either name collisions there, or things start to have very weird naming, and it's generally harder to convey the use of a parameter when it is not grouped with its relevant values, especially when there are relatively many parameters overall. Also, for those who may want to extract some parts of the dict separately for multiple similar dicts (GRPC messages in my case, for which this happens a lot) this makes it impossible due to the inevitably inconsistent naming
Alternatively I can manage figuring out the types by jumping through the type definitions, but many testers for whom I'm making the client can't.
Additional context
Normal usage (pretty nice)
It kinda shows the types
But There is no actual linting or checking
Although it's not that big of a deal for primitive types, more special ones like enums and nested TypedDicts would be very very useful to have linting and static type checking for.
E.g. for
the enum parameter is nice
but the one inside the dict and the other dict are not
This is quite challenging. The core issue is that with robotcode, I can only perform static analysis of Robot Framework code. However, as you may have noticed, the inline conversion for dictionaries, lists, and other data structures involves Python code execution. This would require implementing something like an inline Python code evaluation parser, which I haven't had time to properly design and consider. But I will sometimes.
I'm familiar with GRPC, though I'm not entirely certain about the specific implementation details you're working with. However, I do know about robotframework-openapitools, which shares some similarities with GRPC workflows. The interesting aspect of this library is that you don't need to manually create keywords for API requests - it automatically generates keywords from the OpenAPI specification with the correct parameters.
Perhaps a similar approach could be applied to GRPC? Instead of manually creating TypedDict structures and dealing with nested validation, there might be a way to generate properly typed keywords directly from the GRPC service definitions.
Hmm, I see, that does sound challenging.
Although do the above shown inline dict and list syntax really require Python execution?
I thought only the ${{...}} syntax involved explicit Python code execution.
Although considering the ones above are called list and dictionary literals in the docs, I guess they are fancy strings which you would then indeed need to parse, although I would assume that it is closer to JSON parsing than to Python isn't it? (still not great, but probably easier :D)
Regarding the GRPC suggestion / idea, it can be done to some degree, and I may or may not do it in some dynamic library way when I have more time (although it's very painful as Python is kind of GRPC's least favorite child).
The issue is that regardless of how and where keywords come to existence, the parameterization linting problem still remains.
That is because the messages in the API definition are practically nested dictionaries, and as far as I know there is no way to provide any kind of nested type hinting in RoF. TypedDicts were just an attempt of mine, but if you know of any way (it doesn't necessarily have to be a dict, I can convert from whatever to what I need as long as the hierarchy remains), I would be happy to use it, the only thing I don't want is to use dubious flattened parameter names (so a GRPC message like {paramName1: {paramName2: {paramName3: str}}} should not come in RoF as a parameter called paramName1_paramName2_paramName3: str), because it takes away grouping and some parameter names will eventually collide.
Basically I don't know any kind of RoF doc or type suggestion info that I could provide and would result in useful linting to the user for nested structures. The best I have is making separate keywords to construct sub-messages, but that is also very annoying to use compared to what I would have in let's say JS. Of course I know RoF's syntax with the white spaces leaves way less potential for that kind of convenience.