Generate schema for a dataclass.
(
self, dataclass: type[StandardDataclass], origin: type[StandardDataclass] | None
)
| 1833 | ) |
| 1834 | |
| 1835 | def _dataclass_schema( |
| 1836 | self, dataclass: type[StandardDataclass], origin: type[StandardDataclass] | None |
| 1837 | ) -> core_schema.CoreSchema: |
| 1838 | """Generate schema for a dataclass.""" |
| 1839 | with ( |
| 1840 | self.model_type_stack.push(dataclass), |
| 1841 | self.defs.get_schema_or_ref(dataclass) as ( |
| 1842 | dataclass_ref, |
| 1843 | maybe_schema, |
| 1844 | ), |
| 1845 | ): |
| 1846 | if maybe_schema is not None: |
| 1847 | return maybe_schema |
| 1848 | |
| 1849 | schema = dataclass.__dict__.get('__pydantic_core_schema__') |
| 1850 | if schema is not None and not isinstance(schema, MockCoreSchema): |
| 1851 | if schema['type'] == 'definitions': |
| 1852 | schema = self.defs.unpack_definitions(schema) |
| 1853 | ref = get_ref(schema) |
| 1854 | if ref: |
| 1855 | return self.defs.create_definition_reference_schema(schema) |
| 1856 | else: |
| 1857 | return schema |
| 1858 | |
| 1859 | typevars_map = get_standard_typevars_map(dataclass) |
| 1860 | if origin is not None: |
| 1861 | dataclass = origin |
| 1862 | |
| 1863 | # if (plain) dataclass doesn't have config, we use the parent's config, hence a default of `None` |
| 1864 | # (Pydantic dataclasses have an empty dict config by default). |
| 1865 | # see https://github.com/pydantic/pydantic/issues/10917 |
| 1866 | config = getattr(dataclass, '__pydantic_config__', None) |
| 1867 | |
| 1868 | from ..dataclasses import is_pydantic_dataclass |
| 1869 | |
| 1870 | with self._ns_resolver.push(dataclass), self._config_wrapper_stack.push(config): |
| 1871 | if is_pydantic_dataclass(dataclass): |
| 1872 | if dataclass.__pydantic_fields_complete__(): |
| 1873 | # Copy the field info instances to avoid mutating the `FieldInfo` instances |
| 1874 | # of the generic dataclass generic origin (e.g. `apply_typevars_map` below). |
| 1875 | # Note that we don't apply `deepcopy` on `__pydantic_fields__` because we |
| 1876 | # don't want to copy the `FieldInfo` attributes: |
| 1877 | fields = { |
| 1878 | f_name: copy(field_info) for f_name, field_info in dataclass.__pydantic_fields__.items() |
| 1879 | } |
| 1880 | if typevars_map: |
| 1881 | for field in fields.values(): |
| 1882 | field.apply_typevars_map(typevars_map, *self._types_namespace) |
| 1883 | else: |
| 1884 | try: |
| 1885 | fields = rebuild_dataclass_fields( |
| 1886 | dataclass, |
| 1887 | config_wrapper=self._config_wrapper, |
| 1888 | ns_resolver=self._ns_resolver, |
| 1889 | typevars_map=typevars_map or {}, |
| 1890 | ) |
| 1891 | except NameError as e: |
| 1892 | raise PydanticUndefinedAnnotation.from_name_error(e) from e |
no test coverage detected