Skip to main content
add "dynamic information hiding" solution
Source Link
steve
  • 19
  • 2

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?

What do you think about this "dynamic information hiding" vs static type checking? Which of these two approaches would you recommend?

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?

Post Migrated Here from stackoverflow.com (revisions)
Source Link
steve
steve

Is dynamically hiding specific parts of the input data passed to a function pythonic?

I have a design question regarding "dynamic information hiding" vs static typing.

I have for the following python code

class RuleInput:
    attr1 = ...
    atrr2 = ...
    ...

def example_rule(input: RuleInput) -> bool:
   # does something and returns bool

I have many of these rule functions, each calculating its output based on the attributes in RuleInput (let's assume it's immutable).

For this code, it is clear what the input should be and tools like mypy can be used to do static type checking. Here also features like auto-completion work.

However, most of the rules only require a small number of attributes from the RuleInput. So developers could make mistakes by accessing the wrong information.

Hence, I had the idea of dynamically reducing the content of the RuleInput specific to each rule (rules just specify what they need beforehand). When doing this I lose the possibility of performing static type checking and features like auto-completion.

What do you think about this "dynamic information hiding" vs static type checking? Which of these two approaches would you recommend?