test_pep646_syntax.py 7.8 KB

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