Closed timburke closed 4 years ago
I've saved some changes for this issue in branch "recursive-parsing-return-value-formatters". Will continue on this after issue #62
@timburke I want to clarify to make sure I am on the right way.. For described case, if we have docstring Returns stanza like
Returns:
Dict[User, Property] show as one_line[short_name, default]: description
We have to look for format_one_line
formatter in typedargs.types.basic_dict
module, right?
I have added a formatter there, you can take a look:
@dvksirin Correct.
Take a look also at the new epic #70 which contains some more details on the intended direction that we want to move toward. The goal is ultimately to have typedargs
work basically like function annotations where the annotated class contains all of the information and methods you need to convert it to / from a string or validate it.
Then we would have a legacy mechanism for mapping strings from a docstring to a corresponding class like we do now but eventually we would drop those once there was no longer any code that needed them.
Eventually all of the type extensions would go away since we wouldn't need them anymore.
@dvksirin Some more information on the intended use case here and why its important.
Here's a concrete example.
I have a function that queries AWS and returns the list of IAM groups that exist. There's a Group
class for each one. When called from the shell, I want to show the group name for each group but when called programmatically, I want to just return a list of Group
classes.
Right now the code is hacked:
@docannotate
def list_groups(self):
"""List all groups.
Returns:
list(str) show-as string: The list of all groups.
"""
raw_users = []
paginator = self._client.get_paginator('list_groups')
for response in paginator.paginate():
user_chunk = response.get('Groups', [])
raw_users.extend(user_chunk)
#TODO: Once typedargs#61 is resolved, return the actual class here.
return [x['GroupName'] for x in raw_users]
Ideally I would be able to do:
@docannotate
def list_groups(self):
"""List all groups.
Returns:
List[Group] show-as unordered(short_name): The list of all groups.
"""
raw_users = []
paginator = self._client.get_paginator('list_groups')
for response in paginator.paginate():
user_chunk = response.get('Groups', [])
raw_users.extend(user_chunk)
return raw_users
The result when calling from a script should be that you just get a normal list
of Group
objects but when calling interactively from the shell, you get that list printed as:
- group1
- group2
- group3
See #60 for the basic context that precedes this issue. There is an additional wrinkle on top of that issue though. Often the case where we most need control over how a return value is formatted is when the return value is a container type and we need to control how each item in the container is formatted.
We already support declaring complex types as composition of simple types, so we should also support "complex formatters" for those types that make reference to formatters for the subtypes.
For example, if we are returning a
Dict[User, Property]
, we should be able to specify ashow-as [formatter]
string on that return value of:This should be interpreted as:
format_one_line
should be called on thedict
object we're returning. It will be passed two callables: one that takes in an object and callsformat_short_name
on it and a second that takes in an object and callsstr()
on it (default
should be interpreted as a placeholder forstr
).Some caveats:
The goal should be that if we return a list of objects, we can control how each object in that list is turned into a string.