-
Notifications
You must be signed in to change notification settings - Fork 200
Mamdani Millionaire Income Tax #6421
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
DTrim99
wants to merge
7
commits into
PolicyEngine:master
Choose a base branch
from
DTrim99:DTrim99/issue6420
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
a1c2646
Mamdani Millionaire Income Tax
DTrim99 1b6a01c
add changelog
DTrim99 a8ed32b
Apply suggestions from code review
DTrim99 93f405f
Update in_effect.yaml
DTrim99 5445d95
Mamdani Millionaire Income Tax
DTrim99 41de964
fix logic
DTrim99 e2c2580
fix lint
DTrim99 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
- bump: minor | ||
changes: | ||
added: | ||
- Mamdani Millionaire Income Tax. |
10 changes: 10 additions & 0 deletions
10
policyengine_us/parameters/gov/local/ny/mamdani_income_tax/in_effect.yaml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
description: Zohran Mamdani's proposed additional NYC income tax on income above a certain threshold is in effect if this is true. | ||
values: | ||
0000-01-01: false | ||
metadata: | ||
unit: bool | ||
period: year | ||
label: Zohran Mamdani NYC additional millionaire income tax in effect | ||
reference: | ||
- title: Mamdani Revenue Proposal | ||
href: https://drive.google.com/file/d/14-aM9DKG337SDMilmfQtLRR-pDwyWSTc/view |
10 changes: 10 additions & 0 deletions
10
policyengine_us/parameters/gov/local/ny/mamdani_income_tax/rate.yaml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,10 @@ | ||||||
description: Zohran Mamdani's proposed this NYC income tax rate on income above a certain threshold. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this style for the scale param
Suggested change
|
||||||
values: | ||||||
2026-01-01: 0.02 | ||||||
metadata: | ||||||
unit: /1 | ||||||
period: year | ||||||
label: Zohran Mamdani NYC high earner income tax rate | ||||||
reference: | ||||||
- title: Mamdani Revenue Proposal | ||||||
href: https://drive.google.com/file/d/14-aM9DKG337SDMilmfQtLRR-pDwyWSTc/view |
10 changes: 10 additions & 0 deletions
10
policyengine_us/parameters/gov/local/ny/mamdani_income_tax/threshold.yaml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
description: Zohran Mamdani's proposed NYC income tax applies to income above this threshold. | ||
values: | ||
2026-01-01: 1_000_000 | ||
metadata: | ||
unit: currency-USD | ||
period: year | ||
label: Zohran Mamdani NYC income tax threshold | ||
reference: | ||
- title: Mamdani Revenue Proposal | ||
href: https://drive.google.com/file/d/14-aM9DKG337SDMilmfQtLRR-pDwyWSTc/view |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
from .mamdani_income_tax import ( | ||
create_nyc_mamdani_income_tax_reform, | ||
nyc_mamdani_income_tax, | ||
) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
from policyengine_us.model_api import * | ||
from policyengine_core.periods import period as period_ | ||
|
||
|
||
def create_nyc_mamdani_income_tax() -> Reform: | ||
class nyc_mamdani_income_tax(Variable): | ||
value_type = float | ||
entity = Person | ||
label = "Zohran Mamdani NYC income tax" | ||
unit = USD | ||
definition_period = YEAR | ||
defined_for = "in_nyc" | ||
|
||
def formula(person, period, parameters): | ||
p = parameters(period).gov.local.ny.mamdani_income_tax | ||
taxable_income = person("nyc_taxable_income", period) | ||
threshold = p.threshold | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. irrelevant if moving to a scale parameter, but call parameters directly |
||
rate = p.rate | ||
# Apply 2% tax only to income above $1 million threshold | ||
excess_income = max_(taxable_income - threshold, 0) | ||
return excess_income * rate | ||
|
||
class nyc_income_tax_before_credits(Variable): | ||
value_type = float | ||
entity = TaxUnit | ||
label = "NYC income tax before credits" | ||
unit = USD | ||
definition_period = YEAR | ||
defined_for = "in_nyc" | ||
|
||
def formula(tax_unit, period, parameters): | ||
taxable_income = tax_unit("nyc_taxable_income", period) | ||
filing_status = tax_unit("filing_status", period) | ||
filing_statuses = filing_status.possible_values | ||
rates = parameters(period).gov.local.ny.nyc.tax.income.rates | ||
regular_tax = select( | ||
[ | ||
filing_status == filing_statuses.SINGLE, | ||
filing_status == filing_statuses.JOINT, | ||
filing_status == filing_statuses.HEAD_OF_HOUSEHOLD, | ||
filing_status == filing_statuses.SURVIVING_SPOUSE, | ||
filing_status == filing_statuses.SEPARATE, | ||
], | ||
[ | ||
rates.single.calc(taxable_income), | ||
rates.joint.calc(taxable_income), | ||
rates.head_of_household.calc(taxable_income), | ||
rates.surviving_spouse.calc(taxable_income), | ||
rates.separate.calc(taxable_income), | ||
], | ||
) | ||
mamdani_tax = add(tax_unit, period, ["nyc_mamdani_income_tax"]) | ||
return regular_tax + mamdani_tax | ||
|
||
DTrim99 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
class reform(Reform): | ||
def apply(self): | ||
self.update_variable(nyc_mamdani_income_tax) | ||
self.update_variable(nyc_income_tax_before_credits) | ||
|
||
return reform | ||
|
||
|
||
def create_nyc_mamdani_income_tax_reform( | ||
parameters, period, bypass: bool = False | ||
): | ||
if bypass: | ||
return create_nyc_mamdani_income_tax() | ||
|
||
p = parameters.gov.local.ny.mamdani_income_tax | ||
|
||
reform_active = False | ||
current_period = period_(period) | ||
|
||
for i in range(5): | ||
if p(current_period).in_effect: | ||
reform_active = True | ||
break | ||
current_period = current_period.offset(1, "year") | ||
|
||
if reform_active: | ||
return create_nyc_mamdani_income_tax() | ||
else: | ||
return None | ||
|
||
|
||
nyc_mamdani_income_tax = create_nyc_mamdani_income_tax_reform( | ||
None, None, bypass=True | ||
) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
61 changes: 61 additions & 0 deletions
61
policyengine_us/tests/policy/contrib/local/ny/nyc_mamdani_income_tax.yaml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
- name: Person below threshold in 2026 | ||
period: 2026 | ||
reforms: policyengine_us.reforms.local.ny.mamdani_income_tax.nyc_mamdani_income_tax | ||
input: | ||
gov.local.ny.mamdani_income_tax.in_effect: True | ||
nyc_taxable_income: 800_000 | ||
state_code: NY | ||
output: | ||
nyc_mamdani_income_tax: 0 | ||
|
||
- name: Person at threshold in 2026 | ||
period: 2026 | ||
reforms: policyengine_us.reforms.local.ny.mamdani_income_tax.nyc_mamdani_income_tax | ||
input: | ||
gov.local.ny.mamdani_income_tax.in_effect: True | ||
nyc_taxable_income: 1_000_000 | ||
state_code: NY | ||
output: | ||
nyc_mamdani_income_tax: 0 | ||
|
||
- name: Person above threshold in 2026 | ||
period: 2026 | ||
reforms: policyengine_us.reforms.local.ny.mamdani_income_tax.nyc_mamdani_income_tax | ||
input: | ||
gov.local.ny.mamdani_income_tax.in_effect: True | ||
nyc_taxable_income: 1_200_000 | ||
state_code: NY | ||
output: | ||
# (1_200_000 - 1_000_000) * 0.02 = 200_000 * 0.02 = 4_000 | ||
nyc_mamdani_income_tax: 4_000 | ||
|
||
- name: Person well above threshold in 2026 | ||
period: 2026 | ||
reforms: policyengine_us.reforms.local.ny.mamdani_income_tax.nyc_mamdani_income_tax | ||
input: | ||
gov.local.ny.mamdani_income_tax.in_effect: True | ||
nyc_taxable_income: 2_000_000 | ||
state_code: NY | ||
output: | ||
# (2_000_000 - 1_000_000) * 0.02 = 1_000_000 * 0.02 = 20_000 | ||
nyc_mamdani_income_tax: 20_000 | ||
|
||
- name: Pre-enactment test | ||
period: 2025 | ||
reforms: policyengine_us.reforms.local.ny.mamdani_income_tax.nyc_mamdani_income_tax | ||
input: | ||
gov.local.ny.mamdani_income_tax.in_effect: False | ||
nyc_taxable_income: 1_500_000 | ||
state_code: NY | ||
output: | ||
nyc_mamdani_income_tax: 0 | ||
|
||
- name: Person not in NYC (no tax) | ||
period: 2026 | ||
reforms: policyengine_us.reforms.local.ny.mamdani_income_tax.nyc_mamdani_income_tax | ||
input: | ||
gov.local.ny.mamdani_income_tax.in_effect: True | ||
nyc_taxable_income: 1_500_000 | ||
state_code: CA | ||
output: | ||
nyc_mamdani_income_tax: 0 |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
combine into a scale parameter