parent
e21593e86e
commit
90239b7797
2 changed files with 78 additions and 0 deletions
@ -0,0 +1,38 @@ |
|||||||
|
# sentinel value to detect when to replace a field's default |
||||||
|
from dataclasses import dataclass, field |
||||||
|
|
||||||
|
auto = object() |
||||||
|
|
||||||
|
|
||||||
|
def check_auto(name, bases, cls_dict): |
||||||
|
default = 1 |
||||||
|
|
||||||
|
cls_annotations = cls_dict.get('__annotations__', {}) |
||||||
|
print('cls_annotations2', cls_annotations) |
||||||
|
|
||||||
|
for name, val in cls_dict.items(): |
||||||
|
print('test', name, val) |
||||||
|
if val == auto: |
||||||
|
# cls_dict[name] = default |
||||||
|
# cls_dict[name] = cls_annotations[name] |
||||||
|
cls_dict[name] = field(default_factory=cls_annotations[name]) |
||||||
|
default += 1 |
||||||
|
|
||||||
|
cls = type(name, bases, cls_dict) |
||||||
|
return cls |
||||||
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True) |
||||||
|
class State(metaclass=check_auto): |
||||||
|
test: int = auto |
||||||
|
test2: str = auto |
||||||
|
test3: bool = auto |
||||||
|
|
||||||
|
|
||||||
|
s = State() |
||||||
|
# print(s) # State(val_A=1, val_B=2, val_C=3) |
||||||
|
# assert s.val_B == 2 |
||||||
|
# |
||||||
|
# s = State(val_A=5) |
||||||
|
# assert s.val_A == 5 |
||||||
|
# assert s.val_C == 3 |
@ -0,0 +1,40 @@ |
|||||||
|
class Auto: |
||||||
|
"""A placeholder class to denote an automatically assigned default value.""" |
||||||
|
|
||||||
|
def __repr__(self): |
||||||
|
return "<Auto>" |
||||||
|
|
||||||
|
|
||||||
|
from dataclasses import dataclass, field, fields as dc_fields |
||||||
|
from typing import Any, List |
||||||
|
|
||||||
|
def apply_auto_defaults(cls): |
||||||
|
for f in dc_fields(cls): |
||||||
|
# Check if the field's default is an instance of Auto |
||||||
|
if isinstance(f.default, Auto): |
||||||
|
# Determine the appropriate default factory based on type hints |
||||||
|
if f.type == bool: |
||||||
|
default_factory = bool |
||||||
|
elif f.type == list: |
||||||
|
default_factory = list |
||||||
|
elif f.type == int: |
||||||
|
default_factory = int |
||||||
|
else: |
||||||
|
raise TypeError(f"Unsupported field type for auto-default: {f.type}") |
||||||
|
# Replace the placeholder with an actual dataclass field with default_factory |
||||||
|
setattr(cls, f.name, field(default_factory=default_factory)) |
||||||
|
return cls |
||||||
|
|
||||||
|
|
||||||
|
@apply_auto_defaults |
||||||
|
@dataclass |
||||||
|
class CarControl: |
||||||
|
enabled: bool = Auto() # Auto will be replaced with field(default_factory=bool) |
||||||
|
speed: int = Auto() # Auto will be replaced with field(default_factory=int) |
||||||
|
tags: List[str] = Auto() # Auto will be replaced with field(default_factory=list) |
||||||
|
|
||||||
|
# This will instantiate the dataclass with the fields set to their default types |
||||||
|
car_control = CarControl() |
||||||
|
print(car_control.enabled) # Expected: False |
||||||
|
print(car_control.speed) # Expected: 0 |
||||||
|
print(car_control.tags) # Expected: [] |
Loading…
Reference in new issue