pointblank 0.8.6__tar.gz → 0.9.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 (287) hide show
  1. {pointblank-0.8.6 → pointblank-0.9.0}/.github/workflows/ci-tests.yaml +1 -1
  2. {pointblank-0.8.6 → pointblank-0.9.0}/Makefile +8 -3
  3. {pointblank-0.8.6 → pointblank-0.9.0}/PKG-INFO +19 -4
  4. {pointblank-0.8.6 → pointblank-0.9.0}/README.md +18 -3
  5. {pointblank-0.8.6 → pointblank-0.9.0}/docs/blog/intro-pointblank/index.qmd +1 -1
  6. {pointblank-0.8.6 → pointblank-0.9.0}/docs/demos/02-advanced/index.qmd +0 -2
  7. {pointblank-0.8.6 → pointblank-0.9.0}/docs/index.qmd +1 -1
  8. {pointblank-0.8.6 → pointblank-0.9.0}/docs/styles.css +11 -0
  9. {pointblank-0.8.6 → pointblank-0.9.0}/docs/user-guide/actions.qmd +169 -0
  10. {pointblank-0.8.6 → pointblank-0.9.0}/pointblank/_constants.py +11 -10
  11. {pointblank-0.8.6 → pointblank-0.9.0}/pointblank/_interrogation.py +10 -4
  12. pointblank-0.9.0/pointblank/_typing.py +26 -0
  13. {pointblank-0.8.6 → pointblank-0.9.0}/pointblank/data/api-docs.txt +716 -49
  14. {pointblank-0.8.6 → pointblank-0.9.0}/pointblank/datascan.py +4 -4
  15. {pointblank-0.8.6 → pointblank-0.9.0}/pointblank/draft.py +1 -1
  16. {pointblank-0.8.6 → pointblank-0.9.0}/pointblank/thresholds.py +10 -0
  17. {pointblank-0.8.6 → pointblank-0.9.0}/pointblank/validate.py +1071 -50
  18. {pointblank-0.8.6 → pointblank-0.9.0}/pointblank.egg-info/PKG-INFO +19 -4
  19. {pointblank-0.8.6 → pointblank-0.9.0}/pointblank.egg-info/SOURCES.txt +15 -1
  20. {pointblank-0.8.6 → pointblank-0.9.0}/pyproject.toml +4 -2
  21. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_comprehensive_validation_report_html_snap/comprehensive_validation_report.html +14 -14
  22. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_no_interrogation_validation_report_html_snap/no_interrogation_validation_report.html +14 -14
  23. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_validation_report_briefs_global_local_html/validation_report_briefs_global_local.html +6 -6
  24. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_validation_report_briefs_html/validation_report_with_briefs.html +6 -6
  25. {pointblank-0.8.6/tests/snapshots/test_validate/test_validation_report_interrogate_snap/tbl_pl → pointblank-0.9.0/tests/snapshots/test_validate/test_validation_report_interrogate_snap/tbl_duckdb}/validation_report.json +1 -0
  26. {pointblank-0.8.6/tests/snapshots/test_validate/test_validation_report_interrogate_snap/tbl_pd → pointblank-0.9.0/tests/snapshots/test_validate/test_validation_report_interrogate_snap/tbl_parquet}/validation_report.json +1 -0
  27. {pointblank-0.8.6/tests/snapshots/test_validate/test_validation_report_interrogate_snap/tbl_duckdb → pointblank-0.9.0/tests/snapshots/test_validate/test_validation_report_interrogate_snap/tbl_pd}/validation_report.json +1 -0
  28. {pointblank-0.8.6/tests/snapshots/test_validate/test_validation_report_interrogate_snap/tbl_parquet → pointblank-0.9.0/tests/snapshots/test_validate/test_validation_report_interrogate_snap/tbl_pl}/validation_report.json +1 -0
  29. pointblank-0.9.0/tests/snapshots/test_validate/test_validation_report_interrogate_snap/tbl_sqlite/validation_report.json +26 -0
  30. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_validation_report_no_interrogate_snap/tbl_duckdb/validation_report.json +1 -0
  31. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_validation_report_no_interrogate_snap/tbl_parquet/validation_report.json +1 -0
  32. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_validation_report_no_interrogate_snap/tbl_pd/validation_report.json +1 -0
  33. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_validation_report_no_interrogate_snap/tbl_pl/validation_report.json +1 -0
  34. pointblank-0.9.0/tests/snapshots/test_validate/test_validation_report_no_interrogate_snap/tbl_sqlite/validation_report.json +26 -0
  35. pointblank-0.9.0/tests/snapshots/test_validate/test_validation_report_segments_html/duckdb/validation_report_segments.html +608 -0
  36. pointblank-0.9.0/tests/snapshots/test_validate/test_validation_report_segments_html/pandas/validation_report_segments.html +608 -0
  37. pointblank-0.9.0/tests/snapshots/test_validate/test_validation_report_segments_html/polars/validation_report_segments.html +608 -0
  38. pointblank-0.9.0/tests/snapshots/test_validate/test_validation_report_segments_with_pre_html/polars/validation_report_segments_with_pre.html +185 -0
  39. pointblank-0.9.0/tests/snapshots/test_validate/test_validation_report_segments_with_pre_html/validation_report_segments_with_pre.html +185 -0
  40. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_validation_with_selector_helper_functions_no_match_snap/tbl_memtable_variable_names/selector_helper_functions_no_match.html +2 -2
  41. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_validation_with_selector_helper_functions_no_match_snap/tbl_pd_variable_names/selector_helper_functions_no_match.html +2 -2
  42. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_validation_with_selector_helper_functions_no_match_snap/tbl_pl_variable_names/selector_helper_functions_no_match.html +2 -2
  43. {pointblank-0.8.6 → pointblank-0.9.0}/tests/test__utils.py +4 -11
  44. {pointblank-0.8.6 → pointblank-0.9.0}/tests/test_validate.py +159 -28
  45. pointblank-0.9.0/translations/README.de.md +244 -0
  46. pointblank-0.9.0/translations/README.es.md +242 -0
  47. pointblank-0.9.0/translations/README.fr.md +242 -0
  48. pointblank-0.9.0/translations/README.it.md +244 -0
  49. pointblank-0.9.0/translations/README.ja.md +244 -0
  50. pointblank-0.9.0/translations/README.ko.md +244 -0
  51. pointblank-0.9.0/translations/README.nl.md +244 -0
  52. pointblank-0.9.0/translations/README.pt-BR.md +244 -0
  53. pointblank-0.9.0/translations/README.zh-CN.md +237 -0
  54. pointblank-0.8.6/pointblank/_typing.py +0 -10
  55. pointblank-0.8.6/tests/snapshots/test_validate/test_validation_report_interrogate_snap/tbl_sqlite/validation_report.json +0 -25
  56. pointblank-0.8.6/tests/snapshots/test_validate/test_validation_report_no_interrogate_snap/tbl_sqlite/validation_report.json +0 -25
  57. {pointblank-0.8.6 → pointblank-0.9.0}/.github/CODE_OF_CONDUCT.md +0 -0
  58. {pointblank-0.8.6 → pointblank-0.9.0}/.github/ISSUE_TEMPLATE/bug.md +0 -0
  59. {pointblank-0.8.6 → pointblank-0.9.0}/.github/ISSUE_TEMPLATE/feature.md +0 -0
  60. {pointblank-0.8.6 → pointblank-0.9.0}/.github/ISSUE_TEMPLATE/question.md +0 -0
  61. {pointblank-0.8.6 → pointblank-0.9.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  62. {pointblank-0.8.6 → pointblank-0.9.0}/.github/SECURITY.md +0 -0
  63. {pointblank-0.8.6 → pointblank-0.9.0}/.github/workflows/ci-docs.yaml +0 -0
  64. {pointblank-0.8.6 → pointblank-0.9.0}/.github/workflows/code-checks.yaml +0 -0
  65. {pointblank-0.8.6 → pointblank-0.9.0}/.gitignore +0 -0
  66. {pointblank-0.8.6 → pointblank-0.9.0}/.pre-commit-config.yaml +0 -0
  67. {pointblank-0.8.6 → pointblank-0.9.0}/.vscode/settings.json +0 -0
  68. {pointblank-0.8.6 → pointblank-0.9.0}/CITATION.cff +0 -0
  69. {pointblank-0.8.6 → pointblank-0.9.0}/CONTRIBUTING.md +0 -0
  70. {pointblank-0.8.6 → pointblank-0.9.0}/LICENSE +0 -0
  71. {pointblank-0.8.6 → pointblank-0.9.0}/data_raw/game_revenue.csv +0 -0
  72. {pointblank-0.8.6 → pointblank-0.9.0}/data_raw/nycflights.csv +0 -0
  73. {pointblank-0.8.6 → pointblank-0.9.0}/data_raw/nycflights.ddb +0 -0
  74. {pointblank-0.8.6 → pointblank-0.9.0}/data_raw/small_table.csv +0 -0
  75. {pointblank-0.8.6 → pointblank-0.9.0}/data_raw/x-01-parquet.qmd +0 -0
  76. {pointblank-0.8.6 → pointblank-0.9.0}/data_raw/x-02-duckdb.qmd +0 -0
  77. {pointblank-0.8.6 → pointblank-0.9.0}/data_raw/x-03-sqlite.qmd +0 -0
  78. {pointblank-0.8.6 → pointblank-0.9.0}/docs/.gitignore +0 -0
  79. {pointblank-0.8.6 → pointblank-0.9.0}/docs/_extensions/machow/interlinks/.gitignore +0 -0
  80. {pointblank-0.8.6 → pointblank-0.9.0}/docs/_extensions/machow/interlinks/_extension.yml +0 -0
  81. {pointblank-0.8.6 → pointblank-0.9.0}/docs/_extensions/machow/interlinks/interlinks.lua +0 -0
  82. {pointblank-0.8.6 → pointblank-0.9.0}/docs/_quarto.yml +0 -0
  83. {pointblank-0.8.6 → pointblank-0.9.0}/docs/assets/fav-logo.png +0 -0
  84. {pointblank-0.8.6 → pointblank-0.9.0}/docs/assets/pointblank-sales-data.png +0 -0
  85. {pointblank-0.8.6 → pointblank-0.9.0}/docs/assets/pointblank-step-report.png +0 -0
  86. {pointblank-0.8.6 → pointblank-0.9.0}/docs/assets/pointblank-tabular-report.png +0 -0
  87. {pointblank-0.8.6 → pointblank-0.9.0}/docs/assets/pointblank_logo.svg +0 -0
  88. {pointblank-0.8.6 → pointblank-0.9.0}/docs/assets/validation-table-diagram.png +0 -0
  89. {pointblank-0.8.6 → pointblank-0.9.0}/docs/blog/index.qmd +0 -0
  90. {pointblank-0.8.6 → pointblank-0.9.0}/docs/blog/intro-pointblank/pointblank-localized.png +0 -0
  91. {pointblank-0.8.6 → pointblank-0.9.0}/docs/blog/intro-pointblank/step_report.png +0 -0
  92. {pointblank-0.8.6 → pointblank-0.9.0}/docs/blog/intro-pointblank/validation-table-diagram.png +0 -0
  93. {pointblank-0.8.6 → pointblank-0.9.0}/docs/blog/intro-pointblank/validation-test-units.png +0 -0
  94. {pointblank-0.8.6 → pointblank-0.9.0}/docs/blog/pointblank_blog_logo.png +0 -0
  95. {pointblank-0.8.6 → pointblank-0.9.0}/docs/demos/01-starter/index.qmd +0 -0
  96. {pointblank-0.8.6 → pointblank-0.9.0}/docs/demos/03-data-extracts/index.qmd +0 -0
  97. {pointblank-0.8.6 → pointblank-0.9.0}/docs/demos/04-sundered-data/index.qmd +0 -0
  98. {pointblank-0.8.6 → pointblank-0.9.0}/docs/demos/05-step-report-column-check/index.qmd +0 -0
  99. {pointblank-0.8.6 → pointblank-0.9.0}/docs/demos/06-step-report-schema-check/index.qmd +0 -0
  100. {pointblank-0.8.6 → pointblank-0.9.0}/docs/demos/apply-checks-to-several-columns/index.qmd +0 -0
  101. {pointblank-0.8.6 → pointblank-0.9.0}/docs/demos/check-row-column-counts/index.qmd +0 -0
  102. {pointblank-0.8.6 → pointblank-0.9.0}/docs/demos/checks-for-missing/index.qmd +0 -0
  103. {pointblank-0.8.6 → pointblank-0.9.0}/docs/demos/col-vals-custom-expr/index.qmd +0 -0
  104. {pointblank-0.8.6 → pointblank-0.9.0}/docs/demos/column-selector-functions/index.qmd +0 -0
  105. {pointblank-0.8.6 → pointblank-0.9.0}/docs/demos/comparisons-across-columns/index.qmd +0 -0
  106. {pointblank-0.8.6 → pointblank-0.9.0}/docs/demos/data/game_revenue.parquet +0 -0
  107. {pointblank-0.8.6 → pointblank-0.9.0}/docs/demos/expect-no-duplicate-rows/index.qmd +0 -0
  108. {pointblank-0.8.6 → pointblank-0.9.0}/docs/demos/expect-no-duplicate-values/index.qmd +0 -0
  109. {pointblank-0.8.6 → pointblank-0.9.0}/docs/demos/expect-text-pattern/index.qmd +0 -0
  110. {pointblank-0.8.6 → pointblank-0.9.0}/docs/demos/failure-thresholds/index.qmd +0 -0
  111. {pointblank-0.8.6 → pointblank-0.9.0}/docs/demos/img/advanced_validation.png +0 -0
  112. {pointblank-0.8.6 → pointblank-0.9.0}/docs/demos/img/data_extracts.png +0 -0
  113. {pointblank-0.8.6 → pointblank-0.9.0}/docs/demos/img/starter_validation.png +0 -0
  114. {pointblank-0.8.6 → pointblank-0.9.0}/docs/demos/img/step_report_column_schema.png +0 -0
  115. {pointblank-0.8.6 → pointblank-0.9.0}/docs/demos/img/step_report_column_values.png +0 -0
  116. {pointblank-0.8.6 → pointblank-0.9.0}/docs/demos/img/sundered_data.png +0 -0
  117. {pointblank-0.8.6 → pointblank-0.9.0}/docs/demos/index.qmd +0 -0
  118. {pointblank-0.8.6 → pointblank-0.9.0}/docs/demos/mutate-table-in-step/index.qmd +0 -0
  119. {pointblank-0.8.6 → pointblank-0.9.0}/docs/demos/numeric-comparisons/index.qmd +0 -0
  120. {pointblank-0.8.6 → pointblank-0.9.0}/docs/demos/schema-check/index.qmd +0 -0
  121. {pointblank-0.8.6 → pointblank-0.9.0}/docs/demos/set-membership/index.qmd +0 -0
  122. {pointblank-0.8.6 → pointblank-0.9.0}/docs/demos/using-parquet-data/index.qmd +0 -0
  123. {pointblank-0.8.6 → pointblank-0.9.0}/docs/user-guide/across.qmd +0 -0
  124. {pointblank-0.8.6 → pointblank-0.9.0}/docs/user-guide/col-summary-tbl.qmd +0 -0
  125. {pointblank-0.8.6 → pointblank-0.9.0}/docs/user-guide/columns.qmd +0 -0
  126. {pointblank-0.8.6 → pointblank-0.9.0}/docs/user-guide/extracts.qmd +0 -0
  127. {pointblank-0.8.6 → pointblank-0.9.0}/docs/user-guide/index.qmd +0 -0
  128. {pointblank-0.8.6 → pointblank-0.9.0}/docs/user-guide/missing-vals-tbl.qmd +0 -0
  129. {pointblank-0.8.6 → pointblank-0.9.0}/docs/user-guide/preprocessing.qmd +0 -0
  130. {pointblank-0.8.6 → pointblank-0.9.0}/docs/user-guide/preview.qmd +0 -0
  131. {pointblank-0.8.6 → pointblank-0.9.0}/docs/user-guide/sundering.qmd +0 -0
  132. {pointblank-0.8.6 → pointblank-0.9.0}/docs/user-guide/thresholds.qmd +0 -0
  133. {pointblank-0.8.6 → pointblank-0.9.0}/docs/user-guide/types.qmd +0 -0
  134. {pointblank-0.8.6 → pointblank-0.9.0}/images/pointblank-tabular-report.png +0 -0
  135. {pointblank-0.8.6 → pointblank-0.9.0}/images/pointblank_logo.svg +0 -0
  136. {pointblank-0.8.6 → pointblank-0.9.0}/pointblank/__init__.py +0 -0
  137. {pointblank-0.8.6 → pointblank-0.9.0}/pointblank/_constants_docs.py +0 -0
  138. {pointblank-0.8.6 → pointblank-0.9.0}/pointblank/_constants_translations.py +0 -0
  139. {pointblank-0.8.6 → pointblank-0.9.0}/pointblank/_utils.py +0 -0
  140. {pointblank-0.8.6 → pointblank-0.9.0}/pointblank/_utils_check_args.py +0 -0
  141. {pointblank-0.8.6 → pointblank-0.9.0}/pointblank/_utils_html.py +0 -0
  142. {pointblank-0.8.6 → pointblank-0.9.0}/pointblank/actions.py +0 -0
  143. {pointblank-0.8.6 → pointblank-0.9.0}/pointblank/assistant.py +0 -0
  144. {pointblank-0.8.6 → pointblank-0.9.0}/pointblank/column.py +0 -0
  145. {pointblank-0.8.6 → pointblank-0.9.0}/pointblank/data/game_revenue-duckdb.zip +0 -0
  146. {pointblank-0.8.6 → pointblank-0.9.0}/pointblank/data/game_revenue.zip +0 -0
  147. {pointblank-0.8.6 → pointblank-0.9.0}/pointblank/data/nycflights-duckdb.zip +0 -0
  148. {pointblank-0.8.6 → pointblank-0.9.0}/pointblank/data/nycflights.zip +0 -0
  149. {pointblank-0.8.6 → pointblank-0.9.0}/pointblank/data/polars-api-docs.txt +0 -0
  150. {pointblank-0.8.6 → pointblank-0.9.0}/pointblank/data/small_table-duckdb.zip +0 -0
  151. {pointblank-0.8.6 → pointblank-0.9.0}/pointblank/data/small_table.zip +0 -0
  152. {pointblank-0.8.6 → pointblank-0.9.0}/pointblank/schema.py +0 -0
  153. {pointblank-0.8.6 → pointblank-0.9.0}/pointblank/tf.py +0 -0
  154. {pointblank-0.8.6 → pointblank-0.9.0}/pointblank.egg-info/dependency_links.txt +0 -0
  155. {pointblank-0.8.6 → pointblank-0.9.0}/pointblank.egg-info/requires.txt +0 -0
  156. {pointblank-0.8.6 → pointblank-0.9.0}/pointblank.egg-info/top_level.txt +0 -0
  157. {pointblank-0.8.6 → pointblank-0.9.0}/setup.cfg +0 -0
  158. {pointblank-0.8.6 → pointblank-0.9.0}/tests/__init__.py +0 -0
  159. {pointblank-0.8.6 → pointblank-0.9.0}/tests/manual_tests/schema_step_reports.qmd +0 -0
  160. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_datascan/test_col_summary_tbl_duckdb_snap/col_summary_html_duckdb.html +0 -0
  161. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_datascan/test_col_summary_tbl_pandas_snap/col_summary_html_pandas.html +0 -0
  162. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_datascan/test_col_summary_tbl_polars_snap/col_summary_html_polars.html +0 -0
  163. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_step_report_01/schema_step_report_01-0.txt +0 -0
  164. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_step_report_01_1/schema_step_report_01-1.txt +0 -0
  165. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_step_report_01_2/schema_step_report_01-2.txt +0 -0
  166. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_step_report_01_3/schema_step_report_01-3.txt +0 -0
  167. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_step_report_02/schema_step_report_02-0.txt +0 -0
  168. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_step_report_02_1/schema_step_report_02-1.txt +0 -0
  169. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_step_report_02_2/schema_step_report_02-2.txt +0 -0
  170. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_step_report_02_3/schema_step_report_02-3.txt +0 -0
  171. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_step_report_03/schema_step_report_03-0.txt +0 -0
  172. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_step_report_03_1/schema_step_report_03-1.txt +0 -0
  173. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_step_report_03_2/schema_step_report_03-2.txt +0 -0
  174. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_step_report_03_3/schema_step_report_03-3.txt +0 -0
  175. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_step_report_04/schema_step_report_04-0.txt +0 -0
  176. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_step_report_05/schema_step_report_05-0.txt +0 -0
  177. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_step_report_06/schema_step_report_06-0.txt +0 -0
  178. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_step_report_07/schema_step_report_07-0.txt +0 -0
  179. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_step_report_08/schema_step_report_08-0.txt +0 -0
  180. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_step_report_09/schema_step_report_09-0.txt +0 -0
  181. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_step_report_10/schema_step_report_10-0.txt +0 -0
  182. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_step_report_11/schema_step_report_11-0.txt +0 -0
  183. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_step_report_12/schema_step_report_12-0.txt +0 -0
  184. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_step_report_13/schema_step_report_13-0.txt +0 -0
  185. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_step_report_14/schema_step_report_14-0.txt +0 -0
  186. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_step_report_14_1/schema_step_report_14-1.txt +0 -0
  187. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_step_report_15/schema_step_report_15-0.txt +0 -0
  188. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_step_report_15_1/schema_step_report_15-1.txt +0 -0
  189. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_step_report_16/schema_step_report_16-0.txt +0 -0
  190. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_step_report_16_1/schema_step_report_16-1.txt +0 -0
  191. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_step_report_17/schema_step_report_17-0.txt +0 -0
  192. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_step_report_17_1/schema_step_report_17-1.txt +0 -0
  193. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_step_report_18/schema_step_report_18-0.txt +0 -0
  194. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_step_report_18_1/schema_step_report_18-1.txt +0 -0
  195. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_step_report_19/schema_step_report_19-0.txt +0 -0
  196. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_step_report_19_1/schema_step_report_19-1.txt +0 -0
  197. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_step_report_20/schema_step_report_20-0.txt +0 -0
  198. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_step_report_20_1/schema_step_report_20-1.txt +0 -0
  199. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_step_report_21/schema_step_report_21-0.txt +0 -0
  200. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_step_report_21_1/schema_step_report_21-1.txt +0 -0
  201. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_step_report_21_2/schema_step_report_21-2.txt +0 -0
  202. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_step_report_21_3/schema_step_report_21-3.txt +0 -0
  203. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_step_report_22/schema_step_report_22-0.txt +0 -0
  204. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_step_report_22_1/schema_step_report_22-1.txt +0 -0
  205. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_step_report_23/schema_step_report_23-0.txt +0 -0
  206. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_step_report_23_1/schema_step_report_23-1.txt +0 -0
  207. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_step_report_24/schema_step_report_24-0.txt +0 -0
  208. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_step_report_24_1/schema_step_report_24-1.txt +0 -0
  209. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_step_report_24_2/schema_step_report_24-2.txt +0 -0
  210. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_step_report_24_3/schema_step_report_24-3.txt +0 -0
  211. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_step_report_25/schema_step_report_25-0.txt +0 -0
  212. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_step_report_25_1/schema_step_report_25-1.txt +0 -0
  213. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_step_report_25_2/schema_step_report_25-2.txt +0 -0
  214. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_step_report_25_3/schema_step_report_25-3.txt +0 -0
  215. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_step_report_25_4/schema_step_report_25-4.txt +0 -0
  216. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_step_report_25_5/schema_step_report_25-5.txt +0 -0
  217. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_validation_info/schema_info_01-0.txt +0 -0
  218. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_validation_info/schema_info_02-0.txt +0 -0
  219. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_validation_info/schema_info_03-0.txt +0 -0
  220. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_validation_info/schema_info_04-0.txt +0 -0
  221. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_validation_info/schema_info_05-0.txt +0 -0
  222. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_validation_info/schema_info_06-0.txt +0 -0
  223. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_validation_info/schema_info_07-0.txt +0 -0
  224. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_validation_info/schema_info_08-0.txt +0 -0
  225. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_validation_info/schema_info_09-0.txt +0 -0
  226. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_validation_info/schema_info_10-0.txt +0 -0
  227. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_validation_info/schema_info_11-0.txt +0 -0
  228. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_validation_info/schema_info_12-0.txt +0 -0
  229. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_validation_info/schema_info_13-0.txt +0 -0
  230. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_validation_info/schema_info_14-0.txt +0 -0
  231. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_validation_info/schema_info_14-1.txt +0 -0
  232. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_validation_info/schema_info_15-0.txt +0 -0
  233. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_validation_info/schema_info_15-1.txt +0 -0
  234. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_validation_info/schema_info_16-0.txt +0 -0
  235. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_validation_info/schema_info_16-1.txt +0 -0
  236. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_validation_info/schema_info_17-0.txt +0 -0
  237. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_validation_info/schema_info_17-1.txt +0 -0
  238. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_validation_info/schema_info_18-0.txt +0 -0
  239. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_validation_info/schema_info_18-1.txt +0 -0
  240. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_validation_info/schema_info_19-0.txt +0 -0
  241. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_validation_info/schema_info_19-1.txt +0 -0
  242. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_validation_info/schema_info_20-0.txt +0 -0
  243. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_validation_info/schema_info_20-1.txt +0 -0
  244. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_validation_info/schema_info_21-0.txt +0 -0
  245. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_validation_info/schema_info_21-1.txt +0 -0
  246. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_validation_info/schema_info_21-2.txt +0 -0
  247. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_validation_info/schema_info_21-3.txt +0 -0
  248. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_validation_info/schema_info_22-0.txt +0 -0
  249. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_validation_info/schema_info_22-1.txt +0 -0
  250. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_validation_info/schema_info_23-0.txt +0 -0
  251. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_validation_info/schema_info_23-1.txt +0 -0
  252. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_validation_info/schema_info_24-0.txt +0 -0
  253. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_validation_info/schema_info_24-1.txt +0 -0
  254. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_validation_info/schema_info_24-2.txt +0 -0
  255. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_validation_info/schema_info_24-3.txt +0 -0
  256. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_validation_info/schema_info_25-0.txt +0 -0
  257. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_validation_info/schema_info_25-1.txt +0 -0
  258. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_validation_info/schema_info_25-2.txt +0 -0
  259. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_validation_info/schema_info_25-3.txt +0 -0
  260. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_validation_info/schema_info_25-4.txt +0 -0
  261. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_get_schema_validation_info/schema_info_25-5.txt +0 -0
  262. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_no_steps_validation_report_html_snap/no_steps_validation_report.html +0 -0
  263. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_validation_report_use_fields_snap/tbl_duckdb/validation_report.json +0 -0
  264. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_validation_report_use_fields_snap/tbl_parquet/validation_report.json +0 -0
  265. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_validation_report_use_fields_snap/tbl_pd/validation_report.json +0 -0
  266. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_validation_report_use_fields_snap/tbl_pl/validation_report.json +0 -0
  267. {pointblank-0.8.6 → pointblank-0.9.0}/tests/snapshots/test_validate/test_validation_report_use_fields_snap/tbl_sqlite/validation_report.json +0 -0
  268. {pointblank-0.8.6 → pointblank-0.9.0}/tests/tbl_files/tbl_dates_times_text.ddb +0 -0
  269. {pointblank-0.8.6 → pointblank-0.9.0}/tests/tbl_files/tbl_dates_times_text.parquet +0 -0
  270. {pointblank-0.8.6 → pointblank-0.9.0}/tests/tbl_files/tbl_dates_times_text.sqlite +0 -0
  271. {pointblank-0.8.6 → pointblank-0.9.0}/tests/tbl_files/tbl_true_dates_times.ddb +0 -0
  272. {pointblank-0.8.6 → pointblank-0.9.0}/tests/tbl_files/tbl_xyz.ddb +0 -0
  273. {pointblank-0.8.6 → pointblank-0.9.0}/tests/tbl_files/tbl_xyz.parquet +0 -0
  274. {pointblank-0.8.6 → pointblank-0.9.0}/tests/tbl_files/tbl_xyz.sqlite +0 -0
  275. {pointblank-0.8.6 → pointblank-0.9.0}/tests/tbl_files/tbl_xyz_missing.ddb +0 -0
  276. {pointblank-0.8.6 → pointblank-0.9.0}/tests/tbl_files/tbl_xyz_missing.parquet +0 -0
  277. {pointblank-0.8.6 → pointblank-0.9.0}/tests/tbl_files/tbl_xyz_missing.sqlite +0 -0
  278. {pointblank-0.8.6 → pointblank-0.9.0}/tests/test__interrogation.py +0 -0
  279. {pointblank-0.8.6 → pointblank-0.9.0}/tests/test__utils_check_args.py +0 -0
  280. {pointblank-0.8.6 → pointblank-0.9.0}/tests/test_actions.py +0 -0
  281. {pointblank-0.8.6 → pointblank-0.9.0}/tests/test_assistant.py +0 -0
  282. {pointblank-0.8.6 → pointblank-0.9.0}/tests/test_column.py +0 -0
  283. {pointblank-0.8.6 → pointblank-0.9.0}/tests/test_datascan.py +0 -0
  284. {pointblank-0.8.6 → pointblank-0.9.0}/tests/test_draft.py +0 -0
  285. {pointblank-0.8.6 → pointblank-0.9.0}/tests/test_schema.py +0 -0
  286. {pointblank-0.8.6 → pointblank-0.9.0}/tests/test_tf.py +0 -0
  287. {pointblank-0.8.6 → pointblank-0.9.0}/tests/test_thresholds.py +0 -0
@@ -29,7 +29,7 @@ jobs:
29
29
  pip install -e '.[dev]'
30
30
  - name: Install test dependencies
31
31
  run: |
32
- pip install pytest pytest-cov pytest-snapshot pandas polars ibis-framework[duckdb,mysql,postgres,sqlite]>=9.5.0 chatlas requests shiny
32
+ pip install pytest pytest-rerunfailures pytest-randomly pytest-xdist pytest-cov pytest-snapshot pandas polars ibis-framework[duckdb,mysql,postgres,sqlite]>=9.5.0 chatlas requests shiny
33
33
  - name: pytest unit tests
34
34
  run: |
35
35
  make test
@@ -1,13 +1,18 @@
1
1
  .PHONY: check
2
2
 
3
+ .PHONY: test
3
4
  test:
4
- pytest --cov=pointblank --cov-report=xml
5
+ @pytest \
6
+ --cov=pointblank \
7
+ --cov-report=term-missing \
8
+ --randomly-seed 123 \
9
+ -n auto \
10
+ --reruns 3 \
11
+ --reruns-delay 1
5
12
 
6
13
  test-update:
7
14
  pytest --snapshot-update
8
15
 
9
- test-coverage:
10
- pytest --cov=pointblank --cov-report=term-missing
11
16
 
12
17
  lint: ## Run ruff formatter and linter
13
18
  @uv run ruff format
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pointblank
3
- Version: 0.8.6
3
+ Version: 0.9.0
4
4
  Summary: Find out if your data is what you think it is.
5
5
  Author-email: Richard Iannone <riannone@me.com>
6
6
  License: MIT License
@@ -89,6 +89,7 @@ _Data validation made beautiful and powerful_
89
89
  [![Python Versions](https://img.shields.io/pypi/pyversions/pointblank.svg)](https://pypi.python.org/pypi/pointblank)
90
90
  [![PyPI](https://img.shields.io/pypi/v/pointblank)](https://pypi.org/project/pointblank/#history)
91
91
  [![PyPI Downloads](https://img.shields.io/pypi/dm/pointblank)](https://pypistats.org/packages/pointblank)
92
+ [![Conda Version](https://img.shields.io/conda/vn/conda-forge/pointblank.svg)](https://anaconda.org/conda-forge/pointblank)
92
93
  [![License](https://img.shields.io/github/license/posit-dev/pointblank)](https://img.shields.io/github/license/posit-dev/pointblank)
93
94
 
94
95
  [![CI Build](https://github.com/posit-dev/pointblank/actions/workflows/ci-tests.yaml/badge.svg)](https://github.com/posit-dev/pointblank/actions/workflows/ci-tests.yaml)
@@ -102,9 +103,21 @@ _Data validation made beautiful and powerful_
102
103
 
103
104
  </div>
104
105
 
106
+ <div align="right">
107
+ <a href="translations/README.fr.md">Français</a> |
108
+ <a href="translations/README.de.md">Deutsch</a> |
109
+ <a href="translations/README.it.md">Italiano</a> |
110
+ <a href="translations/README.es.md">Español</a> |
111
+ <a href="translations/README.pt-BR.md">Português</a> |
112
+ <a href="translations/README.nl.md">Nederlands</a> |
113
+ <a href="translations/README.zh-CN.md">简体中文</a> |
114
+ <a href="translations/README.ja.md">日本語</a> |
115
+ <a href="translations/README.ko.md">한국어</a>
116
+ </div>
117
+
105
118
  ## What is Pointblank?
106
119
 
107
- Pointblank is a modern data validation framework for Python that helps you trust your data with confidence. It provides a fluent, expressive API to validate your data against a wide range of constraints and presents results in beautiful, interactive reports.
120
+ Pointblank is a powerful, yet elegant data validation framework for Python that transforms how you ensure data quality. With its intuitive, chainable API, you can quickly validate your data against comprehensive quality checks and visualize results through stunning, interactive reports that make data issues immediately actionable.
108
121
 
109
122
  Whether you're a data scientist, data engineer, or analyst, Pointblank helps you catch data quality issues before they impact your analyses or downstream systems.
110
123
 
@@ -134,9 +147,9 @@ validation
134
147
 
135
148
  <br>
136
149
 
137
- Why Choose Pointblank?
150
+ ## Why Choose Pointblank?
138
151
 
139
- - **Works with your existing stack** - Seamlessly integrates with Polars, Pandas, DuckDB, MySQL, PostgreSQL, SQLite, Parquet, and more!
152
+ - **Works with your existing stack** - Seamlessly integrates with Polars, Pandas, DuckDB, MySQL, PostgreSQL, SQLite, Parquet, PySpark, Snowflake, and more!
140
153
  - **Beautiful, interactive reports** - Crystal-clear validation results that highlight issues and help communicate data quality
141
154
  - **Composable validation pipeline** - Chain validation steps into a complete data quality workflow
142
155
  - **Threshold-based alerts** - Set 'warning', 'error', and 'critical' thresholds with custom actions
@@ -213,6 +226,8 @@ validation.get_step_report(i=3).show("browser") # Get failing records from step
213
226
  <img src="https://posit-dev.github.io/pointblank/assets/pointblank-step-report.png" width="800px">
214
227
  </div>
215
228
 
229
+ <br>
230
+
216
231
  ## Features That Set Pointblank Apart
217
232
 
218
233
  - **Complete validation workflow** - From data access to validation to reporting in a single pipeline
@@ -7,6 +7,7 @@ _Data validation made beautiful and powerful_
7
7
  [![Python Versions](https://img.shields.io/pypi/pyversions/pointblank.svg)](https://pypi.python.org/pypi/pointblank)
8
8
  [![PyPI](https://img.shields.io/pypi/v/pointblank)](https://pypi.org/project/pointblank/#history)
9
9
  [![PyPI Downloads](https://img.shields.io/pypi/dm/pointblank)](https://pypistats.org/packages/pointblank)
10
+ [![Conda Version](https://img.shields.io/conda/vn/conda-forge/pointblank.svg)](https://anaconda.org/conda-forge/pointblank)
10
11
  [![License](https://img.shields.io/github/license/posit-dev/pointblank)](https://img.shields.io/github/license/posit-dev/pointblank)
11
12
 
12
13
  [![CI Build](https://github.com/posit-dev/pointblank/actions/workflows/ci-tests.yaml/badge.svg)](https://github.com/posit-dev/pointblank/actions/workflows/ci-tests.yaml)
@@ -20,9 +21,21 @@ _Data validation made beautiful and powerful_
20
21
 
21
22
  </div>
22
23
 
24
+ <div align="right">
25
+ <a href="translations/README.fr.md">Français</a> |
26
+ <a href="translations/README.de.md">Deutsch</a> |
27
+ <a href="translations/README.it.md">Italiano</a> |
28
+ <a href="translations/README.es.md">Español</a> |
29
+ <a href="translations/README.pt-BR.md">Português</a> |
30
+ <a href="translations/README.nl.md">Nederlands</a> |
31
+ <a href="translations/README.zh-CN.md">简体中文</a> |
32
+ <a href="translations/README.ja.md">日本語</a> |
33
+ <a href="translations/README.ko.md">한국어</a>
34
+ </div>
35
+
23
36
  ## What is Pointblank?
24
37
 
25
- Pointblank is a modern data validation framework for Python that helps you trust your data with confidence. It provides a fluent, expressive API to validate your data against a wide range of constraints and presents results in beautiful, interactive reports.
38
+ Pointblank is a powerful, yet elegant data validation framework for Python that transforms how you ensure data quality. With its intuitive, chainable API, you can quickly validate your data against comprehensive quality checks and visualize results through stunning, interactive reports that make data issues immediately actionable.
26
39
 
27
40
  Whether you're a data scientist, data engineer, or analyst, Pointblank helps you catch data quality issues before they impact your analyses or downstream systems.
28
41
 
@@ -52,9 +65,9 @@ validation
52
65
 
53
66
  <br>
54
67
 
55
- Why Choose Pointblank?
68
+ ## Why Choose Pointblank?
56
69
 
57
- - **Works with your existing stack** - Seamlessly integrates with Polars, Pandas, DuckDB, MySQL, PostgreSQL, SQLite, Parquet, and more!
70
+ - **Works with your existing stack** - Seamlessly integrates with Polars, Pandas, DuckDB, MySQL, PostgreSQL, SQLite, Parquet, PySpark, Snowflake, and more!
58
71
  - **Beautiful, interactive reports** - Crystal-clear validation results that highlight issues and help communicate data quality
59
72
  - **Composable validation pipeline** - Chain validation steps into a complete data quality workflow
60
73
  - **Threshold-based alerts** - Set 'warning', 'error', and 'critical' thresholds with custom actions
@@ -131,6 +144,8 @@ validation.get_step_report(i=3).show("browser") # Get failing records from step
131
144
  <img src="https://posit-dev.github.io/pointblank/assets/pointblank-step-report.png" width="800px">
132
145
  </div>
133
146
 
147
+ <br>
148
+
134
149
  ## Features That Set Pointblank Apart
135
150
 
136
151
  - **Complete validation workflow** - From data access to validation to reporting in a single pipeline
@@ -3,7 +3,7 @@ jupyter: python3
3
3
  html-table-processing: none
4
4
  title: "Introducing Pointblank"
5
5
  author: Rich Iannone
6
- date: 2024-04-04
6
+ date: 2025-04-04
7
7
  freeze: true
8
8
  ---
9
9
 
@@ -15,7 +15,6 @@ A validation with a comprehensive set of rules.
15
15
 
16
16
  import pointblank as pb
17
17
  import polars as pl
18
- import narwhals as nw
19
18
 
20
19
  validation = (
21
20
  pb.Validate(
@@ -52,7 +51,6 @@ validation
52
51
  ```python
53
52
  import pointblank as pb
54
53
  import polars as pl
55
- import narwhals as nw
56
54
 
57
55
  validation = (
58
56
  pb.Validate(
@@ -11,7 +11,7 @@ _Data validation made beautiful and powerful_
11
11
 
12
12
  </div>
13
13
 
14
- Pointblank is a modern data validation framework for Python that helps you trust your data with confidence. It provides a fluent, expressive API to validate your data against a wide range of constraints and presents results in beautiful, interactive reports.
14
+ Pointblank is a powerful, yet elegant data validation framework for Python that transforms how you ensure data quality. With its intuitive, chainable API, you can quickly validate your data against comprehensive quality checks and visualize results through stunning, interactive reports that make data issues immediately actionable.
15
15
 
16
16
  Whether you're a data scientist, data engineer, or analyst, Pointblank helps you catch data quality issues before they impact your analyses or downstream systems.
17
17
 
@@ -17,6 +17,17 @@ p a {
17
17
  text-underline-offset: 4px;
18
18
  }
19
19
 
20
+ li a {
21
+ color: black;
22
+ text-underline-offset: 4px;
23
+ }
24
+
25
+ dt {
26
+ height: 32px;
27
+ overflow-x: scroll;
28
+ margin-left: -4px;
29
+ }
30
+
20
31
  .table td {
21
32
  padding-left: 0px;
22
33
  }
@@ -222,3 +222,172 @@ The metadata dictionary contains the following fields for a given validation ste
222
222
  - `level_num`: The severity level as a numeric value (`30`, `40`, or `50`).
223
223
  - `autobrief`: A localized and brief statement of the expectation for the step.
224
224
  - `failure_text`: Localized text that explains how the validation step failed.
225
+
226
+ ## Final Actions with `FinalActions`
227
+
228
+ When you need to execute actions after all validation steps are complete, Pointblank provides the
229
+ [`FinalActions`](https://posit-dev.github.io/pointblank/reference/FinalActions.html) class. Unlike
230
+ [`Actions`](https://posit-dev.github.io/pointblank/reference/Actions.html) which triggers on a
231
+ per-step basis during the validation process,
232
+ [`FinalActions`](https://posit-dev.github.io/pointblank/reference/FinalActions.html) executes after
233
+ the entire validation is complete, giving you a way to respond to the overall validation results.
234
+
235
+ Here's how to use
236
+ [`FinalActions`](https://posit-dev.github.io/pointblank/reference/FinalActions.html):
237
+
238
+ ```{python}
239
+ import pointblank as pb
240
+
241
+ def send_alert():
242
+ summary = pb.get_validation_summary()
243
+ if summary["highest_severity"] == "critical":
244
+ print(f"ALERT: Critical validation failures found in `{summary['tbl_name']}`")
245
+
246
+ validation_with_final = (
247
+ pb.Validate(
248
+ data=pb.load_dataset(dataset="game_revenue", tbl_type="duckdb"),
249
+ tbl_name="game_revenue",
250
+ thresholds=pb.Thresholds(warning=0.05, error=0.10, critical=0.15),
251
+ final_actions=pb.FinalActions(
252
+ "Validation complete.", # a string message
253
+ send_alert # a callable function
254
+ )
255
+ )
256
+ .col_vals_regex(columns="player_id", pattern=r"[A-Z]{12}\d{3}")
257
+ .col_vals_gt(columns="item_revenue", value=0.10)
258
+ .interrogate()
259
+ )
260
+
261
+ validation_with_final
262
+ ```
263
+
264
+ In this example:
265
+
266
+ - We define the function `send_alert()` that checks the validation summary for critical failures
267
+ - We provide a simple string message `"Validation complete."` that will print to the console
268
+ - Both actions will execute in order after all validation steps have completed
269
+
270
+ Because the 'critical' threshold was exceeded in Step 2, we see the printed alert of `send_alert()`
271
+ after the simple string message.
272
+
273
+ ### Creating Final Actions
274
+
275
+ [`FinalActions`](https://posit-dev.github.io/pointblank/reference/FinalActions.html) accepts any
276
+ number of actions as positional arguments. Each argument can be:
277
+
278
+ 1. **String**: A message to be displayed in the console
279
+ 2. **Callable**: A function to be called with no arguments
280
+ 3. **List of Strings/Callables**: Multiple actions to execute in sequence
281
+
282
+ All actions will be executed in the order they are provided after all validation steps have
283
+ completed.
284
+
285
+ ### Using `get_validation_summary()` in Final Actions
286
+
287
+ When creating a callable function to use with
288
+ [`FinalActions`](https://posit-dev.github.io/pointblank/reference/FinalActions.html), you can access
289
+ information about the overall validation results using the
290
+ [`get_validation_summary()`](https://posit-dev.github.io/pointblank/reference/get_validation_summary.html)
291
+ function. This gives you a dictionary with comprehensive information about the validation:
292
+
293
+ ```python
294
+ def comprehensive_report():
295
+ summary = pb.get_validation_summary()
296
+ print(f"Validation Report for {summary['tbl_name']}:")
297
+ print(f"- Steps: {summary['n_steps']}")
298
+ print(f"- Passing steps: {summary['n_passing_steps']}")
299
+ print(f"- Failing steps: {summary['n_failing_steps']}")
300
+
301
+ # Take additional actions based on results
302
+ if summary["n_failing_steps"] > 0:
303
+ # Create and execute a Slack notification
304
+ notify = pb.send_slack_notification(
305
+ webhook_url="https://hooks.slack.com/services/your/webhook/url",
306
+ summary_msg="""
307
+ 🚨 *Validation Failure Alert*
308
+ • Table: {tbl_name}
309
+ • Failed Steps: {n_failing_steps} of {n_steps}
310
+ • Highest Severity: {highest_severity}
311
+ • Time: {time}
312
+ """,
313
+ )
314
+ notify() # Execute the notification function
315
+
316
+
317
+ validation = (
318
+ pb.Validate(
319
+ data=pb.load_dataset(dataset="game_revenue", tbl_type="duckdb"),
320
+ tbl_name="game_revenue",
321
+ final_actions=pb.FinalActions(comprehensive_report),
322
+ )
323
+ .col_vals_regex(columns="player_id", pattern=r"[A-Z]{12}\d{3}")
324
+ .col_vals_gt(columns="item_revenue", value=0.05)
325
+ .interrogate()
326
+ )
327
+
328
+ validation
329
+ ```
330
+
331
+ ```{python}
332
+ # | echo: false
333
+
334
+ validation = (
335
+ pb.Validate(
336
+ data=pb.load_dataset(dataset="game_revenue", tbl_type="duckdb"),
337
+ tbl_name="game_revenue",
338
+ )
339
+ .col_vals_regex(columns="player_id", pattern=r"[A-Z]{12}\d{3}")
340
+ .col_vals_gt(columns="item_revenue", value=0.05)
341
+ .interrogate()
342
+ )
343
+
344
+ validation
345
+ ```
346
+
347
+ Here we used the [`send_slack_notification()`](https://posit-dev.github.io/pointblank/reference/send_slack_notification.html)
348
+ function, which is available in Pointblank as a pre-built action. It can be used by itself in
349
+ `final_actions=` but here it's integrated into the user's `comprehensive_report()` function.
350
+
351
+ ### Combining the Two Types of Actions
352
+
353
+ You can use both [`Actions`](https://posit-dev.github.io/pointblank/reference/Actions.html) and
354
+ [`FinalActions`](https://posit-dev.github.io/pointblank/reference/FinalActions.html) together for
355
+ comprehensive validation control:
356
+
357
+ ```{python}
358
+ def log_step_failure():
359
+ m = pb.get_action_metadata()
360
+ print(f"Step {m['step']} failed with {m['level']}")
361
+
362
+
363
+ def generate_summary():
364
+ summary = pb.get_validation_summary()
365
+ # Sum up total failed test units across all steps
366
+ total_failed = sum(summary["dict_n_failed"].values())
367
+ # Sum up total test units across all steps
368
+ total_units = sum(summary["dict_n"].values())
369
+ print(f"Validation complete: {total_failed} failures out of {total_units} tests")
370
+
371
+
372
+ validation_combined = (
373
+ pb.Validate(
374
+ data=pb.load_dataset(dataset="game_revenue", tbl_type="duckdb"),
375
+ thresholds=pb.Thresholds(warning=0.05, error=0.10),
376
+ actions=pb.Actions(default=log_step_failure),
377
+ final_actions=pb.FinalActions(generate_summary),
378
+ )
379
+ .col_vals_regex(columns="player_id", pattern=r"[A-Z]{12}\d{3}")
380
+ .col_vals_gt(columns="item_revenue", value=0.05)
381
+ .interrogate()
382
+ )
383
+ ```
384
+
385
+ This approach allows you to:
386
+
387
+ 1. Log individual step failures during the validation process using
388
+ [`Actions`](https://posit-dev.github.io/pointblank/reference/Actions.html)
389
+ 2. Generate a comprehensive report after all validation steps are complete using
390
+ [`FinalActions`](https://posit-dev.github.io/pointblank/reference/FinalActions.html)
391
+
392
+ Using both action types gives you fine-grained control over when and how notifications and other
393
+ actions are triggered in your validation workflow.
@@ -126,6 +126,7 @@ VALIDATION_REPORT_FIELDS = [
126
126
  "inclusive",
127
127
  "na_pass",
128
128
  "pre",
129
+ "segments",
129
130
  "thresholds",
130
131
  "label",
131
132
  "brief",
@@ -231,9 +232,9 @@ SVG_ICONS_FOR_ASSERTION_TYPES = {
231
232
  </svg>""",
232
233
  "col_vals_eq": """<?xml version="1.0" encoding="UTF-8"?>
233
234
  <svg width="67px" height="67px" viewBox="0 0 67 67" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
234
- <title>col_vals_equal</title>
235
+ <title>col_vals_eq</title>
235
236
  <g id="All-Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
236
- <g id="col_vals_equal" transform="translate(0.000000, 0.275862)">
237
+ <g id="col_vals_eq" transform="translate(0.000000, 0.275862)">
237
238
  <path d="M56.712234,1 C59.1975153,1 61.4475153,2.00735931 63.076195,3.63603897 C64.7048747,5.26471863 65.712234,7.51471863 65.712234,10 L65.712234,10 L65.712234,65 L10.712234,65 C8.22695259,65 5.97695259,63.9926407 4.34827294,62.363961 C2.71959328,60.7352814 1.71223397,58.4852814 1.71223397,56 L1.71223397,56 L1.71223397,10 C1.71223397,7.51471863 2.71959328,5.26471863 4.34827294,3.63603897 C5.97695259,2.00735931 8.22695259,1 10.712234,1 L10.712234,1 Z" id="rectangle" stroke="#000000" stroke-width="2" fill="#FFFFFF"></path>
238
239
  <path d="M52.712234,11 L14.712234,11 C13.05989,11 11.712234,12.347656 11.712234,14 L11.712234,52 C11.712234,53.652344 13.05989,55 14.712234,55 L52.712234,55 C54.364578,55 55.712234,53.652344 55.712234,52 L55.712234,14 C55.712234,12.347656 54.364578,11 52.712234,11 Z M46.712234,38 L20.712234,38 L20.712234,36 L46.712234,36 L46.712234,38 Z M46.712234,30 L20.712234,30 L20.712234,28 L46.712234,28 L46.712234,30 Z" id="equals" fill="#000000" fill-rule="nonzero"></path>
239
240
  </g>
@@ -241,9 +242,9 @@ SVG_ICONS_FOR_ASSERTION_TYPES = {
241
242
  </svg>""",
242
243
  "col_vals_ne": """<?xml version="1.0" encoding="UTF-8"?>
243
244
  <svg width="67px" height="67px" viewBox="0 0 67 67" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
244
- <title>col_vals_not_equal</title>
245
+ <title>col_vals_ne</title>
245
246
  <g id="All-Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
246
- <g id="col_vals_not_equal" transform="translate(0.000000, 0.758621)">
247
+ <g id="col_vals_ne" transform="translate(0.000000, 0.758621)">
247
248
  <path d="M56.712234,1 C59.1975153,1 61.4475153,2.00735931 63.076195,3.63603897 C64.7048747,5.26471863 65.712234,7.51471863 65.712234,10 L65.712234,10 L65.712234,65 L10.712234,65 C8.22695259,65 5.97695259,63.9926407 4.34827294,62.363961 C2.71959328,60.7352814 1.71223397,58.4852814 1.71223397,56 L1.71223397,56 L1.71223397,10 C1.71223397,7.51471863 2.71959328,5.26471863 4.34827294,3.63603897 C5.97695259,2.00735931 8.22695259,1 10.712234,1 L10.712234,1 Z" id="rectangle" stroke="#000000" stroke-width="2" fill="#FFFFFF"></path>
248
249
  <path d="M53.712234,12 L13.712234,12 C13.161453,12 12.712234,12.449219 12.712234,13 L12.712234,53 C12.712234,53.550781 13.161453,54 13.712234,54 L53.712234,54 C54.263015,54 54.712234,53.550781 54.712234,53 L54.712234,13 C54.712234,12.449219 54.263015,12 53.712234,12 Z M46.712234,30 L32.989578,30 L36.805984,36 L46.712234,36 L46.712234,38 L38.079422,38 L43.169265,46 L40.798172,46 L35.708328,38 L20.712234,38 L20.712234,36 L34.43489,36 L30.618484,30 L20.712234,30 L20.712234,28 L29.345047,28 L24.251297,20 L26.62239,20 L31.71614,28 L46.712234,28 L46.712234,30 Z" id="not_equal" fill="#000000" fill-rule="nonzero"></path>
249
250
  </g>
@@ -251,9 +252,9 @@ SVG_ICONS_FOR_ASSERTION_TYPES = {
251
252
  </svg>""",
252
253
  "col_vals_ge": """<?xml version="1.0" encoding="UTF-8"?>
253
254
  <svg width="67px" height="67px" viewBox="0 0 67 67" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
254
- <title>col_vals_gte</title>
255
+ <title>col_vals_ge</title>
255
256
  <g id="All-Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
256
- <g id="col_vals_gte" transform="translate(0.000000, 0.241379)">
257
+ <g id="col_vals_ge" transform="translate(0.000000, 0.241379)">
257
258
  <path d="M56.712234,1 C59.1975153,1 61.4475153,2.00735931 63.076195,3.63603897 C64.7048747,5.26471863 65.712234,7.51471863 65.712234,10 L65.712234,10 L65.712234,65 L10.712234,65 C8.22695259,65 5.97695259,63.9926407 4.34827294,62.363961 C2.71959328,60.7352814 1.71223397,58.4852814 1.71223397,56 L1.71223397,56 L1.71223397,10 C1.71223397,7.51471863 2.71959328,5.26471863 4.34827294,3.63603897 C5.97695259,2.00735931 8.22695259,1 10.712234,1 L10.712234,1 Z" id="rectangle" stroke="#000000" stroke-width="2" fill="#FFFFFF"></path>
258
259
  <path d="M49.712234,12 L17.712234,12 C14.952234,12 12.712234,14.24 12.712234,17 L12.712234,49 C12.712234,51.76 14.952234,54 17.712234,54 L49.712234,54 C52.472234,54 54.712234,51.76 54.712234,49 L54.712234,17 C54.712234,14.24 52.472234,12 49.712234,12 Z M44.712234,47 L22.712234,47 L22.712234,45 L44.712234,45 L44.712234,47 Z M24.182234,40.88 L23.242234,39.12 L40.562234,30 L23.242234,20.88 L24.182234,19.12 L44.862234,30 L24.182234,40.88 Z" id="greater_than_equal" fill="#000000" fill-rule="nonzero"></path>
259
260
  </g>
@@ -261,9 +262,9 @@ SVG_ICONS_FOR_ASSERTION_TYPES = {
261
262
  </svg>""",
262
263
  "col_vals_le": """<?xml version="1.0" encoding="UTF-8"?>
263
264
  <svg width="67px" height="67px" viewBox="0 0 67 67" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
264
- <title>col_vals_lte</title>
265
+ <title>col_vals_le</title>
265
266
  <g id="All-Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
266
- <g id="col_vals_lte" transform="translate(0.000000, 0.793103)">
267
+ <g id="col_vals_le" transform="translate(0.000000, 0.793103)">
267
268
  <path d="M56.712234,1 C59.1975153,1 61.4475153,2.00735931 63.076195,3.63603897 C64.7048747,5.26471863 65.712234,7.51471863 65.712234,10 L65.712234,10 L65.712234,65 L10.712234,65 C8.22695259,65 5.97695259,63.9926407 4.34827294,62.363961 C2.71959328,60.7352814 1.71223397,58.4852814 1.71223397,56 L1.71223397,56 L1.71223397,10 C1.71223397,7.51471863 2.71959328,5.26471863 4.34827294,3.63603897 C5.97695259,2.00735931 8.22695259,1 10.712234,1 L10.712234,1 Z" id="rectangle" stroke="#000000" stroke-width="2" fill="#FFFFFF"></path>
268
269
  <path d="M53.712234,12 L13.712234,12 C13.157547,12 12.712234,12.449219 12.712234,13 L12.712234,53 C12.712234,53.550781 13.157547,54 13.712234,54 L53.712234,54 C54.266922,54 54.712234,53.550781 54.712234,53 L54.712234,13 C54.712234,12.449219 54.266922,12 53.712234,12 Z M42.227859,19.125 L43.196609,20.875 L26.770828,30 L43.196609,39.125 L42.227859,40.875 L22.65364,30 L42.227859,19.125 Z M44.712234,47 L22.712234,47 L22.712234,45 L44.712234,45 L44.712234,47 Z" id="less_than_equal" fill="#000000" fill-rule="nonzero"></path>
269
270
  </g>
@@ -281,9 +282,9 @@ SVG_ICONS_FOR_ASSERTION_TYPES = {
281
282
  </svg>""",
282
283
  "col_vals_outside": """<?xml version="1.0" encoding="UTF-8"?>
283
284
  <svg width="67px" height="67px" viewBox="0 0 67 67" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
284
- <title>col_vals_not_between</title>
285
+ <title>col_vals_outside</title>
285
286
  <g id="All-Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
286
- <g id="col_vals_not_between" transform="translate(0.000000, 0.689655)">
287
+ <g id="col_vals_outside" transform="translate(0.000000, 0.689655)">
287
288
  <path d="M56.712234,1 C59.1975153,1 61.4475153,2.00735931 63.076195,3.63603897 C64.7048747,5.26471863 65.712234,7.51471863 65.712234,10 L65.712234,10 L65.712234,65 L10.712234,65 C8.22695259,65 5.97695259,63.9926407 4.34827294,62.363961 C2.71959328,60.7352814 1.71223397,58.4852814 1.71223397,56 L1.71223397,56 L1.71223397,10 C1.71223397,7.51471863 2.71959328,5.26471863 4.34827294,3.63603897 C5.97695259,2.00735931 8.22695259,1 10.712234,1 L10.712234,1 Z" id="rectangle" stroke="#000000" stroke-width="2" fill="#FFFFFF"></path>
288
289
  <g id="outside_range" transform="translate(11.000000, 21.000000)" fill="#000000">
289
290
  <path d="M12.993484,0.96875 C11.962234,1.082031 11.188797,1.964844 11.212234,3 L11.212234,21 C11.200515,21.722656 11.579422,22.390625 12.204422,22.753906 C12.825515,23.121094 13.598953,23.121094 14.220047,22.753906 C14.845047,22.390625 15.223953,21.722656 15.212234,21 L15.212234,3 C15.220047,2.457031 15.009109,1.9375 14.626297,1.554688 C14.243484,1.171875 13.723953,0.960938 13.180984,0.96875 C13.118484,0.964844 13.055984,0.964844 12.993484,0.96875 Z M32.993484,0.96875 C31.962234,1.082031 31.188797,1.964844 31.212234,3 L31.212234,21 C31.200515,21.722656 31.579422,22.390625 32.204422,22.753906 C32.825515,23.121094 33.598953,23.121094 34.220047,22.753906 C34.845047,22.390625 35.223953,21.722656 35.212234,21 L35.212234,3 C35.220047,2.457031 35.009109,1.9375 34.626297,1.554688 C34.243484,1.171875 33.723953,0.960938 33.180984,0.96875 C33.118484,0.964844 33.055984,0.964844 32.993484,0.96875 Z M17.212234,1 C16.661453,1 16.212234,1.449219 16.212234,2 C16.212234,2.550781 16.661453,3 17.212234,3 C17.763015,3 18.212234,2.550781 18.212234,2 C18.212234,1.449219 17.763015,1 17.212234,1 Z M21.212234,1 C20.661453,1 20.212234,1.449219 20.212234,2 C20.212234,2.550781 20.661453,3 21.212234,3 C21.763015,3 22.212234,2.550781 22.212234,2 C22.212234,1.449219 21.763015,1 21.212234,1 Z M25.212234,1 C24.661453,1 24.212234,1.449219 24.212234,2 C24.212234,2.550781 24.661453,3 25.212234,3 C25.763015,3 26.212234,2.550781 26.212234,2 C26.212234,1.449219 25.763015,1 25.212234,1 Z M29.212234,1 C28.661453,1 28.212234,1.449219 28.212234,2 C28.212234,2.550781 28.661453,3 29.212234,3 C29.763015,3 30.212234,2.550781 30.212234,2 C30.212234,1.449219 29.763015,1 29.212234,1 Z M17.212234,21 C16.661453,21 16.212234,21.449219 16.212234,22 C16.212234,22.550781 16.661453,23 17.212234,23 C17.763015,23 18.212234,22.550781 18.212234,22 C18.212234,21.449219 17.763015,21 17.212234,21 Z M21.212234,21 C20.661453,21 20.212234,21.449219 20.212234,22 C20.212234,22.550781 20.661453,23 21.212234,23 C21.763015,23 22.212234,22.550781 22.212234,22 C22.212234,21.449219 21.763015,21 21.212234,21 Z M25.212234,21 C24.661453,21 24.212234,21.449219 24.212234,22 C24.212234,22.550781 24.661453,23 25.212234,23 C25.763015,23 26.212234,22.550781 26.212234,22 C26.212234,21.449219 25.763015,21 25.212234,21 Z M29.212234,21 C28.661453,21 28.212234,21.449219 28.212234,22 C28.212234,22.550781 28.661453,23 29.212234,23 C29.763015,23 30.212234,22.550781 30.212234,22 C30.212234,21.449219 29.763015,21 29.212234,21 Z" id="small_range" fill-rule="nonzero"></path>
@@ -1089,14 +1089,20 @@ class Interrogator:
1089
1089
  def isin(self) -> FrameT | Any:
1090
1090
  # Ibis backends ---------------------------------------------
1091
1091
 
1092
+ can_be_null: bool = None in self.set
1093
+
1092
1094
  if self.tbl_type in IBIS_BACKENDS:
1093
- return self.x.mutate(pb_is_good_=self.x[self.column].isin(self.set))
1095
+ base_expr = self.x[self.column].isin(self.set)
1096
+ if can_be_null:
1097
+ base_expr = base_expr | self.x[self.column].isnull()
1098
+ return self.x.mutate(pb_is_good_=base_expr)
1094
1099
 
1095
1100
  # Local backends (Narwhals) ---------------------------------
1101
+ base_expr: nw.Expr = nw.col(self.column).is_in(self.set)
1102
+ if can_be_null:
1103
+ base_expr = base_expr | nw.col(self.column).is_null()
1096
1104
 
1097
- return self.x.with_columns(
1098
- pb_is_good_=nw.col(self.column).is_in(self.set),
1099
- ).to_native()
1105
+ return self.x.with_columns(pb_is_good_=base_expr).to_native()
1100
1106
 
1101
1107
  def notin(self) -> FrameT | Any:
1102
1108
  # Ibis backends ---------------------------------------------
@@ -0,0 +1,26 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import TypeAlias
4
+
5
+ ## Absolute bounds, ie. plus or minus
6
+ AbsoluteBounds: TypeAlias = tuple[int, int]
7
+
8
+ ## Relative bounds, ie. plus or minus some percent
9
+ RelativeBounds: TypeAlias = tuple[float, float]
10
+
11
+ ## Tolerance afforded to some check
12
+ Tolerance: TypeAlias = int | float | AbsoluteBounds | RelativeBounds
13
+
14
+ ## Types for data segmentation
15
+
16
+ ## Value(s) that can be used in a segment tuple
17
+ SegmentValue: TypeAlias = str | list[str]
18
+
19
+ ## (column, value(s)) format for segments
20
+ SegmentTuple: TypeAlias = tuple[str, SegmentValue]
21
+
22
+ ## Individual segment item (string or tuple)
23
+ SegmentItem: TypeAlias = str | SegmentTuple
24
+
25
+ ## Full segment specification options
26
+ SegmentSpec: TypeAlias = str | SegmentTuple | list[SegmentItem]