@alloy-js/python 0.0.1

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 (206) hide show
  1. package/CHANGELOG.md +3 -0
  2. package/LICENSE +7 -0
  3. package/api-extractor.json +4 -0
  4. package/dist/src/builtins/python.d.ts +9 -0
  5. package/dist/src/builtins/python.d.ts.map +1 -0
  6. package/dist/src/builtins/python.js +17 -0
  7. package/dist/src/components/Atom.d.ts +19 -0
  8. package/dist/src/components/Atom.d.ts.map +1 -0
  9. package/dist/src/components/Atom.js +82 -0
  10. package/dist/src/components/CallSignature.d.ts +79 -0
  11. package/dist/src/components/CallSignature.d.ts.map +1 -0
  12. package/dist/src/components/CallSignature.js +201 -0
  13. package/dist/src/components/ClassDeclaration.d.ts +37 -0
  14. package/dist/src/components/ClassDeclaration.d.ts.map +1 -0
  15. package/dist/src/components/ClassDeclaration.js +83 -0
  16. package/dist/src/components/ClassInstantiation.d.ts +24 -0
  17. package/dist/src/components/ClassInstantiation.d.ts.map +1 -0
  18. package/dist/src/components/ClassInstantiation.js +35 -0
  19. package/dist/src/components/Declaration.d.ts +48 -0
  20. package/dist/src/components/Declaration.d.ts.map +1 -0
  21. package/dist/src/components/Declaration.js +37 -0
  22. package/dist/src/components/EnumDeclaration.d.ts +164 -0
  23. package/dist/src/components/EnumDeclaration.d.ts.map +1 -0
  24. package/dist/src/components/EnumDeclaration.js +278 -0
  25. package/dist/src/components/EnumMember.d.ts +46 -0
  26. package/dist/src/components/EnumMember.d.ts.map +1 -0
  27. package/dist/src/components/EnumMember.js +67 -0
  28. package/dist/src/components/FunctionCallExpression.d.ts +19 -0
  29. package/dist/src/components/FunctionCallExpression.d.ts.map +1 -0
  30. package/dist/src/components/FunctionCallExpression.js +40 -0
  31. package/dist/src/components/FunctionDeclaration.d.ts +47 -0
  32. package/dist/src/components/FunctionDeclaration.d.ts.map +1 -0
  33. package/dist/src/components/FunctionDeclaration.js +107 -0
  34. package/dist/src/components/ImportStatement.d.ts +39 -0
  35. package/dist/src/components/ImportStatement.d.ts.map +1 -0
  36. package/dist/src/components/ImportStatement.js +104 -0
  37. package/dist/src/components/MemberExpression.d.ts +97 -0
  38. package/dist/src/components/MemberExpression.d.ts.map +1 -0
  39. package/dist/src/components/MemberExpression.js +308 -0
  40. package/dist/src/components/NoNamePolicy.d.ts +23 -0
  41. package/dist/src/components/NoNamePolicy.d.ts.map +1 -0
  42. package/dist/src/components/NoNamePolicy.js +27 -0
  43. package/dist/src/components/PyDoc.d.ts +90 -0
  44. package/dist/src/components/PyDoc.d.ts.map +1 -0
  45. package/dist/src/components/PyDoc.js +280 -0
  46. package/dist/src/components/PythonBlock.d.ts +23 -0
  47. package/dist/src/components/PythonBlock.d.ts.map +1 -0
  48. package/dist/src/components/PythonBlock.js +31 -0
  49. package/dist/src/components/Reference.d.ts +13 -0
  50. package/dist/src/components/Reference.d.ts.map +1 -0
  51. package/dist/src/components/Reference.js +18 -0
  52. package/dist/src/components/SourceFile.d.ts +46 -0
  53. package/dist/src/components/SourceFile.d.ts.map +1 -0
  54. package/dist/src/components/SourceFile.js +75 -0
  55. package/dist/src/components/StatementList.d.ts +25 -0
  56. package/dist/src/components/StatementList.d.ts.map +1 -0
  57. package/dist/src/components/StatementList.js +29 -0
  58. package/dist/src/components/VariableDeclaration.d.ts +62 -0
  59. package/dist/src/components/VariableDeclaration.d.ts.map +1 -0
  60. package/dist/src/components/VariableDeclaration.js +131 -0
  61. package/dist/src/components/index.d.ts +19 -0
  62. package/dist/src/components/index.d.ts.map +1 -0
  63. package/dist/src/components/index.js +18 -0
  64. package/dist/src/create-module.d.ts +16 -0
  65. package/dist/src/create-module.d.ts.map +1 -0
  66. package/dist/src/create-module.js +64 -0
  67. package/dist/src/index.d.ts +8 -0
  68. package/dist/src/index.d.ts.map +1 -0
  69. package/dist/src/index.js +7 -0
  70. package/dist/src/name-policy.d.ts +5 -0
  71. package/dist/src/name-policy.d.ts.map +1 -0
  72. package/dist/src/name-policy.js +47 -0
  73. package/dist/src/parameter-descriptor.d.ts +31 -0
  74. package/dist/src/parameter-descriptor.d.ts.map +1 -0
  75. package/dist/src/parameter-descriptor.js +1 -0
  76. package/dist/src/symbol-creation.d.ts +4 -0
  77. package/dist/src/symbol-creation.d.ts.map +1 -0
  78. package/dist/src/symbol-creation.js +24 -0
  79. package/dist/src/symbols/custom-output-scope.d.ts +10 -0
  80. package/dist/src/symbols/custom-output-scope.d.ts.map +1 -0
  81. package/dist/src/symbols/custom-output-scope.js +25 -0
  82. package/dist/src/symbols/index.d.ts +7 -0
  83. package/dist/src/symbols/index.d.ts.map +1 -0
  84. package/dist/src/symbols/index.js +6 -0
  85. package/dist/src/symbols/python-member-scope.d.ts +7 -0
  86. package/dist/src/symbols/python-member-scope.d.ts.map +1 -0
  87. package/dist/src/symbols/python-member-scope.js +9 -0
  88. package/dist/src/symbols/python-module-scope.d.ts +25 -0
  89. package/dist/src/symbols/python-module-scope.d.ts.map +1 -0
  90. package/dist/src/symbols/python-module-scope.js +52 -0
  91. package/dist/src/symbols/python-output-symbol.d.ts +19 -0
  92. package/dist/src/symbols/python-output-symbol.d.ts.map +1 -0
  93. package/dist/src/symbols/python-output-symbol.js +22 -0
  94. package/dist/src/symbols/reference.d.ts +4 -0
  95. package/dist/src/symbols/reference.d.ts.map +1 -0
  96. package/dist/src/symbols/reference.js +60 -0
  97. package/dist/src/symbols/scopes.d.ts +5 -0
  98. package/dist/src/symbols/scopes.d.ts.map +1 -0
  99. package/dist/src/symbols/scopes.js +4 -0
  100. package/dist/src/utils.d.ts +7 -0
  101. package/dist/src/utils.d.ts.map +1 -0
  102. package/dist/src/utils.js +12 -0
  103. package/dist/test/callsignatures.test.d.ts +2 -0
  104. package/dist/test/callsignatures.test.d.ts.map +1 -0
  105. package/dist/test/callsignatures.test.js +276 -0
  106. package/dist/test/classdeclarations.test.d.ts +2 -0
  107. package/dist/test/classdeclarations.test.d.ts.map +1 -0
  108. package/dist/test/classdeclarations.test.js +397 -0
  109. package/dist/test/classinstantiations.test.d.ts +2 -0
  110. package/dist/test/classinstantiations.test.d.ts.map +1 -0
  111. package/dist/test/classinstantiations.test.js +168 -0
  112. package/dist/test/enums.test.d.ts +2 -0
  113. package/dist/test/enums.test.d.ts.map +1 -0
  114. package/dist/test/enums.test.js +211 -0
  115. package/dist/test/externals.test.d.ts +2 -0
  116. package/dist/test/externals.test.d.ts.map +1 -0
  117. package/dist/test/externals.test.js +219 -0
  118. package/dist/test/functioncallexpressions.test.d.ts +2 -0
  119. package/dist/test/functioncallexpressions.test.d.ts.map +1 -0
  120. package/dist/test/functioncallexpressions.test.js +156 -0
  121. package/dist/test/functiondeclaration.test.d.ts +2 -0
  122. package/dist/test/functiondeclaration.test.d.ts.map +1 -0
  123. package/dist/test/functiondeclaration.test.js +363 -0
  124. package/dist/test/imports.test.d.ts +2 -0
  125. package/dist/test/imports.test.d.ts.map +1 -0
  126. package/dist/test/imports.test.js +262 -0
  127. package/dist/test/memberexpressions.test.d.ts +2 -0
  128. package/dist/test/memberexpressions.test.d.ts.map +1 -0
  129. package/dist/test/memberexpressions.test.js +879 -0
  130. package/dist/test/namepolicies.test.d.ts +2 -0
  131. package/dist/test/namepolicies.test.d.ts.map +1 -0
  132. package/dist/test/namepolicies.test.js +109 -0
  133. package/dist/test/pydocs.test.d.ts +2 -0
  134. package/dist/test/pydocs.test.d.ts.map +1 -0
  135. package/dist/test/pydocs.test.js +500 -0
  136. package/dist/test/references.test.d.ts +2 -0
  137. package/dist/test/references.test.d.ts.map +1 -0
  138. package/dist/test/references.test.js +49 -0
  139. package/dist/test/sourcefiles.test.d.ts +2 -0
  140. package/dist/test/sourcefiles.test.d.ts.map +1 -0
  141. package/dist/test/sourcefiles.test.js +198 -0
  142. package/dist/test/utils.d.ts +23 -0
  143. package/dist/test/utils.d.ts.map +1 -0
  144. package/dist/test/utils.js +88 -0
  145. package/dist/test/values.test.d.ts +2 -0
  146. package/dist/test/values.test.d.ts.map +1 -0
  147. package/dist/test/values.test.js +78 -0
  148. package/dist/test/variables.test.d.ts +2 -0
  149. package/dist/test/variables.test.d.ts.map +1 -0
  150. package/dist/test/variables.test.js +173 -0
  151. package/dist/tsconfig.tsbuildinfo +1 -0
  152. package/package.json +39 -0
  153. package/src/builtins/python.ts +20 -0
  154. package/src/components/Atom.tsx +76 -0
  155. package/src/components/CallSignature.tsx +251 -0
  156. package/src/components/ClassDeclaration.tsx +98 -0
  157. package/src/components/ClassInstantiation.tsx +54 -0
  158. package/src/components/Declaration.tsx +91 -0
  159. package/src/components/EnumDeclaration.tsx +291 -0
  160. package/src/components/EnumMember.tsx +92 -0
  161. package/src/components/FunctionCallExpression.tsx +36 -0
  162. package/src/components/FunctionDeclaration.tsx +121 -0
  163. package/src/components/ImportStatement.tsx +134 -0
  164. package/src/components/MemberExpression.tsx +456 -0
  165. package/src/components/NoNamePolicy.tsx +31 -0
  166. package/src/components/PyDoc.tsx +331 -0
  167. package/src/components/PythonBlock.tsx +26 -0
  168. package/src/components/Reference.tsx +21 -0
  169. package/src/components/SourceFile.tsx +93 -0
  170. package/src/components/StatementList.tsx +28 -0
  171. package/src/components/VariableDeclaration.tsx +180 -0
  172. package/src/components/index.ts +18 -0
  173. package/src/create-module.ts +102 -0
  174. package/src/index.ts +7 -0
  175. package/src/name-policy.ts +101 -0
  176. package/src/parameter-descriptor.ts +36 -0
  177. package/src/symbol-creation.ts +36 -0
  178. package/src/symbols/custom-output-scope.ts +35 -0
  179. package/src/symbols/index.ts +6 -0
  180. package/src/symbols/python-member-scope.ts +12 -0
  181. package/src/symbols/python-module-scope.ts +89 -0
  182. package/src/symbols/python-output-symbol.ts +36 -0
  183. package/src/symbols/reference.ts +99 -0
  184. package/src/symbols/scopes.ts +9 -0
  185. package/src/utils.ts +27 -0
  186. package/temp/api.json +7207 -0
  187. package/test/callsignatures.test.tsx +256 -0
  188. package/test/classdeclarations.test.tsx +320 -0
  189. package/test/classinstantiations.test.tsx +159 -0
  190. package/test/enums.test.tsx +203 -0
  191. package/test/externals.test.tsx +190 -0
  192. package/test/functioncallexpressions.test.tsx +145 -0
  193. package/test/functiondeclaration.test.tsx +327 -0
  194. package/test/imports.test.tsx +214 -0
  195. package/test/memberexpressions.test.tsx +725 -0
  196. package/test/namepolicies.test.tsx +109 -0
  197. package/test/pydocs.test.tsx +528 -0
  198. package/test/references.test.tsx +36 -0
  199. package/test/sourcefiles.test.tsx +131 -0
  200. package/test/utils.tsx +131 -0
  201. package/test/values.test.tsx +61 -0
  202. package/test/variables.test.tsx +153 -0
  203. package/tsconfig.json +12 -0
  204. package/tsdoc-metadata.json +11 -0
  205. package/vitest.config.ts +10 -0
  206. package/vitest.setup.ts +1 -0
@@ -0,0 +1,256 @@
1
+ import { d } from "@alloy-js/core/testing";
2
+ import { describe, expect, it } from "vitest";
3
+ import * as py from "../src/index.js";
4
+ import { toSourceText } from "./utils.jsx";
5
+
6
+ describe("Call Signature Parameters", () => {
7
+ it("renders simple function parameters", () => {
8
+ const result = toSourceText([
9
+ <py.CallSignatureParameters parameters={["a", "b"]} />,
10
+ ]);
11
+ expect(result).toRenderTo(d`
12
+ a, b
13
+ `);
14
+ });
15
+ it("renders ParameterDescriptor parameters", () => {
16
+ const result = toSourceText([
17
+ <py.CallSignatureParameters
18
+ parameters={[{ name: "a" }, { name: "b" }]}
19
+ />,
20
+ ]);
21
+ expect(result).toRenderTo(d`
22
+ a, b
23
+ `);
24
+ });
25
+ it("renders ParameterDescriptor parameters with types", () => {
26
+ const result = toSourceText([
27
+ <py.CallSignatureParameters
28
+ parameters={[
29
+ { name: "a", type: "int" },
30
+ { name: "b", type: "str" },
31
+ ]}
32
+ />,
33
+ ]);
34
+ expect(result).toRenderTo(d`
35
+ a: int, b: str
36
+ `);
37
+ });
38
+ it("renders optional ParameterDescriptor parameters with types", () => {
39
+ const result = toSourceText([
40
+ <py.CallSignatureParameters
41
+ parameters={[
42
+ { name: "a", type: "int", optional: true },
43
+ { name: "b", type: "str", optional: true },
44
+ ]}
45
+ />,
46
+ ]);
47
+ expect(result).toRenderTo(d`
48
+ a: int = None, b: str = None
49
+ `);
50
+ });
51
+ it("renders optional ParameterDescriptor parameters default", () => {
52
+ const result = toSourceText([
53
+ <py.CallSignatureParameters
54
+ parameters={[
55
+ { name: "a", default: 5 },
56
+ { name: "b", default: "hello" },
57
+ ]}
58
+ />,
59
+ ]);
60
+ expect(result).toRenderTo(d`
61
+ a=5, b="hello"
62
+ `);
63
+ });
64
+ it("renders optional ParameterDescriptor parameters with types and default", () => {
65
+ const result = toSourceText([
66
+ <py.CallSignatureParameters
67
+ parameters={[
68
+ { name: "a", type: "int", optional: true, default: 5 },
69
+ { name: "b", type: "str", optional: true, default: "hello" },
70
+ ]}
71
+ />,
72
+ ]);
73
+ expect(result).toRenderTo(d`
74
+ a: int = 5, b: str = "hello"
75
+ `);
76
+ });
77
+ });
78
+
79
+ describe("Call Signature", () => {
80
+ it("renders a simple call signature", () => {
81
+ const result = toSourceText([<py.CallSignature parameters={["a", "b"]} />]);
82
+ expect(result).toRenderTo(d`
83
+ (a, b)
84
+ `);
85
+ });
86
+ it("renders a simple call signature with args and kwargs", () => {
87
+ const result = toSourceText([
88
+ <py.CallSignature parameters={["a", "b"]} args kwargs />,
89
+ ]);
90
+ expect(result).toRenderTo(d`
91
+ (a, b, *args, **kwargs)
92
+ `);
93
+ });
94
+ it("renders a simple call signature with type parameters", () => {
95
+ const result = toSourceText([
96
+ <py.CallSignature parameters={["a", "b"]} typeParameters={["T", "U"]} />,
97
+ ]);
98
+ expect(result).toRenderTo(d`
99
+ [T, U](a, b)
100
+ `);
101
+ });
102
+ it("renders a simple call signature with return type", () => {
103
+ const result = toSourceText([
104
+ <py.CallSignature parameters={["a", "b"]} returnType="int" />,
105
+ ]);
106
+ expect(result).toRenderTo(d`
107
+ (a, b) -> int
108
+ `);
109
+ });
110
+ it("renders a simple call signature for a class function", () => {
111
+ const result = toSourceText([
112
+ <py.CallSignature parameters={["a", "b"]} classFunction />,
113
+ ]);
114
+ expect(result).toRenderTo(d`
115
+ (cls, a, b)
116
+ `);
117
+ });
118
+ it("renders a simple call signature for an instance function", () => {
119
+ const result = toSourceText([
120
+ <py.CallSignature parameters={["a", "b"]} instanceFunction />,
121
+ ]);
122
+ expect(result).toRenderTo(d`
123
+ (self, a, b)
124
+ `);
125
+ });
126
+ it("throws an error for a call signature that's instance and class function at the same time", () => {
127
+ expect(() =>
128
+ toSourceText([
129
+ <py.CallSignature
130
+ parameters={["a", "b"]}
131
+ instanceFunction
132
+ classFunction
133
+ />,
134
+ ]),
135
+ ).toThrowError(/Cannot be both an instance function and a class function/);
136
+ });
137
+ it("renders a simple call signature with all properties", () => {
138
+ const result = toSourceText([
139
+ <py.CallSignature
140
+ parameters={["a", "b"]}
141
+ instanceFunction
142
+ args
143
+ kwargs
144
+ returnType="int"
145
+ />,
146
+ ]);
147
+ expect(result).toRenderTo(d`
148
+ (self, a, b, *args, **kwargs) -> int
149
+ `);
150
+ });
151
+ });
152
+
153
+ describe("Call Signature - Parameter Descriptors", () => {
154
+ it("renders a call signature with parameter descriptors", () => {
155
+ const result = toSourceText([
156
+ <py.CallSignature
157
+ parameters={[
158
+ { name: "a", type: "int" },
159
+ { name: "b", type: "str" },
160
+ ]}
161
+ />,
162
+ ]);
163
+ expect(result).toRenderTo(d`
164
+ (a: int, b: str)
165
+ `);
166
+ });
167
+ it("renders a call signature with parameter descriptors, args and kwargs", () => {
168
+ const result = toSourceText([
169
+ <py.CallSignature
170
+ parameters={[
171
+ { name: "a", type: "int" },
172
+ { name: "b", type: "str" },
173
+ ]}
174
+ args
175
+ kwargs
176
+ />,
177
+ ]);
178
+ expect(result).toRenderTo(d`
179
+ (a: int, b: str, *args, **kwargs)
180
+ `);
181
+ });
182
+ it("renders a call signature with parameter descriptors and return type", () => {
183
+ const result = toSourceText([
184
+ <py.CallSignature
185
+ parameters={[
186
+ { name: "a", type: "int" },
187
+ { name: "b", type: "str" },
188
+ ]}
189
+ returnType="int"
190
+ />,
191
+ ]);
192
+ expect(result).toRenderTo(d`
193
+ (a: int, b: str) -> int
194
+ `);
195
+ });
196
+ it("renders a call signature with parameter descriptors for a class function", () => {
197
+ const result = toSourceText([
198
+ <py.CallSignature
199
+ parameters={[
200
+ { name: "a", type: "int" },
201
+ { name: "b", type: "str" },
202
+ ]}
203
+ classFunction
204
+ />,
205
+ ]);
206
+ expect(result).toRenderTo(d`
207
+ (cls, a: int, b: str)
208
+ `);
209
+ });
210
+ it("renders a call signature with parameter descriptors for an instance function", () => {
211
+ const result = toSourceText([
212
+ <py.CallSignature
213
+ parameters={[
214
+ { name: "a", type: "int" },
215
+ { name: "b", type: "str" },
216
+ ]}
217
+ instanceFunction
218
+ />,
219
+ ]);
220
+ expect(result).toRenderTo(d`
221
+ (self, a: int, b: str)
222
+ `);
223
+ });
224
+ it("renders a call signature with all", () => {
225
+ const result = toSourceText([
226
+ <py.CallSignature
227
+ parameters={[
228
+ { name: "a", type: "int" },
229
+ { name: "b", type: "str" },
230
+ ]}
231
+ instanceFunction
232
+ args
233
+ kwargs
234
+ returnType="int"
235
+ />,
236
+ ]);
237
+ expect(result).toRenderTo(d`
238
+ (self, a: int, b: str, *args, **kwargs) -> int
239
+ `);
240
+ });
241
+ it("renders a more complex call signature with parameter descriptors", () => {
242
+ const result = toSourceText([
243
+ <py.CallSignature
244
+ typeParameters={["T", "U"]}
245
+ parameters={[
246
+ { name: "a", type: "int" },
247
+ { name: "b", type: "str", default: "default_value" },
248
+ ]}
249
+ returnType="int"
250
+ />,
251
+ ]);
252
+ expect(result).toRenderTo(d`
253
+ [T, U](a: int, b: str = "default_value") -> int
254
+ `);
255
+ });
256
+ });
@@ -0,0 +1,320 @@
1
+ import { memberRefkey, refkey } from "@alloy-js/core";
2
+ import { d } from "@alloy-js/core/testing";
3
+ import { describe, expect, it } from "vitest";
4
+ import * as py from "../src/index.js";
5
+ import {
6
+ assertFileContents,
7
+ toSourceText,
8
+ toSourceTextMultiple,
9
+ } from "./utils.jsx";
10
+
11
+ describe("Python Class", () => {
12
+ it("renders a class with no body as 'pass'", () => {
13
+ const result = toSourceText([<py.ClassDeclaration name="Foo" />]);
14
+ expect(result).toRenderTo(d`
15
+ class Foo:
16
+ pass
17
+
18
+
19
+ `);
20
+ });
21
+
22
+ it("renders a class with a body", () => {
23
+ const result = toSourceText([
24
+ <py.ClassDeclaration name="Bar">print('hi')</py.ClassDeclaration>,
25
+ ]);
26
+ expect(result).toRenderTo(d`
27
+ class Bar:
28
+ print('hi')
29
+
30
+
31
+ `);
32
+ });
33
+
34
+ it("renders a class with base classes", () => {
35
+ const result = toSourceText([
36
+ <py.StatementList>
37
+ <py.ClassDeclaration name="Base1" />
38
+ <py.ClassDeclaration name="Base2" />
39
+ <py.ClassDeclaration
40
+ name="Baz"
41
+ bases={[refkey("Base1"), refkey("Base2")]}
42
+ />
43
+ </py.StatementList>,
44
+ ]);
45
+ const expected = d`
46
+ class Base1:
47
+ pass
48
+
49
+ class Base2:
50
+ pass
51
+
52
+ class Baz(Base1, Base2):
53
+ pass
54
+
55
+
56
+ `;
57
+ expect(result).toRenderTo(expected);
58
+ });
59
+
60
+ it("renders a class with base classes and body", () => {
61
+ const result = toSourceText([
62
+ <py.ClassDeclaration name="Qux" bases={["Base"]}>
63
+ print('hello')
64
+ </py.ClassDeclaration>,
65
+ ]);
66
+ expect(result).toRenderTo(d`
67
+ class Qux(Base):
68
+ print('hello')
69
+
70
+
71
+ `);
72
+ });
73
+
74
+ it("renders classes across modules with inheritance", () => {
75
+ const result = toSourceTextMultiple([
76
+ <py.SourceFile path="mod1.py">
77
+ <py.ClassDeclaration name="A" />
78
+ </py.SourceFile>,
79
+ <py.SourceFile path="folder/mod2.py">
80
+ <py.ClassDeclaration name="B" bases={[refkey("A")]} />
81
+ </py.SourceFile>,
82
+ <py.SourceFile path="mod3.py">
83
+ <py.ClassDeclaration name="C" bases={[refkey("B")]} />
84
+ </py.SourceFile>,
85
+ ]);
86
+ const mod1Expected = d`
87
+ class A:
88
+ pass
89
+
90
+
91
+ `;
92
+ const mod2Expected = d`
93
+ from mod1 import A
94
+
95
+ class B(A):
96
+ pass
97
+
98
+
99
+ `;
100
+ const mod3Expected = d`
101
+ from folder.mod2 import B
102
+
103
+ class C(B):
104
+ pass
105
+
106
+
107
+ `;
108
+ assertFileContents(result, { "mod1.py": mod1Expected });
109
+ assertFileContents(result, { "folder/mod2.py": mod2Expected });
110
+ assertFileContents(result, { "mod3.py": mod3Expected });
111
+ });
112
+
113
+ it("renders a class with class variables like foo: str, and also bar: A where A is another class", () => {
114
+ const result = toSourceText([
115
+ <py.StatementList>
116
+ <py.ClassDeclaration name="A" />
117
+ <py.ClassDeclaration name="B">
118
+ <py.StatementList>
119
+ <py.VariableDeclaration name="bar" type={refkey("A")} omitNone />
120
+ <py.VariableDeclaration name="foo" type="str" omitNone />
121
+ </py.StatementList>
122
+ </py.ClassDeclaration>
123
+ </py.StatementList>,
124
+ ]);
125
+ const expected = d`
126
+ class A:
127
+ pass
128
+
129
+ class B:
130
+ bar: A
131
+ foo: str
132
+
133
+
134
+ `;
135
+ expect(result).toRenderTo(expected);
136
+ });
137
+
138
+ it("renders a class with class variables like foo: str, and another identical class", () => {
139
+ const result = toSourceText([
140
+ <py.StatementList>
141
+ <py.ClassDeclaration name="A">
142
+ <py.StatementList>
143
+ <py.VariableDeclaration name="foo" type="str" omitNone />
144
+ </py.StatementList>
145
+ </py.ClassDeclaration>
146
+ <py.ClassDeclaration name="B">
147
+ <py.StatementList>
148
+ <py.VariableDeclaration name="foo" type="str" omitNone />
149
+ </py.StatementList>
150
+ </py.ClassDeclaration>
151
+ </py.StatementList>,
152
+ ]);
153
+ const expected = d`
154
+ class A:
155
+ foo: str
156
+
157
+ class B:
158
+ foo: str
159
+
160
+
161
+ `;
162
+ expect(result).toRenderTo(expected);
163
+ });
164
+ });
165
+
166
+ describe("Python Class - VariableDeclaration", () => {
167
+ it("renders a class with class fields", () => {
168
+ const result = toSourceText([
169
+ <py.StatementList>
170
+ <py.ClassDeclaration name="Base"></py.ClassDeclaration>
171
+ <py.ClassDeclaration name="A">
172
+ <py.StatementList>
173
+ <py.VariableDeclaration name="just_name" />
174
+ <py.VariableDeclaration name="name_and_type" type="number" />
175
+ <py.VariableDeclaration
176
+ name="name_type_and_value"
177
+ type="number"
178
+ initializer={12}
179
+ />
180
+ <py.VariableDeclaration name="class_based" type={refkey("Base")} />
181
+ </py.StatementList>
182
+ </py.ClassDeclaration>
183
+ </py.StatementList>,
184
+ ]);
185
+ const expected = d`
186
+ class Base:
187
+ pass
188
+
189
+ class A:
190
+ just_name = None
191
+ name_and_type: number = None
192
+ name_type_and_value: number = 12
193
+ class_based: Base = None
194
+
195
+
196
+ `;
197
+ expect(result).toRenderTo(expected);
198
+ });
199
+
200
+ it("correctly access members of its type", () => {
201
+ const classRk = refkey();
202
+ const classMemberRk = refkey();
203
+ const classMethodRk = refkey();
204
+ const v1Rk = refkey();
205
+
206
+ const res = toSourceTextMultiple([
207
+ <py.SourceFile path="inst.py">
208
+ <py.StatementList>
209
+ <py.VariableDeclaration
210
+ name="one"
211
+ refkey={v1Rk}
212
+ type={classRk}
213
+ initializer={
214
+ <py.MemberExpression>
215
+ <py.MemberExpression.Part refkey={classRk} />
216
+ <py.MemberExpression.Part args />
217
+ </py.MemberExpression>
218
+ }
219
+ />
220
+ <>{memberRefkey(v1Rk, classMemberRk)}</>
221
+ <>{memberRefkey(v1Rk, classMethodRk)}()</>
222
+ </py.StatementList>
223
+ </py.SourceFile>,
224
+ <py.SourceFile path="decl.py">
225
+ <py.ClassDeclaration name="Bar" refkey={classRk}>
226
+ <py.StatementList>
227
+ <py.VariableDeclaration
228
+ name="instanceProp"
229
+ refkey={classMemberRk}
230
+ initializer={42}
231
+ instanceVariable={true}
232
+ />
233
+ <py.FunctionDeclaration
234
+ name="instanceMethod"
235
+ instanceFunction={true}
236
+ refkey={classMethodRk}
237
+ returnType="int"
238
+ />
239
+ </py.StatementList>
240
+ </py.ClassDeclaration>
241
+ </py.SourceFile>,
242
+ ]);
243
+
244
+ assertFileContents(res, {
245
+ "inst.py": `
246
+ from decl import Bar
247
+
248
+ one: Bar = Bar()
249
+ one.instance_prop
250
+ one.instance_method()
251
+ `,
252
+ "decl.py": `
253
+ class Bar:
254
+ instance_prop = 42
255
+ def instance_method(self) -> int:
256
+ pass
257
+
258
+
259
+ `,
260
+ });
261
+ });
262
+ });
263
+
264
+ describe("Python Class - FunctionDeclaration", () => {
265
+ it("renders a class with class fields and method", () => {
266
+ const result = toSourceText([
267
+ <>
268
+ <py.ClassDeclaration name="MyClass" bases={["BaseClass"]}>
269
+ <py.StatementList>
270
+ <py.VariableDeclaration name="a" type="int" />
271
+ <py.VariableDeclaration name="b" type="int" />
272
+ <py.FunctionDeclaration
273
+ name="my_method"
274
+ parameters={[
275
+ { name: "a", type: "int" },
276
+ { name: "b", type: "int" },
277
+ ]}
278
+ returnType="int"
279
+ instanceFunction={true}
280
+ >
281
+ return a + b
282
+ </py.FunctionDeclaration>
283
+ <py.FunctionDeclaration
284
+ name="my_class_method"
285
+ instanceFunction={false}
286
+ classFunction={true}
287
+ returnType="int"
288
+ >
289
+ pass
290
+ </py.FunctionDeclaration>
291
+ <py.FunctionDeclaration
292
+ name="my_standalone_function"
293
+ instanceFunction={false}
294
+ returnType="int"
295
+ >
296
+ pass
297
+ </py.FunctionDeclaration>
298
+ </py.StatementList>
299
+ </py.ClassDeclaration>
300
+ </>,
301
+ ]);
302
+ const expected = d`
303
+ class MyClass(BaseClass):
304
+ a: int = None
305
+ b: int = None
306
+ def my_method(self, a: int, b: int) -> int:
307
+ return a + b
308
+
309
+ def my_class_method(cls) -> int:
310
+ pass
311
+
312
+ def my_standalone_function() -> int:
313
+ pass
314
+
315
+
316
+
317
+ `;
318
+ expect(result).toRenderTo(expected);
319
+ });
320
+ });