Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/pydantic/errors.py: 71%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

41 statements  

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

2 

3from __future__ import annotations as _annotations 

4 

5from typing import Any, ClassVar, Literal 

6 

7from typing_extensions import Self 

8from typing_inspection.introspection import Qualifier 

9 

10from pydantic._internal import _repr 

11 

12from ._migration import getattr_migration 

13from .version import version_short 

14 

15__all__ = ( 

16 'PydanticUserError', 

17 'PydanticUndefinedAnnotation', 

18 'PydanticImportError', 

19 'PydanticSchemaGenerationError', 

20 'PydanticInvalidForJsonSchema', 

21 'PydanticForbiddenQualifier', 

22 'PydanticErrorCodes', 

23) 

24 

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

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

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

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

29PydanticErrorCodes = Literal[ 

30 'class-not-fully-defined', 

31 'custom-json-schema', 

32 'decorator-invalid-fields', 

33 'decorator-missing-arguments', 

34 'decorator-missing-field', 

35 'discriminator-no-field', 

36 'discriminator-alias-type', 

37 'discriminator-needs-literal', 

38 'discriminator-alias', 

39 'discriminator-validator', 

40 'callable-discriminator-no-tag', 

41 'typed-dict-version', 

42 'model-field-overridden', 

43 'model-field-missing-annotation', 

44 'config-both', 

45 'removed-kwargs', 

46 'circular-reference-schema', 

47 'invalid-for-json-schema', 

48 'json-schema-already-used', 

49 'base-model-instantiated', 

50 'undefined-annotation', 

51 'schema-for-unknown-type', 

52 'import-error', 

53 'create-model-field-definitions', 

54 'create-model-namespace', 

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: 

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: 

91 self.message = message 

92 self.code = code 

93 

94 def __str__(self) -> str: 

95 if self.code is None: 

96 return self.message 

97 else: 

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

99 

100 

101class PydanticUserError(PydanticErrorMixin, RuntimeError): 

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

103 

104 

105class PydanticUndefinedAnnotation(PydanticErrorMixin, NameError): 

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

107 

108 Attributes: 

109 name: Name of the error, of `None` if not available. 

110 message: Description of the error. 

111 """ 

112 

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

114 self.name = name 

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

116 

117 @classmethod 

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

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 return cls(name=name_error.name, message=str(name_error)) 

128 

129 

130class PydanticImportError(PydanticErrorMixin, ImportError): 

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

132 

133 Attributes: 

134 message: Description of the error. 

135 """ 

136 

137 def __init__(self, message: str) -> None: 

138 super().__init__(message, code='import-error') 

139 

140 

141class PydanticSchemaGenerationError(PydanticUserError): 

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

143 

144 Attributes: 

145 message: Description of the error. 

146 """ 

147 

148 def __init__(self, message: str) -> None: 

149 super().__init__(message, code='schema-for-unknown-type') 

150 

151 

152class PydanticInvalidForJsonSchema(PydanticUserError): 

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

154 

155 Attributes: 

156 message: Description of the error. 

157 """ 

158 

159 def __init__(self, message: str) -> None: 

160 super().__init__(message, code='invalid-for-json-schema') 

161 

162 

163class PydanticForbiddenQualifier(PydanticUserError): 

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

165 

166 _qualifier_repr_map: ClassVar[dict[Qualifier, str]] = { 

167 'required': 'typing.Required', 

168 'not_required': 'typing.NotRequired', 

169 'read_only': 'typing.ReadOnly', 

170 'class_var': 'typing.ClassVar', 

171 'init_var': 'dataclasses.InitVar', 

172 'final': 'typing.Final', 

173 } 

174 

175 def __init__(self, qualifier: Qualifier, annotation: Any) -> None: 

176 super().__init__( 

177 message=( 

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

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

180 ), 

181 code=None, 

182 ) 

183 

184 

185__getattr__ = getattr_migration(__name__)