-
Notifications
You must be signed in to change notification settings - Fork 8
Open
Description
Summary
Reforms applied to US simulations via p.update() after Microsimulation construction have no effect on calculations. The parameter values are modified, but the tax calculations return baseline results, causing silent failures.
Root Cause
The US country package (policyengine-us) uses a shared singleton TaxBenefitSystem:
# policyengine_us/system.py
system = CountryTaxBenefitSystem() # Module-level singleton
class Microsimulation(CoreMicrosimulation):
default_tax_benefit_system_instance = system # All sims share thisWhen p.update() is called after construction:
- The parameter value is modified on the shared TaxBenefitSystem ✓
- But calculations are cached at the simulation level with the old values
- The updated parameter is never used in calculations ✗
Expected vs Actual
| Metric | Expected | Actual |
|---|---|---|
| Parameter value | Changed ✓ | Changed ✓ |
| Tax calculation | Different | Unchanged ✗ |
Workaround
Pass the reform at Microsimulation construction time:
reform_dict = {
"gov.irs.deductions.standard.amount.SINGLE": {
"2024-01-01": 29200
}
}
microsim = Microsimulation(reform=reform_dict) # Works correctlyComparison with UK
The UK package (policyengine-uk >= 2.72.3) was refactored in July 2025 to give each simulation its own TaxBenefitSystem instance, so p.update() works correctly there.
| Package | Architecture | p.update() Works? |
|---|---|---|
| policyengine-uk | Separate TBS per simulation | ✅ Yes |
| policyengine-us | Shared singleton TBS | ❌ No |
Impact
Any code using policyengine.py simulation_modifier pattern (which calls p.update()) for US simulations will silently return baseline results regardless of the reform.
Suggested Fix
Either:
- In policyengine.py: Convert parameter values to reform dict and pass at construction (implemented in this repo)
- In policyengine-us: Refactor to match UK architecture (separate TBS per simulation)
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels