@alloy-js/python 0.4.0 → 0.5.0-dev.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 (153) hide show
  1. package/dist/dev/src/builtins/python.js +46 -0
  2. package/dist/dev/src/builtins/python.js.map +1 -1
  3. package/dist/dev/src/components/ClassDeclaration.js +19 -10
  4. package/dist/dev/src/components/ClassDeclaration.js.map +1 -1
  5. package/dist/dev/src/components/ClassMethodDeclaration.js +20 -5
  6. package/dist/dev/src/components/ClassMethodDeclaration.js.map +1 -1
  7. package/dist/dev/src/components/DataclassDeclaration.js +14 -12
  8. package/dist/dev/src/components/DataclassDeclaration.js.map +1 -1
  9. package/dist/dev/src/components/DecoratorList.js +55 -0
  10. package/dist/dev/src/components/DecoratorList.js.map +1 -0
  11. package/dist/dev/src/components/EnumDeclaration.js +21 -12
  12. package/dist/dev/src/components/EnumDeclaration.js.map +1 -1
  13. package/dist/dev/src/components/FunctionBase.js +21 -10
  14. package/dist/dev/src/components/FunctionBase.js.map +1 -1
  15. package/dist/dev/src/components/FutureStatement.js +1 -1
  16. package/dist/dev/src/components/MethodBase.js +16 -4
  17. package/dist/dev/src/components/MethodBase.js.map +1 -1
  18. package/dist/dev/src/components/PropertyDeclaration.js +68 -17
  19. package/dist/dev/src/components/PropertyDeclaration.js.map +1 -1
  20. package/dist/dev/src/components/PydanticClassDeclaration.js +136 -0
  21. package/dist/dev/src/components/PydanticClassDeclaration.js.map +1 -0
  22. package/dist/dev/src/components/StaticMethodDeclaration.js +19 -5
  23. package/dist/dev/src/components/StaticMethodDeclaration.js.map +1 -1
  24. package/dist/dev/src/components/index.js +1 -0
  25. package/dist/dev/src/components/index.js.map +1 -1
  26. package/dist/dev/test/classdeclarations.test.js +85 -52
  27. package/dist/dev/test/classdeclarations.test.js.map +1 -1
  28. package/dist/dev/test/dataclassdeclarations.test.js +122 -89
  29. package/dist/dev/test/dataclassdeclarations.test.js.map +1 -1
  30. package/dist/dev/test/decoratorlist.test.js +84 -0
  31. package/dist/dev/test/decoratorlist.test.js.map +1 -0
  32. package/dist/dev/test/enums.test.js +41 -10
  33. package/dist/dev/test/enums.test.js.map +1 -1
  34. package/dist/dev/test/functiondeclaration.test.js +81 -61
  35. package/dist/dev/test/functiondeclaration.test.js.map +1 -1
  36. package/dist/dev/test/methoddeclaration.test.js +117 -26
  37. package/dist/dev/test/methoddeclaration.test.js.map +1 -1
  38. package/dist/dev/test/propertydeclaration.test.js +109 -7
  39. package/dist/dev/test/propertydeclaration.test.js.map +1 -1
  40. package/dist/dev/test/pydanticclassdeclarations.test.js +1137 -0
  41. package/dist/dev/test/pydanticclassdeclarations.test.js.map +1 -0
  42. package/dist/src/builtins/python.d.ts +30 -0
  43. package/dist/src/builtins/python.d.ts.map +1 -1
  44. package/dist/src/builtins/python.js +46 -0
  45. package/dist/src/builtins/python.js.map +1 -1
  46. package/dist/src/components/ClassDeclaration.d.ts +21 -0
  47. package/dist/src/components/ClassDeclaration.d.ts.map +1 -1
  48. package/dist/src/components/ClassDeclaration.js +6 -1
  49. package/dist/src/components/ClassDeclaration.js.map +1 -1
  50. package/dist/src/components/ClassMethodDeclaration.d.ts +5 -1
  51. package/dist/src/components/ClassMethodDeclaration.d.ts.map +1 -1
  52. package/dist/src/components/ClassMethodDeclaration.js +14 -3
  53. package/dist/src/components/ClassMethodDeclaration.js.map +1 -1
  54. package/dist/src/components/DataclassDeclaration.d.ts.map +1 -1
  55. package/dist/src/components/DataclassDeclaration.js +10 -4
  56. package/dist/src/components/DataclassDeclaration.js.map +1 -1
  57. package/dist/src/components/DecoratorList.d.ts +43 -0
  58. package/dist/src/components/DecoratorList.d.ts.map +1 -0
  59. package/dist/src/components/DecoratorList.js +47 -0
  60. package/dist/src/components/DecoratorList.js.map +1 -0
  61. package/dist/src/components/EnumDeclaration.d.ts +9 -0
  62. package/dist/src/components/EnumDeclaration.d.ts.map +1 -1
  63. package/dist/src/components/EnumDeclaration.js +6 -1
  64. package/dist/src/components/EnumDeclaration.js.map +1 -1
  65. package/dist/src/components/FunctionBase.d.ts +31 -1
  66. package/dist/src/components/FunctionBase.d.ts.map +1 -1
  67. package/dist/src/components/FunctionBase.js +9 -2
  68. package/dist/src/components/FunctionBase.js.map +1 -1
  69. package/dist/src/components/FutureStatement.d.ts +1 -1
  70. package/dist/src/components/FutureStatement.js +1 -1
  71. package/dist/src/components/MethodBase.d.ts.map +1 -1
  72. package/dist/src/components/MethodBase.js +10 -2
  73. package/dist/src/components/MethodBase.js.map +1 -1
  74. package/dist/src/components/PropertyDeclaration.d.ts +29 -0
  75. package/dist/src/components/PropertyDeclaration.d.ts.map +1 -1
  76. package/dist/src/components/PropertyDeclaration.js +48 -1
  77. package/dist/src/components/PropertyDeclaration.js.map +1 -1
  78. package/dist/src/components/PydanticClassDeclaration.d.ts +120 -0
  79. package/dist/src/components/PydanticClassDeclaration.d.ts.map +1 -0
  80. package/dist/src/components/PydanticClassDeclaration.js +116 -0
  81. package/dist/src/components/PydanticClassDeclaration.js.map +1 -0
  82. package/dist/src/components/StaticMethodDeclaration.d.ts +3 -0
  83. package/dist/src/components/StaticMethodDeclaration.d.ts.map +1 -1
  84. package/dist/src/components/StaticMethodDeclaration.js +13 -3
  85. package/dist/src/components/StaticMethodDeclaration.js.map +1 -1
  86. package/dist/src/components/index.d.ts +1 -0
  87. package/dist/src/components/index.d.ts.map +1 -1
  88. package/dist/src/components/index.js +1 -0
  89. package/dist/src/components/index.js.map +1 -1
  90. package/dist/test/classdeclarations.test.js +25 -0
  91. package/dist/test/classdeclarations.test.js.map +1 -1
  92. package/dist/test/dataclassdeclarations.test.js +25 -0
  93. package/dist/test/dataclassdeclarations.test.js.map +1 -1
  94. package/dist/test/decoratorlist.test.d.ts +2 -0
  95. package/dist/test/decoratorlist.test.d.ts.map +1 -0
  96. package/dist/test/decoratorlist.test.js +60 -0
  97. package/dist/test/decoratorlist.test.js.map +1 -0
  98. package/dist/test/enums.test.js +27 -0
  99. package/dist/test/enums.test.js.map +1 -1
  100. package/dist/test/functiondeclaration.test.js +16 -0
  101. package/dist/test/functiondeclaration.test.js.map +1 -1
  102. package/dist/test/methoddeclaration.test.js +67 -0
  103. package/dist/test/methoddeclaration.test.js.map +1 -1
  104. package/dist/test/propertydeclaration.test.js +71 -1
  105. package/dist/test/propertydeclaration.test.js.map +1 -1
  106. package/dist/test/pydanticclassdeclarations.test.d.ts +2 -0
  107. package/dist/test/pydanticclassdeclarations.test.d.ts.map +1 -0
  108. package/dist/test/pydanticclassdeclarations.test.js +829 -0
  109. package/dist/test/pydanticclassdeclarations.test.js.map +1 -0
  110. package/dist/tsconfig.tsbuildinfo +1 -1
  111. package/docs/api/components/ClassDeclaration.md +10 -7
  112. package/docs/api/components/ClassEnumDeclaration.md +9 -6
  113. package/docs/api/components/ClassMethodDeclaration.md +7 -5
  114. package/docs/api/components/DataclassDeclaration.md +9 -5
  115. package/docs/api/components/DunderMethodDeclaration.md +7 -5
  116. package/docs/api/components/FunctionDeclaration.md +9 -5
  117. package/docs/api/components/FutureStatement.md +1 -1
  118. package/docs/api/components/MethodDeclaration.md +11 -6
  119. package/docs/api/components/PropertyDeclaration.md +11 -8
  120. package/docs/api/components/PydanticClassDeclaration.md +146 -0
  121. package/docs/api/components/StaticMethodDeclaration.md +7 -5
  122. package/docs/api/components/index.md +1 -0
  123. package/docs/api/index.md +3 -3
  124. package/docs/api/types/CommonFunctionProps.md +4 -3
  125. package/docs/api/types/PydanticModelConfigDictProps.md +32 -0
  126. package/docs/api/types/index.md +1 -0
  127. package/docs/api/variables/index.md +3 -0
  128. package/docs/api/variables/pydanticModule.md +27 -0
  129. package/docs/api/variables/pydanticSettingsModule.md +7 -0
  130. package/docs/api/variables/typingModule.md +9 -0
  131. package/package.json +6 -6
  132. package/src/builtins/python.ts +539 -1
  133. package/src/components/ClassDeclaration.tsx +23 -0
  134. package/src/components/ClassMethodDeclaration.tsx +9 -1
  135. package/src/components/DataclassDeclaration.tsx +18 -11
  136. package/src/components/DecoratorList.tsx +50 -0
  137. package/src/components/EnumDeclaration.tsx +11 -0
  138. package/src/components/FunctionBase.tsx +34 -3
  139. package/src/components/FutureStatement.tsx +1 -1
  140. package/src/components/MethodBase.tsx +6 -2
  141. package/src/components/PropertyDeclaration.tsx +48 -1
  142. package/src/components/PydanticClassDeclaration.tsx +222 -0
  143. package/src/components/StaticMethodDeclaration.tsx +7 -1
  144. package/src/components/index.ts +1 -0
  145. package/temp/api.json +1142 -84
  146. package/test/classdeclarations.test.tsx +27 -0
  147. package/test/dataclassdeclarations.test.tsx +25 -0
  148. package/test/decoratorlist.test.tsx +95 -0
  149. package/test/enums.test.tsx +29 -0
  150. package/test/functiondeclaration.test.tsx +17 -0
  151. package/test/methoddeclaration.test.tsx +70 -0
  152. package/test/propertydeclaration.test.tsx +66 -1
  153. package/test/pydanticclassdeclarations.test.tsx +836 -0
@@ -9,6 +9,33 @@ import {
9
9
  } from "./utils.jsx";
10
10
 
11
11
  describe("Python Class", () => {
12
+ it("renders class-level decorators above `class`", () => {
13
+ const result = toSourceText([
14
+ <py.ClassDeclaration
15
+ name="Foo"
16
+ decorators={["@final", "@deprecated('use Bar')"]}
17
+ />,
18
+ ]);
19
+ expect(result).toRenderTo(d`
20
+ @final
21
+ @deprecated('use Bar')
22
+ class Foo:
23
+ pass
24
+
25
+
26
+ `);
27
+ });
28
+
29
+ it("renders nothing extra when decorators is undefined", () => {
30
+ const result = toSourceText([<py.ClassDeclaration name="Foo" />]);
31
+ expect(result).toRenderTo(d`
32
+ class Foo:
33
+ pass
34
+
35
+
36
+ `);
37
+ });
38
+
12
39
  it("renders a class with no body as 'pass'", () => {
13
40
  const result = toSourceText([<py.ClassDeclaration name="Foo" />]);
14
41
  expect(result).toRenderTo(d`
@@ -10,6 +10,31 @@ import {
10
10
  } from "./utils.jsx";
11
11
 
12
12
  describe("DataclassDeclaration", () => {
13
+ it("stacks user decorators above @dataclass", () => {
14
+ const res = toSourceText(
15
+ [
16
+ <py.SourceFile path="user.py">
17
+ <py.DataclassDeclaration name="User" frozen decorators={["@final"]} />
18
+ </py.SourceFile>,
19
+ ],
20
+ { externals: [dataclassesModule] },
21
+ );
22
+
23
+ expect(res).toRenderTo(
24
+ d`
25
+ from dataclasses import dataclass
26
+
27
+
28
+ @final
29
+ @dataclass(frozen=True)
30
+ class User:
31
+ pass
32
+
33
+
34
+ `,
35
+ );
36
+ });
37
+
13
38
  it("Creates a dataclass with a class doc", () => {
14
39
  const doc = (
15
40
  <py.ClassDoc description={[<Prose>Represents a user.</Prose>]} />
@@ -0,0 +1,95 @@
1
+ import { d } from "@alloy-js/core/testing";
2
+ import { describe, expect, it } from "vitest";
3
+ import { DecoratorList } from "../src/components/DecoratorList.jsx";
4
+ import { toSourceText } from "./utils.js";
5
+
6
+ /**
7
+ * Direct contract tests for `DecoratorList`. The component is exercised
8
+ * transitively by every method/property test, but pinning the three core
9
+ * behaviors here makes regressions caught at the helper's own boundary —
10
+ * not after they propagate through every consumer.
11
+ */
12
+ describe("DecoratorList", () => {
13
+ it("renders nothing when decorators is undefined", () => {
14
+ expect(
15
+ toSourceText([
16
+ <>
17
+ <DecoratorList />
18
+ pass
19
+ </>,
20
+ ]),
21
+ ).toRenderTo("pass");
22
+ });
23
+
24
+ it("renders nothing when decorators is an empty array", () => {
25
+ expect(
26
+ toSourceText([
27
+ <>
28
+ <DecoratorList decorators={[]} />
29
+ pass
30
+ </>,
31
+ ]),
32
+ ).toRenderTo("pass");
33
+ });
34
+
35
+ it("renders a single decorator followed by exactly one hardline", () => {
36
+ expect(
37
+ toSourceText([
38
+ <>
39
+ <DecoratorList decorators={["@one"]} />
40
+ pass
41
+ </>,
42
+ ]),
43
+ ).toRenderTo(d`
44
+ @one
45
+ pass
46
+ `);
47
+ });
48
+
49
+ it("renders multiple decorators with no blank lines between adjacent entries", () => {
50
+ expect(
51
+ toSourceText([
52
+ <>
53
+ <DecoratorList decorators={["@one", "@two", "@three"]} />
54
+ pass
55
+ </>,
56
+ ]),
57
+ ).toRenderTo(d`
58
+ @one
59
+ @two
60
+ @three
61
+ pass
62
+ `);
63
+ });
64
+
65
+ it("preserves source order: first entry is topmost (= applied last)", () => {
66
+ expect(
67
+ toSourceText([
68
+ <>
69
+ <DecoratorList decorators={["@outer", "@middle", "@inner"]} />
70
+ pass
71
+ </>,
72
+ ]),
73
+ ).toRenderTo(d`
74
+ @outer
75
+ @middle
76
+ @inner
77
+ pass
78
+ `);
79
+ });
80
+
81
+ it("skips falsy entries without emitting blank lines", () => {
82
+ expect(
83
+ toSourceText([
84
+ <>
85
+ <DecoratorList decorators={["@one", false, undefined, "@two"]} />
86
+ pass
87
+ </>,
88
+ ]),
89
+ ).toRenderTo(d`
90
+ @one
91
+ @two
92
+ pass
93
+ `);
94
+ });
95
+ });
@@ -6,6 +6,35 @@ import * as py from "../src/index.js";
6
6
  import { toSourceText } from "./utils.jsx";
7
7
 
8
8
  describe("Python Enum", () => {
9
+ it("renders class-level decorators above ClassEnumDeclaration", () => {
10
+ const result = toSourceText(
11
+ [
12
+ <py.ClassEnumDeclaration
13
+ name="Color"
14
+ baseType="IntEnum"
15
+ decorators={["@final"]}
16
+ members={[
17
+ { name: "RED", value: 1 },
18
+ { name: "GREEN", value: 2 },
19
+ ]}
20
+ />,
21
+ ],
22
+ { externals: [enumModule] },
23
+ );
24
+
25
+ expect(result).toRenderTo(d`
26
+ from enum import IntEnum
27
+
28
+
29
+ @final
30
+ class Color(IntEnum):
31
+ RED = 1
32
+ GREEN = 2
33
+
34
+
35
+ `);
36
+ });
37
+
9
38
  it("class enum with explicit values", () => {
10
39
  const result = toSourceText(
11
40
  [
@@ -10,6 +10,23 @@ import {
10
10
  } from "./utils.js";
11
11
 
12
12
  describe("Function Declaration", () => {
13
+ it("renders multiple decorators above def without blank lines", () => {
14
+ const result = toSourceText([
15
+ <py.FunctionDeclaration name="f" decorators={["@a", "@b", "@c"]}>
16
+ pass
17
+ </py.FunctionDeclaration>,
18
+ ]);
19
+ expect(result).toRenderTo(d`
20
+ @a
21
+ @b
22
+ @c
23
+ def f():
24
+ pass
25
+
26
+
27
+ `);
28
+ });
29
+
13
30
  it("renders a function with no body as 'pass'", () => {
14
31
  const result = toSourceText([<py.FunctionDeclaration name="foo" />]);
15
32
  expect(result).toRenderTo(d`
@@ -5,6 +5,76 @@ import { abcModule } from "../src/index.js";
5
5
  import { toSourceText } from "./utils.js";
6
6
 
7
7
  describe("Method-like Declarations", () => {
8
+ it("renders decorators above def", () => {
9
+ const result = toSourceText([
10
+ <py.ClassDeclaration name="MyClass">
11
+ <py.MethodDeclaration
12
+ name="with_decorator"
13
+ decorators={["@some_decorator"]}
14
+ >
15
+ pass
16
+ </py.MethodDeclaration>
17
+ </py.ClassDeclaration>,
18
+ ]);
19
+ expect(result).toRenderTo(d`
20
+ class MyClass:
21
+ @some_decorator
22
+ def with_decorator(self):
23
+ pass
24
+
25
+
26
+
27
+ `);
28
+ });
29
+
30
+ it("renders multiple decorators above def without blank lines", () => {
31
+ const result = toSourceText([
32
+ <py.ClassDeclaration name="MyClass">
33
+ <py.MethodDeclaration
34
+ name="with_decorators"
35
+ decorators={["@outer", "@middle", "@inner"]}
36
+ >
37
+ pass
38
+ </py.MethodDeclaration>
39
+ </py.ClassDeclaration>,
40
+ ]);
41
+ expect(result).toRenderTo(d`
42
+ class MyClass:
43
+ @outer
44
+ @middle
45
+ @inner
46
+ def with_decorators(self):
47
+ pass
48
+
49
+
50
+
51
+ `);
52
+ });
53
+
54
+ it("renders multiple decorators above @classmethod without blank lines", () => {
55
+ const result = toSourceText([
56
+ <py.ClassDeclaration name="MyClass">
57
+ <py.ClassMethodDeclaration
58
+ name="with_decorators"
59
+ decorators={["@outer", "@inner"]}
60
+ >
61
+ pass
62
+ </py.ClassMethodDeclaration>
63
+ </py.ClassDeclaration>,
64
+ ]);
65
+ expect(result).toRenderTo(d`
66
+ class MyClass:
67
+ @outer
68
+ @inner
69
+ @classmethod
70
+ def with_decorators(cls):
71
+ pass
72
+
73
+
74
+
75
+ `);
76
+ });
77
+
8
78
  it("renders an instance function with a body", () => {
9
79
  const result = toSourceText([
10
80
  <py.ClassDeclaration name="MyClass">
@@ -1,4 +1,4 @@
1
- import { Prose } from "@alloy-js/core";
1
+ import { Prose, code } 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";
@@ -148,6 +148,71 @@ describe("PropertyDeclaration", () => {
148
148
  `);
149
149
  });
150
150
 
151
+ it("renders decorators above @property in source order", () => {
152
+ const decl = (
153
+ <py.StatementList>
154
+ <py.ClassDeclaration name="MyClass">
155
+ <py.StatementList>
156
+ <py.PropertyDeclaration
157
+ name="area"
158
+ type="float"
159
+ decorators={[
160
+ code`@computed_field`,
161
+ code`@deprecated("use width**2")`,
162
+ ]}
163
+ >
164
+ return self.width ** 2
165
+ </py.PropertyDeclaration>
166
+ </py.StatementList>
167
+ </py.ClassDeclaration>
168
+ </py.StatementList>
169
+ );
170
+
171
+ expect(toSourceText([decl], { externals: [abcModule] })).toBe(d`
172
+ class MyClass:
173
+ @computed_field
174
+ @deprecated("use width**2")
175
+ @property
176
+ def area(self) -> float:
177
+ return self.width ** 2
178
+
179
+
180
+ `);
181
+ });
182
+
183
+ it("stacks decorators above @property and @abstractmethod below it", () => {
184
+ const decl = (
185
+ <py.StatementList>
186
+ <py.ClassDeclaration name="MyClass">
187
+ <py.StatementList>
188
+ <py.PropertyDeclaration
189
+ name="area"
190
+ type="float"
191
+ abstract
192
+ decorators={[code`@computed_field`]}
193
+ >
194
+ return self.width ** 2
195
+ </py.PropertyDeclaration>
196
+ </py.StatementList>
197
+ </py.ClassDeclaration>
198
+ </py.StatementList>
199
+ );
200
+
201
+ expect(toSourceText([decl], { externals: [abcModule] })).toBe(d`
202
+ from abc import abstractmethod
203
+
204
+
205
+ class MyClass:
206
+ @computed_field
207
+ @property
208
+ @abstractmethod
209
+ def area(self) -> float:
210
+ return self.width ** 2
211
+
212
+
213
+ `);
214
+ });
215
+
151
216
  it("renders abstract property with getter, setter, deleter", () => {
152
217
  const decl = (
153
218
  <py.StatementList>