1import doctest 2import unittest 3 4doctests = """ 5 6Setup 7 8 >>> class AClass: 9 ... def __init__(self): 10 ... self._setitem_name = None 11 ... self._setitem_val = None 12 ... self._delitem_name = None 13 ... def __setitem__(self, name, val): 14 ... self._delitem_name = None 15 ... self._setitem_name = name 16 ... self._setitem_val = val 17 ... def __repr__(self): 18 ... if self._setitem_name is not None: 19 ... return f"A[{self._setitem_name}]={self._setitem_val}" 20 ... elif self._delitem_name is not None: 21 ... return f"delA[{self._delitem_name}]" 22 ... def __getitem__(self, name): 23 ... return ParameterisedA(name) 24 ... def __delitem__(self, name): 25 ... self._setitem_name = None 26 ... self._delitem_name = name 27 ... 28 >>> class ParameterisedA: 29 ... def __init__(self, name): 30 ... self._name = name 31 ... def __repr__(self): 32 ... return f"A[{self._name}]" 33 ... def __iter__(self): 34 ... for p in self._name: 35 ... yield p 36 >>> class B: 37 ... def __iter__(self): 38 ... yield StarredB() 39 ... def __repr__(self): 40 ... return "B" 41 >>> class StarredB: 42 ... def __repr__(self): 43 ... return "StarredB" 44 >>> A = AClass() 45 >>> b = B() 46 47Slices that are supposed to work, starring our custom B class 48 49 >>> A[*b] 50 A[(StarredB,)] 51 >>> A[*b] = 1; A 52 A[(StarredB,)]=1 53 >>> del A[*b]; A 54 delA[(StarredB,)] 55 56 >>> A[*b, *b] 57 A[(StarredB, StarredB)] 58 >>> A[*b, *b] = 1; A 59 A[(StarredB, StarredB)]=1 60 >>> del A[*b, *b]; A 61 delA[(StarredB, StarredB)] 62 63 >>> A[b, *b] 64 A[(B, StarredB)] 65 >>> A[b, *b] = 1; A 66 A[(B, StarredB)]=1 67 >>> del A[b, *b]; A 68 delA[(B, StarredB)] 69 70 >>> A[*b, b] 71 A[(StarredB, B)] 72 >>> A[*b, b] = 1; A 73 A[(StarredB, B)]=1 74 >>> del A[*b, b]; A 75 delA[(StarredB, B)] 76 77 >>> A[b, b, *b] 78 A[(B, B, StarredB)] 79 >>> A[b, b, *b] = 1; A 80 A[(B, B, StarredB)]=1 81 >>> del A[b, b, *b]; A 82 delA[(B, B, StarredB)] 83 84 >>> A[*b, b, b] 85 A[(StarredB, B, B)] 86 >>> A[*b, b, b] = 1; A 87 A[(StarredB, B, B)]=1 88 >>> del A[*b, b, b]; A 89 delA[(StarredB, B, B)] 90 91 >>> A[b, *b, b] 92 A[(B, StarredB, B)] 93 >>> A[b, *b, b] = 1; A 94 A[(B, StarredB, B)]=1 95 >>> del A[b, *b, b]; A 96 delA[(B, StarredB, B)] 97 98 >>> A[b, b, *b, b] 99 A[(B, B, StarredB, B)] 100 >>> A[b, b, *b, b] = 1; A 101 A[(B, B, StarredB, B)]=1 102 >>> del A[b, b, *b, b]; A 103 delA[(B, B, StarredB, B)] 104 105 >>> A[b, *b, b, b] 106 A[(B, StarredB, B, B)] 107 >>> A[b, *b, b, b] = 1; A 108 A[(B, StarredB, B, B)]=1 109 >>> del A[b, *b, b, b]; A 110 delA[(B, StarredB, B, B)] 111 112 >>> A[A[b, *b, b]] 113 A[A[(B, StarredB, B)]] 114 >>> A[A[b, *b, b]] = 1; A 115 A[A[(B, StarredB, B)]]=1 116 >>> del A[A[b, *b, b]]; A 117 delA[A[(B, StarredB, B)]] 118 119 >>> A[*A[b, *b, b]] 120 A[(B, StarredB, B)] 121 >>> A[*A[b, *b, b]] = 1; A 122 A[(B, StarredB, B)]=1 123 >>> del A[*A[b, *b, b]]; A 124 delA[(B, StarredB, B)] 125 126 >>> A[b, ...] 127 A[(B, Ellipsis)] 128 >>> A[b, ...] = 1; A 129 A[(B, Ellipsis)]=1 130 >>> del A[b, ...]; A 131 delA[(B, Ellipsis)] 132 133 >>> A[*A[b, ...]] 134 A[(B, Ellipsis)] 135 >>> A[*A[b, ...]] = 1; A 136 A[(B, Ellipsis)]=1 137 >>> del A[*A[b, ...]]; A 138 delA[(B, Ellipsis)] 139 140Slices that are supposed to work, starring a list 141 142 >>> l = [1, 2, 3] 143 144 >>> A[*l] 145 A[(1, 2, 3)] 146 >>> A[*l] = 1; A 147 A[(1, 2, 3)]=1 148 >>> del A[*l]; A 149 delA[(1, 2, 3)] 150 151 >>> A[*l, 4] 152 A[(1, 2, 3, 4)] 153 >>> A[*l, 4] = 1; A 154 A[(1, 2, 3, 4)]=1 155 >>> del A[*l, 4]; A 156 delA[(1, 2, 3, 4)] 157 158 >>> A[0, *l] 159 A[(0, 1, 2, 3)] 160 >>> A[0, *l] = 1; A 161 A[(0, 1, 2, 3)]=1 162 >>> del A[0, *l]; A 163 delA[(0, 1, 2, 3)] 164 165 >>> A[1:2, *l] 166 A[(slice(1, 2, None), 1, 2, 3)] 167 >>> A[1:2, *l] = 1; A 168 A[(slice(1, 2, None), 1, 2, 3)]=1 169 >>> del A[1:2, *l]; A 170 delA[(slice(1, 2, None), 1, 2, 3)] 171 172 >>> repr(A[1:2, *l]) == repr(A[1:2, 1, 2, 3]) 173 True 174 175Slices that are supposed to work, starring a tuple 176 177 >>> t = (1, 2, 3) 178 179 >>> A[*t] 180 A[(1, 2, 3)] 181 >>> A[*t] = 1; A 182 A[(1, 2, 3)]=1 183 >>> del A[*t]; A 184 delA[(1, 2, 3)] 185 186 >>> A[*t, 4] 187 A[(1, 2, 3, 4)] 188 >>> A[*t, 4] = 1; A 189 A[(1, 2, 3, 4)]=1 190 >>> del A[*t, 4]; A 191 delA[(1, 2, 3, 4)] 192 193 >>> A[0, *t] 194 A[(0, 1, 2, 3)] 195 >>> A[0, *t] = 1; A 196 A[(0, 1, 2, 3)]=1 197 >>> del A[0, *t]; A 198 delA[(0, 1, 2, 3)] 199 200 >>> A[1:2, *t] 201 A[(slice(1, 2, None), 1, 2, 3)] 202 >>> A[1:2, *t] = 1; A 203 A[(slice(1, 2, None), 1, 2, 3)]=1 204 >>> del A[1:2, *t]; A 205 delA[(slice(1, 2, None), 1, 2, 3)] 206 207 >>> repr(A[1:2, *t]) == repr(A[1:2, 1, 2, 3]) 208 True 209 210Starring an expression (rather than a name) in a slice 211 212 >>> def returns_list(): 213 ... return [1, 2, 3] 214 215 >>> A[returns_list()] 216 A[[1, 2, 3]] 217 >>> A[returns_list()] = 1; A 218 A[[1, 2, 3]]=1 219 >>> del A[returns_list()]; A 220 delA[[1, 2, 3]] 221 222 >>> A[returns_list(), 4] 223 A[([1, 2, 3], 4)] 224 >>> A[returns_list(), 4] = 1; A 225 A[([1, 2, 3], 4)]=1 226 >>> del A[returns_list(), 4]; A 227 delA[([1, 2, 3], 4)] 228 229 >>> A[*returns_list()] 230 A[(1, 2, 3)] 231 >>> A[*returns_list()] = 1; A 232 A[(1, 2, 3)]=1 233 >>> del A[*returns_list()]; A 234 delA[(1, 2, 3)] 235 236 >>> A[*returns_list(), 4] 237 A[(1, 2, 3, 4)] 238 >>> A[*returns_list(), 4] = 1; A 239 A[(1, 2, 3, 4)]=1 240 >>> del A[*returns_list(), 4]; A 241 delA[(1, 2, 3, 4)] 242 243 >>> A[0, *returns_list()] 244 A[(0, 1, 2, 3)] 245 >>> A[0, *returns_list()] = 1; A 246 A[(0, 1, 2, 3)]=1 247 >>> del A[0, *returns_list()]; A 248 delA[(0, 1, 2, 3)] 249 250 >>> A[*returns_list(), *returns_list()] 251 A[(1, 2, 3, 1, 2, 3)] 252 >>> A[*returns_list(), *returns_list()] = 1; A 253 A[(1, 2, 3, 1, 2, 3)]=1 254 >>> del A[*returns_list(), *returns_list()]; A 255 delA[(1, 2, 3, 1, 2, 3)] 256 257Using both a starred object and a start:stop in a slice 258(See also tests in test_syntax confirming that starring *inside* a start:stop 259is *not* valid syntax.) 260 261 >>> A[1:2, *b] 262 A[(slice(1, 2, None), StarredB)] 263 >>> A[*b, 1:2] 264 A[(StarredB, slice(1, 2, None))] 265 >>> A[1:2, *b, 1:2] 266 A[(slice(1, 2, None), StarredB, slice(1, 2, None))] 267 >>> A[*b, 1:2, *b] 268 A[(StarredB, slice(1, 2, None), StarredB)] 269 270 >>> A[1:, *b] 271 A[(slice(1, None, None), StarredB)] 272 >>> A[*b, 1:] 273 A[(StarredB, slice(1, None, None))] 274 >>> A[1:, *b, 1:] 275 A[(slice(1, None, None), StarredB, slice(1, None, None))] 276 >>> A[*b, 1:, *b] 277 A[(StarredB, slice(1, None, None), StarredB)] 278 279 >>> A[:1, *b] 280 A[(slice(None, 1, None), StarredB)] 281 >>> A[*b, :1] 282 A[(StarredB, slice(None, 1, None))] 283 >>> A[:1, *b, :1] 284 A[(slice(None, 1, None), StarredB, slice(None, 1, None))] 285 >>> A[*b, :1, *b] 286 A[(StarredB, slice(None, 1, None), StarredB)] 287 288 >>> A[:, *b] 289 A[(slice(None, None, None), StarredB)] 290 >>> A[*b, :] 291 A[(StarredB, slice(None, None, None))] 292 >>> A[:, *b, :] 293 A[(slice(None, None, None), StarredB, slice(None, None, None))] 294 >>> A[*b, :, *b] 295 A[(StarredB, slice(None, None, None), StarredB)] 296 297*args annotated as starred expression 298 299 >>> def f1(*args: *b): pass 300 >>> f1.__annotations__ 301 {'args': StarredB} 302 303 >>> def f2(*args: *b, arg1): pass 304 >>> f2.__annotations__ 305 {'args': StarredB} 306 307 >>> def f3(*args: *b, arg1: int): pass 308 >>> f3.__annotations__ 309 {'args': StarredB, 'arg1': <class 'int'>} 310 311 >>> def f4(*args: *b, arg1: int = 2): pass 312 >>> f4.__annotations__ 313 {'args': StarredB, 'arg1': <class 'int'>} 314 315 >>> def f5(*args: *b = (1,)): pass 316 Traceback (most recent call last): 317 ... 318 SyntaxError: invalid syntax 319""" 320 321__test__ = {'doctests' : doctests} 322 323def load_tests(loader, tests, pattern): 324 tests.addTest(doctest.DocTestSuite()) 325 return tests 326 327 328if __name__ == "__main__": 329 unittest.main() 330