@alloy-js/python 0.4.0-dev.3 → 0.4.0-dev.6

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 (355) 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 +45 -3
  165. package/dist/src/components/ImportStatement.js.map +1 -1
  166. package/dist/src/components/Reference.d.ts.map +1 -1
  167. package/dist/src/components/Reference.js +5 -1
  168. package/dist/src/components/Reference.js.map +1 -1
  169. package/dist/src/components/SourceFile.d.ts +1 -1
  170. package/dist/src/components/SourceFile.d.ts.map +1 -1
  171. package/dist/src/components/SourceFile.js +46 -7
  172. package/dist/src/components/SourceFile.js.map +1 -1
  173. package/dist/src/components/TypeRefContext.d.ts +26 -0
  174. package/dist/src/components/TypeRefContext.d.ts.map +1 -0
  175. package/dist/src/components/TypeRefContext.js +29 -0
  176. package/dist/src/components/TypeRefContext.js.map +1 -0
  177. package/dist/src/components/TypeReference.d.ts +5 -0
  178. package/dist/src/components/TypeReference.d.ts.map +1 -1
  179. package/dist/src/components/TypeReference.js +19 -9
  180. package/dist/src/components/TypeReference.js.map +1 -1
  181. package/dist/src/components/VariableDeclaration.d.ts.map +1 -1
  182. package/dist/src/components/VariableDeclaration.js +7 -2
  183. package/dist/src/components/VariableDeclaration.js.map +1 -1
  184. package/dist/src/components/index.d.ts +1 -1
  185. package/dist/src/components/index.d.ts.map +1 -1
  186. package/dist/src/components/index.js +1 -1
  187. package/dist/src/components/index.js.map +1 -1
  188. package/dist/src/context/index.d.ts +2 -0
  189. package/dist/src/context/index.d.ts.map +1 -0
  190. package/dist/src/context/index.js +2 -0
  191. package/dist/src/context/index.js.map +1 -0
  192. package/dist/src/context/type-ref-context.d.ts +13 -0
  193. package/dist/src/context/type-ref-context.d.ts.map +1 -0
  194. package/dist/src/context/type-ref-context.js +17 -0
  195. package/dist/src/context/type-ref-context.js.map +1 -0
  196. package/dist/src/name-conflict-resolver.d.ts +2 -2
  197. package/dist/src/name-conflict-resolver.d.ts.map +1 -1
  198. package/dist/src/name-conflict-resolver.js +2 -2
  199. package/dist/src/name-conflict-resolver.js.map +1 -1
  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/docs/api/components/AttributeDoc.md +36 -0
  234. package/docs/api/components/CallSignature.md +62 -0
  235. package/docs/api/components/CallSignatureParameters.md +49 -0
  236. package/docs/api/components/ClassDeclaration.md +67 -0
  237. package/docs/api/components/ClassDoc.md +55 -0
  238. package/docs/api/components/ClassEnumDeclaration.md +111 -0
  239. package/docs/api/components/ClassInstantiation.md +44 -0
  240. package/docs/api/components/ClassMethodDeclaration.md +31 -0
  241. package/docs/api/components/ConstructorDeclaration.md +27 -0
  242. package/docs/api/components/DataclassDeclaration.md +55 -0
  243. package/docs/api/components/Declaration.md +41 -0
  244. package/docs/api/components/DunderMethodDeclaration.md +31 -0
  245. package/docs/api/components/EnumMember.md +61 -0
  246. package/docs/api/components/ExceptionDoc.md +55 -0
  247. package/docs/api/components/FunctionCallExpression.md +43 -0
  248. package/docs/api/components/FunctionDeclaration.md +50 -0
  249. package/docs/api/components/FunctionDoc.md +61 -0
  250. package/docs/api/components/FunctionalEnumDeclaration.md +79 -0
  251. package/docs/api/components/FutureStatement.md +51 -0
  252. package/docs/api/components/GeneratorDoc.md +58 -0
  253. package/docs/api/components/InlineDoc.md +29 -0
  254. package/docs/api/components/LexicalScope.md +65 -0
  255. package/docs/api/components/MemberExpression.md +53 -0
  256. package/docs/api/components/MemberScope.md +28 -0
  257. package/docs/api/components/MethodDeclaration.md +49 -0
  258. package/docs/api/components/MethodDoc.md +61 -0
  259. package/docs/api/components/ModuleDoc.md +52 -0
  260. package/docs/api/components/PropertyDeclaration.md +46 -0
  261. package/docs/api/components/PropertyDoc.md +52 -0
  262. package/docs/api/components/PyDoc.md +29 -0
  263. package/docs/api/components/PyDocExample.md +29 -0
  264. package/docs/api/components/PythonBlock.md +47 -0
  265. package/docs/api/components/Reference.md +31 -0
  266. package/docs/api/components/SimpleCommentBlock.md +27 -0
  267. package/docs/api/components/SimpleInlineComment.md +27 -0
  268. package/docs/api/components/SourceFile.md +83 -0
  269. package/docs/api/components/StatementList.md +47 -0
  270. package/docs/api/components/StaticMethodDeclaration.md +31 -0
  271. package/docs/api/components/TypeArguments.md +27 -0
  272. package/docs/api/components/TypeRefContext.md +41 -0
  273. package/docs/api/components/TypeReference.md +37 -0
  274. package/docs/api/components/UnionTypeExpression.md +27 -0
  275. package/docs/api/components/VariableDeclaration.md +87 -0
  276. package/docs/api/components/index.md +46 -0
  277. package/docs/api/components/useSourceFile.md +19 -0
  278. package/docs/api/contexts/PythonSourceFile-context.md +18 -0
  279. package/docs/api/contexts/index.md +3 -0
  280. package/docs/api/functions/createFunctionSymbol.md +23 -0
  281. package/docs/api/functions/createMethodSymbol.md +23 -0
  282. package/docs/api/functions/createModule.md +18 -0
  283. package/docs/api/functions/createPythonNamePolicy.md +17 -0
  284. package/docs/api/functions/getCallSignatureProps.md +21 -0
  285. package/docs/api/functions/index.md +13 -0
  286. package/docs/api/functions/isParameterDescriptor.md +18 -0
  287. package/docs/api/functions/isTypeRefContext.md +17 -0
  288. package/docs/api/functions/ref.md +25 -0
  289. package/docs/api/functions/usePythonLexicalScope.md +17 -0
  290. package/docs/api/functions/usePythonNamePolicy.md +17 -0
  291. package/docs/api/functions/usePythonScope.md +17 -0
  292. package/docs/api/index.md +7 -0
  293. package/docs/api/types/AddImportOptions.md +7 -0
  294. package/docs/api/types/BaseDeclarationProps.md +10 -0
  295. package/docs/api/types/CommonFunctionProps.md +15 -0
  296. package/docs/api/types/CreateModuleProps.md +8 -0
  297. package/docs/api/types/CreatePythonSymbolFunctionOptions.md +9 -0
  298. package/docs/api/types/DataclassDecoratorKey.md +5 -0
  299. package/docs/api/types/DataclassDecoratorKwargs.md +5 -0
  300. package/docs/api/types/EnumPropsBase.md +11 -0
  301. package/docs/api/types/GoogleStyleDocAttributeProps.md +9 -0
  302. package/docs/api/types/ImportRecordProps.md +7 -0
  303. package/docs/api/types/ImportRecords.md +8 -0
  304. package/docs/api/types/ImportedSymbol.md +10 -0
  305. package/docs/api/types/LexicalScopeProps.md +5 -0
  306. package/docs/api/types/MemberExpressionPartProps.md +13 -0
  307. package/docs/api/types/ModuleDescriptor.md +7 -0
  308. package/docs/api/types/ModuleRefkeys.md +7 -0
  309. package/docs/api/types/NamedMap.md +7 -0
  310. package/docs/api/types/ParameterDescriptor.md +13 -0
  311. package/docs/api/types/ParameterMarker.md +5 -0
  312. package/docs/api/types/PropertyMethodDeclarationProps.md +9 -0
  313. package/docs/api/types/PythonElements.md +5 -0
  314. package/docs/api/types/PythonLexicalScope.md +11 -0
  315. package/docs/api/types/PythonMemberScope.md +9 -0
  316. package/docs/api/types/PythonModuleScope.md +13 -0
  317. package/docs/api/types/PythonOutputScope.md +5 -0
  318. package/docs/api/types/PythonOutputSymbol.md +21 -0
  319. package/docs/api/types/PythonOutputSymbolOptions.md +10 -0
  320. package/docs/api/types/RefOptions.md +7 -0
  321. package/docs/api/types/SubscriptionProps.md +9 -0
  322. package/docs/api/types/index.md +31 -0
  323. package/docs/api/variables/abcModule.md +7 -0
  324. package/docs/api/variables/dataclassDecoratorKeySet.md +5 -0
  325. package/docs/api/variables/dataclassDecoratorKeys.md +7 -0
  326. package/docs/api/variables/dataclassesModule.md +7 -0
  327. package/docs/api/variables/enumModule.md +7 -0
  328. package/docs/api/variables/index.md +8 -0
  329. package/docs/api/variables/requestsModule.md +8 -0
  330. package/package.json +7 -5
  331. package/src/components/CallSignature.tsx +6 -2
  332. package/src/components/ImportStatement.tsx +51 -4
  333. package/src/components/Reference.tsx +3 -1
  334. package/src/components/SourceFile.tsx +44 -8
  335. package/src/components/TypeRefContext.tsx +36 -0
  336. package/src/components/TypeReference.tsx +15 -7
  337. package/src/components/VariableDeclaration.tsx +5 -1
  338. package/src/components/index.ts +1 -1
  339. package/src/context/index.ts +1 -0
  340. package/src/context/type-ref-context.tsx +16 -0
  341. package/src/name-conflict-resolver.ts +4 -10
  342. package/src/symbols/python-module-scope.ts +55 -2
  343. package/src/symbols/python-output-symbol.ts +32 -1
  344. package/src/symbols/reference.tsx +10 -0
  345. package/temp/api.json +441 -336
  346. package/test/dataclassdeclarations.test.tsx +8 -2
  347. package/test/externals.test.tsx +8 -2
  348. package/test/functiondeclaration.test.tsx +6 -3
  349. package/test/imports.test.tsx +6 -6
  350. package/test/references.test.tsx +1 -1
  351. package/test/sourcefiles.test.tsx +13 -13
  352. package/test/type-checking-imports.test.tsx +363 -0
  353. package/test/uniontypeexpression.test.tsx +4 -1
  354. package/test/variables.test.tsx +4 -1
  355. package/vitest.config.ts +8 -0
@@ -0,0 +1,1068 @@
1
+ import { createComponent as _$createComponent, createIntrinsic as _$createIntrinsic } from "@alloy-js/core/jsx-runtime";
2
+ import { Prose, namekey, refkey } from "@alloy-js/core";
3
+ import { d } from "@alloy-js/core/testing";
4
+ import { describe, expect, it } from "vitest";
5
+ import { dataclassesModule } from "../src/builtins/python.js";
6
+ import * as py from "../src/index.js";
7
+ import { assertFileContents, toSourceText, toSourceTextMultiple } from "./utils.js";
8
+ describe("DataclassDeclaration", () => {
9
+ it("Creates a dataclass with a class doc", () => {
10
+ const doc = _$createComponent(py.ClassDoc, {
11
+ get description() {
12
+ return [_$createComponent(Prose, {
13
+ children: "Represents a user."
14
+ }, {
15
+ fileName: import.meta.url,
16
+ lineNumber: 15,
17
+ columnNumber: 34
18
+ })];
19
+ }
20
+ }, {
21
+ fileName: import.meta.url,
22
+ lineNumber: 15,
23
+ columnNumber: 7
24
+ });
25
+ const res = toSourceText([_$createComponent(py.SourceFile, {
26
+ path: "user.py",
27
+ get children() {
28
+ return _$createComponent(py.DataclassDeclaration, {
29
+ name: "User",
30
+ doc: doc
31
+ }, {
32
+ fileName: import.meta.url,
33
+ lineNumber: 20,
34
+ columnNumber: 11
35
+ });
36
+ }
37
+ }, {
38
+ fileName: import.meta.url,
39
+ lineNumber: 19,
40
+ columnNumber: 9
41
+ })], {
42
+ externals: [dataclassesModule]
43
+ });
44
+ expect(res).toRenderTo(d`
45
+ from dataclasses import dataclass
46
+
47
+
48
+ @dataclass
49
+ class User:
50
+ """
51
+ Represents a user.
52
+ """
53
+
54
+ pass
55
+
56
+
57
+ `);
58
+ });
59
+ it("Creates a dataclass with fields and defaults", () => {
60
+ const res = toSourceText([_$createComponent(py.SourceFile, {
61
+ path: "user.py",
62
+ get children() {
63
+ return _$createComponent(py.DataclassDeclaration, {
64
+ name: "User",
65
+ get children() {
66
+ return [_$createComponent(py.VariableDeclaration, {
67
+ instanceVariable: true,
68
+ omitNone: true,
69
+ name: "id",
70
+ type: "int"
71
+ }, {
72
+ fileName: import.meta.url,
73
+ lineNumber: 49,
74
+ columnNumber: 13
75
+ }), _$createComponent(py.VariableDeclaration, {
76
+ instanceVariable: true,
77
+ get name() {
78
+ return namekey("_", {
79
+ ignoreNamePolicy: true
80
+ });
81
+ },
82
+ get type() {
83
+ return dataclassesModule["."].KW_ONLY;
84
+ },
85
+ omitNone: true
86
+ }, {
87
+ fileName: import.meta.url,
88
+ lineNumber: 55,
89
+ columnNumber: 13
90
+ }), _$createComponent(py.VariableDeclaration, {
91
+ instanceVariable: true,
92
+ name: "name",
93
+ type: "str",
94
+ initializer: "Anonymous"
95
+ }, {
96
+ fileName: import.meta.url,
97
+ lineNumber: 61,
98
+ columnNumber: 13
99
+ })];
100
+ }
101
+ }, {
102
+ fileName: import.meta.url,
103
+ lineNumber: 48,
104
+ columnNumber: 11
105
+ });
106
+ }
107
+ }, {
108
+ fileName: import.meta.url,
109
+ lineNumber: 47,
110
+ columnNumber: 9
111
+ })], {
112
+ externals: [dataclassesModule]
113
+ });
114
+ expect(res).toRenderTo(d`
115
+ from dataclasses import dataclass
116
+ from typing import TYPE_CHECKING
117
+
118
+ if TYPE_CHECKING:
119
+ from dataclasses import KW_ONLY
120
+
121
+
122
+ @dataclass
123
+ class User:
124
+ id: int
125
+ _: KW_ONLY
126
+ name: str = "Anonymous"
127
+
128
+
129
+ `);
130
+ });
131
+ it("Creates a dataclass with keyword arguments", () => {
132
+ const res = toSourceText([_$createComponent(py.SourceFile, {
133
+ path: "user.py",
134
+ get children() {
135
+ return _$createComponent(py.DataclassDeclaration, {
136
+ name: "User",
137
+ frozen: true,
138
+ slots: true,
139
+ kwOnly: true,
140
+ get children() {
141
+ return _$createComponent(py.VariableDeclaration, {
142
+ instanceVariable: true,
143
+ omitNone: true,
144
+ name: "id",
145
+ type: "int"
146
+ }, {
147
+ fileName: import.meta.url,
148
+ lineNumber: 98,
149
+ columnNumber: 13
150
+ });
151
+ }
152
+ }, {
153
+ fileName: import.meta.url,
154
+ lineNumber: 97,
155
+ columnNumber: 11
156
+ });
157
+ }
158
+ }, {
159
+ fileName: import.meta.url,
160
+ lineNumber: 96,
161
+ columnNumber: 9
162
+ })], {
163
+ externals: [dataclassesModule]
164
+ });
165
+ expect(res).toRenderTo(d`
166
+ from dataclasses import dataclass
167
+
168
+
169
+ @dataclass(frozen=True, slots=True, kw_only=True)
170
+ class User:
171
+ id: int
172
+
173
+
174
+ `);
175
+ });
176
+ it("Creates a dataclass with all keyword arguments", () => {
177
+ const res = toSourceText([_$createComponent(py.SourceFile, {
178
+ path: "user.py",
179
+ get children() {
180
+ return _$createComponent(py.DataclassDeclaration, {
181
+ name: "User",
182
+ init: true,
183
+ repr: false,
184
+ eq: true,
185
+ order: false,
186
+ unsafeHash: true,
187
+ frozen: true,
188
+ matchArgs: false,
189
+ kwOnly: true,
190
+ slots: true,
191
+ weakrefSlot: false
192
+ }, {
193
+ fileName: import.meta.url,
194
+ lineNumber: 128,
195
+ columnNumber: 11
196
+ });
197
+ }
198
+ }, {
199
+ fileName: import.meta.url,
200
+ lineNumber: 127,
201
+ columnNumber: 9
202
+ })], {
203
+ externals: [dataclassesModule]
204
+ });
205
+ expect(res).toRenderTo(d`
206
+ from dataclasses import dataclass
207
+
208
+
209
+ @dataclass(init=True, repr=False, eq=True, order=False, unsafe_hash=True, frozen=True, match_args=False, kw_only=True, slots=True, weakref_slot=False)
210
+ class User:
211
+ pass
212
+
213
+
214
+ `);
215
+ });
216
+ it("Throws error when weakref_slot=True without slots=True", () => {
217
+ expect(() => toSourceText([_$createComponent(py.SourceFile, {
218
+ path: "user.py",
219
+ get children() {
220
+ return _$createComponent(py.DataclassDeclaration, {
221
+ name: "User",
222
+ weakrefSlot: true
223
+ }, {
224
+ fileName: import.meta.url,
225
+ lineNumber: 165,
226
+ columnNumber: 13
227
+ });
228
+ }
229
+ }, {
230
+ fileName: import.meta.url,
231
+ lineNumber: 164,
232
+ columnNumber: 11
233
+ })], {
234
+ externals: [dataclassesModule]
235
+ })).toThrowError(/weakref_slot=True requires slots=True in @dataclass decorator/);
236
+ });
237
+ it("Allows weakref_slot=True when slots=True", () => {
238
+ const res = toSourceText([_$createComponent(py.SourceFile, {
239
+ path: "user.py",
240
+ get children() {
241
+ return _$createComponent(py.DataclassDeclaration, {
242
+ name: "User",
243
+ slots: true,
244
+ weakrefSlot: true
245
+ }, {
246
+ fileName: import.meta.url,
247
+ lineNumber: 179,
248
+ columnNumber: 11
249
+ });
250
+ }
251
+ }, {
252
+ fileName: import.meta.url,
253
+ lineNumber: 178,
254
+ columnNumber: 9
255
+ })], {
256
+ externals: [dataclassesModule]
257
+ });
258
+ expect(res).toRenderTo(d`
259
+ from dataclasses import dataclass
260
+
261
+
262
+ @dataclass(slots=True, weakref_slot=True)
263
+ class User:
264
+ pass
265
+
266
+
267
+ `);
268
+ });
269
+ it("Throws error when order=True and eq=False", () => {
270
+ expect(() => toSourceText([_$createComponent(py.SourceFile, {
271
+ path: "user.py",
272
+ get children() {
273
+ return _$createComponent(py.DataclassDeclaration, {
274
+ name: "User",
275
+ order: true,
276
+ eq: false
277
+ }, {
278
+ fileName: import.meta.url,
279
+ lineNumber: 203,
280
+ columnNumber: 13
281
+ });
282
+ }
283
+ }, {
284
+ fileName: import.meta.url,
285
+ lineNumber: 202,
286
+ columnNumber: 11
287
+ })], {
288
+ externals: [dataclassesModule]
289
+ })).toThrowError(/order=True requires eq=True/);
290
+ });
291
+ it("Creates a dataclass with order=True and no conflicting methods", () => {
292
+ const res = toSourceText([_$createComponent(py.SourceFile, {
293
+ path: "user.py",
294
+ get children() {
295
+ return _$createComponent(py.DataclassDeclaration, {
296
+ name: "User",
297
+ order: true
298
+ }, {
299
+ fileName: import.meta.url,
300
+ lineNumber: 215,
301
+ columnNumber: 11
302
+ });
303
+ }
304
+ }, {
305
+ fileName: import.meta.url,
306
+ lineNumber: 214,
307
+ columnNumber: 9
308
+ })], {
309
+ externals: [dataclassesModule]
310
+ });
311
+ expect(res).toRenderTo(d`
312
+ from dataclasses import dataclass
313
+
314
+
315
+ @dataclass(order=True)
316
+ class User:
317
+ pass
318
+
319
+
320
+ `);
321
+ });
322
+ it("Throws error when order=True and class defines __lt__", () => {
323
+ expect(() => toSourceText([_$createComponent(py.SourceFile, {
324
+ path: "user.py",
325
+ get children() {
326
+ return _$createComponent(py.DataclassDeclaration, {
327
+ name: "User",
328
+ order: true,
329
+ get children() {
330
+ return _$createComponent(py.DunderMethodDeclaration, {
331
+ name: "__lt__"
332
+ }, {
333
+ fileName: import.meta.url,
334
+ lineNumber: 240,
335
+ columnNumber: 15
336
+ });
337
+ }
338
+ }, {
339
+ fileName: import.meta.url,
340
+ lineNumber: 239,
341
+ columnNumber: 13
342
+ });
343
+ }
344
+ }, {
345
+ fileName: import.meta.url,
346
+ lineNumber: 238,
347
+ columnNumber: 11
348
+ })], {
349
+ externals: [dataclassesModule]
350
+ })).toThrowError(/Cannot specify order=True when the class already defines __lt__\(\)/);
351
+ });
352
+ it("Throws error when order=True and class defines __le__", () => {
353
+ expect(() => toSourceText([_$createComponent(py.SourceFile, {
354
+ path: "user.py",
355
+ get children() {
356
+ return _$createComponent(py.DataclassDeclaration, {
357
+ name: "User",
358
+ order: true,
359
+ get children() {
360
+ return _$createComponent(py.DunderMethodDeclaration, {
361
+ name: "__le__"
362
+ }, {
363
+ fileName: import.meta.url,
364
+ lineNumber: 257,
365
+ columnNumber: 15
366
+ });
367
+ }
368
+ }, {
369
+ fileName: import.meta.url,
370
+ lineNumber: 256,
371
+ columnNumber: 13
372
+ });
373
+ }
374
+ }, {
375
+ fileName: import.meta.url,
376
+ lineNumber: 255,
377
+ columnNumber: 11
378
+ })], {
379
+ externals: [dataclassesModule]
380
+ })).toThrowError(/Cannot specify order=True when the class already defines __le__\(\)/);
381
+ });
382
+ it("Throws error when order=True and class defines __gt__", () => {
383
+ expect(() => toSourceText([_$createComponent(py.SourceFile, {
384
+ path: "user.py",
385
+ get children() {
386
+ return _$createComponent(py.DataclassDeclaration, {
387
+ name: "User",
388
+ order: true,
389
+ get children() {
390
+ return _$createComponent(py.DunderMethodDeclaration, {
391
+ name: "__gt__"
392
+ }, {
393
+ fileName: import.meta.url,
394
+ lineNumber: 274,
395
+ columnNumber: 15
396
+ });
397
+ }
398
+ }, {
399
+ fileName: import.meta.url,
400
+ lineNumber: 273,
401
+ columnNumber: 13
402
+ });
403
+ }
404
+ }, {
405
+ fileName: import.meta.url,
406
+ lineNumber: 272,
407
+ columnNumber: 11
408
+ })], {
409
+ externals: [dataclassesModule]
410
+ })).toThrowError(/Cannot specify order=True when the class already defines __gt__\(\)/);
411
+ });
412
+ it("Throws error when order=True and class defines __ge__", () => {
413
+ expect(() => toSourceText([_$createComponent(py.SourceFile, {
414
+ path: "user.py",
415
+ get children() {
416
+ return _$createComponent(py.DataclassDeclaration, {
417
+ name: "User",
418
+ order: true,
419
+ get children() {
420
+ return _$createComponent(py.DunderMethodDeclaration, {
421
+ name: "__ge__"
422
+ }, {
423
+ fileName: import.meta.url,
424
+ lineNumber: 291,
425
+ columnNumber: 15
426
+ });
427
+ }
428
+ }, {
429
+ fileName: import.meta.url,
430
+ lineNumber: 290,
431
+ columnNumber: 13
432
+ });
433
+ }
434
+ }, {
435
+ fileName: import.meta.url,
436
+ lineNumber: 289,
437
+ columnNumber: 11
438
+ })], {
439
+ externals: [dataclassesModule]
440
+ })).toThrowError(/Cannot specify order=True when the class already defines __ge__\(\)/);
441
+ });
442
+ it("Throws error when order=True and a wrapper defines __lt__", () => {
443
+ function Wrapper() {
444
+ return _$createComponent(py.DunderMethodDeclaration, {
445
+ name: "__lt__"
446
+ }, {
447
+ fileName: import.meta.url,
448
+ lineNumber: 304,
449
+ columnNumber: 14
450
+ });
451
+ }
452
+ expect(() => toSourceText([_$createComponent(py.SourceFile, {
453
+ path: "user.py",
454
+ get children() {
455
+ return _$createComponent(py.DataclassDeclaration, {
456
+ name: "User",
457
+ order: true,
458
+ get children() {
459
+ return _$createComponent(Wrapper, {}, {
460
+ fileName: import.meta.url,
461
+ lineNumber: 311,
462
+ columnNumber: 15
463
+ });
464
+ }
465
+ }, {
466
+ fileName: import.meta.url,
467
+ lineNumber: 310,
468
+ columnNumber: 13
469
+ });
470
+ }
471
+ }, {
472
+ fileName: import.meta.url,
473
+ lineNumber: 309,
474
+ columnNumber: 11
475
+ })], {
476
+ externals: [dataclassesModule]
477
+ })).toThrowError(/Cannot specify order=True when the class already defines __lt__\(\)/);
478
+ });
479
+ it("Throws error when unsafe_hash=True and class defines __hash__", () => {
480
+ expect(() => toSourceText([_$createComponent(py.SourceFile, {
481
+ path: "user.py",
482
+ get children() {
483
+ return _$createComponent(py.DataclassDeclaration, {
484
+ name: "User",
485
+ unsafeHash: true,
486
+ get children() {
487
+ return _$createComponent(py.DunderMethodDeclaration, {
488
+ name: "__hash__"
489
+ }, {
490
+ fileName: import.meta.url,
491
+ lineNumber: 328,
492
+ columnNumber: 15
493
+ });
494
+ }
495
+ }, {
496
+ fileName: import.meta.url,
497
+ lineNumber: 327,
498
+ columnNumber: 13
499
+ });
500
+ }
501
+ }, {
502
+ fileName: import.meta.url,
503
+ lineNumber: 326,
504
+ columnNumber: 11
505
+ })], {
506
+ externals: [dataclassesModule]
507
+ })).toThrowError(/Cannot specify unsafe_hash=True when the class already defines __hash__\(\)/);
508
+ });
509
+ it("Throws error when frozen=True and class defines __setattr__", () => {
510
+ expect(() => toSourceText([_$createComponent(py.SourceFile, {
511
+ path: "user.py",
512
+ get children() {
513
+ return _$createComponent(py.DataclassDeclaration, {
514
+ name: "User",
515
+ frozen: true,
516
+ get children() {
517
+ return _$createComponent(py.DunderMethodDeclaration, {
518
+ name: "__setattr__"
519
+ }, {
520
+ fileName: import.meta.url,
521
+ lineNumber: 345,
522
+ columnNumber: 15
523
+ });
524
+ }
525
+ }, {
526
+ fileName: import.meta.url,
527
+ lineNumber: 344,
528
+ columnNumber: 13
529
+ });
530
+ }
531
+ }, {
532
+ fileName: import.meta.url,
533
+ lineNumber: 343,
534
+ columnNumber: 11
535
+ })], {
536
+ externals: [dataclassesModule]
537
+ })).toThrowError(/Cannot specify frozen=True when the class already defines __setattr__\(\)/);
538
+ });
539
+ it("Throws errorwhen frozen=True and class defines __delattr__", () => {
540
+ expect(() => toSourceText([_$createComponent(py.SourceFile, {
541
+ path: "user.py",
542
+ get children() {
543
+ return _$createComponent(py.DataclassDeclaration, {
544
+ name: "User",
545
+ frozen: true,
546
+ get children() {
547
+ return _$createComponent(py.DunderMethodDeclaration, {
548
+ name: "__delattr__"
549
+ }, {
550
+ fileName: import.meta.url,
551
+ lineNumber: 362,
552
+ columnNumber: 15
553
+ });
554
+ }
555
+ }, {
556
+ fileName: import.meta.url,
557
+ lineNumber: 361,
558
+ columnNumber: 13
559
+ });
560
+ }
561
+ }, {
562
+ fileName: import.meta.url,
563
+ lineNumber: 360,
564
+ columnNumber: 11
565
+ })], {
566
+ externals: [dataclassesModule]
567
+ })).toThrowError(/Cannot specify frozen=True when the class already defines __delattr__\(\)/);
568
+ });
569
+ it("Throws error when slots=True and class defines __slots__", () => {
570
+ expect(() => toSourceText([_$createComponent(py.SourceFile, {
571
+ path: "user.py",
572
+ get children() {
573
+ return _$createComponent(py.DataclassDeclaration, {
574
+ name: "User",
575
+ slots: true,
576
+ get children() {
577
+ return _$createComponent(py.DunderMethodDeclaration, {
578
+ name: "__slots__"
579
+ }, {
580
+ fileName: import.meta.url,
581
+ lineNumber: 379,
582
+ columnNumber: 15
583
+ });
584
+ }
585
+ }, {
586
+ fileName: import.meta.url,
587
+ lineNumber: 378,
588
+ columnNumber: 13
589
+ });
590
+ }
591
+ }, {
592
+ fileName: import.meta.url,
593
+ lineNumber: 377,
594
+ columnNumber: 11
595
+ })], {
596
+ externals: [dataclassesModule]
597
+ })).toThrowError(/Cannot specify slots=True when the class already defines __slots__\(\)/);
598
+ });
599
+ it("Creates a dataclass with kw_only=True on decorator (sentinel not used)", () => {
600
+ const res = toSourceText([_$createComponent(py.SourceFile, {
601
+ path: "user.py",
602
+ get children() {
603
+ return _$createComponent(py.DataclassDeclaration, {
604
+ name: "User",
605
+ kwOnly: true,
606
+ get children() {
607
+ return _$createComponent(py.VariableDeclaration, {
608
+ instanceVariable: true,
609
+ omitNone: true,
610
+ name: "id",
611
+ type: "int"
612
+ }, {
613
+ fileName: import.meta.url,
614
+ lineNumber: 395,
615
+ columnNumber: 13
616
+ });
617
+ }
618
+ }, {
619
+ fileName: import.meta.url,
620
+ lineNumber: 394,
621
+ columnNumber: 11
622
+ });
623
+ }
624
+ }, {
625
+ fileName: import.meta.url,
626
+ lineNumber: 393,
627
+ columnNumber: 9
628
+ })], {
629
+ externals: [dataclassesModule]
630
+ });
631
+ expect(res).toRenderTo(d`
632
+ from dataclasses import dataclass
633
+
634
+
635
+ @dataclass(kw_only=True)
636
+ class User:
637
+ id: int
638
+
639
+
640
+ `);
641
+ });
642
+ it("Creates a dataclass with base classes", () => {
643
+ const res = toSourceText([_$createComponent(py.SourceFile, {
644
+ path: "user.py",
645
+ get children() {
646
+ return _$createComponent(py.DataclassDeclaration, {
647
+ name: "User",
648
+ bases: ["Base"]
649
+ }, {
650
+ fileName: import.meta.url,
651
+ lineNumber: 424,
652
+ columnNumber: 11
653
+ });
654
+ }
655
+ }, {
656
+ fileName: import.meta.url,
657
+ lineNumber: 423,
658
+ columnNumber: 9
659
+ })], {
660
+ externals: [dataclassesModule]
661
+ });
662
+ expect(res).toRenderTo(d`
663
+ from dataclasses import dataclass
664
+
665
+
666
+ @dataclass
667
+ class User(Base):
668
+ pass
669
+
670
+
671
+ `);
672
+ });
673
+ it("Throws error when more than one KW_ONLY sentinel is present", () => {
674
+ expect(() => toSourceText([_$createComponent(py.SourceFile, {
675
+ path: "user.py",
676
+ get children() {
677
+ return _$createComponent(py.DataclassDeclaration, {
678
+ name: "User",
679
+ get children() {
680
+ return [_$createComponent(py.VariableDeclaration, {
681
+ instanceVariable: true,
682
+ get name() {
683
+ return namekey("_", {
684
+ ignoreNamePolicy: true
685
+ });
686
+ },
687
+ get type() {
688
+ return dataclassesModule["."].KW_ONLY;
689
+ },
690
+ omitNone: true
691
+ }, {
692
+ fileName: import.meta.url,
693
+ lineNumber: 450,
694
+ columnNumber: 15
695
+ }), _$createComponent(py.VariableDeclaration, {
696
+ instanceVariable: true,
697
+ get name() {
698
+ return namekey("_", {
699
+ ignoreNamePolicy: true
700
+ });
701
+ },
702
+ get type() {
703
+ return dataclassesModule["."].KW_ONLY;
704
+ },
705
+ omitNone: true
706
+ }, {
707
+ fileName: import.meta.url,
708
+ lineNumber: 456,
709
+ columnNumber: 15
710
+ })];
711
+ }
712
+ }, {
713
+ fileName: import.meta.url,
714
+ lineNumber: 449,
715
+ columnNumber: 13
716
+ });
717
+ }
718
+ }, {
719
+ fileName: import.meta.url,
720
+ lineNumber: 448,
721
+ columnNumber: 11
722
+ })], {
723
+ externals: [dataclassesModule]
724
+ })).toThrowError(/Only one KW_ONLY sentinel is allowed per dataclass body/);
725
+ });
726
+ it("Will raise arg validation errors first over member conflicts", () => {
727
+ expect(() => toSourceText([_$createComponent(py.SourceFile, {
728
+ path: "user.py",
729
+ get children() {
730
+ return _$createComponent(py.DataclassDeclaration, {
731
+ name: "User",
732
+ order: true,
733
+ eq: false,
734
+ get children() {
735
+ return _$createComponent(py.DunderMethodDeclaration, {
736
+ name: "__lt__"
737
+ }, {
738
+ fileName: import.meta.url,
739
+ lineNumber: 476,
740
+ columnNumber: 15
741
+ });
742
+ }
743
+ }, {
744
+ fileName: import.meta.url,
745
+ lineNumber: 475,
746
+ columnNumber: 13
747
+ });
748
+ }
749
+ }, {
750
+ fileName: import.meta.url,
751
+ lineNumber: 474,
752
+ columnNumber: 11
753
+ })], {
754
+ externals: [dataclassesModule]
755
+ })).toThrowError(/order=True requires eq=True/);
756
+ });
757
+ it("Does not raise errors for member conflict checks without the equivalent kwargs", () => {
758
+ expect(() => toSourceText([_$createComponent(py.SourceFile, {
759
+ path: "user.py",
760
+ get children() {
761
+ return _$createComponent(py.DataclassDeclaration, {
762
+ name: "User",
763
+ get children() {
764
+ return [_$createComponent(py.DunderMethodDeclaration, {
765
+ name: "__lt__"
766
+ }, {
767
+ fileName: import.meta.url,
768
+ lineNumber: 491,
769
+ columnNumber: 15
770
+ }), _$createComponent(py.DunderMethodDeclaration, {
771
+ name: "__slots__"
772
+ }, {
773
+ fileName: import.meta.url,
774
+ lineNumber: 492,
775
+ columnNumber: 15
776
+ }), _$createComponent(py.DunderMethodDeclaration, {
777
+ name: "__hash__"
778
+ }, {
779
+ fileName: import.meta.url,
780
+ lineNumber: 493,
781
+ columnNumber: 15
782
+ }), _$createComponent(py.DunderMethodDeclaration, {
783
+ name: "__setattr__"
784
+ }, {
785
+ fileName: import.meta.url,
786
+ lineNumber: 494,
787
+ columnNumber: 15
788
+ }), _$createComponent(py.DunderMethodDeclaration, {
789
+ name: "__delattr__"
790
+ }, {
791
+ fileName: import.meta.url,
792
+ lineNumber: 495,
793
+ columnNumber: 15
794
+ })];
795
+ }
796
+ }, {
797
+ fileName: import.meta.url,
798
+ lineNumber: 490,
799
+ columnNumber: 13
800
+ });
801
+ }
802
+ }, {
803
+ fileName: import.meta.url,
804
+ lineNumber: 489,
805
+ columnNumber: 11
806
+ })], {
807
+ externals: [dataclassesModule]
808
+ })).not.toThrow();
809
+ });
810
+ it("Allows unsafe_hash=True when no __hash__ is defined", () => {
811
+ const res = toSourceText([_$createComponent(py.SourceFile, {
812
+ path: "user.py",
813
+ get children() {
814
+ return _$createComponent(py.DataclassDeclaration, {
815
+ name: "User",
816
+ unsafeHash: true
817
+ }, {
818
+ fileName: import.meta.url,
819
+ lineNumber: 508,
820
+ columnNumber: 11
821
+ });
822
+ }
823
+ }, {
824
+ fileName: import.meta.url,
825
+ lineNumber: 507,
826
+ columnNumber: 9
827
+ })], {
828
+ externals: [dataclassesModule]
829
+ });
830
+ expect(res).toRenderTo(d`
831
+ from dataclasses import dataclass
832
+
833
+
834
+ @dataclass(unsafe_hash=True)
835
+ class User:
836
+ pass
837
+
838
+
839
+ `);
840
+ });
841
+ it("Counts KW_ONLY sentinels through wrappers (symbol-level)", () => {
842
+ function Wrapper() {
843
+ return _$createComponent(py.VariableDeclaration, {
844
+ instanceVariable: true,
845
+ get name() {
846
+ return namekey("_", {
847
+ ignoreNamePolicy: true
848
+ });
849
+ },
850
+ get type() {
851
+ return dataclassesModule["."].KW_ONLY;
852
+ },
853
+ omitNone: true
854
+ }, {
855
+ fileName: import.meta.url,
856
+ lineNumber: 530,
857
+ columnNumber: 9
858
+ });
859
+ }
860
+ expect(() => toSourceText([_$createComponent(py.SourceFile, {
861
+ path: "user.py",
862
+ get children() {
863
+ return _$createComponent(py.DataclassDeclaration, {
864
+ name: "User",
865
+ get children() {
866
+ return [_$createComponent(py.VariableDeclaration, {
867
+ instanceVariable: true,
868
+ get name() {
869
+ return namekey("_", {
870
+ ignoreNamePolicy: true
871
+ });
872
+ },
873
+ get type() {
874
+ return dataclassesModule["."].KW_ONLY;
875
+ },
876
+ omitNone: true
877
+ }, {
878
+ fileName: import.meta.url,
879
+ lineNumber: 543,
880
+ columnNumber: 15
881
+ }), _$createComponent(Wrapper, {}, {
882
+ fileName: import.meta.url,
883
+ lineNumber: 549,
884
+ columnNumber: 15
885
+ })];
886
+ }
887
+ }, {
888
+ fileName: import.meta.url,
889
+ lineNumber: 542,
890
+ columnNumber: 13
891
+ });
892
+ }
893
+ }, {
894
+ fileName: import.meta.url,
895
+ lineNumber: 541,
896
+ columnNumber: 11
897
+ })], {
898
+ externals: [dataclassesModule]
899
+ })).toThrowError(/Only one KW_ONLY sentinel is allowed per dataclass body/);
900
+ });
901
+ it("Allows frozen=True when no conflicting dunders exist", () => {
902
+ const res = toSourceText([_$createComponent(py.SourceFile, {
903
+ path: "user.py",
904
+ get children() {
905
+ return _$createComponent(py.DataclassDeclaration, {
906
+ name: "User",
907
+ frozen: true
908
+ }, {
909
+ fileName: import.meta.url,
910
+ lineNumber: 562,
911
+ columnNumber: 11
912
+ });
913
+ }
914
+ }, {
915
+ fileName: import.meta.url,
916
+ lineNumber: 561,
917
+ columnNumber: 9
918
+ })], {
919
+ externals: [dataclassesModule]
920
+ });
921
+ expect(res).toRenderTo(d`
922
+ from dataclasses import dataclass
923
+
924
+
925
+ @dataclass(frozen=True)
926
+ class User:
927
+ pass
928
+
929
+
930
+ `);
931
+ });
932
+ it("Allows slots=True when no __slots__ is defined", () => {
933
+ const res = toSourceText([_$createComponent(py.SourceFile, {
934
+ path: "user.py",
935
+ get children() {
936
+ return _$createComponent(py.DataclassDeclaration, {
937
+ name: "User",
938
+ slots: true
939
+ }, {
940
+ fileName: import.meta.url,
941
+ lineNumber: 585,
942
+ columnNumber: 11
943
+ });
944
+ }
945
+ }, {
946
+ fileName: import.meta.url,
947
+ lineNumber: 584,
948
+ columnNumber: 9
949
+ })], {
950
+ externals: [dataclassesModule]
951
+ });
952
+ expect(res).toRenderTo(d`
953
+ from dataclasses import dataclass
954
+
955
+
956
+ @dataclass(slots=True)
957
+ class User:
958
+ pass
959
+
960
+
961
+ `);
962
+ });
963
+ it("Forwards refkey prop for symbol resolution in type references", () => {
964
+ const userRefkey = refkey();
965
+ const res = toSourceTextMultiple([_$createComponent(py.SourceFile, {
966
+ path: "models.py",
967
+ get children() {
968
+ return _$createComponent(py.DataclassDeclaration, {
969
+ name: "User",
970
+ refkey: userRefkey,
971
+ get children() {
972
+ return [_$createComponent(py.VariableDeclaration, {
973
+ instanceVariable: true,
974
+ omitNone: true,
975
+ name: "id",
976
+ type: "int"
977
+ }, {
978
+ fileName: import.meta.url,
979
+ lineNumber: 610,
980
+ columnNumber: 13
981
+ }), _$createComponent(py.VariableDeclaration, {
982
+ instanceVariable: true,
983
+ omitNone: true,
984
+ name: "name",
985
+ type: "str"
986
+ }, {
987
+ fileName: import.meta.url,
988
+ lineNumber: 616,
989
+ columnNumber: 13
990
+ })];
991
+ }
992
+ }, {
993
+ fileName: import.meta.url,
994
+ lineNumber: 609,
995
+ columnNumber: 11
996
+ });
997
+ }
998
+ }, {
999
+ fileName: import.meta.url,
1000
+ lineNumber: 608,
1001
+ columnNumber: 9
1002
+ }), _$createComponent(py.SourceFile, {
1003
+ path: "services.py",
1004
+ get children() {
1005
+ return _$createComponent(py.FunctionDeclaration, {
1006
+ name: "get_user",
1007
+ returnType: userRefkey,
1008
+ get children() {
1009
+ return [_$createComponent(py.VariableDeclaration, {
1010
+ name: "user",
1011
+ type: userRefkey,
1012
+ get initializer() {
1013
+ return _$createComponent(py.ClassInstantiation, {
1014
+ target: userRefkey,
1015
+ args: ["1", '"Alice"']
1016
+ }, {
1017
+ fileName: import.meta.url,
1018
+ lineNumber: 630,
1019
+ columnNumber: 17
1020
+ });
1021
+ }
1022
+ }, {
1023
+ fileName: import.meta.url,
1024
+ lineNumber: 626,
1025
+ columnNumber: 13
1026
+ }), _$createIntrinsic("hbr", {}, {
1027
+ fileName: import.meta.url,
1028
+ lineNumber: 636,
1029
+ columnNumber: 13
1030
+ }), "return user"];
1031
+ }
1032
+ }, {
1033
+ fileName: import.meta.url,
1034
+ lineNumber: 625,
1035
+ columnNumber: 11
1036
+ });
1037
+ }
1038
+ }, {
1039
+ fileName: import.meta.url,
1040
+ lineNumber: 624,
1041
+ columnNumber: 9
1042
+ })], {
1043
+ externals: [dataclassesModule]
1044
+ });
1045
+ assertFileContents(res, {
1046
+ "models.py": `
1047
+ from dataclasses import dataclass
1048
+
1049
+
1050
+ @dataclass
1051
+ class User:
1052
+ id: int
1053
+ name: str
1054
+
1055
+ `,
1056
+ "services.py": `
1057
+ from models import User
1058
+
1059
+
1060
+ def get_user() -> User:
1061
+ user: User = User(1, "Alice")
1062
+ return user
1063
+
1064
+ `
1065
+ });
1066
+ });
1067
+ });
1068
+ //# sourceMappingURL=dataclassdeclarations.test.js.map