Skip to content

fix(context): compare allowed values by type for numeric and boolean columns - #380

Merged
kevincostner17 merged 1 commit into
mainfrom
fix/context-allowed-values
Sep 15, 2026
Merged

kevincostner17 merged 1 commit into
mainfrom
fix/context-allowed-values

Conversation

@kevincostner17

Copy link
Copy Markdown
Contributor

Summary

fd.validate's allowed_values check stringified both the column and the declared values, so float columns (1.0 vs 1) and bool columns (True vs true) reported every row as a violation. The stringified value_set also leaked into export_gx_suite (and export_dbt_tests), producing expectations that fail on every row.

The comparison now follows the column dtype:

  • bool / nullable boolean: allowed entries map case-insensitively from true/false/yes/no/t/f/y/n/1/0.
  • other numeric: allowed entries are parsed as finite numbers and compared with exact numeric equality (1 matches 1.0).
  • everything else: unchanged string comparison.

Missing values are still ignored. extra["value_set"] and observed_value now carry typed values, so GX expect_column_values_to_be_in_set gets [1, 2, 3] / [true, false] and dbt accepted_values emits unquoted numbers/booleans. Allowed entries that don't convert stay in value_set as strings but can't match typed values.

Tests

New tests/context/test_allowed_values_typed.py: issue repro, float column with 1.5, 2.5, int column (typed value_set/observed_value), nullable Int64 with missing values, non-numeric entry on a numeric column, bool spellings (true/false, yes/no, mixed case, 1/0, Y/n), nullable boolean, string column unchanged, GX export typed value_set, dbt export typed scalars.

Verification

  • ruff check . — pass
  • mypy src/freshdata — no issues
  • pytest -m "not online and not large" — py3.12: 4261 passed, 6 skipped; py3.9: 4257 passed, 10 skipped (before rebasing onto current main; context and integration suites re-run after the rebase on both)

Closes #255

…columns

_check_allowed_values stringified both sides, so a float column's 1.0
('1.0') never matched a declared '1' and a bool column's True ('True')
never matched 'true'. Every value in those columns was reported as a
violation, and the stringified value_set was passed through to the
Great Expectations and dbt exporters, which then failed on every row too.

Now the comparison follows the column dtype:
- bool / nullable boolean columns: allowed entries map case-insensitively
  from true/false/yes/no/t/f/y/n/1/0 to bools;
- other numeric columns: allowed entries are parsed as finite numbers and
  compared with exact numeric equality (1 matches 1.0);
- all other columns keep the existing string comparison.

Missing values are still ignored. extra["value_set"] and observed_value
now carry the typed values, so exported GX expectations and dbt
accepted_values tests use numbers and booleans. Allowed entries that do
not convert stay in value_set as strings but cannot match typed values.

Closes #255
@coderabbitai

coderabbitai Bot commented Sep 15, 2026

Copy link
Copy Markdown
Contributor

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: 8852c30f-060c-4ceb-aea3-e002a4e2b044


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown

FreshData benchmark report — performance

  • freshdata: ?
  • python: ?
  • platform: ?
fixture n_rows n_cols p50 s p95 s peak MB repair % false-repair % preserve % trust monotonic export %

Authored-code reduction (Metric 6)

@kevincostner17
kevincostner17 merged commit 548f069 into main Sep 15, 2026
21 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fd.validate allowed_values flags every value in float and bool columns

1 participant