-
Notifications
You must be signed in to change notification settings - Fork 85
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
feat: Alternative Schema Locations #1753
Conversation
Codecov Report
@@ Coverage Diff @@
## master #1753 +/- ##
==========================================
- Coverage 98.14% 98.02% -0.13%
==========================================
Files 64 68 +4
Lines 4270 4310 +40
Branches 719 725 +6
==========================================
+ Hits 4191 4225 +34
- Misses 46 49 +3
- Partials 33 36 +3
Flags with carried forward coverage won't be shown. Click here to find out more.
Continue to review full report at Codecov.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kratsg Just a question, the general idea of
import pyhf, pathlib, json
pyhf.utils.schemas = pathlib.Path('/Users/kratsg/pyhf/myschemas')
ws = pyhf.Workspace(json.load(open('myschemas/custom.json')))
of being able to update the schema path seems fine, but instead of having users overwriting the value by assignment, do you think there is value in offering a pyhf.utils.update_schema_path
or something that performs this operation through the API?
Other than that things seem to be looking good here I think. Though maybe worth also asking @alexander-held and maybe @lhenkelm as they asked for this in Issue #1609, and so might have some thoughts.
Thanks @kratsg for taking up my suggestion! I second @matthewfeickert's suggestion to change schemas via function call rather than assignment. It is much simpler to add functionality to a function if it ever becomes necessary, than to replace an entire existing module with a class instance with a property. I'd even go so far to say that a context manager doubling as an update function would be ideal IMO: # in pyhf.utils
_SCHEMAS = Path(...)
class use_schema_path: # snake_case to remind of function-like usage
def __init__(self, path):
global _SCHEMAS
self._old_schemas = _SCHEMAS
_SCHEMAS = pathlib.Path(path)
def __enter__(self):
pass
def __exit__(self, *args, **kwargs):
global _SCHEMAS
_SCHEMAS = self._old_schemas which can still be called as a function (only executing def make_my_workspace(spec):
with pyhf.utils.use_schema_path('/my/very/special/schemas'):
return pyhf.Workspace(spec) So as a user writing code on top of pyhf, I don't have to worry about resesetting the global variable, the CM does it for me, and there are fewer mistakes to make. |
a4d1d79
to
abe11f4
Compare
abe11f4
to
7f2fae3
Compare
7f2fae3
to
5148451
Compare
This is filed as #1815 so this PR isn't overtly complicated. The API for this PR will be |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for this nice work @kratsg. Overall it looks really solid 👍 and stepping through it with you annotations (thanks! 🙏) I see that it isn't really that bad at all (just looks like a lot).
I have a few super minor suggestions that are more just around testing and adding notes for ourselves in the future and then just one question (though it might not even be necessary if my question comes from me being confused).
Co-authored-by: Matthew Feickert <matthew.feickert@cern.ch>
Co-authored-by: Matthew Feickert <matthew.feickert@cern.ch>
Co-authored-by: Matthew Feickert <matthew.feickert@cern.ch>
Co-authored-by: Matthew Feickert <matthew.feickert@cern.ch>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @kratsg. LGTM now!
LGTM! |
* Report coverage for the oldest Python (3.7) and newest (3.10) that are tested to ensure that version specific 'if' statements are properly covered. * Add Python version specific flags to the coverage reporting to compare differences in coverage and track coverage changes across versions more easily. * Follow up to PR #1753
* Add contextlib support to the pyhf.schema API. - Follow up to PR #1753. * Add tests for use of the schema contextlib to tests/test_schema.py. * Add tests for use of the schema contextlib to the public API tests.
* Load `defs.json` into `schema.variables.SCHEMA_CACHE` from the local file. - in line with what was done before in PR #1753 * Add pytest-socket as a dependency of the 'test' extra. `pytest_socket.socket_disabled` was added in pytest-socket v0.2.0. - c.f. https://github.com/miketheman/pytest-socket/releases/tag/0.2.0 * Add a unit test to catch this regression in the future. * `pyhf.schema` clears the cache to avoid stale schemas (and restores the cache if used as a CM). * Amend unit tests for `pyhf.schema` to test the correct treatment of the cache.
Description
Resolves #1609.
Refactor:
pkg_resources
toimportlib
. See migration guide and details about importlib.load_schema
will handle functionality for finding the schema locations locally in multiple placesload_schema
will not handleversion
identification (that is done throughvalidate
only)Feature:
pyhf
installed location as a base viapyhf.utils.schemas
load_schema
commands)SchemaNotFound
exception for when a schema cannot be found locally (outside ofjsonschema.RefResolver
calls)Example Usage:
and then additionally, a nice benefit (maybe?) we get for free is that code which generates against a different schema won't work and fails more loudly (where it might have been more silent in the past).
Documentation: https://pyhf--1753.org.readthedocs.build/en/1753/api.html#schema
Checklist Before Requesting Reviewer
Before Merging
For the PR Assignees: