feat: Generalize metrics and add nullability delta metric#43
Draft
Moritz Potthoff (MoritzPotthoffQC) wants to merge 9 commits into
Draft
feat: Generalize metrics and add nullability delta metric#43Moritz Potthoff (MoritzPotthoffQC) wants to merge 9 commits into
Moritz Potthoff (MoritzPotthoffQC) wants to merge 9 commits into
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #43 +/- ##
=========================================
Coverage 100.00% 100.00%
=========================================
Files 11 11
Lines 1018 1030 +12
=========================================
+ Hits 1018 1030 +12 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
This was referenced Jul 10, 2026
Merged
Copilot started reviewing on behalf of
Moritz Potthoff (MoritzPotthoffQC)
July 10, 2026 14:28
View session
There was a problem hiding this comment.
Pull request overview
This PR extends Diffly’s per-column summary metrics to support non-numeric columns via an explicit Metric(fn, selector=...) wrapper, and introduces a built-in metric for nullability changes so users can quickly see how null fractions evolve between left/right frames.
Changes:
- Allow
summary(metrics=...)/ testing helpers to accept either a bare metric callable (numeric-only) or aMetricwith a Polars selector (any column types). - Add the
null_fraction_changepreset and expose it asΔNull%inDEFAULT_METRICSand the CLI. - Update summary formatting + docs, and add tests + generated summary fixtures for the new metric behavior.
Reviewed changes
Copilot reviewed 41 out of 41 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| diffly/metrics.py | Adds Metric wrapper type, null-fraction change preset, and updates DEFAULT_METRICS to include selector-based metrics. |
| diffly/comparison.py | Accepts Metric objects in summary(metrics=...) and resolves bare callables as numeric-only. |
| diffly/summary.py | Allows metrics to render string results in column summaries. |
| diffly/testing.py | Broadens metrics typing/docs to allow Metric values in assertion helpers. |
| diffly/cli.py | Updates CLI help text and passes selector-based preset metrics through to summary(). |
| docs/api/metrics.rst | Documents selector-based metrics and adds Metric + null_fraction_change to the API docs. |
| tests/test_metrics.py | Adds unit tests for null_fraction_change output (including non-numeric columns). |
| tests/cli/test_cli.py | Adds CLI coverage for selecting the ΔNull% metric preset. |
| tests/summary/fixtures/metrics_null_fraction/test_metrics_null_fraction.py | New fixture generator test for summaries including ΔNull% and a selector-based custom metric. |
| tests/summary/fixtures/metrics_null_fraction/gen/pretty_True_perfect_True_top_True_slim_True_sample_rows_True_sample_pk_True.txt | Generated summary fixture variant for ΔNull%. |
| tests/summary/fixtures/metrics_null_fraction/gen/pretty_True_perfect_True_top_True_slim_True_sample_rows_False_sample_pk_False.txt | Generated summary fixture variant for ΔNull%. |
| tests/summary/fixtures/metrics_null_fraction/gen/pretty_True_perfect_True_top_True_slim_False_sample_rows_True_sample_pk_True.txt | Generated summary fixture variant for ΔNull%. |
| tests/summary/fixtures/metrics_null_fraction/gen/pretty_True_perfect_True_top_True_slim_False_sample_rows_False_sample_pk_False.txt | Generated summary fixture variant for ΔNull%. |
| tests/summary/fixtures/metrics_null_fraction/gen/pretty_True_perfect_True_top_False_slim_True_sample_rows_True_sample_pk_False.txt | Generated summary fixture variant for ΔNull%. |
| tests/summary/fixtures/metrics_null_fraction/gen/pretty_True_perfect_True_top_False_slim_True_sample_rows_False_sample_pk_False.txt | Generated summary fixture variant for ΔNull%. |
| tests/summary/fixtures/metrics_null_fraction/gen/pretty_True_perfect_True_top_False_slim_False_sample_rows_True_sample_pk_False.txt | Generated summary fixture variant for ΔNull%. |
| tests/summary/fixtures/metrics_null_fraction/gen/pretty_True_perfect_True_top_False_slim_False_sample_rows_False_sample_pk_False.txt | Generated summary fixture variant for ΔNull%. |
| tests/summary/fixtures/metrics_null_fraction/gen/pretty_True_perfect_False_top_True_slim_True_sample_rows_True_sample_pk_True.txt | Generated summary fixture variant for ΔNull%. |
| tests/summary/fixtures/metrics_null_fraction/gen/pretty_True_perfect_False_top_True_slim_True_sample_rows_False_sample_pk_False.txt | Generated summary fixture variant for ΔNull%. |
| tests/summary/fixtures/metrics_null_fraction/gen/pretty_True_perfect_False_top_True_slim_False_sample_rows_True_sample_pk_True.txt | Generated summary fixture variant for ΔNull%. |
| tests/summary/fixtures/metrics_null_fraction/gen/pretty_True_perfect_False_top_True_slim_False_sample_rows_False_sample_pk_False.txt | Generated summary fixture variant for ΔNull%. |
| tests/summary/fixtures/metrics_null_fraction/gen/pretty_True_perfect_False_top_False_slim_True_sample_rows_True_sample_pk_False.txt | Generated summary fixture variant for ΔNull%. |
| tests/summary/fixtures/metrics_null_fraction/gen/pretty_True_perfect_False_top_False_slim_True_sample_rows_False_sample_pk_False.txt | Generated summary fixture variant for ΔNull%. |
| tests/summary/fixtures/metrics_null_fraction/gen/pretty_True_perfect_False_top_False_slim_False_sample_rows_True_sample_pk_False.txt | Generated summary fixture variant for ΔNull%. |
| tests/summary/fixtures/metrics_null_fraction/gen/pretty_True_perfect_False_top_False_slim_False_sample_rows_False_sample_pk_False.txt | Generated summary fixture variant for ΔNull%. |
| tests/summary/fixtures/metrics_null_fraction/gen/pretty_False_perfect_True_top_True_slim_True_sample_rows_True_sample_pk_True.txt | Generated summary fixture variant for ΔNull%. |
| tests/summary/fixtures/metrics_null_fraction/gen/pretty_False_perfect_True_top_True_slim_True_sample_rows_False_sample_pk_False.txt | Generated summary fixture variant for ΔNull%. |
| tests/summary/fixtures/metrics_null_fraction/gen/pretty_False_perfect_True_top_True_slim_False_sample_rows_True_sample_pk_True.txt | Generated summary fixture variant for ΔNull%. |
| tests/summary/fixtures/metrics_null_fraction/gen/pretty_False_perfect_True_top_True_slim_False_sample_rows_False_sample_pk_False.txt | Generated summary fixture variant for ΔNull%. |
| tests/summary/fixtures/metrics_null_fraction/gen/pretty_False_perfect_True_top_False_slim_True_sample_rows_True_sample_pk_False.txt | Generated summary fixture variant for ΔNull%. |
| tests/summary/fixtures/metrics_null_fraction/gen/pretty_False_perfect_True_top_False_slim_True_sample_rows_False_sample_pk_False.txt | Generated summary fixture variant for ΔNull%. |
| tests/summary/fixtures/metrics_null_fraction/gen/pretty_False_perfect_True_top_False_slim_False_sample_rows_True_sample_pk_False.txt | Generated summary fixture variant for ΔNull%. |
| tests/summary/fixtures/metrics_null_fraction/gen/pretty_False_perfect_True_top_False_slim_False_sample_rows_False_sample_pk_False.txt | Generated summary fixture variant for ΔNull%. |
| tests/summary/fixtures/metrics_null_fraction/gen/pretty_False_perfect_False_top_True_slim_True_sample_rows_True_sample_pk_True.txt | Generated summary fixture variant for ΔNull%. |
| tests/summary/fixtures/metrics_null_fraction/gen/pretty_False_perfect_False_top_True_slim_True_sample_rows_False_sample_pk_False.txt | Generated summary fixture variant for ΔNull%. |
| tests/summary/fixtures/metrics_null_fraction/gen/pretty_False_perfect_False_top_True_slim_False_sample_rows_True_sample_pk_True.txt | Generated summary fixture variant for ΔNull%. |
| tests/summary/fixtures/metrics_null_fraction/gen/pretty_False_perfect_False_top_True_slim_False_sample_rows_False_sample_pk_False.txt | Generated summary fixture variant for ΔNull%. |
| tests/summary/fixtures/metrics_null_fraction/gen/pretty_False_perfect_False_top_False_slim_True_sample_rows_True_sample_pk_False.txt | Generated summary fixture variant for ΔNull%. |
| tests/summary/fixtures/metrics_null_fraction/gen/pretty_False_perfect_False_top_False_slim_True_sample_rows_False_sample_pk_False.txt | Generated summary fixture variant for ΔNull%. |
| tests/summary/fixtures/metrics_null_fraction/gen/pretty_False_perfect_False_top_False_slim_False_sample_rows_True_sample_pk_False.txt | Generated summary fixture variant for ΔNull%. |
| tests/summary/fixtures/metrics_null_fraction/gen/pretty_False_perfect_False_top_False_slim_False_sample_rows_False_sample_pk_False.txt | Generated summary fixture variant for ΔNull%. |
| tests/summary/fixtures/metrics_null_fraction/gen/pretty_True_perfect_True_top_True_slim_True_sample_rows_False_sample_pk_False.txt | Generated summary fixture variant for ΔNull%. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Copilot started reviewing on behalf of
Moritz Potthoff (MoritzPotthoffQC)
July 10, 2026 14:40
View session
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Copilot started reviewing on behalf of
Moritz Potthoff (MoritzPotthoffQC)
July 10, 2026 15:35
View session
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
I like the concept of metrics to give the user as much information about their data at first glance. I think it would be nice to extend it even further by generalizing metrics to non-numeric columns. The specific use-case I have for this is to explain how the share of null values in a column changed.
Changes
<old> -> <new> (<delta>). This is consistent with the sample values we show. feat: Improve existing numeric metrics for new output format #44 also applies this to existing metrics in follow-up.