policyengine-core 3.0.0__tar.gz → 3.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (199) hide show
  1. {policyengine_core-3.0.0/policyengine_core.egg-info → policyengine_core-3.2.0}/PKG-INFO +1 -1
  2. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/country_template/data/datasets/country_template_dataset.py +1 -0
  3. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/data/dataset.py +61 -7
  4. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/parameters/parameter.py +2 -2
  5. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/parameters/parameter_node.py +21 -0
  6. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/reforms/reform.py +20 -18
  7. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/simulations/simulation.py +84 -41
  8. policyengine_core-3.2.0/policyengine_core/weighting/__init__.py +1 -0
  9. policyengine_core-3.2.0/policyengine_core/weighting/microdf.py +685 -0
  10. {policyengine_core-3.0.0 → policyengine_core-3.2.0/policyengine_core.egg-info}/PKG-INFO +1 -1
  11. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core.egg-info/SOURCES.txt +3 -1
  12. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/setup.py +1 -1
  13. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/LICENSE +0 -0
  14. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/MANIFEST.in +0 -0
  15. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/README.md +0 -0
  16. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/__init__.py +0 -0
  17. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/charts/__init__.py +0 -0
  18. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/charts/api.py +0 -0
  19. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/charts/bar.py +0 -0
  20. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/charts/formatting.py +0 -0
  21. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/commons/__init__.py +0 -0
  22. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/commons/formulas.py +0 -0
  23. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/commons/misc.py +0 -0
  24. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/commons/rates.py +0 -0
  25. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/country_template/__init__.py +0 -0
  26. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/country_template/constants.py +0 -0
  27. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/country_template/data/__init__.py +0 -0
  28. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/country_template/data/datasets/__init__.py +0 -0
  29. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/country_template/entities.py +0 -0
  30. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/country_template/modelled_policies.yaml +0 -0
  31. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/country_template/parameters/benefits/basic_income.yaml +0 -0
  32. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/country_template/parameters/benefits/housing_allowance.yaml +0 -0
  33. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/country_template/parameters/benefits/index.yaml +0 -0
  34. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/country_template/parameters/benefits/parenting_allowance/amount.yaml +0 -0
  35. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/country_template/parameters/benefits/parenting_allowance/income_threshold.yaml +0 -0
  36. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/country_template/parameters/general/age_of_majority.yaml +0 -0
  37. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/country_template/parameters/general/age_of_retirement.yaml +0 -0
  38. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/country_template/parameters/taxes/housing_tax.yaml +0 -0
  39. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/country_template/parameters/taxes/income_tax_rate.yaml +0 -0
  40. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/country_template/parameters/taxes/social_security_contribution.yaml +0 -0
  41. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/country_template/reforms/__init__.py +0 -0
  42. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/country_template/reforms/add_dynamic_variable.py +0 -0
  43. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/country_template/reforms/add_new_tax.py +0 -0
  44. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/country_template/reforms/flat_social_security_contribution.py +0 -0
  45. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/country_template/reforms/modify_social_security_taxation.py +0 -0
  46. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/country_template/reforms/removal_basic_income.py +0 -0
  47. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/country_template/situation_examples/__init__.py +0 -0
  48. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/country_template/situation_examples/couple.json +0 -0
  49. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/country_template/situation_examples/housing.json +0 -0
  50. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/country_template/situation_examples/single.json +0 -0
  51. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/country_template/tests/age.yaml +0 -0
  52. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/country_template/tests/basic_income.yaml +0 -0
  53. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/country_template/tests/disposable_income.yaml +0 -0
  54. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/country_template/tests/housing_allowance.yaml +0 -0
  55. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/country_template/tests/housing_tax.yaml +0 -0
  56. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/country_template/tests/income_tax.yaml +0 -0
  57. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/country_template/tests/reforms/add_dynamic_variable.yaml +0 -0
  58. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/country_template/tests/reforms/add_new_tax.yaml +0 -0
  59. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/country_template/tests/reforms/modify_social_security_taxation.yaml +0 -0
  60. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/country_template/tests/situations/income_tax.yaml +0 -0
  61. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/country_template/tests/situations/parenting_allowance.yaml +0 -0
  62. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/country_template/tests/social_security_contribution.yaml +0 -0
  63. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/country_template/tests/test_microsimulation.py +0 -0
  64. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/country_template/variables/__init__.py +0 -0
  65. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/country_template/variables/benefits.py +0 -0
  66. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/country_template/variables/demographics.py +0 -0
  67. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/country_template/variables/housing.py +0 -0
  68. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/country_template/variables/ids.py +0 -0
  69. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/country_template/variables/income.py +0 -0
  70. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/country_template/variables/stats.py +0 -0
  71. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/country_template/variables/taxes.py +0 -0
  72. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/data/__init__.py +0 -0
  73. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/data_storage/__init__.py +0 -0
  74. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/data_storage/in_memory_storage.py +0 -0
  75. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/data_storage/on_disk_storage.py +0 -0
  76. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/data_structures/__init__.py +0 -0
  77. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/data_structures/parameter_metadata.py +0 -0
  78. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/data_structures/parameter_node_metadata.py +0 -0
  79. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/data_structures/reference.py +0 -0
  80. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/data_structures/unit.py +0 -0
  81. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/entities/__init__.py +0 -0
  82. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/entities/entity.py +0 -0
  83. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/entities/group_entity.py +0 -0
  84. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/entities/helpers.py +0 -0
  85. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/entities/role.py +0 -0
  86. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/enums/__init__.py +0 -0
  87. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/enums/config.py +0 -0
  88. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/enums/enum.py +0 -0
  89. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/enums/enum_array.py +0 -0
  90. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/errors/__init__.py +0 -0
  91. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/errors/cycle_error.py +0 -0
  92. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/errors/empty_argument_error.py +0 -0
  93. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/errors/nan_creation_error.py +0 -0
  94. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/errors/parameter_not_found_error.py +0 -0
  95. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/errors/parameter_parsing_error.py +0 -0
  96. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/errors/period_mismatch_error.py +0 -0
  97. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/errors/situation_parsing_error.py +0 -0
  98. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/errors/spiral_error.py +0 -0
  99. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/errors/variable_name_conflict_error.py +0 -0
  100. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/errors/variable_not_found_error.py +0 -0
  101. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/experimental/__init__.py +0 -0
  102. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/experimental/memory_config.py +0 -0
  103. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/extension_template/__init__.py +0 -0
  104. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/extension_template/local_benefit.py +0 -0
  105. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/extension_template/parameters/local_town/child_allowance/amount.yaml +0 -0
  106. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/extension_template/parameters/local_town/child_allowance/index.yaml +0 -0
  107. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/extension_template/parameters/local_town/index.yaml +0 -0
  108. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/extension_template/tests/local_benefit.yaml +0 -0
  109. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/holders/__init__.py +0 -0
  110. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/holders/helpers.py +0 -0
  111. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/holders/holder.py +0 -0
  112. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/model_api.py +0 -0
  113. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/parameters/__init__.py +0 -0
  114. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/parameters/at_instant_like.py +0 -0
  115. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/parameters/config.py +0 -0
  116. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/parameters/helpers.py +0 -0
  117. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/parameters/operations/__init__.py +0 -0
  118. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/parameters/operations/get_parameter.py +0 -0
  119. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/parameters/operations/homogenize_parameters.py +0 -0
  120. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/parameters/operations/interpolate_parameters.py +0 -0
  121. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/parameters/operations/propagate_parameter_metadata.py +0 -0
  122. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/parameters/operations/uprate_parameters.py +0 -0
  123. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/parameters/parameter_at_instant.py +0 -0
  124. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/parameters/parameter_node_at_instant.py +0 -0
  125. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/parameters/parameter_scale.py +0 -0
  126. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/parameters/parameter_scale_bracket.py +0 -0
  127. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/parameters/vectorial_parameter_node_at_instant.py +0 -0
  128. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/periods/__init__.py +0 -0
  129. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/periods/config.py +0 -0
  130. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/periods/helpers.py +0 -0
  131. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/periods/instant_.py +0 -0
  132. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/periods/period_.py +0 -0
  133. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/populations/__init__.py +0 -0
  134. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/populations/config.py +0 -0
  135. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/populations/group_population.py +0 -0
  136. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/populations/population.py +0 -0
  137. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/projectors/__init__.py +0 -0
  138. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/projectors/entity_to_person_projector.py +0 -0
  139. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/projectors/first_person_to_entity_projector.py +0 -0
  140. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/projectors/helpers.py +0 -0
  141. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/projectors/projector.py +0 -0
  142. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/projectors/unique_role_to_entity_projector.py +0 -0
  143. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/reforms/__init__.py +0 -0
  144. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/scripts/__init__.py +0 -0
  145. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/scripts/assets/__init__.py +0 -0
  146. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/scripts/assets/index.html +0 -0
  147. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/scripts/policyengine_command.py +0 -0
  148. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/scripts/run_data.py +0 -0
  149. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/scripts/run_test.py +0 -0
  150. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/scripts/simulation_generator.py +0 -0
  151. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/simulations/__init__.py +0 -0
  152. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/simulations/helpers.py +0 -0
  153. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/simulations/individual_sim.py +0 -0
  154. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/simulations/microsimulation.py +0 -0
  155. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/simulations/simulation_builder.py +0 -0
  156. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/taxbenefitsystems/__init__.py +0 -0
  157. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/taxbenefitsystems/tax_benefit_system.py +0 -0
  158. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/taxscales/__init__.py +0 -0
  159. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/taxscales/abstract_rate_tax_scale.py +0 -0
  160. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/taxscales/abstract_tax_scale.py +0 -0
  161. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/taxscales/amount_tax_scale_like.py +0 -0
  162. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/taxscales/helpers.py +0 -0
  163. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/taxscales/linear_average_rate_tax_scale.py +0 -0
  164. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/taxscales/marginal_amount_tax_scale.py +0 -0
  165. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/taxscales/marginal_rate_tax_scale.py +0 -0
  166. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/taxscales/rate_tax_scale_like.py +0 -0
  167. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/taxscales/single_amount_tax_scale.py +0 -0
  168. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/taxscales/tax_scale_like.py +0 -0
  169. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/tools/__init__.py +0 -0
  170. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/tools/simulation_dumper.py +0 -0
  171. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/tools/test_from_situation.py +0 -0
  172. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/tools/test_runner.py +0 -0
  173. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/tracers/__init__.py +0 -0
  174. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/tracers/computation_log.py +0 -0
  175. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/tracers/flat_trace.py +0 -0
  176. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/tracers/full_tracer.py +0 -0
  177. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/tracers/performance_log.py +0 -0
  178. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/tracers/simple_tracer.py +0 -0
  179. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/tracers/trace_node.py +0 -0
  180. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/tracers/tracing_parameter_node_at_instant.py +0 -0
  181. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/tracers/variable_graph.py +0 -0
  182. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/types/__init__.py +0 -0
  183. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/types/data_types/__init__.py +0 -0
  184. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/types/data_types/arrays.py +0 -0
  185. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/variables/__init__.py +0 -0
  186. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/variables/config.py +0 -0
  187. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/variables/defined_for.py +0 -0
  188. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/variables/helpers.py +0 -0
  189. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/variables/typing.py +0 -0
  190. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/variables/variable.py +0 -0
  191. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/warnings/__init__.py +0 -0
  192. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/warnings/libyaml_warning.py +0 -0
  193. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/warnings/memory_config_warning.py +0 -0
  194. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core/warnings/tempfile_warning.py +0 -0
  195. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core.egg-info/dependency_links.txt +0 -0
  196. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core.egg-info/entry_points.txt +0 -0
  197. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core.egg-info/requires.txt +0 -0
  198. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/policyengine_core.egg-info/top_level.txt +0 -0
  199. {policyengine_core-3.0.0 → policyengine_core-3.2.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: policyengine-core
3
- Version: 3.0.0
3
+ Version: 3.2.0
4
4
  Summary: Core microsimulation engine enabling country-specific policy models.
5
5
  Home-page: https://github.com/policyengine/policyengine-core
6
6
  Author: PolicyEngine
@@ -29,6 +29,7 @@ class CountryTemplateDataset(Dataset):
29
29
  "person_household_id": {ETERNITY: person_household_id},
30
30
  "person_household_role": {ETERNITY: person_household_role},
31
31
  "salary": {salary_time_period: salary},
32
+ "accommodation_size": {salary_time_period: [200, 300]},
32
33
  "household_weight": {weight_time_period: weight},
33
34
  }
34
35
  self.save_dataset(data)
@@ -30,6 +30,7 @@ class Dataset:
30
30
  TABLES = "tables"
31
31
  ARRAYS = "arrays"
32
32
  TIME_PERIOD_ARRAYS = "time_period_arrays"
33
+ FLAT_FILE = "flat_file"
33
34
 
34
35
  _table_cache: Dict[str, pd.DataFrame] = None
35
36
 
@@ -55,17 +56,11 @@ class Dataset:
55
56
  Dataset.TABLES,
56
57
  Dataset.ARRAYS,
57
58
  Dataset.TIME_PERIOD_ARRAYS,
59
+ Dataset.FLAT_FILE,
58
60
  ], f"You tried to instantiate a Dataset object, but your data_format attribute is invalid ({self.data_format})."
59
61
 
60
62
  self._table_cache = {}
61
63
 
62
- if (
63
- self.data_format != Dataset.TIME_PERIOD_ARRAYS
64
- ) and self.time_period is None:
65
- raise ValueError(
66
- "You tried to instantiate a Dataset object, but no time_period has been provided."
67
- )
68
-
69
64
  if not self.exists and require:
70
65
  if self.url is not None:
71
66
  self.download()
@@ -107,6 +102,13 @@ class Dataset:
107
102
  values = f[key]
108
103
  self._table_cache[key] = values
109
104
  return values
105
+ elif self.data_format == Dataset.FLAT_FILE:
106
+ if key is None:
107
+ return pd.read_csv(file)
108
+ else:
109
+ raise ValueError(
110
+ "You tried to load a key from a flat file dataset, but flat file datasets do not support keys."
111
+ )
110
112
  else:
111
113
  raise ValueError(
112
114
  f"Invalid data format {self.data_format} for dataset {self.label}."
@@ -130,6 +132,8 @@ class Dataset:
130
132
  with pd.HDFStore(file, "a") as f:
131
133
  f.put(key, values)
132
134
  self._table_cache = {}
135
+ elif self.data_format == Dataset.FLAT_FILE:
136
+ values.to_csv(file, index=False)
133
137
  else:
134
138
  raise ValueError(
135
139
  f"Invalid data format {self.data_format} for dataset {self.label}."
@@ -242,6 +246,8 @@ class Dataset:
242
246
  elif self.data_format in (Dataset.ARRAYS, Dataset.TIME_PERIOD_ARRAYS):
243
247
  with h5py.File(self.file_path, "r") as f:
244
248
  return list(f.keys())
249
+ elif self.data_format == Dataset.FLAT_FILE:
250
+ return pd.read_csv(self.file_path, nrows=0).columns.tolist()
245
251
  else:
246
252
  raise ValueError(
247
253
  f"Invalid data format {self.data_format} for dataset {self.label}."
@@ -332,3 +338,51 @@ class Dataset:
332
338
  """Removes the dataset from disk."""
333
339
  if self.exists:
334
340
  self.file_path.unlink()
341
+
342
+ @staticmethod
343
+ def from_file(file_path: str, time_period: str = None):
344
+ """Creates a dataset from a file.
345
+
346
+ Args:
347
+ file_path (str): The file path to create the dataset from.
348
+
349
+ Returns:
350
+ Dataset: The dataset.
351
+ """
352
+ file_path = Path(file_path)
353
+ dataset = type(
354
+ "Dataset",
355
+ (Dataset,),
356
+ {
357
+ "name": file_path.stem,
358
+ "label": file_path.stem,
359
+ "data_format": Dataset.FLAT_FILE,
360
+ "file_path": file_path,
361
+ "time_period": time_period,
362
+ },
363
+ )()
364
+
365
+ return dataset
366
+
367
+ @staticmethod
368
+ def from_dataframe(dataframe: pd.DataFrame, time_period: str = None):
369
+ """Creates a dataset from a DataFrame.
370
+
371
+ Returns:
372
+ Dataset: The dataset.
373
+ """
374
+ file_path = Path(file_path)
375
+ dataset = type(
376
+ "Dataset",
377
+ (Dataset,),
378
+ {
379
+ "name": file_path.stem,
380
+ "label": file_path.stem,
381
+ "data_format": Dataset.FLAT_FILE,
382
+ "file_path": "dataframe",
383
+ "time_period": time_period,
384
+ "load": lambda: dataframe,
385
+ },
386
+ )()
387
+
388
+ return dataset
@@ -137,7 +137,7 @@ class Parameter(AtInstantLike):
137
137
  ]
138
138
  return clone
139
139
 
140
- def update(self, period=None, start=None, stop=None, value=None):
140
+ def update(self, value=None, period=None, start=None, stop=None):
141
141
  """
142
142
  Change the value for a given period.
143
143
 
@@ -156,7 +156,7 @@ class Parameter(AtInstantLike):
156
156
  start = period.start
157
157
  stop = period.stop
158
158
  if start is None:
159
- raise ValueError("You must provide either a start or a period")
159
+ start = "0000-01-01"
160
160
  start_str = str(start)
161
161
  stop_str = str(stop.offset(1, "day")) if stop else None
162
162
 
@@ -253,3 +253,24 @@ class ParameterNode(AtInstantLike):
253
253
  self.modified = True
254
254
  if self.parent is not None:
255
255
  self.parent.mark_as_modified()
256
+
257
+ def get_child(self, path: str) -> "ParameterNode":
258
+ node = self
259
+ for name in path.split("."):
260
+ try:
261
+ if "[" not in name:
262
+ node = node.children[name]
263
+ else:
264
+ try:
265
+ name, index = name.split("[")
266
+ index = int(index[:-1])
267
+ node = node.children[name].brackets[index]
268
+ except:
269
+ raise ValueError(
270
+ "Invalid bracket syntax (should be e.g. tax.brackets[3].rate"
271
+ )
272
+ except:
273
+ raise ValueError(
274
+ f"Could not find the parameter (failed at {name})."
275
+ )
276
+ return node
@@ -1,10 +1,13 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import copy
4
- from typing import Callable, Union
4
+ from typing import Callable, Union, TYPE_CHECKING
5
5
 
6
6
  from policyengine_core.parameters import ParameterNode, Parameter
7
7
  from policyengine_core.taxbenefitsystems import TaxBenefitSystem
8
+
9
+ if TYPE_CHECKING:
10
+ from policyengine_core.simulations import Simulation
8
11
  from policyengine_core.periods import (
9
12
  period as period_,
10
13
  instant as instant_,
@@ -60,6 +63,8 @@ class Reform(TaxBenefitSystem):
60
63
  parameter_values: dict = None
61
64
  """The parameter values of the reform. This is used to inform any calls to the PolicyEngine API."""
62
65
 
66
+ simulation: "Simulation" = None
67
+
63
68
  def __init__(self, baseline: TaxBenefitSystem):
64
69
  """
65
70
  :param baseline: Baseline TaxBenefitSystem.
@@ -134,25 +139,22 @@ class Reform(TaxBenefitSystem):
134
139
  class reform(Reform):
135
140
  def apply(self):
136
141
  for path, period_values in parameter_values.items():
137
- for period, value in period_values.items():
138
- if "." in period:
139
- start, stop = period.split(".")
140
- self.modify_parameters(
141
- set_parameter(
142
- path,
143
- value,
144
- period=None,
145
- start=start,
146
- stop=stop,
147
- return_modifier=True,
142
+ parameter = self.parameters.get_child(path)
143
+ if not isinstance(period_values, dict):
144
+ parameter.update(
145
+ start="0000-01-01", value=period_values
146
+ )
147
+ else:
148
+ for period, value in period_values.items():
149
+ if "." in period:
150
+ start, stop = period.split(".")
151
+ parameter.update(
152
+ start=start, stop=stop, value=value
148
153
  )
149
- )
150
- else:
151
- self.modify_parameters(
152
- set_parameter(
153
- path, value, period, return_modifier=True
154
+ else:
155
+ parameter = parameter.update(
156
+ period=period, value=value
154
157
  )
155
- )
156
158
 
157
159
  reform.country_id = country_id
158
160
  reform.parameter_values = parameter_values
@@ -5,6 +5,7 @@ import numpy
5
5
  import numpy as np
6
6
  import pandas as pd
7
7
  from numpy.typing import ArrayLike
8
+ import logging
8
9
 
9
10
  from policyengine_core import commons, periods
10
11
  from policyengine_core.data.dataset import Dataset
@@ -30,7 +31,7 @@ if TYPE_CHECKING:
30
31
  from policyengine_core.taxbenefitsystems import TaxBenefitSystem
31
32
 
32
33
  from policyengine_core.experimental import MemoryConfig
33
- from policyengine_core.populations import Population
34
+ from policyengine_core.populations import Population, GroupPopulation
34
35
  from policyengine_core.tracers import SimpleTracer
35
36
  from policyengine_core.variables import Variable, QuantityType
36
37
  from policyengine_core.reforms.reform import Reform
@@ -84,7 +85,6 @@ class Simulation:
84
85
  reform: Reform = None,
85
86
  trace: bool = False,
86
87
  ):
87
- reform_applied_after = False
88
88
  if tax_benefit_system is None:
89
89
  if (
90
90
  self.default_tax_benefit_system_instance is not None
@@ -93,20 +93,11 @@ class Simulation:
93
93
  tax_benefit_system = self.default_tax_benefit_system_instance
94
94
  else:
95
95
  # If reform is taken as an arg, pass it
96
- try:
97
- tax_benefit_system = self.default_tax_benefit_system(
98
- reform=reform
99
- )
100
- except:
101
- tax_benefit_system = self.default_tax_benefit_system()
102
- reform_applied_after = True
96
+ tax_benefit_system = self.default_tax_benefit_system()
103
97
  self.tax_benefit_system = tax_benefit_system
104
98
 
105
99
  self.reform = reform
106
100
  self.tax_benefit_system = tax_benefit_system
107
-
108
- if reform_applied_after and reform is not None:
109
- self.apply_reform(reform)
110
101
  self.branch_name = "default"
111
102
 
112
103
  if dataset is None:
@@ -156,17 +147,23 @@ class Simulation:
156
147
  datasets_by_name = {
157
148
  dataset.name: dataset for dataset in self.datasets
158
149
  }
159
- if dataset not in datasets_by_name:
160
- raise ValueError(
161
- f"Dataset {dataset} not found. Available datasets: {list(datasets_by_name.keys())}"
150
+ if dataset in datasets_by_name:
151
+ dataset = datasets_by_name.get(dataset)
152
+ elif Path(dataset).exists():
153
+ dataset = Dataset.from_file(
154
+ dataset, self.default_input_period
162
155
  )
163
- dataset = datasets_by_name[dataset]
164
156
  if isinstance(dataset, type):
165
157
  self.dataset: Dataset = dataset(require=True)
166
158
  else:
167
159
  self.dataset = dataset
168
160
  self.build_from_dataset()
169
161
 
162
+ self.tax_benefit_system.simulation = self
163
+
164
+ if self.reform is not None:
165
+ self.tax_benefit_system.apply_reform_set(self.reform)
166
+
170
167
  # Backwards compatibility methods
171
168
  self.calc = self.calculate
172
169
  self.df = self.calculate_dataframe
@@ -247,23 +244,31 @@ class Simulation:
247
244
 
248
245
  person_entity = self.tax_benefit_system.person_entity
249
246
  entity_id_field = f"{person_entity.key}_id"
250
- assert (
251
- entity_id_field in data
252
- ), f"Missing {entity_id_field} column in the dataset. Each person entity must have an ID array defined for ETERNITY."
253
-
254
- get_eternity_array = lambda ds: (
255
- ds[list(ds.keys())[0]]
256
- if self.dataset.data_format == Dataset.TIME_PERIOD_ARRAYS
257
- else ds
258
- )
247
+ if self.dataset.data_format != Dataset.FLAT_FILE:
248
+ assert (
249
+ entity_id_field in data
250
+ ), f"Missing {entity_id_field} column in the dataset. Each person entity must have an ID array defined for ETERNITY."
251
+ elif entity_id_field not in data:
252
+ data[entity_id_field] = np.arange(len(data))
253
+ if self.dataset.data_format != Dataset.FLAT_FILE:
254
+ get_eternity_array = lambda ds: (
255
+ ds[list(ds.keys())[0]]
256
+ if self.dataset.data_format == Dataset.TIME_PERIOD_ARRAYS
257
+ else ds
258
+ )
259
+ else:
260
+ get_eternity_array = lambda ds: ds
259
261
  entity_ids = get_eternity_array(data[entity_id_field])
260
262
  builder.declare_person_entity(person_entity.key, entity_ids)
261
263
 
262
264
  for group_entity in self.tax_benefit_system.group_entities:
263
265
  entity_id_field = f"{group_entity.key}_id"
264
- assert (
265
- entity_id_field in data
266
- ), f"Missing {entity_id_field} column in the dataset. Each group entity must have an ID array defined for ETERNITY."
266
+ if self.dataset.data_format != Dataset.FLAT_FILE:
267
+ assert (
268
+ entity_id_field in data
269
+ ), f"Missing {entity_id_field} column in the dataset. Each group entity must have an ID array defined for ETERNITY."
270
+ elif entity_id_field not in data:
271
+ data[entity_id_field] = np.arange(len(data))
267
272
 
268
273
  entity_ids = get_eternity_array(data[entity_id_field])
269
274
  builder.declare_entity(group_entity.key, entity_ids)
@@ -271,9 +276,12 @@ class Simulation:
271
276
  person_membership_id_field = (
272
277
  f"{person_entity.key}_{group_entity.key}_id"
273
278
  )
274
- assert (
275
- person_membership_id_field in data
276
- ), f"Missing {person_membership_id_field} column in the dataset. Each group entity must have a person membership array defined for ETERNITY."
279
+ if self.dataset.data_format != Dataset.FLAT_FILE:
280
+ assert (
281
+ person_membership_id_field in data
282
+ ), f"Missing {person_membership_id_field} column in the dataset. Each group entity must have a person membership array defined for ETERNITY."
283
+ elif person_membership_id_field not in data:
284
+ data[person_membership_id_field] = np.arange(len(data))
277
285
  person_membership_ids = get_eternity_array(
278
286
  data[person_membership_id_field]
279
287
  )
@@ -297,20 +305,55 @@ class Simulation:
297
305
 
298
306
  self.build_from_populations(builder.populations)
299
307
 
300
- for variable in data:
301
- if variable in self.tax_benefit_system.variables:
302
- if self.dataset.data_format == Dataset.TIME_PERIOD_ARRAYS:
303
- for time_period in data[variable]:
308
+ if self.dataset.data_format != Dataset.FLAT_FILE:
309
+ for variable in data:
310
+ if variable in self.tax_benefit_system.variables:
311
+ if self.dataset.data_format == Dataset.TIME_PERIOD_ARRAYS:
312
+ for time_period in data[variable]:
313
+ self.set_input(
314
+ variable,
315
+ time_period,
316
+ data[variable][time_period],
317
+ )
318
+ else:
304
319
  self.set_input(
305
- variable, time_period, data[variable][time_period]
320
+ variable, self.dataset.time_period, data[variable]
306
321
  )
307
322
  else:
308
- self.set_input(
309
- variable, self.dataset.time_period, data[variable]
323
+ # Silently skip.
324
+ pass
325
+ else:
326
+ for variable in data:
327
+ if "__" in variable:
328
+ variable_name, time_period = variable.split("__")
329
+ else:
330
+ variable_name = variable
331
+ time_period = (
332
+ self.dataset.time_period or self.default_input_period
310
333
  )
311
- else:
312
- # Silently skip.
313
- pass
334
+
335
+ if variable_name not in self.tax_benefit_system.variables:
336
+ logging.warn(
337
+ f"Variable {variable_name} not found. Skipping."
338
+ )
339
+ continue
340
+
341
+ variable_meta = self.tax_benefit_system.get_variable(
342
+ variable_name
343
+ )
344
+ entity = variable_meta.entity
345
+ population = self.get_population(entity.plural)
346
+
347
+ # All data should be person level
348
+ if len(data[variable]) != len(population.ids):
349
+ population: GroupPopulation
350
+ entity_level_data = population.value_from_first_person(
351
+ data[variable]
352
+ )
353
+ else:
354
+ entity_level_data = data[variable]
355
+
356
+ self.set_input(variable, time_period, entity_level_data)
314
357
 
315
358
  self.default_calculation_period = self.dataset.time_period
316
359
 
@@ -0,0 +1 @@
1
+ from .microdf import MicroDataFrame, MicroSeries