Skip to content

Instantly share code, notes, and snippets.

@alkasm
Created July 24, 2022 02:24
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alkasm/80a13a62615e0889b60d5f0156625d5b to your computer and use it in GitHub Desktop.
Save alkasm/80a13a62615e0889b60d5f0156625d5b to your computer and use it in GitHub Desktop.
A pattern for "required" arguments in dataclasses, allowing for fields without defaults to follow fields with defaults.
from dataclasses import dataclass, field
from datetime import datetime
from typing import Optional, TypeVar
T = TypeVar("T")
def required() -> T:
f: T
def factory() -> T:
# mypy treats a Field as a T, even though it has attributes like .name, .default, etc
field_name = f.name # type: ignore[attr-defined]
raise ValueError(f"field '{field_name}' required")
f = field(default_factory=factory)
return f
@dataclass
class Event:
id: str
created_at: datetime
updated_at: Optional[datetime] = None
@dataclass
class NamedEvent(Event):
name: str = required()
event = NamedEvent(name="Some Event", id="ab13c1a", created_at=datetime.now())
print("created event:", event)
event2 = NamedEvent("ab13c1a", datetime.now(), name="Some Other Event")
print("created event:", event2)
event3 = NamedEvent("ab13c1a", datetime.now())
@alkasm
Copy link
Author

alkasm commented Jul 24, 2022

Example output:

created event: NamedEvent(id='ab13c1a', created_at=datetime.datetime(2022, 7, 23, 19, 22, 17, 944550), updated_at=None, name='Some Event')
created event: NamedEvent(id='ab13c1a', created_at=datetime.datetime(2022, 7, 23, 19, 22, 17, 944588), updated_at=None, name='Some Other Event')
Traceback (most recent call last):
  File ".../gist.py", line 39, in <module>
    event3 = NamedEvent("ab13c1a", datetime.now())
  File "<string>", line 6, in __init__
  File ".../gist.py", line 14, in factory
    raise ValueError(f"field '{field_name}' required")
ValueError: field 'name' required

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment