|
4 | 4 | import os
|
5 | 5 | import warnings
|
6 | 6 | from abc import ABC, abstractmethod
|
| 7 | +from collections import deque |
7 | 8 | from dataclasses import is_dataclass
|
8 | 9 | from pathlib import Path
|
9 |
| -from typing import TYPE_CHECKING, Any, Dict, List, Mapping, Optional, Tuple, Type, Union |
| 10 | +from typing import TYPE_CHECKING, Any, Dict, List, Mapping, Optional, Sequence, Tuple, Type, Union |
10 | 11 |
|
11 | 12 | from pydantic import BaseModel
|
12 | 13 | from pydantic._internal._typing_extra import origin_is_union
|
@@ -53,10 +54,16 @@ def get_field_value(self, field: FieldInfo, field_name: str) -> Tuple[Any, str,
|
53 | 54 | pass
|
54 | 55 |
|
55 | 56 | def field_is_complex(self, field: FieldInfo) -> bool:
|
56 |
| - def _annotation_is_complex(annotation: type[Any] | None) -> bool: |
57 |
| - return lenient_issubclass(annotation, (BaseModel, list, set, frozenset, dict)) or is_dataclass(annotation) |
| 57 | + """ |
| 58 | + Checks whether a field is complex, in which case it will attempt to be parsed as JSON. |
| 59 | +
|
| 60 | + Args: |
| 61 | + field (FieldInfo): The field. |
58 | 62 |
|
59 |
| - return _annotation_is_complex(field.annotation) or _annotation_is_complex(get_origin(field.annotation)) |
| 63 | + Returns: |
| 64 | + bool: Whether the field is complex. |
| 65 | + """ |
| 66 | + return _annotation_is_complex(field.annotation) |
60 | 67 |
|
61 | 68 | def prepare_field_value(self, field_name: str, field: FieldInfo, value: Any, value_is_complex: bool) -> Any:
|
62 | 69 | """
|
@@ -433,3 +440,22 @@ def find_case_path(dir_path: Path, file_name: str, case_sensitive: bool) -> Opti
|
433 | 440 | elif not case_sensitive and f.name.lower() == file_name.lower():
|
434 | 441 | return f
|
435 | 442 | return None
|
| 443 | + |
| 444 | + |
| 445 | +def _annotation_is_complex(annotation: type[Any] | None) -> bool: |
| 446 | + origin = get_origin(annotation) |
| 447 | + return ( |
| 448 | + _annotation_is_complex_inner(annotation) |
| 449 | + or _annotation_is_complex_inner(origin) |
| 450 | + or hasattr(origin, '__pydantic_core_schema__') |
| 451 | + or hasattr(origin, '__get_pydantic_core_schema__') |
| 452 | + ) |
| 453 | + |
| 454 | + |
| 455 | +def _annotation_is_complex_inner(annotation: type[Any] | None) -> bool: |
| 456 | + if lenient_issubclass(annotation, str): |
| 457 | + return False |
| 458 | + |
| 459 | + return lenient_issubclass(annotation, (BaseModel, Mapping, Sequence, tuple, set, frozenset, deque)) or is_dataclass( |
| 460 | + annotation |
| 461 | + ) |
0 commit comments