@alloy-js/python 0.2.0-dev.2 → 0.2.0-dev.4

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 (209) hide show
  1. package/dist/src/builtins/python.d.ts +3 -0
  2. package/dist/src/builtins/python.d.ts.map +1 -1
  3. package/dist/src/builtins/python.js +6 -0
  4. package/dist/src/builtins/python.js.map +1 -1
  5. package/dist/src/components/CallSignature.d.ts +4 -15
  6. package/dist/src/components/CallSignature.d.ts.map +1 -1
  7. package/dist/src/components/CallSignature.js +13 -67
  8. package/dist/src/components/CallSignature.js.map +1 -1
  9. package/dist/src/components/ClassMethodDeclaration.d.ts +22 -0
  10. package/dist/src/components/ClassMethodDeclaration.d.ts.map +1 -0
  11. package/dist/src/components/ClassMethodDeclaration.js +32 -0
  12. package/dist/src/components/ClassMethodDeclaration.js.map +1 -0
  13. package/dist/src/components/ConstructorDeclaration.d.ts +21 -0
  14. package/dist/src/components/ConstructorDeclaration.d.ts.map +1 -0
  15. package/dist/src/components/ConstructorDeclaration.js +35 -0
  16. package/dist/src/components/ConstructorDeclaration.js.map +1 -0
  17. package/dist/src/components/DunderMethodDeclaration.d.ts +21 -0
  18. package/dist/src/components/DunderMethodDeclaration.d.ts.map +1 -0
  19. package/dist/src/components/DunderMethodDeclaration.js +29 -0
  20. package/dist/src/components/DunderMethodDeclaration.js.map +1 -0
  21. package/dist/src/components/EnumDeclaration.d.ts +11 -32
  22. package/dist/src/components/EnumDeclaration.d.ts.map +1 -1
  23. package/dist/src/components/EnumDeclaration.js +10 -48
  24. package/dist/src/components/EnumDeclaration.js.map +1 -1
  25. package/dist/src/components/EnumMember.js +3 -3
  26. package/dist/src/components/EnumMember.js.map +1 -1
  27. package/dist/src/components/FunctionBase.d.ts +48 -0
  28. package/dist/src/components/FunctionBase.d.ts.map +1 -0
  29. package/dist/src/components/FunctionBase.js +91 -0
  30. package/dist/src/components/FunctionBase.js.map +1 -0
  31. package/dist/src/components/FunctionDeclaration.d.ts +11 -31
  32. package/dist/src/components/FunctionDeclaration.d.ts.map +1 -1
  33. package/dist/src/components/FunctionDeclaration.js +22 -79
  34. package/dist/src/components/FunctionDeclaration.js.map +1 -1
  35. package/dist/src/components/MemberExpression.d.ts.map +1 -1
  36. package/dist/src/components/MemberExpression.js +12 -13
  37. package/dist/src/components/MemberExpression.js.map +1 -1
  38. package/dist/src/components/MethodBase.d.ts +29 -0
  39. package/dist/src/components/MethodBase.d.ts.map +1 -0
  40. package/dist/src/components/MethodBase.js +32 -0
  41. package/dist/src/components/MethodBase.js.map +1 -0
  42. package/dist/src/components/MethodDeclaration.d.ts +22 -0
  43. package/dist/src/components/MethodDeclaration.d.ts.map +1 -0
  44. package/dist/src/components/MethodDeclaration.js +34 -0
  45. package/dist/src/components/MethodDeclaration.js.map +1 -0
  46. package/dist/src/components/PropertyDeclaration.d.ts +71 -0
  47. package/dist/src/components/PropertyDeclaration.d.ts.map +1 -0
  48. package/dist/src/components/PropertyDeclaration.js +227 -0
  49. package/dist/src/components/PropertyDeclaration.js.map +1 -0
  50. package/dist/src/components/PyDoc.d.ts +107 -42
  51. package/dist/src/components/PyDoc.d.ts.map +1 -1
  52. package/dist/src/components/PyDoc.js +845 -181
  53. package/dist/src/components/PyDoc.js.map +1 -1
  54. package/dist/src/components/SourceFile.d.ts +24 -0
  55. package/dist/src/components/SourceFile.d.ts.map +1 -1
  56. package/dist/src/components/SourceFile.js +28 -1
  57. package/dist/src/components/SourceFile.js.map +1 -1
  58. package/dist/src/components/StaticMethodDeclaration.d.ts +22 -0
  59. package/dist/src/components/StaticMethodDeclaration.d.ts.map +1 -0
  60. package/dist/src/components/StaticMethodDeclaration.js +32 -0
  61. package/dist/src/components/StaticMethodDeclaration.js.map +1 -0
  62. package/dist/src/components/TypeArguments.d.ts +9 -0
  63. package/dist/src/components/TypeArguments.d.ts.map +1 -0
  64. package/dist/src/components/TypeArguments.js +18 -0
  65. package/dist/src/components/TypeArguments.js.map +1 -0
  66. package/dist/src/components/TypeReference.d.ts +14 -0
  67. package/dist/src/components/TypeReference.d.ts.map +1 -0
  68. package/dist/src/components/TypeReference.js +29 -0
  69. package/dist/src/components/TypeReference.js.map +1 -0
  70. package/dist/src/components/UnionTypeExpression.d.ts +1 -2
  71. package/dist/src/components/UnionTypeExpression.d.ts.map +1 -1
  72. package/dist/src/components/UnionTypeExpression.js +3 -11
  73. package/dist/src/components/UnionTypeExpression.js.map +1 -1
  74. package/dist/src/components/VariableDeclaration.d.ts.map +1 -1
  75. package/dist/src/components/VariableDeclaration.js +3 -3
  76. package/dist/src/components/VariableDeclaration.js.map +1 -1
  77. package/dist/src/components/index.d.ts +10 -0
  78. package/dist/src/components/index.d.ts.map +1 -1
  79. package/dist/src/components/index.js +9 -0
  80. package/dist/src/components/index.js.map +1 -1
  81. package/dist/src/parameter-descriptor.d.ts +1 -4
  82. package/dist/src/parameter-descriptor.d.ts.map +1 -1
  83. package/dist/src/parameter-descriptor.js +7 -1
  84. package/dist/src/parameter-descriptor.js.map +1 -1
  85. package/dist/src/symbol-creation.d.ts +4 -0
  86. package/dist/src/symbol-creation.d.ts.map +1 -1
  87. package/dist/src/symbol-creation.js +12 -0
  88. package/dist/src/symbol-creation.js.map +1 -1
  89. package/dist/src/symbols/factories.d.ts +15 -0
  90. package/dist/src/symbols/factories.d.ts.map +1 -0
  91. package/dist/src/symbols/factories.js +28 -0
  92. package/dist/src/symbols/factories.js.map +1 -0
  93. package/dist/src/symbols/index.d.ts +1 -0
  94. package/dist/src/symbols/index.d.ts.map +1 -1
  95. package/dist/src/symbols/index.js +1 -0
  96. package/dist/src/symbols/index.js.map +1 -1
  97. package/dist/src/symbols/reference.d.ts +1 -1
  98. package/dist/src/symbols/reference.d.ts.map +1 -1
  99. package/dist/src/symbols/reference.js +1 -1
  100. package/dist/src/symbols/reference.js.map +1 -1
  101. package/dist/src/utils.d.ts.map +1 -1
  102. package/dist/src/utils.js +1 -1
  103. package/dist/src/utils.js.map +1 -1
  104. package/dist/test/callsignatures.test.js +42 -64
  105. package/dist/test/callsignatures.test.js.map +1 -1
  106. package/dist/test/class-method-declaration.test.d.ts +2 -0
  107. package/dist/test/class-method-declaration.test.d.ts.map +1 -0
  108. package/dist/test/class-method-declaration.test.js +61 -0
  109. package/dist/test/class-method-declaration.test.js.map +1 -0
  110. package/dist/test/classdeclarations.test.js +6 -8
  111. package/dist/test/classdeclarations.test.js.map +1 -1
  112. package/dist/test/constructordeclaration.test.d.ts +2 -0
  113. package/dist/test/constructordeclaration.test.d.ts.map +1 -0
  114. package/dist/test/constructordeclaration.test.js +58 -0
  115. package/dist/test/constructordeclaration.test.js.map +1 -0
  116. package/dist/test/dundermethoddeclaration.test.d.ts +2 -0
  117. package/dist/test/dundermethoddeclaration.test.d.ts.map +1 -0
  118. package/dist/test/dundermethoddeclaration.test.js +65 -0
  119. package/dist/test/dundermethoddeclaration.test.js.map +1 -0
  120. package/dist/test/enums.test.js +14 -16
  121. package/dist/test/enums.test.js.map +1 -1
  122. package/dist/test/externals.test.js +2 -4
  123. package/dist/test/externals.test.js.map +1 -1
  124. package/dist/test/factories.test.d.ts +2 -0
  125. package/dist/test/factories.test.d.ts.map +1 -0
  126. package/dist/test/factories.test.js +78 -0
  127. package/dist/test/factories.test.js.map +1 -0
  128. package/dist/test/functiondeclaration.test.js +213 -59
  129. package/dist/test/functiondeclaration.test.js.map +1 -1
  130. package/dist/test/memberexpressions.test.js +1 -1
  131. package/dist/test/memberexpressions.test.js.map +1 -1
  132. package/dist/test/methoddeclaration.test.d.ts +2 -0
  133. package/dist/test/methoddeclaration.test.d.ts.map +1 -0
  134. package/dist/test/methoddeclaration.test.js +239 -0
  135. package/dist/test/methoddeclaration.test.js.map +1 -0
  136. package/dist/test/namepolicies.test.js +1 -2
  137. package/dist/test/namepolicies.test.js.map +1 -1
  138. package/dist/test/propertydeclaration.test.d.ts +2 -0
  139. package/dist/test/propertydeclaration.test.d.ts.map +1 -0
  140. package/dist/test/propertydeclaration.test.js +229 -0
  141. package/dist/test/propertydeclaration.test.js.map +1 -0
  142. package/dist/test/pydocs.test.js +926 -126
  143. package/dist/test/pydocs.test.js.map +1 -1
  144. package/dist/test/references.test.js +1 -5
  145. package/dist/test/references.test.js.map +1 -1
  146. package/dist/test/sourcefiles.test.js +90 -1
  147. package/dist/test/sourcefiles.test.js.map +1 -1
  148. package/dist/test/staticmethoddeclaration.test.d.ts +2 -0
  149. package/dist/test/staticmethoddeclaration.test.d.ts.map +1 -0
  150. package/dist/test/staticmethoddeclaration.test.js +61 -0
  151. package/dist/test/staticmethoddeclaration.test.js.map +1 -0
  152. package/dist/test/typereference.test.d.ts +2 -0
  153. package/dist/test/typereference.test.d.ts.map +1 -0
  154. package/dist/test/typereference.test.js +51 -0
  155. package/dist/test/typereference.test.js.map +1 -0
  156. package/dist/test/uniontypeexpression.test.js +152 -15
  157. package/dist/test/uniontypeexpression.test.js.map +1 -1
  158. package/dist/test/variables.test.js +28 -19
  159. package/dist/test/variables.test.js.map +1 -1
  160. package/dist/tsconfig.tsbuildinfo +1 -1
  161. package/package.json +2 -2
  162. package/src/builtins/python.ts +7 -0
  163. package/src/components/CallSignature.tsx +17 -69
  164. package/src/components/ClassMethodDeclaration.tsx +34 -0
  165. package/src/components/ConstructorDeclaration.tsx +37 -0
  166. package/src/components/DunderMethodDeclaration.tsx +30 -0
  167. package/src/components/EnumDeclaration.tsx +16 -44
  168. package/src/components/EnumMember.tsx +3 -3
  169. package/src/components/FunctionBase.tsx +88 -0
  170. package/src/components/FunctionDeclaration.tsx +18 -82
  171. package/src/components/MemberExpression.tsx +6 -19
  172. package/src/components/MethodBase.tsx +53 -0
  173. package/src/components/MethodDeclaration.tsx +27 -0
  174. package/src/components/PropertyDeclaration.tsx +264 -0
  175. package/src/components/PyDoc.tsx +795 -195
  176. package/src/components/SourceFile.tsx +29 -0
  177. package/src/components/StaticMethodDeclaration.tsx +34 -0
  178. package/src/components/TypeArguments.tsx +24 -0
  179. package/src/components/TypeReference.tsx +33 -0
  180. package/src/components/UnionTypeExpression.tsx +4 -15
  181. package/src/components/VariableDeclaration.tsx +1 -3
  182. package/src/components/index.ts +10 -0
  183. package/src/parameter-descriptor.ts +6 -5
  184. package/src/symbol-creation.ts +17 -0
  185. package/src/symbols/factories.ts +39 -0
  186. package/src/symbols/index.ts +1 -0
  187. package/src/symbols/reference.tsx +3 -5
  188. package/src/utils.ts +0 -2
  189. package/temp/api.json +5281 -2273
  190. package/test/callsignatures.test.tsx +102 -74
  191. package/test/class-method-declaration.test.tsx +53 -0
  192. package/test/classdeclarations.test.tsx +7 -9
  193. package/test/constructordeclaration.test.tsx +48 -0
  194. package/test/dundermethoddeclaration.test.tsx +53 -0
  195. package/test/enums.test.tsx +14 -16
  196. package/test/externals.test.tsx +5 -7
  197. package/test/factories.test.tsx +72 -0
  198. package/test/functiondeclaration.test.tsx +196 -44
  199. package/test/memberexpressions.test.tsx +7 -2
  200. package/test/methoddeclaration.test.tsx +202 -0
  201. package/test/namepolicies.test.tsx +1 -2
  202. package/test/propertydeclaration.test.tsx +192 -0
  203. package/test/pydocs.test.tsx +1093 -129
  204. package/test/references.test.tsx +1 -1
  205. package/test/sourcefiles.test.tsx +100 -1
  206. package/test/staticmethoddeclaration.test.tsx +49 -0
  207. package/test/typereference.test.tsx +52 -0
  208. package/test/uniontypeexpression.test.tsx +169 -34
  209. package/test/variables.test.tsx +27 -16
@@ -13,7 +13,7 @@ describe("Reference", () => {
13
13
  <py.SourceFile path="services.py">
14
14
  <py.VariableDeclaration
15
15
  name="current_user"
16
- type={<py.Reference refkey={rk1} />}
16
+ type={rk1}
17
17
  initializer={
18
18
  <py.ClassInstantiation target="User" args={['"Marvin"']} />
19
19
  }
@@ -1,7 +1,12 @@
1
+ import { Prose } from "@alloy-js/core";
1
2
  import { d } from "@alloy-js/core/testing";
2
3
  import { expect, it } from "vitest";
3
4
  import * as py from "../src/index.js";
4
- import { toSourceText } from "./utils.jsx";
5
+ import {
6
+ assertFileContents,
7
+ toSourceText,
8
+ toSourceTextMultiple,
9
+ } from "./utils.jsx";
5
10
 
6
11
  /**
7
12
  * toSourceText wraps the children in a SourceFile component
@@ -129,3 +134,97 @@ it("correct formatting of source file", () => {
129
134
  `;
130
135
  expect(result).toRenderTo(expected);
131
136
  });
137
+
138
+ it("renders module documentation correctly", () => {
139
+ const moduleDoc = (
140
+ <py.ModuleDoc
141
+ description={[
142
+ <Prose>
143
+ This module provides utility functions for data processing. It
144
+ includes functions for validation, transformation, and analysis.
145
+ </Prose>,
146
+ ]}
147
+ attributes={[
148
+ {
149
+ name: "DEFAULT_TIMEOUT",
150
+ type: "int",
151
+ children: "Default timeout value in seconds.",
152
+ },
153
+ {
154
+ name: "MAX_RETRIES",
155
+ type: "int",
156
+ children: "Maximum number of retry attempts.",
157
+ },
158
+ ]}
159
+ todo={["Add caching functionality", "Improve error messages"]}
160
+ style="google"
161
+ />
162
+ );
163
+
164
+ const content = (
165
+ <py.SourceFile path="utils.py" doc={moduleDoc}>
166
+ <py.VariableDeclaration name="DEFAULT_TIMEOUT" initializer={30} />
167
+ <py.VariableDeclaration name="MAX_RETRIES" initializer={3} />
168
+ <py.FunctionDeclaration name="process_data">pass</py.FunctionDeclaration>
169
+ </py.SourceFile>
170
+ );
171
+
172
+ const res = toSourceTextMultiple([content]);
173
+ const file = res.contents.find(
174
+ (f) => f.kind === "file" && f.path === "utils.py",
175
+ );
176
+ expect(file).toBeDefined();
177
+
178
+ assertFileContents(res, {
179
+ "utils.py": d`
180
+ """
181
+ This module provides utility functions for data processing. It includes
182
+ functions for validation, transformation, and analysis.
183
+
184
+ Attributes:
185
+ DEFAULT_TIMEOUT (int): Default timeout value in seconds.
186
+
187
+ MAX_RETRIES (int): Maximum number of retry attempts.
188
+
189
+ Todo:
190
+ * Add caching functionality
191
+ * Improve error messages
192
+ """
193
+
194
+
195
+ default_timeout = 30
196
+
197
+ max_retries = 3
198
+
199
+ def process_data():
200
+ pass
201
+
202
+
203
+ `,
204
+ });
205
+ });
206
+
207
+ it("renders source file without documentation correctly", () => {
208
+ const content = (
209
+ <py.SourceFile path="simple.py">
210
+ <py.FunctionDeclaration name="hello_world">
211
+ print("Hello, World!")
212
+ </py.FunctionDeclaration>
213
+ </py.SourceFile>
214
+ );
215
+
216
+ const res = toSourceTextMultiple([content]);
217
+ const file = res.contents.find(
218
+ (f) => f.kind === "file" && f.path === "simple.py",
219
+ );
220
+ expect(file).toBeDefined();
221
+
222
+ assertFileContents(res, {
223
+ "simple.py": d`
224
+ def hello_world():
225
+ print("Hello, World!")
226
+
227
+
228
+ `,
229
+ });
230
+ });
@@ -0,0 +1,49 @@
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.js";
5
+
6
+ describe("StaticMethodDeclaration", () => {
7
+ it("renders async static method", () => {
8
+ const decl = (
9
+ <py.StatementList>
10
+ <py.ClassDeclaration name="MyClass">
11
+ <py.StatementList>
12
+ <py.StaticMethodDeclaration async name="util" returnType="str">
13
+ return "x"
14
+ </py.StaticMethodDeclaration>
15
+ </py.StatementList>
16
+ </py.ClassDeclaration>
17
+ </py.StatementList>
18
+ );
19
+
20
+ expect(toSourceText([decl])).toBe(d`
21
+ class MyClass:
22
+ @staticmethod
23
+ async def util() -> str:
24
+ return "x"
25
+
26
+
27
+ `);
28
+ });
29
+
30
+ it("renders static method with parameters", () => {
31
+ const parameters = [{ name: "x", type: "int" }];
32
+ const decl = (
33
+ <py.ClassDeclaration name="MyClass">
34
+ <py.StaticMethodDeclaration name="foo" parameters={parameters}>
35
+ attribute = "value"
36
+ </py.StaticMethodDeclaration>
37
+ </py.ClassDeclaration>
38
+ );
39
+
40
+ expect(toSourceText([decl])).toBe(d`
41
+ class MyClass:
42
+ @staticmethod
43
+ def foo(x: int):
44
+ attribute = "value"
45
+
46
+
47
+ `);
48
+ });
49
+ });
@@ -0,0 +1,52 @@
1
+ import { code, 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 { toSourceText } from "./utils.jsx";
6
+
7
+ describe("TypeReference", () => {
8
+ it("renders a Python TypeReference with a refkey and type arguments", () => {
9
+ const classRefkey = refkey();
10
+
11
+ expect(
12
+ toSourceText([
13
+ <py.StatementList>
14
+ <py.ClassDeclaration
15
+ name="Bar"
16
+ refkey={classRefkey}
17
+ ></py.ClassDeclaration>
18
+ <py.TypeReference refkey={classRefkey} typeArgs={["T", "P"]} />
19
+ <py.TypeReference name="dict" typeArgs={["str", "int"]} />
20
+ </py.StatementList>,
21
+ ]),
22
+ ).toRenderTo(d`
23
+ class Bar:
24
+ pass
25
+
26
+ Bar[T, P]
27
+ dict[str, int]
28
+ `);
29
+ });
30
+
31
+ it("renders a Python list expression with a reference", () => {
32
+ const classRefkey = refkey();
33
+ const type = code`list[${classRefkey}]`;
34
+
35
+ expect(
36
+ toSourceText([
37
+ <py.StatementList>
38
+ <py.ClassDeclaration
39
+ name="Foo"
40
+ refkey={classRefkey}
41
+ ></py.ClassDeclaration>
42
+ <py.TypeReference name={type} />
43
+ </py.StatementList>,
44
+ ]),
45
+ ).toRenderTo(d`
46
+ class Foo:
47
+ pass
48
+
49
+ list[Foo]
50
+ `);
51
+ });
52
+ });
@@ -1,45 +1,44 @@
1
- import { code } from "@alloy-js/core";
1
+ import { refkey } from "@alloy-js/core";
2
2
  import { d } from "@alloy-js/core/testing";
3
3
  import { describe, expect, it } from "vitest";
4
4
  import * as py from "../src/index.js";
5
- import { toSourceText } from "./utils.jsx";
5
+ import {
6
+ assertFileContents,
7
+ toSourceText,
8
+ toSourceTextMultiple,
9
+ } from "./utils.jsx";
6
10
 
7
11
  describe("UnionTypeExpression", () => {
8
12
  it("renders a Python union expression - 1 item", () => {
9
- const elements = [code`int`];
10
13
  expect(
11
- toSourceText([
12
- <py.UnionTypeExpression>{elements}</py.UnionTypeExpression>,
13
- ]),
14
+ toSourceText([<py.UnionTypeExpression children={["int"]} />]),
14
15
  ).toRenderTo("int");
15
16
  });
16
17
  it("renders a Python union expression - 2 items", () => {
17
- const elements = [code`int`, code`str`];
18
18
  expect(
19
- toSourceText([
20
- <py.UnionTypeExpression>{elements}</py.UnionTypeExpression>,
21
- ]),
19
+ toSourceText([<py.UnionTypeExpression children={["int", "str"]} />]),
22
20
  ).toRenderTo("int | str");
23
21
  });
24
22
  it("renders a Python union expression - N items", () => {
25
- const elements = [
26
- code`int`,
27
- code`str`,
28
- code`float`,
29
- code`bool`,
30
- code`list`,
31
- code`dict`,
32
- code`set`,
33
- code`tuple`,
34
- code`frozenset`,
35
- code`bytes`,
36
- code`bytearray`,
37
- code`memoryview`,
38
- code`complex`,
39
- ];
40
23
  expect(
41
24
  toSourceText([
42
- <py.UnionTypeExpression>{elements}</py.UnionTypeExpression>,
25
+ <py.UnionTypeExpression
26
+ children={[
27
+ "int",
28
+ "str",
29
+ "float",
30
+ "bool",
31
+ "list",
32
+ "dict",
33
+ "set",
34
+ "tuple",
35
+ "frozenset",
36
+ "bytes",
37
+ "bytearray",
38
+ "memoryview",
39
+ "complex",
40
+ ]}
41
+ />,
43
42
  ]),
44
43
  ).toRenderTo(d`
45
44
  (
@@ -58,20 +57,156 @@ describe("UnionTypeExpression", () => {
58
57
  | complex
59
58
  )`);
60
59
  });
61
- it("renders a Python union expression - 2 items", () => {
62
- const elements = [code`int`, code`str`];
60
+ it("renders a Python union expression - 2 items again", () => {
63
61
  expect(
64
- toSourceText([
65
- <py.UnionTypeExpression>{elements}</py.UnionTypeExpression>,
66
- ]),
62
+ toSourceText([<py.UnionTypeExpression children={["int", "str"]} />]),
67
63
  ).toRenderTo("int | str");
68
64
  });
69
- it("renders a Python union expression - 2 items with optional", () => {
70
- const elements = [code`int`, code`str`];
65
+ it("renders a Python union expression - 2 items with None", () => {
71
66
  expect(
72
67
  toSourceText([
73
- <py.UnionTypeExpression optional>{elements}</py.UnionTypeExpression>,
68
+ <py.UnionTypeExpression children={["int", "str", "None"]} />,
74
69
  ]),
75
70
  ).toRenderTo("int | str | None");
76
71
  });
72
+
73
+ it("renders a Python union with generic types", () => {
74
+ expect(
75
+ toSourceText([
76
+ <py.UnionTypeExpression
77
+ children={[
78
+ <py.TypeReference name="list" typeArgs={["int"]} />,
79
+ <py.TypeReference name="dict" typeArgs={["str", "int"]} />,
80
+ ]}
81
+ />,
82
+ ]),
83
+ ).toRenderTo("list[int] | dict[str, int]");
84
+ });
85
+
86
+ it("renders a Python type expression with references", () => {
87
+ const classRefkey = refkey();
88
+ const otherClassRefkey = refkey();
89
+
90
+ expect(
91
+ toSourceText([
92
+ <py.StatementList>
93
+ <py.ClassDeclaration
94
+ name="Bar"
95
+ refkey={classRefkey}
96
+ ></py.ClassDeclaration>
97
+ <py.ClassDeclaration
98
+ name="Foo"
99
+ refkey={otherClassRefkey}
100
+ ></py.ClassDeclaration>
101
+ <py.UnionTypeExpression
102
+ children={[
103
+ <py.Reference refkey={classRefkey} />,
104
+ <py.Reference refkey={otherClassRefkey} />,
105
+ ]}
106
+ />
107
+ </py.StatementList>,
108
+ ]),
109
+ ).toRenderTo(d`
110
+ class Bar:
111
+ pass
112
+
113
+ class Foo:
114
+ pass
115
+
116
+ Bar | Foo
117
+ `);
118
+ });
119
+
120
+ it("emits import for TypeReference with refkey and typeArgs across files", () => {
121
+ const classRefkey = refkey();
122
+ const res = toSourceTextMultiple([
123
+ <py.SourceFile path="defs.py">
124
+ <py.ClassDeclaration name="Bar" refkey={classRefkey} />
125
+ </py.SourceFile>,
126
+ <py.SourceFile path="use.py">
127
+ <py.StatementList>
128
+ <py.VariableDeclaration
129
+ name="v"
130
+ type={<py.TypeReference refkey={classRefkey} typeArgs={["T"]} />}
131
+ />
132
+ </py.StatementList>
133
+ </py.SourceFile>,
134
+ ]);
135
+ assertFileContents(res, {
136
+ "defs.py": `
137
+ class Bar:
138
+ pass
139
+
140
+ `,
141
+ "use.py": `
142
+ from defs import Bar
143
+
144
+ v: Bar[T] = None
145
+ `,
146
+ });
147
+ });
148
+ });
149
+
150
+ describe("TypeExpression in different scenarios", () => {
151
+ it("renders an UnionTypeExpression as a function type parameter and return type", () => {
152
+ const classRefkey = refkey();
153
+ const type = (
154
+ <py.UnionTypeExpression
155
+ children={["int", "str", <py.Reference refkey={classRefkey} />]}
156
+ />
157
+ );
158
+ expect(
159
+ toSourceText([
160
+ <py.ClassDeclaration
161
+ name="Foo"
162
+ refkey={classRefkey}
163
+ ></py.ClassDeclaration>,
164
+ <py.FunctionDeclaration
165
+ name="fooFunction"
166
+ parameters={[
167
+ {
168
+ name: "x",
169
+ type: type,
170
+ },
171
+ ]}
172
+ args={true}
173
+ kwargs={true}
174
+ returnType={type}
175
+ />,
176
+ ]),
177
+ ).toRenderTo(d`
178
+ class Foo:
179
+ pass
180
+
181
+
182
+ def foo_function(x: int | str | Foo, *args, **kwargs) -> int | str | Foo:
183
+ pass
184
+
185
+
186
+ `);
187
+ });
188
+ it("renders an UnionTypeExpression as a variable type", () => {
189
+ const classRefkey = refkey();
190
+ const type = (
191
+ <py.UnionTypeExpression
192
+ children={["int", "str", <py.Reference refkey={classRefkey} />]}
193
+ />
194
+ );
195
+ expect(
196
+ toSourceText([
197
+ <py.ClassDeclaration
198
+ name="Foo"
199
+ refkey={classRefkey}
200
+ ></py.ClassDeclaration>,
201
+ <py.VariableDeclaration name="fooVariable" type={type} />,
202
+ ]),
203
+ ).toRenderTo(d`
204
+ class Foo:
205
+ pass
206
+
207
+
208
+ foo_variable: int | str | Foo = None
209
+
210
+ `);
211
+ });
77
212
  });
@@ -1,4 +1,4 @@
1
- import { code, namekey, refkey } from "@alloy-js/core";
1
+ import { namekey, refkey } from "@alloy-js/core";
2
2
  import { d } from "@alloy-js/core/testing";
3
3
  import { describe, expect, it } from "vitest";
4
4
  import * as py from "../src/index.js";
@@ -27,6 +27,17 @@ describe("Python Variable", () => {
27
27
  expect(res).toBe(`my_var: int = 42`);
28
28
  });
29
29
 
30
+ it("takes a namekey", () => {
31
+ const res = toSourceText([
32
+ <py.VariableDeclaration
33
+ name={namekey("my-var")}
34
+ type="int"
35
+ initializer={42}
36
+ />,
37
+ ]);
38
+ expect(res).toBe(`my_var: int = 42`);
39
+ });
40
+
30
41
  it("declares a python variable without value", () => {
31
42
  const res = toSourceText([
32
43
  <py.VariableDeclaration name="myVar" type="int" omitNone />,
@@ -60,7 +71,7 @@ describe("Python Variable", () => {
60
71
  const res = toSourceText([
61
72
  <py.VariableDeclaration
62
73
  name="numbers"
63
- type="list[int]"
74
+ type={<py.TypeReference name="list" typeArgs={["int"]} />}
64
75
  initializer={<py.Atom jsValue={[1, 2, 3]} />}
65
76
  />,
66
77
  ]);
@@ -107,13 +118,14 @@ describe("Python Variable", () => {
107
118
  });
108
119
 
109
120
  it("declares a python variable with an optional type", () => {
110
- const elements = [code`int`];
111
- const typing = (
112
- <py.UnionTypeExpression optional>{elements}</py.UnionTypeExpression>
113
- );
114
121
  const res = toSourceText([
115
122
  <py.StatementList>
116
- <py.VariableDeclaration name="my_var" type={typing} />
123
+ <py.VariableDeclaration
124
+ name="my_var"
125
+ type={
126
+ <py.UnionTypeExpression>{["int", "None"]}</py.UnionTypeExpression>
127
+ }
128
+ />
117
129
  </py.StatementList>,
118
130
  ]);
119
131
  expect(res).toBe(d`
@@ -121,13 +133,15 @@ describe("Python Variable", () => {
121
133
  });
122
134
 
123
135
  it("declares a python variable with an optional type omitting none", () => {
124
- const elements = [code`int`];
125
- const typing = (
126
- <py.UnionTypeExpression optional>{elements}</py.UnionTypeExpression>
127
- );
128
136
  const res = toSourceText([
129
137
  <py.StatementList>
130
- <py.VariableDeclaration name="my_var" type={typing} omitNone />
138
+ <py.VariableDeclaration
139
+ name="my_var"
140
+ type={
141
+ <py.UnionTypeExpression>{["int", "None"]}</py.UnionTypeExpression>
142
+ }
143
+ omitNone
144
+ />
131
145
  </py.StatementList>,
132
146
  ]);
133
147
  expect(res).toBe(d`
@@ -159,10 +173,7 @@ describe("Python Variable", () => {
159
173
  <py.ClassDeclaration name="MyClass" refkey={classKey} />
160
174
  </py.SourceFile>,
161
175
  <py.SourceFile path="usage.py">
162
- <py.VariableDeclaration
163
- name="my_var"
164
- type={<py.Reference refkey={classKey} />}
165
- />
176
+ <py.VariableDeclaration name="my_var" type={classKey} />
166
177
  </py.SourceFile>,
167
178
  ]);
168
179
  assertFileContents(res, {