@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,98 @@
1
+ import {
2
+ Children,
3
+ List,
4
+ Name,
5
+ OutputSymbolFlags,
6
+ Scope,
7
+ Show,
8
+ childrenArray,
9
+ takeSymbols,
10
+ } from "@alloy-js/core";
11
+ import { createPythonSymbol } from "../symbol-creation.js";
12
+ import {
13
+ BaseDeclarationProps,
14
+ Declaration,
15
+ DeclarationProps,
16
+ } from "./Declaration.js";
17
+ import { PythonBlock } from "./PythonBlock.jsx";
18
+
19
+ export interface ClassDeclarationProps extends BaseDeclarationProps {
20
+ /**
21
+ * The base classes that this class inherits from.
22
+ */
23
+ bases?: Children[];
24
+ }
25
+
26
+ /**
27
+ * Create a Python class declaration.
28
+ *
29
+ * @example
30
+ * ```tsx
31
+ * <ClassDeclaration name="MyClass" bases={["BaseClass"]}>
32
+ * <VariableDeclaration name="a" type="int" />
33
+ * <VariableDeclaration name="b" type="str" />
34
+ * <py.FunctionDeclaration name="my_method" parameters={[{ name: "a", type: "int" }, { name: "b", type: "str" }]} returnType="int">
35
+ * return a + b
36
+ * </py.FunctionDeclaration>
37
+ * </ClassDeclaration>
38
+ * ```
39
+ * renders to
40
+ * ```py
41
+ * class MyClass(BaseClass):
42
+ * a: int = None
43
+ * b: str = None
44
+ * def my_method(self, a: int, b: str) -> int:
45
+ * return a + b
46
+ * ```
47
+ * @remarks
48
+ *
49
+ * Any child declarations (methods, fields, nested classes) will be placed
50
+ * in the class scope. This component creates a class scope to hold its
51
+ * members.
52
+ */
53
+ export function ClassDeclaration(props: ClassDeclarationProps) {
54
+ const basesPart = props.bases && (
55
+ <>
56
+ (<List children={props.bases} comma space />)
57
+ </>
58
+ );
59
+
60
+ const sym = createPythonSymbol(
61
+ props.name!,
62
+ {
63
+ refkeys: props.refkey,
64
+ flags:
65
+ (props.flags ?? OutputSymbolFlags.None) |
66
+ OutputSymbolFlags.MemberContainer,
67
+ },
68
+ "class",
69
+ true,
70
+ );
71
+
72
+ takeSymbols((memberSymbol) => {
73
+ // Transform emitted symbols into instance/class members
74
+ memberSymbol.flags |= OutputSymbolFlags.InstanceMember;
75
+ });
76
+
77
+ // Propagate the name after the name policy was applied
78
+ const updatedProps: DeclarationProps = {
79
+ ...props,
80
+ name: sym.name,
81
+ nameKind: "class",
82
+ };
83
+ const hasChildren =
84
+ childrenArray(() => props.children).filter((c) => Boolean(c)).length > 0;
85
+
86
+ return (
87
+ <Declaration symbol={sym}>
88
+ class <Name />
89
+ <Scope name={updatedProps.name} kind="class">
90
+ {basesPart}
91
+ <PythonBlock opener=":">
92
+ <Show when={Boolean(props.doc)}>{props.doc}</Show>
93
+ {hasChildren ? props.children : "pass"}
94
+ </PythonBlock>
95
+ </Scope>
96
+ </Declaration>
97
+ );
98
+ }
@@ -0,0 +1,54 @@
1
+ import {
2
+ emitSymbol,
3
+ instantiateTakenMembersTo as instantiateTakenSymbolsTo,
4
+ OutputSymbolFlags,
5
+ useContext,
6
+ } from "@alloy-js/core";
7
+ import { createPythonSymbol } from "../symbol-creation.js";
8
+ import {
9
+ FunctionCallExpression,
10
+ FunctionCallExpressionProps,
11
+ } from "./FunctionCallExpression.jsx";
12
+ import { PythonSourceFileContext } from "./SourceFile.jsx";
13
+
14
+ export interface ClassInstantiationProps extends FunctionCallExpressionProps {}
15
+
16
+ /**
17
+ * Used to create new instances of classes in Python.
18
+ *
19
+ * @example
20
+ * ```tsx
21
+ * <ClassInstantiation target="MyClass" args={["arg1", "arg2"]} />
22
+ * ```
23
+ * This will generate:
24
+ * ```python
25
+ * MyClass(arg1, arg2)
26
+ * ```
27
+ * @remarks
28
+ *
29
+ * It is similar to FunctionCallExpression but specifically for class instantiation.
30
+ * Args should be a list arguments that can be either simple js values or py.Atoms, which will render as positional arguments,
31
+ * or py.VariableDeclarations, which will render as named arguments in the call statement. This component will
32
+ * not check for the correctness of the python grammar and will just work with any children you provide.
33
+ * It is up to you to ensure that the arguments you provide are valid in the context of a class instantiation.
34
+ */
35
+ export function ClassInstantiation(props: ClassInstantiationProps) {
36
+ const sfContext = useContext(PythonSourceFileContext);
37
+ const module = sfContext?.module;
38
+ const sym = createPythonSymbol(
39
+ "",
40
+ {
41
+ flags: OutputSymbolFlags.Transient,
42
+ module: module,
43
+ },
44
+ undefined,
45
+ false,
46
+ );
47
+ instantiateTakenSymbolsTo(sym);
48
+ emitSymbol(sym);
49
+ return (
50
+ <>
51
+ <FunctionCallExpression {...props} />
52
+ </>
53
+ );
54
+ }
@@ -0,0 +1,91 @@
1
+ import {
2
+ Children,
3
+ Declaration as CoreDeclaration,
4
+ MemberScope,
5
+ OutputSymbolFlags,
6
+ Refkey,
7
+ } from "@alloy-js/core";
8
+ import { PythonElements } from "../name-policy.js";
9
+ import { createPythonSymbol } from "../symbol-creation.js";
10
+ import { PythonOutputSymbol } from "../symbols/index.js";
11
+
12
+ export interface BaseDeclarationProps {
13
+ /**
14
+ * The base name of this declaration. May change depending on naming policy
15
+ * and any conflicts.
16
+ */
17
+ name: string;
18
+
19
+ /**
20
+ * The refkey or array of refkeys for this declaration.
21
+ */
22
+ refkey?: Refkey | Refkey[];
23
+
24
+ /**
25
+ * Flags for the symbol created by this component.
26
+ */
27
+ flags?: OutputSymbolFlags;
28
+
29
+ children?: Children;
30
+
31
+ /**
32
+ * Documentation for this declaration
33
+ */
34
+ doc?: Children;
35
+ }
36
+
37
+ export interface DeclarationProps extends Omit<BaseDeclarationProps, "name"> {
38
+ /**
39
+ * The name of this declaration.
40
+ */
41
+ name?: string;
42
+
43
+ /**
44
+ * The name policy kind to apply to the declaration.
45
+ */
46
+ nameKind?: PythonElements;
47
+
48
+ /**
49
+ * The symbol to use for this declaration.
50
+ */
51
+ symbol?: PythonOutputSymbol;
52
+ }
53
+
54
+ /**
55
+ * A Python declaration, which can be a class, function, variable, etc.
56
+ *
57
+ * @remarks
58
+ * This component is used to create a declaration with a symbol that can be
59
+ * referenced in the code. It can also be used to create a member scope for
60
+ * member containers.
61
+ *
62
+ */
63
+ export function Declaration(props: DeclarationProps) {
64
+ let sym: PythonOutputSymbol;
65
+
66
+ if (props.symbol) {
67
+ sym = props.symbol;
68
+ } else {
69
+ sym = createPythonSymbol(
70
+ props.name!,
71
+ {
72
+ refkeys: props.refkey,
73
+ flags: props.flags,
74
+ },
75
+ props.nameKind!,
76
+ true,
77
+ );
78
+ }
79
+
80
+ function withMemberScope(children: Children) {
81
+ return <MemberScope owner={sym}>{children}</MemberScope>;
82
+ }
83
+
84
+ let children: Children = () => props.children;
85
+
86
+ if (sym.flags & OutputSymbolFlags.MemberContainer) {
87
+ children = withMemberScope(children);
88
+ }
89
+
90
+ return <CoreDeclaration symbol={sym}>{children}</CoreDeclaration>;
91
+ }
@@ -0,0 +1,291 @@
1
+ import {
2
+ Children,
3
+ Declaration as CoreDeclaration,
4
+ For,
5
+ MemberScope,
6
+ OutputSymbolFlags,
7
+ Scope,
8
+ Show,
9
+ useBinder,
10
+ } from "@alloy-js/core";
11
+ import { enumModule } from "../builtins/python.js";
12
+ import { createPythonSymbol } from "../symbol-creation.js";
13
+ import { usePythonScope } from "../symbols/scopes.js";
14
+ import { BaseDeclarationProps } from "./Declaration.js";
15
+ import { EnumMember } from "./EnumMember.js";
16
+ import { PythonBlock } from "./PythonBlock.jsx";
17
+ import { SimpleCommentBlock } from "./index.js";
18
+
19
+ export interface EnumProps extends BaseDeclarationProps {
20
+ /**
21
+ * The base type of the enum. One of: 'Enum', 'IntEnum', 'StrEnum', 'Flag', 'IntFlag'.
22
+ * Defaults to 'Enum'.
23
+ */
24
+ baseType?: "Enum" | "IntEnum" | "StrEnum" | "Flag" | "IntFlag";
25
+ /**
26
+ * Members of the enum as an array of objects.
27
+ */
28
+ members?: Array<{
29
+ name: string;
30
+ value?: Children;
31
+ jsValue?: string | number;
32
+ doc?: string;
33
+ }>;
34
+ /**
35
+ * The enum style: 'classic' (default), 'auto', or 'functional'.
36
+ */
37
+ style?: "classic" | "auto" | "functional";
38
+ /**
39
+ * Optional docstring for the enum.
40
+ */
41
+ doc?: Children;
42
+ }
43
+
44
+ /**
45
+ * A Python enum declaration, following https://docs.python.org/3.11/library/enum.html.
46
+ *
47
+ * @example
48
+ * ```tsx
49
+ * <EnumDeclaration name="Direction" style="functional">
50
+ * members={[
51
+ * { name: "NORTH" },
52
+ * { name: "SOUTH" },
53
+ * { name: "EAST" },
54
+ * { name: "WEST" },
55
+ * ]}
56
+ * />
57
+ * ```
58
+ * This will generate:
59
+ * ```python
60
+ * from enum import Enum
61
+ * class Direction(Enum):
62
+ * NORTH = "NORTH"
63
+ * SOUTH = "SOUTH"
64
+ * EAST = "EAST"
65
+ * WEST = "WEST"
66
+ * ```
67
+ */
68
+ export function EnumDeclaration(props: EnumProps) {
69
+ // Handle enum styles
70
+ if (props.style === "functional") {
71
+ return <FunctionalEnumDeclaration {...props} />;
72
+ }
73
+ return <ClassEnumDeclaration {...props} />;
74
+ }
75
+
76
+ /**
77
+ * Create a Python enum using the functional syntax.
78
+ *
79
+ * This generates enums using the `Enum('Name', [...])` or `Enum('Name', {...})` syntax.
80
+ * The format depends on whether enum members have explicit values:
81
+ * - Members without values: `Enum('Direction', ['NORTH', 'SOUTH', 'EAST', 'WEST'])`
82
+ * - Members with values: `Enum('Direction', {'NORTH': 1, 'SOUTH': 2, 'EAST': 3, 'WEST': 4})`
83
+ *
84
+ * @example
85
+ * ```tsx
86
+ * <FunctionalEnumDeclaration
87
+ * name="Direction"
88
+ * members={[
89
+ * { name: "NORTH" },
90
+ * { name: "SOUTH" },
91
+ * { name: "EAST" },
92
+ * { name: "WEST" }
93
+ * ]}
94
+ * />
95
+ * ```
96
+ * renders to:
97
+ * ```python
98
+ * Direction = Enum('Direction', ['NORTH', 'SOUTH', 'EAST', 'WEST'])
99
+ * ```
100
+ *
101
+ * @example
102
+ * ```tsx
103
+ * <FunctionalEnumDeclaration
104
+ * name="Status"
105
+ * members={[
106
+ * { name: "PENDING", value: 1 },
107
+ * { name: "ACTIVE", value: 2 },
108
+ * { name: "INACTIVE", value: 3 }
109
+ * ]}
110
+ * />
111
+ * ```
112
+ * renders to:
113
+ * ```python
114
+ * Status = Enum('Status', {'PENDING': 1, 'ACTIVE': 2, 'INACTIVE': 3})
115
+ * ```
116
+ */
117
+ export function FunctionalEnumDeclaration(props: EnumProps) {
118
+ const binder = useBinder();
119
+ const scope = usePythonScope();
120
+ const sym = createPythonSymbol(
121
+ props.name,
122
+ {
123
+ binder: binder,
124
+ scope: scope,
125
+ refkeys: props.refkey,
126
+ flags: OutputSymbolFlags.StaticMemberContainer,
127
+ },
128
+ "enum",
129
+ false,
130
+ );
131
+ const members = props.members ?? [];
132
+ let opener, ender;
133
+ if (members.length && members.every((m) => m.value === undefined)) {
134
+ // List of names: Enum('Direction', ['NORTH', ...])
135
+ opener = "[";
136
+ ender = "]";
137
+ } else {
138
+ // List of name-value pairs: Enum('Direction', {'NORTH': 1, ...})
139
+ opener = "{";
140
+ ender = "}";
141
+ }
142
+ const memberExpr = (
143
+ <>
144
+ {opener}
145
+ <For each={members} joiner=", ">
146
+ {(m) => <EnumMember name={m.name} value={m.value} functional={true} />}
147
+ </For>
148
+ {ender}
149
+ </>
150
+ );
151
+ return (
152
+ <>
153
+ <CoreDeclaration symbol={sym}>
154
+ {sym.name} = {enumModule["."].Enum}('{sym.name}',{" "}
155
+ <MemberScope owner={sym}>
156
+ <Scope name={props.name} kind="enum">
157
+ {memberExpr}
158
+ </Scope>
159
+ </MemberScope>
160
+ )
161
+ </CoreDeclaration>
162
+ </>
163
+ );
164
+ }
165
+
166
+ /**
167
+ * Create a Python enum using the class-based syntax.
168
+ *
169
+ * This generates enums using the `class Name(Enum):` syntax with member definitions
170
+ * inside the class body. Supports various member value styles including auto-generated
171
+ * values, explicit values, and custom base types.
172
+ *
173
+ * @example
174
+ * ```tsx
175
+ * <ClassEnumDeclaration
176
+ * name="Direction"
177
+ * members={[
178
+ * { name: "NORTH" },
179
+ * { name: "SOUTH" },
180
+ * { name: "EAST" },
181
+ * { name: "WEST" }
182
+ * ]}
183
+ * />
184
+ * ```
185
+ * renders to:
186
+ * ```python
187
+ * class Direction(Enum):
188
+ * NORTH = "NORTH"
189
+ * SOUTH = "SOUTH"
190
+ * EAST = "EAST"
191
+ * WEST = "WEST"
192
+ * ```
193
+ *
194
+ * @example
195
+ * With explicit values:
196
+ * ```tsx
197
+ * <ClassEnumDeclaration
198
+ * name="Status"
199
+ * members={[
200
+ * { name: "PENDING", value: 1 },
201
+ * { name: "ACTIVE", value: 2 },
202
+ * { name: "INACTIVE", value: 3 }
203
+ * ]}
204
+ * />
205
+ * ```
206
+ * renders to:
207
+ * ```python
208
+ * class Status(Enum):
209
+ * PENDING = 1
210
+ * ACTIVE = 2
211
+ * INACTIVE = 3
212
+ * ```
213
+ *
214
+ * @example
215
+ * With auto() values:
216
+ * ```tsx
217
+ * <ClassEnumDeclaration
218
+ * name="Color"
219
+ * style="auto"
220
+ * members={[
221
+ * { name: "RED" },
222
+ * { name: "GREEN" },
223
+ * { name: "BLUE" }
224
+ * ]}
225
+ * />
226
+ * ```
227
+ * renders to:
228
+ * ```python
229
+ * class Color(Enum):
230
+ * RED = auto()
231
+ * GREEN = auto()
232
+ * BLUE = auto()
233
+ * ```
234
+ */
235
+ export function ClassEnumDeclaration(props: EnumProps) {
236
+ const baseType = props.baseType || "Enum";
237
+ const binder = useBinder();
238
+ const scope = usePythonScope();
239
+ const sym = createPythonSymbol(
240
+ props.name,
241
+ {
242
+ binder: binder,
243
+ scope: scope,
244
+ refkeys: props.refkey,
245
+ flags: OutputSymbolFlags.StaticMemberContainer,
246
+ },
247
+ "enum",
248
+ false,
249
+ );
250
+ let memberList: Array<{
251
+ name: string;
252
+ value?: Children;
253
+ jsValue?: string | number;
254
+ auto?: boolean;
255
+ doc?: string;
256
+ }> = (props.members ?? []).map((m) =>
257
+ m.value === undefined ? { ...m, auto: false } : m,
258
+ );
259
+ if (props.style === "auto") {
260
+ memberList = memberList.map((m) =>
261
+ m.value === undefined ? { name: m.name, auto: true } : m,
262
+ );
263
+ }
264
+ return (
265
+ <CoreDeclaration symbol={sym}>
266
+ <Show when={Boolean(props.doc)}>
267
+ <SimpleCommentBlock children={props.doc} />
268
+ <hbr />
269
+ </Show>
270
+ class {sym.name}({enumModule["."][baseType]})
271
+ <MemberScope owner={sym}>
272
+ <Scope name={sym.name} kind="enum">
273
+ <PythonBlock opener=":">
274
+ <For each={memberList} hardline>
275
+ {(member) => (
276
+ <EnumMember
277
+ name={member.name}
278
+ value={member.value}
279
+ jsValue={member.jsValue}
280
+ auto={member.auto}
281
+ doc={member.doc}
282
+ />
283
+ )}
284
+ </For>
285
+ {props.children}
286
+ </PythonBlock>
287
+ </Scope>
288
+ </MemberScope>
289
+ </CoreDeclaration>
290
+ );
291
+ }
@@ -0,0 +1,92 @@
1
+ import { Children, OutputSymbolFlags, Refkey, Show } from "@alloy-js/core";
2
+ import { enumModule } from "../builtins/python.js";
3
+ import { createPythonSymbol } from "../symbol-creation.js";
4
+ import { PythonOutputSymbol } from "../symbols/index.js";
5
+ import { Atom } from "./Atom.jsx";
6
+ import { SimpleInlineComment } from "./index.js";
7
+
8
+ export interface EnumMemberProps {
9
+ /**
10
+ * The name of the enum member.
11
+ */
12
+ name: string;
13
+
14
+ /**
15
+ * Refkey for the enum member symbol. If the refkey is not provided, a symbol
16
+ * will be created and the member cannot be referenced by refkey.
17
+ */
18
+ refkey?: Refkey;
19
+
20
+ /**
21
+ * The value of the enum member.
22
+ */
23
+ value?: Children;
24
+
25
+ /**
26
+ * The JS value of the enum member.
27
+ */
28
+ jsValue?: string | number;
29
+
30
+ /**
31
+ * Functional mappings/list
32
+ */
33
+ functional?: boolean;
34
+
35
+ /**
36
+ * Will use auto() to generate the value if set to true.
37
+ */
38
+ auto?: boolean;
39
+
40
+ /**
41
+ * Documentation for the enum member.
42
+ */
43
+ doc?: Children;
44
+ }
45
+
46
+ /**
47
+ * A Python enum member.
48
+ *
49
+ * @example
50
+ * ```tsx
51
+ * <EnumMember name="NORTH" />
52
+ * ```
53
+ * This will generate:
54
+ * ```python
55
+ * NORTH
56
+ * ```
57
+ */
58
+ export function EnumMember(props: EnumMemberProps) {
59
+ const autoReference = props.auto === true ? enumModule["."].auto : undefined;
60
+ const value = props.auto === true ? <>{autoReference}()</> : props.value;
61
+ const sym: PythonOutputSymbol = createPythonSymbol(
62
+ props.name,
63
+ {
64
+ refkeys: props.refkey,
65
+ flags: OutputSymbolFlags.StaticMember,
66
+ },
67
+ "enum-member",
68
+ true,
69
+ );
70
+ const valueCode =
71
+ props.jsValue !== undefined ? <Atom jsValue={props.jsValue} /> : value;
72
+
73
+ if (props.functional) {
74
+ return (
75
+ <>
76
+ '{sym.name}'<Show when={valueCode !== undefined}> : {valueCode}</Show>
77
+ <Show when={props.doc !== undefined}>
78
+ <SimpleInlineComment>{props.doc}</SimpleInlineComment>
79
+ </Show>
80
+ </>
81
+ );
82
+ }
83
+ return (
84
+ <>
85
+ {sym.name}
86
+ <Show when={valueCode !== undefined}> = {valueCode}</Show>
87
+ <Show when={props.doc !== undefined}>
88
+ <SimpleInlineComment>{props.doc}</SimpleInlineComment>
89
+ </Show>
90
+ </>
91
+ );
92
+ }
@@ -0,0 +1,36 @@
1
+ import { Children, For, Indent, Wrap } from "@alloy-js/core";
2
+
3
+ export interface FunctionCallExpressionProps {
4
+ target: Children;
5
+ args?: Children[];
6
+ }
7
+
8
+ /**
9
+ * A Python function call expression.
10
+ *
11
+ * @example
12
+ * ```tsx
13
+ * <FunctionCallExpression target="foo" args={["arg1", "arg2"]} />
14
+ * ```
15
+ * This will generate:
16
+ * ```python
17
+ * foo(arg1, arg2)
18
+ * ```
19
+ */
20
+ export function FunctionCallExpression(props: FunctionCallExpressionProps) {
21
+ return (
22
+ <group>
23
+ {props.target}(
24
+ <Wrap
25
+ when={!!props.args && props.args.length > 1}
26
+ with={Indent}
27
+ props={{ softline: true, trailingBreak: true }}
28
+ >
29
+ <For each={props.args ?? []} comma line>
30
+ {(arg) => arg}
31
+ </For>
32
+ </Wrap>
33
+ )
34
+ </group>
35
+ );
36
+ }