Coverage for pydantic/_migration.py: 100.00%

34 statements  

« prev     ^ index     » next       coverage.py v7.5.4, created at 2024-07-03 19:29 +0000

1import sys 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL

2from typing import Any, Callable, Dict 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL

3 

4from .version import version_short 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL

5 

6MOVED_IN_V2 = { 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL

7 'pydantic.utils:version_info': 'pydantic.version:version_info', 

8 'pydantic.error_wrappers:ValidationError': 'pydantic:ValidationError', 

9 'pydantic.utils:to_camel': 'pydantic.alias_generators:to_pascal', 

10 'pydantic.utils:to_lower_camel': 'pydantic.alias_generators:to_camel', 

11 'pydantic:PyObject': 'pydantic.types:ImportString', 

12 'pydantic.types:PyObject': 'pydantic.types:ImportString', 

13 'pydantic.generics:GenericModel': 'pydantic.BaseModel', 

14} 

15 

16DEPRECATED_MOVED_IN_V2 = { 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL

17 'pydantic.tools:schema_of': 'pydantic.deprecated.tools:schema_of', 

18 'pydantic.tools:parse_obj_as': 'pydantic.deprecated.tools:parse_obj_as', 

19 'pydantic.tools:schema_json_of': 'pydantic.deprecated.tools:schema_json_of', 

20 'pydantic.json:pydantic_encoder': 'pydantic.deprecated.json:pydantic_encoder', 

21 'pydantic:validate_arguments': 'pydantic.deprecated.decorator:validate_arguments', 

22 'pydantic.json:custom_pydantic_encoder': 'pydantic.deprecated.json:custom_pydantic_encoder', 

23 'pydantic.json:timedelta_isoformat': 'pydantic.deprecated.json:timedelta_isoformat', 

24 'pydantic.decorator:validate_arguments': 'pydantic.deprecated.decorator:validate_arguments', 

25 'pydantic.class_validators:validator': 'pydantic.deprecated.class_validators:validator', 

26 'pydantic.class_validators:root_validator': 'pydantic.deprecated.class_validators:root_validator', 

27 'pydantic.config:BaseConfig': 'pydantic.deprecated.config:BaseConfig', 

28 'pydantic.config:Extra': 'pydantic.deprecated.config:Extra', 

29} 

30 

31REDIRECT_TO_V1 = { 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL

32 f'pydantic.utils:{obj}': f'pydantic.v1.utils:{obj}' 

33 for obj in ( 

34 'deep_update', 

35 'GetterDict', 

36 'lenient_issubclass', 

37 'lenient_isinstance', 

38 'is_valid_field', 

39 'update_not_none', 

40 'import_string', 

41 'Representation', 

42 'ROOT_KEY', 

43 'smart_deepcopy', 

44 'sequence_like', 

45 ) 

46} 

47 

48 

49REMOVED_IN_V2 = { 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL

50 'pydantic:ConstrainedBytes', 

51 'pydantic:ConstrainedDate', 

52 'pydantic:ConstrainedDecimal', 

53 'pydantic:ConstrainedFloat', 

54 'pydantic:ConstrainedFrozenSet', 

55 'pydantic:ConstrainedInt', 

56 'pydantic:ConstrainedList', 

57 'pydantic:ConstrainedSet', 

58 'pydantic:ConstrainedStr', 

59 'pydantic:JsonWrapper', 

60 'pydantic:NoneBytes', 

61 'pydantic:NoneStr', 

62 'pydantic:NoneStrBytes', 

63 'pydantic:Protocol', 

64 'pydantic:Required', 

65 'pydantic:StrBytes', 

66 'pydantic:compiled', 

67 'pydantic.config:get_config', 

68 'pydantic.config:inherit_config', 

69 'pydantic.config:prepare_config', 

70 'pydantic:create_model_from_namedtuple', 

71 'pydantic:create_model_from_typeddict', 

72 'pydantic.dataclasses:create_pydantic_model_from_dataclass', 

73 'pydantic.dataclasses:make_dataclass_validator', 

74 'pydantic.dataclasses:set_validation', 

75 'pydantic.datetime_parse:parse_date', 

76 'pydantic.datetime_parse:parse_time', 

77 'pydantic.datetime_parse:parse_datetime', 

78 'pydantic.datetime_parse:parse_duration', 

79 'pydantic.error_wrappers:ErrorWrapper', 

80 'pydantic.errors:AnyStrMaxLengthError', 

81 'pydantic.errors:AnyStrMinLengthError', 

82 'pydantic.errors:ArbitraryTypeError', 

83 'pydantic.errors:BoolError', 

84 'pydantic.errors:BytesError', 

85 'pydantic.errors:CallableError', 

86 'pydantic.errors:ClassError', 

87 'pydantic.errors:ColorError', 

88 'pydantic.errors:ConfigError', 

89 'pydantic.errors:DataclassTypeError', 

90 'pydantic.errors:DateError', 

91 'pydantic.errors:DateNotInTheFutureError', 

92 'pydantic.errors:DateNotInThePastError', 

93 'pydantic.errors:DateTimeError', 

94 'pydantic.errors:DecimalError', 

95 'pydantic.errors:DecimalIsNotFiniteError', 

96 'pydantic.errors:DecimalMaxDigitsError', 

97 'pydantic.errors:DecimalMaxPlacesError', 

98 'pydantic.errors:DecimalWholeDigitsError', 

99 'pydantic.errors:DictError', 

100 'pydantic.errors:DurationError', 

101 'pydantic.errors:EmailError', 

102 'pydantic.errors:EnumError', 

103 'pydantic.errors:EnumMemberError', 

104 'pydantic.errors:ExtraError', 

105 'pydantic.errors:FloatError', 

106 'pydantic.errors:FrozenSetError', 

107 'pydantic.errors:FrozenSetMaxLengthError', 

108 'pydantic.errors:FrozenSetMinLengthError', 

109 'pydantic.errors:HashableError', 

110 'pydantic.errors:IPv4AddressError', 

111 'pydantic.errors:IPv4InterfaceError', 

112 'pydantic.errors:IPv4NetworkError', 

113 'pydantic.errors:IPv6AddressError', 

114 'pydantic.errors:IPv6InterfaceError', 

115 'pydantic.errors:IPv6NetworkError', 

116 'pydantic.errors:IPvAnyAddressError', 

117 'pydantic.errors:IPvAnyInterfaceError', 

118 'pydantic.errors:IPvAnyNetworkError', 

119 'pydantic.errors:IntEnumError', 

120 'pydantic.errors:IntegerError', 

121 'pydantic.errors:InvalidByteSize', 

122 'pydantic.errors:InvalidByteSizeUnit', 

123 'pydantic.errors:InvalidDiscriminator', 

124 'pydantic.errors:InvalidLengthForBrand', 

125 'pydantic.errors:JsonError', 

126 'pydantic.errors:JsonTypeError', 

127 'pydantic.errors:ListError', 

128 'pydantic.errors:ListMaxLengthError', 

129 'pydantic.errors:ListMinLengthError', 

130 'pydantic.errors:ListUniqueItemsError', 

131 'pydantic.errors:LuhnValidationError', 

132 'pydantic.errors:MissingDiscriminator', 

133 'pydantic.errors:MissingError', 

134 'pydantic.errors:NoneIsAllowedError', 

135 'pydantic.errors:NoneIsNotAllowedError', 

136 'pydantic.errors:NotDigitError', 

137 'pydantic.errors:NotNoneError', 

138 'pydantic.errors:NumberNotGeError', 

139 'pydantic.errors:NumberNotGtError', 

140 'pydantic.errors:NumberNotLeError', 

141 'pydantic.errors:NumberNotLtError', 

142 'pydantic.errors:NumberNotMultipleError', 

143 'pydantic.errors:PathError', 

144 'pydantic.errors:PathNotADirectoryError', 

145 'pydantic.errors:PathNotAFileError', 

146 'pydantic.errors:PathNotExistsError', 

147 'pydantic.errors:PatternError', 

148 'pydantic.errors:PyObjectError', 

149 'pydantic.errors:PydanticTypeError', 

150 'pydantic.errors:PydanticValueError', 

151 'pydantic.errors:SequenceError', 

152 'pydantic.errors:SetError', 

153 'pydantic.errors:SetMaxLengthError', 

154 'pydantic.errors:SetMinLengthError', 

155 'pydantic.errors:StrError', 

156 'pydantic.errors:StrRegexError', 

157 'pydantic.errors:StrictBoolError', 

158 'pydantic.errors:SubclassError', 

159 'pydantic.errors:TimeError', 

160 'pydantic.errors:TupleError', 

161 'pydantic.errors:TupleLengthError', 

162 'pydantic.errors:UUIDError', 

163 'pydantic.errors:UUIDVersionError', 

164 'pydantic.errors:UrlError', 

165 'pydantic.errors:UrlExtraError', 

166 'pydantic.errors:UrlHostError', 

167 'pydantic.errors:UrlHostTldError', 

168 'pydantic.errors:UrlPortError', 

169 'pydantic.errors:UrlSchemeError', 

170 'pydantic.errors:UrlSchemePermittedError', 

171 'pydantic.errors:UrlUserInfoError', 

172 'pydantic.errors:WrongConstantError', 

173 'pydantic.main:validate_model', 

174 'pydantic.networks:stricturl', 

175 'pydantic:parse_file_as', 

176 'pydantic:parse_raw_as', 

177 'pydantic:stricturl', 

178 'pydantic.tools:parse_file_as', 

179 'pydantic.tools:parse_raw_as', 

180 'pydantic.types:ConstrainedBytes', 

181 'pydantic.types:ConstrainedDate', 

182 'pydantic.types:ConstrainedDecimal', 

183 'pydantic.types:ConstrainedFloat', 

184 'pydantic.types:ConstrainedFrozenSet', 

185 'pydantic.types:ConstrainedInt', 

186 'pydantic.types:ConstrainedList', 

187 'pydantic.types:ConstrainedSet', 

188 'pydantic.types:ConstrainedStr', 

189 'pydantic.types:JsonWrapper', 

190 'pydantic.types:NoneBytes', 

191 'pydantic.types:NoneStr', 

192 'pydantic.types:NoneStrBytes', 

193 'pydantic.types:StrBytes', 

194 'pydantic.typing:evaluate_forwardref', 

195 'pydantic.typing:AbstractSetIntStr', 

196 'pydantic.typing:AnyCallable', 

197 'pydantic.typing:AnyClassMethod', 

198 'pydantic.typing:CallableGenerator', 

199 'pydantic.typing:DictAny', 

200 'pydantic.typing:DictIntStrAny', 

201 'pydantic.typing:DictStrAny', 

202 'pydantic.typing:IntStr', 

203 'pydantic.typing:ListStr', 

204 'pydantic.typing:MappingIntStrAny', 

205 'pydantic.typing:NoArgAnyCallable', 

206 'pydantic.typing:NoneType', 

207 'pydantic.typing:ReprArgs', 

208 'pydantic.typing:SetStr', 

209 'pydantic.typing:StrPath', 

210 'pydantic.typing:TupleGenerator', 

211 'pydantic.typing:WithArgsTypes', 

212 'pydantic.typing:all_literal_values', 

213 'pydantic.typing:display_as_type', 

214 'pydantic.typing:get_all_type_hints', 

215 'pydantic.typing:get_args', 

216 'pydantic.typing:get_origin', 

217 'pydantic.typing:get_sub_types', 

218 'pydantic.typing:is_callable_type', 

219 'pydantic.typing:is_classvar', 

220 'pydantic.typing:is_finalvar', 

221 'pydantic.typing:is_literal_type', 

222 'pydantic.typing:is_namedtuple', 

223 'pydantic.typing:is_new_type', 

224 'pydantic.typing:is_none_type', 

225 'pydantic.typing:is_typeddict', 

226 'pydantic.typing:is_typeddict_special', 

227 'pydantic.typing:is_union', 

228 'pydantic.typing:new_type_supertype', 

229 'pydantic.typing:resolve_annotations', 

230 'pydantic.typing:typing_base', 

231 'pydantic.typing:update_field_forward_refs', 

232 'pydantic.typing:update_model_forward_refs', 

233 'pydantic.utils:ClassAttribute', 

234 'pydantic.utils:DUNDER_ATTRIBUTES', 

235 'pydantic.utils:PyObjectStr', 

236 'pydantic.utils:ValueItems', 

237 'pydantic.utils:almost_equal_floats', 

238 'pydantic.utils:get_discriminator_alias_and_values', 

239 'pydantic.utils:get_model', 

240 'pydantic.utils:get_unique_discriminator_alias', 

241 'pydantic.utils:in_ipython', 

242 'pydantic.utils:is_valid_identifier', 

243 'pydantic.utils:path_type', 

244 'pydantic.utils:validate_field_name', 

245 'pydantic:validate_model', 

246} 

247 

248 

249def getattr_migration(module: str) -> Callable[[str], Any]: 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL

250 """Implement PEP 562 for objects that were either moved or removed on the migration 

251 to V2. 

252 

253 Args: 

254 module: The module name. 

255 

256 Returns: 

257 A callable that will raise an error if the object is not found. 

258 """ 

259 # This avoids circular import with errors.py. 

260 from .errors import PydanticImportError 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL

261 

262 def wrapper(name: str) -> object: 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL

263 """Raise an error if the object is not found, or warn if it was moved. 

264 

265 In case it was moved, it still returns the object. 

266 

267 Args: 

268 name: The object name. 

269 

270 Returns: 

271 The object. 

272 """ 

273 if name == '__path__': 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL

274 raise AttributeError(f'module {module!r} has no attribute {name!r}') 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL

275 

276 import warnings 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL

277 

278 from ._internal._validators import import_string 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL

279 

280 import_path = f'{module}:{name}' 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL

281 if import_path in MOVED_IN_V2.keys(): 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL

282 new_location = MOVED_IN_V2[import_path] 1abcdefghijklmnopqrstuvwxyzABCDEFGHIJKL

283 warnings.warn(f'`{import_path}` has been moved to `{new_location}`.') 1abcdefghijklmnopqrstuvwxyzABCDEFGHIJKL

284 return import_string(MOVED_IN_V2[import_path]) 1abcdefghijklmnopqrstuvwxyzABCDEFGHIJKL

285 if import_path in DEPRECATED_MOVED_IN_V2: 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL

286 # skip the warning here because a deprecation warning will be raised elsewhere 

287 return import_string(DEPRECATED_MOVED_IN_V2[import_path]) 1abcdefghijklmnopqrstuvwxyzABCDEFGHIJKL

288 if import_path in REDIRECT_TO_V1: 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL

289 new_location = REDIRECT_TO_V1[import_path] 1abcdefghijklmnopqrstuvwxyzABCDEFGHIJKL

290 warnings.warn( 1abcdefghijklmnopqrstuvwxyzABCDEFGHIJKL

291 f'`{import_path}` has been removed. We are importing from `{new_location}` instead.' 

292 'See the migration guide for more details: https://docs.pydantic.dev/latest/migration/' 

293 ) 

294 return import_string(REDIRECT_TO_V1[import_path]) 1abcdefghijklmnopqrstuvwxyzABCDEFGHIJKL

295 if import_path == 'pydantic:BaseSettings': 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL

296 raise PydanticImportError( 1abcdefghijklmnopqrstuvwxyzABCDEFGHIJKL

297 '`BaseSettings` has been moved to the `pydantic-settings` package. ' 

298 f'See https://docs.pydantic.dev/{version_short()}/migration/#basesettings-has-moved-to-pydantic-settings ' 

299 'for more details.' 

300 ) 

301 if import_path in REMOVED_IN_V2: 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL

302 raise PydanticImportError(f'`{import_path}` has been removed in V2.') 1abcdefghijklmnopqrstuvwxyzABCDEFGHIJKL

303 globals: Dict[str, Any] = sys.modules[module].__dict__ 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL

304 if name in globals: 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL

305 return globals[name] 1abcdefghijklmnopqrstuvwxyzABCDEFGHIJKL

306 raise AttributeError(f'module {module!r} has no attribute {name!r}') 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL

307 

308 return wrapper 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL