OpenFisca-Core 44.5.0__tar.gz → 44.7.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 (214) hide show
  1. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/CHANGELOG.md +6 -36
  2. {openfisca_core-44.5.0 → openfisca_core-44.7.0/OpenFisca_Core.egg-info}/PKG-INFO +1 -1
  3. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/OpenFisca_Core.egg-info/SOURCES.txt +0 -13
  4. {openfisca_core-44.5.0/OpenFisca_Core.egg-info → openfisca_core-44.7.0}/PKG-INFO +1 -1
  5. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/entities/_core_entity.py +0 -40
  6. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/holders/holder.py +0 -65
  7. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/indexed_enums/enum_array.py +4 -2
  8. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/populations/_core_population.py +0 -32
  9. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/populations/group_population.py +15 -68
  10. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/populations/population.py +5 -7
  11. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/reforms/reform_excel.py +14 -2
  12. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/simulations/_build_default_simulation.py +0 -11
  13. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/simulations/simulation.py +0 -48
  14. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/simulations/simulation_builder.py +0 -2
  15. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/taxscales/abstract_rate_tax_scale.py +1 -1
  16. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/taxscales/abstract_tax_scale.py +2 -2
  17. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/taxscales/tax_scale_like.py +2 -2
  18. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/variables/variable.py +0 -28
  19. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/pyproject.toml +1 -1
  20. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/setup.py +1 -1
  21. openfisca_core-44.5.0/openfisca_core/links/__init__.py +0 -36
  22. openfisca_core-44.5.0/openfisca_core/links/implicit.py +0 -111
  23. openfisca_core-44.5.0/openfisca_core/links/link.py +0 -109
  24. openfisca_core-44.5.0/openfisca_core/links/many2one.py +0 -310
  25. openfisca_core-44.5.0/openfisca_core/links/one2many.py +0 -306
  26. openfisca_core-44.5.0/openfisca_core/links/tests/__init__.py +0 -58
  27. openfisca_core-44.5.0/openfisca_core/links/tests/test_benchmark.py +0 -93
  28. openfisca_core-44.5.0/openfisca_core/links/tests/test_edge_cases.py +0 -467
  29. openfisca_core-44.5.0/openfisca_core/links/tests/test_implicit.py +0 -76
  30. openfisca_core-44.5.0/openfisca_core/links/tests/test_integration.py +0 -192
  31. openfisca_core-44.5.0/openfisca_core/links/tests/test_many2one.py +0 -149
  32. openfisca_core-44.5.0/openfisca_core/links/tests/test_one2many.py +0 -112
  33. openfisca_core-44.5.0/openfisca_core/links/tests/test_one2many_logic.py +0 -398
  34. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/LICENSE +0 -0
  35. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/MANIFEST.in +0 -0
  36. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/OpenFisca_Core.egg-info/dependency_links.txt +0 -0
  37. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/OpenFisca_Core.egg-info/entry_points.txt +0 -0
  38. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/OpenFisca_Core.egg-info/requires.txt +0 -0
  39. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/OpenFisca_Core.egg-info/top_level.txt +0 -0
  40. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/README.md +0 -0
  41. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/__init__.py +0 -0
  42. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/commons/__init__.py +0 -0
  43. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/commons/dummy.py +0 -0
  44. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/commons/formulas.py +0 -0
  45. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/commons/misc.py +0 -0
  46. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/commons/py.typed +0 -0
  47. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/commons/rates.py +0 -0
  48. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/commons/tests/__init__.py +0 -0
  49. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/commons/tests/test_dummy.py +0 -0
  50. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/commons/tests/test_formulas.py +0 -0
  51. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/commons/tests/test_rates.py +0 -0
  52. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/data_storage/__init__.py +0 -0
  53. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/data_storage/in_memory_storage.py +0 -0
  54. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/data_storage/on_disk_storage.py +0 -0
  55. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/data_storage/types.py +0 -0
  56. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/entities/__init__.py +0 -0
  57. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/entities/_description.py +0 -0
  58. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/entities/entity.py +0 -0
  59. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/entities/group_entity.py +0 -0
  60. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/entities/helpers.py +0 -0
  61. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/entities/py.typed +0 -0
  62. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/entities/role.py +0 -0
  63. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/entities/tests/__init__.py +0 -0
  64. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/entities/tests/test_entity.py +0 -0
  65. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/entities/tests/test_group_entity.py +0 -0
  66. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/entities/tests/test_role.py +0 -0
  67. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/entities/types.py +0 -0
  68. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/errors/__init__.py +0 -0
  69. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/errors/cycle_error.py +0 -0
  70. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/errors/empty_argument_error.py +0 -0
  71. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/errors/nan_creation_error.py +0 -0
  72. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/errors/parameter_not_found_error.py +0 -0
  73. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/errors/parameter_parsing_error.py +0 -0
  74. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/errors/period_mismatch_error.py +0 -0
  75. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/errors/situation_parsing_error.py +0 -0
  76. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/errors/spiral_error.py +0 -0
  77. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/errors/variable_name_config_error.py +0 -0
  78. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/errors/variable_not_found_error.py +0 -0
  79. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/experimental/__init__.py +0 -0
  80. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/experimental/_errors.py +0 -0
  81. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/experimental/_memory_config.py +0 -0
  82. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/formula_helpers.py +0 -0
  83. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/holders/__init__.py +0 -0
  84. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/holders/helpers.py +0 -0
  85. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/holders/tests/__init__.py +0 -0
  86. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/holders/tests/test_helpers.py +0 -0
  87. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/holders/types.py +0 -0
  88. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/indexed_enums/__init__.py +0 -0
  89. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/indexed_enums/_enum_type.py +0 -0
  90. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/indexed_enums/_errors.py +0 -0
  91. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/indexed_enums/_guards.py +0 -0
  92. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/indexed_enums/_utils.py +0 -0
  93. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/indexed_enums/config.py +0 -0
  94. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/indexed_enums/enum.py +0 -0
  95. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/indexed_enums/py.typed +0 -0
  96. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/indexed_enums/tests/__init__.py +0 -0
  97. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/indexed_enums/tests/test_enum.py +0 -0
  98. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/indexed_enums/tests/test_enum_array.py +0 -0
  99. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/indexed_enums/types.py +0 -0
  100. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/memory_config.py +0 -0
  101. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/model_api.py +0 -0
  102. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/parameters/__init__.py +0 -0
  103. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/parameters/at_instant_like.py +0 -0
  104. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/parameters/config.py +0 -0
  105. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/parameters/helpers.py +0 -0
  106. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/parameters/parameter.py +0 -0
  107. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/parameters/parameter_at_instant.py +0 -0
  108. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/parameters/parameter_node.py +0 -0
  109. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/parameters/parameter_node_at_instant.py +0 -0
  110. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/parameters/parameter_scale.py +0 -0
  111. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/parameters/parameter_scale_bracket.py +0 -0
  112. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/parameters/values_history.py +0 -0
  113. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/parameters/vectorial_parameter_node_at_instant.py +0 -0
  114. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/periods/__init__.py +0 -0
  115. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/periods/_errors.py +0 -0
  116. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/periods/_parsers.py +0 -0
  117. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/periods/config.py +0 -0
  118. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/periods/date_unit.py +0 -0
  119. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/periods/helpers.py +0 -0
  120. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/periods/instant_.py +0 -0
  121. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/periods/period_.py +0 -0
  122. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/periods/py.typed +0 -0
  123. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/periods/tests/__init__.py +0 -0
  124. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/periods/tests/helpers/__init__.py +0 -0
  125. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/periods/tests/helpers/test_helpers.py +0 -0
  126. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/periods/tests/helpers/test_instant.py +0 -0
  127. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/periods/tests/helpers/test_period.py +0 -0
  128. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/periods/tests/test_instant.py +0 -0
  129. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/periods/tests/test_parsers.py +0 -0
  130. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/periods/tests/test_period.py +0 -0
  131. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/populations/__init__.py +0 -0
  132. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/populations/_errors.py +0 -0
  133. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/populations/tests/__init__.py +0 -0
  134. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/populations/tests/test_members_position.py +0 -0
  135. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/populations/types.py +0 -0
  136. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/projectors/__init__.py +0 -0
  137. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/projectors/entity_to_person_projector.py +0 -0
  138. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/projectors/first_person_to_entity_projector.py +0 -0
  139. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/projectors/helpers.py +0 -0
  140. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/projectors/projector.py +0 -0
  141. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/projectors/typing.py +0 -0
  142. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/projectors/unique_role_to_entity_projector.py +0 -0
  143. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/rates.py +0 -0
  144. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/reforms/__init__.py +0 -0
  145. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/reforms/in_yaml_test_reform.py +0 -0
  146. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/reforms/reform.py +0 -0
  147. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/scripts/__init__.py +0 -0
  148. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/scripts/assets/__init__.py +0 -0
  149. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/scripts/assets/index.html +0 -0
  150. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/scripts/find_placeholders.py +0 -0
  151. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/scripts/measure_numpy_condition_notations.py +0 -0
  152. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/scripts/measure_performances.py +0 -0
  153. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/scripts/measure_performances_fancy_indexing.py +0 -0
  154. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/scripts/migrations/__init__.py +0 -0
  155. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/scripts/migrations/v16_2_to_v17/__init__.py +0 -0
  156. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/scripts/migrations/v16_2_to_v17/legislation.xsd +0 -0
  157. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/scripts/migrations/v16_2_to_v17/xml_to_yaml_country_template.py +0 -0
  158. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/scripts/migrations/v16_2_to_v17/xml_to_yaml_extension_template.py +0 -0
  159. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/scripts/migrations/v24_to_25.py +0 -0
  160. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/scripts/openfisca_command.py +0 -0
  161. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/scripts/remove_fuzzy.py +0 -0
  162. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/scripts/run_test.py +0 -0
  163. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/scripts/simulation_generator.py +0 -0
  164. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/simulation_builder.py +0 -0
  165. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/simulations/__init__.py +0 -0
  166. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/simulations/_build_from_variables.py +0 -0
  167. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/simulations/_type_guards.py +0 -0
  168. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/simulations/helpers.py +0 -0
  169. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/simulations/typing.py +0 -0
  170. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/taxbenefitsystems/__init__.py +0 -0
  171. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/taxbenefitsystems/tax_benefit_system.py +0 -0
  172. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/taxscales/__init__.py +0 -0
  173. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/taxscales/amount_tax_scale_like.py +0 -0
  174. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/taxscales/helpers.py +0 -0
  175. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/taxscales/linear_average_rate_tax_scale.py +0 -0
  176. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/taxscales/marginal_amount_tax_scale.py +0 -0
  177. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/taxscales/marginal_rate_tax_scale.py +0 -0
  178. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/taxscales/rate_tax_scale_like.py +0 -0
  179. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/taxscales/single_amount_tax_scale.py +0 -0
  180. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/tools/__init__.py +0 -0
  181. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/tools/parallel_plugin.py +0 -0
  182. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/tools/simulation_dumper.py +0 -0
  183. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/tools/test_runner.py +0 -0
  184. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/tracers/__init__.py +0 -0
  185. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/tracers/computation_log.py +0 -0
  186. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/tracers/flat_trace.py +0 -0
  187. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/tracers/full_tracer.py +0 -0
  188. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/tracers/performance_log.py +0 -0
  189. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/tracers/simple_tracer.py +0 -0
  190. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/tracers/trace_node.py +0 -0
  191. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/tracers/tracing_parameter_node_at_instant.py +0 -0
  192. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/types.py +0 -0
  193. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/variables/__init__.py +0 -0
  194. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/variables/config.py +0 -0
  195. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/variables/helpers.py +0 -0
  196. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/variables/tests/__init__.py +0 -0
  197. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/variables/tests/test_definition_period.py +0 -0
  198. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/warnings/__init__.py +0 -0
  199. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/warnings/libyaml_warning.py +0 -0
  200. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_core/warnings/tempfile_warning.py +0 -0
  201. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_web_api/__init__.py +0 -0
  202. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_web_api/app.py +0 -0
  203. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_web_api/errors.py +0 -0
  204. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_web_api/handlers.py +0 -0
  205. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_web_api/loader/__init__.py +0 -0
  206. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_web_api/loader/entities.py +0 -0
  207. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_web_api/loader/parameters.py +0 -0
  208. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_web_api/loader/spec.py +0 -0
  209. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_web_api/loader/tax_benefit_system.py +0 -0
  210. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_web_api/loader/variables.py +0 -0
  211. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_web_api/openAPI.yml +0 -0
  212. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_web_api/scripts/__init__.py +0 -0
  213. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/openfisca_web_api/scripts/serve.py +0 -0
  214. {openfisca_core-44.5.0 → openfisca_core-44.7.0}/setup.cfg +0 -0
@@ -1,48 +1,18 @@
1
1
  # Changelog
2
2
 
3
- ## 44.5.0
3
+ ## 44.7.0 [#1357](https://github.com/openfisca/openfisca-core/pull/1357)
4
4
 
5
5
  #### New features
6
6
 
7
- - Add `as_of` attribute to `Variable` for persistent vector variables.
8
- - A variable declared with `as_of = True` (or `"start"` / `"end"`) stores its value at a given instant and automatically returns that value for any later period, until a new value is explicitly set — the vectorial analogue of OpenFisca parameters.
9
- - `as_of = "start"` (default when `True`): lookup uses the start of the requested period as reference instant.
10
- - `as_of = "end"`: lookup uses the end of the requested period (useful for annual variables like income tax).
11
- - Lookup is O(log P) via `bisect` on a sorted instants index.
12
- - Reference sharing: when consecutive stored values are identical, the same array object is reused, reducing memory usage for stable variables (e.g. `marital_status`, `housing_occupancy_status`).
13
- - Stored arrays are read-only (`writeable=False`) to prevent accidental in-place mutation.
14
- - Combining `as_of` with `set_input` dispatch helpers raises a `ValueError` at variable definition time.
7
+ - Manage list parameter in Excel reform
15
8
 
16
- ## 44.4.0 [#1364](https://github.com/openfisca/openfisca-core/pull/1364)
17
-
18
- #### New features
19
-
20
- - **Entity links**: role-based and positional accessors, and dynamic population period-index helpers.
21
- - `Many2OneLink.get_by_role(variable_name, period, role_value=...)`, `One2ManyLink.get_by_role(...)` and `ImplicitOne2ManyLink.get_by_role(...)`.
22
- - `Many2OneLink.rank(variable_name, period)` (and on chained getter, e.g. `person.links["mother"].household.rank("age", period)`).
23
- - `One2ManyLink.nth(n, variable_name, period, role=..., condition=...)` for the n-th target member per source.
24
- - `has_role(role_value)` now supports `Role` objects (comparison by `.key`) in addition to raw values.
25
- - `CorePopulation.snapshot_period(period)` and `get_period_id_to_rownum(period)` for optional dynamic-population period indexing.
26
-
27
- #### Technical changes
28
-
29
- - Removed unused `openfisca_core.model_api` import in `tests/core/parameters_date_indexing/test_date_indexing.py`.
30
- - SimulationBuilder sets `_id_to_rownum` identity mapping for static simulations (`build_default_simulation`, `build_from_dict` / `build_from_entities`), for dynamic-population support.
31
- - Add `PYTHON` variable to `tasks/lint.mk` so `make lint PYTHON=.venv/bin/python` works; fix style in `test_link_accessors.py` and remove unused variable in `test_many2one.py`.
32
-
33
- ## 44.3.0 [#1365](https://github.com/openfisca/openfisca-core/pull/1365)
34
-
35
- #### New features
36
-
37
- - **Generic Entity Links (Phase 1-6)**: Introduced a new Liam2-inspired generic entity linking system avoiding rigid hierarchies like `Person -> Household`.
38
- - Added new `Many2OneLink` and `One2ManyLink` models to create powerful inter-entity networks (e.g., `Person -> Employer`).
39
- - Added implicit links directly binding members arrays. This powers the new `population.links` property natively inside `TaxBenefitSystem.instantiate_entities()`.
40
- - Full capability to chain relationships via python: `person.mother.household.get("rent", period)`.
41
- - Powerful vectorized declarative aggregations out-of-the-box (e.g., `households.persons.sum("salary", period, condition=is_female)`).
9
+ ## 44.6.0
42
10
 
43
11
  #### Technical changes
44
12
 
45
- - Backward compatibility is 100% maintained. Existing syntax via Projectors natively redirects to implicit links via modified `__getattr__`.
13
+ - Revert the codebase to commit `8d26af3` to align the repository with the currently published `44.2.2` baseline on PyPI.
14
+ - Mark versions `44.3.0`, `44.4.0`, `44.4.1`, and `44.5.0` as yanked.
15
+ - Bump version to `44.6.0` to restore continuous deployment from this reverted baseline.
46
16
 
47
17
  ## 44.2.2
48
18
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: OpenFisca-Core
3
- Version: 44.5.0
3
+ Version: 44.7.0
4
4
  Summary: A versatile microsimulation free software
5
5
  Home-page: https://github.com/openfisca/openfisca-core
6
6
  Author: OpenFisca Team
@@ -78,19 +78,6 @@ openfisca_core/indexed_enums/types.py
78
78
  openfisca_core/indexed_enums/tests/__init__.py
79
79
  openfisca_core/indexed_enums/tests/test_enum.py
80
80
  openfisca_core/indexed_enums/tests/test_enum_array.py
81
- openfisca_core/links/__init__.py
82
- openfisca_core/links/implicit.py
83
- openfisca_core/links/link.py
84
- openfisca_core/links/many2one.py
85
- openfisca_core/links/one2many.py
86
- openfisca_core/links/tests/__init__.py
87
- openfisca_core/links/tests/test_benchmark.py
88
- openfisca_core/links/tests/test_edge_cases.py
89
- openfisca_core/links/tests/test_implicit.py
90
- openfisca_core/links/tests/test_integration.py
91
- openfisca_core/links/tests/test_many2one.py
92
- openfisca_core/links/tests/test_one2many.py
93
- openfisca_core/links/tests/test_one2many_logic.py
94
81
  openfisca_core/parameters/__init__.py
95
82
  openfisca_core/parameters/at_instant_like.py
96
83
  openfisca_core/parameters/config.py
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: OpenFisca-Core
3
- Version: 44.5.0
3
+ Version: 44.7.0
4
4
  Summary: A versatile microsimulation free software
5
5
  Home-page: https://github.com/openfisca/openfisca-core
6
6
  Author: OpenFisca Team
@@ -47,9 +47,6 @@ class CoreEntity:
47
47
  #: A ``TaxBenefitSystem`` instance.
48
48
  _tax_benefit_system: None | t.TaxBenefitSystem = None
49
49
 
50
- #: Named links to other entities (Many2One, One2Many, etc.).
51
- _links: dict
52
-
53
50
  @abc.abstractmethod
54
51
  def __init__(self, *__args: object, **__kwargs: object) -> None: ...
55
52
 
@@ -60,43 +57,6 @@ class CoreEntity:
60
57
  """A ``CoreEntity`` belongs to a ``TaxBenefitSystem``."""
61
58
  self._tax_benefit_system = tax_benefit_system
62
59
 
63
- # -- Link management --------------------------------------------------
64
-
65
- def add_link(self, link) -> None:
66
- """Register a named link on this entity.
67
-
68
- Args:
69
- link: A ``Link`` instance (Many2OneLink, One2ManyLink, etc.).
70
-
71
- Example::
72
-
73
- from openfisca_core.links import Many2OneLink
74
-
75
- mother = Many2OneLink(
76
- name="mother",
77
- link_field="mother_id",
78
- target_entity_key="person",
79
- )
80
- person_entity.add_link(mother)
81
-
82
- """
83
- if not hasattr(self, "_links") or self._links is None:
84
- self._links = {}
85
- self._links[link.name] = link
86
-
87
- def get_link(self, name: str):
88
- """Retrieve a link by name, or ``None`` if not found."""
89
- if not hasattr(self, "_links") or self._links is None:
90
- return None
91
- return self._links.get(name)
92
-
93
- @property
94
- def links(self) -> dict:
95
- """All links registered on this entity."""
96
- if not hasattr(self, "_links") or self._links is None:
97
- self._links = {}
98
- return self._links
99
-
100
60
  def get_variable(
101
61
  self,
102
62
  variable_name: t.VariableName,
@@ -3,7 +3,6 @@ from __future__ import annotations
3
3
  from collections.abc import Sequence
4
4
  from typing import Any
5
5
 
6
- import bisect
7
6
  import os
8
7
  import warnings
9
8
 
@@ -30,10 +29,7 @@ class Holder:
30
29
  self.variable = variable
31
30
  self.simulation = population.simulation
32
31
  self._eternal = self.variable.definition_period == periods.DateUnit.ETERNITY
33
- self._as_of = getattr(self.variable, "as_of", False)
34
32
  self._memory_storage = storage.InMemoryStorage(is_eternal=self._eternal)
35
- if self._as_of:
36
- self._sorted_instants: list = []
37
33
 
38
34
  # By default, do not activate on-disk storage, or variable dropping
39
35
  self._disk_storage = None
@@ -58,11 +54,6 @@ class Holder:
58
54
  if key not in ("population", "formula", "simulation"):
59
55
  new_dict[key] = value
60
56
 
61
- # _sorted_instants must be an independent copy so that writes to the
62
- # clone don't corrupt the original's index.
63
- if self._as_of:
64
- new_dict["_sorted_instants"] = list(self._sorted_instants)
65
-
66
57
  new_dict["population"] = population
67
58
  new_dict["simulation"] = population.simulation
68
59
 
@@ -99,52 +90,10 @@ class Holder:
99
90
  value = self._memory_storage.get(period)
100
91
  if value is not None:
101
92
  return value
102
- if self._as_of:
103
- value = self._get_as_of(period)
104
- if value is not None:
105
- return value
106
93
  if self._disk_storage:
107
94
  return self._disk_storage.get(period)
108
95
  return None
109
96
 
110
- def _get_as_of(self, period):
111
- """Return the most recent stored value at or before the reference instant.
112
-
113
- Uses a sorted list of instants + bisect for O(log P) lookup.
114
- Falls back to a linear scan if _sorted_instants is not yet initialised
115
- (e.g. after clone()).
116
- """
117
- target = period.start if self._as_of == "start" else period.stop
118
- sorted_instants = getattr(self, "_sorted_instants", None)
119
-
120
- if sorted_instants is not None:
121
- pos = bisect.bisect_right(sorted_instants, target)
122
- if pos == 0:
123
- return None
124
- best_instant = sorted_instants[pos - 1]
125
- else:
126
- # Fallback linear scan (e.g. after clone without _sorted_instants)
127
- best_instant = None
128
- for known_period in self._memory_storage.get_known_periods():
129
- start = known_period.start
130
- if start <= target:
131
- if best_instant is None or start > best_instant:
132
- best_instant = start
133
- if best_instant is None:
134
- return None
135
-
136
- for known_period in self._memory_storage.get_known_periods():
137
- if known_period.start == best_instant:
138
- return self._memory_storage.get(known_period)
139
- return None
140
-
141
- def _register_instant(self, period) -> None:
142
- """Insert period.start into the sorted instants list (no duplicates)."""
143
- instant = period.start
144
- pos = bisect.bisect_left(self._sorted_instants, instant)
145
- if pos == len(self._sorted_instants) or self._sorted_instants[pos] != instant:
146
- self._sorted_instants.insert(pos, instant)
147
-
148
97
  def get_memory_usage(self) -> t.MemoryUsage:
149
98
  """Get data about the virtual memory usage of the Holder.
150
99
 
@@ -353,25 +302,11 @@ class Holder:
353
302
  >= self.simulation.memory_config.max_memory_occupation_pc
354
303
  )
355
304
 
356
- if self._as_of:
357
- # Reference sharing: reuse existing array object when value unchanged,
358
- # otherwise store a read-only defensive copy so that callers cannot
359
- # corrupt stored data by mutating their original array in-place.
360
- prev = self._get_as_of(period)
361
- if prev is not None and numpy.array_equal(value, prev):
362
- value = prev # prev is already read-only
363
- else:
364
- value = value.copy()
365
- value.flags.writeable = False
366
-
367
305
  if should_store_on_disk:
368
306
  self._disk_storage.put(value, period)
369
307
  else:
370
308
  self._memory_storage.put(value, period)
371
309
 
372
- if self._as_of:
373
- self._register_instant(period)
374
-
375
310
  def put_in_cache(self, value, period) -> None:
376
311
  if self._do_not_store:
377
312
  return
@@ -266,7 +266,8 @@ class EnumArray(t.EnumArray):
266
266
  result: t.ObjArray
267
267
  if self.possible_values is None:
268
268
  msg = (
269
- f"The possible values of the {self.__class__.__name__} are not defined."
269
+ f"The possible values of the {self.__class__.__name__} are "
270
+ f"not defined."
270
271
  )
271
272
  raise TypeError(msg)
272
273
  array = self.reshape(1).astype(t.EnumDType) if self.ndim == 0 else self
@@ -300,7 +301,8 @@ class EnumArray(t.EnumArray):
300
301
  result: t.StrArray
301
302
  if self.possible_values is None:
302
303
  msg = (
303
- f"The possible values of the {self.__class__.__name__} are not defined."
304
+ f"The possible values of the {self.__class__.__name__} are "
305
+ f"not defined."
304
306
  )
305
307
  raise TypeError(msg)
306
308
  array = self.reshape(1).astype(t.EnumDType) if self.ndim == 0 else self
@@ -42,12 +42,6 @@ class CorePopulation:
42
42
 
43
43
  #: The :class:`~simulations.Simulation` for which the population is calculated.
44
44
  simulation: None | t.Simulation = None
45
- # === Dynamic population helpers (optional) ===
46
- _dynamic: bool = False
47
- _permanent_ids: None | numpy.ndarray = None
48
- _id_to_rownum: None | numpy.ndarray = None
49
- _next_id: None | int = None
50
- _period_index: None | dict = None
51
45
 
52
46
  def __init__(self, entity: t.CoreEntity, *__args: object, **__kwds: object) -> None:
53
47
  self.entity = entity
@@ -457,31 +451,5 @@ class CorePopulation:
457
451
  by_variable=holders_memory_usage,
458
452
  )
459
453
 
460
- # -- Dynamic population period index helpers -------------------------
461
-
462
- def snapshot_period(self, period: t.PeriodLike) -> None:
463
- """Save the current ``_id_to_rownum`` mapping for ``period``.
464
-
465
- If no ``_id_to_rownum`` exists yet, a default identity mapping is
466
- created (positions == ids) sized to ``self.count``.
467
- """
468
- if self._period_index is None:
469
- self._period_index = {}
470
-
471
- if self._id_to_rownum is None:
472
- # Default identity mapping: id -> row (0..count-1)
473
- self._id_to_rownum = numpy.arange(self.count, dtype=numpy.intp)
474
-
475
- self._period_index[periods.period(period)] = self._id_to_rownum.copy()
476
-
477
- def get_period_id_to_rownum(self, period: t.PeriodLike) -> None | numpy.ndarray:
478
- """Return the saved ``id -> rownum`` mapping for ``period`` or ``None``.
479
-
480
- Returns ``None`` when no index was saved for that period.
481
- """
482
- if self._period_index is None:
483
- return None
484
- return self._period_index.get(periods.period(period))
485
-
486
454
 
487
455
  __all__ = ["CorePopulation"]
@@ -96,42 +96,16 @@ class GroupPopulation(Population):
96
96
  None,
97
97
  )
98
98
 
99
- # Filtering helpers
100
-
101
- def _build_member_mask(self, role=None, condition=None):
102
- """Build a combined boolean mask from role and condition filters.
103
-
104
- Returns None if no filtering is needed (both are None), otherwise
105
- returns a boolean array of length ``members.count``.
106
- """
107
- if role is None and condition is None:
108
- return None
109
-
110
- mask = numpy.ones(self.members.count, dtype=bool)
111
-
112
- if role is not None:
113
- role_filter = self.members.has_role(role)
114
- mask &= role_filter
115
-
116
- if condition is not None:
117
- mask &= condition
118
-
119
- return mask
120
-
121
99
  # Aggregation persons -> entity
122
100
 
123
101
  @projectors.projectable
124
- def sum(self, array, role=None, condition=None):
102
+ def sum(self, array, role=None):
125
103
  """Return the sum of ``array`` for the members of the entity.
126
104
 
127
105
  ``array`` must have the dimension of the number of persons in the simulation
128
106
 
129
107
  If ``role`` is provided, only the entity member with the given role are taken into account.
130
108
 
131
- If ``condition`` is provided (a boolean array of the same size as the
132
- person population), only members for whom the condition is ``True`` are
133
- taken into account. ``role`` and ``condition`` can be combined.
134
-
135
109
  Example:
136
110
  >>> salaries = household.members(
137
111
  ... "salary", "2018-01"
@@ -142,27 +116,23 @@ class GroupPopulation(Population):
142
116
  """
143
117
  self.entity.check_role_validity(role)
144
118
  self.members.check_array_compatible_with_entity(array)
145
- mask = self._build_member_mask(role, condition)
146
- if mask is not None:
119
+ if role is not None:
120
+ role_filter = self.members.has_role(role)
147
121
  return numpy.bincount(
148
- self.members_entity_id[mask],
149
- weights=array[mask],
122
+ self.members_entity_id[role_filter],
123
+ weights=array[role_filter],
150
124
  minlength=self.count,
151
125
  )
152
126
  return numpy.bincount(self.members_entity_id, weights=array)
153
127
 
154
128
  @projectors.projectable
155
- def any(self, array, role=None, condition=None):
129
+ def any(self, array, role=None):
156
130
  """Return ``True`` if ``array`` is ``True`` for any members of the entity.
157
131
 
158
132
  ``array`` must have the dimension of the number of persons in the simulation
159
133
 
160
134
  If ``role`` is provided, only the entity member with the given role are taken into account.
161
135
 
162
- If ``condition`` is provided (a boolean array of the same size as the
163
- person population), only members for whom the condition is ``True`` are
164
- taken into account. ``role`` and ``condition`` can be combined.
165
-
166
136
  Example:
167
137
  >>> salaries = household.members(
168
138
  ... "salary", "2018-01"
@@ -171,18 +141,16 @@ class GroupPopulation(Population):
171
141
  >>> array([True])
172
142
 
173
143
  """
174
- sum_in_entity = self.sum(array, role=role, condition=condition)
144
+ sum_in_entity = self.sum(array, role=role)
175
145
  return sum_in_entity > 0
176
146
 
177
147
  @projectors.projectable
178
- def reduce(self, array, reducer, neutral_element, role=None, condition=None):
148
+ def reduce(self, array, reducer, neutral_element, role=None):
179
149
  self.members.check_array_compatible_with_entity(array)
180
150
  self.entity.check_role_validity(role)
181
151
  position_in_entity = self.members_position
182
- mask = self._build_member_mask(role, condition)
183
- if mask is None:
184
- mask = True # scalar True broadcasts; preserves old upcast behavior
185
- filtered_array = numpy.where(mask, array, neutral_element)
152
+ role_filter = self.members.has_role(role) if role is not None else True
153
+ filtered_array = numpy.where(role_filter, array, neutral_element)
186
154
 
187
155
  result = self.filled_array(
188
156
  neutral_element,
@@ -199,17 +167,13 @@ class GroupPopulation(Population):
199
167
  return result
200
168
 
201
169
  @projectors.projectable
202
- def all(self, array, role=None, condition=None):
170
+ def all(self, array, role=None):
203
171
  """Return ``True`` if ``array`` is ``True`` for all members of the entity.
204
172
 
205
173
  ``array`` must have the dimension of the number of persons in the simulation
206
174
 
207
175
  If ``role`` is provided, only the entity member with the given role are taken into account.
208
176
 
209
- If ``condition`` is provided (a boolean array of the same size as the
210
- person population), only members for whom the condition is ``True`` are
211
- taken into account. ``role`` and ``condition`` can be combined.
212
-
213
177
  Example:
214
178
  >>> salaries = household.members(
215
179
  ... "salary", "2018-01"
@@ -223,21 +187,16 @@ class GroupPopulation(Population):
223
187
  reducer=numpy.logical_and,
224
188
  neutral_element=True,
225
189
  role=role,
226
- condition=condition,
227
190
  )
228
191
 
229
192
  @projectors.projectable
230
- def max(self, array, role=None, condition=None):
193
+ def max(self, array, role=None):
231
194
  """Return the maximum value of ``array`` for the entity members.
232
195
 
233
196
  ``array`` must have the dimension of the number of persons in the simulation
234
197
 
235
198
  If ``role`` is provided, only the entity member with the given role are taken into account.
236
199
 
237
- If ``condition`` is provided (a boolean array of the same size as the
238
- person population), only members for whom the condition is ``True`` are
239
- taken into account. ``role`` and ``condition`` can be combined.
240
-
241
200
  Example:
242
201
  >>> salaries = household.members(
243
202
  ... "salary", "2018-01"
@@ -251,21 +210,16 @@ class GroupPopulation(Population):
251
210
  reducer=numpy.maximum,
252
211
  neutral_element=-numpy.inf,
253
212
  role=role,
254
- condition=condition,
255
213
  )
256
214
 
257
215
  @projectors.projectable
258
- def min(self, array, role=None, condition=None):
216
+ def min(self, array, role=None):
259
217
  """Return the minimum value of ``array`` for the entity members.
260
218
 
261
219
  ``array`` must have the dimension of the number of persons in the simulation
262
220
 
263
221
  If ``role`` is provided, only the entity member with the given role are taken into account.
264
222
 
265
- If ``condition`` is provided (a boolean array of the same size as the
266
- person population), only members for whom the condition is ``True`` are
267
- taken into account. ``role`` and ``condition`` can be combined.
268
-
269
223
  Example:
270
224
  >>> salaries = household.members(
271
225
  ... "salary", "2018-01"
@@ -283,18 +237,13 @@ class GroupPopulation(Population):
283
237
  reducer=numpy.minimum,
284
238
  neutral_element=numpy.inf,
285
239
  role=role,
286
- condition=condition,
287
240
  )
288
241
 
289
242
  @projectors.projectable
290
- def nb_persons(self, role=None, condition=None):
243
+ def nb_persons(self, role=None):
291
244
  """Returns the number of persons contained in the entity.
292
245
 
293
246
  If ``role`` is provided, only the entity member with the given role are taken into account.
294
-
295
- If ``condition`` is provided (a boolean array of the same size as the
296
- person population), only members for whom the condition is ``True`` are
297
- counted. ``role`` and ``condition`` can be combined.
298
247
  """
299
248
  if role:
300
249
  if role.subroles:
@@ -303,9 +252,7 @@ class GroupPopulation(Population):
303
252
  )
304
253
  else:
305
254
  role_condition = self.members_role == role
306
- return self.sum(role_condition, condition=condition)
307
- if condition is not None:
308
- return self.sum(condition.astype(float)).astype(int)
255
+ return self.sum(role_condition)
309
256
  return numpy.bincount(self.members_entity_id)
310
257
 
311
258
  # Projection person -> entity
@@ -24,9 +24,6 @@ class Population(CorePopulation):
24
24
  return result
25
25
 
26
26
  def __getattr__(self, attribute: str) -> projectors.Projector:
27
- if hasattr(self, "links") and attribute in self.links:
28
- return self.links[attribute]
29
-
30
27
  projector: projectors.Projector | None
31
28
  projector = projectors.get_projector_from_shortcut(self, attribute)
32
29
 
@@ -114,10 +111,11 @@ class Population(CorePopulation):
114
111
 
115
112
  """
116
113
  # If entity is for instance 'person.household', we get the reference entity 'household' behind the projector
117
- if isinstance(entity, projectors.Projector):
118
- entity = entity.reference_entity
119
- elif hasattr(entity, "_target_population"): # Handle new Link system
120
- entity = entity._target_population
114
+ entity = (
115
+ entity
116
+ if not isinstance(entity, projectors.Projector)
117
+ else entity.reference_entity
118
+ )
121
119
 
122
120
  positions = entity.members_position
123
121
  biggest_entity_size = numpy.max(positions) + 1
@@ -117,7 +117,10 @@ class ReformExcelTemplateGenerator:
117
117
  for threshold, val in zip(value.thresholds, threshold_values):
118
118
  values.append((f"{name}.{threshold}", val))
119
119
  else:
120
- values.append((name, value))
120
+ if isinstance(value, list):
121
+ values.append((name, ", ".join(value)))
122
+ else:
123
+ values.append((name, value))
121
124
  return sorted(values, key=lambda v: v[0])
122
125
 
123
126
  def parameter_data(self) -> list[tuple[str, float]]:
@@ -212,7 +215,16 @@ class ReformExcel(Reform):
212
215
  )
213
216
  )
214
217
  else:
215
- leaf.update(start=date_, value=value)
218
+ if "unit" in leaf.metadata and leaf.metadata["unit"] == "list":
219
+ if value is None:
220
+ leaf.update(start=date_, value=[])
221
+ else:
222
+ values = [
223
+ p.replace(",", "").strip() for p in value.split(" ")
224
+ ]
225
+ leaf.update(start=date_, value=[v for v in values if v])
226
+ else:
227
+ leaf.update(start=date_, value=value)
216
228
 
217
229
  for leaf, threshold in params_with_thresholds.values():
218
230
  sorted_brackets = [v[1] for v in sorted(threshold, key=lambda x: x[0])]
@@ -30,7 +30,6 @@ class _BuildDefaultSimulation:
30
30
  ... .add_count()
31
31
  ... .add_ids()
32
32
  ... .add_members_entity_id()
33
- ... .add_id_to_rownum()
34
33
  ... )
35
34
 
36
35
  >>> builder.count
@@ -122,16 +121,6 @@ class _BuildDefaultSimulation:
122
121
 
123
122
  return self
124
123
 
125
- def add_id_to_rownum(self) -> Self:
126
- """Set identity id_to_rownum mapping on all populations.
127
-
128
- For static simulations, each entity's permanent ID equals its row
129
- position, so id_to_rownum is the identity: id_to_rownum[i] = i.
130
- """
131
- for population in self.populations.values():
132
- population._id_to_rownum = numpy.arange(self.count, dtype=numpy.intp)
133
- return self
134
-
135
124
  def add_members_entity_id(self) -> Self:
136
125
  """Add ???
137
126
 
@@ -47,7 +47,6 @@ class Simulation:
47
47
  self.persons = self.populations[tax_benefit_system.person_entity.key]
48
48
  self.link_to_entities_instances()
49
49
  self.create_shortcuts()
50
- self._resolve_links()
51
50
 
52
51
  self.invalidated_caches = set()
53
52
 
@@ -83,53 +82,6 @@ class Simulation:
83
82
  # create shortcut simulation.person and simulation.household (for instance)
84
83
  setattr(self, population.entity.key, population)
85
84
 
86
- def _resolve_links(self) -> None:
87
- """Attach and resolve all links declared on every entity.
88
-
89
- This also auto-generates implicit links for each GroupEntity:
90
- - A Many2One link on the person entity (e.g. ``person.household``)
91
- - A One2Many link on the group entity (e.g. ``household.members``)
92
-
93
- This is called once at ``__init__`` time, after
94
- ``link_to_entities_instances`` and ``create_shortcuts``.
95
- """
96
- from openfisca_core.links.implicit import (
97
- ImplicitMany2OneLink,
98
- ImplicitOne2ManyLink,
99
- )
100
- from openfisca_core.populations.group_population import GroupPopulation
101
-
102
- person_entity = self.persons.entity
103
-
104
- # Auto-generate implicit links
105
- for population in self.populations.values():
106
- if not isinstance(population, GroupPopulation):
107
- continue
108
- group_key = population.entity.key
109
-
110
- # person -> group (Many2One)
111
- if not person_entity.get_link(group_key):
112
- m2o = ImplicitMany2OneLink(group_key)
113
- person_entity.add_link(m2o)
114
-
115
- # group -> persons (One2Many)
116
- o2m_name = person_entity.plural
117
- if not population.entity.get_link(o2m_name):
118
- o2m = ImplicitOne2ManyLink(o2m_name, group_key)
119
- population.entity.add_link(o2m)
120
-
121
- from copy import copy
122
-
123
- # Attach and resolve all links, making a simulation-local copy
124
- for _key, population in self.populations.items():
125
- entity = population.entity
126
- population.links = {}
127
- for name, link in entity.links.items():
128
- bound_link = copy(link)
129
- bound_link.attach(population)
130
- bound_link.resolve(self.populations)
131
- population.links[name] = bound_link
132
-
133
85
  @property
134
86
  def data_storage_dir(self):
135
87
  """Temporary folder used to store intermediate calculation data in case the memory is saturated."""