Coverage for pydantic/errors.py: 100.00%

45 statements  

« prev     ^ index     » next       coverage.py v7.9.2, created at 2025-07-20 16:49 +0000

1"""Pydantic-specific errors.""" 

2 

3from __future__ import annotations as _annotations 1abghijklmnopqrscdtuvwxyzABCDPefEFGHIJKLMNO

4 

5import re 1abghijklmnopqrscdtuvwxyzABCDPefEFGHIJKLMNO

6from typing import Any, ClassVar, Literal 1abghijklmnopqrscdtuvwxyzABCDPefEFGHIJKLMNO

7 

8from typing_extensions import Self 1abghijklmnopqrscdtuvwxyzABCDPefEFGHIJKLMNO

9from typing_inspection.introspection import Qualifier 1abghijklmnopqrscdtuvwxyzABCDPefEFGHIJKLMNO

10 

11from pydantic._internal import _repr 1abghijklmnopqrscdtuvwxyzABCDPefEFGHIJKLMNO

12 

13from ._migration import getattr_migration 1abghijklmnopqrscdtuvwxyzABCDPefEFGHIJKLMNO

14from .version import version_short 1abghijklmnopqrscdtuvwxyzABCDPefEFGHIJKLMNO

15 

16__all__ = ( 1abghijklmnopqrscdtuvwxyzABCDPefEFGHIJKLMNO

17 'PydanticUserError', 

18 'PydanticUndefinedAnnotation', 

19 'PydanticImportError', 

20 'PydanticSchemaGenerationError', 

21 'PydanticInvalidForJsonSchema', 

22 'PydanticForbiddenQualifier', 

23 'PydanticErrorCodes', 

24) 

25 

26# We use this URL to allow for future flexibility about how we host the docs, while allowing for Pydantic 

27# code in the while with "old" URLs to still work. 

28# 'u' refers to "user errors" - e.g. errors caused by developers using pydantic, as opposed to validation errors. 

29DEV_ERROR_DOCS_URL = f'https://errors.pydantic.dev/{version_short()}/u/' 1abghijklmnopqrscdtuvwxyzABCDPefEFGHIJKLMNO

30PydanticErrorCodes = Literal[ 1abghijklmnopqrscdtuvwxyzABCDPefEFGHIJKLMNO

31 'class-not-fully-defined', 

32 'custom-json-schema', 

33 'decorator-missing-field', 

34 'discriminator-no-field', 

35 'discriminator-alias-type', 

36 'discriminator-needs-literal', 

37 'discriminator-alias', 

38 'discriminator-validator', 

39 'callable-discriminator-no-tag', 

40 'typed-dict-version', 

41 'model-field-overridden', 

42 'model-field-missing-annotation', 

43 'config-both', 

44 'removed-kwargs', 

45 'circular-reference-schema', 

46 'invalid-for-json-schema', 

47 'json-schema-already-used', 

48 'base-model-instantiated', 

49 'undefined-annotation', 

50 'schema-for-unknown-type', 

51 'import-error', 

52 'create-model-field-definitions', 

53 'validator-no-fields', 

54 'validator-invalid-fields', 

55 'validator-instance-method', 

56 'validator-input-type', 

57 'root-validator-pre-skip', 

58 'model-serializer-instance-method', 

59 'validator-field-config-info', 

60 'validator-v1-signature', 

61 'validator-signature', 

62 'field-serializer-signature', 

63 'model-serializer-signature', 

64 'multiple-field-serializers', 

65 'invalid-annotated-type', 

66 'type-adapter-config-unused', 

67 'root-model-extra', 

68 'unevaluable-type-annotation', 

69 'dataclass-init-false-extra-allow', 

70 'clashing-init-and-init-var', 

71 'model-config-invalid-field-name', 

72 'with-config-on-model', 

73 'dataclass-on-model', 

74 'validate-call-type', 

75 'unpack-typed-dict', 

76 'overlapping-unpack-typed-dict', 

77 'invalid-self-type', 

78 'validate-by-alias-and-name-false', 

79] 

80 

81 

82class PydanticErrorMixin: 1abghijklmnopqrscdtuvwxyzABCDPefEFGHIJKLMNO

83 """A mixin class for common functionality shared by all Pydantic-specific errors. 

84 

85 Attributes: 

86 message: A message describing the error. 

87 code: An optional error code from PydanticErrorCodes enum. 

88 """ 

89 

90 def __init__(self, message: str, *, code: PydanticErrorCodes | None) -> None: 1abghijklmnopqrscdtuvwxyzABCDPefEFGHIJKLMNO

91 self.message = message 1abghijklmnopqrscdtuvwxyzABCDPefEFGHIJKLMNO

92 self.code = code 1abghijklmnopqrscdtuvwxyzABCDPefEFGHIJKLMNO

93 

94 def __str__(self) -> str: 1abghijklmnopqrscdtuvwxyzABCDPefEFGHIJKLMNO

95 if self.code is None: 1abghijklmnopqrscdtuvwxyzABCDefEFGHIJKLMNO

96 return self.message 1abghijklmnopqrscdtuvwxyzABCDefEFGHIJKLMNO

97 else: 

98 return f'{self.message}\n\nFor further information visit {DEV_ERROR_DOCS_URL}{self.code}' 1abghijklmnopqrscdtuvwxyzABCDefEFGHIJKLMNO

99 

100 

101class PydanticUserError(PydanticErrorMixin, TypeError): 1abghijklmnopqrscdtuvwxyzABCDPefEFGHIJKLMNO

102 """An error raised due to incorrect use of Pydantic.""" 

103 

104 

105class PydanticUndefinedAnnotation(PydanticErrorMixin, NameError): 1abghijklmnopqrscdtuvwxyzABCDPefEFGHIJKLMNO

106 """A subclass of `NameError` raised when handling undefined annotations during `CoreSchema` generation. 

107 

108 Attributes: 

109 name: Name of the error. 

110 message: Description of the error. 

111 """ 

112 

113 def __init__(self, name: str, message: str) -> None: 1abghijklmnopqrscdtuvwxyzABCDPefEFGHIJKLMNO

114 self.name = name 1abghijklmnopqrscdtuvwxyzABCDPefEFGHIJKLMNO

115 super().__init__(message=message, code='undefined-annotation') 1abghijklmnopqrscdtuvwxyzABCDPefEFGHIJKLMNO

116 

117 @classmethod 1abghijklmnopqrscdtuvwxyzABCDPefEFGHIJKLMNO

118 def from_name_error(cls, name_error: NameError) -> Self: 1abghijklmnopqrscdtuvwxyzABCDPefEFGHIJKLMNO

119 """Convert a `NameError` to a `PydanticUndefinedAnnotation` error. 

120 

121 Args: 

122 name_error: `NameError` to be converted. 

123 

124 Returns: 

125 Converted `PydanticUndefinedAnnotation` error. 

126 """ 

127 try: 1abghijklmnopqrscdtuvwxyzABCDPefEFGHIJKLMNO

128 name = name_error.name # type: ignore # python > 3.10 1abghijklmnopqrscdtuvwxyzABCDPefEFGHIJKLMNO

129 except AttributeError: 1abcdef

130 name = re.search(r".*'(.+?)'", str(name_error)).group(1) # type: ignore[union-attr] 1abcdef

131 return cls(name=name, message=str(name_error)) 1abghijklmnopqrscdtuvwxyzABCDPefEFGHIJKLMNO

132 

133 

134class PydanticImportError(PydanticErrorMixin, ImportError): 1abghijklmnopqrscdtuvwxyzABCDPefEFGHIJKLMNO

135 """An error raised when an import fails due to module changes between V1 and V2. 

136 

137 Attributes: 

138 message: Description of the error. 

139 """ 

140 

141 def __init__(self, message: str) -> None: 1abghijklmnopqrscdtuvwxyzABCDPefEFGHIJKLMNO

142 super().__init__(message, code='import-error') 1abghijklmnopqrscdtuvwxyzABCDefEFGHIJKLMNO

143 

144 

145class PydanticSchemaGenerationError(PydanticUserError): 1abghijklmnopqrscdtuvwxyzABCDPefEFGHIJKLMNO

146 """An error raised during failures to generate a `CoreSchema` for some type. 

147 

148 Attributes: 

149 message: Description of the error. 

150 """ 

151 

152 def __init__(self, message: str) -> None: 1abghijklmnopqrscdtuvwxyzABCDPefEFGHIJKLMNO

153 super().__init__(message, code='schema-for-unknown-type') 1abghijklmnopqrscdtuvwxyzABCDefEFGHIJKLMNO

154 

155 

156class PydanticInvalidForJsonSchema(PydanticUserError): 1abghijklmnopqrscdtuvwxyzABCDPefEFGHIJKLMNO

157 """An error raised during failures to generate a JSON schema for some `CoreSchema`. 

158 

159 Attributes: 

160 message: Description of the error. 

161 """ 

162 

163 def __init__(self, message: str) -> None: 1abghijklmnopqrscdtuvwxyzABCDPefEFGHIJKLMNO

164 super().__init__(message, code='invalid-for-json-schema') 1abghijklmnopqrscdtuvwxyzABCDefEFGHIJKLMNO

165 

166 

167class PydanticForbiddenQualifier(PydanticUserError): 1abghijklmnopqrscdtuvwxyzABCDPefEFGHIJKLMNO

168 """An error raised if a forbidden type qualifier is found in a type annotation.""" 

169 

170 _qualifier_repr_map: ClassVar[dict[Qualifier, str]] = { 1abghijklmnopqrscdtuvwxyzABCDPefEFGHIJKLMNO

171 'required': 'typing.Required', 

172 'not_required': 'typing.NotRequired', 

173 'read_only': 'typing.ReadOnly', 

174 'class_var': 'typing.ClassVar', 

175 'init_var': 'dataclasses.InitVar', 

176 'final': 'typing.Final', 

177 } 

178 

179 def __init__(self, qualifier: Qualifier, annotation: Any) -> None: 1abghijklmnopqrscdtuvwxyzABCDPefEFGHIJKLMNO

180 super().__init__( 1abghijklmnopqrscdtuvwxyzABCDefEFGHIJKLMNO

181 message=( 

182 f'The annotation {_repr.display_as_type(annotation)!r} contains the {self._qualifier_repr_map[qualifier]!r} ' 

183 f'type qualifier, which is invalid in the context it is defined.' 

184 ), 

185 code=None, 

186 ) 

187 

188 

189__getattr__ = getattr_migration(__name__) 1abghijklmnopqrscdtuvwxyzABCDPefEFGHIJKLMNO