OpenFisca-Core 44.3.0__tar.gz → 44.6.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.3.0 → openfisca_core-44.6.0}/CHANGELOG.md +5 -11
  2. {openfisca_core-44.3.0 → openfisca_core-44.6.0/OpenFisca_Core.egg-info}/PKG-INFO +1 -1
  3. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/OpenFisca_Core.egg-info/SOURCES.txt +0 -13
  4. {openfisca_core-44.3.0/OpenFisca_Core.egg-info → openfisca_core-44.6.0}/PKG-INFO +1 -1
  5. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/entities/_core_entity.py +0 -40
  6. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/indexed_enums/enum_array.py +4 -2
  7. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/populations/group_population.py +15 -68
  8. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/populations/population.py +5 -7
  9. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/simulations/simulation.py +0 -48
  10. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/taxscales/abstract_rate_tax_scale.py +1 -1
  11. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/taxscales/abstract_tax_scale.py +2 -2
  12. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/taxscales/tax_scale_like.py +2 -2
  13. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/pyproject.toml +1 -1
  14. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/setup.py +1 -1
  15. openfisca_core-44.3.0/openfisca_core/links/__init__.py +0 -36
  16. openfisca_core-44.3.0/openfisca_core/links/implicit.py +0 -73
  17. openfisca_core-44.3.0/openfisca_core/links/link.py +0 -109
  18. openfisca_core-44.3.0/openfisca_core/links/many2one.py +0 -227
  19. openfisca_core-44.3.0/openfisca_core/links/one2many.py +0 -242
  20. openfisca_core-44.3.0/openfisca_core/links/tests/__init__.py +0 -58
  21. openfisca_core-44.3.0/openfisca_core/links/tests/test_benchmark.py +0 -93
  22. openfisca_core-44.3.0/openfisca_core/links/tests/test_edge_cases.py +0 -467
  23. openfisca_core-44.3.0/openfisca_core/links/tests/test_implicit.py +0 -76
  24. openfisca_core-44.3.0/openfisca_core/links/tests/test_integration.py +0 -192
  25. openfisca_core-44.3.0/openfisca_core/links/tests/test_many2one.py +0 -121
  26. openfisca_core-44.3.0/openfisca_core/links/tests/test_one2many.py +0 -112
  27. openfisca_core-44.3.0/openfisca_core/links/tests/test_one2many_logic.py +0 -398
  28. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/LICENSE +0 -0
  29. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/MANIFEST.in +0 -0
  30. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/OpenFisca_Core.egg-info/dependency_links.txt +0 -0
  31. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/OpenFisca_Core.egg-info/entry_points.txt +0 -0
  32. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/OpenFisca_Core.egg-info/requires.txt +0 -0
  33. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/OpenFisca_Core.egg-info/top_level.txt +0 -0
  34. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/README.md +0 -0
  35. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/__init__.py +0 -0
  36. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/commons/__init__.py +0 -0
  37. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/commons/dummy.py +0 -0
  38. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/commons/formulas.py +0 -0
  39. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/commons/misc.py +0 -0
  40. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/commons/py.typed +0 -0
  41. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/commons/rates.py +0 -0
  42. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/commons/tests/__init__.py +0 -0
  43. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/commons/tests/test_dummy.py +0 -0
  44. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/commons/tests/test_formulas.py +0 -0
  45. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/commons/tests/test_rates.py +0 -0
  46. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/data_storage/__init__.py +0 -0
  47. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/data_storage/in_memory_storage.py +0 -0
  48. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/data_storage/on_disk_storage.py +0 -0
  49. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/data_storage/types.py +0 -0
  50. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/entities/__init__.py +0 -0
  51. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/entities/_description.py +0 -0
  52. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/entities/entity.py +0 -0
  53. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/entities/group_entity.py +0 -0
  54. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/entities/helpers.py +0 -0
  55. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/entities/py.typed +0 -0
  56. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/entities/role.py +0 -0
  57. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/entities/tests/__init__.py +0 -0
  58. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/entities/tests/test_entity.py +0 -0
  59. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/entities/tests/test_group_entity.py +0 -0
  60. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/entities/tests/test_role.py +0 -0
  61. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/entities/types.py +0 -0
  62. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/errors/__init__.py +0 -0
  63. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/errors/cycle_error.py +0 -0
  64. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/errors/empty_argument_error.py +0 -0
  65. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/errors/nan_creation_error.py +0 -0
  66. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/errors/parameter_not_found_error.py +0 -0
  67. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/errors/parameter_parsing_error.py +0 -0
  68. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/errors/period_mismatch_error.py +0 -0
  69. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/errors/situation_parsing_error.py +0 -0
  70. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/errors/spiral_error.py +0 -0
  71. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/errors/variable_name_config_error.py +0 -0
  72. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/errors/variable_not_found_error.py +0 -0
  73. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/experimental/__init__.py +0 -0
  74. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/experimental/_errors.py +0 -0
  75. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/experimental/_memory_config.py +0 -0
  76. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/formula_helpers.py +0 -0
  77. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/holders/__init__.py +0 -0
  78. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/holders/helpers.py +0 -0
  79. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/holders/holder.py +0 -0
  80. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/holders/tests/__init__.py +0 -0
  81. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/holders/tests/test_helpers.py +0 -0
  82. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/holders/types.py +0 -0
  83. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/indexed_enums/__init__.py +0 -0
  84. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/indexed_enums/_enum_type.py +0 -0
  85. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/indexed_enums/_errors.py +0 -0
  86. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/indexed_enums/_guards.py +0 -0
  87. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/indexed_enums/_utils.py +0 -0
  88. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/indexed_enums/config.py +0 -0
  89. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/indexed_enums/enum.py +0 -0
  90. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/indexed_enums/py.typed +0 -0
  91. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/indexed_enums/tests/__init__.py +0 -0
  92. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/indexed_enums/tests/test_enum.py +0 -0
  93. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/indexed_enums/tests/test_enum_array.py +0 -0
  94. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/indexed_enums/types.py +0 -0
  95. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/memory_config.py +0 -0
  96. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/model_api.py +0 -0
  97. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/parameters/__init__.py +0 -0
  98. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/parameters/at_instant_like.py +0 -0
  99. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/parameters/config.py +0 -0
  100. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/parameters/helpers.py +0 -0
  101. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/parameters/parameter.py +0 -0
  102. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/parameters/parameter_at_instant.py +0 -0
  103. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/parameters/parameter_node.py +0 -0
  104. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/parameters/parameter_node_at_instant.py +0 -0
  105. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/parameters/parameter_scale.py +0 -0
  106. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/parameters/parameter_scale_bracket.py +0 -0
  107. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/parameters/values_history.py +0 -0
  108. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/parameters/vectorial_parameter_node_at_instant.py +0 -0
  109. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/periods/__init__.py +0 -0
  110. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/periods/_errors.py +0 -0
  111. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/periods/_parsers.py +0 -0
  112. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/periods/config.py +0 -0
  113. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/periods/date_unit.py +0 -0
  114. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/periods/helpers.py +0 -0
  115. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/periods/instant_.py +0 -0
  116. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/periods/period_.py +0 -0
  117. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/periods/py.typed +0 -0
  118. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/periods/tests/__init__.py +0 -0
  119. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/periods/tests/helpers/__init__.py +0 -0
  120. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/periods/tests/helpers/test_helpers.py +0 -0
  121. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/periods/tests/helpers/test_instant.py +0 -0
  122. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/periods/tests/helpers/test_period.py +0 -0
  123. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/periods/tests/test_instant.py +0 -0
  124. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/periods/tests/test_parsers.py +0 -0
  125. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/periods/tests/test_period.py +0 -0
  126. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/populations/__init__.py +0 -0
  127. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/populations/_core_population.py +0 -0
  128. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/populations/_errors.py +0 -0
  129. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/populations/tests/__init__.py +0 -0
  130. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/populations/tests/test_members_position.py +0 -0
  131. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/populations/types.py +0 -0
  132. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/projectors/__init__.py +0 -0
  133. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/projectors/entity_to_person_projector.py +0 -0
  134. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/projectors/first_person_to_entity_projector.py +0 -0
  135. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/projectors/helpers.py +0 -0
  136. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/projectors/projector.py +0 -0
  137. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/projectors/typing.py +0 -0
  138. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/projectors/unique_role_to_entity_projector.py +0 -0
  139. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/rates.py +0 -0
  140. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/reforms/__init__.py +0 -0
  141. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/reforms/in_yaml_test_reform.py +0 -0
  142. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/reforms/reform.py +0 -0
  143. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/reforms/reform_excel.py +0 -0
  144. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/scripts/__init__.py +0 -0
  145. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/scripts/assets/__init__.py +0 -0
  146. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/scripts/assets/index.html +0 -0
  147. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/scripts/find_placeholders.py +0 -0
  148. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/scripts/measure_numpy_condition_notations.py +0 -0
  149. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/scripts/measure_performances.py +0 -0
  150. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/scripts/measure_performances_fancy_indexing.py +0 -0
  151. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/scripts/migrations/__init__.py +0 -0
  152. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/scripts/migrations/v16_2_to_v17/__init__.py +0 -0
  153. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/scripts/migrations/v16_2_to_v17/legislation.xsd +0 -0
  154. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/scripts/migrations/v16_2_to_v17/xml_to_yaml_country_template.py +0 -0
  155. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/scripts/migrations/v16_2_to_v17/xml_to_yaml_extension_template.py +0 -0
  156. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/scripts/migrations/v24_to_25.py +0 -0
  157. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/scripts/openfisca_command.py +0 -0
  158. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/scripts/remove_fuzzy.py +0 -0
  159. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/scripts/run_test.py +0 -0
  160. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/scripts/simulation_generator.py +0 -0
  161. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/simulation_builder.py +0 -0
  162. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/simulations/__init__.py +0 -0
  163. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/simulations/_build_default_simulation.py +0 -0
  164. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/simulations/_build_from_variables.py +0 -0
  165. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/simulations/_type_guards.py +0 -0
  166. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/simulations/helpers.py +0 -0
  167. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/simulations/simulation_builder.py +0 -0
  168. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/simulations/typing.py +0 -0
  169. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/taxbenefitsystems/__init__.py +0 -0
  170. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/taxbenefitsystems/tax_benefit_system.py +0 -0
  171. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/taxscales/__init__.py +0 -0
  172. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/taxscales/amount_tax_scale_like.py +0 -0
  173. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/taxscales/helpers.py +0 -0
  174. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/taxscales/linear_average_rate_tax_scale.py +0 -0
  175. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/taxscales/marginal_amount_tax_scale.py +0 -0
  176. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/taxscales/marginal_rate_tax_scale.py +0 -0
  177. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/taxscales/rate_tax_scale_like.py +0 -0
  178. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/taxscales/single_amount_tax_scale.py +0 -0
  179. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/tools/__init__.py +0 -0
  180. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/tools/parallel_plugin.py +0 -0
  181. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/tools/simulation_dumper.py +0 -0
  182. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/tools/test_runner.py +0 -0
  183. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/tracers/__init__.py +0 -0
  184. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/tracers/computation_log.py +0 -0
  185. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/tracers/flat_trace.py +0 -0
  186. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/tracers/full_tracer.py +0 -0
  187. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/tracers/performance_log.py +0 -0
  188. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/tracers/simple_tracer.py +0 -0
  189. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/tracers/trace_node.py +0 -0
  190. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/tracers/tracing_parameter_node_at_instant.py +0 -0
  191. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/types.py +0 -0
  192. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/variables/__init__.py +0 -0
  193. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/variables/config.py +0 -0
  194. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/variables/helpers.py +0 -0
  195. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/variables/tests/__init__.py +0 -0
  196. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/variables/tests/test_definition_period.py +0 -0
  197. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/variables/variable.py +0 -0
  198. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/warnings/__init__.py +0 -0
  199. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/warnings/libyaml_warning.py +0 -0
  200. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/warnings/tempfile_warning.py +0 -0
  201. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_web_api/__init__.py +0 -0
  202. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_web_api/app.py +0 -0
  203. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_web_api/errors.py +0 -0
  204. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_web_api/handlers.py +0 -0
  205. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_web_api/loader/__init__.py +0 -0
  206. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_web_api/loader/entities.py +0 -0
  207. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_web_api/loader/parameters.py +0 -0
  208. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_web_api/loader/spec.py +0 -0
  209. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_web_api/loader/tax_benefit_system.py +0 -0
  210. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_web_api/loader/variables.py +0 -0
  211. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_web_api/openAPI.yml +0 -0
  212. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_web_api/scripts/__init__.py +0 -0
  213. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_web_api/scripts/serve.py +0 -0
  214. {openfisca_core-44.3.0 → openfisca_core-44.6.0}/setup.cfg +0 -0
@@ -1,18 +1,12 @@
1
1
  # Changelog
2
2
 
3
- ## 44.3.0
3
+ ## 44.6.0
4
4
 
5
- #### New Features
6
-
7
- - **Generic Entity Links (Phase 1-6)**: Introduced a new Liam2-inspired generic entity linking system avoiding rigid hierarchies like `Person -> Household`.
8
- - Added new `Many2OneLink` and `One2ManyLink` models to create powerful inter-entity networks (e.g., `Person -> Employer`).
9
- - Added implicit links directly binding members arrays. This powers the new `population.links` property natively inside `TaxBenefitSystem.instantiate_entities()`.
10
- - Full capability to chain relationships via python: `person.mother.household.get("rent", period)`.
11
- - Powerful vectorized declarative aggregations out-of-the-box (e.g., `households.persons.sum("salary", period, condition=is_female)`).
12
-
13
- #### Technical Changes
5
+ #### Technical changes
14
6
 
15
- - Backward compatibility is 100% maintained. Existing syntax via Projectors natively redirects to implicit links via modified `__getattr__`.
7
+ - Revert the codebase to commit `8d26af3` to align the repository with the currently published `44.2.2` baseline on PyPI.
8
+ - Mark versions `44.3.0`, `44.4.0`, `44.4.1`, and `44.5.0` as yanked.
9
+ - Bump version to `44.6.0` to restore continuous deployment from this reverted baseline.
16
10
 
17
11
  ## 44.2.2
18
12
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: OpenFisca-Core
3
- Version: 44.3.0
3
+ Version: 44.6.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.3.0
3
+ Version: 44.6.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,
@@ -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
@@ -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
@@ -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."""
@@ -36,7 +36,7 @@ class AbstractRateTaxScale(RateTaxScaleLike):
36
36
  tax_base: NumericalArray,
37
37
  right: bool,
38
38
  ) -> typing.NoReturn:
39
- msg = f"Method 'calc' is not implemented for {self.__class__.__name__}"
39
+ msg = "Method 'calc' is not implemented for " f"{self.__class__.__name__}"
40
40
  raise NotImplementedError(
41
41
  msg,
42
42
  )
@@ -32,7 +32,7 @@ class AbstractTaxScale(TaxScaleLike):
32
32
  super().__init__(name, option, unit)
33
33
 
34
34
  def __repr__(self) -> typing.NoReturn:
35
- msg = f"Method '__repr__' is not implemented for {self.__class__.__name__}"
35
+ msg = "Method '__repr__' is not implemented for " f"{self.__class__.__name__}"
36
36
  raise NotImplementedError(
37
37
  msg,
38
38
  )
@@ -42,7 +42,7 @@ class AbstractTaxScale(TaxScaleLike):
42
42
  tax_base: NumericalArray,
43
43
  right: bool,
44
44
  ) -> typing.NoReturn:
45
- msg = f"Method 'calc' is not implemented for {self.__class__.__name__}"
45
+ msg = "Method 'calc' is not implemented for " f"{self.__class__.__name__}"
46
46
  raise NotImplementedError(
47
47
  msg,
48
48
  )
@@ -36,13 +36,13 @@ class TaxScaleLike(abc.ABC):
36
36
  self.thresholds = []
37
37
 
38
38
  def __eq__(self, _other: object) -> typing.NoReturn:
39
- msg = f"Method '__eq__' is not implemented for {self.__class__.__name__}"
39
+ msg = "Method '__eq__' is not implemented for " f"{self.__class__.__name__}"
40
40
  raise NotImplementedError(
41
41
  msg,
42
42
  )
43
43
 
44
44
  def __ne__(self, _other: object) -> typing.NoReturn:
45
- msg = f"Method '__ne__' is not implemented for {self.__class__.__name__}"
45
+ msg = "Method '__ne__' is not implemented for " f"{self.__class__.__name__}"
46
46
  raise NotImplementedError(
47
47
  msg,
48
48
  )
@@ -11,4 +11,4 @@ ignore-words-list = [
11
11
  "impot",
12
12
  "treshold",
13
13
  ]
14
- skip = "./venv,./docs/implementation"
14
+ skip = "./venv"
@@ -84,7 +84,7 @@ dev_requirements = [
84
84
 
85
85
  setup(
86
86
  name="OpenFisca-Core",
87
- version="44.3.0",
87
+ version="44.6.0",
88
88
  author="OpenFisca Team",
89
89
  author_email="contact@openfisca.org",
90
90
  classifiers=[
@@ -1,36 +0,0 @@
1
- """Links between entities (Many2One, One2Many, chaining).
2
-
3
- This module implements a generic link system inspired by LIAM2, enriched
4
- with OpenFisca's role semantics. Links are orthogonal to the existing
5
- GroupEntity/Projector machinery: current code keeps working unchanged,
6
- and links provide additional capabilities (intra-entity links, chaining,
7
- arbitrary named links).
8
-
9
- Usage in a country package::
10
-
11
- from openfisca_core.links import Many2OneLink, One2ManyLink
12
-
13
- # Declare a person→person link (intra-entity)
14
- mother = Many2OneLink(
15
- name="mother",
16
- link_field="mother_id",
17
- target_entity_key="person",
18
- )
19
-
20
- # Declare a person→employer link (inter-entity)
21
- employer = Many2OneLink(
22
- name="employer",
23
- link_field="employer_id",
24
- target_entity_key="employer",
25
- )
26
- """
27
-
28
- from .link import Link
29
- from .many2one import Many2OneLink
30
- from .one2many import One2ManyLink
31
-
32
- __all__ = [
33
- "Link",
34
- "Many2OneLink",
35
- "One2ManyLink",
36
- ]
@@ -1,73 +0,0 @@
1
- """Implicit links dynamically inferred from OpenFisca's GroupPopulation system."""
2
-
3
- from __future__ import annotations
4
-
5
- import numpy
6
-
7
- from .many2one import Many2OneLink
8
- from .one2many import One2ManyLink
9
-
10
-
11
- class ImplicitMany2OneLink(Many2OneLink):
12
- """A person → group link using GroupPopulation's internal arrays.
13
-
14
- This bypasses the usual Variable lookup (``simulation.calculate``)
15
- and directly reads ``members_entity_id`` and ``members_role`` from
16
- the target GroupPopulation.
17
- """
18
-
19
- def __init__(self, group_entity_key: str):
20
- super().__init__(
21
- name=group_entity_key,
22
- link_field="", # Not used
23
- target_entity_key=group_entity_key,
24
- )
25
-
26
- def _get_target_ids(self, period) -> numpy.ndarray:
27
- return self._target_population.members_entity_id
28
-
29
- @property
30
- def role(self) -> numpy.ndarray | None:
31
- return self._target_population.members_role
32
-
33
- def _project_implicit(self, result: numpy.ndarray) -> numpy.ndarray:
34
- # Fully compatible with old Projector logic
35
- return self._target_population.project(result)
36
-
37
-
38
- class ImplicitOne2ManyLink(One2ManyLink):
39
- """A group → person link using GroupPopulation's internal arrays."""
40
-
41
- def __init__(self, name: str, group_entity_key: str):
42
- super().__init__(
43
- name=name,
44
- link_field="", # Not used
45
- target_entity_key="person", # The target of the O2M is persons
46
- )
47
- self._group_entity_key = group_entity_key
48
-
49
- def _source_rows(self, period) -> numpy.ndarray:
50
- # For a group->person O2M, the source is the group, the target is the person.
51
- # members_entity_id is an array of length person.count, containing the group index.
52
- # So members_entity_id IS the array of source rows for each target member.
53
- return self._source_population.members_entity_id
54
-
55
- def _apply_filters(self, period, values, role, condition):
56
- source_rows = self._source_rows(period)
57
- mask = numpy.ones(len(source_rows), dtype=bool)
58
-
59
- if role is not None:
60
- roles = self._source_population.members_role
61
- mask &= roles == role
62
-
63
- if condition is not None:
64
- mask &= condition
65
-
66
- source_rows = source_rows[mask]
67
- values = values[mask]
68
-
69
- valid = source_rows >= 0
70
- return source_rows[valid], values[valid]
71
-
72
-
73
- __all__ = ["ImplicitMany2OneLink", "ImplicitOne2ManyLink"]