@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,327 @@
1
+ import { 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.js";
10
+
11
+ describe("Function Declaration", () => {
12
+ it("renders a function with no body as 'pass'", () => {
13
+ const result = toSourceText([
14
+ <py.FunctionDeclaration name="foo" instanceFunction={true} />,
15
+ ]);
16
+ expect(result).toRenderTo(d`
17
+ def foo(self):
18
+ pass
19
+
20
+
21
+ `);
22
+ });
23
+
24
+ it("renders a function with no body as 'pass' with return type", () => {
25
+ const result = toSourceText([
26
+ <py.FunctionDeclaration name="foo" returnType="int" />,
27
+ ]);
28
+ expect(result).toRenderTo(d`
29
+ def foo() -> int:
30
+ pass
31
+
32
+
33
+ `);
34
+ });
35
+
36
+ it("renders a function that calls another function", () => {
37
+ const refkeyFoo = refkey();
38
+ const result = toSourceText([
39
+ <py.StatementList>
40
+ <py.FunctionDeclaration
41
+ name="foo"
42
+ instanceFunction={true}
43
+ returnType="int"
44
+ refkey={refkeyFoo}
45
+ />
46
+ <py.FunctionDeclaration
47
+ name="bar"
48
+ instanceFunction={true}
49
+ returnType="int"
50
+ >
51
+ <py.VariableDeclaration
52
+ name="result"
53
+ type="int"
54
+ initializer={
55
+ <py.FunctionCallExpression target={refkeyFoo} args={[]} />
56
+ }
57
+ />
58
+ </py.FunctionDeclaration>
59
+ </py.StatementList>,
60
+ ]);
61
+ expect(result).toRenderTo(d`
62
+ def foo(self) -> int:
63
+ pass
64
+
65
+ def bar(self) -> int:
66
+ result: int = foo()
67
+
68
+
69
+ `);
70
+ });
71
+
72
+ it("renders an instance function with a body", () => {
73
+ const result = toSourceText([
74
+ <py.FunctionDeclaration name="bar" instanceFunction={true}>
75
+ print('hi')
76
+ </py.FunctionDeclaration>,
77
+ ]);
78
+ expect(result).toRenderTo(d`
79
+ def bar(self):
80
+ print('hi')
81
+
82
+
83
+ `);
84
+ });
85
+
86
+ it("renders a function with parameters", () => {
87
+ const result = toSourceText([
88
+ <py.FunctionDeclaration
89
+ name="baz"
90
+ parameters={[
91
+ { name: "x", type: "int" },
92
+ { name: "y", default: 0 },
93
+ { name: "z", type: "int", default: 42 },
94
+ ]}
95
+ args={true}
96
+ kwargs={true}
97
+ >
98
+ print(x, y)
99
+ </py.FunctionDeclaration>,
100
+ ]);
101
+ expect(result).toRenderTo(
102
+ d`
103
+ def baz(x: int, y=0, z: int = 42, *args, **kwargs):
104
+ print(x, y)
105
+
106
+
107
+ `,
108
+ );
109
+ });
110
+
111
+ it("renders an __init__ function with no body as 'pass'", () => {
112
+ const result = toSourceText([
113
+ <py.InitFunctionDeclaration parameters={[{ name: "x" }]} />,
114
+ ]);
115
+ expect(result).toRenderTo(d`
116
+ def __init__(self, x):
117
+ pass
118
+
119
+
120
+ `);
121
+ });
122
+
123
+ it("can be an async function", () => {
124
+ expect(toSourceText([<py.FunctionDeclaration async name="foo" />])).toBe(d`
125
+ async def foo():
126
+ pass
127
+
128
+ `);
129
+ });
130
+
131
+ it("can be an async function with returnType", () => {
132
+ expect(
133
+ toSourceText([
134
+ <py.FunctionDeclaration async name="foo" returnType="Foo" />,
135
+ ]),
136
+ ).toBe(d`
137
+ async def foo() -> Foo:
138
+ pass
139
+
140
+ `);
141
+ });
142
+
143
+ it("can be an async function with returnType element with Reference", () => {
144
+ expect(
145
+ toSourceText([
146
+ <py.StatementList>
147
+ <py.ClassDeclaration name="Foo" />
148
+ <py.FunctionDeclaration
149
+ async
150
+ name="foo"
151
+ returnType={<py.Reference refkey={refkey("Foo")} />}
152
+ />
153
+ </py.StatementList>,
154
+ ]),
155
+ ).toBe(d`
156
+ class Foo:
157
+ pass
158
+
159
+ async def foo() -> Foo:
160
+ pass
161
+
162
+ `);
163
+ });
164
+
165
+ it("supports parameters", () => {
166
+ const decl = (
167
+ <py.FunctionDeclaration name="foo" parameters={["a", "b"]}>
168
+ return a + b
169
+ </py.FunctionDeclaration>
170
+ );
171
+
172
+ expect(toSourceText([decl])).toBe(d`
173
+ def foo(a, b):
174
+ return a + b
175
+
176
+ `);
177
+ });
178
+ it("supports type parameters", () => {
179
+ const decl = (
180
+ <py.FunctionDeclaration
181
+ name="foo"
182
+ parameters={["a", "b"]}
183
+ typeParameters={["T", "U"]}
184
+ >
185
+ return a + b
186
+ </py.FunctionDeclaration>
187
+ );
188
+
189
+ expect(toSourceText([decl])).toBe(d`
190
+ def foo[T, U](a, b):
191
+ return a + b
192
+
193
+ `);
194
+ });
195
+ it("renders function with parameters", () => {
196
+ const parameters = [{ name: "x", type: "int" }];
197
+ const decl = (
198
+ <py.FunctionDeclaration
199
+ name="foo"
200
+ instanceFunction={true}
201
+ parameters={parameters}
202
+ >
203
+ self.attribute = "value"
204
+ </py.FunctionDeclaration>
205
+ );
206
+
207
+ expect(toSourceText([decl])).toBe(d`
208
+ def foo(self, x: int):
209
+ self.attribute = "value"
210
+
211
+ `);
212
+ });
213
+ it("renders __init__ function with parameters", () => {
214
+ const parameters = [{ name: "x", type: "int" }];
215
+ const decl = (
216
+ <py.InitFunctionDeclaration parameters={parameters}>
217
+ self.attribute = "value"
218
+ </py.InitFunctionDeclaration>
219
+ );
220
+
221
+ expect(toSourceText([decl])).toBe(d`
222
+ def __init__(self, x: int):
223
+ self.attribute = "value"
224
+
225
+ `);
226
+ });
227
+
228
+ it("renders nested functions", () => {
229
+ const parameters = [{ name: "x", type: "int" }];
230
+ const parameters_nested = [{ name: "y", type: "int" }];
231
+ const parameters_nested_nested = [{ name: "z", type: "int" }];
232
+ const fooRef = refkey();
233
+ const barRef = refkey();
234
+ const foobarRef = refkey();
235
+ const decl = (
236
+ <py.FunctionDeclaration
237
+ name="foo"
238
+ parameters={parameters}
239
+ refkey={fooRef}
240
+ >
241
+ <py.FunctionDeclaration
242
+ name="bar"
243
+ parameters={parameters_nested}
244
+ refkey={barRef}
245
+ >
246
+ <py.FunctionDeclaration
247
+ name="foobar"
248
+ parameters={parameters_nested_nested}
249
+ refkey={foobarRef}
250
+ >
251
+ return z * 2
252
+ </py.FunctionDeclaration>
253
+ return{" "}
254
+ <py.FunctionCallExpression
255
+ target={foobarRef}
256
+ args={[<py.Atom jsValue={2} />]}
257
+ />
258
+ </py.FunctionDeclaration>
259
+ return{" "}
260
+ <py.FunctionCallExpression
261
+ target={barRef}
262
+ args={[<py.Atom jsValue={3} />]}
263
+ />
264
+ </py.FunctionDeclaration>
265
+ );
266
+
267
+ expect(toSourceText([decl])).toBe(d`
268
+ def foo(x: int):
269
+ def bar(y: int):
270
+ def foobar(z: int):
271
+ return z * 2
272
+ return foobar(2)
273
+ return bar(3)
274
+
275
+ `);
276
+ });
277
+ it("renders complex typing structure", () => {
278
+ const res = toSourceTextMultiple([
279
+ <py.SourceFile path="mod1.py">
280
+ <py.ClassDeclaration name="Foo" />
281
+ </py.SourceFile>,
282
+ <py.SourceFile path="mod2.py">
283
+ <py.ClassDeclaration name="A" />
284
+ <py.ClassDeclaration name="B" />
285
+ </py.SourceFile>,
286
+ <py.SourceFile path="usage.py">
287
+ <py.FunctionDeclaration
288
+ async
289
+ name="foo"
290
+ parameters={[
291
+ { name: "x", type: <py.Reference refkey={refkey("A")} /> },
292
+ { name: "y", type: <py.Reference refkey={refkey("B")} /> },
293
+ ]}
294
+ args={true}
295
+ kwargs={true}
296
+ returnType={<py.Reference refkey={refkey("Foo")} />}
297
+ />
298
+ </py.SourceFile>,
299
+ ]);
300
+
301
+ assertFileContents(res, {
302
+ "mod1.py": `
303
+ class Foo:
304
+ pass
305
+
306
+ `,
307
+ "mod2.py": `
308
+ class A:
309
+ pass
310
+
311
+
312
+ class B:
313
+ pass
314
+
315
+ `,
316
+ "usage.py": `
317
+ from mod1 import Foo
318
+ from mod2 import A
319
+ from mod2 import B
320
+
321
+ async def foo(x: A, y: B, *args, **kwargs) -> Foo:
322
+ pass
323
+
324
+ `,
325
+ });
326
+ });
327
+ });
@@ -0,0 +1,214 @@
1
+ import { refkey } from "@alloy-js/core";
2
+ import { describe, expect, it } from "vitest";
3
+ import { ImportStatement } from "../src/components/ImportStatement.jsx";
4
+ import * as py from "../src/index.js";
5
+ import { createPythonSymbol } from "../src/symbol-creation.js";
6
+ import { ImportedSymbol, ImportRecords } from "../src/symbols/index.js";
7
+ import {
8
+ assertFileContents,
9
+ createPythonModuleScope,
10
+ toSourceText,
11
+ toSourceTextMultiple,
12
+ } from "./utils.jsx";
13
+
14
+ describe("ImportStatement", () => {
15
+ it("renders module import", () => {
16
+ const result = toSourceText([<ImportStatement path="sys" />]);
17
+ const expected = `import sys`;
18
+ expect(result).toRenderTo(expected);
19
+ });
20
+
21
+ it("renders named imports", () => {
22
+ const sqrtSymbol = createPythonSymbol("sqrt", {
23
+ binder: undefined,
24
+ scope: undefined,
25
+ });
26
+ const piSymbol = createPythonSymbol("pi", {
27
+ binder: undefined,
28
+ scope: undefined,
29
+ });
30
+ const symbols = new Set<ImportedSymbol>([
31
+ new ImportedSymbol(sqrtSymbol, sqrtSymbol),
32
+ new ImportedSymbol(piSymbol, piSymbol),
33
+ ]);
34
+ const result = toSourceText([
35
+ <ImportStatement path="math" symbols={symbols} />,
36
+ ]);
37
+ const expected = `from math import pi, sqrt`;
38
+ expect(result).toRenderTo(expected);
39
+ });
40
+ });
41
+
42
+ describe("ImportStatements", () => {
43
+ it("renders multiple import statements", () => {
44
+ const pythonModuleScope = createPythonModuleScope("math", undefined);
45
+ const sqrtSymbol = createPythonSymbol("sqrt", {
46
+ binder: undefined,
47
+ scope: undefined,
48
+ });
49
+ const piSymbol = createPythonSymbol("pi", {
50
+ binder: undefined,
51
+ scope: undefined,
52
+ });
53
+ const mathSymbols = new Set<ImportedSymbol>([
54
+ new ImportedSymbol(sqrtSymbol, sqrtSymbol),
55
+ new ImportedSymbol(piSymbol, piSymbol),
56
+ ]);
57
+ const sysModuleScope = createPythonModuleScope("sys", undefined);
58
+ const requestsScope = createPythonModuleScope("requests", undefined);
59
+ const getSymbol = createPythonSymbol("get", {
60
+ binder: undefined,
61
+ scope: undefined,
62
+ });
63
+ const requestsSymbols = new Set<ImportedSymbol>([
64
+ new ImportedSymbol(getSymbol, getSymbol),
65
+ ]);
66
+ const records = new ImportRecords([
67
+ [pythonModuleScope, { symbols: mathSymbols }],
68
+ [requestsScope, { symbols: requestsSymbols }],
69
+ [sysModuleScope, { symbols: new Set<ImportedSymbol>() }],
70
+ ]);
71
+
72
+ const result = toSourceText([<py.ImportStatements records={records} />]);
73
+ const expected = `
74
+ from math import pi
75
+ from math import sqrt
76
+ from requests import get
77
+ import sys`;
78
+ expect(result).toRenderTo(expected);
79
+ });
80
+ it("renders multiple import statements, but joining imports from the same module", () => {
81
+ const pythonModuleScope = createPythonModuleScope("math", undefined);
82
+ const sqrtSymbol = createPythonSymbol("sqrt", {
83
+ binder: undefined,
84
+ scope: undefined,
85
+ });
86
+ const piSymbol = createPythonSymbol("pi", {
87
+ binder: undefined,
88
+ scope: undefined,
89
+ });
90
+ const mathSymbols = new Set<ImportedSymbol>([
91
+ new ImportedSymbol(sqrtSymbol, sqrtSymbol),
92
+ new ImportedSymbol(piSymbol, piSymbol),
93
+ ]);
94
+ const requestsScope = createPythonModuleScope("requests", undefined);
95
+ const getSymbol = createPythonSymbol("get", {
96
+ binder: undefined,
97
+ scope: undefined,
98
+ });
99
+ const postSymbol = createPythonSymbol("post", {
100
+ binder: undefined,
101
+ scope: undefined,
102
+ });
103
+ const requestsSymbols = new Set<ImportedSymbol>([
104
+ new ImportedSymbol(getSymbol, getSymbol),
105
+ new ImportedSymbol(postSymbol, postSymbol),
106
+ ]);
107
+ const records = new ImportRecords([
108
+ [pythonModuleScope, { symbols: mathSymbols }],
109
+ [requestsScope, { symbols: requestsSymbols }],
110
+ ]);
111
+
112
+ const result = toSourceText([
113
+ <py.ImportStatements
114
+ records={records}
115
+ joinImportsFromSameModule={true}
116
+ />,
117
+ ]);
118
+ const expected = `
119
+ from math import pi, sqrt
120
+ from requests import get, post`;
121
+ expect(result).toRenderTo(expected);
122
+ });
123
+ });
124
+
125
+ describe("Imports being used", () => {
126
+ it("works with importing the same name many times from different files with the default name conflict resolver", () => {
127
+ const rk1 = refkey();
128
+ const rk2 = refkey();
129
+ const rk3 = refkey();
130
+ const result = toSourceTextMultiple([
131
+ <py.SourceFile path="test_1.py">
132
+ <py.VariableDeclaration name="conflict" refkey={rk1} />
133
+ </py.SourceFile>,
134
+ <py.SourceFile path="test_3.py">
135
+ <py.VariableDeclaration name="conflict" refkey={rk3} />
136
+ </py.SourceFile>,
137
+ <py.SourceFile path="test_2.py">
138
+ <py.VariableDeclaration name="conflict" refkey={rk2} />
139
+ </py.SourceFile>,
140
+ <py.SourceFile path="test.py">
141
+ <py.StatementList>
142
+ <py.VariableDeclaration name="one" initializer={rk1} />
143
+ <py.VariableDeclaration name="three" initializer={rk3} />
144
+ <py.VariableDeclaration name="two" initializer={rk2} />
145
+ </py.StatementList>
146
+ </py.SourceFile>,
147
+ ]);
148
+ assertFileContents(result, {
149
+ "test.py": `
150
+ from test_1 import conflict
151
+ from test_2 import conflict as conflict_3_test_2
152
+ from test_3 import conflict as conflict_2_test_3
153
+
154
+ one = conflict
155
+ three = conflict_2_test_3
156
+ two = conflict_3_test_2
157
+ `,
158
+ });
159
+ });
160
+ it("works with importing the same name many times from different files and with the correct order", () => {
161
+ const rk1 = refkey();
162
+ const rk2 = refkey();
163
+ const rk3 = refkey();
164
+ const rk4 = refkey();
165
+ const rk5 = refkey();
166
+ const rk6 = refkey();
167
+ const rk7 = refkey();
168
+ const result = toSourceTextMultiple([
169
+ <py.SourceFile path="test_1.py">
170
+ <py.VariableDeclaration name="conflict" refkey={rk1} />
171
+ <py.VariableDeclaration name="something_else" refkey={rk4} />
172
+ </py.SourceFile>,
173
+ <py.SourceFile path="test_2.py">
174
+ <py.VariableDeclaration name="conflict" refkey={rk2} />
175
+ <py.VariableDeclaration name="something" refkey={rk6} />
176
+ <py.VariableDeclaration name="something_else" refkey={rk5} />
177
+ </py.SourceFile>,
178
+ <py.SourceFile path="test_3.py">
179
+ <py.VariableDeclaration name="conflict" refkey={rk3} />
180
+ <py.VariableDeclaration name="something" refkey={rk7} />
181
+ </py.SourceFile>,
182
+ <py.SourceFile path="test.py">
183
+ <py.StatementList>
184
+ <py.VariableDeclaration name="one" initializer={rk1} />
185
+ <py.VariableDeclaration name="two" initializer={rk2} />
186
+ <py.VariableDeclaration name="three" initializer={rk3} />
187
+ <py.VariableDeclaration name="something_else" initializer={rk4} />
188
+ <py.VariableDeclaration name="something_else_two" initializer={rk5} />
189
+ <py.VariableDeclaration name="something" initializer={rk6} />
190
+ <py.VariableDeclaration name="something_two" initializer={rk7} />
191
+ </py.StatementList>
192
+ </py.SourceFile>,
193
+ ]);
194
+ assertFileContents(result, {
195
+ "test.py": `
196
+ from test_1 import conflict
197
+ from test_1 import something_else as something_else_2_test_1
198
+ from test_2 import conflict as conflict_2_test_2
199
+ from test_2 import something as something_2_test_2
200
+ from test_2 import something_else as something_else_3_test_2
201
+ from test_3 import conflict as conflict_3_test_3
202
+ from test_3 import something as something_3_test_3
203
+
204
+ one = conflict
205
+ two = conflict_2_test_2
206
+ three = conflict_3_test_3
207
+ something_else = something_else_2_test_1
208
+ something_else_two = something_else_3_test_2
209
+ something = something_2_test_2
210
+ something_two = something_3_test_3
211
+ `,
212
+ });
213
+ });
214
+ });