|
11 | 11 |
|
12 | 12 | import jsonschema
|
13 | 13 | from hypothesis import assume, provisional as prov, strategies as st
|
14 |
| -from hypothesis.errors import InvalidArgument |
| 14 | +from hypothesis.errors import HypothesisWarning, InvalidArgument |
15 | 15 | from hypothesis.internal.conjecture import utils as cu
|
16 | 16 |
|
17 | 17 | from ._canonicalise import (
|
@@ -76,8 +76,11 @@ def from_schema(
|
76 | 76 | ) -> st.SearchStrategy[JSONType]:
|
77 | 77 | """Take a JSON schema and return a strategy for allowed JSON objects.
|
78 | 78 |
|
79 |
| - Schema reuse with "definitions" and "$ref" is not yet supported, but |
80 |
| - everything else in drafts 04, 05, and 07 is fully tested and working. |
| 79 | + To generate specific string formats, pass a ``custom_formats`` dict |
| 80 | + mapping the format name to a strategy for allowed strings. |
| 81 | +
|
| 82 | + Supports JSONSchema drafts 04, 06, and 07, with the exception of |
| 83 | + recursive references. |
81 | 84 | """
|
82 | 85 | try:
|
83 | 86 | return __from_schema(schema, custom_formats=custom_formats)
|
@@ -127,13 +130,18 @@ def __from_schema(
|
127 | 130 | for name, strat in custom_formats.items():
|
128 | 131 | if not isinstance(name, str):
|
129 | 132 | raise InvalidArgument(f"format name {name!r} must be a string")
|
130 |
| - if name in STRING_FORMATS: |
131 |
| - raise InvalidArgument(f"Cannot redefine standard format {name!r}") |
132 | 133 | if not isinstance(strat, st.SearchStrategy):
|
133 | 134 | raise InvalidArgument(
|
134 | 135 | f"custom_formats[{name!r}]={strat!r} must be a Hypothesis "
|
135 | 136 | "strategy which generates strings matching this format."
|
136 | 137 | )
|
| 138 | + if name in STRING_FORMATS: |
| 139 | + warnings.warn( |
| 140 | + f"Overriding standard format {name!r} - was " |
| 141 | + f"{STRING_FORMATS[name]!r}, now {strat!r}", |
| 142 | + HypothesisWarning, |
| 143 | + stacklevel=2, |
| 144 | + ) |
137 | 145 | format_checker = jsonschema.FormatChecker()
|
138 | 146 | custom_formats = {
|
139 | 147 | name: _get_format_filter(name, format_checker, strategy)
|
@@ -406,7 +414,7 @@ def string_schema(
|
406 | 414 | min_size = schema.get("minLength", 0)
|
407 | 415 | max_size = schema.get("maxLength")
|
408 | 416 | strategy = st.text(min_size=min_size, max_size=max_size)
|
409 |
| - known_formats = {**(custom_formats or {}), **STRING_FORMATS} |
| 417 | + known_formats = {**STRING_FORMATS, **(custom_formats or {})} |
410 | 418 | if schema.get("format") in known_formats:
|
411 | 419 | # Unknown "format" specifiers should be ignored for validation.
|
412 | 420 | # See https://json-schema.org/latest/json-schema-validation.html#format
|
|
0 commit comments