@@ -11,24 +11,68 @@ class RegexVariantName(enum.Enum):
1111 python = "python"
1212
1313
14+ class _ConcreteImplementation (t .Protocol ):
15+ def check_format (self , instance : t .Any ) -> bool : ...
16+
17+ def pattern_keyword (
18+ self , validator : t .Any , pattern : str , instance : str , schema : t .Any
19+ ) -> t .Iterator [jsonschema .ValidationError ]: ...
20+
21+
1422class RegexImplementation :
23+ """
24+ A high-level interface for getting at the different possible
25+ implementations of regex behaviors.
26+ """
27+
28+ _real_implementation : _ConcreteImplementation
29+
1530 def __init__ (self , variant : RegexVariantName ) -> None :
1631 self .variant = variant
1732
33+ if self .variant == RegexVariantName .default :
34+ self ._real_implementation = _RegressImplementation ()
35+ else :
36+ self ._real_implementation = _PythonImplementation ()
37+
38+ self .check_format = self ._real_implementation .check_format
39+ self .pattern_keyword = self ._real_implementation .pattern_keyword
40+
41+
42+ class _RegressImplementation :
1843 def check_format (self , instance : t .Any ) -> bool :
1944 if not isinstance (instance , str ):
2045 return True
21-
2246 try :
23- if self .variant == RegexVariantName .default :
24- regress .Regex (instance )
25- else :
26- re .compile (instance )
47+ regress .Regex (instance )
2748 # something is wrong with RegressError getting into the published types
2849 # needs investigation... for now, ignore the error
29- except ( regress .RegressError , re . error ) : # type: ignore[attr-defined]
50+ except regress .RegressError : # type: ignore[attr-defined]
3051 return False
52+ return True
3153
54+ def pattern_keyword (
55+ self , validator : t .Any , pattern : str , instance : str , schema : t .Any
56+ ) -> t .Iterator [jsonschema .ValidationError ]:
57+ if not validator .is_type (instance , "string" ):
58+ return
59+
60+ try :
61+ regress_pattern = regress .Regex (pattern )
62+ except regress .RegressError : # type: ignore[attr-defined]
63+ yield jsonschema .ValidationError (f"pattern { pattern !r} failed to compile" )
64+ if not regress_pattern .find (instance ):
65+ yield jsonschema .ValidationError (f"{ instance !r} does not match { pattern !r} " )
66+
67+
68+ class _PythonImplementation :
69+ def check_format (self , instance : t .Any ) -> bool :
70+ if not isinstance (instance , str ):
71+ return True
72+ try :
73+ re .compile (instance )
74+ except re .error :
75+ return False
3276 return True
3377
3478 def pattern_keyword (
@@ -37,25 +81,9 @@ def pattern_keyword(
3781 if not validator .is_type (instance , "string" ):
3882 return
3983
40- if self .variant == RegexVariantName .default :
41- try :
42- regress_pattern = regress .Regex (pattern )
43- except regress .RegressError : # type: ignore[attr-defined]
44- yield jsonschema .ValidationError (
45- f"pattern { pattern !r} failed to compile"
46- )
47- if not regress_pattern .find (instance ):
48- yield jsonschema .ValidationError (
49- f"{ instance !r} does not match { pattern !r} "
50- )
51- else :
52- try :
53- re_pattern = re .compile (pattern )
54- except re .error :
55- yield jsonschema .ValidationError (
56- f"pattern { pattern !r} failed to compile"
57- )
58- if not re_pattern .search (instance ):
59- yield jsonschema .ValidationError (
60- f"{ instance !r} does not match { pattern !r} "
61- )
84+ try :
85+ re_pattern = re .compile (pattern )
86+ except re .error :
87+ yield jsonschema .ValidationError (f"pattern { pattern !r} failed to compile" )
88+ if not re_pattern .search (instance ):
89+ yield jsonschema .ValidationError (f"{ instance !r} does not match { pattern !r} " )
0 commit comments