Skip to content
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

The default_factory for subgroups will not set the default metavar in FieldWrapper #187

Closed
zhiruiluo opened this issue Dec 15, 2022 · 1 comment

Comments

@zhiruiluo
Copy link
Contributor

Describe the bug
The default_factory for subgroups will not set the default metavar in FieldWrapper.

To Reproduce

# test_subgroups_default_factory.py
from typing import Union
from dataclasses import dataclass, is_dataclass, MISSING
import pytest

from simple_parsing import subgroups

from .testutils import TestSetup

@dataclass
class Foo:
    a: int = 1
    b: int = 2

@dataclass
class Bar:
    c: int = 1
    d: int = 2

@dataclass
class Bob(TestSetup):
    thing: Union[Foo, Bar] = subgroups({"foo_thing": Foo, "bar_thing": Bar}, default_factory=lambda: Bar(d=3))
    # the original design will only work when using the "default" argument.
    # thing: Union[Foo, Bar] = subgroups({"foo_thing": Foo, "bar_thing": Bar}, default=Bar(d=3)) 

def test_default_factory_subgroups():
    assert '--thing.c' in Bob.get_help_text('--help')

Expected behavior
Test passed

Actual behavior
Failed

AssertionError: assert '--thing.c' in ''

Desktop (please complete the following information):

  • Version: 0.0.21.post1
  • Python version: Python 3.9

Additional context
The below default_value function check both field.default and field.default_factory.

# utilis.py
def default_value(field: dataclasses.Field) -> T | _MISSING_TYPE:
    """Returns the default value of a field in a dataclass, if available.
    When not available, returns `dataclasses.MISSING`.

    Args:
        field (dataclasses.Field): The dataclasses.Field to get the default value of.

    Returns:
        Union[T, _MISSING_TYPE]: The default value for that field, if present, or None otherwise.
    """
    if field.default is not dataclasses.MISSING:
        return field.default
    elif field.default_factory is not dataclasses.MISSING:  # type: ignore
        constructor = field.default_factory  # type: ignore
        return constructor()
    else:
        return dataclasses.MISSING

However, the subgroups give the default value of "default" "None" instead of MISSING.

def subgroups(
    subgroups: Dict[str, Type[T]],
    *args,
    default: Union[T, Type[T], None] = None,
    **kwargs,
) -> T:
@zhiruiluo
Copy link
Contributor Author

zhiruiluo commented Jan 11, 2023

Closed with PR #185.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant