Dataclasses

In Python 3.7, a new dataclasses module has been added to the standard library.This module allows defining and customizing simple boilerplate-free classes.They can be defined using the @dataclasses.dataclass decorator:

  1. from dataclasses import dataclass, field
  2.  
  3. @dataclass
  4. class Application:
  5. name: str
  6. plugins: List[str] = field(default_factory=list)
  7.  
  8. test = Application("Testing...") # OK
  9. bad = Application("Testing...", "with plugin") # Error: List[str] expected

Mypy will detect special methods (such as lt) depending on the flags used todefine dataclasses. For example:

  1. from dataclasses import dataclass
  2.  
  3. @dataclass(order=True)
  4. class OrderedPoint:
  5. x: int
  6. y: int
  7.  
  8. @dataclass(order=False)
  9. class UnorderedPoint:
  10. x: int
  11. y: int
  12.  
  13. OrderedPoint(1, 2) < OrderedPoint(3, 4) # OK
  14. UnorderedPoint(1, 2) < UnorderedPoint(3, 4) # Error: Unsupported operand types

Dataclasses can be generic and can be used in any other way a normalclass can be used:

  1. from dataclasses import dataclass
  2. from typing import Generic, TypeVar
  3.  
  4. T = TypeVar('T')
  5.  
  6. @dataclass
  7. class BoxedData(Generic[T]):
  8. data: T
  9. label: str
  10.  
  11. def unbox(bd: BoxedData[T]) -> T:
  12. ...
  13.  
  14. val = unbox(BoxedData(42, "<important>")) # OK, inferred type is int

For more information see official docsand PEP 557.

Caveats/Known Issues

Some functions in the dataclasses module, such as replace() and asdict(),have imprecise (too permissive) types. This will be fixed in future releases.

Mypy does not yet recognize aliases of dataclasses.dataclass, and willprobably never recognize dynamically computed decorators. The following examplesdo not work:

  1. from dataclasses import dataclass
  2.  
  3. dataclass_alias = dataclass
  4. def dataclass_wrapper(cls):
  5. return dataclass(cls)
  6.  
  7. @dataclass_alias
  8. class AliasDecorated:
  9. """
  10. Mypy doesn't recognize this as a dataclass because it is decorated by an
  11. alias of `dataclass` rather than by `dataclass` itself.
  12. """
  13. attribute: int
  14.  
  15. @dataclass_wrapper
  16. class DynamicallyDecorated:
  17. """
  18. Mypy doesn't recognize this as a dataclass because it is decorated by a
  19. function returning `dataclass` rather than by `dataclass` itself.
  20. """
  21. attribute: int
  22.  
  23. AliasDecorated(attribute=1) # error: Unexpected keyword argument
  24. DynamicallyDecorated(attribute=1) # error: Unexpected keyword argument