• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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