Replies: 3 comments 4 replies
-
I've thought about it, and perhaps a from dataclasses import dataclass
class validator_hook:
def __post_init__(self):
for name, field in self.__dataclass_fields__.items():
if (method := getattr(self, f"validate_{name}", None)):
setattr(self, name, method(getattr(self, name)))
@dataclass
class MountFlags(validator_hook):
compress :bool | None = None
nodatacow :bool | None = None
compress_level :int | None = None
def __post_init__(self):
validator_hook.__post_init__(self)
if self.compress and self.nodatacow:
raise ValueError("Cannot have compression and nodatacow at the same time.")
def validate_compress_level(self, val):
if val and (not isinstance(int, val) or 19 < val < 0):
raise ValueError("Compression level must be a positive int between 0 - 19")
MountFlags(compress=True)
MountFlags(nodatacow=True)
MountFlags(compress=True, nodatacow=True) |
Beta Was this translation helpful? Give feedback.
-
I do prefer dataclasses over inheritance, IMHO inheritance is difficult to maintain in a sane way if things grow. To @Torxed example the post init will work but it doesn't prevent setting one of the attributes manually after the objective was created. We could move those two under an enum fir now and just have them as a single attribute in the Btrfs class |
Beta Was this translation helpful? Give feedback.
-
We can use dataclasses as both of you suggested, along with union types to create @dataclass(frozen=True)
class Compress:
level: int
def __post_init__(self):
if not 0 < self.level < 19:
raise ValueError("Compression level must be a positive int between 0 - 19")
@dataclass
class Nodatacow:
pass
BtrfsMountFlag = Compress | Nodatacow
def describe_flag(flag: BtrfsMountFlag):
match flag:
case Compress(level):
print(f"compress with level {level}")
case Nodatacow:
print("nodatacow")
describe_flag(Compress(2))
describe_flag(Nodatacow())
describe_flag(Compress(20)) # ValueError Edit: We can also pass |
Beta Was this translation helpful? Give feedback.
-
I've been trying to create a better fix for the compress / nodatacow flags for btrfs. I've come up with the idea of separating the flags into enums, each enum containing a set of mutually exclusive variants.
When we run this, we get
Notice how the last flag variant is automatically removed from the set.
I want to hear everyone's opinion about this, whether this is a good enough design. Thanks!
Beta Was this translation helpful? Give feedback.
All reactions