@alloy-js/python 0.4.0-dev.2 → 0.4.0-dev.5

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 (258) hide show
  1. package/dist/dev/src/builtins/python.js +30 -0
  2. package/dist/dev/src/builtins/python.js.map +1 -0
  3. package/dist/dev/src/components/Atom.js +122 -0
  4. package/dist/dev/src/components/Atom.js.map +1 -0
  5. package/dist/dev/src/components/CallSignature.js +195 -0
  6. package/dist/dev/src/components/CallSignature.js.map +1 -0
  7. package/dist/dev/src/components/ClassDeclaration.js +112 -0
  8. package/dist/dev/src/components/ClassDeclaration.js.map +1 -0
  9. package/dist/dev/src/components/ClassInstantiation.js +40 -0
  10. package/dist/dev/src/components/ClassInstantiation.js.map +1 -0
  11. package/dist/dev/src/components/ClassMethodDeclaration.js +40 -0
  12. package/dist/dev/src/components/ClassMethodDeclaration.js.map +1 -0
  13. package/dist/dev/src/components/ConstructorDeclaration.js +39 -0
  14. package/dist/dev/src/components/ConstructorDeclaration.js.map +1 -0
  15. package/dist/dev/src/components/DataclassDeclaration.js +177 -0
  16. package/dist/dev/src/components/DataclassDeclaration.js.map +1 -0
  17. package/dist/dev/src/components/Declaration.js +31 -0
  18. package/dist/dev/src/components/Declaration.js.map +1 -0
  19. package/dist/dev/src/components/DunderMethodDeclaration.js +33 -0
  20. package/dist/dev/src/components/DunderMethodDeclaration.js.map +1 -0
  21. package/dist/dev/src/components/EnumDeclaration.js +259 -0
  22. package/dist/dev/src/components/EnumDeclaration.js.map +1 -0
  23. package/dist/dev/src/components/EnumMember.js +95 -0
  24. package/dist/dev/src/components/EnumMember.js.map +1 -0
  25. package/dist/dev/src/components/FunctionBase.js +130 -0
  26. package/dist/dev/src/components/FunctionBase.js.map +1 -0
  27. package/dist/dev/src/components/FunctionCallExpression.js +53 -0
  28. package/dist/dev/src/components/FunctionCallExpression.js.map +1 -0
  29. package/dist/dev/src/components/FunctionDeclaration.js +45 -0
  30. package/dist/dev/src/components/FunctionDeclaration.js.map +1 -0
  31. package/dist/dev/src/components/FutureStatement.js +31 -0
  32. package/dist/dev/src/components/FutureStatement.js.map +1 -0
  33. package/dist/dev/src/components/ImportStatement.js +167 -0
  34. package/dist/dev/src/components/ImportStatement.js.map +1 -0
  35. package/dist/dev/src/components/LexicalScope.js +26 -0
  36. package/dist/dev/src/components/LexicalScope.js.map +1 -0
  37. package/dist/dev/src/components/MemberExpression.js +290 -0
  38. package/dist/dev/src/components/MemberExpression.js.map +1 -0
  39. package/dist/dev/src/components/MemberScope.js +23 -0
  40. package/dist/dev/src/components/MemberScope.js.map +1 -0
  41. package/dist/dev/src/components/MethodBase.js +40 -0
  42. package/dist/dev/src/components/MethodBase.js.map +1 -0
  43. package/dist/dev/src/components/MethodDeclaration.js +38 -0
  44. package/dist/dev/src/components/MethodDeclaration.js.map +1 -0
  45. package/dist/dev/src/components/PropertyDeclaration.js +287 -0
  46. package/dist/dev/src/components/PropertyDeclaration.js.map +1 -0
  47. package/dist/dev/src/components/PyDoc.js +1478 -0
  48. package/dist/dev/src/components/PyDoc.js.map +1 -0
  49. package/dist/dev/src/components/PythonBlock.js +35 -0
  50. package/dist/dev/src/components/PythonBlock.js.map +1 -0
  51. package/dist/dev/src/components/Reference.js +23 -0
  52. package/dist/dev/src/components/Reference.js.map +1 -0
  53. package/dist/dev/src/components/SourceFile.js +385 -0
  54. package/dist/dev/src/components/SourceFile.js.map +1 -0
  55. package/dist/dev/src/components/StatementList.js +34 -0
  56. package/dist/dev/src/components/StatementList.js.map +1 -0
  57. package/dist/dev/src/components/StaticMethodDeclaration.js +40 -0
  58. package/dist/dev/src/components/StaticMethodDeclaration.js.map +1 -0
  59. package/dist/dev/src/components/TypeArguments.js +22 -0
  60. package/dist/dev/src/components/TypeArguments.js.map +1 -0
  61. package/dist/dev/src/components/TypeRefContext.js +33 -0
  62. package/dist/dev/src/components/TypeRefContext.js.map +1 -0
  63. package/dist/dev/src/components/TypeReference.js +67 -0
  64. package/dist/dev/src/components/TypeReference.js.map +1 -0
  65. package/dist/dev/src/components/UnionTypeExpression.js +57 -0
  66. package/dist/dev/src/components/UnionTypeExpression.js.map +1 -0
  67. package/dist/dev/src/components/VariableDeclaration.js +150 -0
  68. package/dist/dev/src/components/VariableDeclaration.js.map +1 -0
  69. package/dist/dev/src/components/index.js +32 -0
  70. package/dist/dev/src/components/index.js.map +1 -0
  71. package/dist/dev/src/context/index.js +2 -0
  72. package/dist/dev/src/context/index.js.map +1 -0
  73. package/dist/dev/src/context/type-ref-context.js +17 -0
  74. package/dist/dev/src/context/type-ref-context.js.map +1 -0
  75. package/dist/dev/src/create-module.js +64 -0
  76. package/dist/dev/src/create-module.js.map +1 -0
  77. package/dist/dev/src/index.js +8 -0
  78. package/dist/dev/src/index.js.map +1 -0
  79. package/dist/dev/src/name-conflict-resolver.js +8 -0
  80. package/dist/dev/src/name-conflict-resolver.js.map +1 -0
  81. package/dist/dev/src/name-policy.js +48 -0
  82. package/dist/dev/src/name-policy.js.map +1 -0
  83. package/dist/dev/src/parameter-descriptor.js +8 -0
  84. package/dist/dev/src/parameter-descriptor.js.map +1 -0
  85. package/dist/dev/src/symbol-creation.js +58 -0
  86. package/dist/dev/src/symbol-creation.js.map +1 -0
  87. package/dist/dev/src/symbols/factories.js +28 -0
  88. package/dist/dev/src/symbols/factories.js.map +1 -0
  89. package/dist/dev/src/symbols/index.js +8 -0
  90. package/dist/dev/src/symbols/index.js.map +1 -0
  91. package/dist/dev/src/symbols/python-lexical-scope.js +15 -0
  92. package/dist/dev/src/symbols/python-lexical-scope.js.map +1 -0
  93. package/dist/dev/src/symbols/python-member-scope.js +7 -0
  94. package/dist/dev/src/symbols/python-member-scope.js.map +1 -0
  95. package/dist/dev/src/symbols/python-module-scope.js +86 -0
  96. package/dist/dev/src/symbols/python-module-scope.js.map +1 -0
  97. package/dist/dev/src/symbols/python-output-symbol.js +73 -0
  98. package/dist/dev/src/symbols/python-output-symbol.js.map +1 -0
  99. package/dist/dev/src/symbols/reference.js +87 -0
  100. package/dist/dev/src/symbols/reference.js.map +1 -0
  101. package/dist/dev/src/symbols/scopes.js +13 -0
  102. package/dist/dev/src/symbols/scopes.js.map +1 -0
  103. package/dist/dev/src/utils.js +13 -0
  104. package/dist/dev/src/utils.js.map +1 -0
  105. package/dist/dev/test/callsignatures.test.js +482 -0
  106. package/dist/dev/test/callsignatures.test.js.map +1 -0
  107. package/dist/dev/test/class-method-declaration.test.js +85 -0
  108. package/dist/dev/test/class-method-declaration.test.js.map +1 -0
  109. package/dist/dev/test/classdeclarations.test.js +654 -0
  110. package/dist/dev/test/classdeclarations.test.js.map +1 -0
  111. package/dist/dev/test/classinstantiations.test.js +281 -0
  112. package/dist/dev/test/classinstantiations.test.js.map +1 -0
  113. package/dist/dev/test/constructordeclaration.test.js +86 -0
  114. package/dist/dev/test/constructordeclaration.test.js.map +1 -0
  115. package/dist/dev/test/dataclassdeclarations.test.js +1068 -0
  116. package/dist/dev/test/dataclassdeclarations.test.js.map +1 -0
  117. package/dist/dev/test/dundermethoddeclaration.test.js +93 -0
  118. package/dist/dev/test/dundermethoddeclaration.test.js.map +1 -0
  119. package/dist/dev/test/enums.test.js +263 -0
  120. package/dist/dev/test/enums.test.js.map +1 -0
  121. package/dist/dev/test/externals.test.js +307 -0
  122. package/dist/dev/test/externals.test.js.map +1 -0
  123. package/dist/dev/test/factories.test.js +122 -0
  124. package/dist/dev/test/factories.test.js.map +1 -0
  125. package/dist/dev/test/functioncallexpressions.test.js +257 -0
  126. package/dist/dev/test/functioncallexpressions.test.js.map +1 -0
  127. package/dist/dev/test/functiondeclaration.test.js +817 -0
  128. package/dist/dev/test/functiondeclaration.test.js.map +1 -0
  129. package/dist/dev/test/imports.test.js +372 -0
  130. package/dist/dev/test/imports.test.js.map +1 -0
  131. package/dist/dev/test/memberexpressions.test.js +1668 -0
  132. package/dist/dev/test/memberexpressions.test.js.map +1 -0
  133. package/dist/dev/test/methoddeclaration.test.js +344 -0
  134. package/dist/dev/test/methoddeclaration.test.js.map +1 -0
  135. package/dist/dev/test/namepolicies.test.js +154 -0
  136. package/dist/dev/test/namepolicies.test.js.map +1 -0
  137. package/dist/dev/test/propertydeclaration.test.js +354 -0
  138. package/dist/dev/test/propertydeclaration.test.js.map +1 -0
  139. package/dist/dev/test/pydocs.test.js +1675 -0
  140. package/dist/dev/test/pydocs.test.js.map +1 -0
  141. package/dist/dev/test/references.test.js +66 -0
  142. package/dist/dev/test/references.test.js.map +1 -0
  143. package/dist/dev/test/sourcefiles.test.js +1802 -0
  144. package/dist/dev/test/sourcefiles.test.js.map +1 -0
  145. package/dist/dev/test/staticmethoddeclaration.test.js +85 -0
  146. package/dist/dev/test/staticmethoddeclaration.test.js.map +1 -0
  147. package/dist/dev/test/type-checking-imports.test.js +617 -0
  148. package/dist/dev/test/type-checking-imports.test.js.map +1 -0
  149. package/dist/dev/test/typereference.test.js +79 -0
  150. package/dist/dev/test/typereference.test.js.map +1 -0
  151. package/dist/dev/test/uniontypeexpression.test.js +307 -0
  152. package/dist/dev/test/uniontypeexpression.test.js.map +1 -0
  153. package/dist/dev/test/utils.js +100 -0
  154. package/dist/dev/test/utils.js.map +1 -0
  155. package/dist/dev/test/values.test.js +182 -0
  156. package/dist/dev/test/values.test.js.map +1 -0
  157. package/dist/dev/test/variables.test.js +363 -0
  158. package/dist/dev/test/variables.test.js.map +1 -0
  159. package/dist/src/components/CallSignature.d.ts.map +1 -1
  160. package/dist/src/components/CallSignature.js +12 -3
  161. package/dist/src/components/CallSignature.js.map +1 -1
  162. package/dist/src/components/ImportStatement.d.ts +12 -0
  163. package/dist/src/components/ImportStatement.d.ts.map +1 -1
  164. package/dist/src/components/ImportStatement.js +47 -5
  165. package/dist/src/components/ImportStatement.js.map +1 -1
  166. package/dist/src/components/MemberExpression.d.ts +1 -1
  167. package/dist/src/components/MemberExpression.d.ts.map +1 -1
  168. package/dist/src/components/MemberExpression.js +98 -180
  169. package/dist/src/components/MemberExpression.js.map +1 -1
  170. package/dist/src/components/Reference.d.ts.map +1 -1
  171. package/dist/src/components/Reference.js +5 -1
  172. package/dist/src/components/Reference.js.map +1 -1
  173. package/dist/src/components/SourceFile.d.ts +1 -1
  174. package/dist/src/components/SourceFile.d.ts.map +1 -1
  175. package/dist/src/components/SourceFile.js +46 -7
  176. package/dist/src/components/SourceFile.js.map +1 -1
  177. package/dist/src/components/TypeRefContext.d.ts +26 -0
  178. package/dist/src/components/TypeRefContext.d.ts.map +1 -0
  179. package/dist/src/components/TypeRefContext.js +29 -0
  180. package/dist/src/components/TypeRefContext.js.map +1 -0
  181. package/dist/src/components/TypeReference.d.ts +5 -0
  182. package/dist/src/components/TypeReference.d.ts.map +1 -1
  183. package/dist/src/components/TypeReference.js +19 -9
  184. package/dist/src/components/TypeReference.js.map +1 -1
  185. package/dist/src/components/VariableDeclaration.d.ts.map +1 -1
  186. package/dist/src/components/VariableDeclaration.js +7 -2
  187. package/dist/src/components/VariableDeclaration.js.map +1 -1
  188. package/dist/src/components/index.d.ts +1 -1
  189. package/dist/src/components/index.d.ts.map +1 -1
  190. package/dist/src/components/index.js +1 -1
  191. package/dist/src/components/index.js.map +1 -1
  192. package/dist/src/context/index.d.ts +2 -0
  193. package/dist/src/context/index.d.ts.map +1 -0
  194. package/dist/src/context/index.js +2 -0
  195. package/dist/src/context/index.js.map +1 -0
  196. package/dist/src/context/type-ref-context.d.ts +13 -0
  197. package/dist/src/context/type-ref-context.d.ts.map +1 -0
  198. package/dist/src/context/type-ref-context.js +17 -0
  199. package/dist/src/context/type-ref-context.js.map +1 -0
  200. package/dist/src/symbols/python-module-scope.d.ts +13 -1
  201. package/dist/src/symbols/python-module-scope.d.ts.map +1 -1
  202. package/dist/src/symbols/python-module-scope.js +36 -2
  203. package/dist/src/symbols/python-module-scope.js.map +1 -1
  204. package/dist/src/symbols/python-output-symbol.d.ts +11 -0
  205. package/dist/src/symbols/python-output-symbol.d.ts.map +1 -1
  206. package/dist/src/symbols/python-output-symbol.js +26 -2
  207. package/dist/src/symbols/python-output-symbol.js.map +1 -1
  208. package/dist/src/symbols/reference.d.ts +8 -1
  209. package/dist/src/symbols/reference.d.ts.map +1 -1
  210. package/dist/src/symbols/reference.js +4 -2
  211. package/dist/src/symbols/reference.js.map +1 -1
  212. package/dist/test/dataclassdeclarations.test.js +5 -2
  213. package/dist/test/dataclassdeclarations.test.js.map +1 -1
  214. package/dist/test/externals.test.js +8 -2
  215. package/dist/test/externals.test.js.map +1 -1
  216. package/dist/test/functiondeclaration.test.js +6 -3
  217. package/dist/test/functiondeclaration.test.js.map +1 -1
  218. package/dist/test/imports.test.js +3 -3
  219. package/dist/test/imports.test.js.map +1 -1
  220. package/dist/test/references.test.js +1 -1
  221. package/dist/test/references.test.js.map +1 -1
  222. package/dist/test/sourcefiles.test.js +26 -26
  223. package/dist/test/sourcefiles.test.js.map +1 -1
  224. package/dist/test/type-checking-imports.test.d.ts +2 -0
  225. package/dist/test/type-checking-imports.test.d.ts.map +1 -0
  226. package/dist/test/type-checking-imports.test.js +437 -0
  227. package/dist/test/type-checking-imports.test.js.map +1 -0
  228. package/dist/test/uniontypeexpression.test.js +4 -1
  229. package/dist/test/uniontypeexpression.test.js.map +1 -1
  230. package/dist/test/variables.test.js +4 -1
  231. package/dist/test/variables.test.js.map +1 -1
  232. package/dist/tsconfig.tsbuildinfo +1 -1
  233. package/package.json +6 -4
  234. package/src/components/CallSignature.tsx +6 -2
  235. package/src/components/ImportStatement.tsx +52 -5
  236. package/src/components/MemberExpression.tsx +174 -298
  237. package/src/components/Reference.tsx +3 -1
  238. package/src/components/SourceFile.tsx +44 -8
  239. package/src/components/TypeRefContext.tsx +36 -0
  240. package/src/components/TypeReference.tsx +15 -7
  241. package/src/components/VariableDeclaration.tsx +5 -1
  242. package/src/components/index.ts +1 -1
  243. package/src/context/index.ts +1 -0
  244. package/src/context/type-ref-context.tsx +16 -0
  245. package/src/symbols/python-module-scope.ts +55 -2
  246. package/src/symbols/python-output-symbol.ts +32 -1
  247. package/src/symbols/reference.tsx +10 -0
  248. package/temp/api.json +443 -338
  249. package/test/dataclassdeclarations.test.tsx +8 -2
  250. package/test/externals.test.tsx +8 -2
  251. package/test/functiondeclaration.test.tsx +6 -3
  252. package/test/imports.test.tsx +6 -6
  253. package/test/references.test.tsx +1 -1
  254. package/test/sourcefiles.test.tsx +13 -13
  255. package/test/type-checking-imports.test.tsx +363 -0
  256. package/test/uniontypeexpression.test.tsx +4 -1
  257. package/test/variables.test.tsx +4 -1
  258. package/vitest.config.ts +8 -0
@@ -0,0 +1,1675 @@
1
+ import { createComponent as _$createComponent } from "@alloy-js/core/jsx-runtime";
2
+ import { Prose } from "@alloy-js/core";
3
+ import { d } from "@alloy-js/core/testing";
4
+ import { describe, expect, it } from "vitest";
5
+ import { enumModule } from "../src/builtins/python.js";
6
+ import * as py from "../src/index.js";
7
+ import { assertFileContents, toSourceText, toSourceTextMultiple } from "./utils.js";
8
+ describe("PyDoc", () => {
9
+ it("formats properly", () => {
10
+ const res = toSourceText([_$createComponent(py.PyDoc, {
11
+ get children() {
12
+ return [_$createComponent(Prose, {
13
+ children: "This is an example of a long docstring that will be broken in lines. We will also render another paragraph after this one."
14
+ }, {
15
+ fileName: import.meta.url,
16
+ lineNumber: 17,
17
+ columnNumber: 11
18
+ }), _$createComponent(Prose, {
19
+ children: "This is another paragraph, and there's a line break before it."
20
+ }, {
21
+ fileName: import.meta.url,
22
+ lineNumber: 21,
23
+ columnNumber: 11
24
+ })];
25
+ }
26
+ }, {
27
+ fileName: import.meta.url,
28
+ lineNumber: 16,
29
+ columnNumber: 9
30
+ })], {
31
+ printOptions: {
32
+ printWidth: 40
33
+ }
34
+ });
35
+ expect(res).toRenderTo(d`
36
+ """
37
+ This is an example of a long docstring
38
+ that will be broken in lines. We will
39
+ also render another paragraph after this
40
+ one.
41
+
42
+ This is another paragraph, and there's a
43
+ line break before it.
44
+ """
45
+
46
+
47
+ `);
48
+ });
49
+ });
50
+ describe("PyDocExample", () => {
51
+ it("creates docstring with a code sample", () => {
52
+ const res = toSourceText([_$createComponent(py.PyDoc, {
53
+ get children() {
54
+ return [_$createComponent(Prose, {
55
+ children: "This is an example of a docstring with a code sample."
56
+ }, {
57
+ fileName: import.meta.url,
58
+ lineNumber: 52,
59
+ columnNumber: 11
60
+ }), _$createComponent(py.PyDocExample, {
61
+ children: "print(\"Hello world!\")"
62
+ }, {
63
+ fileName: import.meta.url,
64
+ lineNumber: 53,
65
+ columnNumber: 11
66
+ })];
67
+ }
68
+ }, {
69
+ fileName: import.meta.url,
70
+ lineNumber: 51,
71
+ columnNumber: 9
72
+ })], {
73
+ printOptions: {
74
+ printWidth: 40
75
+ }
76
+ });
77
+ expect(res).toRenderTo(d`
78
+ """
79
+ This is an example of a docstring with a
80
+ code sample.
81
+
82
+ >> print("Hello world!")
83
+ """
84
+
85
+
86
+ `);
87
+ });
88
+ it("creates docstring with more than one code sample", () => {
89
+ const res = toSourceText([_$createComponent(py.PyDoc, {
90
+ get children() {
91
+ return [_$createComponent(Prose, {
92
+ children: "This is an example of a docstring with a code sample."
93
+ }, {
94
+ fileName: import.meta.url,
95
+ lineNumber: 77,
96
+ columnNumber: 11
97
+ }), _$createComponent(py.PyDocExample, {
98
+ children: "print(\"Hello world!\")"
99
+ }, {
100
+ fileName: import.meta.url,
101
+ lineNumber: 78,
102
+ columnNumber: 11
103
+ }), _$createComponent(py.PyDocExample, {
104
+ children: "print(\"Hello world again!\")"
105
+ }, {
106
+ fileName: import.meta.url,
107
+ lineNumber: 79,
108
+ columnNumber: 11
109
+ })];
110
+ }
111
+ }, {
112
+ fileName: import.meta.url,
113
+ lineNumber: 76,
114
+ columnNumber: 9
115
+ })], {
116
+ printOptions: {
117
+ printWidth: 40
118
+ }
119
+ });
120
+ expect(res).toRenderTo(d`
121
+ """
122
+ This is an example of a docstring with a
123
+ code sample.
124
+
125
+ >> print("Hello world!")
126
+
127
+ >> print("Hello world again!")
128
+ """
129
+
130
+
131
+ `);
132
+ });
133
+ it("creates docstring with a multiline code sample", () => {
134
+ const res = toSourceText([_$createComponent(py.PyDoc, {
135
+ get children() {
136
+ return [_$createComponent(Prose, {
137
+ children: "This is an example of a docstring with a code sample."
138
+ }, {
139
+ fileName: import.meta.url,
140
+ lineNumber: 105,
141
+ columnNumber: 11
142
+ }), _$createComponent(py.PyDocExample, {
143
+ children: `print("Hello world!")\nx = "Hello"\nprint(x)`
144
+ }, {
145
+ fileName: import.meta.url,
146
+ lineNumber: 106,
147
+ columnNumber: 11
148
+ })];
149
+ }
150
+ }, {
151
+ fileName: import.meta.url,
152
+ lineNumber: 104,
153
+ columnNumber: 9
154
+ })], {
155
+ printOptions: {
156
+ printWidth: 40
157
+ }
158
+ });
159
+ expect(res).toRenderTo(d`
160
+ """
161
+ This is an example of a docstring with a
162
+ code sample.
163
+
164
+ >> print("Hello world!")
165
+ >> x = "Hello"
166
+ >> print(x)
167
+ """
168
+
169
+
170
+ `);
171
+ });
172
+ });
173
+ describe("SimpleCommentBlock", () => {
174
+ it("renders simple comment block", () => {
175
+ const res = toSourceText([_$createComponent(py.SimpleCommentBlock, {
176
+ children: "This is a simple comment block that spans multiple lines and should be split automatically."
177
+ }, {
178
+ fileName: import.meta.url,
179
+ lineNumber: 134,
180
+ columnNumber: 7
181
+ })]);
182
+ expect(res).toRenderTo(d`
183
+ # This is a simple comment block that spans multiple lines and should be split
184
+ # automatically.
185
+
186
+ `);
187
+ });
188
+ it("renders comment block with line breaks", () => {
189
+ const res = toSourceText([_$createComponent(py.SimpleCommentBlock, {
190
+ children: "First line of comment.\\nSecond line of comment."
191
+ }, {
192
+ fileName: import.meta.url,
193
+ lineNumber: 150,
194
+ columnNumber: 7
195
+ })]);
196
+ expect(res).toRenderTo(d`
197
+ # First line of comment.
198
+ # Second line of comment.
199
+
200
+ `);
201
+ });
202
+ });
203
+ describe("SimpleInlineComment", () => {
204
+ it("renders inline comment", () => {
205
+ const res = toSourceText([["x = 42", _$createComponent(py.SimpleInlineComment, {
206
+ children: "This is an inline comment"
207
+ }, {
208
+ fileName: import.meta.url,
209
+ lineNumber: 169,
210
+ columnNumber: 9
211
+ })]]);
212
+ expect(res).toRenderTo(d`
213
+ x = 42 # This is an inline comment
214
+ `);
215
+ });
216
+ it("renders inline comment with complex text", () => {
217
+ const res = toSourceText([["result = calculate()", _$createComponent(py.SimpleInlineComment, {
218
+ children: "TODO: Add error handling here"
219
+ }, {
220
+ fileName: import.meta.url,
221
+ lineNumber: 185,
222
+ columnNumber: 9
223
+ })]]);
224
+ expect(res).toRenderTo(d`
225
+ result = calculate() # TODO: Add error handling here
226
+ `);
227
+ });
228
+ });
229
+ describe("New Documentation Components", () => {
230
+ it("ModuleDoc renders correctly", () => {
231
+ const res = toSourceText([_$createComponent(py.ModuleDoc, {
232
+ get description() {
233
+ return [_$createComponent(Prose, {
234
+ children: "This module demonstrates documentation as specified by the Google Python Style Guide."
235
+ }, {
236
+ fileName: import.meta.url,
237
+ lineNumber: 203,
238
+ columnNumber: 11
239
+ })];
240
+ },
241
+ attributes: [{
242
+ name: "module_level_variable1",
243
+ type: "int",
244
+ children: "Module level variables may be documented."
245
+ }],
246
+ get examples() {
247
+ return [_$createComponent(py.PyDocExample, {
248
+ children: "print(\"mod\")"
249
+ }, {
250
+ fileName: import.meta.url,
251
+ lineNumber: 215,
252
+ columnNumber: 20
253
+ })];
254
+ },
255
+ seeAlso: ["another_module.func", "RelatedClass"],
256
+ warning: "Internal API.",
257
+ deprecated: "Use new_module instead.",
258
+ todo: ["For module TODOs", "You have to also use sphinx.ext.todo extension"]
259
+ }, {
260
+ fileName: import.meta.url,
261
+ lineNumber: 201,
262
+ columnNumber: 7
263
+ })]);
264
+ expect(res).toRenderTo(d`
265
+ """
266
+ This module demonstrates documentation as specified by the Google Python Style
267
+ Guide.
268
+
269
+ Attributes:
270
+ module_level_variable1 (int): Module level variables may be documented.
271
+
272
+ Examples:
273
+ >> print("mod")
274
+
275
+ See Also:
276
+ another_module.func
277
+ RelatedClass
278
+
279
+ Warning:
280
+ Internal API.
281
+
282
+ Deprecated:
283
+ Use new_module instead.
284
+
285
+ Todo:
286
+ * For module TODOs
287
+ * You have to also use sphinx.ext.todo extension
288
+ """
289
+
290
+
291
+ `);
292
+ });
293
+ it("PropertyDoc renders correctly", () => {
294
+ const res = toSourceText([_$createComponent(py.PropertyDoc, {
295
+ get description() {
296
+ return [_$createComponent(Prose, {
297
+ children: "Properties should be documented in their getter method."
298
+ }, {
299
+ fileName: import.meta.url,
300
+ lineNumber: 262,
301
+ columnNumber: 11
302
+ })];
303
+ },
304
+ returns: "str: The readonly property value.",
305
+ get examples() {
306
+ return [_$createComponent(py.PyDocExample, {
307
+ children: "print(obj.name)"
308
+ }, {
309
+ fileName: import.meta.url,
310
+ lineNumber: 267,
311
+ columnNumber: 20
312
+ })];
313
+ },
314
+ seeAlso: ["other_property"],
315
+ warning: "Access may be slow.",
316
+ deprecated: "Use full_name instead.",
317
+ note: "If the setter method contains notable behavior, it should be mentioned here."
318
+ }, {
319
+ fileName: import.meta.url,
320
+ lineNumber: 260,
321
+ columnNumber: 7
322
+ })]);
323
+ expect(res).toRenderTo(d`
324
+ """
325
+ Properties should be documented in their getter method.
326
+
327
+ Returns:
328
+ str: The readonly property value.
329
+
330
+ Examples:
331
+ >> print(obj.name)
332
+
333
+ See Also:
334
+ other_property
335
+
336
+ Warning:
337
+ Access may be slow.
338
+
339
+ Deprecated:
340
+ Use full_name instead.
341
+
342
+ Note:
343
+ If the setter method contains notable behavior, it should be mentioned here.
344
+ """
345
+
346
+
347
+ `);
348
+ });
349
+ it("GeneratorDoc renders correctly", () => {
350
+ const res = toSourceText([_$createComponent(py.GeneratorDoc, {
351
+ get description() {
352
+ return [_$createComponent(Prose, {
353
+ children: "Generators have a Yields section instead of a Returns section."
354
+ }, {
355
+ fileName: import.meta.url,
356
+ lineNumber: 308,
357
+ columnNumber: 11
358
+ })];
359
+ },
360
+ parameters: [{
361
+ name: "n",
362
+ type: "int",
363
+ doc: "The upper limit of the range to generate, from 0 to n - 1."
364
+ }],
365
+ yields: "int: The next number in the range of 0 to n - 1.",
366
+ get examples() {
367
+ return [_$createComponent(py.PyDocExample, {
368
+ children: "print(next(gen))"
369
+ }, {
370
+ fileName: import.meta.url,
371
+ lineNumber: 320,
372
+ columnNumber: 20
373
+ })];
374
+ },
375
+ seeAlso: ["make_generator"],
376
+ warning: "Do not consume in tight loops without sleep.",
377
+ deprecated: "Use new_generator instead.",
378
+ note: "Examples should be written in doctest format."
379
+ }, {
380
+ fileName: import.meta.url,
381
+ lineNumber: 306,
382
+ columnNumber: 7
383
+ })]);
384
+ expect(res).toRenderTo(d`
385
+ """
386
+ Generators have a Yields section instead of a Returns section.
387
+
388
+ Args:
389
+ n (int): The upper limit of the range to generate, from 0 to n - 1.
390
+
391
+ Yields:
392
+ int: The next number in the range of 0 to n - 1.
393
+
394
+ Examples:
395
+ >> print(next(gen))
396
+
397
+ See Also:
398
+ make_generator
399
+
400
+ Warning:
401
+ Do not consume in tight loops without sleep.
402
+
403
+ Deprecated:
404
+ Use new_generator instead.
405
+
406
+ Note:
407
+ Examples should be written in doctest format.
408
+ """
409
+
410
+
411
+ `);
412
+ });
413
+ it("ExceptionDoc renders correctly", () => {
414
+ const res = toSourceText([_$createComponent(py.ExceptionDoc, {
415
+ get description() {
416
+ return [_$createComponent(Prose, {
417
+ children: "Exceptions are documented in the same way as classes."
418
+ }, {
419
+ fileName: import.meta.url,
420
+ lineNumber: 364,
421
+ columnNumber: 11
422
+ })];
423
+ },
424
+ parameters: [{
425
+ name: "msg",
426
+ type: "str",
427
+ doc: "Human readable string describing the exception."
428
+ }, {
429
+ name: "code",
430
+ type: "int",
431
+ default: undefined,
432
+ doc: "Error code."
433
+ }],
434
+ attributes: [{
435
+ name: "msg",
436
+ type: "str",
437
+ children: "Human readable string describing the exception."
438
+ }, {
439
+ name: "code",
440
+ type: "int",
441
+ children: "Exception error code."
442
+ }],
443
+ seeAlso: ["BaseException"],
444
+ deprecated: "Use NewException instead.",
445
+ note: "Do not include the 'self' parameter in the Args section."
446
+ }, {
447
+ fileName: import.meta.url,
448
+ lineNumber: 362,
449
+ columnNumber: 7
450
+ })]);
451
+ expect(res).toRenderTo(d`
452
+ """
453
+ Exceptions are documented in the same way as classes.
454
+
455
+ Args:
456
+ msg (str): Human readable string describing the exception.
457
+
458
+ code (int): Error code.
459
+
460
+ Attributes:
461
+ msg (str): Human readable string describing the exception.
462
+
463
+ code (int): Exception error code.
464
+
465
+ See Also:
466
+ BaseException
467
+
468
+ Deprecated:
469
+ Use NewException instead.
470
+
471
+ Note:
472
+ Do not include the 'self' parameter in the Args section.
473
+ """
474
+
475
+
476
+ `);
477
+ });
478
+ it("MethodDoc renders correctly without default note", () => {
479
+ const res = toSourceText([_$createComponent(py.MethodDoc, {
480
+ get description() {
481
+ return [_$createComponent(Prose, {
482
+ children: "Class methods are similar to regular functions."
483
+ }, {
484
+ fileName: import.meta.url,
485
+ lineNumber: 431,
486
+ columnNumber: 11
487
+ })];
488
+ },
489
+ parameters: [{
490
+ name: "param1",
491
+ doc: "The first parameter."
492
+ }, {
493
+ name: "param2",
494
+ doc: "The second parameter."
495
+ }],
496
+ returns: "True if successful, False otherwise.",
497
+ overrides: "Base.method"
498
+ }, {
499
+ fileName: import.meta.url,
500
+ lineNumber: 429,
501
+ columnNumber: 7
502
+ })]);
503
+ expect(res).toRenderTo(d`
504
+ """
505
+ Class methods are similar to regular functions.
506
+
507
+ Args:
508
+ param1: The first parameter.
509
+
510
+ param2: The second parameter.
511
+
512
+ Returns:
513
+ True if successful, False otherwise.
514
+
515
+ Overrides:
516
+ Base.method
517
+ """
518
+
519
+
520
+ `);
521
+ });
522
+ it("MethodDoc renders correctly with custom note", () => {
523
+ const res = toSourceText([_$createComponent(py.MethodDoc, {
524
+ get description() {
525
+ return [_$createComponent(Prose, {
526
+ children: "Class methods are similar to regular functions."
527
+ }, {
528
+ fileName: import.meta.url,
529
+ lineNumber: 474,
530
+ columnNumber: 11
531
+ })];
532
+ },
533
+ parameters: [{
534
+ name: "param1",
535
+ doc: "The first parameter."
536
+ }],
537
+ returns: "True if successful, False otherwise.",
538
+ note: "This method has special behavior when called multiple times."
539
+ }, {
540
+ fileName: import.meta.url,
541
+ lineNumber: 472,
542
+ columnNumber: 7
543
+ })]);
544
+ expect(res).toRenderTo(d`
545
+ """
546
+ Class methods are similar to regular functions.
547
+
548
+ Args:
549
+ param1: The first parameter.
550
+
551
+ Returns:
552
+ True if successful, False otherwise.
553
+
554
+ Note:
555
+ This method has special behavior when called multiple times.
556
+ """
557
+
558
+
559
+ `);
560
+ });
561
+ it("ModuleDoc with minimal content", () => {
562
+ const res = toSourceText([_$createComponent(py.ModuleDoc, {
563
+ get description() {
564
+ return [_$createComponent(Prose, {
565
+ children: "Simple module description."
566
+ }, {
567
+ fileName: import.meta.url,
568
+ lineNumber: 510,
569
+ columnNumber: 23
570
+ })];
571
+ }
572
+ }, {
573
+ fileName: import.meta.url,
574
+ lineNumber: 509,
575
+ columnNumber: 7
576
+ })]);
577
+ expect(res).toRenderTo(d`
578
+ """
579
+ Simple module description.
580
+ """
581
+
582
+
583
+ `);
584
+ });
585
+ it("ModuleDoc with only todo items", () => {
586
+ const res = toSourceText([_$createComponent(py.ModuleDoc, {
587
+ get description() {
588
+ return [_$createComponent(Prose, {
589
+ children: "Module with pending tasks."
590
+ }, {
591
+ fileName: import.meta.url,
592
+ lineNumber: 528,
593
+ columnNumber: 23
594
+ })];
595
+ },
596
+ todo: ["Implement feature X", "Add more tests", "Update documentation"]
597
+ }, {
598
+ fileName: import.meta.url,
599
+ lineNumber: 527,
600
+ columnNumber: 7
601
+ })]);
602
+ expect(res).toRenderTo(d`
603
+ """
604
+ Module with pending tasks.
605
+
606
+ Todo:
607
+ * Implement feature X
608
+ * Add more tests
609
+ * Update documentation
610
+ """
611
+
612
+
613
+ `);
614
+ });
615
+ it("PropertyDoc minimal (description only)", () => {
616
+ const res = toSourceText([_$createComponent(py.PropertyDoc, {
617
+ get description() {
618
+ return [_$createComponent(Prose, {
619
+ children: "A simple readonly property."
620
+ }, {
621
+ fileName: import.meta.url,
622
+ lineNumber: 552,
623
+ columnNumber: 23
624
+ })];
625
+ }
626
+ }, {
627
+ fileName: import.meta.url,
628
+ lineNumber: 551,
629
+ columnNumber: 7
630
+ })]);
631
+ expect(res).toRenderTo(d`
632
+ """
633
+ A simple readonly property.
634
+ """
635
+
636
+
637
+ `);
638
+ });
639
+ it("PropertyDoc with getter and setter info", () => {
640
+ const res = toSourceText([_$createComponent(py.PropertyDoc, {
641
+ get description() {
642
+ return [_$createComponent(Prose, {
643
+ children: "Properties with both a getter and setter should only be documented in their getter method."
644
+ }, {
645
+ fileName: import.meta.url,
646
+ lineNumber: 571,
647
+ columnNumber: 11
648
+ })];
649
+ },
650
+ returns: ":obj:`list` of :obj:`str`: The property value.",
651
+ note: "If the setter method contains notable behavior, it should be mentioned here."
652
+ }, {
653
+ fileName: import.meta.url,
654
+ lineNumber: 569,
655
+ columnNumber: 7
656
+ })]);
657
+ expect(res).toRenderTo(d`
658
+ """
659
+ Properties with both a getter and setter should only be documented in their
660
+ getter method.
661
+
662
+ Returns:
663
+ :obj:\`list\` of :obj:\`str\`: The property value.
664
+
665
+ Note:
666
+ If the setter method contains notable behavior, it should be mentioned here.
667
+ """
668
+
669
+
670
+ `);
671
+ });
672
+ it("GeneratorDoc with complex parameters", () => {
673
+ const res = toSourceText([_$createComponent(py.GeneratorDoc, {
674
+ get description() {
675
+ return [_$createComponent(Prose, {
676
+ children: "A more complex generator example with multiple parameters."
677
+ }, {
678
+ fileName: import.meta.url,
679
+ lineNumber: 603,
680
+ columnNumber: 11
681
+ })];
682
+ },
683
+ parameters: [{
684
+ name: "start",
685
+ type: "int",
686
+ default: "0",
687
+ doc: "Starting value for the sequence."
688
+ }, {
689
+ name: "stop",
690
+ type: "int",
691
+ doc: "Ending value for the sequence (exclusive)."
692
+ }, {
693
+ name: "step",
694
+ type: "int",
695
+ default: "1",
696
+ doc: "Step size between values."
697
+ }],
698
+ yields: "int: The next number in the sequence.",
699
+ raises: ["ValueError: If step is zero.", "TypeError: If parameters are not integers."]
700
+ }, {
701
+ fileName: import.meta.url,
702
+ lineNumber: 601,
703
+ columnNumber: 7
704
+ })]);
705
+ expect(res).toRenderTo(d`
706
+ """
707
+ A more complex generator example with multiple parameters.
708
+
709
+ Args:
710
+ start (int, optional): Starting value for the sequence. Defaults to "0".
711
+
712
+ stop (int): Ending value for the sequence (exclusive).
713
+
714
+ step (int, optional): Step size between values. Defaults to "1".
715
+
716
+ Yields:
717
+ int: The next number in the sequence.
718
+
719
+ Raises:
720
+ ValueError: If step is zero.
721
+
722
+ Raises:
723
+ TypeError: If parameters are not integers.
724
+ """
725
+
726
+
727
+ `);
728
+ });
729
+ it("ExceptionDoc with comprehensive documentation", () => {
730
+ const res = toSourceText([_$createComponent(py.ExceptionDoc, {
731
+ get description() {
732
+ return [_$createComponent(Prose, {
733
+ children: "A custom exception for authentication failures."
734
+ }, {
735
+ fileName: import.meta.url,
736
+ lineNumber: 665,
737
+ columnNumber: 11
738
+ }), _$createComponent(Prose, {
739
+ children: "This exception is raised when authentication credentials are invalid or when authentication tokens have expired."
740
+ }, {
741
+ fileName: import.meta.url,
742
+ lineNumber: 666,
743
+ columnNumber: 11
744
+ })];
745
+ },
746
+ parameters: [{
747
+ name: "message",
748
+ type: "str",
749
+ doc: "Human readable error message describing the authentication failure."
750
+ }, {
751
+ name: "error_code",
752
+ type: "int",
753
+ default: "401",
754
+ doc: "HTTP error code associated with the authentication failure."
755
+ }, {
756
+ name: "retry_after",
757
+ type: "int",
758
+ default: undefined,
759
+ doc: "Number of seconds to wait before retrying authentication."
760
+ }],
761
+ attributes: [{
762
+ name: "message",
763
+ type: "str",
764
+ children: "The error message."
765
+ }, {
766
+ name: "error_code",
767
+ type: "int",
768
+ children: "HTTP status code."
769
+ }, {
770
+ name: "retry_after",
771
+ type: "int",
772
+ children: "Retry delay in seconds, if applicable."
773
+ }],
774
+ note: "This exception should be caught and handled gracefully in production code."
775
+ }, {
776
+ fileName: import.meta.url,
777
+ lineNumber: 663,
778
+ columnNumber: 7
779
+ })]);
780
+ expect(res).toRenderTo(d`
781
+ """
782
+ A custom exception for authentication failures.
783
+
784
+ This exception is raised when authentication credentials are invalid or when
785
+ authentication tokens have expired.
786
+
787
+ Args:
788
+ message (str): Human readable error message describing the authentication
789
+ failure.
790
+
791
+ error_code (int, optional): HTTP error code associated with the
792
+ authentication failure. Defaults to "401".
793
+
794
+ retry_after (int): Number of seconds to wait before retrying authentication.
795
+
796
+ Attributes:
797
+ message (str): The error message.
798
+
799
+ error_code (int): HTTP status code.
800
+
801
+ retry_after (int): Retry delay in seconds, if applicable.
802
+
803
+ Note:
804
+ This exception should be caught and handled gracefully in production code.
805
+ """
806
+
807
+
808
+ `);
809
+ });
810
+ it("MethodDoc with raises but no returns", () => {
811
+ const res = toSourceText([_$createComponent(py.MethodDoc, {
812
+ get description() {
813
+ return [_$createComponent(Prose, {
814
+ children: "A method that performs an action but doesn't return a value."
815
+ }, {
816
+ fileName: import.meta.url,
817
+ lineNumber: 748,
818
+ columnNumber: 11
819
+ })];
820
+ },
821
+ parameters: [{
822
+ name: "data",
823
+ type: "bytes",
824
+ doc: "Raw data to process."
825
+ }],
826
+ raises: ["ValueError: If data is empty or invalid.", "IOError: If processing fails due to I/O issues."]
827
+ }, {
828
+ fileName: import.meta.url,
829
+ lineNumber: 746,
830
+ columnNumber: 7
831
+ })]);
832
+ expect(res).toRenderTo(d`
833
+ """
834
+ A method that performs an action but doesn't return a value.
835
+
836
+ Args:
837
+ data (bytes): Raw data to process.
838
+
839
+ Raises:
840
+ ValueError: If data is empty or invalid.
841
+
842
+ Raises:
843
+ IOError: If processing fails due to I/O issues.
844
+ """
845
+
846
+
847
+ `);
848
+ });
849
+ it("MethodDoc with no parameters", () => {
850
+ const res = toSourceText([_$createComponent(py.MethodDoc, {
851
+ get description() {
852
+ return [_$createComponent(Prose, {
853
+ children: "A simple method with no parameters (except self)."
854
+ }, {
855
+ fileName: import.meta.url,
856
+ lineNumber: 790,
857
+ columnNumber: 11
858
+ })];
859
+ },
860
+ returns: "bool: True if the operation was successful.",
861
+ note: "This is a parameterless method that only operates on instance state."
862
+ }, {
863
+ fileName: import.meta.url,
864
+ lineNumber: 788,
865
+ columnNumber: 7
866
+ })]);
867
+ expect(res).toRenderTo(d`
868
+ """
869
+ A simple method with no parameters (except self).
870
+
871
+ Returns:
872
+ bool: True if the operation was successful.
873
+
874
+ Note:
875
+ This is a parameterless method that only operates on instance state.
876
+ """
877
+
878
+
879
+ `);
880
+ });
881
+ it("AttributeDoc standalone usage", () => {
882
+ const res = toSourceText([_$createComponent(py.PyDoc, {
883
+ get children() {
884
+ return _$createComponent(py.AttributeDoc, {
885
+ name: "connection_timeout",
886
+ type: "float",
887
+ children: "Maximum time in seconds to wait for a connection to be established."
888
+ }, {
889
+ fileName: import.meta.url,
890
+ lineNumber: 817,
891
+ columnNumber: 9
892
+ });
893
+ }
894
+ }, {
895
+ fileName: import.meta.url,
896
+ lineNumber: 816,
897
+ columnNumber: 7
898
+ })]);
899
+ expect(res).toRenderTo(d`
900
+ """
901
+ connection_timeout (float): Maximum time in seconds to wait for a connection to
902
+ be established.
903
+ """
904
+
905
+
906
+ `);
907
+ });
908
+ it("GeneratorDoc with examples in description", () => {
909
+ const res = toSourceText([_$createComponent(py.GeneratorDoc, {
910
+ get description() {
911
+ return [_$createComponent(Prose, {
912
+ children: "Generators have a Yields section instead of a Returns section."
913
+ }, {
914
+ fileName: import.meta.url,
915
+ lineNumber: 839,
916
+ columnNumber: 11
917
+ }), _$createComponent(py.PyDocExample, {
918
+ children: `print([i for i in example_generator(4)])\n[0, 1, 2, 3]`
919
+ }, {
920
+ fileName: import.meta.url,
921
+ lineNumber: 842,
922
+ columnNumber: 11
923
+ })];
924
+ },
925
+ parameters: [{
926
+ name: "n",
927
+ type: "int",
928
+ doc: "The upper limit of the range to generate, from 0 to n - 1."
929
+ }],
930
+ yields: "int: The next number in the range of 0 to n - 1.",
931
+ note: "Examples should be written in doctest format, and should illustrate how to use the function."
932
+ }, {
933
+ fileName: import.meta.url,
934
+ lineNumber: 837,
935
+ columnNumber: 7
936
+ })]);
937
+ expect(res).toRenderTo(d`
938
+ """
939
+ Generators have a Yields section instead of a Returns section.
940
+
941
+ >> print([i for i in example_generator(4)])
942
+ >> [0, 1, 2, 3]
943
+
944
+ Args:
945
+ n (int): The upper limit of the range to generate, from 0 to n - 1.
946
+
947
+ Yields:
948
+ int: The next number in the range of 0 to n - 1.
949
+
950
+ Note:
951
+ Examples should be written in doctest format, and should illustrate how to use the function.
952
+ """
953
+
954
+
955
+ `);
956
+ });
957
+ });
958
+ describe("Full example", () => {
959
+ it("renders correctly in a Class", () => {
960
+ const doc = _$createComponent(py.ClassDoc, {
961
+ get description() {
962
+ return [_$createComponent(Prose, {
963
+ children: "This is an example of a long docstring that will be broken in lines. We will also render another paragraph after this one."
964
+ }, {
965
+ fileName: import.meta.url,
966
+ lineNumber: 887,
967
+ columnNumber: 11
968
+ }), _$createComponent(py.PyDocExample, {
969
+ children: `print("Hello world!")\nx = "Hello"\nprint(x)`
970
+ }, {
971
+ fileName: import.meta.url,
972
+ lineNumber: 891,
973
+ columnNumber: 11
974
+ })];
975
+ },
976
+ attributes: [{
977
+ name: "attr1",
978
+ type: "str",
979
+ children: "Description of attr1."
980
+ }, {
981
+ name: "attr2",
982
+ type: "int",
983
+ children: "Description of attr2."
984
+ }],
985
+ get examples() {
986
+ return [_$createComponent(py.PyDocExample, {
987
+ children: "print(\"class-doc\")"
988
+ }, {
989
+ fileName: import.meta.url,
990
+ lineNumber: 907,
991
+ columnNumber: 20
992
+ })];
993
+ },
994
+ seeAlso: ["RelatedClass", "helper_function"],
995
+ warning: "This class is experimental.",
996
+ deprecated: "Use NewClass instead.",
997
+ parameters: [{
998
+ name: "somebody",
999
+ type: "str",
1000
+ default: "John Doe",
1001
+ doc: "Somebody's name. This can be any string representing a person, whether it's a first name, full name, nickname, or even a codename (e.g., 'Agent X'). It's used primarily for display purposes, logging, or greeting messages and is not required to be unique or validated unless specified by the caller."
1002
+ }, {
1003
+ name: "somebody2",
1004
+ type: "str",
1005
+ doc: "Somebody's name. This can be any string representing a person, whether it's a first name, full name, nickname, or even a codename (e.g., 'Agent X'). It's used primarily for display purposes, logging, or greeting messages and is not required to be unique or validated unless specified by the caller."
1006
+ }],
1007
+ note: "Do not include the 'self' parameter in the Args section.",
1008
+ style: "google"
1009
+ }, {
1010
+ fileName: import.meta.url,
1011
+ lineNumber: 885,
1012
+ columnNumber: 7
1013
+ });
1014
+ const res = toSourceText([_$createComponent(py.ClassDeclaration, {
1015
+ name: "A",
1016
+ doc: doc,
1017
+ get children() {
1018
+ return _$createComponent(py.StatementList, {
1019
+ get children() {
1020
+ return [_$createComponent(py.VariableDeclaration, {
1021
+ name: "just_name"
1022
+ }, {
1023
+ fileName: import.meta.url,
1024
+ lineNumber: 932,
1025
+ columnNumber: 13
1026
+ }), _$createComponent(py.VariableDeclaration, {
1027
+ name: "name_and_type",
1028
+ type: "int"
1029
+ }, {
1030
+ fileName: import.meta.url,
1031
+ lineNumber: 933,
1032
+ columnNumber: 13
1033
+ }), _$createComponent(py.VariableDeclaration, {
1034
+ name: "name_type_and_value",
1035
+ type: "int",
1036
+ initializer: 12
1037
+ }, {
1038
+ fileName: import.meta.url,
1039
+ lineNumber: 934,
1040
+ columnNumber: 13
1041
+ })];
1042
+ }
1043
+ }, {
1044
+ fileName: import.meta.url,
1045
+ lineNumber: 931,
1046
+ columnNumber: 11
1047
+ });
1048
+ }
1049
+ }, {
1050
+ fileName: import.meta.url,
1051
+ lineNumber: 930,
1052
+ columnNumber: 9
1053
+ })], {
1054
+ printOptions: {
1055
+ printWidth: 80,
1056
+ tabWidth: 4
1057
+ }
1058
+ });
1059
+ expect(res).toRenderTo(d`
1060
+ class A:
1061
+ """
1062
+ This is an example of a long docstring that will be broken in lines. We will
1063
+ also render another paragraph after this one.
1064
+
1065
+ >> print("Hello world!")
1066
+ >> x = "Hello"
1067
+ >> print(x)
1068
+
1069
+ Attributes:
1070
+ attr1 (str): Description of attr1.
1071
+
1072
+ attr2 (int): Description of attr2.
1073
+
1074
+ Args:
1075
+ somebody (str, optional): Somebody's name. This can be any string
1076
+ representing a person, whether it's a first name, full name,
1077
+ nickname, or even a codename (e.g., 'Agent X'). It's used primarily
1078
+ for display purposes, logging, or greeting messages and is not
1079
+ required to be unique or validated unless specified by the caller.
1080
+ Defaults to \"John Doe\".
1081
+
1082
+ somebody2 (str): Somebody's name. This can be any string representing a
1083
+ person, whether it's a first name, full name, nickname, or even a
1084
+ codename (e.g., 'Agent X'). It's used primarily for display
1085
+ purposes, logging, or greeting messages and is not required to be
1086
+ unique or validated unless specified by the caller.
1087
+
1088
+ Examples:
1089
+ >> print("class-doc")
1090
+
1091
+ See Also:
1092
+ RelatedClass
1093
+ helper_function
1094
+
1095
+ Warning:
1096
+ This class is experimental.
1097
+
1098
+ Deprecated:
1099
+ Use NewClass instead.
1100
+
1101
+ Note:
1102
+ Do not include the 'self' parameter in the Args section.
1103
+ """
1104
+
1105
+ just_name = None
1106
+ name_and_type: int = None
1107
+ name_type_and_value: int = 12
1108
+
1109
+
1110
+ `);
1111
+ });
1112
+ it("renders correctly in a Function", () => {
1113
+ const doc = _$createComponent(py.FunctionDoc, {
1114
+ get description() {
1115
+ return [_$createComponent(Prose, {
1116
+ children: "This is an example of a long docstring that will be broken in lines. We will also render another paragraph after this one."
1117
+ }, {
1118
+ fileName: import.meta.url,
1119
+ lineNumber: 1005,
1120
+ columnNumber: 11
1121
+ }), _$createComponent(py.PyDocExample, {
1122
+ children: `print("Hello world!")\nx = "Hello"\nprint(x)`
1123
+ }, {
1124
+ fileName: import.meta.url,
1125
+ lineNumber: 1009,
1126
+ columnNumber: 11
1127
+ })];
1128
+ },
1129
+ parameters: [{
1130
+ name: "somebody",
1131
+ type: "str",
1132
+ default: "John Doe",
1133
+ doc: "Somebody's name. This can be any string representing a person, whether it's a first name, full name, nickname, or even a codename (e.g., 'Agent X'). It's used primarily for display purposes, logging, or greeting messages and is not required to be unique or validated unless specified by the caller."
1134
+ }, {
1135
+ name: "somebody2",
1136
+ type: "str",
1137
+ doc: "Somebody's name. This can be any string representing a person, whether it's a first name, full name, nickname, or even a codename (e.g., 'Agent X'). It's used primarily for display purposes, logging, or greeting messages and is not required to be unique or validated unless specified by the caller."
1138
+ }],
1139
+ returns: "The return value. True for success, False otherwise.",
1140
+ yields: "int: The next number in the sequence.",
1141
+ raises: ["ValueError: If somebody2 is equal to somebody."],
1142
+ note: "This function can be used as both a regular function and a generator.",
1143
+ style: "google"
1144
+ }, {
1145
+ fileName: import.meta.url,
1146
+ lineNumber: 1003,
1147
+ columnNumber: 7
1148
+ });
1149
+ const res = toSourceText([_$createComponent(py.FunctionDeclaration, {
1150
+ name: "some_function",
1151
+ doc: doc,
1152
+ get children() {
1153
+ return _$createComponent(py.StatementList, {
1154
+ get children() {
1155
+ return [_$createComponent(py.VariableDeclaration, {
1156
+ name: "just_name"
1157
+ }, {
1158
+ fileName: import.meta.url,
1159
+ lineNumber: 1037,
1160
+ columnNumber: 13
1161
+ }), _$createComponent(py.VariableDeclaration, {
1162
+ name: "name_and_type",
1163
+ type: "number"
1164
+ }, {
1165
+ fileName: import.meta.url,
1166
+ lineNumber: 1038,
1167
+ columnNumber: 13
1168
+ }), _$createComponent(py.VariableDeclaration, {
1169
+ name: "name_type_and_value",
1170
+ type: "number",
1171
+ initializer: 12
1172
+ }, {
1173
+ fileName: import.meta.url,
1174
+ lineNumber: 1039,
1175
+ columnNumber: 13
1176
+ })];
1177
+ }
1178
+ }, {
1179
+ fileName: import.meta.url,
1180
+ lineNumber: 1036,
1181
+ columnNumber: 11
1182
+ });
1183
+ }
1184
+ }, {
1185
+ fileName: import.meta.url,
1186
+ lineNumber: 1035,
1187
+ columnNumber: 9
1188
+ })], {
1189
+ printOptions: {
1190
+ printWidth: 80,
1191
+ tabWidth: 4
1192
+ }
1193
+ });
1194
+ expect(res).toRenderTo(d`
1195
+ def some_function():
1196
+ """
1197
+ This is an example of a long docstring that will be broken in lines. We will
1198
+ also render another paragraph after this one.
1199
+
1200
+ >> print("Hello world!")
1201
+ >> x = "Hello"
1202
+ >> print(x)
1203
+
1204
+ Args:
1205
+ somebody (str, optional): Somebody's name. This can be any string
1206
+ representing a person, whether it's a first name, full name,
1207
+ nickname, or even a codename (e.g., 'Agent X'). It's used primarily
1208
+ for display purposes, logging, or greeting messages and is not
1209
+ required to be unique or validated unless specified by the caller.
1210
+ Defaults to \"John Doe\".
1211
+
1212
+ somebody2 (str): Somebody's name. This can be any string representing a
1213
+ person, whether it's a first name, full name, nickname, or even a
1214
+ codename (e.g., 'Agent X'). It's used primarily for display
1215
+ purposes, logging, or greeting messages and is not required to be
1216
+ unique or validated unless specified by the caller.
1217
+
1218
+ Returns:
1219
+ The return value. True for success, False otherwise.
1220
+
1221
+ Yields:
1222
+ int: The next number in the sequence.
1223
+
1224
+ Raises:
1225
+ ValueError: If somebody2 is equal to somebody.
1226
+
1227
+ Note:
1228
+ This function can be used as both a regular function and a generator.
1229
+ """
1230
+ just_name = None
1231
+ name_and_type: number = None
1232
+ name_type_and_value: number = 12
1233
+
1234
+
1235
+ `);
1236
+ });
1237
+ it("renders correctly in a Variable", () => {
1238
+ const res = toSourceText([_$createComponent(py.VariableDeclaration, {
1239
+ name: "myVar",
1240
+ initializer: 42,
1241
+ doc: "This is a very long docstring that will be broken in two lines when rendered. This part of the docstring will be in the second line."
1242
+ }, {
1243
+ fileName: import.meta.url,
1244
+ lineNumber: 1099,
1245
+ columnNumber: 9
1246
+ })], {
1247
+ printOptions: {
1248
+ printWidth: 80,
1249
+ tabWidth: 4
1250
+ }
1251
+ });
1252
+ expect(res).toRenderTo(d`
1253
+ # This is a very long docstring that will be broken in two lines when rendered.
1254
+ # This part of the docstring will be in the second line.
1255
+ my_var = 42
1256
+ `);
1257
+ });
1258
+ it("classic enum with explicit values", () => {
1259
+ const doc = _$createComponent(py.ClassDoc, {
1260
+ get description() {
1261
+ return [_$createComponent(Prose, {
1262
+ children: "An enum representing colors."
1263
+ }, {
1264
+ fileName: import.meta.url,
1265
+ lineNumber: 1120,
1266
+ columnNumber: 23
1267
+ })];
1268
+ }
1269
+ }, {
1270
+ fileName: import.meta.url,
1271
+ lineNumber: 1119,
1272
+ columnNumber: 7
1273
+ });
1274
+ const result = toSourceText([_$createComponent(py.ClassEnumDeclaration, {
1275
+ name: "Color",
1276
+ baseType: "IntEnum",
1277
+ members: [{
1278
+ name: "RED",
1279
+ value: "1",
1280
+ doc: "The color red."
1281
+ }, {
1282
+ name: "GREEN",
1283
+ value: "2",
1284
+ doc: "The color green."
1285
+ }, {
1286
+ name: "BLUE",
1287
+ value: "3",
1288
+ doc: "The color blue."
1289
+ }],
1290
+ doc: doc
1291
+ }, {
1292
+ fileName: import.meta.url,
1293
+ lineNumber: 1125,
1294
+ columnNumber: 9
1295
+ })], {
1296
+ externals: [enumModule]
1297
+ });
1298
+ const expected = d`
1299
+ from enum import IntEnum
1300
+
1301
+
1302
+ class Color(IntEnum):
1303
+ """
1304
+ An enum representing colors.
1305
+ """
1306
+
1307
+ RED = 1
1308
+ """
1309
+ The color red.
1310
+ """
1311
+ GREEN = 2
1312
+ """
1313
+ The color green.
1314
+ """
1315
+ BLUE = 3
1316
+ """
1317
+ The color blue.
1318
+ """
1319
+
1320
+
1321
+ `;
1322
+ expect(result).toRenderTo(expected);
1323
+ });
1324
+ it("ModuleDoc with SourceFile integration", () => {
1325
+ const moduleDoc = _$createComponent(py.ModuleDoc, {
1326
+ get description() {
1327
+ return [_$createComponent(Prose, {
1328
+ children: "This module provides utility functions for data processing. It includes functions for validation, transformation, and analysis."
1329
+ }, {
1330
+ fileName: import.meta.url,
1331
+ lineNumber: 1169,
1332
+ columnNumber: 11
1333
+ })];
1334
+ },
1335
+ attributes: [{
1336
+ name: "DEFAULT_TIMEOUT",
1337
+ type: "int",
1338
+ children: "Default timeout value in seconds."
1339
+ }, {
1340
+ name: "MAX_RETRIES",
1341
+ type: "int",
1342
+ children: "Maximum number of retry attempts."
1343
+ }],
1344
+ todo: ["Add caching functionality", "Improve error messages"],
1345
+ style: "google"
1346
+ }, {
1347
+ fileName: import.meta.url,
1348
+ lineNumber: 1167,
1349
+ columnNumber: 7
1350
+ });
1351
+ const content = _$createComponent(py.SourceFile, {
1352
+ path: "utils.py",
1353
+ doc: moduleDoc,
1354
+ get children() {
1355
+ return [_$createComponent(py.VariableDeclaration, {
1356
+ name: "DEFAULT_TIMEOUT",
1357
+ initializer: 30
1358
+ }, {
1359
+ fileName: import.meta.url,
1360
+ lineNumber: 1193,
1361
+ columnNumber: 9
1362
+ }), _$createComponent(py.VariableDeclaration, {
1363
+ name: "MAX_RETRIES",
1364
+ initializer: 3
1365
+ }, {
1366
+ fileName: import.meta.url,
1367
+ lineNumber: 1194,
1368
+ columnNumber: 9
1369
+ }), _$createComponent(py.FunctionDeclaration, {
1370
+ name: "process_data",
1371
+ children: "pass"
1372
+ }, {
1373
+ fileName: import.meta.url,
1374
+ lineNumber: 1195,
1375
+ columnNumber: 9
1376
+ })];
1377
+ }
1378
+ }, {
1379
+ fileName: import.meta.url,
1380
+ lineNumber: 1192,
1381
+ columnNumber: 7
1382
+ });
1383
+ const res = toSourceTextMultiple([content]);
1384
+ const file = res.contents.find(f => f.kind === "file" && f.path === "utils.py");
1385
+ expect(file).toBeDefined();
1386
+ assertFileContents(res, {
1387
+ "utils.py": d`
1388
+ """
1389
+ This module provides utility functions for data processing. It includes
1390
+ functions for validation, transformation, and analysis.
1391
+
1392
+ Attributes:
1393
+ DEFAULT_TIMEOUT (int): Default timeout value in seconds.
1394
+
1395
+ MAX_RETRIES (int): Maximum number of retry attempts.
1396
+
1397
+ Todo:
1398
+ * Add caching functionality
1399
+ * Improve error messages
1400
+ """
1401
+
1402
+ default_timeout = 30
1403
+
1404
+ max_retries = 3
1405
+
1406
+ def process_data():
1407
+ pass
1408
+
1409
+
1410
+ `
1411
+ });
1412
+ });
1413
+ it("GeneratorDoc with FunctionDeclaration integration", () => {
1414
+ const generatorDoc = _$createComponent(py.GeneratorDoc, {
1415
+ get description() {
1416
+ return [_$createComponent(Prose, {
1417
+ children: "A generator function that yields fibonacci numbers. This is an efficient way to generate the sequence on demand."
1418
+ }, {
1419
+ fileName: import.meta.url,
1420
+ lineNumber: 1239,
1421
+ columnNumber: 11
1422
+ })];
1423
+ },
1424
+ parameters: [{
1425
+ name: "n",
1426
+ type: "int",
1427
+ doc: "Number of fibonacci numbers to generate."
1428
+ }],
1429
+ yields: "int: The next fibonacci number in the sequence.",
1430
+ style: "google"
1431
+ }, {
1432
+ fileName: import.meta.url,
1433
+ lineNumber: 1237,
1434
+ columnNumber: 7
1435
+ });
1436
+ const result = toSourceText([_$createComponent(py.FunctionDeclaration, {
1437
+ name: "fibonacci_generator",
1438
+ doc: generatorDoc,
1439
+ children: "yield 0"
1440
+ }, {
1441
+ fileName: import.meta.url,
1442
+ lineNumber: 1257,
1443
+ columnNumber: 7
1444
+ })]);
1445
+ expect(result).toRenderTo(d`
1446
+ def fibonacci_generator():
1447
+ """
1448
+ A generator function that yields fibonacci numbers. This is an efficient way
1449
+ to generate the sequence on demand.
1450
+
1451
+ Args:
1452
+ n (int): Number of fibonacci numbers to generate.
1453
+
1454
+ Yields:
1455
+ int: The next fibonacci number in the sequence.
1456
+ """
1457
+ yield 0
1458
+
1459
+
1460
+ `);
1461
+ });
1462
+ it("ExceptionDoc with ClassDeclaration integration", () => {
1463
+ const exceptionDoc = _$createComponent(py.ExceptionDoc, {
1464
+ get description() {
1465
+ return [_$createComponent(Prose, {
1466
+ children: "Custom exception raised when data validation fails. This exception includes details about the validation error."
1467
+ }, {
1468
+ fileName: import.meta.url,
1469
+ lineNumber: 1286,
1470
+ columnNumber: 11
1471
+ })];
1472
+ },
1473
+ attributes: [{
1474
+ name: "field_name",
1475
+ type: "str",
1476
+ children: "Name of the field that failed validation."
1477
+ }, {
1478
+ name: "error_code",
1479
+ type: "int",
1480
+ children: "Numeric error code for the validation failure."
1481
+ }],
1482
+ style: "google"
1483
+ }, {
1484
+ fileName: import.meta.url,
1485
+ lineNumber: 1284,
1486
+ columnNumber: 7
1487
+ });
1488
+ const result = toSourceText([_$createComponent(py.ClassDeclaration, {
1489
+ name: "ValidationError",
1490
+ bases: ["Exception"],
1491
+ doc: exceptionDoc,
1492
+ get children() {
1493
+ return _$createComponent(py.StatementList, {
1494
+ get children() {
1495
+ return [_$createComponent(py.VariableDeclaration, {
1496
+ name: "field_name",
1497
+ type: "str"
1498
+ }, {
1499
+ fileName: import.meta.url,
1500
+ lineNumber: 1314,
1501
+ columnNumber: 11
1502
+ }), _$createComponent(py.VariableDeclaration, {
1503
+ name: "error_code",
1504
+ type: "int"
1505
+ }, {
1506
+ fileName: import.meta.url,
1507
+ lineNumber: 1315,
1508
+ columnNumber: 11
1509
+ })];
1510
+ }
1511
+ }, {
1512
+ fileName: import.meta.url,
1513
+ lineNumber: 1313,
1514
+ columnNumber: 9
1515
+ });
1516
+ }
1517
+ }, {
1518
+ fileName: import.meta.url,
1519
+ lineNumber: 1308,
1520
+ columnNumber: 7
1521
+ })]);
1522
+ expect(result).toRenderTo(d`
1523
+ class ValidationError(Exception):
1524
+ """
1525
+ Custom exception raised when data validation fails. This exception includes
1526
+ details about the validation error.
1527
+
1528
+ Attributes:
1529
+ field_name (str): Name of the field that failed validation.
1530
+
1531
+ error_code (int): Numeric error code for the validation failure.
1532
+ """
1533
+
1534
+ field_name: str = None
1535
+ error_code: int = None
1536
+
1537
+
1538
+ `);
1539
+ });
1540
+ it("PropertyDoc with FunctionDeclaration (as property method) integration", () => {
1541
+ const propertyDoc = _$createComponent(py.PropertyDoc, {
1542
+ get description() {
1543
+ return [_$createComponent(Prose, {
1544
+ children: "The full name of the person, combining first and last name. This property automatically formats the name with proper capitalization."
1545
+ }, {
1546
+ fileName: import.meta.url,
1547
+ lineNumber: 1345,
1548
+ columnNumber: 11
1549
+ })];
1550
+ },
1551
+ style: "google"
1552
+ }, {
1553
+ fileName: import.meta.url,
1554
+ lineNumber: 1343,
1555
+ columnNumber: 7
1556
+ });
1557
+ const result = toSourceText([_$createComponent(py.ClassDeclaration, {
1558
+ name: "Person",
1559
+ get children() {
1560
+ return _$createComponent(py.PropertyDeclaration, {
1561
+ name: "full_name",
1562
+ doc: propertyDoc,
1563
+ type: "str",
1564
+ children: "return \"John Doe\""
1565
+ }, {
1566
+ fileName: import.meta.url,
1567
+ lineNumber: 1356,
1568
+ columnNumber: 9
1569
+ });
1570
+ }
1571
+ }, {
1572
+ fileName: import.meta.url,
1573
+ lineNumber: 1355,
1574
+ columnNumber: 7
1575
+ })]);
1576
+ expect(result).toRenderTo(`
1577
+ class Person:
1578
+ @property
1579
+ def full_name(self) -> str:
1580
+ """
1581
+ The full name of the person, combining first and last name. This
1582
+ property automatically formats the name with proper capitalization.
1583
+ """
1584
+ return "John Doe"
1585
+
1586
+
1587
+ `);
1588
+ });
1589
+ it("MethodDoc with FunctionDeclaration (inside class) integration", () => {
1590
+ const methodDoc = _$createComponent(py.MethodDoc, {
1591
+ get description() {
1592
+ return [_$createComponent(Prose, {
1593
+ children: "Validates the input data according to the defined schema. This method performs comprehensive validation including type checking."
1594
+ }, {
1595
+ fileName: import.meta.url,
1596
+ lineNumber: 1380,
1597
+ columnNumber: 11
1598
+ })];
1599
+ },
1600
+ parameters: [{
1601
+ name: "data",
1602
+ type: "dict",
1603
+ doc: "The data dictionary to validate."
1604
+ }, {
1605
+ name: "strict",
1606
+ type: "bool",
1607
+ default: "True",
1608
+ doc: "Whether to enforce strict validation rules."
1609
+ }],
1610
+ returns: "bool: True if validation passes, False otherwise.",
1611
+ raises: ["ValidationError: If data format is invalid."],
1612
+ note: "This method modifies the internal validation state.",
1613
+ style: "google"
1614
+ }, {
1615
+ fileName: import.meta.url,
1616
+ lineNumber: 1378,
1617
+ columnNumber: 7
1618
+ });
1619
+ const result = toSourceText([_$createComponent(py.ClassDeclaration, {
1620
+ name: "DataValidator",
1621
+ get children() {
1622
+ return _$createComponent(py.MethodDeclaration, {
1623
+ name: "validate",
1624
+ doc: methodDoc,
1625
+ parameters: [{
1626
+ name: "data",
1627
+ type: "dict"
1628
+ }, {
1629
+ name: "strict",
1630
+ type: "bool",
1631
+ default: true
1632
+ }],
1633
+ returnType: "bool",
1634
+ children: "return self.validate(data, strict)"
1635
+ }, {
1636
+ fileName: import.meta.url,
1637
+ lineNumber: 1407,
1638
+ columnNumber: 9
1639
+ });
1640
+ }
1641
+ }, {
1642
+ fileName: import.meta.url,
1643
+ lineNumber: 1406,
1644
+ columnNumber: 7
1645
+ })]);
1646
+ expect(result).toRenderTo(d`
1647
+ class DataValidator:
1648
+ def validate(self, data: dict, strict: bool = True) -> bool:
1649
+ """
1650
+ Validates the input data according to the defined schema. This method
1651
+ performs comprehensive validation including type checking.
1652
+
1653
+ Args:
1654
+ data (dict): The data dictionary to validate.
1655
+
1656
+ strict (bool, optional): Whether to enforce strict validation rules.
1657
+ Defaults to "True".
1658
+
1659
+ Returns:
1660
+ bool: True if validation passes, False otherwise.
1661
+
1662
+ Raises:
1663
+ ValidationError: If data format is invalid.
1664
+
1665
+ Note:
1666
+ This method modifies the internal validation state.
1667
+ """
1668
+ return self.validate(data, strict)
1669
+
1670
+
1671
+
1672
+ `);
1673
+ });
1674
+ });
1675
+ //# sourceMappingURL=pydocs.test.js.map