We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Schema validation crashes when running in an environment without internet access
### Summary

In master and the 0.7.0 release candidate, pyhf operations involving model validation will crash in offline environments with a RefResolutionError. This is a common situation e.g. with worker nodes on HTC clusters.
The bug was introduced after 0.6.3, I think in #1753 where the [pre-loading was dropped](https://github.com/scikit-hep/pyhf/pull/1753/files#diff-01a944844c3739d996c27da33c727473ec48ebcac65f16b4001384bc3ae4e725L48).

### OS / Environment

```console
NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7"
HOME_URL="http://cern.ch/linux/"
BUG_REPORT_URL="http://cern.ch/linux/"

CENTOS_MANTISBT_PROJECT="CentOS-7"
CENTOS_MANTISBT_PROJECT_VERSION="7"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="7"
```


### Steps to Reproduce

I don't know a good way to prepare the environment to demonstrate this. 
But the below test exposes the attempt by the RefResolver to resolve the schema id through the https URL, and fails against the release candidate/master, but passes in 0.6.3
<!--- Paste your minimal failing Python example code between the quotes below -->
```python (paste below)
from functools import partial

import pytest
import jsonschema
import pyhf

def make_asserting_handler(origin):
    def asserting_handler(*args, **kwargs):
        raise AssertionError(
            f'called URL request handler from {origin} with args={args!r}, kwargs={kwargs!r} '
            'when no call should have been needed'
        )

    return asserting_handler


@pytest.fixture
def no_http_jsonschema_ref_resolving(monkeypatch):
    asserting_handler = make_asserting_handler('handlers')
    handlers = {
        'https': asserting_handler,
        'http': asserting_handler,
    }
    WrappedResolver = partial(jsonschema.RefResolver, handlers=handlers)
    monkeypatch.setattr('jsonschema.RefResolver', WrappedResolver, raising=True)

def test_preloaded_cache(
    no_http_jsonschema_ref_resolving,
):
    spec = {
        'channels': [
            {
                'name': 'singlechannel',
                'samples': [
                    {
                        'name': 'signal',
                        'data': [10],
                        'modifiers': [
                            {'name': 'mu', 'type': 'normfactor', 'data': None}
                        ],
                    },
                    {
                        'name': 'background',
                        'data': [20],
                        'modifiers': [
                            {
                                'name': 'uncorr_bkguncrt',
                                'type': 'shapesys',
                                'data': [30],
                            }
                        ],
                    },
                ],
            }
        ]
    }
    try:
        pyhf.schema.validate(spec, 'model.json')
    except AttributeError:
        pyhf.utils.validate(spec, 'model.json')
                                               
```


### File Upload (optional)

_No response_

### Expected Results

I expect schema validation to succeed without crashing even when there is no network access that allows resolving the https schema-ids.

### Actual Results

```console
jsonschema.exceptions.RefResolutionError: HTTPSConnectionPool(host='scikit-hep.org', port=443): Max retries exceeded with url: /pyhf/schemas/1.0.0/defs.json (Caused by NewConnectionError('<urllib3.connection.HTTPSConnection object at 0x2b2bb8457c40>: Failed to establish a new connection: [Errno 101] Network is unreachable'))
```


### pyhf Version

```console
pyhf, version 0.7.0rc2
```


### Code of Conduct

- [X] I agree to follow the Code of Conduct

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `src/pyhf/schema/loader.py`
Content:
```
1 from pathlib import Path
2 import sys
3 import json
4 import pyhf.exceptions
5 from pyhf.schema import variables
6 
7 # importlib.resources.as_file wasn't added until Python 3.9
8 # c.f. https://docs.python.org/3.9/library/importlib.html#importlib.resources.as_file
9 if sys.version_info >= (3, 9):
10     from importlib import resources
11 else:
12     import importlib_resources as resources
13 
14 
15 def load_schema(schema_id: str):
16     """
17     Get a schema by relative path from cache, or load it into the cache and return.
18 
19     Args:
20         schema_id (str): Relative path to schema from :attr:`pyhf.schema.path`
21 
22     Returns:
23         schema (dict): The loaded schema.
24     """
25     try:
26         return variables.SCHEMA_CACHE[
27             f'{Path(variables.SCHEMA_BASE).joinpath(schema_id)}'
28         ]
29     except KeyError:
30         pass
31 
32     ref = variables.schemas.joinpath(schema_id)
33     with resources.as_file(ref) as path:
34         if not path.exists():
35             raise pyhf.exceptions.SchemaNotFound(
36                 f'The schema {schema_id} was not found. Do you have the right version or the right path? {path}'
37             )
38         with path.open() as json_schema:
39             schema = json.load(json_schema)
40             variables.SCHEMA_CACHE[schema['$id']] = schema
41         return variables.SCHEMA_CACHE[schema['$id']]
42
```

Path: `setup.py`
Content:
```
1 from setuptools import setup
2 
3 extras_require = {
4     'shellcomplete': ['click_completion'],
5     'tensorflow': [
6         'tensorflow>=2.6.5',  # c.f. PR #1874
7         'tensorflow-probability>=0.11.0',  # c.f. PR #1657
8     ],
9     'torch': ['torch>=1.10.0'],  # c.f. PR #1657
10     'jax': ['jax>=0.2.10', 'jaxlib>=0.1.60,!=0.1.68'],  # c.f. Issue 1501
11     'xmlio': ['uproot>=4.1.1'],  # c.f. PR #1567
12     'minuit': ['iminuit>=2.7.0'],  # c.f. PR #1895
13 }
14 extras_require['backends'] = sorted(
15     set(
16         extras_require['tensorflow']
17         + extras_require['torch']
18         + extras_require['jax']
19         + extras_require['minuit']
20     )
21 )
22 extras_require['contrib'] = sorted({'matplotlib', 'requests'})
23 extras_require['test'] = sorted(
24     set(
25         extras_require['backends']
26         + extras_require['xmlio']
27         + extras_require['contrib']
28         + extras_require['shellcomplete']
29         + [
30             'scikit-hep-testdata>=0.4.11',
31             'pytest>=6.0',
32             'pytest-cov>=2.5.1',
33             'pytest-mock',
34             'requests-mock>=1.9.0',
35             'pytest-benchmark[histogram]',
36             'pytest-console-scripts',
37             'pytest-mpl',
38             'pydocstyle',
39             'papermill~=2.3.4',
40             'scrapbook~=0.5.0',
41             'jupyter',
42             'graphviz',
43         ]
44     )
45 )
46 extras_require['docs'] = sorted(
47     set(
48         extras_require['xmlio']
49         + extras_require['contrib']
50         + [
51             'sphinx>=5.1.1',  # c.f. https://github.com/scikit-hep/pyhf/pull/1926
52             'sphinxcontrib-bibtex~=2.1',
53             'sphinx-click',
54             'sphinx_rtd_theme',
55             'nbsphinx!=0.8.8',  # c.f. https://github.com/spatialaudio/nbsphinx/issues/620
56             'ipywidgets',
57             'sphinx-issues',
58             'sphinx-copybutton>=0.3.2',
59             'sphinx-togglebutton>=0.3.0',
60         ]
61     )
62 )
63 extras_require['develop'] = sorted(
64     set(
65         extras_require['docs']
66         + extras_require['test']
67         + [
68             'nbdime',
69             'tbump>=6.7.0',
70             'ipython',
71             'pre-commit',
72             'check-manifest',
73             'codemetapy>=0.3.4',
74             'twine',
75         ]
76     )
77 )
78 extras_require['complete'] = sorted(set(sum(extras_require.values(), [])))
79 
80 
81 setup(
82     extras_require=extras_require,
83     use_scm_version=lambda: {'local_scheme': lambda version: ''},
84 )
85
```

Path: `src/pyhf/schema/__init__.py`
Content:
```
1 """
2 See :class:`~pyhf.schema.Schema` for documentation.
3 """
4 import pathlib
5 import sys
6 from pyhf.schema.loader import load_schema
7 from pyhf.schema.validator import validate
8 from pyhf.schema import variables
9 
10 __all__ = [
11     "load_schema",
12     "validate",
13     "path",
14     "version",
15 ]
16 
17 
18 def __dir__():
19     return __all__
20 
21 
22 class Schema(sys.modules[__name__].__class__):
23     """
24     A module-level wrapper around :mod:`pyhf.schema` which will provide additional functionality for interacting with schemas.
25 
26     .. rubric:: Example (callable)
27 
28     .. code-block:: pycon
29 
30         >>> import pyhf.schema
31         >>> import pathlib
32         >>> curr_path = pyhf.schema.path
33         >>> curr_path  # doctest: +ELLIPSIS
34         PosixPath('.../pyhf/schemas')
35         >>> new_path = pathlib.Path("/home/root/my/new/path")
36         >>> pyhf.schema(new_path)  # doctest: +ELLIPSIS
37         <module 'pyhf.schema' from ...>
38         >>> pyhf.schema.path
39         PosixPath('/home/root/my/new/path')
40         >>> pyhf.schema(curr_path)  # doctest: +ELLIPSIS
41         <module 'pyhf.schema' from ...>
42         >>> pyhf.schema.path  # doctest: +ELLIPSIS
43         PosixPath('.../pyhf/schemas')
44 
45     .. rubric:: Example (context-manager)
46 
47     .. code-block:: pycon
48 
49         >>> import pyhf.schema
50         >>> import pathlib
51         >>> curr_path = pyhf.schema.path
52         >>> curr_path  # doctest: +ELLIPSIS
53         PosixPath('.../pyhf/schemas')
54         >>> new_path = pathlib.Path("/home/root/my/new/path")
55         >>> with pyhf.schema(new_path):
56         ...     print(repr(pyhf.schema.path))
57         ...
58         PosixPath('/home/root/my/new/path')
59         >>> pyhf.schema.path  # doctest: +ELLIPSIS
60         PosixPath('.../pyhf/schemas')
61 
62     """
63 
64     def __call__(self, new_path: pathlib.Path):
65         """
66         Change the local search path for finding schemas locally.
67 
68         Args:
69             new_path (pathlib.Path): Path to folder containing the schemas
70 
71         Returns:
72             self (pyhf.schema.Schema): Returns itself (for contextlib management)
73         """
74         self.orig_path, variables.schemas = variables.schemas, new_path
75         return self
76 
77     def __enter__(self):
78         pass
79 
80     def __exit__(self, *args, **kwargs):
81         """
82         Reset the local search path for finding schemas locally.
83 
84         Returns:
85             None
86         """
87         variables.schemas = self.orig_path
88 
89     @property
90     def path(self):
91         """
92         The local path for schemas.
93         """
94         return variables.schemas
95 
96     @property
97     def version(self):
98         """
99         The default version used for finding schemas.
100         """
101         return variables.SCHEMA_VERSION
102 
103 
104 sys.modules[__name__].__class__ = Schema
105
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -40,6 +40,7 @@
             'scrapbook~=0.5.0',
             'jupyter',
             'graphviz',
+            'pytest-socket>=0.2.0',  # c.f. PR #1917
         ]
     )
 )
diff --git a/src/pyhf/schema/__init__.py b/src/pyhf/schema/__init__.py
--- a/src/pyhf/schema/__init__.py
+++ b/src/pyhf/schema/__init__.py
@@ -72,6 +72,8 @@
             self (pyhf.schema.Schema): Returns itself (for contextlib management)
         """
         self.orig_path, variables.schemas = variables.schemas, new_path
+        self.orig_cache = dict(variables.SCHEMA_CACHE)
+        variables.SCHEMA_CACHE.clear()
         return self
 
     def __enter__(self):
@@ -85,6 +87,7 @@
             None
         """
         variables.schemas = self.orig_path
+        variables.SCHEMA_CACHE = self.orig_cache
 
     @property
     def path(self):
diff --git a/src/pyhf/schema/loader.py b/src/pyhf/schema/loader.py
--- a/src/pyhf/schema/loader.py
+++ b/src/pyhf/schema/loader.py
@@ -39,3 +39,9 @@
             schema = json.load(json_schema)
             variables.SCHEMA_CACHE[schema['$id']] = schema
         return variables.SCHEMA_CACHE[schema['$id']]
+
+
+# pre-populate the cache to avoid network access
+# on first validation in standard usage
+# (not in pyhf.schema.variables to avoid circular imports)
+load_schema(f'{variables.SCHEMA_VERSION}/defs.json')

{"golden_diff": "diff --git a/setup.py b/setup.py\n--- a/setup.py\n+++ b/setup.py\n@@ -40,6 +40,7 @@\n             'scrapbook~=0.5.0',\n             'jupyter',\n             'graphviz',\n+            'pytest-socket>=0.2.0',  # c.f. PR #1917\n         ]\n     )\n )\ndiff --git a/src/pyhf/schema/__init__.py b/src/pyhf/schema/__init__.py\n--- a/src/pyhf/schema/__init__.py\n+++ b/src/pyhf/schema/__init__.py\n@@ -72,6 +72,8 @@\n             self (pyhf.schema.Schema): Returns itself (for contextlib management)\n         \"\"\"\n         self.orig_path, variables.schemas = variables.schemas, new_path\n+        self.orig_cache = dict(variables.SCHEMA_CACHE)\n+        variables.SCHEMA_CACHE.clear()\n         return self\n \n     def __enter__(self):\n@@ -85,6 +87,7 @@\n             None\n         \"\"\"\n         variables.schemas = self.orig_path\n+        variables.SCHEMA_CACHE = self.orig_cache\n \n     @property\n     def path(self):\ndiff --git a/src/pyhf/schema/loader.py b/src/pyhf/schema/loader.py\n--- a/src/pyhf/schema/loader.py\n+++ b/src/pyhf/schema/loader.py\n@@ -39,3 +39,9 @@\n             schema = json.load(json_schema)\n             variables.SCHEMA_CACHE[schema['$id']] = schema\n         return variables.SCHEMA_CACHE[schema['$id']]\n+\n+\n+# pre-populate the cache to avoid network access\n+# on first validation in standard usage\n+# (not in pyhf.schema.variables to avoid circular imports)\n+load_schema(f'{variables.SCHEMA_VERSION}/defs.json')\n", "issue": "Schema validation crashes when running in an environment without internet access\n### Summary\r\n\r\nIn master and the 0.7.0 release candidate, pyhf operations involving model validation will crash in offline environments with a RefResolutionError. This is a common situation e.g. with worker nodes on HTC clusters.\r\nThe bug was introduced after 0.6.3, I think in #1753 where the [pre-loading was dropped](https://github.com/scikit-hep/pyhf/pull/1753/files#diff-01a944844c3739d996c27da33c727473ec48ebcac65f16b4001384bc3ae4e725L48).\r\n\r\n### OS / Environment\r\n\r\n```console\r\nNAME=\"CentOS Linux\"\r\nVERSION=\"7 (Core)\"\r\nID=\"centos\"\r\nID_LIKE=\"rhel fedora\"\r\nVERSION_ID=\"7\"\r\nPRETTY_NAME=\"CentOS Linux 7 (Core)\"\r\nANSI_COLOR=\"0;31\"\r\nCPE_NAME=\"cpe:/o:centos:centos:7\"\r\nHOME_URL=\"http://cern.ch/linux/\"\r\nBUG_REPORT_URL=\"http://cern.ch/linux/\"\r\n\r\nCENTOS_MANTISBT_PROJECT=\"CentOS-7\"\r\nCENTOS_MANTISBT_PROJECT_VERSION=\"7\"\r\nREDHAT_SUPPORT_PRODUCT=\"centos\"\r\nREDHAT_SUPPORT_PRODUCT_VERSION=\"7\"\r\n```\r\n\r\n\r\n### Steps to Reproduce\r\n\r\nI don't know a good way to prepare the environment to demonstrate this. \r\nBut the below test exposes the attempt by the RefResolver to resolve the schema id through the https URL, and fails against the release candidate/master, but passes in 0.6.3\r\n<!--- Paste your minimal failing Python example code between the quotes below -->\r\n```python (paste below)\r\nfrom functools import partial\r\n\r\nimport pytest\r\nimport jsonschema\r\nimport pyhf\r\n\r\ndef make_asserting_handler(origin):\r\n    def asserting_handler(*args, **kwargs):\r\n        raise AssertionError(\r\n            f'called URL request handler from {origin} with args={args!r}, kwargs={kwargs!r} '\r\n            'when no call should have been needed'\r\n        )\r\n\r\n    return asserting_handler\r\n\r\n\r\n@pytest.fixture\r\ndef no_http_jsonschema_ref_resolving(monkeypatch):\r\n    asserting_handler = make_asserting_handler('handlers')\r\n    handlers = {\r\n        'https': asserting_handler,\r\n        'http': asserting_handler,\r\n    }\r\n    WrappedResolver = partial(jsonschema.RefResolver, handlers=handlers)\r\n    monkeypatch.setattr('jsonschema.RefResolver', WrappedResolver, raising=True)\r\n\r\ndef test_preloaded_cache(\r\n    no_http_jsonschema_ref_resolving,\r\n):\r\n    spec = {\r\n        'channels': [\r\n            {\r\n                'name': 'singlechannel',\r\n                'samples': [\r\n                    {\r\n                        'name': 'signal',\r\n                        'data': [10],\r\n                        'modifiers': [\r\n                            {'name': 'mu', 'type': 'normfactor', 'data': None}\r\n                        ],\r\n                    },\r\n                    {\r\n                        'name': 'background',\r\n                        'data': [20],\r\n                        'modifiers': [\r\n                            {\r\n                                'name': 'uncorr_bkguncrt',\r\n                                'type': 'shapesys',\r\n                                'data': [30],\r\n                            }\r\n                        ],\r\n                    },\r\n                ],\r\n            }\r\n        ]\r\n    }\r\n    try:\r\n        pyhf.schema.validate(spec, 'model.json')\r\n    except AttributeError:\r\n        pyhf.utils.validate(spec, 'model.json')\r\n                                               \r\n```\r\n\r\n\r\n### File Upload (optional)\r\n\r\n_No response_\r\n\r\n### Expected Results\r\n\r\nI expect schema validation to succeed without crashing even when there is no network access that allows resolving the https schema-ids.\r\n\r\n### Actual Results\r\n\r\n```console\r\njsonschema.exceptions.RefResolutionError: HTTPSConnectionPool(host='scikit-hep.org', port=443): Max retries exceeded with url: /pyhf/schemas/1.0.0/defs.json (Caused by NewConnectionError('<urllib3.connection.HTTPSConnection object at 0x2b2bb8457c40>: Failed to establish a new connection: [Errno 101] Network is unreachable'))\r\n```\r\n\r\n\r\n### pyhf Version\r\n\r\n```console\r\npyhf, version 0.7.0rc2\r\n```\r\n\r\n\r\n### Code of Conduct\r\n\r\n- [X] I agree to follow the Code of Conduct\n", "before_files": [{"content": "from pathlib import Path\nimport sys\nimport json\nimport pyhf.exceptions\nfrom pyhf.schema import variables\n\n# importlib.resources.as_file wasn't added until Python 3.9\n# c.f. https://docs.python.org/3.9/library/importlib.html#importlib.resources.as_file\nif sys.version_info >= (3, 9):\n    from importlib import resources\nelse:\n    import importlib_resources as resources\n\n\ndef load_schema(schema_id: str):\n    \"\"\"\n    Get a schema by relative path from cache, or load it into the cache and return.\n\n    Args:\n        schema_id (str): Relative path to schema from :attr:`pyhf.schema.path`\n\n    Returns:\n        schema (dict): The loaded schema.\n    \"\"\"\n    try:\n        return variables.SCHEMA_CACHE[\n            f'{Path(variables.SCHEMA_BASE).joinpath(schema_id)}'\n        ]\n    except KeyError:\n        pass\n\n    ref = variables.schemas.joinpath(schema_id)\n    with resources.as_file(ref) as path:\n        if not path.exists():\n            raise pyhf.exceptions.SchemaNotFound(\n                f'The schema {schema_id} was not found. Do you have the right version or the right path? {path}'\n            )\n        with path.open() as json_schema:\n            schema = json.load(json_schema)\n            variables.SCHEMA_CACHE[schema['$id']] = schema\n        return variables.SCHEMA_CACHE[schema['$id']]\n", "path": "src/pyhf/schema/loader.py"}, {"content": "from setuptools import setup\n\nextras_require = {\n    'shellcomplete': ['click_completion'],\n    'tensorflow': [\n        'tensorflow>=2.6.5',  # c.f. PR #1874\n        'tensorflow-probability>=0.11.0',  # c.f. PR #1657\n    ],\n    'torch': ['torch>=1.10.0'],  # c.f. PR #1657\n    'jax': ['jax>=0.2.10', 'jaxlib>=0.1.60,!=0.1.68'],  # c.f. Issue 1501\n    'xmlio': ['uproot>=4.1.1'],  # c.f. PR #1567\n    'minuit': ['iminuit>=2.7.0'],  # c.f. PR #1895\n}\nextras_require['backends'] = sorted(\n    set(\n        extras_require['tensorflow']\n        + extras_require['torch']\n        + extras_require['jax']\n        + extras_require['minuit']\n    )\n)\nextras_require['contrib'] = sorted({'matplotlib', 'requests'})\nextras_require['test'] = sorted(\n    set(\n        extras_require['backends']\n        + extras_require['xmlio']\n        + extras_require['contrib']\n        + extras_require['shellcomplete']\n        + [\n            'scikit-hep-testdata>=0.4.11',\n            'pytest>=6.0',\n            'pytest-cov>=2.5.1',\n            'pytest-mock',\n            'requests-mock>=1.9.0',\n            'pytest-benchmark[histogram]',\n            'pytest-console-scripts',\n            'pytest-mpl',\n            'pydocstyle',\n            'papermill~=2.3.4',\n            'scrapbook~=0.5.0',\n            'jupyter',\n            'graphviz',\n        ]\n    )\n)\nextras_require['docs'] = sorted(\n    set(\n        extras_require['xmlio']\n        + extras_require['contrib']\n        + [\n            'sphinx>=5.1.1',  # c.f. https://github.com/scikit-hep/pyhf/pull/1926\n            'sphinxcontrib-bibtex~=2.1',\n            'sphinx-click',\n            'sphinx_rtd_theme',\n            'nbsphinx!=0.8.8',  # c.f. https://github.com/spatialaudio/nbsphinx/issues/620\n            'ipywidgets',\n            'sphinx-issues',\n            'sphinx-copybutton>=0.3.2',\n            'sphinx-togglebutton>=0.3.0',\n        ]\n    )\n)\nextras_require['develop'] = sorted(\n    set(\n        extras_require['docs']\n        + extras_require['test']\n        + [\n            'nbdime',\n            'tbump>=6.7.0',\n            'ipython',\n            'pre-commit',\n            'check-manifest',\n            'codemetapy>=0.3.4',\n            'twine',\n        ]\n    )\n)\nextras_require['complete'] = sorted(set(sum(extras_require.values(), [])))\n\n\nsetup(\n    extras_require=extras_require,\n    use_scm_version=lambda: {'local_scheme': lambda version: ''},\n)\n", "path": "setup.py"}, {"content": "\"\"\"\nSee :class:`~pyhf.schema.Schema` for documentation.\n\"\"\"\nimport pathlib\nimport sys\nfrom pyhf.schema.loader import load_schema\nfrom pyhf.schema.validator import validate\nfrom pyhf.schema import variables\n\n__all__ = [\n    \"load_schema\",\n    \"validate\",\n    \"path\",\n    \"version\",\n]\n\n\ndef __dir__():\n    return __all__\n\n\nclass Schema(sys.modules[__name__].__class__):\n    \"\"\"\n    A module-level wrapper around :mod:`pyhf.schema` which will provide additional functionality for interacting with schemas.\n\n    .. rubric:: Example (callable)\n\n    .. code-block:: pycon\n\n        >>> import pyhf.schema\n        >>> import pathlib\n        >>> curr_path = pyhf.schema.path\n        >>> curr_path  # doctest: +ELLIPSIS\n        PosixPath('.../pyhf/schemas')\n        >>> new_path = pathlib.Path(\"/home/root/my/new/path\")\n        >>> pyhf.schema(new_path)  # doctest: +ELLIPSIS\n        <module 'pyhf.schema' from ...>\n        >>> pyhf.schema.path\n        PosixPath('/home/root/my/new/path')\n        >>> pyhf.schema(curr_path)  # doctest: +ELLIPSIS\n        <module 'pyhf.schema' from ...>\n        >>> pyhf.schema.path  # doctest: +ELLIPSIS\n        PosixPath('.../pyhf/schemas')\n\n    .. rubric:: Example (context-manager)\n\n    .. code-block:: pycon\n\n        >>> import pyhf.schema\n        >>> import pathlib\n        >>> curr_path = pyhf.schema.path\n        >>> curr_path  # doctest: +ELLIPSIS\n        PosixPath('.../pyhf/schemas')\n        >>> new_path = pathlib.Path(\"/home/root/my/new/path\")\n        >>> with pyhf.schema(new_path):\n        ...     print(repr(pyhf.schema.path))\n        ...\n        PosixPath('/home/root/my/new/path')\n        >>> pyhf.schema.path  # doctest: +ELLIPSIS\n        PosixPath('.../pyhf/schemas')\n\n    \"\"\"\n\n    def __call__(self, new_path: pathlib.Path):\n        \"\"\"\n        Change the local search path for finding schemas locally.\n\n        Args:\n            new_path (pathlib.Path): Path to folder containing the schemas\n\n        Returns:\n            self (pyhf.schema.Schema): Returns itself (for contextlib management)\n        \"\"\"\n        self.orig_path, variables.schemas = variables.schemas, new_path\n        return self\n\n    def __enter__(self):\n        pass\n\n    def __exit__(self, *args, **kwargs):\n        \"\"\"\n        Reset the local search path for finding schemas locally.\n\n        Returns:\n            None\n        \"\"\"\n        variables.schemas = self.orig_path\n\n    @property\n    def path(self):\n        \"\"\"\n        The local path for schemas.\n        \"\"\"\n        return variables.schemas\n\n    @property\n    def version(self):\n        \"\"\"\n        The default version used for finding schemas.\n        \"\"\"\n        return variables.SCHEMA_VERSION\n\n\nsys.modules[__name__].__class__ = Schema\n", "path": "src/pyhf/schema/__init__.py"}], "after_files": [{"content": "from pathlib import Path\nimport sys\nimport json\nimport pyhf.exceptions\nfrom pyhf.schema import variables\n\n# importlib.resources.as_file wasn't added until Python 3.9\n# c.f. https://docs.python.org/3.9/library/importlib.html#importlib.resources.as_file\nif sys.version_info >= (3, 9):\n    from importlib import resources\nelse:\n    import importlib_resources as resources\n\n\ndef load_schema(schema_id: str):\n    \"\"\"\n    Get a schema by relative path from cache, or load it into the cache and return.\n\n    Args:\n        schema_id (str): Relative path to schema from :attr:`pyhf.schema.path`\n\n    Returns:\n        schema (dict): The loaded schema.\n    \"\"\"\n    try:\n        return variables.SCHEMA_CACHE[\n            f'{Path(variables.SCHEMA_BASE).joinpath(schema_id)}'\n        ]\n    except KeyError:\n        pass\n\n    ref = variables.schemas.joinpath(schema_id)\n    with resources.as_file(ref) as path:\n        if not path.exists():\n            raise pyhf.exceptions.SchemaNotFound(\n                f'The schema {schema_id} was not found. Do you have the right version or the right path? {path}'\n            )\n        with path.open() as json_schema:\n            schema = json.load(json_schema)\n            variables.SCHEMA_CACHE[schema['$id']] = schema\n        return variables.SCHEMA_CACHE[schema['$id']]\n\n\n# pre-populate the cache to avoid network access\n# on first validation in standard usage\n# (not in pyhf.schema.variables to avoid circular imports)\nload_schema(f'{variables.SCHEMA_VERSION}/defs.json')\n", "path": "src/pyhf/schema/loader.py"}, {"content": "from setuptools import setup\n\nextras_require = {\n    'shellcomplete': ['click_completion'],\n    'tensorflow': [\n        'tensorflow>=2.6.5',  # c.f. PR #1874\n        'tensorflow-probability>=0.11.0',  # c.f. PR #1657\n    ],\n    'torch': ['torch>=1.10.0'],  # c.f. PR #1657\n    'jax': ['jax>=0.2.10', 'jaxlib>=0.1.60,!=0.1.68'],  # c.f. Issue 1501\n    'xmlio': ['uproot>=4.1.1'],  # c.f. PR #1567\n    'minuit': ['iminuit>=2.7.0'],  # c.f. PR #1895\n}\nextras_require['backends'] = sorted(\n    set(\n        extras_require['tensorflow']\n        + extras_require['torch']\n        + extras_require['jax']\n        + extras_require['minuit']\n    )\n)\nextras_require['contrib'] = sorted({'matplotlib', 'requests'})\nextras_require['test'] = sorted(\n    set(\n        extras_require['backends']\n        + extras_require['xmlio']\n        + extras_require['contrib']\n        + extras_require['shellcomplete']\n        + [\n            'scikit-hep-testdata>=0.4.11',\n            'pytest>=6.0',\n            'pytest-cov>=2.5.1',\n            'pytest-mock',\n            'requests-mock>=1.9.0',\n            'pytest-benchmark[histogram]',\n            'pytest-console-scripts',\n            'pytest-mpl',\n            'pydocstyle',\n            'papermill~=2.3.4',\n            'scrapbook~=0.5.0',\n            'jupyter',\n            'graphviz',\n            'pytest-socket>=0.2.0',  # c.f. PR #1917\n        ]\n    )\n)\nextras_require['docs'] = sorted(\n    set(\n        extras_require['xmlio']\n        + extras_require['contrib']\n        + [\n            'sphinx>=5.1.1',  # c.f. https://github.com/scikit-hep/pyhf/pull/1926\n            'sphinxcontrib-bibtex~=2.1',\n            'sphinx-click',\n            'sphinx_rtd_theme',\n            'nbsphinx!=0.8.8',  # c.f. https://github.com/spatialaudio/nbsphinx/issues/620\n            'ipywidgets',\n            'sphinx-issues',\n            'sphinx-copybutton>=0.3.2',\n            'sphinx-togglebutton>=0.3.0',\n        ]\n    )\n)\nextras_require['develop'] = sorted(\n    set(\n        extras_require['docs']\n        + extras_require['test']\n        + [\n            'nbdime',\n            'tbump>=6.7.0',\n            'ipython',\n            'pre-commit',\n            'check-manifest',\n            'codemetapy>=0.3.4',\n            'twine',\n        ]\n    )\n)\nextras_require['complete'] = sorted(set(sum(extras_require.values(), [])))\n\n\nsetup(\n    extras_require=extras_require,\n    use_scm_version=lambda: {'local_scheme': lambda version: ''},\n)\n", "path": "setup.py"}, {"content": "\"\"\"\nSee :class:`~pyhf.schema.Schema` for documentation.\n\"\"\"\nimport pathlib\nimport sys\nfrom pyhf.schema.loader import load_schema\nfrom pyhf.schema.validator import validate\nfrom pyhf.schema import variables\n\n__all__ = [\n    \"load_schema\",\n    \"validate\",\n    \"path\",\n    \"version\",\n]\n\n\ndef __dir__():\n    return __all__\n\n\nclass Schema(sys.modules[__name__].__class__):\n    \"\"\"\n    A module-level wrapper around :mod:`pyhf.schema` which will provide additional functionality for interacting with schemas.\n\n    .. rubric:: Example (callable)\n\n    .. code-block:: pycon\n\n        >>> import pyhf.schema\n        >>> import pathlib\n        >>> curr_path = pyhf.schema.path\n        >>> curr_path  # doctest: +ELLIPSIS\n        PosixPath('.../pyhf/schemas')\n        >>> new_path = pathlib.Path(\"/home/root/my/new/path\")\n        >>> pyhf.schema(new_path)  # doctest: +ELLIPSIS\n        <module 'pyhf.schema' from ...>\n        >>> pyhf.schema.path\n        PosixPath('/home/root/my/new/path')\n        >>> pyhf.schema(curr_path)  # doctest: +ELLIPSIS\n        <module 'pyhf.schema' from ...>\n        >>> pyhf.schema.path  # doctest: +ELLIPSIS\n        PosixPath('.../pyhf/schemas')\n\n    .. rubric:: Example (context-manager)\n\n    .. code-block:: pycon\n\n        >>> import pyhf.schema\n        >>> import pathlib\n        >>> curr_path = pyhf.schema.path\n        >>> curr_path  # doctest: +ELLIPSIS\n        PosixPath('.../pyhf/schemas')\n        >>> new_path = pathlib.Path(\"/home/root/my/new/path\")\n        >>> with pyhf.schema(new_path):\n        ...     print(repr(pyhf.schema.path))\n        ...\n        PosixPath('/home/root/my/new/path')\n        >>> pyhf.schema.path  # doctest: +ELLIPSIS\n        PosixPath('.../pyhf/schemas')\n\n    \"\"\"\n\n    def __call__(self, new_path: pathlib.Path):\n        \"\"\"\n        Change the local search path for finding schemas locally.\n\n        Args:\n            new_path (pathlib.Path): Path to folder containing the schemas\n\n        Returns:\n            self (pyhf.schema.Schema): Returns itself (for contextlib management)\n        \"\"\"\n        self.orig_path, variables.schemas = variables.schemas, new_path\n        self.orig_cache = dict(variables.SCHEMA_CACHE)\n        variables.SCHEMA_CACHE.clear()\n        return self\n\n    def __enter__(self):\n        pass\n\n    def __exit__(self, *args, **kwargs):\n        \"\"\"\n        Reset the local search path for finding schemas locally.\n\n        Returns:\n            None\n        \"\"\"\n        variables.schemas = self.orig_path\n        variables.SCHEMA_CACHE = self.orig_cache\n\n    @property\n    def path(self):\n        \"\"\"\n        The local path for schemas.\n        \"\"\"\n        return variables.schemas\n\n    @property\n    def version(self):\n        \"\"\"\n        The default version used for finding schemas.\n        \"\"\"\n        return variables.SCHEMA_VERSION\n\n\nsys.modules[__name__].__class__ = Schema\n", "path": "src/pyhf/schema/__init__.py"}]}