-
Notifications
You must be signed in to change notification settings - Fork 43
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
[WIP] tapify
with subparsers
#140
base: main
Are you sure you want to change the base?
Conversation
Demo# demo_subparsers.py
from typing import List, Optional
from tap import tapify_with_subparsers
class Class:
def __init__(self, arg_int: int, arg_bool: bool = True, arg_list: Optional[List[int]] = None):
"""
:param arg_int: some integer
:param arg_list: some list of integers
"""
self.arg_int = arg_int
self.arg_bool = arg_bool
self.arg_list = arg_list
def my_method(self, x: int) -> int:
"""Summary of my method
:param x: an integer
:return: another integer
"""
return self.arg_int + x
def my_other_method(self) -> Optional[List[int]]:
"""Summary of my other method
:return: hmmm
"""
return self.arg_list if self.arg_bool else None
def __repr__(self) -> str:
return f"{self.arg_int=} {self.arg_bool=} {self.arg_list=}"
if __name__ == "__main__":
print(tapify_with_subparsers(Class)) Running—
—outputs:
Running—
—outputs:
Running—
—outputs:
Running—
—outputs:
|
The name-collision issue is weird. Play w/ this # demo_names.py
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--verbose", default=0, type=int)
subparsers = parser.add_subparsers(dest="parser_name")
parser_lan = subparsers.add_parser("car")
parser_lan.add_argument("--boo")
parser_lan.add_argument("--verbose") # collides w/ name in the main parser
parser_serial = subparsers.add_parser("bus")
parser_serial.add_argument("--fun")
print(parser.parse_args()) For example, running—
outputs:
Seems unexpected. Not sure how to handle it: be consistent w/ |
method_name, | ||
subparser_tap, | ||
help=f"{method_name} help", # TODO: think about how to set | ||
description=f"{method_name} description", # TODO: think about how to set |
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.
TODO: think about how to set
I think that the docstring for that method should work well
Hi @kddubey, This PR looks awesome so far. Thank you!!
I'm a fan of the approach where Tap raises an error for name collisions and then adds a flag that applies a solution similar to the one in the stackoverflow that you linked. I think that second part can be a separate issue and implementation. For this PR, I think that raising an error is good. Kyle and I will discuss more soon. Thanks again, |
for method_name in dir(class_): | ||
method = getattr(class_, method_name) | ||
if method_name.startswith("_") or not callable(method): | ||
# TODO: maybe the user can input their own function (method_name: str -> bool) for deciding whether |
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.
Maybe add a decorator to mark methods as subparsers then this can all be integrated into the existing tapify
implementation.
--JK
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.
Neat. That sounds like a better interface
Fix #101
Not ready for a full review yet, but I'd appreciate feedback on the overall approach
I'll do all of the
# TODO:
s and add tests soonI'll also study
fire.Fire
's interface and behavior a bit more to understand what ppl want out of this type of feature