Core: Fix OptionList and OptionSet to allow Iterable of Iterable (#2911)
* fix, maybe * typegard for iterable of any * wow I'm so tired I just changed the method name without changing what it actually does... * also exclude bytes in is_iterable_but_str * apply pr comments * Update Utils.py Co-authored-by: Doug Hoskisson <beauxq@users.noreply.github.com> * Revert "also exclude bytes in is_iterable_but_str" This reverts commit cf087d2ee20727dbbe561c8c0f90aa85ef0a5d4b. --------- Co-authored-by: Doug Hoskisson <beauxq@users.noreply.github.com>
This commit is contained in:
		
							parent
							
								
									d3019421de
								
							
						
					
					
						commit
						a3125cb06e
					
				| 
						 | 
				
			
			@ -12,7 +12,7 @@ from dataclasses import dataclass
 | 
			
		|||
 | 
			
		||||
from schema import And, Optional, Or, Schema
 | 
			
		||||
 | 
			
		||||
from Utils import get_fuzzy_results, is_iterable_of_str
 | 
			
		||||
from Utils import get_fuzzy_results, is_iterable_except_str
 | 
			
		||||
 | 
			
		||||
if typing.TYPE_CHECKING:
 | 
			
		||||
    from BaseClasses import PlandoOptions
 | 
			
		||||
| 
						 | 
				
			
			@ -847,7 +847,7 @@ class OptionList(Option[typing.List[typing.Any]], VerifyKeys):
 | 
			
		|||
    default: typing.Union[typing.List[typing.Any], typing.Tuple[typing.Any, ...]] = ()
 | 
			
		||||
    supports_weighting = False
 | 
			
		||||
 | 
			
		||||
    def __init__(self, value: typing.Iterable[str]):
 | 
			
		||||
    def __init__(self, value: typing.Iterable[typing.Any]):
 | 
			
		||||
        self.value = list(deepcopy(value))
 | 
			
		||||
        super(OptionList, self).__init__()
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -857,7 +857,7 @@ class OptionList(Option[typing.List[typing.Any]], VerifyKeys):
 | 
			
		|||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def from_any(cls, data: typing.Any):
 | 
			
		||||
        if is_iterable_of_str(data):
 | 
			
		||||
        if is_iterable_except_str(data):
 | 
			
		||||
            cls.verify_keys(data)
 | 
			
		||||
            return cls(data)
 | 
			
		||||
        return cls.from_text(str(data))
 | 
			
		||||
| 
						 | 
				
			
			@ -883,7 +883,7 @@ class OptionSet(Option[typing.Set[str]], VerifyKeys):
 | 
			
		|||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def from_any(cls, data: typing.Any):
 | 
			
		||||
        if is_iterable_of_str(data):
 | 
			
		||||
        if is_iterable_except_str(data):
 | 
			
		||||
            cls.verify_keys(data)
 | 
			
		||||
            return cls(data)
 | 
			
		||||
        return cls.from_text(str(data))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										9
									
								
								Utils.py
								
								
								
								
							
							
						
						
									
										9
									
								
								Utils.py
								
								
								
								
							| 
						 | 
				
			
			@ -969,11 +969,8 @@ class RepeatableChain:
 | 
			
		|||
        return sum(len(iterable) for iterable in self.iterable)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def is_iterable_of_str(obj: object) -> TypeGuard[typing.Iterable[str]]:
 | 
			
		||||
    """ but not a `str` (because technically, `str` is `Iterable[str]`) """
 | 
			
		||||
def is_iterable_except_str(obj: object) -> TypeGuard[typing.Iterable[typing.Any]]:
 | 
			
		||||
    """ `str` is `Iterable`, but that's not what we want """
 | 
			
		||||
    if isinstance(obj, str):
 | 
			
		||||
        return False
 | 
			
		||||
    if not isinstance(obj, typing.Iterable):
 | 
			
		||||
        return False
 | 
			
		||||
    obj_it: typing.Iterable[object] = obj
 | 
			
		||||
    return all(isinstance(v, str) for v in obj_it)
 | 
			
		||||
    return isinstance(obj, typing.Iterable)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue