@@ -173,7 +173,7 @@ def test_nonnegative_integer_fields(self, field):
173173 with pytest .raises (ValueError , match = f"{ field } ` must be >= 0, got -10" ):
174174 Meta (** {field : - 10 })
175175
176- @pytest .mark .parametrize ("field" , ["pattern" , " title" , "description" ])
176+ @pytest .mark .parametrize ("field" , ["title" , "description" ])
177177 def test_string_fields (self , field ):
178178 Meta (** {field : "good" })
179179 with pytest .raises (TypeError , match = f"`{ field } ` must be a str, got bytes" ):
@@ -202,6 +202,14 @@ def test_invalid_pattern_errors(self):
202202 with pytest .raises (re .error ):
203203 Meta (pattern = "[abc" )
204204
205+ @pytest .mark .parametrize ("good" , ("string" , re .compile ("string" )))
206+ def test_pattern_valid_type (self , good ):
207+ Meta (pattern = good )
208+
209+ def test_pattern_invalid_type (self ):
210+ with pytest .raises (TypeError , match = f"`pattern` must be a str, or an re.Pattern like type, got bytes" ):
211+ Meta (pattern = b"bad" )
212+
205213 def test_conflicting_bounds_errors (self ):
206214 with pytest .raises (ValueError , match = "both `gt` and `ge`" ):
207215 Meta (gt = 0 , ge = 1 )
@@ -443,6 +451,14 @@ class Ex(msgspec.Struct):
443451 assert dec .decode (proto .encode (Ex (x )))
444452
445453
454+ class CustomRegexPattern :
455+ def __init__ (self , pattern : str ) -> None :
456+ self .pattern = pattern
457+
458+ def search (self , v : str ) -> re .Match [str ] | None :
459+ return re .search (self .pattern , v )
460+
461+
446462class TestStrConstraints :
447463 def test_min_length (self , proto ):
448464 class Ex (msgspec .Struct ):
@@ -478,6 +494,8 @@ class Ex(msgspec.Struct):
478494 ("" , ["" , "test" ], []),
479495 ("as" , ["as" , "ease" , "ast" , "pass" ], ["" , "nope" ]),
480496 ("^pre[123]*$" , ["pre1" , "pre123" ], ["apre1" , "pre1two" ]),
497+ pytest .param (re .compile ("as" ), ["as" ], ["nope" ], id = "re.Pattern" ),
498+ pytest .param (CustomRegexPattern ("as" ), ["as" ], ["nope" ], id = "CustomPattern" ),
481499 ],
482500 )
483501 def test_pattern (self , proto , pattern , good , bad ):
@@ -489,7 +507,8 @@ class Ex(msgspec.Struct):
489507 for x in good :
490508 assert dec .decode (proto .encode (Ex (x ))).x == x
491509
492- err_msg = f"Expected `str` matching regex { pattern !r} - at `$.x`"
510+ raw_pattern = pattern if isinstance (pattern , str ) else pattern .pattern
511+ err_msg = f"Expected `str` matching regex { raw_pattern !r} - at `$.x`"
493512 for x in bad :
494513 with pytest .raises (msgspec .ValidationError ) as rec :
495514 dec .decode (proto .encode (Ex (x )))
0 commit comments