Here is the "dynamic information hiding" solution:
RULE_INPUTS = [
('attr1', int, field(default=0)),
('attr2', int, field(default=0))
]
RuleInputNames = Enum(
"RuleInputNames",
" ".join([x[0] for x in RULE_INPUTS])
)
def check(required_props):
def extract_required_properties(full_input, required_properties):
all_props = asdict(full_input)
selected_props = {}
for key in required_properties:
selected_props[key] = all_props[key]
return selected_props
req_props = [x.name for x in required_props]
RequiredProperties = make_dataclass(
"RequiredProperties",
[x for x in RULE_INPUTS if x[0] in req_props]
)
def decorator(func):
def wrapper(full_rule_input):
return func(
RequiredProperties(
**extract_required_properties(full_rule_input,
req_edge_props),
)
)
return wrapper
return decorator
@rule(required_props=[ParticlePropertyNames.attr1])
def some_rule(rule_input):
rule_input.attr1 # works
rule_input.attr2 # wont work
What do you think about this "dynamic information hiding" vs static type checking? Which of these two approaches would you recommend?