Skip to content

Commit c4814c6

Browse files
committed
Rename --format-regex and update docs
Docs cover the expected usage, which is not implemented in this initial change. The rename and alias is all that's covered here.
1 parent a4e407c commit c4814c6

File tree

7 files changed

+85
-48
lines changed

7 files changed

+85
-48
lines changed

CHANGELOG.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ Unreleased
99
----------
1010

1111
.. vendor-insert-here
12+
- Rename ``--format-regex`` to ``--regex-variant`` and convert
13+
``--format-regex`` to a deprecated alias.
14+
It will be removed in a future release.
1215

1316
- Update vendored schemas (2024-12-22)
1417
- Drop support for Python 3.8

docs/usage.rst

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -183,11 +183,11 @@ Example usage:
183183
# disables all three of time, date-time, and iri
184184
--disable-formats time,date-time --disable-formats iri
185185
186-
``--format-regex``
186+
``--regex-variant``
187187
~~~~~~~~~~~~~~~~~~
188188

189-
Set a mode for handling of the ``"regex"`` value for ``"format"``. The modes are as
190-
follows:
189+
Set a mode for handling of the ``"regex"`` value for ``"format"`` and the mode
190+
for ``"pattern"`` interpretation. The modes are as follows:
191191

192192
.. list-table:: Regex Options
193193
:widths: 15 30
@@ -196,9 +196,15 @@ follows:
196196
* - mode
197197
- description
198198
* - default
199-
- Require the regex to be valid in ECMAScript regex syntax.
199+
- Use ECMAScript regex syntax.
200200
* - python
201-
- Require the regex to be valid in Python regex syntax.
201+
- Use Python regex syntax.
202+
203+
.. note::
204+
205+
This only controls the regex mode used for ``format`` and ``pattern``.
206+
``patternProperties`` is not currently controlled, and always uses the
207+
Python engine.
202208

203209
Other Options
204210
--------------

src/check_jsonschema/checker.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ def __init__(
2828
instance_loader: InstanceLoader,
2929
reporter: Reporter,
3030
*,
31-
format_opts: FormatOptions | None = None,
31+
format_opts: FormatOptions,
3232
traceback_mode: str = "short",
3333
fill_defaults: bool = False,
3434
) -> None:

src/check_jsonschema/cli/main_command.py

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,10 @@ def pretty_helptext_list(values: list[str] | tuple[str, ...]) -> str:
6868
date, date-time, email, ipv4, ipv6, regex, uuid
6969
7070
\b
71-
For the "regex" format, there are multiple modes which can be specified with
72-
'--format-regex':
73-
default | check that the string is a valid ECMAScript regex
74-
python | check that the string is a valid python regex
71+
For handling of regexes, there are multiple modes which can be specified with
72+
'--regex-variant':
73+
default | use ECMAScript regex syntax (via regress)
74+
python | use python regex syntax
7575
7676
\b
7777
The '--builtin-schema' flag supports the following schema names:
@@ -138,11 +138,18 @@ def pretty_helptext_list(values: list[str] | tuple[str, ...]) -> str:
138138
)
139139
@click.option(
140140
"--format-regex",
141+
hidden=True,
142+
help="Legacy name for `--regex-variant`.",
143+
default=None,
144+
type=click.Choice([x.value for x in RegexVariantName], case_sensitive=False),
145+
)
146+
@click.option(
147+
"--regex-variant",
141148
help=(
142-
"Set the mode of format validation for regexes. "
143-
"If `--disable-formats regex` is used, this option has no effect."
149+
"Name of which regex dialect should be used for format checking "
150+
"and 'pattern' matching."
144151
),
145-
default=RegexVariantName.default.value,
152+
default=None,
146153
type=click.Choice([x.value for x in RegexVariantName], case_sensitive=False),
147154
)
148155
@click.option(
@@ -230,7 +237,8 @@ def main(
230237
no_cache: bool,
231238
cache_filename: str | None,
232239
disable_formats: tuple[list[str], ...],
233-
format_regex: t.Literal["python", "default"],
240+
format_regex: t.Literal["python", "default"] | None,
241+
regex_variant: t.Literal["python", "default"] | None,
234242
default_filetype: t.Literal["json", "yaml", "toml", "json5"],
235243
traceback_mode: t.Literal["full", "short"],
236244
data_transform: t.Literal["azure-pipelines", "gitlab-ci"] | None,
@@ -243,6 +251,8 @@ def main(
243251
) -> None:
244252
args = ParseResult()
245253

254+
args.set_regex_variant(regex_variant, legacy_opt=format_regex)
255+
246256
args.set_schema(schemafile, builtin_schema, check_metaschema)
247257
args.set_validator(validator_class)
248258

@@ -257,7 +267,6 @@ def main(
257267
else:
258268
args.disable_formats = normalized_disable_formats
259269

260-
args.format_regex = RegexVariantName(format_regex)
261270
args.disable_cache = no_cache
262271
args.default_filetype = default_filetype
263272
args.fill_defaults = fill_defaults

src/check_jsonschema/cli/parse_result.py

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,21 @@
11
from __future__ import annotations
22

33
import enum
4+
import sys
45
import typing as t
56

67
import click
78
import jsonschema
89

9-
from ..formats import FormatOptions, RegexVariantName
10+
from ..formats import FormatOptions
11+
from ..regex_variants import RegexVariantName
1012
from ..transforms import Transform
1113

14+
if sys.version_info >= (3, 8):
15+
from typing import Literal
16+
else:
17+
from typing_extensions import Literal
18+
1219

1320
class SchemaLoadingMode(enum.Enum):
1421
filepath = "filepath"
@@ -36,12 +43,22 @@ def __init__(self) -> None:
3643
# regex format options
3744
self.disable_all_formats: bool = False
3845
self.disable_formats: tuple[str, ...] = ()
39-
self.format_regex: RegexVariantName = RegexVariantName.default
46+
self.regex_variant: RegexVariantName = RegexVariantName.default
4047
# error and output controls
4148
self.verbosity: int = 1
4249
self.traceback_mode: str = "short"
4350
self.output_format: str = "text"
4451

52+
def set_regex_variant(
53+
self,
54+
variant_opt: Literal["python", "default"] | None,
55+
*,
56+
legacy_opt: Literal["python", "default"] | None = None,
57+
) -> None:
58+
variant_name: Literal["python", "default"] | None = variant_opt or legacy_opt
59+
if variant_name:
60+
self.regex_variant = RegexVariantName(variant_name)
61+
4562
def set_schema(
4663
self, schemafile: str | None, builtin_schema: str | None, check_metaschema: bool
4764
) -> None:
@@ -83,6 +100,6 @@ def set_validator(
83100
def format_opts(self) -> FormatOptions:
84101
return FormatOptions(
85102
enabled=not self.disable_all_formats,
86-
regex_variant=self.format_regex,
103+
regex_variant=self.regex_variant,
87104
disabled_formats=self.disable_formats,
88105
)

src/check_jsonschema/formats/__init__.py

Lines changed: 1 addition & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,11 @@
11
from __future__ import annotations
22

33
import copy
4-
import enum
5-
import re
6-
import typing as t
74

85
import jsonschema
96
import jsonschema.validators
10-
import regress
117

8+
from ..regex_variants import RegexImplementation, RegexVariantName
129
from .implementations import validate_rfc3339, validate_time
1310

1411
# all known format strings except for a selection from draft3 which have either
@@ -39,32 +36,6 @@
3936
)
4037

4138

42-
class RegexVariantName(enum.Enum):
43-
default = "default"
44-
python = "python"
45-
46-
47-
class RegexImplementation:
48-
def __init__(self, variant: RegexVariantName) -> None:
49-
self.variant = variant
50-
51-
def check_format(self, instance: t.Any) -> bool:
52-
if not isinstance(instance, str):
53-
return True
54-
55-
try:
56-
if self.variant == RegexVariantName.default:
57-
regress.Regex(instance)
58-
else:
59-
re.compile(instance)
60-
# something is wrong with RegressError getting into the published types
61-
# needs investigation... for now, ignore the error
62-
except (regress.RegressError, re.error): # type: ignore[attr-defined]
63-
return False
64-
65-
return True
66-
67-
6839
class FormatOptions:
6940
def __init__(
7041
self,
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import enum
2+
import re
3+
import typing as t
4+
5+
import regress
6+
7+
8+
class RegexVariantName(enum.Enum):
9+
default = "default"
10+
python = "python"
11+
12+
13+
class RegexImplementation:
14+
def __init__(self, variant: RegexVariantName) -> None:
15+
self.variant = variant
16+
17+
def check_format(self, instance: t.Any) -> bool:
18+
if not isinstance(instance, str):
19+
return True
20+
21+
try:
22+
if self.variant == RegexVariantName.default:
23+
regress.Regex(instance)
24+
else:
25+
re.compile(instance)
26+
# something is wrong with RegressError getting into the published types
27+
# needs investigation... for now, ignore the error
28+
except (regress.RegressError, re.error): # type: ignore[attr-defined]
29+
return False
30+
31+
return True

0 commit comments

Comments
 (0)