rapydscript-ns 0.9.3 → 0.9.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. package/.agignore +1 -1
  2. package/.github/workflows/ci.yml +38 -38
  3. package/=template.pyj +5 -5
  4. package/CHANGELOG.md +18 -0
  5. package/HACKING.md +103 -103
  6. package/LICENSE +24 -24
  7. package/PYTHON_GAPS.md +52 -142
  8. package/README.md +51 -21
  9. package/TODO.md +1 -26
  10. package/add-toc-to-readme +2 -2
  11. package/bin/export +75 -75
  12. package/bin/rapydscript +0 -0
  13. package/bin/web-repl-export +102 -102
  14. package/build +2 -2
  15. package/language-service/index.js +88 -36
  16. package/package.json +1 -1
  17. package/publish.py +37 -37
  18. package/release/baselib-plain-pretty.js +157 -31
  19. package/release/baselib-plain-ugly.js +5 -5
  20. package/release/compiler.js +724 -426
  21. package/release/signatures.json +29 -29
  22. package/session.vim +4 -4
  23. package/setup.cfg +2 -2
  24. package/src/ast.pyj +7 -0
  25. package/src/baselib-containers.pyj +41 -4
  26. package/src/baselib-errors.pyj +4 -3
  27. package/src/baselib-internal.pyj +47 -18
  28. package/src/baselib-str.pyj +16 -3
  29. package/src/compiler.pyj +36 -36
  30. package/src/errors.pyj +30 -30
  31. package/src/lib/aes.pyj +646 -646
  32. package/src/lib/collections.pyj +227 -3
  33. package/src/lib/copy.pyj +120 -120
  34. package/src/lib/elementmaker.pyj +83 -83
  35. package/src/lib/encodings.pyj +126 -126
  36. package/src/lib/gettext.pyj +569 -569
  37. package/src/lib/itertools.pyj +580 -580
  38. package/src/lib/math.pyj +193 -193
  39. package/src/lib/operator.pyj +11 -11
  40. package/src/lib/pprint.pyj +455 -0
  41. package/src/lib/random.pyj +118 -118
  42. package/src/lib/react.pyj +74 -74
  43. package/src/lib/statistics.pyj +0 -0
  44. package/src/lib/traceback.pyj +63 -63
  45. package/src/lib/uuid.pyj +77 -77
  46. package/src/monaco-language-service/completions.js +21 -14
  47. package/src/monaco-language-service/diagnostics.js +2 -2
  48. package/src/monaco-language-service/dts.js +58 -15
  49. package/src/monaco-language-service/package.json +3 -0
  50. package/src/output/classes.pyj +25 -2
  51. package/src/output/codegen.pyj +4 -1
  52. package/src/output/comments.pyj +45 -45
  53. package/src/output/exceptions.pyj +201 -201
  54. package/src/output/jsx.pyj +164 -164
  55. package/src/output/treeshake.pyj +182 -182
  56. package/src/output/utils.pyj +72 -72
  57. package/src/parse.pyj +42 -7
  58. package/src/string_interpolation.pyj +72 -72
  59. package/src/tokenizer.pyj +18 -2
  60. package/src/unicode_aliases.pyj +576 -576
  61. package/src/utils.pyj +192 -192
  62. package/test/_import_one.pyj +37 -37
  63. package/test/_import_two/__init__.pyj +11 -11
  64. package/test/_import_two/level2/deep.pyj +4 -4
  65. package/test/_import_two/other.pyj +6 -6
  66. package/test/_import_two/sub.pyj +13 -13
  67. package/test/aes_vectors.pyj +421 -421
  68. package/test/annotations.pyj +80 -80
  69. package/test/baselib.pyj +23 -0
  70. package/test/chainmap.pyj +185 -0
  71. package/test/dataclasses.pyj +3 -4
  72. package/test/decorators.pyj +77 -77
  73. package/test/docstrings.pyj +39 -39
  74. package/test/elementmaker_test.pyj +45 -45
  75. package/test/enum.pyj +1 -1
  76. package/test/functions.pyj +151 -151
  77. package/test/generators.pyj +41 -41
  78. package/test/generic.pyj +370 -370
  79. package/test/internationalization.pyj +73 -73
  80. package/test/lint.pyj +164 -164
  81. package/test/loops.pyj +85 -85
  82. package/test/numpy.pyj +734 -734
  83. package/test/pprint.pyj +232 -0
  84. package/test/python_features.pyj +1 -1
  85. package/test/repl.pyj +121 -121
  86. package/test/scoped_flags.pyj +76 -76
  87. package/test/statistics.pyj +224 -0
  88. package/test/str.pyj +4 -4
  89. package/test/unit/index.js +455 -0
  90. package/test/unit/language-service-completions.js +2 -0
  91. package/test/unit/language-service-dts.js +113 -0
  92. package/test/unit/language-service-hover.js +455 -455
  93. package/test/unit/language-service.js +135 -2
  94. package/test/unit/web-repl.js +349 -1
  95. package/tools/compiler.d.ts +367 -367
  96. package/tools/completer.js +131 -131
  97. package/tools/export.js +4 -2
  98. package/tools/gettext.js +185 -185
  99. package/tools/ini.js +65 -65
  100. package/tools/msgfmt.js +187 -187
  101. package/tools/repl.js +223 -223
  102. package/tools/test.js +118 -118
  103. package/tools/utils.js +141 -128
  104. package/tools/web_repl.js +95 -95
  105. package/try +41 -41
  106. package/web-repl/env.js +196 -196
  107. package/web-repl/index.html +163 -163
  108. package/web-repl/prism.css +139 -139
  109. package/web-repl/prism.js +113 -113
  110. package/web-repl/rapydscript.js +228 -226
  111. package/web-repl/sha1.js +25 -25
@@ -1,80 +1,80 @@
1
- def add(a: int, b: float):
2
- return a + b
3
-
4
- assrt.ok(add.__annotations__)
5
- assrt.equal(add.__annotations__['a'], int)
6
- assrt.equal(add.__annotations__['b'], float)
7
- assrt.equal(add.__annotations__['return'], undefined)
8
-
9
- def sum(ls: list) -> int:
10
- pass
11
-
12
- assrt.ok(not (sum.__annotations__ == undefined))
13
- assrt.deepEqual(sum.__annotations__, {
14
- 'ls': list,
15
- 'return': int
16
- })
17
-
18
- def optional(a:int=10):
19
- return a
20
-
21
- assrt.ok(not (optional.__annotations__ == undefined))
22
- assrt.equal(optional.__annotations__.a, int)
23
- assrt.equal(optional.__defaults__.a, 10)
24
-
25
- def otherexpr(a:3+4) -> [1, 2]:
26
- pass
27
-
28
- assrt.ok(not (otherexpr.__annotations__ == undefined))
29
- assrt.equal(otherexpr.__annotations__['a'], 7)
30
- assrt.deepEqual(otherexpr.__annotations__['return'], [1, 2])
31
-
32
- def basic(x:float):
33
- pass
34
-
35
- assrt.deepEqual(basic.__annotations__, {
36
- 'x': float
37
- })
38
-
39
- def kwstarargs(*args:list, **kwargs:dict) -> int:
40
- pass
41
-
42
- assrt.equal(kwstarargs.__annotations__['return'], int)
43
-
44
- def nothing():
45
- pass
46
-
47
- assrt.ok(nothing.__annotations__ == undefined)
48
- assrt.throws(def():
49
- nothing.__annotations__['return']
50
- )
51
-
52
- test = def(x: int):
53
- pass
54
-
55
- assrt.deepEqual(test.__annotations__, {
56
- 'x': int
57
- })
58
-
59
- anonreturn = def() -> 'test':
60
- pass
61
-
62
- assrt.equal(anonreturn.__annotations__['return'], 'test')
63
-
64
- assrt.equal(def asexpr(a: int):
65
- a
66
- .__annotations__['a'], int)
67
-
68
- assrt.deepEqual(def(a: int) -> float:
69
- a + 10.0
70
- .__annotations__, {
71
- 'a': int,
72
- 'return': float
73
- })
74
-
75
- class A:
76
-
77
- def f(self, a : int, b: 'x') -> float:
78
- pass
79
-
80
- assrt.deepEqual(A.prototype.f.__annotations__, {'a':int, 'b':'x', 'return': float})
1
+ def add(a: int, b: float):
2
+ return a + b
3
+
4
+ assrt.ok(add.__annotations__)
5
+ assrt.equal(add.__annotations__['a'], int)
6
+ assrt.equal(add.__annotations__['b'], float)
7
+ assrt.equal(add.__annotations__['return'], undefined)
8
+
9
+ def sum(ls: list) -> int:
10
+ pass
11
+
12
+ assrt.ok(not (sum.__annotations__ == undefined))
13
+ assrt.deepEqual(sum.__annotations__, {
14
+ 'ls': list,
15
+ 'return': int
16
+ })
17
+
18
+ def optional(a:int=10):
19
+ return a
20
+
21
+ assrt.ok(not (optional.__annotations__ == undefined))
22
+ assrt.equal(optional.__annotations__.a, int)
23
+ assrt.equal(optional.__defaults__.a, 10)
24
+
25
+ def otherexpr(a:3+4) -> [1, 2]:
26
+ pass
27
+
28
+ assrt.ok(not (otherexpr.__annotations__ == undefined))
29
+ assrt.equal(otherexpr.__annotations__['a'], 7)
30
+ assrt.deepEqual(otherexpr.__annotations__['return'], [1, 2])
31
+
32
+ def basic(x:float):
33
+ pass
34
+
35
+ assrt.deepEqual(basic.__annotations__, {
36
+ 'x': float
37
+ })
38
+
39
+ def kwstarargs(*args:list, **kwargs:dict) -> int:
40
+ pass
41
+
42
+ assrt.equal(kwstarargs.__annotations__['return'], int)
43
+
44
+ def nothing():
45
+ pass
46
+
47
+ assrt.ok(nothing.__annotations__ == undefined)
48
+ assrt.throws(def():
49
+ nothing.__annotations__['return']
50
+ )
51
+
52
+ test = def(x: int):
53
+ pass
54
+
55
+ assrt.deepEqual(test.__annotations__, {
56
+ 'x': int
57
+ })
58
+
59
+ anonreturn = def() -> 'test':
60
+ pass
61
+
62
+ assrt.equal(anonreturn.__annotations__['return'], 'test')
63
+
64
+ assrt.equal(def asexpr(a: int):
65
+ a
66
+ .__annotations__['a'], int)
67
+
68
+ assrt.deepEqual(def(a: int) -> float:
69
+ a + 10.0
70
+ .__annotations__, {
71
+ 'a': int,
72
+ 'return': float
73
+ })
74
+
75
+ class A:
76
+
77
+ def f(self, a : int, b: 'x') -> float:
78
+ pass
79
+
80
+ assrt.deepEqual(A.prototype.f.__annotations__, {'a':int, 'b':'x', 'return': float})
package/test/baselib.pyj CHANGED
@@ -159,6 +159,29 @@ a.sort()
159
159
  assrt.deepEqual(a, [1,2,3,4])
160
160
  a.sort(reverse=True)
161
161
  assrt.deepEqual(a, [4,3,2,1])
162
+
163
+ # sort: a positional two-argument function is treated as a comparator
164
+ assrt.deepEqual(sorted([3, 1, 2, 10], def(x, y): return x - y;), [1, 2, 3, 10])
165
+ assrt.deepEqual(sorted([3, 1, 2, 10], def(x, y): return y - x;), [10, 3, 2, 1])
166
+ sort_cmp = [5, 2, 8, 1]
167
+ sort_cmp.sort(def(x, y): return x - y;)
168
+ assrt.deepEqual(sort_cmp, [1, 2, 5, 8])
169
+ # a one-argument function is still a key function
170
+ assrt.deepEqual(sorted([3, 1, 2], key=def(x): return -x;), [3, 2, 1])
171
+ # comparator path keeps ties in their original order (stable)
172
+ assrt.deepEqual(sorted([[1, 'a'], [1, 'b'], [0, 'c']], def(p, q): return p[0] - q[0];),
173
+ [[0, 'c'], [1, 'a'], [1, 'b']])
174
+
175
+ # sort: custom objects are ordered via their __lt__ method
176
+ class SortOrd:
177
+ def __init__(self, v):
178
+ self.v = v
179
+ def __lt__(self, other):
180
+ return self.v < other.v
181
+ ord_asc = sorted([SortOrd(3), SortOrd(1), SortOrd(2)])
182
+ assrt.deepEqual([ord_asc[0].v, ord_asc[1].v, ord_asc[2].v], [1, 2, 3])
183
+ ord_desc = sorted([SortOrd(3), SortOrd(1), SortOrd(2)], reverse=True)
184
+ assrt.deepEqual([ord_desc[0].v, ord_desc[1].v, ord_desc[2].v], [3, 2, 1])
162
185
  assrt.deepEqual(a, a.slice())
163
186
  assrt.ok(a is not a.slice())
164
187
  assrt.ok(a.slice().extend is not undefined)
@@ -0,0 +1,185 @@
1
+ # globals: assrt
2
+ # vim:fileencoding=utf-8
3
+ #
4
+ # chainmap.pyj
5
+ # Tests for collections.ChainMap.
6
+
7
+ from __python__ import overload_getitem
8
+ from collections import ChainMap
9
+
10
+ ae = assrt.equal
11
+ ade = assrt.deepEqual
12
+ ok = assrt.ok
13
+
14
+ # ── 1. construction and lookup — first map wins ───────────────────────────────
15
+
16
+ defaults = {'color': 'red', 'user': 'guest', 'depth': 1}
17
+ overrides = {'user': 'admin'}
18
+ cm = ChainMap(overrides, defaults)
19
+
20
+ ae(cm['user'], 'admin') # found in first map
21
+ ae(cm['color'], 'red') # falls through to second map
22
+ ae(cm['depth'], 1)
23
+ ae(len(cm), 3) # unique keys across all maps
24
+
25
+ # ── 2. empty construction uses a single empty dict ────────────────────────────
26
+
27
+ empty = ChainMap()
28
+ ae(len(empty), 0)
29
+ ae(empty.maps.length, 1)
30
+
31
+ # ── 3. missing key raises KeyError ────────────────────────────────────────────
32
+
33
+ _err = False
34
+ try:
35
+ cm['missing']
36
+ except KeyError:
37
+ _err = True
38
+ ok(_err, 'missing key raises KeyError')
39
+
40
+ # ── 4. writes, deletes and updates affect only the first map ──────────────────
41
+
42
+ cm['depth'] = 99
43
+ ae(cm['depth'], 99) # shadows the value in defaults
44
+ ae(defaults['depth'], 1) # underlying map untouched
45
+ ae(overrides['depth'], 99) # written to the first map
46
+
47
+ cm['user'] = 'root'
48
+ ae(cm['user'], 'root')
49
+
50
+ del cm['user']
51
+ ae(cm['user'], 'guest') # first-map entry removed; falls through again
52
+
53
+ _del_err = False
54
+ try:
55
+ del cm['color'] # 'color' lives in the second map, not the first
56
+ except KeyError:
57
+ _del_err = True
58
+ ok(_del_err, 'deleting a key absent from the first map raises KeyError')
59
+
60
+ # ── 5. membership, get, and iteration ─────────────────────────────────────────
61
+
62
+ ok('color' in cm)
63
+ ok('user' in cm)
64
+ ok('nope' not in cm)
65
+ ae(cm.get('color'), 'red')
66
+ ae(cm.get('nope'), None)
67
+ ae(cm.get('nope', 'fallback'), 'fallback')
68
+
69
+ m1 = {'a': 1, 'b': 2}
70
+ m2 = {'c': 3}
71
+ ordered = ChainMap(m1, m2)
72
+ ade(list(ordered), ['c', 'a', 'b']) # Python order: later maps first
73
+ ade(ordered.keys(), ['c', 'a', 'b'])
74
+ ade(ordered.values(), [3, 1, 2])
75
+ ade(ordered.items(), [['c', 3], ['a', 1], ['b', 2]])
76
+
77
+ _seen = []
78
+ for k in ordered:
79
+ _seen.push(k)
80
+ ade(_seen, ['c', 'a', 'b'])
81
+
82
+ # ── 6. maps attribute, new_child and parents ──────────────────────────────────
83
+
84
+ base = ChainMap({'x': 1})
85
+ child = base.new_child({'x': 2, 'y': 3})
86
+ ae(child['x'], 2) # child's own map shadows the parent
87
+ ae(child['y'], 3)
88
+ ae(base['x'], 1) # parent unchanged
89
+ ae(child.maps.length, 2)
90
+
91
+ # new_child() with no argument adds a fresh empty map
92
+ fresh = base.new_child()
93
+ ae(fresh.maps.length, 2)
94
+ ae(len(fresh), 1)
95
+ fresh['z'] = 7
96
+ ae(fresh['z'], 7)
97
+ ok('z' not in base)
98
+
99
+ # parents drops the first map
100
+ parents = child.parents
101
+ ae(parents['x'], 1)
102
+ ae(parents.maps.length, 1)
103
+
104
+ # ── 7. copy is shallow — first map cloned, rest shared ────────────────────────
105
+
106
+ src = ChainMap({'a': 1}, {'b': 2})
107
+ dup = src.copy()
108
+ dup['a'] = 100
109
+ ae(src['a'], 1) # first map was cloned
110
+ dup['c'] = 9 # writes to the cloned first map
111
+ ok('c' not in src)
112
+ ae(dup['b'], 2) # tail maps are shared
113
+
114
+ # ── 8. pop, popitem, clear, setdefault, update ────────────────────────────────
115
+
116
+ p = ChainMap({'a': 1, 'b': 2}, {'c': 3})
117
+ ae(p.pop('a'), 1)
118
+ ok('a' not in p.maps[0])
119
+ ae(p.pop('missing', 'dflt'), 'dflt')
120
+
121
+ _pop_err = False
122
+ try:
123
+ p.pop('c') # 'c' is not in the first map
124
+ except KeyError:
125
+ _pop_err = True
126
+ ok(_pop_err, 'pop of a key absent from the first map raises KeyError')
127
+
128
+ pi = ChainMap({'only': 42})
129
+ ade(pi.popitem(), ['only', 42])
130
+ ae(len(pi.maps[0]), 0)
131
+
132
+ sd = ChainMap({'a': 1}, {'b': 2})
133
+ ae(sd.setdefault('a', 999), 1) # existing key — unchanged
134
+ ae(sd.setdefault('new', 5), 5) # missing key — inserted into first map
135
+ ae(sd['new'], 5)
136
+ ae(sd.setdefault('b', 0), 2) # found in tail map — not copied forward
137
+ ok('b' not in sd.maps[0])
138
+
139
+ up = ChainMap({'a': 1}, {'b': 2})
140
+ up.update({'a': 10, 'd': 4})
141
+ ae(up['a'], 10)
142
+ ae(up['d'], 4)
143
+ up.update(e=5)
144
+ ae(up['e'], 5)
145
+ up.update([['f', 6]])
146
+ ae(up['f'], 6)
147
+
148
+ cl = ChainMap({'a': 1, 'b': 2}, {'c': 3})
149
+ cl.clear()
150
+ ae(len(cl.maps[0]), 0)
151
+ ae(cl['c'], 3) # tail map survives clear()
152
+
153
+ # ── 9. nested ChainMap as a member map ────────────────────────────────────────
154
+
155
+ inner = ChainMap({'a': 1}, {'b': 2})
156
+ outer = ChainMap({'c': 3}, inner)
157
+ ae(outer['a'], 1)
158
+ ae(outer['b'], 2)
159
+ ae(outer['c'], 3)
160
+ ok('a' in outer)
161
+ ae(len(outer), 3)
162
+
163
+ # ── 10. equality ──────────────────────────────────────────────────────────────
164
+
165
+ ok(ChainMap({'a': 1}, {'b': 2}) == ChainMap({'a': 1}, {'b': 2}))
166
+ ok(ChainMap({'a': 1}) == {'a': 1})
167
+ ok(not (ChainMap({'a': 1}) == ChainMap({'a': 2})))
168
+ ok(not (ChainMap({'a': 1}) == {'a': 1, 'b': 2}))
169
+
170
+ # ── 11. repr ──────────────────────────────────────────────────────────────────
171
+
172
+ # RapydScript's repr() quotes strings with double quotes (as Counter/OrderedDict do)
173
+ ae(ChainMap({'a': 1}, {'b': 2}).__repr__(), "ChainMap({'a': 1}, {'b': 2})")
174
+
175
+ # ── 12. dynamic — changes to underlying maps are visible ──────────────────────
176
+
177
+ live = {'k': 'v1'}
178
+ dyn = ChainMap({}, live)
179
+ ae(dyn['k'], 'v1')
180
+ live['k'] = 'v2'
181
+ ae(dyn['k'], 'v2') # ChainMap reflects the mutation
182
+ live['extra'] = 'x'
183
+ ok('extra' in dyn)
184
+
185
+ print('chainmap tests passed')
@@ -76,7 +76,7 @@ class _Hidden:
76
76
  secret: str = field('s3cr3t', repr=False)
77
77
 
78
78
  h = _Hidden("visible")
79
- ae(repr(h), '_Hidden(public="visible")')
79
+ ae(repr(h), "_Hidden(public='visible')")
80
80
  ae(h.secret, 's3cr3t')
81
81
 
82
82
  # ── 6. field() init=False ─────────────────────────────────────────────────────
@@ -209,11 +209,10 @@ ae(ch2.y, 0)
209
209
  ae(ch2.z, 'default')
210
210
 
211
211
  # repr shows all fields including inherited
212
- # (RapydScript repr() uses double quotes for strings, like JavaScript)
213
212
  r = repr(ch2)
214
213
  ok('x=10' in r)
215
214
  ok('y=0' in r)
216
- ok('z="default"' in r)
215
+ ok("z='default'" in r)
217
216
 
218
217
  # ── 15. MISSING sentinel ──────────────────────────────────────────────────────
219
218
 
@@ -240,7 +239,7 @@ class _Explicit:
240
239
 
241
240
  ex = _Explicit()
242
241
  ae(ex.name, 'x')
243
- ae(repr(ex), '_Explicit(name="x")')
242
+ ae(repr(ex), "_Explicit(name='x')")
244
243
 
245
244
  # ── 18. Nested list field with asdict ────────────────────────────────────────
246
245
 
@@ -1,77 +1,77 @@
1
- # vim:fileencoding=utf-8
2
- # License: BSD Copyright: 2015, Kovid Goyal <kovid at kovidgoyal.net>
3
-
4
- def double(f):
5
- return def (x):
6
- return 2 * f(x)
7
-
8
- def triple(f):
9
- return def(x):
10
- return 3 * f(x)
11
-
12
- @double
13
- def half(x):
14
- return x // 2
15
-
16
- @double
17
- def f1(x):
18
- return x
19
-
20
- @double
21
- @triple
22
- def f2(x):
23
- return x
24
-
25
- def append_one(f):
26
- return def(x):
27
- ans = f(x)
28
- ans.push(1)
29
- return ans
30
-
31
- def append_two(f):
32
- return def(x):
33
- ans = f(x)
34
- ans.push(2)
35
- return ans
36
-
37
- @append_two
38
- @append_one
39
- def f3():
40
- return []
41
-
42
- o = {'double':double}
43
-
44
- @o.double
45
- def f4():
46
- return 1
47
-
48
- assrt.equal(2, half(2))
49
- assrt.equal(4, f1(2))
50
- assrt.equal(12, f2(2))
51
- assrt.equal(2, f4())
52
- assrt.deepEqual([1, 2], f3())
53
-
54
- def multiply(amt):
55
-
56
- def wrapper(f):
57
- return def ():
58
- return amt * f()
59
-
60
- return wrapper
61
-
62
- @multiply(2)
63
- def two():
64
- return 1
65
-
66
- @multiply(3)
67
- def three():
68
- return 1
69
-
70
- @multiply(2)
71
- @multiply(2)
72
- def four():
73
- return 1
74
-
75
- assrt.equal(2, two())
76
- assrt.equal(3, three())
77
- assrt.equal(4, four())
1
+ # vim:fileencoding=utf-8
2
+ # License: BSD Copyright: 2015, Kovid Goyal <kovid at kovidgoyal.net>
3
+
4
+ def double(f):
5
+ return def (x):
6
+ return 2 * f(x)
7
+
8
+ def triple(f):
9
+ return def(x):
10
+ return 3 * f(x)
11
+
12
+ @double
13
+ def half(x):
14
+ return x // 2
15
+
16
+ @double
17
+ def f1(x):
18
+ return x
19
+
20
+ @double
21
+ @triple
22
+ def f2(x):
23
+ return x
24
+
25
+ def append_one(f):
26
+ return def(x):
27
+ ans = f(x)
28
+ ans.push(1)
29
+ return ans
30
+
31
+ def append_two(f):
32
+ return def(x):
33
+ ans = f(x)
34
+ ans.push(2)
35
+ return ans
36
+
37
+ @append_two
38
+ @append_one
39
+ def f3():
40
+ return []
41
+
42
+ o = {'double':double}
43
+
44
+ @o.double
45
+ def f4():
46
+ return 1
47
+
48
+ assrt.equal(2, half(2))
49
+ assrt.equal(4, f1(2))
50
+ assrt.equal(12, f2(2))
51
+ assrt.equal(2, f4())
52
+ assrt.deepEqual([1, 2], f3())
53
+
54
+ def multiply(amt):
55
+
56
+ def wrapper(f):
57
+ return def ():
58
+ return amt * f()
59
+
60
+ return wrapper
61
+
62
+ @multiply(2)
63
+ def two():
64
+ return 1
65
+
66
+ @multiply(3)
67
+ def three():
68
+ return 1
69
+
70
+ @multiply(2)
71
+ @multiply(2)
72
+ def four():
73
+ return 1
74
+
75
+ assrt.equal(2, two())
76
+ assrt.equal(3, three())
77
+ assrt.equal(4, four())
@@ -1,39 +1,39 @@
1
- # vim:fileencoding=utf-8
2
- # License: BSD Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
3
- # globals: ρσ_module_doc__
4
-
5
- import _import_one
6
-
7
- def f():
8
- " A basic docstring "
9
- pass
10
-
11
- assrt.equal(f.__doc__, 'A basic docstring')
12
- assrt.equal(_import_one.__doc__, 'Module level ds1\n\nModule level ds2\nline2\n\nModule level ds 3')
13
-
14
- def g():
15
- '''
16
- A more complex docstring:
17
- xxx
18
- yyyy
19
-
20
- the end
21
- '''
22
- pass
23
-
24
- assrt.equal(g.__doc__, 'A more complex docstring:\n xxx\n yyyy\n\nthe end')
25
-
26
- class D:
27
- ' Docstring for a class '
28
-
29
- def method(self):
30
- 'ds for a method'
31
- pass
32
-
33
- assrt.equal(D().__doc__, 'Docstring for a class')
34
- assrt.equal(D().method.__doc__, 'ds for a method')
35
-
36
- x = def():
37
- 'xxx'
38
-
39
- assrt.equal(x.__doc__, 'xxx')
1
+ # vim:fileencoding=utf-8
2
+ # License: BSD Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
3
+ # globals: ρσ_module_doc__
4
+
5
+ import _import_one
6
+
7
+ def f():
8
+ " A basic docstring "
9
+ pass
10
+
11
+ assrt.equal(f.__doc__, 'A basic docstring')
12
+ assrt.equal(_import_one.__doc__, 'Module level ds1\n\nModule level ds2\nline2\n\nModule level ds 3')
13
+
14
+ def g():
15
+ '''
16
+ A more complex docstring:
17
+ xxx
18
+ yyyy
19
+
20
+ the end
21
+ '''
22
+ pass
23
+
24
+ assrt.equal(g.__doc__, 'A more complex docstring:\n xxx\n yyyy\n\nthe end')
25
+
26
+ class D:
27
+ ' Docstring for a class '
28
+
29
+ def method(self):
30
+ 'ds for a method'
31
+ pass
32
+
33
+ assrt.equal(D().__doc__, 'Docstring for a class')
34
+ assrt.equal(D().method.__doc__, 'ds for a method')
35
+
36
+ x = def():
37
+ 'xxx'
38
+
39
+ assrt.equal(x.__doc__, 'xxx')