Skip to content

Variable.clone() fails for variables registered via update_variable #502

@MaxGhenis

Description

@MaxGhenis

Variable.clone() re-runs self.__class__() with baseline_variable=None (policyengine_core/variables/variable.py, clone), so cloning any variable that was registered through a reform's update_variable drops every attribute it inherited from the baseline variable. A label-only or adds-only reform override then fails to clone with Missing attribute 'value_type'.

Reproduce:

from policyengine_core.country_template import CountryTaxBenefitSystem
from policyengine_core.model_api import Reform, Variable

class disposable_income(Variable):
    label = "Updated label only"

class reform(Reform):
    def apply(self):
        self.update_variable(disposable_income)

system = reform(CountryTaxBenefitSystem())
system.get_variable("disposable_income").clone()  # ValueError: Missing attribute 'value_type'

This predates #501 (reproduced identically on the commit before it) and does not bite the normal flow because TaxBenefitSystem.clone() happens on the baseline system before reforms apply, or reforms re-apply on the clone. But any code path that clones a reformed system's variables directly will crash.

Suggested fix: decouple clone() from re-running __init__ — e.g. an empty_clone + __dict__ copy, the same pattern TaxBenefitSystem.clone() uses — so a cloned variable preserves its merged (baseline + override) state.

Found during the review of #501.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions