@@ -167,26 +167,34 @@ def test_str_constrained_config():
167
167
v .validate_python ('test long' )
168
168
169
169
170
- def test_invalid_regex ():
170
+ @pytest .mark .parametrize ('engine' , [None , 'rust-regex' , 'python-re' ])
171
+ def test_invalid_regex (engine ):
171
172
# TODO uncomment and fix once #150 is done
172
173
# with pytest.raises(SchemaError) as exc_info:
173
174
# SchemaValidator({'type': 'str', 'pattern': 123})
174
175
# assert exc_info.value.args[0] == (
175
176
# 'Error building "str" validator:\n TypeError: \'int\' object cannot be converted to \'PyString\''
176
177
# )
177
178
with pytest .raises (SchemaError ) as exc_info :
178
- SchemaValidator ({'type' : 'str' , 'pattern' : '(abc' })
179
- assert exc_info .value .args [0 ] == (
180
- 'Error building "str" validator:\n '
181
- ' SchemaError: regex parse error:\n '
182
- ' (abc\n '
183
- ' ^\n '
184
- 'error: unclosed group'
185
- )
186
-
187
-
188
- def test_regex_error ():
189
- v = SchemaValidator ({'type' : 'str' , 'pattern' : '11' })
179
+ SchemaValidator (core_schema .str_schema (pattern = '(abc' , regex_engine = engine ))
180
+
181
+ if engine is None or engine == 'rust-regex' :
182
+ assert exc_info .value .args [0 ] == (
183
+ 'Error building "str" validator:\n '
184
+ ' SchemaError: regex parse error:\n '
185
+ ' (abc\n '
186
+ ' ^\n '
187
+ 'error: unclosed group'
188
+ )
189
+ elif engine == 'python-re' :
190
+ assert exc_info .value .args [0 ] == (
191
+ 'Error building "str" validator:\n error: missing ), unterminated subpattern at position 0'
192
+ )
193
+
194
+
195
+ @pytest .mark .parametrize ('engine' , [None , 'rust-regex' , 'python-re' ])
196
+ def test_regex_error (engine ):
197
+ v = SchemaValidator (core_schema .str_schema (pattern = '11' , regex_engine = engine ))
190
198
with pytest .raises (ValidationError ) as exc_info :
191
199
v .validate_python ('12' )
192
200
assert exc_info .value .errors (include_url = False ) == [
@@ -297,3 +305,40 @@ def test_coerce_numbers_to_str_from_json(number: str, expected_str: str) -> None
297
305
298
306
v = SchemaValidator (core_schema .str_schema (), config )
299
307
assert v .validate_json (number ) == expected_str
308
+
309
+
310
+ @pytest .mark .parametrize ('mode' , (None , 'schema' , 'config' ))
311
+ def test_backtracking_regex_rust_unsupported (mode ) -> None :
312
+ pattern = r'r(#*)".*?"\1'
313
+
314
+ with pytest .raises (SchemaError ) as exc_info :
315
+ if mode is None :
316
+ # rust-regex is the default
317
+ SchemaValidator (core_schema .str_schema (pattern = pattern ))
318
+ elif mode == 'schema' :
319
+ SchemaValidator (core_schema .str_schema (pattern = pattern , regex_engine = 'rust-regex' ))
320
+ elif mode == 'config' :
321
+ SchemaValidator (core_schema .str_schema (pattern = pattern ), core_schema .CoreConfig (regex_engine = 'rust-regex' ))
322
+
323
+ assert exc_info .value .args [0 ] == (
324
+ 'Error building \" str\" validator:\n '
325
+ ' SchemaError: regex parse error:\n '
326
+ ' r(#*)\" .*?\" \\ 1\n '
327
+ ' ^^\n '
328
+ 'error: backreferences are not supported'
329
+ )
330
+
331
+
332
+ @pytest .mark .parametrize ('mode' , ('schema' , 'config' ))
333
+ def test_backtracking_regex_python (mode ) -> None :
334
+ pattern = r'r(#*)".*?"\1'
335
+
336
+ if mode == 'schema' :
337
+ v = SchemaValidator (core_schema .str_schema (pattern = pattern , regex_engine = 'python-re' ))
338
+ elif mode == 'config' :
339
+ v = SchemaValidator (core_schema .str_schema (pattern = pattern ), core_schema .CoreConfig (regex_engine = 'python-re' ))
340
+ assert v .validate_python ('r""' ) == 'r""'
341
+ assert v .validate_python ('r#""#' ) == 'r#""#'
342
+ with pytest .raises (ValidationError ):
343
+ # not a valid match for the pattern
344
+ v .validate_python ('r#"#' )
0 commit comments