Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature] Support for JSON minimum , maximum, exclusiveMinimum, and exclusiveMaximum #1023

Merged
merged 38 commits into from
Oct 1, 2024

Conversation

hudson-ai
Copy link
Collaborator

@hudson-ai hudson-ai commented Sep 13, 2024

JSON support for integer and float bounds.

Closes #1019 (thanks for the code @mmoskal!)

@codecov-commenter
Copy link

codecov-commenter commented Sep 16, 2024

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

Attention: Patch coverage is 98.06763% with 4 lines in your changes missing coverage. Please review.

Project coverage is 63.04%. Comparing base (6eb08f4) to head (ac64849).
Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
guidance/library/_regex_utils.py 97.54% 4 Missing ⚠️

❗ Your organization needs to install the Codecov GitHub app to enable full functionality.

❗ There is a different number of reports uploaded between BASE (6eb08f4) and HEAD (ac64849). Click for more details.

HEAD has 56 uploads less than BASE
Flag BASE (6eb08f4) HEAD (ac64849)
124 68
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1023      +/-   ##
==========================================
- Coverage   70.25%   63.04%   -7.22%     
==========================================
  Files          62       63       +1     
  Lines        4472     4670     +198     
==========================================
- Hits         3142     2944     -198     
- Misses       1330     1726     +396     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@hudson-ai hudson-ai changed the title [WIP] [Feature] Support for JSON minimum , maximum, exclusiveMinimum, and exclusiveMaximum [Feature] Support for JSON minimum , maximum, exclusiveMinimum, and exclusiveMaximum Sep 19, 2024
@hudson-ai
Copy link
Collaborator Author

Note: we have one xfail here due to the fact that JSON apparently allows trailing .00000... on integers. We could add support for this in the future, but I don't really see a reason to (as doing so doesn't really add any expressive power to a model). Keeping the xfail around as a little piece of "documentation".

Ready for review.

@hudson-ai
Copy link
Collaborator Author

Another note: JSON Schema Draft4 has a slightly different convention around exclusiveMinimum/exclusiveMaximum (where they are treated as bools). We may want to allow schemas using this convention, just because I still see a lot of Draft4 in the wild.

Currently, our Draft202012 validator will reject these schemas, so we should be safe not to handle that case internally. Allowing Draft4 might open a bit of a can of worms, so I want to punt on that for at least a while.

@hudson-ai
Copy link
Collaborator Author

@riedgar-ms let me know if you're satisfied with the tests here :)

Copy link
Collaborator

@riedgar-ms riedgar-ms left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My main concern is the lack of negative number tests in TestBoundedNumeric.

*(5.0, {"type": "integer", "minimum": 5}, True),
marks=pytest.mark.xfail(reason="JSON technically allows trailing zeroes, but we currently don't")
),
(5.1, {"type": "integer", "minimum": 5}, False),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Integer" and "5.1" .... is this telling me something about JSON schema that I don't want to know?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't worry, this is a "should fail" case (see the False in the third slot of the tuple 😄)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably should have made the comment on the previous line :-) The 'reason' gives me bad feelings about potentially subtle bugs (but we have to follow the JSON standard, so 🤷)

(9.9, {"type": "number", "exclusiveMinimum": 5.0, "exclusiveMaximum": 10.0}, True),
# --- Edge cases ---
(0, {"type": "integer", "minimum": 0}, True),
(-1, {"type": "integer", "minimum": 0}, False),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason that these are the only tests of negative numbers?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, that was a terrible oversight on my part. There are a lot more test cases on the underlying regex_utils, but I'll make sure to get some populated in the higher-level json tests.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just the core cases should be enough. Don't need to re-test everything exhaustively.

(6, {"type": "integer", "maximum": 5.5}, False),
(5, {"type": "integer", "exclusiveMaximum": 5.5}, True),
(6, {"type": "integer", "exclusiveMaximum": 5.5}, False),
# --- Large numbers ---
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could add a bunch more large number and precision cases (as I think manically about how floating point can really Mess You Up), but I wouldn't worry right now.

if not right_inclusive and right_int == right:
right_int -= 1
do_test_int_range(rx, left_int, right_int, left_none, right_none)
eps = 0.000001
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like a float epsilon, not a double one?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was just supposed to be a small number. I think we could probably test with 0.0000000001 all way down to 0.1 each 10x or something. AFAIK JSON schema doesn't say numbers are doubles.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wouldn't worry about that right now; my main concern is having more negative numbers in the main test cases. I have the impression that JSON may be a bit relaxed in its concepts of floating point.

@hudson-ai
Copy link
Collaborator Author

@riedgar-ms added some negative test cases. Will merge once I see some green :)

@hudson-ai hudson-ai merged commit 63bfd9f into guidance-ai:main Oct 1, 2024
88 of 100 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.

support for minimum/maximum in JSON schemas
4 participants