Skip to content

refundable_ctc ↔ income_tax dependency cycle surfaces on itemizing branch #8059

@MaxGhenis

Description

@MaxGhenis

Summary

In policyengine-us 1.647.0, calculating refundable_ctc on the itemizing reform branch raises:

Exception: RecursionError while calculating refundable_ctc for period 2024. The full computation stack is:
  - income_tax 2024, itemizing
  - income_tax_before_refundable_credits 2024, itemizing
  - income_tax_capped_non_refundable_credits 2024, itemizing
  - income_tax_non_refundable_credits 2024, itemizing
  - non_refundable_ctc 2024, itemizing
  - refundable_ctc 2024, itemizing

The cycle is refundable_ctc → non_refundable_ctc → income_tax_non_refundable_credits → income_tax_capped_non_refundable_credits → income_tax_before_refundable_credits → income_tax → refundable_ctc.

Reproducer

Surfaces in policyengine.py's integration tests when the [us] / [dev] extras are bumped to us 1.647.0 — e.g. PolicyEngine/policyengine.py#280 CI run: https://github.com/PolicyEngine/policyengine.py/actions/runs/24584...

Failing tests:

  • TestUSHouseholdImpact.test_single_adult_no_income
  • TestUSHouseholdImpact.test_single_adult_with_employment_income
  • TestUSHouseholdReformApplication::test__given_baseline_policy__then_returns_baseline_tax (and several other reform-application cases)

All fail with the same stack. All exercise the itemizing reform branch via get_branch("itemizing").

Likely resolution

Either:

  • Increase max_spiral_loops on the branch if the cycle is expected to resolve via spiral detection, or
  • Break the circularity explicitly (e.g. refundable_ctc should depend on a pre-credit income_tax_before_refundable_credits variable rather than the full income_tax)

I don't know the intent well enough to pick between them.

Not blocking

This didn't block the 3.9-support work that's already merged — us main CI passes on 1.647.0 because us doesn't exercise this specific reform-branch call path. It only surfaces downstream in pypkg.

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