44from dataclasses import dataclass
55from datetime import datetime as datetime_type
66from types import UnionType
7- from typing import Literal , Optional , Union , get_args , get_origin , get_type_hints # pyright:ignore[reportDeprecated]
7+ from typing import ( # pyright:ignore[reportDeprecated]
8+ Literal ,
9+ Optional ,
10+ Self ,
11+ Union ,
12+ get_args ,
13+ get_origin ,
14+ get_type_hints ,
15+ )
816
917import arrow
1018import pytimeparse
@@ -101,7 +109,7 @@ def parse(cls, source: dict, parse_type: type):
101109 if key in hints :
102110 # This entry has an explicit type
103111 try :
104- kwargs [key ] = _parse_value (value , hints [key ])
112+ kwargs [key ] = _parse_value (value , hints [key ], parse_type )
105113 except _PARSING_ERRORS as e :
106114 raise _bubble_up_parse_error (e , key )
107115 else :
@@ -175,7 +183,7 @@ def has_field_with_value(self, field_name: str) -> bool:
175183 return field_name in self and self [field_name ] is not None
176184
177185
178- def _parse_value (value , value_type : type ):
186+ def _parse_value (value , value_type : type , root_type : type ):
179187 generic_type = get_origin (value_type )
180188 if generic_type :
181189 # Type is generic
@@ -192,7 +200,7 @@ def _parse_value(value, value_type: type):
192200 result = []
193201 for i , v in enumerate (value_list ):
194202 try :
195- result .append (_parse_value (v , arg_types [0 ]))
203+ result .append (_parse_value (v , arg_types [0 ], root_type ))
196204 except _PARSING_ERRORS as e :
197205 raise _bubble_up_parse_error (e , f"[{ i } ]" )
198206 return result
@@ -201,9 +209,9 @@ def _parse_value(value, value_type: type):
201209 # value is a dict of some kind
202210 result = {}
203211 for k , v in value .items ():
204- parsed_key = k if arg_types [0 ] is str else _parse_value (k , arg_types [0 ])
212+ parsed_key = k if arg_types [0 ] is str else _parse_value (k , arg_types [0 ], root_type )
205213 try :
206- parsed_value = _parse_value (v , arg_types [1 ])
214+ parsed_value = _parse_value (v , arg_types [1 ], root_type )
207215 except _PARSING_ERRORS as e :
208216 raise _bubble_up_parse_error (e , k )
209217 result [parsed_key ] = parsed_value
@@ -220,7 +228,7 @@ def _parse_value(value, value_type: type):
220228 # omitting the field's value
221229 return None
222230 else :
223- return _parse_value (value , arg_types [0 ])
231+ return _parse_value (value , arg_types [0 ], root_type )
224232
225233 elif generic_type is Literal and len (arg_types ) == 1 :
226234 # Type is a Literal (parsed value must match specified value)
@@ -231,12 +239,15 @@ def _parse_value(value, value_type: type):
231239 else :
232240 raise ValueError (f"Automatic parsing of { value_type } type is not yet implemented" )
233241
242+ elif value_type == Self :
243+ # value is outself type
244+ return ImplicitDict .parse (value , root_type )
234245 elif issubclass (value_type , ImplicitDict ):
235246 # value is an ImplicitDict
236247 return ImplicitDict .parse (value , value_type )
237248
238249 if hasattr (value_type , "__orig_bases__" ) and value_type .__orig_bases__ :
239- return value_type (_parse_value (value , value_type .__orig_bases__ [0 ]))
250+ return value_type (_parse_value (value , value_type .__orig_bases__ [0 ], root_type ))
240251
241252 else :
242253 # value is a non-generic type that is not an ImplicitDict
0 commit comments