Skip to content

Commit

Permalink
initial fix up of typehints
Browse files Browse the repository at this point in the history
  • Loading branch information
kratsg committed Dec 7, 2023
1 parent 531e0ba commit bc7fffa
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 30 deletions.
11 changes: 6 additions & 5 deletions src/pyhf/schema/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@
from pyhf.schema.loader import load_schema
from pyhf.schema.validator import validate
from pyhf.schema import variables
from pyhf.typing import Self, SchemaVersion, Traversable
from pyhf.typing import Self, SchemaVersion, PathOrStr, Traversable
from pyhf.schema.upgrader import upgrade

from pathlib import Path

__all__ = [
"load_schema",
"validate",
Expand Down Expand Up @@ -65,8 +67,7 @@ class Schema(sys.modules[__name__].__class__): # type: ignore[misc]
"""

# type ignore below, see https://github.com/python/mypy/pull/11666
def __call__(self, new_path: Traversable) -> Self: # type: ignore[valid-type]
def __call__(self, new_path: PathOrStr) -> Self:
"""
Change the local search path for finding schemas locally.
Expand All @@ -76,7 +77,7 @@ def __call__(self, new_path: Traversable) -> Self: # type: ignore[valid-type]
Returns:
self (pyhf.schema.Schema): Returns itself (for contextlib management)
"""
self.orig_path, variables.schemas = variables.schemas, new_path
self.orig_path, variables.schemas = variables.schemas, Path(new_path)
self.orig_cache = dict(variables.SCHEMA_CACHE)
variables.SCHEMA_CACHE.clear()
return self
Expand All @@ -95,7 +96,7 @@ def __exit__(self, *args: Any, **kwargs: Any) -> None:
variables.SCHEMA_CACHE = self.orig_cache

@property
def path(self) -> Traversable:
def path(self) -> Traversable | Path:
"""
The local path for schemas.
"""
Expand Down
63 changes: 39 additions & 24 deletions src/pyhf/schema/validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,14 @@
from pyhf.schema.loader import load_schema
from pyhf.typing import Workspace, Model, Measurement, PatchSet
from typing import Any
import sys

# importlib.resources.as_file wasn't added until Python 3.9
# c.f. https://docs.python.org/3.9/library/importlib.html#importlib.resources.as_file
if sys.version_info >= (3, 9):
from importlib import resources
else:
import importlib_resources as resources

log = logging.getLogger(__name__)

Expand Down Expand Up @@ -84,29 +92,36 @@ def validate(
f"Specification requested version {version} but latest is {latest_known_version}. Upgrade your specification or downgrade pyhf."
)

if version is None:
msg = f'The version for {schema_name} is not set and could not be determined automatically as there is no default version specified for this schema. This could be due to using a schema that pyhf is not aware of, or a mistake.'
raise ValueError(msg)

schema = load_schema(str(Path(version).joinpath(schema_name)))

# note: trailing slash needed for RefResolver to resolve correctly and by
# design, pathlib strips trailing slashes. See ref below:
# * https://bugs.python.org/issue21039
# * https://github.com/python/cpython/issues/65238
resolver = jsonschema.RefResolver(
base_uri=f"{Path(variables.schemas).joinpath(version).as_uri()}/",
referrer=schema_name,
store=variables.SCHEMA_CACHE,
)

Validator = jsonschema.Draft202012Validator

if allow_tensors:
type_checker = Validator.TYPE_CHECKER.redefine(
"array", _is_array_or_tensor
).redefine("number", _is_number_or_tensor_subtype)
Validator = jsonschema.validators.extend(Validator, type_checker=type_checker)

validator = Validator(schema, resolver=resolver, format_checker=None)

try:
return validator.validate(spec)
except jsonschema.ValidationError as err:
raise pyhf.exceptions.InvalidSpecification(err, schema_name) # type: ignore[no-untyped-call]
with resources.as_file(variables.schemas) as path:
# note: trailing slash needed for RefResolver to resolve correctly and by
# design, pathlib strips trailing slashes. See ref below:
# * https://bugs.python.org/issue21039
# * https://github.com/python/cpython/issues/65238
resolver = jsonschema.RefResolver(
base_uri=f"{path.joinpath(version).as_uri()}/",
referrer=schema_name,
store=variables.SCHEMA_CACHE,
)

Validator = jsonschema.Draft202012Validator

if allow_tensors:
type_checker = Validator.TYPE_CHECKER.redefine(
"array", _is_array_or_tensor
).redefine("number", _is_number_or_tensor_subtype)
Validator = jsonschema.validators.extend(
Validator, type_checker=type_checker
)

validator = Validator(schema, resolver=resolver, format_checker=None)

try:
return validator.validate(spec)
except jsonschema.ValidationError as err:
raise pyhf.exceptions.InvalidSpecification(err, schema_name) # type: ignore[no-untyped-call]
4 changes: 3 additions & 1 deletion src/pyhf/schema/variables.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@
import sys
from pyhf.typing import Schema, SchemaVersion, Traversable

from pathlib import Path

# importlib.resources.as_file wasn't added until Python 3.9
# c.f. https://docs.python.org/3.9/library/importlib.html#importlib.resources.as_file
if sys.version_info >= (3, 9):
from importlib import resources
else:
import importlib_resources as resources
schemas: Traversable = resources.files('pyhf') / "schemas"
schemas: Traversable | Path = resources.files('pyhf') / "schemas"

SCHEMA_CACHE: dict[str, Schema] = {}
SCHEMA_BASE = "https://scikit-hep.org/pyhf/schemas/"
Expand Down

0 comments on commit bc7fffa

Please sign in to comment.