yahp
yahp copied to clipboard
Add `hp.from_init_signature` helper method
Consider the following:
import dataclasses
import yahp as hp
class Foo:
"""Foo class
Args:
bar (int, optional): Most helpful docstring ever
"""
def __init__(self, bar: int = 5):
self.bar = bar
@dataclasses.dataclass
class FooHparams:
bar: int = hp.optional("Most helpful docstring ever", default=5)
It's kinda redundant to have to copy and paste the docstring and default value in the yahp dataclass. Wouldn't it be nice if you could just do this?
import yahp as hp
import dataclasses
@dataclasses.dataclass
class FooHparams(hp.Hparams):
bar: int = hp.from_init_signature(Foo, kwarg_name="bar") # equivalent to: hp.optional("Most helpful docstring ever", default=5)
Implementation
This should be possible via python's inspect
and https://pypi.org/project/docstring-parser/
As for the API, I'm thinking something like this:
def init_from_signature(cls: Type[Any], kwarg_name: str):
'''Infer the docstring and default value from the ``__init__`` signature.
Args:
cls (type): The class's `__init__` signature to parse.
kwarg_name (str,): The name of the argument in the `__init__` signature.
If this field has a default value, then the YAHP dataclass field will be optional,
and that default value will be used.
If the field does not have a default value, then the YAHP dataclass field is required. '''
...
Other Designs
Originally, I thought it would have been nice to support the following:
import yahp as hp
import dataclasses
@dataclasses.dataclass
class FooHparams(hp.Hparams):
bar: int = hp.from_init_signature(Foo) # automatically infer that it's the `bar` argument from the field name in the hparams.
However, hp.from_init_signature
would not know whether to return a hp.optional
or hp.required
since it doesn't know the field name. It is impossible to set this information later (such as on __init_subclass__
), since python's dataclasses parses this on the @dataclass
decorator. We would need our own @yahp_datalcass
decorator to preprocess the class before passing it to python's dataclasses. This is a feature that can be done later if this is a design that we want...