| 
									
										
										
										
											2023-09-04 12:41:58 +03:00
										 |  |  | import doctest | 
					
						
							| 
									
										
										
										
											2023-09-04 15:24:03 +03:00
										 |  |  | import unittest | 
					
						
							| 
									
										
										
										
											2023-09-04 12:41:58 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-26 16:55:35 +00:00
										 |  |  | doctests = """
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Setup | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     >>> class AClass: | 
					
						
							|  |  |  |     ...    def __init__(self): | 
					
						
							|  |  |  |     ...        self._setitem_name = None | 
					
						
							|  |  |  |     ...        self._setitem_val = None | 
					
						
							|  |  |  |     ...        self._delitem_name = None | 
					
						
							|  |  |  |     ...    def __setitem__(self, name, val): | 
					
						
							|  |  |  |     ...        self._delitem_name = None | 
					
						
							|  |  |  |     ...        self._setitem_name = name | 
					
						
							|  |  |  |     ...        self._setitem_val = val | 
					
						
							|  |  |  |     ...    def __repr__(self): | 
					
						
							|  |  |  |     ...        if self._setitem_name is not None: | 
					
						
							|  |  |  |     ...            return f"A[{self._setitem_name}]={self._setitem_val}" | 
					
						
							|  |  |  |     ...        elif self._delitem_name is not None: | 
					
						
							|  |  |  |     ...            return f"delA[{self._delitem_name}]" | 
					
						
							|  |  |  |     ...    def __getitem__(self, name): | 
					
						
							|  |  |  |     ...        return ParameterisedA(name) | 
					
						
							|  |  |  |     ...    def __delitem__(self, name): | 
					
						
							|  |  |  |     ...        self._setitem_name = None | 
					
						
							|  |  |  |     ...        self._delitem_name = name | 
					
						
							|  |  |  |     ... | 
					
						
							|  |  |  |     >>> class ParameterisedA: | 
					
						
							|  |  |  |     ...    def __init__(self, name): | 
					
						
							|  |  |  |     ...        self._name = name | 
					
						
							|  |  |  |     ...    def __repr__(self): | 
					
						
							|  |  |  |     ...        return f"A[{self._name}]" | 
					
						
							|  |  |  |     ...    def __iter__(self): | 
					
						
							|  |  |  |     ...        for p in self._name: | 
					
						
							|  |  |  |     ...            yield p | 
					
						
							|  |  |  |     >>> class B: | 
					
						
							|  |  |  |     ...    def __iter__(self): | 
					
						
							|  |  |  |     ...        yield StarredB() | 
					
						
							|  |  |  |     ...    def __repr__(self): | 
					
						
							|  |  |  |     ...        return "B" | 
					
						
							|  |  |  |     >>> class StarredB: | 
					
						
							|  |  |  |     ...    def __repr__(self): | 
					
						
							|  |  |  |     ...        return "StarredB" | 
					
						
							|  |  |  |     >>> A = AClass() | 
					
						
							|  |  |  |     >>> b = B() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Slices that are supposed to work, starring our custom B class | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     >>> A[*b] | 
					
						
							|  |  |  |     A[(StarredB,)] | 
					
						
							|  |  |  |     >>> A[*b] = 1; A | 
					
						
							|  |  |  |     A[(StarredB,)]=1 | 
					
						
							|  |  |  |     >>> del A[*b]; A | 
					
						
							|  |  |  |     delA[(StarredB,)] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     >>> A[*b, *b] | 
					
						
							|  |  |  |     A[(StarredB, StarredB)] | 
					
						
							|  |  |  |     >>> A[*b, *b] = 1; A | 
					
						
							|  |  |  |     A[(StarredB, StarredB)]=1 | 
					
						
							|  |  |  |     >>> del A[*b, *b]; A | 
					
						
							|  |  |  |     delA[(StarredB, StarredB)] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     >>> A[b, *b] | 
					
						
							|  |  |  |     A[(B, StarredB)] | 
					
						
							|  |  |  |     >>> A[b, *b] = 1; A | 
					
						
							|  |  |  |     A[(B, StarredB)]=1 | 
					
						
							|  |  |  |     >>> del A[b, *b]; A | 
					
						
							|  |  |  |     delA[(B, StarredB)] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     >>> A[*b, b] | 
					
						
							|  |  |  |     A[(StarredB, B)] | 
					
						
							|  |  |  |     >>> A[*b, b] = 1; A | 
					
						
							|  |  |  |     A[(StarredB, B)]=1 | 
					
						
							|  |  |  |     >>> del A[*b, b]; A | 
					
						
							|  |  |  |     delA[(StarredB, B)] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     >>> A[b, b, *b] | 
					
						
							|  |  |  |     A[(B, B, StarredB)] | 
					
						
							|  |  |  |     >>> A[b, b, *b] = 1; A | 
					
						
							|  |  |  |     A[(B, B, StarredB)]=1 | 
					
						
							|  |  |  |     >>> del A[b, b, *b]; A | 
					
						
							|  |  |  |     delA[(B, B, StarredB)] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     >>> A[*b, b, b] | 
					
						
							|  |  |  |     A[(StarredB, B, B)] | 
					
						
							|  |  |  |     >>> A[*b, b, b] = 1; A | 
					
						
							|  |  |  |     A[(StarredB, B, B)]=1 | 
					
						
							|  |  |  |     >>> del A[*b, b, b]; A | 
					
						
							|  |  |  |     delA[(StarredB, B, B)] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     >>> A[b, *b, b] | 
					
						
							|  |  |  |     A[(B, StarredB, B)] | 
					
						
							|  |  |  |     >>> A[b, *b, b] = 1; A | 
					
						
							|  |  |  |     A[(B, StarredB, B)]=1 | 
					
						
							|  |  |  |     >>> del A[b, *b, b]; A | 
					
						
							|  |  |  |     delA[(B, StarredB, B)] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     >>> A[b, b, *b, b] | 
					
						
							|  |  |  |     A[(B, B, StarredB, B)] | 
					
						
							|  |  |  |     >>> A[b, b, *b, b] = 1; A | 
					
						
							|  |  |  |     A[(B, B, StarredB, B)]=1 | 
					
						
							|  |  |  |     >>> del A[b, b, *b, b]; A | 
					
						
							|  |  |  |     delA[(B, B, StarredB, B)] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     >>> A[b, *b, b, b] | 
					
						
							|  |  |  |     A[(B, StarredB, B, B)] | 
					
						
							|  |  |  |     >>> A[b, *b, b, b] = 1; A | 
					
						
							|  |  |  |     A[(B, StarredB, B, B)]=1 | 
					
						
							|  |  |  |     >>> del A[b, *b, b, b]; A | 
					
						
							|  |  |  |     delA[(B, StarredB, B, B)] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     >>> A[A[b, *b, b]] | 
					
						
							|  |  |  |     A[A[(B, StarredB, B)]] | 
					
						
							|  |  |  |     >>> A[A[b, *b, b]] = 1; A | 
					
						
							|  |  |  |     A[A[(B, StarredB, B)]]=1 | 
					
						
							|  |  |  |     >>> del A[A[b, *b, b]]; A | 
					
						
							|  |  |  |     delA[A[(B, StarredB, B)]] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     >>> A[*A[b, *b, b]] | 
					
						
							|  |  |  |     A[(B, StarredB, B)] | 
					
						
							|  |  |  |     >>> A[*A[b, *b, b]] = 1; A | 
					
						
							|  |  |  |     A[(B, StarredB, B)]=1 | 
					
						
							|  |  |  |     >>> del A[*A[b, *b, b]]; A | 
					
						
							|  |  |  |     delA[(B, StarredB, B)] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     >>> A[b, ...] | 
					
						
							|  |  |  |     A[(B, Ellipsis)] | 
					
						
							|  |  |  |     >>> A[b, ...] = 1; A | 
					
						
							|  |  |  |     A[(B, Ellipsis)]=1 | 
					
						
							|  |  |  |     >>> del A[b, ...]; A | 
					
						
							|  |  |  |     delA[(B, Ellipsis)] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     >>> A[*A[b, ...]] | 
					
						
							|  |  |  |     A[(B, Ellipsis)] | 
					
						
							|  |  |  |     >>> A[*A[b, ...]] = 1; A | 
					
						
							|  |  |  |     A[(B, Ellipsis)]=1 | 
					
						
							|  |  |  |     >>> del A[*A[b, ...]]; A | 
					
						
							|  |  |  |     delA[(B, Ellipsis)] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Slices that are supposed to work, starring a list | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     >>> l = [1, 2, 3] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     >>> A[*l] | 
					
						
							|  |  |  |     A[(1, 2, 3)] | 
					
						
							|  |  |  |     >>> A[*l] = 1; A | 
					
						
							|  |  |  |     A[(1, 2, 3)]=1 | 
					
						
							|  |  |  |     >>> del A[*l]; A | 
					
						
							|  |  |  |     delA[(1, 2, 3)] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     >>> A[*l, 4] | 
					
						
							|  |  |  |     A[(1, 2, 3, 4)] | 
					
						
							|  |  |  |     >>> A[*l, 4] = 1; A | 
					
						
							|  |  |  |     A[(1, 2, 3, 4)]=1 | 
					
						
							|  |  |  |     >>> del A[*l, 4]; A | 
					
						
							|  |  |  |     delA[(1, 2, 3, 4)] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     >>> A[0, *l] | 
					
						
							|  |  |  |     A[(0, 1, 2, 3)] | 
					
						
							|  |  |  |     >>> A[0, *l] = 1; A | 
					
						
							|  |  |  |     A[(0, 1, 2, 3)]=1 | 
					
						
							|  |  |  |     >>> del A[0, *l]; A | 
					
						
							|  |  |  |     delA[(0, 1, 2, 3)] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     >>> A[1:2, *l] | 
					
						
							|  |  |  |     A[(slice(1, 2, None), 1, 2, 3)] | 
					
						
							|  |  |  |     >>> A[1:2, *l] = 1; A | 
					
						
							|  |  |  |     A[(slice(1, 2, None), 1, 2, 3)]=1 | 
					
						
							|  |  |  |     >>> del A[1:2, *l]; A | 
					
						
							|  |  |  |     delA[(slice(1, 2, None), 1, 2, 3)] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     >>> repr(A[1:2, *l]) == repr(A[1:2, 1, 2, 3]) | 
					
						
							|  |  |  |     True | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Slices that are supposed to work, starring a tuple | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     >>> t = (1, 2, 3) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     >>> A[*t] | 
					
						
							|  |  |  |     A[(1, 2, 3)] | 
					
						
							|  |  |  |     >>> A[*t] = 1; A | 
					
						
							|  |  |  |     A[(1, 2, 3)]=1 | 
					
						
							|  |  |  |     >>> del A[*t]; A | 
					
						
							|  |  |  |     delA[(1, 2, 3)] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     >>> A[*t, 4] | 
					
						
							|  |  |  |     A[(1, 2, 3, 4)] | 
					
						
							|  |  |  |     >>> A[*t, 4] = 1; A | 
					
						
							|  |  |  |     A[(1, 2, 3, 4)]=1 | 
					
						
							|  |  |  |     >>> del A[*t, 4]; A | 
					
						
							|  |  |  |     delA[(1, 2, 3, 4)] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     >>> A[0, *t] | 
					
						
							|  |  |  |     A[(0, 1, 2, 3)] | 
					
						
							|  |  |  |     >>> A[0, *t] = 1; A | 
					
						
							|  |  |  |     A[(0, 1, 2, 3)]=1 | 
					
						
							|  |  |  |     >>> del A[0, *t]; A | 
					
						
							|  |  |  |     delA[(0, 1, 2, 3)] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     >>> A[1:2, *t] | 
					
						
							|  |  |  |     A[(slice(1, 2, None), 1, 2, 3)] | 
					
						
							|  |  |  |     >>> A[1:2, *t] = 1; A | 
					
						
							|  |  |  |     A[(slice(1, 2, None), 1, 2, 3)]=1 | 
					
						
							|  |  |  |     >>> del A[1:2, *t]; A | 
					
						
							|  |  |  |     delA[(slice(1, 2, None), 1, 2, 3)] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     >>> repr(A[1:2, *t]) == repr(A[1:2, 1, 2, 3]) | 
					
						
							|  |  |  |     True | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Starring an expression (rather than a name) in a slice | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     >>> def returns_list(): | 
					
						
							|  |  |  |     ...     return [1, 2, 3] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     >>> A[returns_list()] | 
					
						
							|  |  |  |     A[[1, 2, 3]] | 
					
						
							|  |  |  |     >>> A[returns_list()] = 1; A | 
					
						
							|  |  |  |     A[[1, 2, 3]]=1 | 
					
						
							|  |  |  |     >>> del A[returns_list()]; A | 
					
						
							|  |  |  |     delA[[1, 2, 3]] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     >>> A[returns_list(), 4] | 
					
						
							|  |  |  |     A[([1, 2, 3], 4)] | 
					
						
							|  |  |  |     >>> A[returns_list(), 4] = 1; A | 
					
						
							|  |  |  |     A[([1, 2, 3], 4)]=1 | 
					
						
							|  |  |  |     >>> del A[returns_list(), 4]; A | 
					
						
							|  |  |  |     delA[([1, 2, 3], 4)] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     >>> A[*returns_list()] | 
					
						
							|  |  |  |     A[(1, 2, 3)] | 
					
						
							|  |  |  |     >>> A[*returns_list()] = 1; A | 
					
						
							|  |  |  |     A[(1, 2, 3)]=1 | 
					
						
							|  |  |  |     >>> del A[*returns_list()]; A | 
					
						
							|  |  |  |     delA[(1, 2, 3)] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     >>> A[*returns_list(), 4] | 
					
						
							|  |  |  |     A[(1, 2, 3, 4)] | 
					
						
							|  |  |  |     >>> A[*returns_list(), 4] = 1; A | 
					
						
							|  |  |  |     A[(1, 2, 3, 4)]=1 | 
					
						
							|  |  |  |     >>> del A[*returns_list(), 4]; A | 
					
						
							|  |  |  |     delA[(1, 2, 3, 4)] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     >>> A[0, *returns_list()] | 
					
						
							|  |  |  |     A[(0, 1, 2, 3)] | 
					
						
							|  |  |  |     >>> A[0, *returns_list()] = 1; A | 
					
						
							|  |  |  |     A[(0, 1, 2, 3)]=1 | 
					
						
							|  |  |  |     >>> del A[0, *returns_list()]; A | 
					
						
							|  |  |  |     delA[(0, 1, 2, 3)] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     >>> A[*returns_list(), *returns_list()] | 
					
						
							|  |  |  |     A[(1, 2, 3, 1, 2, 3)] | 
					
						
							|  |  |  |     >>> A[*returns_list(), *returns_list()] = 1; A | 
					
						
							|  |  |  |     A[(1, 2, 3, 1, 2, 3)]=1 | 
					
						
							|  |  |  |     >>> del A[*returns_list(), *returns_list()]; A | 
					
						
							|  |  |  |     delA[(1, 2, 3, 1, 2, 3)] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Using both a starred object and a start:stop in a slice | 
					
						
							|  |  |  | (See also tests in test_syntax confirming that starring *inside* a start:stop | 
					
						
							|  |  |  | is *not* valid syntax.) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     >>> A[1:2, *b] | 
					
						
							|  |  |  |     A[(slice(1, 2, None), StarredB)] | 
					
						
							|  |  |  |     >>> A[*b, 1:2] | 
					
						
							|  |  |  |     A[(StarredB, slice(1, 2, None))] | 
					
						
							|  |  |  |     >>> A[1:2, *b, 1:2] | 
					
						
							|  |  |  |     A[(slice(1, 2, None), StarredB, slice(1, 2, None))] | 
					
						
							|  |  |  |     >>> A[*b, 1:2, *b] | 
					
						
							|  |  |  |     A[(StarredB, slice(1, 2, None), StarredB)] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     >>> A[1:, *b] | 
					
						
							|  |  |  |     A[(slice(1, None, None), StarredB)] | 
					
						
							|  |  |  |     >>> A[*b, 1:] | 
					
						
							|  |  |  |     A[(StarredB, slice(1, None, None))] | 
					
						
							|  |  |  |     >>> A[1:, *b, 1:] | 
					
						
							|  |  |  |     A[(slice(1, None, None), StarredB, slice(1, None, None))] | 
					
						
							|  |  |  |     >>> A[*b, 1:, *b] | 
					
						
							|  |  |  |     A[(StarredB, slice(1, None, None), StarredB)] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     >>> A[:1, *b] | 
					
						
							|  |  |  |     A[(slice(None, 1, None), StarredB)] | 
					
						
							|  |  |  |     >>> A[*b, :1] | 
					
						
							|  |  |  |     A[(StarredB, slice(None, 1, None))] | 
					
						
							|  |  |  |     >>> A[:1, *b, :1] | 
					
						
							|  |  |  |     A[(slice(None, 1, None), StarredB, slice(None, 1, None))] | 
					
						
							|  |  |  |     >>> A[*b, :1, *b] | 
					
						
							|  |  |  |     A[(StarredB, slice(None, 1, None), StarredB)] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     >>> A[:, *b] | 
					
						
							|  |  |  |     A[(slice(None, None, None), StarredB)] | 
					
						
							|  |  |  |     >>> A[*b, :] | 
					
						
							|  |  |  |     A[(StarredB, slice(None, None, None))] | 
					
						
							|  |  |  |     >>> A[:, *b, :] | 
					
						
							|  |  |  |     A[(slice(None, None, None), StarredB, slice(None, None, None))] | 
					
						
							|  |  |  |     >>> A[*b, :, *b] | 
					
						
							|  |  |  |     A[(StarredB, slice(None, None, None), StarredB)] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | *args annotated as starred expression | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     >>> def f1(*args: *b): pass | 
					
						
							|  |  |  |     >>> f1.__annotations__ | 
					
						
							|  |  |  |     {'args': StarredB} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     >>> def f2(*args: *b, arg1): pass | 
					
						
							|  |  |  |     >>> f2.__annotations__ | 
					
						
							|  |  |  |     {'args': StarredB} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     >>> def f3(*args: *b, arg1: int): pass | 
					
						
							|  |  |  |     >>> f3.__annotations__ | 
					
						
							|  |  |  |     {'args': StarredB, 'arg1': <class 'int'>} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     >>> def f4(*args: *b, arg1: int = 2): pass | 
					
						
							|  |  |  |     >>> f4.__annotations__ | 
					
						
							|  |  |  |     {'args': StarredB, 'arg1': <class 'int'>} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     >>> def f5(*args: *b = (1,)): pass | 
					
						
							|  |  |  |     Traceback (most recent call last): | 
					
						
							|  |  |  |         ... | 
					
						
							|  |  |  |     SyntaxError: invalid syntax | 
					
						
							|  |  |  | """
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | __test__ = {'doctests' : doctests} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-04 12:41:58 +03:00
										 |  |  | def load_tests(loader, tests, pattern): | 
					
						
							|  |  |  |     tests.addTest(doctest.DocTestSuite()) | 
					
						
							|  |  |  |     return tests | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-26 16:55:35 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | if __name__ == "__main__": | 
					
						
							| 
									
										
										
										
											2023-09-04 12:41:58 +03:00
										 |  |  |     unittest.main() |