@@ -286,7 +286,7 @@ class PolicyEngineUSVariableMaterializationResult:
286286 "other_medical_expenses" ,
287287 "over_the_counter_health_expenses" ,
288288 "self_employment_income_before_lsr" ,
289- "social_security_retirement " ,
289+ "social_security_retirement_reported " ,
290290 "social_security_disability" ,
291291 "social_security_survivors" ,
292292 "social_security_dependents" ,
@@ -327,6 +327,7 @@ class PolicyEngineUSVariableMaterializationResult:
327327
328328POLICYENGINE_US_EXPORT_COLUMN_ALIASES : dict [str , str ] = {
329329 "race" : "cps_race" ,
330+ "social_security_retirement" : "social_security_retirement_reported" ,
330331}
331332
332333POLICYENGINE_US_EXPORT_DEFAULTS : dict [str , Any ] = {
@@ -1866,18 +1867,70 @@ def compile_supported_policyengine_us_household_linear_constraints(
18661867 return supported_targets , unsupported_targets , tuple (constraints )
18671868
18681869
1870+ def _policyengine_us_target_required_variables (targets : list [TargetSpec ]) -> set [str ]:
1871+ return {
1872+ feature
1873+ for target in targets
1874+ for feature in target .required_features
1875+ }
1876+
1877+
1878+ def policyengine_us_formula_variables_for_targets (
1879+ targets : list [TargetSpec ],
1880+ * ,
1881+ simulation_cls : Any | None = None ,
1882+ tax_benefit_system : Any | None = None ,
1883+ direct_override_variables : tuple [str , ...] = (),
1884+ ) -> set [str ]:
1885+ """Return target features that should be recalculated by PolicyEngine."""
1886+ required_variables = _policyengine_us_target_required_variables (targets )
1887+ if not required_variables :
1888+ return set ()
1889+ if tax_benefit_system is None :
1890+ tax_benefit_system = _resolve_policyengine_us_tax_benefit_system (
1891+ simulation_cls
1892+ )
1893+ variables = getattr (tax_benefit_system , "variables" , {})
1894+ direct_overrides = set (direct_override_variables )
1895+ formula_variables : set [str ] = set ()
1896+ for variable in required_variables :
1897+ if variable in direct_overrides :
1898+ continue
1899+ variable_metadata = variables .get (variable )
1900+ if variable_metadata is None :
1901+ continue
1902+ if _policyengine_us_variable_is_calculated (variable_metadata ):
1903+ formula_variables .add (variable )
1904+ return formula_variables
1905+
1906+
1907+ def _policyengine_us_variable_is_calculated (variable_metadata : Any ) -> bool :
1908+ if getattr (variable_metadata , "formulas" , {}):
1909+ return True
1910+ if getattr (variable_metadata , "adds" , ()) or getattr (variable_metadata , "subtracts" , ()):
1911+ return True
1912+ is_input_variable = getattr (variable_metadata , "is_input_variable" , None )
1913+ if callable (is_input_variable ):
1914+ try :
1915+ return not bool (is_input_variable ())
1916+ except TypeError :
1917+ return False
1918+ return False
1919+
1920+
18691921def policyengine_us_variables_to_materialize (
18701922 targets : list [TargetSpec ],
18711923 bindings : dict [str , PolicyEngineUSVariableBinding ],
1924+ * ,
1925+ force_materialize_variables : set [str ] | tuple [str , ...] | None = None ,
18721926) -> set [str ]:
18731927 """Compute the missing features required to score the given targets."""
1874- requested_variables = {
1875- feature
1876- for target in targets
1877- for feature in target .required_features
1878- }
1928+ requested_variables = _policyengine_us_target_required_variables (targets )
1929+ force_variables = set (force_materialize_variables or ())
18791930 return {
1880- variable for variable in requested_variables if variable not in bindings
1931+ variable
1932+ for variable in requested_variables
1933+ if variable not in bindings or variable in force_variables
18811934 }
18821935
18831936
0 commit comments