import dataclasses
from typing import Any


def terse_str(cls: type) -> type:
  """Decorator for a dataclasses.dataclass, which defines a custom str().

  >>> @terse_str
  ... @dataclasses.dataclass
  ... class TestTerseStr:
  ...   a: int = 3
  ...   b: List[str] = dataclasses.field(default_factory=lambda: ['g', 'h'])

  >>> str(TestTerseStr())
  'TestTerseStr()'

  >>> str(TestTerseStr(a=4))
  'TestTerseStr(a=4)'

  >>> str(TestTerseStr(b=['i', 'j']))
  "TestTerseStr(b=['i', 'j'])"
  """
  assert isinstance(cls, type)
  default_for_field = {
      field.name: (field.default_factory() if callable(field.default_factory)
                   else field.default)
      for field in dataclasses.fields(cls)
      if field.repr
  }

  def __str__(self: Any) -> str:
    """Return a string containing only the non-default field values."""
    text = ', '.join(f'{name}={getattr(self, name)!r}'
                     for name, default in default_for_field.items()
                     if getattr(self, name) != default)
    return f'{type(self).__name__}({text})'

  setattr(cls, '__str__', __str__)
  return cls