py.lib
37:ae0107755941 Browse Files
. Исправление ошибок и рефакторинг
config_parse_helper.py dataclass_utils.py
1.1 --- a/config_parse_helper.py Fri Aug 19 00:07:55 2022 +0300 1.2 +++ b/config_parse_helper.py Fri Aug 19 02:36:30 2022 +0300 1.3 @@ -28,12 +28,12 @@ 1.4 self.like = like 1.5 self.is_complex = is_complex 1.6 1.7 - def __instancecheck__(self, instance): 1.8 + def check(self, instance): 1.9 if self.like is None: 1.10 return False 1.11 1.12 else: 1.13 - return isinstance(instance, self.like) 1.14 + return check_instance(instance, self.like) 1.15 1.16 def __repr__(self): 1.17 return f'<TypeDescriber({self.__name__}, {self.like})>' 1.18 @@ -42,8 +42,31 @@ 1.19 if val is None: 1.20 return None 1.21 1.22 + elif not self.is_complex and check_instance(val, self.like): 1.23 + return val 1.24 + 1.25 else: 1.26 - return self.cast(val) 1.27 + return self.cast(val) 1.28 + 1.29 + 1.30 +def check_instance(obj, types): 1.31 + if types is None: 1.32 + return False 1.33 + 1.34 + elif isinstance(types, (tuple, list)): 1.35 + _flag = False 1.36 + for t in types: 1.37 + if check_instance(obj, t): 1.38 + _flag = True 1.39 + break 1.40 + 1.41 + return _flag 1.42 + 1.43 + elif isinstance(types, TypeDescriber): 1.44 + return types.check(obj) 1.45 + 1.46 + else: 1.47 + return isinstance(obj, types) 1.48 1.49 1.50 def cast_iterator(t: Union[type, TypeDescriber], lst: Iterable): 1.51 @@ -51,14 +74,16 @@ 1.52 Обрабатывает последовательности единого типа. 1.53 """ 1.54 for i in lst: 1.55 - if isinstance(i, t): 1.56 + if check_instance(i, t): 1.57 yield i 1.58 1.59 - try: 1.60 - yield t(i) 1.61 + else: 1.62 + try: 1.63 + yield t(i) 1.64 1.65 - except (TypeError, ValueError) as e: 1.66 - raise ValueError(f'Не удалось привести значение к нужному типу: тип={t.__name__}; знач={i}') 1.67 + except (TypeError, ValueError) as e: 1.68 + raise ValueError(f'Не удалось привести значение к нужному типу: ' 1.69 + f'тип={t.__name__}; знач={i}') 1.70 1.71 1.72 def multi_item_tuple(tt, val): 1.73 @@ -78,14 +103,16 @@ 1.74 res = [] 1.75 1.76 for i in range(t_len): 1.77 - if isinstance(val[i], tt[i]): 1.78 - yield val[i] 1.79 + if check_instance(val[i], tt[i]): 1.80 + res.append(val[i]) 1.81 1.82 - try: 1.83 - res.append(tt[i](val[i])) 1.84 + else: 1.85 + try: 1.86 + res.append(tt[i](val[i])) 1.87 1.88 - except (TypeError, ValueError) as e: 1.89 - raise ValueError(f'Не удалось привести значение к нужному типу: тип={tt[i].__name__}; знач={val[i]}') 1.90 + except (TypeError, ValueError) as e: 1.91 + raise ValueError(f'Не удалось привести значение к нужному типу: ' 1.92 + f'тип={tt[i].__name__}; знач={val[i]}') 1.93 1.94 return tuple(res) 1.95 1.96 @@ -105,9 +132,14 @@ 1.97 if len(tt) == 0: 1.98 raise ValueError('Не указан ни один тип в составном типе Union') 1.99 1.100 - for t in tt: 1.101 + sorted_types_begin = [ t for t in tt if t in (int, float, bool)] 1.102 + sorted_types_body = [ t for t in tt if t not in (int, float, bool, str)] 1.103 + sorted_types_end = [ t for t in tt if t == str] 1.104 + 1.105 + for t in sorted_types_begin + sorted_types_body + sorted_types_end: 1.106 + _t = get_type_describer(t) 1.107 try: 1.108 - res = t(val) 1.109 + res = _t(val) 1.110 break 1.111 1.112 except (TypeError, ValueError) as e:
2.1 --- a/dataclass_utils.py Fri Aug 19 00:07:55 2022 +0300 2.2 +++ b/dataclass_utils.py Fri Aug 19 02:36:30 2022 +0300 2.3 @@ -30,12 +30,12 @@ 2.4 self.like = like 2.5 self.is_complex = is_complex 2.6 2.7 - def __instancecheck__(self, instance): 2.8 + def check(self, instance): 2.9 if self.like is None: 2.10 return False 2.11 2.12 else: 2.13 - return isinstance(instance, self.like) 2.14 + return check_instance(instance, self.like) 2.15 2.16 def __repr__(self): 2.17 return f'<TypeDescriber({self.__name__}, {self.like})>' 2.18 @@ -44,8 +44,31 @@ 2.19 if val is None: 2.20 return None 2.21 2.22 + elif not self.is_complex and check_instance(val, self.like): 2.23 + return val 2.24 + 2.25 else: 2.26 - return self.cast(val) 2.27 + return self.cast(val) 2.28 + 2.29 + 2.30 +def check_instance(obj, types): 2.31 + if types is None: 2.32 + return False 2.33 + 2.34 + elif isinstance(types, (tuple, list)): 2.35 + _flag = False 2.36 + for t in types: 2.37 + if check_instance(obj, t): 2.38 + _flag = True 2.39 + break 2.40 + 2.41 + return _flag 2.42 + 2.43 + elif isinstance(types, TypeDescriber): 2.44 + return types.check(obj) 2.45 + 2.46 + else: 2.47 + return isinstance(obj, types) 2.48 2.49 2.50 def cast_iterator(t: Union[type, TypeDescriber], lst: Iterable): 2.51 @@ -53,14 +76,16 @@ 2.52 Обрабатывает последовательности единого типа. 2.53 """ 2.54 for i in lst: 2.55 - if isinstance(i, t): 2.56 + if check_instance(i, t): 2.57 yield i 2.58 2.59 - try: 2.60 - yield t(i) 2.61 + else: 2.62 + try: 2.63 + yield t(i) 2.64 2.65 - except (TypeError, ValueError) as e: 2.66 - raise ValueError(f'Не удалось привести значение к нужному типу: тип={t.__name__}; знач={i}') 2.67 + except (TypeError, ValueError) as e: 2.68 + raise ValueError(f'Не удалось привести значение к нужному типу: ' 2.69 + f'тип={t.__name__}; знач={i}') 2.70 2.71 2.72 def multi_item_tuple(tt, val): 2.73 @@ -80,14 +105,16 @@ 2.74 res = [] 2.75 2.76 for i in range(t_len): 2.77 - if isinstance(val[i], tt[i]): 2.78 - yield val[i] 2.79 + if check_instance(val[i], tt[i]): 2.80 + res.append(val[i]) 2.81 2.82 - try: 2.83 - res.append(tt[i](val[i])) 2.84 + else: 2.85 + try: 2.86 + res.append(tt[i](val[i])) 2.87 2.88 - except (TypeError, ValueError) as e: 2.89 - raise ValueError(f'Не удалось привести значение к нужному типу: тип={tt[i].__name__}; знач={val[i]}') 2.90 + except (TypeError, ValueError) as e: 2.91 + raise ValueError(f'Не удалось привести значение к нужному типу: ' 2.92 + f'тип={tt[i].__name__}; знач={val[i]}') 2.93 2.94 return tuple(res) 2.95 2.96 @@ -107,9 +134,14 @@ 2.97 if len(tt) == 0: 2.98 raise ValueError('Не указан ни один тип в составном типе Union') 2.99 2.100 - for t in tt: 2.101 + sorted_types_begin = [ t for t in tt if t in (int, float, bool)] 2.102 + sorted_types_body = [ t for t in tt if t not in (int, float, bool, str)] 2.103 + sorted_types_end = [ t for t in tt if t == str] 2.104 + 2.105 + for t in sorted_types_begin + sorted_types_body + sorted_types_end: 2.106 + _t = get_type_describer(t) 2.107 try: 2.108 - res = t(val) 2.109 + res = _t(val) 2.110 break 2.111 2.112 except (TypeError, ValueError) as e: 2.113 @@ -134,9 +166,11 @@ 2.114 2.115 _p = [] 2.116 2.117 + tt_cast = [get_type_describer(t) for t in tt] 2.118 + 2.119 for k, v in _d.items(): 2.120 try: 2.121 - _p.append((tt[0](k), tt[1](v))) 2.122 + _p.append((tt_cast[0](k), tt_cast[1](v))) 2.123 2.124 except (TypeError, ValueError) as e: 2.125 raise ValueError(f'Не удалось привести значения элемента словаря к требуемому типу: ' 2.126 @@ -224,7 +258,7 @@ 2.127 if len(_args) == 0: 2.128 raise ValueError('Не указан ни один тип в конструкции Union') 2.129 2.130 - _cast_args = tuple(map(get_type_describer, _args)) 2.131 + _cast_args = tuple(map(get_type_describer, [ i for i in _args if i is not None])) 2.132 _args_name = ', '.join(map(lambda x: x.__name__, _args)) 2.133 2.134 return TypeDescriber( 2.135 @@ -264,7 +298,7 @@ 2.136 if _has(obj, fld.name): 2.137 val = _get(obj, fld.name) 2.138 type_desc = get_type_describer(fld.type) 2.139 - if val is not None and not isinstance(val, type_desc): 2.140 + if val is not None: 2.141 try: 2.142 val = type_desc(val) 2.143