xadrianzetx / optuna-distributed

Distributed hyperparameter optimization made easy
MIT License
34 stars 1 forks source link

Avoid type bingo in `suggest_categorical` #46

Closed xadrianzetx closed 2 years ago

xadrianzetx commented 2 years ago

Inspired by https://github.com/optuna/optuna/pull/4143, but uses generics instead.

ConnorBaker commented 2 years ago

In this formulation, I was unable to get heterogenous lists to type check.

For example, [1, "fish", 2, "fish"] is an inhabitant of Sequence[CategoricalChoiceType]. However, [1, "fish", 2, "fish"] is not an inhabitant of Sequence[T] for any T in CategoricalChoiceType.

EDIT: For what it's worth, I was also unable to get this to work with something like

@overload
def suggest_categorical(self, name: str, choices: Sequence[_T]) -> _T:
    ...

@overload
def suggest_categorical(
    self, name: str, choices: Sequence[CategoricalChoiceType]
) -> CategoricalChoiceType:
    ...

def suggest_categorical(
    self, name: str, choices: Sequence[CategoricalChoiceType]
) -> CategoricalChoiceType:
    """Suggest a value for the categorical parameter.

because I could not convince the type checker that the first overload was more specific than the second (Overloaded function signature 2 will never be matched: signature 1's parameter type(s) are the same or broader).

xadrianzetx commented 2 years ago

Thanks for investigating this! I assumed that choices were intended to be homogeneous, but indeed it seems like they are allowed to be of multiple types at once. I'll probably update the implementation based on Optuna's master.

Edit: Alternatively https://docs.python.org/3/library/typing.html#typing.TypeVarTuple (although seems like there's no support for it prior to Python 3.11).