|
16 | 16 | from polyfactory.field_meta import Constraints, FieldMeta, Null |
17 | 17 | from polyfactory.utils.deprecation import check_for_deprecated_parameters |
18 | 18 | from polyfactory.utils.helpers import unwrap_new_type, unwrap_optional |
19 | | -from polyfactory.utils.predicates import is_optional, is_safe_subclass, is_union |
| 19 | +from polyfactory.utils.predicates import is_annotated, is_optional, is_safe_subclass, is_union |
20 | 20 | from polyfactory.utils.types import NoneType |
21 | 21 | from polyfactory.value_generators.primitives import create_random_bytes |
22 | 22 |
|
@@ -270,31 +270,37 @@ def from_model_field( # pragma: no cover |
270 | 270 | else unwrap_new_type(model_field.annotation) |
271 | 271 | ) |
272 | 272 |
|
273 | | - constraints = cast( |
274 | | - "Constraints", |
275 | | - { |
276 | | - "ge": getattr(outer_type, "ge", model_field.field_info.ge), |
277 | | - "gt": getattr(outer_type, "gt", model_field.field_info.gt), |
278 | | - "le": getattr(outer_type, "le", model_field.field_info.le), |
279 | | - "lt": getattr(outer_type, "lt", model_field.field_info.lt), |
280 | | - "min_length": ( |
281 | | - getattr(outer_type, "min_length", model_field.field_info.min_length) |
282 | | - or getattr(outer_type, "min_items", model_field.field_info.min_items) |
283 | | - ), |
284 | | - "max_length": ( |
285 | | - getattr(outer_type, "max_length", model_field.field_info.max_length) |
286 | | - or getattr(outer_type, "max_items", model_field.field_info.max_items) |
287 | | - ), |
288 | | - "pattern": getattr(outer_type, "regex", model_field.field_info.regex), |
289 | | - "unique_items": getattr(outer_type, "unique_items", model_field.field_info.unique_items), |
290 | | - "decimal_places": getattr(outer_type, "decimal_places", None), |
291 | | - "max_digits": getattr(outer_type, "max_digits", None), |
292 | | - "multiple_of": getattr(outer_type, "multiple_of", None), |
293 | | - "upper_case": getattr(outer_type, "to_upper", None), |
294 | | - "lower_case": getattr(outer_type, "to_lower", None), |
295 | | - "item_type": getattr(outer_type, "item_type", None), |
296 | | - }, |
297 | | - ) |
| 273 | + # In pydantic v1, we need to check if the annotation is directly annotated to properly extract constraints |
| 274 | + # from the metadata, as v1 doesn't automatically propagate constraints like v2 does |
| 275 | + annotation_constraints: Constraints = {} |
| 276 | + if is_annotated(model_field.annotation): |
| 277 | + annotation_metadata = cls.get_constraints_metadata(model_field.annotation) |
| 278 | + annotation_constraints = cls.parse_constraints(annotation_metadata) if annotation_metadata else {} |
| 279 | + |
| 280 | + field_info_constraints = { |
| 281 | + "ge": getattr(outer_type, "ge", model_field.field_info.ge), |
| 282 | + "gt": getattr(outer_type, "gt", model_field.field_info.gt), |
| 283 | + "le": getattr(outer_type, "le", model_field.field_info.le), |
| 284 | + "lt": getattr(outer_type, "lt", model_field.field_info.lt), |
| 285 | + "min_length": ( |
| 286 | + getattr(outer_type, "min_length", model_field.field_info.min_length) |
| 287 | + or getattr(outer_type, "min_items", model_field.field_info.min_items) |
| 288 | + ), |
| 289 | + "max_length": ( |
| 290 | + getattr(outer_type, "max_length", model_field.field_info.max_length) |
| 291 | + or getattr(outer_type, "max_items", model_field.field_info.max_items) |
| 292 | + ), |
| 293 | + "pattern": getattr(outer_type, "regex", model_field.field_info.regex), |
| 294 | + "unique_items": getattr(outer_type, "unique_items", model_field.field_info.unique_items), |
| 295 | + "decimal_places": getattr(outer_type, "decimal_places", None), |
| 296 | + "max_digits": getattr(outer_type, "max_digits", None), |
| 297 | + "multiple_of": getattr(outer_type, "multiple_of", None), |
| 298 | + "upper_case": getattr(outer_type, "to_upper", None), |
| 299 | + "lower_case": getattr(outer_type, "to_lower", None), |
| 300 | + "item_type": getattr(outer_type, "item_type", None), |
| 301 | + } |
| 302 | + |
| 303 | + constraints = cast("Constraints", {**field_info_constraints, **annotation_constraints}) |
298 | 304 |
|
299 | 305 | # pydantic v1 has constraints set for these values, but we generate them using faker |
300 | 306 | if unwrap_optional(annotation) in ( |
|
0 commit comments