Skip to content
This repository has been archived by the owner on May 8, 2023. It is now read-only.

Add hp.from_init_signature helper method #97

Open
ravi-mosaicml opened this issue Jan 19, 2022 · 0 comments
Open

Add hp.from_init_signature helper method #97

ravi-mosaicml opened this issue Jan 19, 2022 · 0 comments
Assignees
Labels
Needs Design Further design is required. Do not start implementation until design questions are resolved.

Comments

@ravi-mosaicml
Copy link
Contributor

ravi-mosaicml commented Jan 19, 2022

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...

@ravi-mosaicml ravi-mosaicml added the Needs Design Further design is required. Do not start implementation until design questions are resolved. label Jan 20, 2022
@ravi-mosaicml ravi-mosaicml assigned anisehsani and unassigned jbloxham Feb 3, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Needs Design Further design is required. Do not start implementation until design questions are resolved.
Projects
None yet
Development

No branches or pull requests

3 participants