metricflow 0.206.0.dev1__tar.gz → 0.206.0.dev2__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 (261) hide show
  1. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/PKG-INFO +1 -1
  2. metricflow-0.206.0.dev2/metricflow/test_helpers.py +204 -0
  3. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/pyproject.toml +1 -1
  4. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/.gitattributes +0 -0
  5. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/.gitignore +0 -0
  6. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/CHANGELOG.md +0 -0
  7. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/GLOSSARY.md +0 -0
  8. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/LICENSE +0 -0
  9. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/README.md +0 -0
  10. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/TENETS.md +0 -0
  11. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/assets/MetricFlow_logo.png +0 -0
  12. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/assets/example_plan.svg +0 -0
  13. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/attribution.md +0 -0
  14. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/__init__.py +0 -0
  15. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/aggregation_properties.py +0 -0
  16. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/assert_one_arg.py +0 -0
  17. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/collection_helpers/__init__.py +0 -0
  18. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/collection_helpers/merger.py +0 -0
  19. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/dag/__init__.py +0 -0
  20. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/dag/dag_to_text.py +0 -0
  21. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/dag/dag_visualization.py +0 -0
  22. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/dag/id_prefix.py +0 -0
  23. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/dag/mf_dag.py +0 -0
  24. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/dag/sequential_id.py +0 -0
  25. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/dataflow/__init__.py +0 -0
  26. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/dataflow/builder/__init__.py +0 -0
  27. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/dataflow/builder/dataflow_plan_builder.py +0 -0
  28. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/dataflow/builder/measure_additiveness.py +0 -0
  29. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/dataflow/builder/node_data_set.py +0 -0
  30. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/dataflow/builder/node_evaluator.py +0 -0
  31. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/dataflow/builder/partitions.py +0 -0
  32. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/dataflow/builder/source_node.py +0 -0
  33. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/dataflow/dataflow_plan.py +0 -0
  34. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/dataflow/nodes/__init__.py +0 -0
  35. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/dataflow/nodes/add_generated_uuid.py +0 -0
  36. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/dataflow/nodes/aggregate_measures.py +0 -0
  37. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/dataflow/nodes/combine_aggregated_outputs.py +0 -0
  38. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/dataflow/nodes/compute_metrics.py +0 -0
  39. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/dataflow/nodes/constrain_time.py +0 -0
  40. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/dataflow/nodes/filter_elements.py +0 -0
  41. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/dataflow/nodes/join_conversion_events.py +0 -0
  42. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/dataflow/nodes/join_over_time.py +0 -0
  43. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/dataflow/nodes/join_to_base.py +0 -0
  44. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/dataflow/nodes/join_to_time_spine.py +0 -0
  45. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/dataflow/nodes/metric_time_transform.py +0 -0
  46. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/dataflow/nodes/min_max.py +0 -0
  47. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/dataflow/nodes/order_by_limit.py +0 -0
  48. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/dataflow/nodes/read_sql_source.py +0 -0
  49. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/dataflow/nodes/semi_additive_join.py +0 -0
  50. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/dataflow/nodes/where_filter.py +0 -0
  51. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/dataflow/nodes/write_to_dataframe.py +0 -0
  52. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/dataflow/nodes/write_to_table.py +0 -0
  53. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/dataflow/optimizer/__init__.py +0 -0
  54. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/dataflow/optimizer/dataflow_plan_optimizer.py +0 -0
  55. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/dataflow/optimizer/source_scan/__init__.py +0 -0
  56. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/dataflow/optimizer/source_scan/cm_branch_combiner.py +0 -0
  57. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/dataflow/optimizer/source_scan/matching_linkable_specs.py +0 -0
  58. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/dataflow/optimizer/source_scan/source_scan_optimizer.py +0 -0
  59. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/dataset/__init__.py +0 -0
  60. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/dataset/convert_semantic_model.py +0 -0
  61. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/dataset/dataset.py +0 -0
  62. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/dataset/semantic_model_adapter.py +0 -0
  63. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/dataset/sql_dataset.py +0 -0
  64. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/engine/__init__.py +0 -0
  65. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/engine/metricflow_engine.py +0 -0
  66. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/engine/models.py +0 -0
  67. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/engine/time_source.py +0 -0
  68. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/errors/__init__.py +0 -0
  69. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/errors/errors.py +0 -0
  70. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/execution/__init__.py +0 -0
  71. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/execution/execution_plan.py +0 -0
  72. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/execution/executor.py +0 -0
  73. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/filters/__init__.py +0 -0
  74. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/filters/merge_where.py +0 -0
  75. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/filters/time_constraint.py +0 -0
  76. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/inference/__init__.py +0 -0
  77. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/inference/context/__init__.py +0 -0
  78. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/inference/context/base.py +0 -0
  79. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/inference/context/data_warehouse.py +0 -0
  80. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/inference/context/snowflake.py +0 -0
  81. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/inference/models.py +0 -0
  82. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/inference/renderer/__init__.py +0 -0
  83. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/inference/renderer/base.py +0 -0
  84. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/inference/renderer/config_file.py +0 -0
  85. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/inference/renderer/stream.py +0 -0
  86. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/inference/rule/base.py +0 -0
  87. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/inference/rule/defaults.py +0 -0
  88. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/inference/rule/rules.py +0 -0
  89. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/inference/runner.py +0 -0
  90. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/inference/solver/__init__.py +0 -0
  91. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/inference/solver/base.py +0 -0
  92. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/inference/solver/weighted_tree.py +0 -0
  93. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/instances.py +0 -0
  94. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/mf_logging/__init__.py +0 -0
  95. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/mf_logging/formatting.py +0 -0
  96. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/mf_logging/pretty_print.py +0 -0
  97. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/mf_logging/runtime.py +0 -0
  98. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/model/__init__.py +0 -0
  99. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/model/data_warehouse_model_validator.py +0 -0
  100. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/model/dbt_manifest_parser.py +0 -0
  101. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/model/graph.py +0 -0
  102. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/model/object_to_reference.py +0 -0
  103. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/model/semantic_manifest_lookup.py +0 -0
  104. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/model/semantics/__init__.py +0 -0
  105. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/model/semantics/element_group.py +0 -0
  106. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/model/semantics/linkable_element_properties.py +0 -0
  107. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/model/semantics/linkable_spec_resolver.py +0 -0
  108. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/model/semantics/metric_lookup.py +0 -0
  109. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/model/semantics/semantic_model_container.py +0 -0
  110. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/model/semantics/semantic_model_join_evaluator.py +0 -0
  111. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/model/semantics/semantic_model_lookup.py +0 -0
  112. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/model/spec_converters.py +0 -0
  113. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/model/transformations/__init__.py +0 -0
  114. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/model/transformations/dedupe_metric_input_measures.py +0 -0
  115. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/naming/__init__.py +0 -0
  116. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/naming/dunder_scheme.py +0 -0
  117. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/naming/linkable_spec_name.py +0 -0
  118. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/naming/metric_scheme.py +0 -0
  119. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/naming/naming_scheme.py +0 -0
  120. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/naming/object_builder_scheme.py +0 -0
  121. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/naming/object_builder_str.py +0 -0
  122. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/plan_conversion/__init__.py +0 -0
  123. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/plan_conversion/column_resolver.py +0 -0
  124. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/plan_conversion/convert_to_execution_plan.py +0 -0
  125. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/plan_conversion/convert_to_sql_plan.py +0 -0
  126. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/plan_conversion/dataflow_to_execution.py +0 -0
  127. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/plan_conversion/dataflow_to_sql.py +0 -0
  128. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/plan_conversion/instance_converters.py +0 -0
  129. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/plan_conversion/node_processor.py +0 -0
  130. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/plan_conversion/select_column_gen.py +0 -0
  131. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/plan_conversion/spec_transforms.py +0 -0
  132. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/plan_conversion/sql_expression_builders.py +0 -0
  133. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/plan_conversion/sql_join_builder.py +0 -0
  134. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/plan_conversion/time_spine.py +0 -0
  135. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/protocols/__init__.py +0 -0
  136. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/protocols/query_parameter.py +0 -0
  137. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/protocols/semantics.py +0 -0
  138. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/protocols/sql_client.py +0 -0
  139. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/py.typed +0 -0
  140. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/query/__init__.py +0 -0
  141. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/query/group_by_item/__init__.py +0 -0
  142. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/query/group_by_item/candidate_push_down/__init__.py +0 -0
  143. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/query/group_by_item/candidate_push_down/group_by_item_candidate.py +0 -0
  144. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/query/group_by_item/candidate_push_down/push_down_visitor.py +0 -0
  145. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/query/group_by_item/filter_spec_resolution/__init__.py +0 -0
  146. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/query/group_by_item/filter_spec_resolution/filter_location.py +0 -0
  147. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/query/group_by_item/filter_spec_resolution/filter_pattern_factory.py +0 -0
  148. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/query/group_by_item/filter_spec_resolution/filter_spec_lookup.py +0 -0
  149. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/query/group_by_item/filter_spec_resolution/filter_spec_resolver.py +0 -0
  150. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/query/group_by_item/group_by_item_resolver.py +0 -0
  151. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/query/group_by_item/path_prefixable.py +0 -0
  152. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/query/group_by_item/resolution_dag/__init__.py +0 -0
  153. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/query/group_by_item/resolution_dag/dag.py +0 -0
  154. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/query/group_by_item/resolution_dag/dag_builder.py +0 -0
  155. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/query/group_by_item/resolution_dag/input_metric_location.py +0 -0
  156. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/query/group_by_item/resolution_dag/resolution_nodes/__init__.py +0 -0
  157. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/query/group_by_item/resolution_dag/resolution_nodes/base_node.py +0 -0
  158. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/query/group_by_item/resolution_dag/resolution_nodes/measure_source_node.py +0 -0
  159. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/query/group_by_item/resolution_dag/resolution_nodes/metric_resolution_node.py +0 -0
  160. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/query/group_by_item/resolution_dag/resolution_nodes/no_metrics_query_source_node.py +0 -0
  161. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/query/group_by_item/resolution_dag/resolution_nodes/query_resolution_node.py +0 -0
  162. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/query/group_by_item/resolution_path.py +0 -0
  163. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/query/issues/__init__.py +0 -0
  164. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/query/issues/filter_spec_resolver/__init__.py +0 -0
  165. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/query/issues/filter_spec_resolver/invalid_where.py +0 -0
  166. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/query/issues/group_by_item_resolver/__init__.py +0 -0
  167. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/query/issues/group_by_item_resolver/ambiguous_group_by_item.py +0 -0
  168. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/query/issues/group_by_item_resolver/invalid_use_of_date_part.py +0 -0
  169. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/query/issues/group_by_item_resolver/multiple_join_paths.py +0 -0
  170. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/query/issues/group_by_item_resolver/no_common_items.py +0 -0
  171. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/query/issues/group_by_item_resolver/no_matching_items_for_measure.py +0 -0
  172. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/query/issues/group_by_item_resolver/no_matching_items_for_no_metrics_query.py +0 -0
  173. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/query/issues/group_by_item_resolver/no_parent_candidates.py +0 -0
  174. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/query/issues/issues_base.py +0 -0
  175. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/query/issues/parsing/__init__.py +0 -0
  176. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/query/issues/parsing/cumulative_metric_requires_metric_time.py +0 -0
  177. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/query/issues/parsing/duplicate_metric.py +0 -0
  178. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/query/issues/parsing/invalid_limit.py +0 -0
  179. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/query/issues/parsing/invalid_metric.py +0 -0
  180. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/query/issues/parsing/invalid_min_max_only.py +0 -0
  181. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/query/issues/parsing/invalid_order.py +0 -0
  182. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/query/issues/parsing/no_metric_or_group_by.py +0 -0
  183. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/query/issues/parsing/offset_metric_requires_metric_time.py +0 -0
  184. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/query/issues/parsing/string_input_parsing_issue.py +0 -0
  185. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/query/query_exceptions.py +0 -0
  186. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/query/query_parser.py +0 -0
  187. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/query/query_resolution.py +0 -0
  188. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/query/query_resolver.py +0 -0
  189. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/query/resolver_inputs/__init__.py +0 -0
  190. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/query/resolver_inputs/base_resolver_inputs.py +0 -0
  191. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/query/resolver_inputs/query_resolver_inputs.py +0 -0
  192. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/query/similarity.py +0 -0
  193. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/query/suggestion_generator.py +0 -0
  194. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/query/validation_rules/__init__.py +0 -0
  195. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/query/validation_rules/base_validation_rule.py +0 -0
  196. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/query/validation_rules/duplicate_metric.py +0 -0
  197. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/query/validation_rules/metric_time_requirements.py +0 -0
  198. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/query/validation_rules/query_validator.py +0 -0
  199. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/random_id.py +0 -0
  200. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/specs/__init__.py +0 -0
  201. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/specs/column_assoc.py +0 -0
  202. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/specs/dimension_spec_resolver.py +0 -0
  203. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/specs/patterns/__init__.py +0 -0
  204. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/specs/patterns/base_time_grain.py +0 -0
  205. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/specs/patterns/entity_link_pattern.py +0 -0
  206. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/specs/patterns/match_list_pattern.py +0 -0
  207. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/specs/patterns/metric_pattern.py +0 -0
  208. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/specs/patterns/metric_time_pattern.py +0 -0
  209. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/specs/patterns/none_date_part.py +0 -0
  210. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/specs/patterns/spec_pattern.py +0 -0
  211. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/specs/patterns/typed_patterns.py +0 -0
  212. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/specs/python_object.py +0 -0
  213. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/specs/query_param_implementations.py +0 -0
  214. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/specs/rendered_spec_tracker.py +0 -0
  215. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/specs/spec_set_transforms.py +0 -0
  216. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/specs/specs.py +0 -0
  217. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/specs/where_filter_dimension.py +0 -0
  218. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/specs/where_filter_entity.py +0 -0
  219. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/specs/where_filter_metric.py +0 -0
  220. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/specs/where_filter_time_dimension.py +0 -0
  221. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/specs/where_filter_transform.py +0 -0
  222. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/sql/__init__.py +0 -0
  223. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/sql/optimizer/__init__.py +0 -0
  224. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/sql/optimizer/column_pruner.py +0 -0
  225. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/sql/optimizer/optimization_levels.py +0 -0
  226. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/sql/optimizer/rewriting_sub_query_reducer.py +0 -0
  227. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/sql/optimizer/sql_query_plan_optimizer.py +0 -0
  228. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/sql/optimizer/sub_query_reducer.py +0 -0
  229. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/sql/optimizer/table_alias_simplifier.py +0 -0
  230. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/sql/render/__init__.py +0 -0
  231. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/sql/render/big_query.py +0 -0
  232. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/sql/render/databricks.py +0 -0
  233. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/sql/render/duckdb_renderer.py +0 -0
  234. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/sql/render/expr_renderer.py +0 -0
  235. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/sql/render/postgres.py +0 -0
  236. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/sql/render/redshift.py +0 -0
  237. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/sql/render/rendering_constants.py +0 -0
  238. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/sql/render/snowflake.py +0 -0
  239. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/sql/render/sql_plan_renderer.py +0 -0
  240. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/sql/render/trino.py +0 -0
  241. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/sql/sql_bind_parameters.py +0 -0
  242. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/sql/sql_column.py +0 -0
  243. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/sql/sql_column_type.py +0 -0
  244. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/sql/sql_exprs.py +0 -0
  245. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/sql/sql_plan.py +0 -0
  246. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/sql/sql_table.py +0 -0
  247. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/sql_request/__init__.py +0 -0
  248. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/sql_request/sql_request_attributes.py +0 -0
  249. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/telemetry/__init__.py +0 -0
  250. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/telemetry/handlers/__init__.py +0 -0
  251. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/telemetry/handlers/handlers.py +0 -0
  252. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/telemetry/handlers/python_log.py +0 -0
  253. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/telemetry/models.py +0 -0
  254. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/telemetry/reporter.py +0 -0
  255. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/time/__init__.py +0 -0
  256. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/time/time_constants.py +0 -0
  257. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/time/time_granularity.py +0 -0
  258. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/time/time_source.py +0 -0
  259. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/metricflow/visitor.py +0 -0
  260. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/mypy.ini +0 -0
  261. {metricflow-0.206.0.dev1 → metricflow-0.206.0.dev2}/ruff.toml +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: metricflow
3
- Version: 0.206.0.dev1
3
+ Version: 0.206.0.dev2
4
4
  Summary: Translates a simple metric definition into reusable SQL and executes it against the SQL engine of your choice.
5
5
  Project-URL: Documentation, https://transform.co/metricflow
6
6
  Project-URL: Source Code, https://github.com/transform-data/metricflow
@@ -0,0 +1,204 @@
1
+ from __future__ import annotations
2
+
3
+ import datetime
4
+ import difflib
5
+ import logging
6
+ import os
7
+ import re
8
+ import webbrowser
9
+ from dataclasses import dataclass
10
+ from typing import Callable, List, Optional, Tuple
11
+
12
+ import _pytest
13
+ import _pytest.fixtures
14
+
15
+ from metricflow.time.time_source import TimeSource
16
+
17
+ logger = logging.getLogger(__name__)
18
+
19
+ DISPLAY_SNAPSHOTS_CLI_FLAG = "--display-snapshots"
20
+ OVERWRITE_SNAPSHOTS_CLI_FLAG = "--overwrite-snapshots"
21
+
22
+
23
+ def add_display_snapshots_cli_flag(parser: _pytest.config.argparsing.Parser) -> None: # noqa: D103
24
+ parser.addoption(DISPLAY_SNAPSHOTS_CLI_FLAG, action="store_true", help="Displays snapshots in a browser if set")
25
+
26
+
27
+ def add_overwrite_snapshots_cli_flag(parser: _pytest.config.argparsing.Parser) -> None: # noqa: D103
28
+ parser.addoption(
29
+ OVERWRITE_SNAPSHOTS_CLI_FLAG,
30
+ action="store_true",
31
+ help="Overwrites existing snapshots by ones generated during this testing session",
32
+ )
33
+
34
+
35
+ @dataclass(frozen=True)
36
+ class SnapshotConfiguration:
37
+ """Configuration for handling snapshots in a test session."""
38
+
39
+ # Whether to display the snapshot associated with a test session in a browser window.
40
+ display_snapshots: bool
41
+ # Whether to overwrite any text files that were generated.
42
+ overwrite_snapshots: bool
43
+
44
+
45
+ @dataclass(frozen=True)
46
+ class MetricFlowTestConfiguration(SnapshotConfiguration):
47
+ """State that is shared between tests during a testing session."""
48
+
49
+ sql_engine_url: str
50
+ sql_engine_password: str
51
+ # Where MF system tables should be stored.
52
+ mf_system_schema: str
53
+ # Where tables for test data sets should be stored.
54
+ mf_source_schema: str
55
+
56
+ # Whether to display the graph associated with a test session in a browser window.
57
+ display_graphs: bool
58
+
59
+ # The source schema contains tables that are used for running tests. If this is set, a source schema in the SQL
60
+ # is created and persisted between runs. The source schema name includes a hash of the tables that should be in
61
+ # the schema, so
62
+ use_persistent_source_schema: bool
63
+
64
+
65
+ def assert_snapshot_text_equal(
66
+ request: _pytest.fixtures.FixtureRequest,
67
+ mf_test_configuration: MetricFlowTestConfiguration,
68
+ group_id: str,
69
+ snapshot_id: str,
70
+ snapshot_text: str,
71
+ snapshot_file_extension: str,
72
+ exclude_line_regex: Optional[str] = None,
73
+ incomparable_strings_replacement_function: Optional[Callable[[str], str]] = None,
74
+ additional_sub_directories_for_snapshots: Tuple[str, ...] = (),
75
+ ) -> None:
76
+ """Similar to assert_plan_snapshot_text_equal(), but with more controls on how the snapshot paths are generated."""
77
+ file_path = (
78
+ snapshot_path_prefix(
79
+ request=request,
80
+ snapshot_group=group_id,
81
+ snapshot_id=snapshot_id,
82
+ additional_sub_directories=additional_sub_directories_for_snapshots,
83
+ )
84
+ + snapshot_file_extension
85
+ )
86
+
87
+ if incomparable_strings_replacement_function is not None:
88
+ snapshot_text = incomparable_strings_replacement_function(snapshot_text)
89
+
90
+ # Add a new line at the end of the file so that PRs don't show the "no newline" symbol on Github.
91
+ if len(snapshot_text) > 1 and snapshot_text[-1] != "\n":
92
+ snapshot_text = snapshot_text + "\n"
93
+
94
+ # If we are in overwrite mode, make a new plan:
95
+ if mf_test_configuration.overwrite_snapshots:
96
+ # Create parent directory for the plan text files.
97
+ os.makedirs(os.path.dirname(file_path), exist_ok=True)
98
+ with open(file_path, "w") as snapshot_text_file:
99
+ snapshot_text_file.write(snapshot_text)
100
+
101
+ # Throw an exception if the plan is not there.
102
+ if not os.path.exists(file_path):
103
+ raise FileNotFoundError(
104
+ f"Could not find snapshot file at path {file_path}. Re-run with --overwrite-snapshots and check git status "
105
+ "to see what's new."
106
+ )
107
+
108
+ if mf_test_configuration.display_snapshots:
109
+ if not mf_test_configuration.overwrite_snapshots:
110
+ logger.warning(f"Not overwriting snapshots, so displaying existing snapshot at {file_path}")
111
+
112
+ if len(request.session.items) > 1:
113
+ raise ValueError("Displaying snapshots is only supported when there's a single item in a testing session.")
114
+ webbrowser.open("file://" + file_path)
115
+
116
+ # Read the existing plan from the file and compare with the actual plan
117
+ with open(file_path, "r") as snapshot_text_file:
118
+ expected_snapshot_text = snapshot_text_file.read()
119
+
120
+ if exclude_line_regex:
121
+ # Filter out lines that should be ignored.
122
+ expected_snapshot_text = _exclude_lines_matching_regex(
123
+ file_contents=expected_snapshot_text, exclude_line_regex=exclude_line_regex
124
+ )
125
+ snapshot_text = _exclude_lines_matching_regex(
126
+ file_contents=snapshot_text, exclude_line_regex=exclude_line_regex
127
+ )
128
+ # pytest should show a detailed diff with "assert actual_modified == expected_modified", but it's not, so doing
129
+ # this instead.
130
+ if snapshot_text != expected_snapshot_text:
131
+ differ = difflib.Differ()
132
+ diff = differ.compare(expected_snapshot_text.splitlines(), snapshot_text.splitlines())
133
+ assert False, f"Snapshot from {file_path} does not match. Diff from expected to actual:\n" + "\n".join(diff)
134
+
135
+
136
+ def snapshot_path_prefix(
137
+ request: _pytest.fixtures.FixtureRequest,
138
+ snapshot_group: str,
139
+ snapshot_id: str,
140
+ additional_sub_directories: Tuple[str, ...] = (),
141
+ ) -> str:
142
+ """Returns a path prefix that can be used to build filenames for files associated with the snapshot.
143
+
144
+ The snapshot prefix is generated from the name of the test file, the name of the test, name of the snapshot class,
145
+ and the name of the snapshot.
146
+
147
+ e.g.
148
+ .../snapshots/test_file.py/DataflowPlan/test_name__plan1
149
+
150
+ which can be used to construct paths like
151
+
152
+ .../snapshots/test_file.py/DataflowPlan/test_name__plan1.xml
153
+ .../snapshots/test_file.py/DataflowPlan/test_name__plan1.svg
154
+ """
155
+ test_name = request.node.name
156
+
157
+ snapshot_file_name_parts = []
158
+ # Parameterized test names look like 'test_case[some_param]'. "[" and "]" are annoying to deal with in the shell,
159
+ # so replace them with dunders.
160
+ snapshot_file_name_parts.extend(re.split(r"[\[\]]", test_name))
161
+ # A trailing ] will produce an empty string in the list, so remove that.
162
+ snapshot_file_name_parts = [part for part in snapshot_file_name_parts if len(part) > 0]
163
+ snapshot_file_name_parts.append(snapshot_id)
164
+
165
+ snapshot_file_name = "__".join(snapshot_file_name_parts)
166
+
167
+ path_items: List[str] = []
168
+
169
+ test_file_path_items = os.path.normpath(request.node.fspath).split(os.sep)
170
+ test_file_name = test_file_path_items[-1]
171
+ # Default to where this is defined, but use more appropriate directories if found.
172
+ test_directory_root_index = -1
173
+ for i, path_item in enumerate(test_file_path_items):
174
+ if path_item in ("tests", "metricflow"):
175
+ test_directory_root_index = i + 1
176
+
177
+ path_to_store_snapshots = os.sep.join(test_file_path_items[:test_directory_root_index])
178
+ path_items.extend([path_to_store_snapshots, "snapshots", test_file_name, snapshot_group])
179
+
180
+ if additional_sub_directories:
181
+ path_items.extend(additional_sub_directories)
182
+ path_items.append(snapshot_file_name)
183
+
184
+ return os.path.abspath(os.path.join(*path_items))
185
+
186
+
187
+ def _exclude_lines_matching_regex(file_contents: str, exclude_line_regex: str) -> str:
188
+ """Removes lines from file contents if the line matches exclude_regex."""
189
+ compiled_regex = re.compile(exclude_line_regex)
190
+ return "\n".join([line for line in file_contents.split("\n") if not compiled_regex.match(line)])
191
+
192
+
193
+ class ConfigurableTimeSource(TimeSource):
194
+ """A time source that can be configured so that scheduled operations can be simulated in testing."""
195
+
196
+ def __init__(self, configured_time: datetime.datetime) -> None: # noqa: D107
197
+ self._configured_time = configured_time
198
+
199
+ def get_time(self) -> datetime.datetime: # noqa: D102
200
+ return self._configured_time
201
+
202
+ def set_time(self, new_time: datetime.datetime) -> datetime.datetime: # noqa: D102
203
+ self._configured_time = new_time
204
+ return new_time
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "metricflow"
7
- version = "0.206.0.dev1"
7
+ version = "0.206.0.dev2"
8
8
  description = "Translates a simple metric definition into reusable SQL and executes it against the SQL engine of your choice."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.8,<3.12"