Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@aodag
Created April 10, 2019 00:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aodag/b7bc5f5f9676684f867b39f510ec4bfa to your computer and use it in GitHub Desktop.
Save aodag/b7bc5f5f9676684f867b39f510ec4bfa to your computer and use it in GitHub Desktop.
import argparse
import dataclasses
from typing import TypeVar, Generic, Type
T = TypeVar("T")
class Parser(Generic[T]):
def __init__(self, cls: Type[T]) -> None:
assert dataclasses.is_dataclass(cls)
self.cls = cls
self.parser = make_parser(cls)
def parse_args(self, args=None) -> T:
args = self.parser.parse_args(args)
return self.make_instance(vars(args))
def make_instance(self, d):
return self.cls(**d)
def make_parser(cls: Type[T]) -> argparse.ArgumentParser:
parser = argparse.ArgumentParser()
for f in dataclasses.fields(cls):
opt_name = f"--{f.name}"
default = None if f.default == dataclasses.MISSING else f.default
parser.add_argument(opt_name, type=f.type, default=default)
return parser
@dataclasses.dataclass
class WebOpt:
port: int = dataclasses.field(default=8080)
host: str = dataclasses.field(default="0.0.0.0")
def serve(opt: WebOpt) -> None:
print(f"serve on {opt.host}:{opt.port}")
def main() -> None:
parser = Parser(WebOpt)
args = parser.parse_args()
serve(args)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment