pylegend 0.12.0__tar.gz → 0.14.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 (182) hide show
  1. {pylegend-0.12.0 → pylegend-0.14.0}/PKG-INFO +1 -1
  2. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/database/sql_to_string/db_extension.py +177 -1
  3. pylegend-0.14.0/pylegend/core/language/pandas_api/pandas_api_groupby_series.py +357 -0
  4. pylegend-0.14.0/pylegend/core/language/pandas_api/pandas_api_series.py +371 -0
  5. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/language/shared/expression.py +5 -0
  6. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/language/shared/literal_expressions.py +22 -1
  7. pylegend-0.14.0/pylegend/core/language/shared/operations/boolean_operation_expressions.py +268 -0
  8. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/language/shared/operations/date_operation_expressions.py +91 -0
  9. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/language/shared/operations/integer_operation_expressions.py +183 -1
  10. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/language/shared/operations/string_operation_expressions.py +31 -1
  11. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/language/shared/primitives/boolean.py +40 -0
  12. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/language/shared/primitives/date.py +39 -0
  13. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/language/shared/primitives/datetime.py +18 -0
  14. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/language/shared/primitives/integer.py +54 -1
  15. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/language/shared/primitives/strictdate.py +25 -1
  16. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/language/shared/primitives/string.py +16 -2
  17. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/sql/metamodel.py +50 -1
  18. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/sql/metamodel_extension.py +77 -1
  19. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/pandas_api/frames/functions/aggregate_function.py +21 -11
  20. pylegend-0.14.0/pylegend/core/tds/pandas_api/frames/functions/iloc.py +99 -0
  21. pylegend-0.14.0/pylegend/core/tds/pandas_api/frames/functions/loc.py +136 -0
  22. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/pandas_api/frames/pandas_api_applied_function_tds_frame.py +3 -0
  23. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/pandas_api/frames/pandas_api_base_tds_frame.py +50 -2
  24. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/pandas_api/frames/pandas_api_groupby_tds_frame.py +87 -27
  25. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/pandas_api/frames/pandas_api_tds_frame.py +12 -0
  26. {pylegend-0.12.0 → pylegend-0.14.0}/pyproject.toml +1 -1
  27. pylegend-0.12.0/pylegend/core/language/pandas_api/pandas_api_series.py +0 -177
  28. pylegend-0.12.0/pylegend/core/language/shared/operations/boolean_operation_expressions.py +0 -124
  29. {pylegend-0.12.0 → pylegend-0.14.0}/LICENSE +0 -0
  30. {pylegend-0.12.0 → pylegend-0.14.0}/LICENSE.spdx +0 -0
  31. {pylegend-0.12.0 → pylegend-0.14.0}/NOTICE +0 -0
  32. {pylegend-0.12.0 → pylegend-0.14.0}/README.md +0 -0
  33. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/__init__.py +0 -0
  34. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/_typing.py +0 -0
  35. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/__init__.py +0 -0
  36. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/database/__init__.py +0 -0
  37. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/database/sql_to_string/__init__.py +0 -0
  38. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/database/sql_to_string/config.py +0 -0
  39. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/database/sql_to_string/generator.py +0 -0
  40. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/language/__init__.py +0 -0
  41. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/language/legacy_api/__init__.py +0 -0
  42. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/language/legacy_api/aggregate_specification.py +0 -0
  43. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/language/legacy_api/legacy_api_tds_row.py +0 -0
  44. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/language/legendql_api/__init__.py +0 -0
  45. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/language/legendql_api/legendql_api_custom_expressions.py +0 -0
  46. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/language/legendql_api/legendql_api_tds_row.py +0 -0
  47. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/language/pandas_api/__init__.py +0 -0
  48. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/language/pandas_api/pandas_api_aggregate_specification.py +0 -0
  49. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/language/pandas_api/pandas_api_custom_expressions.py +0 -0
  50. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/language/pandas_api/pandas_api_tds_row.py +0 -0
  51. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/language/shared/__init__.py +0 -0
  52. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/language/shared/column_expressions.py +0 -0
  53. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/language/shared/functions.py +0 -0
  54. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/language/shared/helpers.py +0 -0
  55. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/language/shared/operations/__init__.py +0 -0
  56. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/language/shared/operations/binary_expression.py +0 -0
  57. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/language/shared/operations/collection_operation_expressions.py +0 -0
  58. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/language/shared/operations/float_operation_expressions.py +0 -0
  59. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/language/shared/operations/nary_expression.py +0 -0
  60. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/language/shared/operations/nullary_expression.py +0 -0
  61. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/language/shared/operations/number_operation_expressions.py +0 -0
  62. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/language/shared/operations/primitive_operation_expressions.py +0 -0
  63. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/language/shared/operations/unary_expression.py +0 -0
  64. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/language/shared/pct_helpers.py +0 -0
  65. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/language/shared/primitive_collection.py +0 -0
  66. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/language/shared/primitives/__init__.py +0 -0
  67. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/language/shared/primitives/float.py +0 -0
  68. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/language/shared/primitives/number.py +0 -0
  69. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/language/shared/primitives/primitive.py +0 -0
  70. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/language/shared/tds_row.py +0 -0
  71. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/project_cooridnates.py +0 -0
  72. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/request/__init__.py +0 -0
  73. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/request/auth.py +0 -0
  74. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/request/legend_client.py +0 -0
  75. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/request/response_reader.py +0 -0
  76. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/request/service_client.py +0 -0
  77. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/sql/__init__.py +0 -0
  78. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/__init__.py +0 -0
  79. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/abstract/__init__.py +0 -0
  80. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/abstract/frames/__init__.py +0 -0
  81. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/abstract/frames/applied_function_tds_frame.py +0 -0
  82. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/abstract/frames/base_tds_frame.py +0 -0
  83. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/abstract/frames/input_tds_frame.py +0 -0
  84. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/abstract/function_helpers.py +0 -0
  85. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/legacy_api/__init__.py +0 -0
  86. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/legacy_api/frames/__init__.py +0 -0
  87. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/legacy_api/frames/functions/__init__.py +0 -0
  88. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/legacy_api/frames/functions/legacy_api_concatenate_function.py +0 -0
  89. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/legacy_api/frames/functions/legacy_api_distinct_function.py +0 -0
  90. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/legacy_api/frames/functions/legacy_api_drop_function.py +0 -0
  91. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/legacy_api/frames/functions/legacy_api_extend_function.py +0 -0
  92. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/legacy_api/frames/functions/legacy_api_filter_function.py +0 -0
  93. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/legacy_api/frames/functions/legacy_api_group_by_function.py +0 -0
  94. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/legacy_api/frames/functions/legacy_api_head_function.py +0 -0
  95. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/legacy_api/frames/functions/legacy_api_join_by_columns_function.py +0 -0
  96. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/legacy_api/frames/functions/legacy_api_join_function.py +0 -0
  97. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/legacy_api/frames/functions/legacy_api_rename_columns_function.py +0 -0
  98. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/legacy_api/frames/functions/legacy_api_restrict_function.py +0 -0
  99. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/legacy_api/frames/functions/legacy_api_slice_function.py +0 -0
  100. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/legacy_api/frames/functions/legacy_api_sort_function.py +0 -0
  101. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/legacy_api/frames/legacy_api_applied_function_tds_frame.py +0 -0
  102. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/legacy_api/frames/legacy_api_base_tds_frame.py +0 -0
  103. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/legacy_api/frames/legacy_api_input_tds_frame.py +0 -0
  104. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/legacy_api/frames/legacy_api_tds_frame.py +0 -0
  105. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/legendql_api/__init__.py +0 -0
  106. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/legendql_api/frames/__init__.py +0 -0
  107. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/legendql_api/frames/functions/__init__.py +0 -0
  108. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/legendql_api/frames/functions/legendql_api_asofjoin_function.py +0 -0
  109. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/legendql_api/frames/functions/legendql_api_concatenate_function.py +0 -0
  110. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/legendql_api/frames/functions/legendql_api_distinct_function.py +0 -0
  111. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/legendql_api/frames/functions/legendql_api_drop_function.py +0 -0
  112. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/legendql_api/frames/functions/legendql_api_extend_function.py +0 -0
  113. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/legendql_api/frames/functions/legendql_api_filter_function.py +0 -0
  114. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/legendql_api/frames/functions/legendql_api_function_helpers.py +0 -0
  115. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/legendql_api/frames/functions/legendql_api_groupby_function.py +0 -0
  116. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/legendql_api/frames/functions/legendql_api_head_function.py +0 -0
  117. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/legendql_api/frames/functions/legendql_api_join_function.py +0 -0
  118. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/legendql_api/frames/functions/legendql_api_project_function.py +0 -0
  119. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/legendql_api/frames/functions/legendql_api_rename_function.py +0 -0
  120. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/legendql_api/frames/functions/legendql_api_select_function.py +0 -0
  121. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/legendql_api/frames/functions/legendql_api_slice_function.py +0 -0
  122. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/legendql_api/frames/functions/legendql_api_sort_function.py +0 -0
  123. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/legendql_api/frames/functions/legendql_api_window_extend_function.py +0 -0
  124. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/legendql_api/frames/legendql_api_applied_function_tds_frame.py +0 -0
  125. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/legendql_api/frames/legendql_api_base_tds_frame.py +0 -0
  126. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/legendql_api/frames/legendql_api_input_tds_frame.py +0 -0
  127. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/legendql_api/frames/legendql_api_tds_frame.py +0 -0
  128. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/pandas_api/__init__.py +0 -0
  129. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/pandas_api/frames/__init__.py +0 -0
  130. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/pandas_api/frames/functions/__init__.py +0 -0
  131. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/pandas_api/frames/functions/assign_function.py +0 -0
  132. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/pandas_api/frames/functions/drop.py +0 -0
  133. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/pandas_api/frames/functions/dropna.py +0 -0
  134. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/pandas_api/frames/functions/fillna.py +0 -0
  135. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/pandas_api/frames/functions/filter.py +0 -0
  136. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/pandas_api/frames/functions/filtering.py +0 -0
  137. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/pandas_api/frames/functions/merge.py +0 -0
  138. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/pandas_api/frames/functions/rename.py +0 -0
  139. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/pandas_api/frames/functions/sort_values_function.py +0 -0
  140. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/pandas_api/frames/functions/truncate_function.py +0 -0
  141. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/pandas_api/frames/pandas_api_input_tds_frame.py +0 -0
  142. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/result_handler/__init__.py +0 -0
  143. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/result_handler/result_handler.py +0 -0
  144. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/result_handler/to_csv_file_result_handler.py +0 -0
  145. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/result_handler/to_json_file_result_handler.py +0 -0
  146. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/result_handler/to_string_result_handler.py +0 -0
  147. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/sql_query_helpers.py +0 -0
  148. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/tds_column.py +0 -0
  149. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/core/tds/tds_frame.py +0 -0
  150. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/extensions/__init__.py +0 -0
  151. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/extensions/database/__init__.py +0 -0
  152. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/extensions/database/vendors/__init__.py +0 -0
  153. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/extensions/database/vendors/postgres/__init__.py +0 -0
  154. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/extensions/database/vendors/postgres/postgres_sql_to_string.py +0 -0
  155. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/extensions/tds/__init__.py +0 -0
  156. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/extensions/tds/abstract/__init__.py +0 -0
  157. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/extensions/tds/abstract/csv_tds_frame.py +0 -0
  158. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/extensions/tds/abstract/legend_function_input_frame.py +0 -0
  159. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/extensions/tds/abstract/legend_service_input_frame.py +0 -0
  160. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/extensions/tds/abstract/table_spec_input_frame.py +0 -0
  161. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/extensions/tds/legacy_api/__init__.py +0 -0
  162. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/extensions/tds/legacy_api/frames/__init__.py +0 -0
  163. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/extensions/tds/legacy_api/frames/legacy_api_legend_function_input_frame.py +0 -0
  164. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/extensions/tds/legacy_api/frames/legacy_api_legend_service_input_frame.py +0 -0
  165. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/extensions/tds/legacy_api/frames/legacy_api_table_spec_input_frame.py +0 -0
  166. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/extensions/tds/legendql_api/__init__.py +0 -0
  167. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/extensions/tds/legendql_api/frames/__init__.py +0 -0
  168. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/extensions/tds/legendql_api/frames/legendql_api_csv_input_frame.py +0 -0
  169. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/extensions/tds/legendql_api/frames/legendql_api_legend_function_input_frame.py +0 -0
  170. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/extensions/tds/legendql_api/frames/legendql_api_legend_service_input_frame.py +0 -0
  171. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/extensions/tds/legendql_api/frames/legendql_api_table_spec_input_frame.py +0 -0
  172. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/extensions/tds/pandas_api/__init__.py +0 -0
  173. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/extensions/tds/pandas_api/frames/__init__.py +0 -0
  174. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/extensions/tds/pandas_api/frames/pandas_api_legend_function_input_frame.py +0 -0
  175. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/extensions/tds/pandas_api/frames/pandas_api_legend_service_input_frame.py +0 -0
  176. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/extensions/tds/pandas_api/frames/pandas_api_table_spec_input_frame.py +0 -0
  177. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/extensions/tds/result_handler/__init__.py +0 -0
  178. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/extensions/tds/result_handler/to_pandas_df_result_handler.py +0 -0
  179. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/legacy_api_tds_client.py +0 -0
  180. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/legendql_api_tds_client.py +0 -0
  181. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/utils/__init__.py +0 -0
  182. {pylegend-0.12.0 → pylegend-0.14.0}/pylegend/utils/class_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pylegend
3
- Version: 0.12.0
3
+ Version: 0.14.0
4
4
  Summary: Python language binding for Legend data management platform
5
5
  License: Apache-2.0
6
6
  License-File: LICENSE
@@ -75,7 +75,11 @@ from pylegend.core.sql.metamodel import (
75
75
  WindowFrame,
76
76
  WindowFrameMode,
77
77
  FrameBound,
78
- FrameBoundType
78
+ FrameBoundType,
79
+ BitwiseShiftExpression,
80
+ BitwiseShiftDirection,
81
+ BitwiseBinaryExpression,
82
+ BitwiseBinaryOperator
79
83
  )
80
84
  from pylegend.core.sql.metamodel_extension import (
81
85
  StringLengthExpression,
@@ -137,6 +141,11 @@ from pylegend.core.sql.metamodel_extension import (
137
141
  WindowExpression,
138
142
  ConstantExpression,
139
143
  StringSubStringExpression,
144
+ DateAdjustExpression,
145
+ BitwiseNotExpression,
146
+ DateDiffExpression,
147
+ DateTimeBucketExpression,
148
+ DateType,
140
149
  )
141
150
 
142
151
  __all__: PyLegendSequence[str] = [
@@ -460,6 +469,18 @@ def expression_processor(
460
469
  return expression.name
461
470
  elif isinstance(expression, StringSubStringExpression):
462
471
  return extension.process_string_substring_expression(expression, config)
472
+ elif isinstance(expression, DateAdjustExpression):
473
+ return extension.process_date_adjust_expression(expression, config)
474
+ elif isinstance(expression, DateDiffExpression):
475
+ return extension.process_date_diff_expression(expression, config)
476
+ elif isinstance(expression, DateTimeBucketExpression):
477
+ return extension.process_date_time_bucket_expression(expression, config)
478
+ elif isinstance(expression, BitwiseNotExpression):
479
+ return extension.process_bitwise_not_expression(expression, config)
480
+ elif isinstance(expression, BitwiseShiftExpression):
481
+ return extension.process_bitwise_shift_expression(expression, config)
482
+ elif isinstance(expression, BitwiseBinaryExpression):
483
+ return extension.process_bitwise_binary_expression(expression, config)
463
484
 
464
485
  else:
465
486
  raise ValueError("Unsupported expression type: " + str(type(expression))) # pragma: no cover
@@ -520,6 +541,139 @@ def logical_binary_expression_processor(
520
541
  return f"({left} {op} {right})"
521
542
 
522
543
 
544
+ def bitwise_binary_expression_processor(
545
+ bitwise: BitwiseBinaryExpression,
546
+ extension: "SqlToStringDbExtension",
547
+ config: SqlToStringConfig
548
+ ) -> str:
549
+ op_type = bitwise.operator
550
+ if op_type == BitwiseBinaryOperator.AND:
551
+ op = "&"
552
+ elif op_type == BitwiseBinaryOperator.OR:
553
+ op = "|"
554
+ elif op_type == BitwiseBinaryOperator.XOR:
555
+ op = "#"
556
+ else:
557
+ raise ValueError("Unknown bitwise binary operator type: " + str(op_type)) # pragma: no cover
558
+
559
+ left = extension.process_expression(bitwise.left, config)
560
+ right = extension.process_expression(bitwise.right, config)
561
+ return f"({left} {op} {right})"
562
+
563
+
564
+ def date_diff_processor(
565
+ date_diff: DateDiffExpression,
566
+ extension: "SqlToStringDbExtension",
567
+ config: SqlToStringConfig
568
+ ) -> str:
569
+ unit = date_diff.duration_unit.value
570
+
571
+ end = extension.process_expression(date_diff.end_date, config)
572
+ start = extension.process_expression(date_diff.start_date, config)
573
+
574
+ def extract_diff(part: str) -> str:
575
+ return f"(EXTRACT({part} FROM {end}) - EXTRACT({part} FROM {start}))"
576
+
577
+ year_diff = extract_diff("YEAR")
578
+ month_diff = extract_diff("MONTH")
579
+ # d1 - d2 → Pure dateDiff(d1, d2) → evaluated as d2 - d1
580
+ # Reverse to preserve expected semantics.
581
+ # only for days
582
+ day_diff = f"CAST(CAST({start} AS DATE) - CAST({end} AS DATE) AS INTEGER)"
583
+ epoch_diff = f"(EXTRACT(EPOCH FROM {end}) - EXTRACT(EPOCH FROM {start}))"
584
+
585
+ if unit == "YEARS":
586
+ return year_diff
587
+
588
+ if unit == "MONTHS":
589
+ return f"({year_diff} * 12 + {month_diff})"
590
+
591
+ if unit == "DAYS":
592
+ return day_diff
593
+
594
+ if unit == "WEEKS":
595
+ return f"CAST(FLOOR({day_diff} / 7) AS INTEGER)"
596
+
597
+ if unit == "HOURS":
598
+ return f"CAST(FLOOR({epoch_diff} / 3600) AS INTEGER)"
599
+
600
+ if unit == "MINUTES":
601
+ return f"CAST(FLOOR({epoch_diff} / 60) AS INTEGER)"
602
+
603
+ if unit == "SECONDS":
604
+ return f"CAST({epoch_diff} AS BIGINT)"
605
+
606
+ if unit == "MILLISECONDS":
607
+ return f"CAST({epoch_diff} * 1000 AS BIGINT)"
608
+
609
+ raise ValueError(f"Unsupported DATE DIFF unit: {unit}") # pragma: no cover
610
+
611
+
612
+ def date_time_bucket_processor(
613
+ expression: DateTimeBucketExpression,
614
+ extension: "SqlToStringDbExtension",
615
+ config: SqlToStringConfig
616
+ ) -> str:
617
+ unit = expression.duration_unit.value
618
+ ts = extension.process_expression(expression.date, config)
619
+ q = extension.process_expression(expression.quantity, config)
620
+
621
+ def coerce_to_datetime(sql: str) -> str:
622
+ return (
623
+ f"(({sql}) + INTERVAL '0 second')"
624
+ if expression.date_type == DateType.DateTime
625
+ else sql
626
+ )
627
+
628
+ def epoch() -> str:
629
+ return (
630
+ f"EXTRACT(EPOCH FROM {ts})"
631
+ )
632
+
633
+ if unit == "YEARS":
634
+ return coerce_to_datetime(
635
+ f"make_date(1970,1,1) + "
636
+ f"(FLOOR((EXTRACT(YEAR FROM {ts}) - 1970) / {q}) * {q}) * INTERVAL '1 year'"
637
+ )
638
+
639
+ if unit == "MONTHS":
640
+ total_months_sql = f"((EXTRACT(YEAR FROM {ts}) - 1970) * 12 + (EXTRACT(MONTH FROM {ts}) - 1))"
641
+ return coerce_to_datetime(
642
+ f"make_date(1970,1,1) + "
643
+ f"(FLOOR({total_months_sql} / {q}) * {q}) * INTERVAL '1 month'"
644
+ )
645
+
646
+ if unit == "WEEKS":
647
+ return coerce_to_datetime(
648
+ f"make_date(1969,12,29) + ("
649
+ f"FLOOR(("
650
+ f"{epoch()} - EXTRACT(EPOCH FROM make_date(1969,12,29))"
651
+ f") / (86400 * {q} * 7))"
652
+ f") * ({q} * 7) * INTERVAL '1 day'"
653
+ )
654
+
655
+ if unit == "DAYS":
656
+ days_from_1970 = f"({epoch()} / 86400)"
657
+ return coerce_to_datetime(
658
+ f"make_date(1970,1,1) + "
659
+ f"(FLOOR({days_from_1970} / {q}) * {q}) * INTERVAL '1 day'"
660
+ )
661
+
662
+ unit_seconds_map = {
663
+ "HOURS": 3600,
664
+ "MINUTES": 60,
665
+ "SECONDS": 1
666
+ }
667
+
668
+ if unit in unit_seconds_map:
669
+ seconds_per_unit = unit_seconds_map[unit]
670
+ return (f"(make_date(1970,1,1) + "
671
+ f"(FLOOR({epoch()} / ({q} * {seconds_per_unit})) * ({q} * {seconds_per_unit})) "
672
+ f"* INTERVAL '1 second')")
673
+
674
+ raise ValueError(f"Unsupported TIME BUCKET unit: {unit}") # pragma: no cover
675
+
676
+
523
677
  def not_expression_processor(
524
678
  not_expression: NotExpression,
525
679
  extension: "SqlToStringDbExtension",
@@ -1322,3 +1476,25 @@ class SqlToStringDbExtension:
1322
1476
 
1323
1477
  def process_frame_bound(self, frame_bound: FrameBound, config: SqlToStringConfig) -> str:
1324
1478
  return frame_bound_processor(frame_bound, self, config)
1479
+
1480
+ def process_date_adjust_expression(self, expr: DateAdjustExpression, config: SqlToStringConfig) -> str:
1481
+ return (f"({self.process_expression(expr.date, config)}::DATE + "
1482
+ f"(INTERVAL '{self.process_expression(expr.number, config)} "
1483
+ f"{expr.duration_unit.value.upper()}'))::DATE")
1484
+
1485
+ def process_bitwise_not_expression(self, expr: BitwiseNotExpression, config: SqlToStringConfig) -> str:
1486
+ return f"~({self.process_expression(expr.value, config)})"
1487
+
1488
+ def process_bitwise_shift_expression(self, expr: BitwiseShiftExpression, config: SqlToStringConfig) -> str:
1489
+ return (f"({self.process_expression(expr.value, config)} "
1490
+ f"{'>>' if expr.direction == BitwiseShiftDirection.RIGHT else '<<'} "
1491
+ f"{self.process_expression(expr.shift, config)})")
1492
+
1493
+ def process_bitwise_binary_expression(self, expr: BitwiseBinaryExpression, config: SqlToStringConfig) -> str:
1494
+ return bitwise_binary_expression_processor(expr, self, config)
1495
+
1496
+ def process_date_diff_expression(self, expr: DateDiffExpression, config: SqlToStringConfig) -> str:
1497
+ return date_diff_processor(expr, self, config)
1498
+
1499
+ def process_date_time_bucket_expression(self, expr: DateTimeBucketExpression, config: SqlToStringConfig) -> str:
1500
+ return date_time_bucket_processor(expr, self, config)
@@ -0,0 +1,357 @@
1
+ # Copyright 2026 Goldman Sachs
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ import copy
16
+ import pandas as pd
17
+ from pylegend._typing import (
18
+ TYPE_CHECKING,
19
+ PyLegendDict,
20
+ PyLegendOptional,
21
+ PyLegendSequence,
22
+ PyLegendTypeVar,
23
+ PyLegendUnion
24
+ )
25
+ from pylegend.core.language.pandas_api.pandas_api_aggregate_specification import PyLegendAggInput
26
+ from pylegend.core.language.pandas_api.pandas_api_series import (
27
+ SupportsToPureExpression,
28
+ SupportsToSqlExpression
29
+ )
30
+ from pylegend.core.language.pandas_api.pandas_api_tds_row import PandasApiTdsRow
31
+ from pylegend.core.language.shared.column_expressions import PyLegendColumnExpression
32
+ from pylegend.core.language.shared.expression import (
33
+ PyLegendExpressionBooleanReturn,
34
+ PyLegendExpressionDateReturn,
35
+ PyLegendExpressionDateTimeReturn,
36
+ PyLegendExpressionFloatReturn,
37
+ PyLegendExpressionIntegerReturn,
38
+ PyLegendExpressionNumberReturn,
39
+ PyLegendExpressionStrictDateReturn,
40
+ PyLegendExpressionStringReturn
41
+ )
42
+ from pylegend.core.language.shared.primitives.boolean import PyLegendBoolean
43
+ from pylegend.core.language.shared.primitives.date import PyLegendDate
44
+ from pylegend.core.language.shared.primitives.datetime import PyLegendDateTime
45
+ from pylegend.core.language.shared.primitives.float import PyLegendFloat
46
+ from pylegend.core.language.shared.primitives.integer import PyLegendInteger
47
+ from pylegend.core.language.shared.primitives.number import PyLegendNumber
48
+ from pylegend.core.language.shared.primitives.primitive import (
49
+ PyLegendPrimitive,
50
+ PyLegendPrimitiveOrPythonPrimitive
51
+ )
52
+ from pylegend.core.language.shared.primitives.strictdate import PyLegendStrictDate
53
+ from pylegend.core.language.shared.primitives.string import PyLegendString
54
+ from pylegend.core.sql.metamodel import Expression, QuerySpecification
55
+ from pylegend.core.tds.abstract.frames.base_tds_frame import BaseTdsFrame
56
+ from pylegend.core.tds.pandas_api.frames.pandas_api_applied_function_tds_frame import PandasApiAppliedFunctionTdsFrame
57
+ from pylegend.core.tds.pandas_api.frames.pandas_api_groupby_tds_frame import PandasApiGroupbyTdsFrame
58
+ from pylegend.core.tds.result_handler import ResultHandler
59
+ from pylegend.core.tds.tds_column import TdsColumn
60
+ from pylegend.core.tds.tds_frame import FrameToPureConfig, FrameToSqlConfig
61
+ from pylegend.extensions.tds.result_handler import PandasDfReadConfig
62
+
63
+ if TYPE_CHECKING:
64
+ from pylegend.core.tds.pandas_api.frames.pandas_api_tds_frame import PandasApiTdsFrame
65
+
66
+ __all__: PyLegendSequence[str] = [
67
+ "GroupbySeries",
68
+ "BooleanGroupbySeries",
69
+ "StringGroupbySeries",
70
+ "NumberGroupbySeries",
71
+ "IntegerGroupbySeries",
72
+ "FloatGroupbySeries",
73
+ "DateGroupbySeries",
74
+ "DateTimeGroupbySeries",
75
+ "StrictDateGroupbySeries",
76
+ ]
77
+
78
+ R = PyLegendTypeVar('R')
79
+
80
+
81
+ class GroupbySeries(PyLegendColumnExpression, PyLegendPrimitive, BaseTdsFrame):
82
+ _base_groupby_frame: PandasApiGroupbyTdsFrame
83
+ _applied_function_frame: PyLegendOptional[PandasApiAppliedFunctionTdsFrame]
84
+
85
+ def __init__(self, base_groupby_frame: PandasApiGroupbyTdsFrame):
86
+ selected_columns = base_groupby_frame.get_selected_columns()
87
+ assert selected_columns is not None and len(selected_columns) == 1, (
88
+ "To initialize a GroupbySeries object, exactly one column must be selected, "
89
+ f"but got selected columns: {[str(col) for col in selected_columns] if selected_columns is not None else None}"
90
+ )
91
+
92
+ row = PandasApiTdsRow.from_tds_frame("c", base_groupby_frame.base_frame())
93
+ PyLegendColumnExpression.__init__(self, row=row, column=selected_columns[0].get_name())
94
+
95
+ self._base_groupby_frame: PandasApiGroupbyTdsFrame = base_groupby_frame
96
+ self._applied_function_frame = None
97
+
98
+ @property
99
+ def applied_function_frame(self) -> PyLegendOptional[PandasApiAppliedFunctionTdsFrame]:
100
+ return self._applied_function_frame
101
+
102
+ @applied_function_frame.setter
103
+ def applied_function_frame(self, value: PandasApiAppliedFunctionTdsFrame) -> None:
104
+ self._applied_function_frame = value
105
+
106
+ def _raise_exception_if_no_function_applied(self) -> PandasApiAppliedFunctionTdsFrame:
107
+ if self._applied_function_frame is None:
108
+ raise RuntimeError(
109
+ "The 'groupby' function requires at least one operation to be performed right after it (e.g. aggregate, rank)"
110
+ )
111
+ return self._applied_function_frame
112
+
113
+ def get_base_frame(self) -> "PandasApiGroupbyTdsFrame":
114
+ return self._base_groupby_frame
115
+
116
+ def to_sql_expression(
117
+ self,
118
+ frame_name_to_base_query_map: PyLegendDict[str, QuerySpecification],
119
+ config: FrameToSqlConfig
120
+ ) -> Expression:
121
+ applied_function_frame = self._raise_exception_if_no_function_applied()
122
+ applied_func = applied_function_frame.get_applied_function()
123
+ if isinstance(applied_func, SupportsToSqlExpression):
124
+ return applied_func.to_sql_expression(frame_name_to_base_query_map, config)
125
+
126
+ raise NotImplementedError( # pragma: no cover
127
+ f"The '{applied_func.name()}' function cannot provide a SQL expression"
128
+ )
129
+
130
+ def to_pure_expression(self, config: FrameToPureConfig) -> str:
131
+ applied_function_frame = self._raise_exception_if_no_function_applied()
132
+ applied_func = applied_function_frame.get_applied_function()
133
+ if isinstance(applied_func, SupportsToPureExpression):
134
+ return applied_func.to_pure_expression(config)
135
+
136
+ raise NotImplementedError( # pragma: no cover
137
+ f"The '{applied_func.name()}' function cannot provide a pure expression"
138
+ )
139
+
140
+ def columns(self) -> PyLegendSequence[TdsColumn]:
141
+ applied_function_frame = self._raise_exception_if_no_function_applied()
142
+ return applied_function_frame.columns()
143
+
144
+ def to_sql_query(self, config: FrameToSqlConfig = FrameToSqlConfig()) -> str:
145
+ applied_function_frame = self._raise_exception_if_no_function_applied()
146
+ return applied_function_frame.to_sql_query(config)
147
+
148
+ def to_pure_query(self, config: FrameToPureConfig = FrameToPureConfig()) -> str:
149
+ applied_function_frame = self._raise_exception_if_no_function_applied()
150
+ return applied_function_frame.to_pure_query(config)
151
+
152
+ def execute_frame(
153
+ self,
154
+ result_handler: ResultHandler[R],
155
+ chunk_size: PyLegendOptional[int] = None
156
+ ) -> R: # pragma: no cover
157
+ applied_function_frame = self._raise_exception_if_no_function_applied()
158
+ return applied_function_frame.execute_frame(result_handler, chunk_size)
159
+
160
+ def execute_frame_to_string(
161
+ self,
162
+ chunk_size: PyLegendOptional[int] = None
163
+ ) -> str: # pragma: no cover
164
+ applied_function_frame = self._raise_exception_if_no_function_applied()
165
+ return applied_function_frame.execute_frame_to_string(chunk_size)
166
+
167
+ def execute_frame_to_pandas_df(
168
+ self,
169
+ chunk_size: PyLegendOptional[int] = None,
170
+ pandas_df_read_config: PandasDfReadConfig = PandasDfReadConfig()
171
+ ) -> pd.DataFrame: # pragma: no cover
172
+ applied_function_frame = self._raise_exception_if_no_function_applied()
173
+ return applied_function_frame.execute_frame_to_pandas_df(chunk_size, pandas_df_read_config)
174
+
175
+ def to_sql_query_object(self, config: FrameToSqlConfig) -> QuerySpecification:
176
+ applied_function_frame = self._raise_exception_if_no_function_applied()
177
+ return applied_function_frame.to_sql_query_object(config)
178
+
179
+ def to_pure(self, config: FrameToPureConfig) -> str:
180
+ applied_function_frame = self._raise_exception_if_no_function_applied()
181
+ return applied_function_frame.to_pure(config)
182
+
183
+ def get_all_tds_frames(self) -> PyLegendSequence["BaseTdsFrame"]:
184
+ applied_function_frame = self._raise_exception_if_no_function_applied()
185
+ return applied_function_frame.get_all_tds_frames()
186
+
187
+ def aggregate(
188
+ self,
189
+ func: PyLegendAggInput,
190
+ axis: PyLegendUnion[int, str] = 0,
191
+ *args: PyLegendPrimitiveOrPythonPrimitive,
192
+ **kwargs: PyLegendPrimitiveOrPythonPrimitive
193
+ ) -> "PandasApiTdsFrame":
194
+ new_series = copy.copy(self)
195
+ if new_series.applied_function_frame is None:
196
+ return new_series.get_base_frame().aggregate(func, axis, *args, **kwargs)
197
+ else:
198
+ return new_series.applied_function_frame.aggregate(func, axis, *args, **kwargs)
199
+
200
+ def agg(
201
+ self,
202
+ func: PyLegendAggInput,
203
+ axis: PyLegendUnion[int, str] = 0,
204
+ *args: PyLegendPrimitiveOrPythonPrimitive,
205
+ **kwargs: PyLegendPrimitiveOrPythonPrimitive
206
+ ) -> "PandasApiTdsFrame":
207
+ return self.aggregate(func, axis, *args, **kwargs)
208
+
209
+ def sum(
210
+ self,
211
+ numeric_only: bool = False,
212
+ min_count: int = 0,
213
+ engine: PyLegendOptional[str] = None,
214
+ engine_kwargs: PyLegendOptional[PyLegendDict[str, bool]] = None,
215
+ ) -> "PandasApiTdsFrame":
216
+ if numeric_only is not False:
217
+ raise NotImplementedError("numeric_only=True is not currently supported in sum function.")
218
+ if min_count != 0:
219
+ raise NotImplementedError(f"min_count must be 0 in sum function, but got: {min_count}")
220
+ if engine is not None:
221
+ raise NotImplementedError("engine parameter is not supported in sum function.")
222
+ if engine_kwargs is not None:
223
+ raise NotImplementedError("engine_kwargs parameter is not supported in sum function.")
224
+ return self.aggregate("sum", 0)
225
+
226
+ def mean(
227
+ self,
228
+ numeric_only: bool = False,
229
+ engine: PyLegendOptional[str] = None,
230
+ engine_kwargs: PyLegendOptional[PyLegendDict[str, bool]] = None,
231
+ ) -> "PandasApiTdsFrame":
232
+ if numeric_only is not False:
233
+ raise NotImplementedError("numeric_only=True is not currently supported in mean function.")
234
+ if engine is not None:
235
+ raise NotImplementedError("engine parameter is not supported in mean function.")
236
+ if engine_kwargs is not None:
237
+ raise NotImplementedError("engine_kwargs parameter is not supported in mean function.")
238
+ return self.aggregate("mean", 0)
239
+
240
+ def min(
241
+ self,
242
+ numeric_only: bool = False,
243
+ min_count: int = -1,
244
+ engine: PyLegendOptional[str] = None,
245
+ engine_kwargs: PyLegendOptional[PyLegendDict[str, bool]] = None,
246
+ ) -> "PandasApiTdsFrame":
247
+ if numeric_only is not False:
248
+ raise NotImplementedError("numeric_only=True is not currently supported in min function.")
249
+ if min_count != -1:
250
+ raise NotImplementedError(f"min_count must be -1 (default) in min function, but got: {min_count}")
251
+ if engine is not None:
252
+ raise NotImplementedError("engine parameter is not supported in min function.")
253
+ if engine_kwargs is not None:
254
+ raise NotImplementedError("engine_kwargs parameter is not supported in min function.")
255
+ return self.aggregate("min", 0)
256
+
257
+ def max(
258
+ self,
259
+ numeric_only: bool = False,
260
+ min_count: int = -1,
261
+ engine: PyLegendOptional[str] = None,
262
+ engine_kwargs: PyLegendOptional[PyLegendDict[str, bool]] = None,
263
+ ) -> "PandasApiTdsFrame":
264
+ if numeric_only is not False:
265
+ raise NotImplementedError("numeric_only=True is not currently supported in max function.")
266
+ if min_count != -1:
267
+ raise NotImplementedError(f"min_count must be -1 (default) in max function, but got: {min_count}")
268
+ if engine is not None:
269
+ raise NotImplementedError("engine parameter is not supported in max function.")
270
+ if engine_kwargs is not None:
271
+ raise NotImplementedError("engine_kwargs parameter is not supported in max function.")
272
+ return self.aggregate("max", 0)
273
+
274
+ def std(
275
+ self,
276
+ ddof: int = 1,
277
+ engine: PyLegendOptional[str] = None,
278
+ engine_kwargs: PyLegendOptional[PyLegendDict[str, bool]] = None,
279
+ numeric_only: bool = False,
280
+ ) -> "PandasApiTdsFrame":
281
+ if ddof != 1:
282
+ raise NotImplementedError(f"Only ddof=1 (Sample Standard Deviation) is supported in std function, but got: {ddof}")
283
+ if engine is not None:
284
+ raise NotImplementedError("engine parameter is not supported in std function.")
285
+ if engine_kwargs is not None:
286
+ raise NotImplementedError("engine_kwargs parameter is not supported in std function.")
287
+ if numeric_only is not False:
288
+ raise NotImplementedError("numeric_only=True is not currently supported in std function.")
289
+ return self.aggregate("std", 0)
290
+
291
+ def var(
292
+ self,
293
+ ddof: int = 1,
294
+ engine: PyLegendOptional[str] = None,
295
+ engine_kwargs: PyLegendOptional[PyLegendDict[str, bool]] = None,
296
+ numeric_only: bool = False,
297
+ ) -> "PandasApiTdsFrame":
298
+ if ddof != 1:
299
+ raise NotImplementedError(f"Only ddof=1 (Sample Variance) is supported in var function, but got: {ddof}")
300
+ if engine is not None:
301
+ raise NotImplementedError("engine parameter is not supported in var function.")
302
+ if engine_kwargs is not None:
303
+ raise NotImplementedError("engine_kwargs parameter is not supported in var function.")
304
+ if numeric_only is not False:
305
+ raise NotImplementedError("numeric_only=True is not currently supported in var function.")
306
+ return self.aggregate("var", 0)
307
+
308
+ def count(self) -> "PandasApiTdsFrame":
309
+ return self.aggregate("count", 0)
310
+
311
+
312
+ class BooleanGroupbySeries(GroupbySeries, PyLegendBoolean, PyLegendExpressionBooleanReturn):
313
+ def __init__(self, base_frame: "PandasApiGroupbyTdsFrame"):
314
+ super().__init__(base_frame) # pragma: no cover (Boolean column not supported in PURE)
315
+ PyLegendBoolean.__init__(self, self) # pragma: no cover (Boolean column not supported in PURE)
316
+
317
+
318
+ class StringGroupbySeries(GroupbySeries, PyLegendString, PyLegendExpressionStringReturn):
319
+ def __init__(self, base_frame: "PandasApiGroupbyTdsFrame"):
320
+ super().__init__(base_frame)
321
+ PyLegendString.__init__(self, self)
322
+
323
+
324
+ class NumberGroupbySeries(GroupbySeries, PyLegendNumber, PyLegendExpressionNumberReturn):
325
+ def __init__(self, base_frame: "PandasApiGroupbyTdsFrame"):
326
+ super().__init__(base_frame)
327
+ PyLegendNumber.__init__(self, self)
328
+
329
+
330
+ class IntegerGroupbySeries(NumberGroupbySeries, PyLegendInteger, PyLegendExpressionIntegerReturn):
331
+ def __init__(self, base_frame: "PandasApiGroupbyTdsFrame"):
332
+ super().__init__(base_frame)
333
+ PyLegendInteger.__init__(self, self)
334
+
335
+
336
+ class FloatGroupbySeries(NumberGroupbySeries, PyLegendFloat, PyLegendExpressionFloatReturn):
337
+ def __init__(self, base_frame: "PandasApiGroupbyTdsFrame"):
338
+ super().__init__(base_frame)
339
+ PyLegendFloat.__init__(self, self)
340
+
341
+
342
+ class DateGroupbySeries(GroupbySeries, PyLegendDate, PyLegendExpressionDateReturn):
343
+ def __init__(self, base_frame: "PandasApiGroupbyTdsFrame"):
344
+ super().__init__(base_frame)
345
+ PyLegendDate.__init__(self, self)
346
+
347
+
348
+ class DateTimeGroupbySeries(DateGroupbySeries, PyLegendDateTime, PyLegendExpressionDateTimeReturn):
349
+ def __init__(self, base_frame: "PandasApiGroupbyTdsFrame"):
350
+ super().__init__(base_frame)
351
+ PyLegendDateTime.__init__(self, self)
352
+
353
+
354
+ class StrictDateGroupbySeries(DateGroupbySeries, PyLegendStrictDate, PyLegendExpressionStrictDateReturn):
355
+ def __init__(self, base_frame: "PandasApiGroupbyTdsFrame"):
356
+ super().__init__(base_frame)
357
+ PyLegendStrictDate.__init__(self, self)