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