py.lib

Yohn Y. 2022-08-19 Parent:f1a05e880961

37:ae0107755941 Go to Latest

py.lib/config_parse_helper.py

. Исправление ошибок и рефакторинг

History
     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: