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