frida 16.2.0 → 16.2.2

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 (386) hide show
  1. package/BSDmakefile +6 -0
  2. package/Makefile +16 -0
  3. package/README.md +14 -11
  4. package/configure +18 -0
  5. package/configure.bat +22 -0
  6. package/dist/native.js +0 -8
  7. package/lib/application.ts +98 -0
  8. package/lib/authentication.ts +3 -0
  9. package/lib/build.py +50 -0
  10. package/lib/bus.ts +30 -0
  11. package/lib/cancellable.ts +33 -0
  12. package/lib/child.ts +15 -0
  13. package/lib/crash.ts +11 -0
  14. package/lib/device.ts +329 -0
  15. package/lib/device_manager.ts +69 -0
  16. package/lib/endpoint_parameters.ts +56 -0
  17. package/lib/icon.ts +15 -0
  18. package/lib/index.ts +311 -0
  19. package/lib/iostream.ts +78 -0
  20. package/lib/meson.build +53 -0
  21. package/lib/native.ts +9 -0
  22. package/lib/portal_membership.ts +10 -0
  23. package/lib/portal_service.ts +105 -0
  24. package/lib/process.ts +57 -0
  25. package/lib/relay.ts +44 -0
  26. package/lib/script.ts +352 -0
  27. package/lib/session.ts +113 -0
  28. package/lib/signals.ts +45 -0
  29. package/lib/socket_address.ts +35 -0
  30. package/lib/spawn.ts +4 -0
  31. package/lib/system_parameters.ts +78 -0
  32. package/make.bat +23 -0
  33. package/meson.build +160 -0
  34. package/meson.options +11 -0
  35. package/package.json +27 -6
  36. package/releng/deps.py +1133 -0
  37. package/releng/deps.toml +391 -0
  38. package/releng/devkit-assets/frida-core-example-unix.c +188 -0
  39. package/releng/devkit-assets/frida-core-example-windows.c +197 -0
  40. package/releng/devkit-assets/frida-core-example.sln +28 -0
  41. package/releng/devkit-assets/frida-core-example.vcxproj +157 -0
  42. package/releng/devkit-assets/frida-core-example.vcxproj.filters +27 -0
  43. package/releng/devkit-assets/frida-gum-example-unix.c +122 -0
  44. package/releng/devkit-assets/frida-gum-example-windows.c +132 -0
  45. package/releng/devkit-assets/frida-gum-example.sln +28 -0
  46. package/releng/devkit-assets/frida-gum-example.vcxproj +157 -0
  47. package/releng/devkit-assets/frida-gum-example.vcxproj.filters +27 -0
  48. package/releng/devkit-assets/frida-gumjs-example-unix.c +84 -0
  49. package/releng/devkit-assets/frida-gumjs-example-windows.c +91 -0
  50. package/releng/devkit-assets/frida-gumjs-example.sln +28 -0
  51. package/releng/devkit-assets/frida-gumjs-example.vcxproj +157 -0
  52. package/releng/devkit-assets/frida-gumjs-example.vcxproj.filters +27 -0
  53. package/releng/devkit.py +535 -0
  54. package/releng/env.py +420 -0
  55. package/releng/env_android.py +150 -0
  56. package/releng/env_apple.py +176 -0
  57. package/releng/env_generic.py +373 -0
  58. package/releng/frida_version.py +69 -0
  59. package/releng/machine_file.py +44 -0
  60. package/releng/machine_spec.py +290 -0
  61. package/releng/meson/meson.py +27 -0
  62. package/releng/meson/mesonbuild/__init__.py +0 -0
  63. package/releng/meson/mesonbuild/_pathlib.py +63 -0
  64. package/releng/meson/mesonbuild/_typing.py +69 -0
  65. package/releng/meson/mesonbuild/arglist.py +321 -0
  66. package/releng/meson/mesonbuild/ast/__init__.py +23 -0
  67. package/releng/meson/mesonbuild/ast/interpreter.py +441 -0
  68. package/releng/meson/mesonbuild/ast/introspection.py +374 -0
  69. package/releng/meson/mesonbuild/ast/postprocess.py +109 -0
  70. package/releng/meson/mesonbuild/ast/printer.py +620 -0
  71. package/releng/meson/mesonbuild/ast/visitor.py +161 -0
  72. package/releng/meson/mesonbuild/backend/__init__.py +0 -0
  73. package/releng/meson/mesonbuild/backend/backends.py +2047 -0
  74. package/releng/meson/mesonbuild/backend/ninjabackend.py +3808 -0
  75. package/releng/meson/mesonbuild/backend/nonebackend.py +26 -0
  76. package/releng/meson/mesonbuild/backend/vs2010backend.py +2078 -0
  77. package/releng/meson/mesonbuild/backend/vs2012backend.py +35 -0
  78. package/releng/meson/mesonbuild/backend/vs2013backend.py +34 -0
  79. package/releng/meson/mesonbuild/backend/vs2015backend.py +35 -0
  80. package/releng/meson/mesonbuild/backend/vs2017backend.py +59 -0
  81. package/releng/meson/mesonbuild/backend/vs2019backend.py +54 -0
  82. package/releng/meson/mesonbuild/backend/vs2022backend.py +54 -0
  83. package/releng/meson/mesonbuild/backend/xcodebackend.py +1781 -0
  84. package/releng/meson/mesonbuild/build.py +3249 -0
  85. package/releng/meson/mesonbuild/cargo/__init__.py +5 -0
  86. package/releng/meson/mesonbuild/cargo/builder.py +238 -0
  87. package/releng/meson/mesonbuild/cargo/cfg.py +274 -0
  88. package/releng/meson/mesonbuild/cargo/interpreter.py +733 -0
  89. package/releng/meson/mesonbuild/cargo/manifest.py +227 -0
  90. package/releng/meson/mesonbuild/cargo/version.py +95 -0
  91. package/releng/meson/mesonbuild/cmake/__init__.py +28 -0
  92. package/releng/meson/mesonbuild/cmake/common.py +331 -0
  93. package/releng/meson/mesonbuild/cmake/data/__init__.py +0 -0
  94. package/releng/meson/mesonbuild/cmake/data/preload.cmake +82 -0
  95. package/releng/meson/mesonbuild/cmake/executor.py +241 -0
  96. package/releng/meson/mesonbuild/cmake/fileapi.py +324 -0
  97. package/releng/meson/mesonbuild/cmake/generator.py +186 -0
  98. package/releng/meson/mesonbuild/cmake/interpreter.py +1267 -0
  99. package/releng/meson/mesonbuild/cmake/toolchain.py +248 -0
  100. package/releng/meson/mesonbuild/cmake/traceparser.py +814 -0
  101. package/releng/meson/mesonbuild/cmake/tracetargets.py +161 -0
  102. package/releng/meson/mesonbuild/compilers/__init__.py +86 -0
  103. package/releng/meson/mesonbuild/compilers/asm.py +307 -0
  104. package/releng/meson/mesonbuild/compilers/c.py +788 -0
  105. package/releng/meson/mesonbuild/compilers/c_function_attributes.py +143 -0
  106. package/releng/meson/mesonbuild/compilers/compilers.py +1388 -0
  107. package/releng/meson/mesonbuild/compilers/cpp.py +1035 -0
  108. package/releng/meson/mesonbuild/compilers/cs.py +136 -0
  109. package/releng/meson/mesonbuild/compilers/cuda.py +806 -0
  110. package/releng/meson/mesonbuild/compilers/cython.py +91 -0
  111. package/releng/meson/mesonbuild/compilers/d.py +861 -0
  112. package/releng/meson/mesonbuild/compilers/detect.py +1396 -0
  113. package/releng/meson/mesonbuild/compilers/fortran.py +523 -0
  114. package/releng/meson/mesonbuild/compilers/java.py +113 -0
  115. package/releng/meson/mesonbuild/compilers/mixins/__init__.py +0 -0
  116. package/releng/meson/mesonbuild/compilers/mixins/arm.py +167 -0
  117. package/releng/meson/mesonbuild/compilers/mixins/ccrx.py +113 -0
  118. package/releng/meson/mesonbuild/compilers/mixins/clang.py +170 -0
  119. package/releng/meson/mesonbuild/compilers/mixins/clike.py +1330 -0
  120. package/releng/meson/mesonbuild/compilers/mixins/compcert.py +117 -0
  121. package/releng/meson/mesonbuild/compilers/mixins/elbrus.py +93 -0
  122. package/releng/meson/mesonbuild/compilers/mixins/emscripten.py +89 -0
  123. package/releng/meson/mesonbuild/compilers/mixins/gnu.py +629 -0
  124. package/releng/meson/mesonbuild/compilers/mixins/intel.py +167 -0
  125. package/releng/meson/mesonbuild/compilers/mixins/islinker.py +120 -0
  126. package/releng/meson/mesonbuild/compilers/mixins/metrowerks.py +279 -0
  127. package/releng/meson/mesonbuild/compilers/mixins/pgi.py +88 -0
  128. package/releng/meson/mesonbuild/compilers/mixins/ti.py +130 -0
  129. package/releng/meson/mesonbuild/compilers/mixins/visualstudio.py +458 -0
  130. package/releng/meson/mesonbuild/compilers/mixins/xc16.py +111 -0
  131. package/releng/meson/mesonbuild/compilers/objc.py +120 -0
  132. package/releng/meson/mesonbuild/compilers/objcpp.py +102 -0
  133. package/releng/meson/mesonbuild/compilers/rust.py +230 -0
  134. package/releng/meson/mesonbuild/compilers/swift.py +131 -0
  135. package/releng/meson/mesonbuild/compilers/vala.py +121 -0
  136. package/releng/meson/mesonbuild/coredata.py +1532 -0
  137. package/releng/meson/mesonbuild/dependencies/__init__.py +252 -0
  138. package/releng/meson/mesonbuild/dependencies/base.py +663 -0
  139. package/releng/meson/mesonbuild/dependencies/boost.py +1083 -0
  140. package/releng/meson/mesonbuild/dependencies/cmake.py +656 -0
  141. package/releng/meson/mesonbuild/dependencies/coarrays.py +80 -0
  142. package/releng/meson/mesonbuild/dependencies/configtool.py +163 -0
  143. package/releng/meson/mesonbuild/dependencies/cuda.py +295 -0
  144. package/releng/meson/mesonbuild/dependencies/data/CMakeLists.txt +102 -0
  145. package/releng/meson/mesonbuild/dependencies/data/CMakeListsLLVM.txt +204 -0
  146. package/releng/meson/mesonbuild/dependencies/data/CMakePathInfo.txt +31 -0
  147. package/releng/meson/mesonbuild/dependencies/data/__init__.py +0 -0
  148. package/releng/meson/mesonbuild/dependencies/detect.py +225 -0
  149. package/releng/meson/mesonbuild/dependencies/dev.py +707 -0
  150. package/releng/meson/mesonbuild/dependencies/dub.py +424 -0
  151. package/releng/meson/mesonbuild/dependencies/factory.py +146 -0
  152. package/releng/meson/mesonbuild/dependencies/framework.py +111 -0
  153. package/releng/meson/mesonbuild/dependencies/hdf5.py +168 -0
  154. package/releng/meson/mesonbuild/dependencies/misc.py +618 -0
  155. package/releng/meson/mesonbuild/dependencies/mpi.py +231 -0
  156. package/releng/meson/mesonbuild/dependencies/pkgconfig.py +570 -0
  157. package/releng/meson/mesonbuild/dependencies/platform.py +52 -0
  158. package/releng/meson/mesonbuild/dependencies/python.py +431 -0
  159. package/releng/meson/mesonbuild/dependencies/qt.py +484 -0
  160. package/releng/meson/mesonbuild/dependencies/scalapack.py +142 -0
  161. package/releng/meson/mesonbuild/dependencies/ui.py +281 -0
  162. package/releng/meson/mesonbuild/depfile.py +82 -0
  163. package/releng/meson/mesonbuild/envconfig.py +480 -0
  164. package/releng/meson/mesonbuild/environment.py +987 -0
  165. package/releng/meson/mesonbuild/interpreter/__init__.py +47 -0
  166. package/releng/meson/mesonbuild/interpreter/compiler.py +900 -0
  167. package/releng/meson/mesonbuild/interpreter/dependencyfallbacks.py +386 -0
  168. package/releng/meson/mesonbuild/interpreter/interpreter.py +3595 -0
  169. package/releng/meson/mesonbuild/interpreter/interpreterobjects.py +1096 -0
  170. package/releng/meson/mesonbuild/interpreter/kwargs.py +479 -0
  171. package/releng/meson/mesonbuild/interpreter/mesonmain.py +487 -0
  172. package/releng/meson/mesonbuild/interpreter/primitives/__init__.py +29 -0
  173. package/releng/meson/mesonbuild/interpreter/primitives/array.py +108 -0
  174. package/releng/meson/mesonbuild/interpreter/primitives/boolean.py +52 -0
  175. package/releng/meson/mesonbuild/interpreter/primitives/dict.py +88 -0
  176. package/releng/meson/mesonbuild/interpreter/primitives/integer.py +86 -0
  177. package/releng/meson/mesonbuild/interpreter/primitives/range.py +38 -0
  178. package/releng/meson/mesonbuild/interpreter/primitives/string.py +247 -0
  179. package/releng/meson/mesonbuild/interpreter/type_checking.py +853 -0
  180. package/releng/meson/mesonbuild/interpreterbase/__init__.py +126 -0
  181. package/releng/meson/mesonbuild/interpreterbase/_unholder.py +25 -0
  182. package/releng/meson/mesonbuild/interpreterbase/baseobjects.py +174 -0
  183. package/releng/meson/mesonbuild/interpreterbase/decorators.py +806 -0
  184. package/releng/meson/mesonbuild/interpreterbase/disabler.py +35 -0
  185. package/releng/meson/mesonbuild/interpreterbase/exceptions.py +22 -0
  186. package/releng/meson/mesonbuild/interpreterbase/helpers.py +67 -0
  187. package/releng/meson/mesonbuild/interpreterbase/interpreterbase.py +665 -0
  188. package/releng/meson/mesonbuild/interpreterbase/operator.py +32 -0
  189. package/releng/meson/mesonbuild/linkers/__init__.py +20 -0
  190. package/releng/meson/mesonbuild/linkers/base.py +39 -0
  191. package/releng/meson/mesonbuild/linkers/detect.py +229 -0
  192. package/releng/meson/mesonbuild/linkers/linkers.py +1614 -0
  193. package/releng/meson/mesonbuild/mcompile.py +380 -0
  194. package/releng/meson/mesonbuild/mconf.py +368 -0
  195. package/releng/meson/mesonbuild/mdevenv.py +234 -0
  196. package/releng/meson/mesonbuild/mdist.py +376 -0
  197. package/releng/meson/mesonbuild/mesondata.py +38 -0
  198. package/releng/meson/mesonbuild/mesonlib.py +23 -0
  199. package/releng/meson/mesonbuild/mesonmain.py +289 -0
  200. package/releng/meson/mesonbuild/minit.py +204 -0
  201. package/releng/meson/mesonbuild/minstall.py +864 -0
  202. package/releng/meson/mesonbuild/mintro.py +667 -0
  203. package/releng/meson/mesonbuild/mlog.py +542 -0
  204. package/releng/meson/mesonbuild/modules/__init__.py +270 -0
  205. package/releng/meson/mesonbuild/modules/cmake.py +442 -0
  206. package/releng/meson/mesonbuild/modules/cuda.py +377 -0
  207. package/releng/meson/mesonbuild/modules/dlang.py +117 -0
  208. package/releng/meson/mesonbuild/modules/external_project.py +306 -0
  209. package/releng/meson/mesonbuild/modules/fs.py +323 -0
  210. package/releng/meson/mesonbuild/modules/gnome.py +2215 -0
  211. package/releng/meson/mesonbuild/modules/hotdoc.py +487 -0
  212. package/releng/meson/mesonbuild/modules/i18n.py +405 -0
  213. package/releng/meson/mesonbuild/modules/icestorm.py +123 -0
  214. package/releng/meson/mesonbuild/modules/java.py +112 -0
  215. package/releng/meson/mesonbuild/modules/keyval.py +65 -0
  216. package/releng/meson/mesonbuild/modules/modtest.py +33 -0
  217. package/releng/meson/mesonbuild/modules/pkgconfig.py +744 -0
  218. package/releng/meson/mesonbuild/modules/python.py +556 -0
  219. package/releng/meson/mesonbuild/modules/python3.py +85 -0
  220. package/releng/meson/mesonbuild/modules/qt.py +621 -0
  221. package/releng/meson/mesonbuild/modules/qt4.py +23 -0
  222. package/releng/meson/mesonbuild/modules/qt5.py +23 -0
  223. package/releng/meson/mesonbuild/modules/qt6.py +22 -0
  224. package/releng/meson/mesonbuild/modules/rust.py +355 -0
  225. package/releng/meson/mesonbuild/modules/simd.py +114 -0
  226. package/releng/meson/mesonbuild/modules/sourceset.py +291 -0
  227. package/releng/meson/mesonbuild/modules/wayland.py +151 -0
  228. package/releng/meson/mesonbuild/modules/windows.py +207 -0
  229. package/releng/meson/mesonbuild/mparser.py +1114 -0
  230. package/releng/meson/mesonbuild/msetup.py +365 -0
  231. package/releng/meson/mesonbuild/msubprojects.py +764 -0
  232. package/releng/meson/mesonbuild/mtest.py +2201 -0
  233. package/releng/meson/mesonbuild/munstable_coredata.py +107 -0
  234. package/releng/meson/mesonbuild/optinterpreter.py +276 -0
  235. package/releng/meson/mesonbuild/programs.py +367 -0
  236. package/releng/meson/mesonbuild/rewriter.py +1075 -0
  237. package/releng/meson/mesonbuild/scripts/__init__.py +10 -0
  238. package/releng/meson/mesonbuild/scripts/clangformat.py +55 -0
  239. package/releng/meson/mesonbuild/scripts/clangtidy.py +30 -0
  240. package/releng/meson/mesonbuild/scripts/cleantrees.py +35 -0
  241. package/releng/meson/mesonbuild/scripts/cmake_run_ctgt.py +103 -0
  242. package/releng/meson/mesonbuild/scripts/cmd_or_ps.ps1 +17 -0
  243. package/releng/meson/mesonbuild/scripts/copy.py +19 -0
  244. package/releng/meson/mesonbuild/scripts/coverage.py +214 -0
  245. package/releng/meson/mesonbuild/scripts/delwithsuffix.py +27 -0
  246. package/releng/meson/mesonbuild/scripts/depfixer.py +495 -0
  247. package/releng/meson/mesonbuild/scripts/depscan.py +198 -0
  248. package/releng/meson/mesonbuild/scripts/dirchanger.py +20 -0
  249. package/releng/meson/mesonbuild/scripts/env2mfile.py +402 -0
  250. package/releng/meson/mesonbuild/scripts/externalproject.py +106 -0
  251. package/releng/meson/mesonbuild/scripts/gettext.py +86 -0
  252. package/releng/meson/mesonbuild/scripts/gtkdochelper.py +286 -0
  253. package/releng/meson/mesonbuild/scripts/hotdochelper.py +40 -0
  254. package/releng/meson/mesonbuild/scripts/itstool.py +77 -0
  255. package/releng/meson/mesonbuild/scripts/meson_exe.py +115 -0
  256. package/releng/meson/mesonbuild/scripts/msgfmthelper.py +29 -0
  257. package/releng/meson/mesonbuild/scripts/pycompile.py +54 -0
  258. package/releng/meson/mesonbuild/scripts/python_info.py +121 -0
  259. package/releng/meson/mesonbuild/scripts/regen_checker.py +55 -0
  260. package/releng/meson/mesonbuild/scripts/run_tool.py +58 -0
  261. package/releng/meson/mesonbuild/scripts/scanbuild.py +57 -0
  262. package/releng/meson/mesonbuild/scripts/symbolextractor.py +322 -0
  263. package/releng/meson/mesonbuild/scripts/tags.py +44 -0
  264. package/releng/meson/mesonbuild/scripts/test_loaded_modules.py +14 -0
  265. package/releng/meson/mesonbuild/scripts/uninstall.py +41 -0
  266. package/releng/meson/mesonbuild/scripts/vcstagger.py +35 -0
  267. package/releng/meson/mesonbuild/scripts/yasm.py +24 -0
  268. package/releng/meson/mesonbuild/templates/__init__.py +0 -0
  269. package/releng/meson/mesonbuild/templates/cpptemplates.py +143 -0
  270. package/releng/meson/mesonbuild/templates/cstemplates.py +90 -0
  271. package/releng/meson/mesonbuild/templates/ctemplates.py +126 -0
  272. package/releng/meson/mesonbuild/templates/cudatemplates.py +143 -0
  273. package/releng/meson/mesonbuild/templates/dlangtemplates.py +109 -0
  274. package/releng/meson/mesonbuild/templates/fortrantemplates.py +101 -0
  275. package/releng/meson/mesonbuild/templates/javatemplates.py +94 -0
  276. package/releng/meson/mesonbuild/templates/mesontemplates.py +70 -0
  277. package/releng/meson/mesonbuild/templates/objcpptemplates.py +126 -0
  278. package/releng/meson/mesonbuild/templates/objctemplates.py +126 -0
  279. package/releng/meson/mesonbuild/templates/rusttemplates.py +79 -0
  280. package/releng/meson/mesonbuild/templates/samplefactory.py +41 -0
  281. package/releng/meson/mesonbuild/templates/sampleimpl.py +160 -0
  282. package/releng/meson/mesonbuild/templates/valatemplates.py +82 -0
  283. package/releng/meson/mesonbuild/utils/__init__.py +0 -0
  284. package/releng/meson/mesonbuild/utils/core.py +166 -0
  285. package/releng/meson/mesonbuild/utils/platform.py +27 -0
  286. package/releng/meson/mesonbuild/utils/posix.py +32 -0
  287. package/releng/meson/mesonbuild/utils/universal.py +2445 -0
  288. package/releng/meson/mesonbuild/utils/vsenv.py +126 -0
  289. package/releng/meson/mesonbuild/utils/win32.py +29 -0
  290. package/releng/meson/mesonbuild/wrap/__init__.py +59 -0
  291. package/releng/meson/mesonbuild/wrap/wrap.py +846 -0
  292. package/releng/meson/mesonbuild/wrap/wraptool.py +198 -0
  293. package/releng/meson-scripts/BSDmakefile +6 -0
  294. package/releng/meson-scripts/Makefile +16 -0
  295. package/releng/meson-scripts/configure +18 -0
  296. package/releng/meson-scripts/configure.bat +22 -0
  297. package/releng/meson-scripts/make.bat +23 -0
  298. package/releng/meson_configure.py +506 -0
  299. package/releng/meson_make.py +131 -0
  300. package/releng/mkdevkit.py +107 -0
  301. package/releng/mkfatmacho.py +54 -0
  302. package/releng/post-process-oabi.py +97 -0
  303. package/releng/progress.py +14 -0
  304. package/releng/sync-from-upstream.py +185 -0
  305. package/releng/tomlkit/tomlkit/__init__.py +59 -0
  306. package/releng/tomlkit/tomlkit/_compat.py +22 -0
  307. package/releng/tomlkit/tomlkit/_types.py +83 -0
  308. package/releng/tomlkit/tomlkit/_utils.py +158 -0
  309. package/releng/tomlkit/tomlkit/api.py +308 -0
  310. package/releng/tomlkit/tomlkit/container.py +875 -0
  311. package/releng/tomlkit/tomlkit/exceptions.py +227 -0
  312. package/releng/tomlkit/tomlkit/items.py +1967 -0
  313. package/releng/tomlkit/tomlkit/parser.py +1141 -0
  314. package/releng/tomlkit/tomlkit/py.typed +0 -0
  315. package/releng/tomlkit/tomlkit/source.py +180 -0
  316. package/releng/tomlkit/tomlkit/toml_char.py +52 -0
  317. package/releng/tomlkit/tomlkit/toml_document.py +7 -0
  318. package/releng/tomlkit/tomlkit/toml_file.py +58 -0
  319. package/releng/winenv.py +140 -0
  320. package/scripts/adjust-version.py +19 -0
  321. package/scripts/detect-version.py +40 -0
  322. package/scripts/fetch-abi-bits.py +343 -0
  323. package/scripts/install.js +23 -0
  324. package/scripts/package.py +15 -0
  325. package/src/addon.cc +76 -0
  326. package/src/application.cc +148 -0
  327. package/src/application.h +31 -0
  328. package/src/authentication.cc +174 -0
  329. package/src/authentication.h +24 -0
  330. package/src/bus.cc +167 -0
  331. package/src/bus.h +33 -0
  332. package/src/cancellable.cc +117 -0
  333. package/src/cancellable.h +31 -0
  334. package/src/child.cc +150 -0
  335. package/src/child.h +32 -0
  336. package/src/crash.cc +122 -0
  337. package/src/crash.h +30 -0
  338. package/src/device.cc +1302 -0
  339. package/src/device.h +55 -0
  340. package/src/device_manager.cc +362 -0
  341. package/src/device_manager.h +35 -0
  342. package/src/endpoint_parameters.cc +171 -0
  343. package/src/endpoint_parameters.h +28 -0
  344. package/src/glib_context.cc +62 -0
  345. package/src/glib_context.h +29 -0
  346. package/src/glib_object.cc +25 -0
  347. package/src/glib_object.h +37 -0
  348. package/src/iostream.cc +247 -0
  349. package/src/iostream.h +30 -0
  350. package/src/meson.build +26 -0
  351. package/src/operation.h +94 -0
  352. package/src/portal_membership.cc +100 -0
  353. package/src/portal_membership.h +26 -0
  354. package/src/portal_service.cc +401 -0
  355. package/src/portal_service.h +40 -0
  356. package/src/process.cc +135 -0
  357. package/src/process.h +30 -0
  358. package/src/relay.cc +139 -0
  359. package/src/relay.h +31 -0
  360. package/src/runtime.cc +443 -0
  361. package/src/runtime.h +64 -0
  362. package/src/script.cc +301 -0
  363. package/src/script.h +36 -0
  364. package/src/session.cc +860 -0
  365. package/src/session.h +42 -0
  366. package/src/signals.cc +334 -0
  367. package/src/signals.h +47 -0
  368. package/src/spawn.cc +95 -0
  369. package/src/spawn.h +27 -0
  370. package/src/usage_monitor.h +117 -0
  371. package/src/uv_context.cc +118 -0
  372. package/src/uv_context.h +40 -0
  373. package/src/win_delay_load_hook.cc +63 -0
  374. package/subprojects/frida-core.wrap +8 -0
  375. package/subprojects/nan.wrap +9 -0
  376. package/subprojects/packagefiles/nan.patch +13 -0
  377. package/test/data/index.ts +13 -0
  378. package/test/data/unixvictim-linux-x86 +0 -0
  379. package/test/data/unixvictim-linux-x86_64 +0 -0
  380. package/test/data/unixvictim-macos +0 -0
  381. package/test/device.ts +27 -0
  382. package/test/device_manager.ts +16 -0
  383. package/test/labrat.ts +32 -0
  384. package/test/script.ts +176 -0
  385. package/test/session.ts +73 -0
  386. package/tsconfig.json +18 -0
@@ -0,0 +1,1967 @@
1
+ from __future__ import annotations
2
+
3
+ import abc
4
+ import copy
5
+ import dataclasses
6
+ import math
7
+ import re
8
+ import string
9
+ import sys
10
+
11
+ from datetime import date
12
+ from datetime import datetime
13
+ from datetime import time
14
+ from datetime import tzinfo
15
+ from enum import Enum
16
+ from typing import TYPE_CHECKING
17
+ from typing import Any
18
+ from typing import Callable
19
+ from typing import Collection
20
+ from typing import Iterable
21
+ from typing import Iterator
22
+ from typing import Sequence
23
+ from typing import TypeVar
24
+ from typing import cast
25
+ from typing import overload
26
+
27
+ from tomlkit._compat import PY38
28
+ from tomlkit._compat import decode
29
+ from tomlkit._types import _CustomDict
30
+ from tomlkit._types import _CustomFloat
31
+ from tomlkit._types import _CustomInt
32
+ from tomlkit._types import _CustomList
33
+ from tomlkit._types import wrap_method
34
+ from tomlkit._utils import CONTROL_CHARS
35
+ from tomlkit._utils import escape_string
36
+ from tomlkit.exceptions import InvalidStringError
37
+
38
+
39
+ if TYPE_CHECKING:
40
+ from tomlkit import container
41
+
42
+
43
+ ItemT = TypeVar("ItemT", bound="Item")
44
+ Encoder = Callable[[Any], "Item"]
45
+ CUSTOM_ENCODERS: list[Encoder] = []
46
+ AT = TypeVar("AT", bound="AbstractTable")
47
+
48
+
49
+ class _ConvertError(TypeError, ValueError):
50
+ """An internal error raised when item() fails to convert a value.
51
+ It should be a TypeError, but due to historical reasons
52
+ it needs to subclass ValueError as well.
53
+ """
54
+
55
+
56
+ @overload
57
+ def item(value: bool, _parent: Item | None = ..., _sort_keys: bool = ...) -> Bool:
58
+ ...
59
+
60
+
61
+ @overload
62
+ def item(value: int, _parent: Item | None = ..., _sort_keys: bool = ...) -> Integer:
63
+ ...
64
+
65
+
66
+ @overload
67
+ def item(value: float, _parent: Item | None = ..., _sort_keys: bool = ...) -> Float:
68
+ ...
69
+
70
+
71
+ @overload
72
+ def item(value: str, _parent: Item | None = ..., _sort_keys: bool = ...) -> String:
73
+ ...
74
+
75
+
76
+ @overload
77
+ def item(
78
+ value: datetime, _parent: Item | None = ..., _sort_keys: bool = ...
79
+ ) -> DateTime:
80
+ ...
81
+
82
+
83
+ @overload
84
+ def item(value: date, _parent: Item | None = ..., _sort_keys: bool = ...) -> Date:
85
+ ...
86
+
87
+
88
+ @overload
89
+ def item(value: time, _parent: Item | None = ..., _sort_keys: bool = ...) -> Time:
90
+ ...
91
+
92
+
93
+ @overload
94
+ def item(
95
+ value: Sequence[dict], _parent: Item | None = ..., _sort_keys: bool = ...
96
+ ) -> AoT:
97
+ ...
98
+
99
+
100
+ @overload
101
+ def item(value: Sequence, _parent: Item | None = ..., _sort_keys: bool = ...) -> Array:
102
+ ...
103
+
104
+
105
+ @overload
106
+ def item(value: dict, _parent: Array = ..., _sort_keys: bool = ...) -> InlineTable:
107
+ ...
108
+
109
+
110
+ @overload
111
+ def item(value: dict, _parent: Item | None = ..., _sort_keys: bool = ...) -> Table:
112
+ ...
113
+
114
+
115
+ @overload
116
+ def item(value: ItemT, _parent: Item | None = ..., _sort_keys: bool = ...) -> ItemT:
117
+ ...
118
+
119
+
120
+ def item(value: Any, _parent: Item | None = None, _sort_keys: bool = False) -> Item:
121
+ """Create a TOML item from a Python object.
122
+
123
+ :Example:
124
+
125
+ >>> item(42)
126
+ 42
127
+ >>> item([1, 2, 3])
128
+ [1, 2, 3]
129
+ >>> item({'a': 1, 'b': 2})
130
+ a = 1
131
+ b = 2
132
+ """
133
+
134
+ from tomlkit.container import Container
135
+
136
+ if isinstance(value, Item):
137
+ return value
138
+
139
+ if isinstance(value, bool):
140
+ return Bool(value, Trivia())
141
+ elif isinstance(value, int):
142
+ return Integer(value, Trivia(), str(value))
143
+ elif isinstance(value, float):
144
+ return Float(value, Trivia(), str(value))
145
+ elif isinstance(value, dict):
146
+ table_constructor = (
147
+ InlineTable if isinstance(_parent, (Array, InlineTable)) else Table
148
+ )
149
+ val = table_constructor(Container(), Trivia(), False)
150
+ for k, v in sorted(
151
+ value.items(),
152
+ key=lambda i: (isinstance(i[1], dict), i[0]) if _sort_keys else 1,
153
+ ):
154
+ val[k] = item(v, _parent=val, _sort_keys=_sort_keys)
155
+
156
+ return val
157
+ elif isinstance(value, (list, tuple)):
158
+ if (
159
+ value
160
+ and all(isinstance(v, dict) for v in value)
161
+ and (_parent is None or isinstance(_parent, Table))
162
+ ):
163
+ a = AoT([])
164
+ table_constructor = Table
165
+ else:
166
+ a = Array([], Trivia())
167
+ table_constructor = InlineTable
168
+
169
+ for v in value:
170
+ if isinstance(v, dict):
171
+ table = table_constructor(Container(), Trivia(), True)
172
+
173
+ for k, _v in sorted(
174
+ v.items(),
175
+ key=lambda i: (isinstance(i[1], dict), i[0] if _sort_keys else 1),
176
+ ):
177
+ i = item(_v, _parent=table, _sort_keys=_sort_keys)
178
+ if isinstance(table, InlineTable):
179
+ i.trivia.trail = ""
180
+
181
+ table[k] = i
182
+
183
+ v = table
184
+
185
+ a.append(v)
186
+
187
+ return a
188
+ elif isinstance(value, str):
189
+ return String.from_raw(value)
190
+ elif isinstance(value, datetime):
191
+ return DateTime(
192
+ value.year,
193
+ value.month,
194
+ value.day,
195
+ value.hour,
196
+ value.minute,
197
+ value.second,
198
+ value.microsecond,
199
+ value.tzinfo,
200
+ Trivia(),
201
+ value.isoformat().replace("+00:00", "Z"),
202
+ )
203
+ elif isinstance(value, date):
204
+ return Date(value.year, value.month, value.day, Trivia(), value.isoformat())
205
+ elif isinstance(value, time):
206
+ return Time(
207
+ value.hour,
208
+ value.minute,
209
+ value.second,
210
+ value.microsecond,
211
+ value.tzinfo,
212
+ Trivia(),
213
+ value.isoformat(),
214
+ )
215
+ else:
216
+ for encoder in CUSTOM_ENCODERS:
217
+ try:
218
+ rv = encoder(value)
219
+ except TypeError:
220
+ pass
221
+ else:
222
+ if not isinstance(rv, Item):
223
+ raise _ConvertError(
224
+ f"Custom encoder returned {type(rv)}, not a subclass of Item"
225
+ )
226
+ return rv
227
+
228
+ raise _ConvertError(f"Invalid type {type(value)}")
229
+
230
+
231
+ class StringType(Enum):
232
+ # Single Line Basic
233
+ SLB = '"'
234
+ # Multi Line Basic
235
+ MLB = '"""'
236
+ # Single Line Literal
237
+ SLL = "'"
238
+ # Multi Line Literal
239
+ MLL = "'''"
240
+
241
+ @classmethod
242
+ def select(cls, literal=False, multiline=False) -> StringType:
243
+ return {
244
+ (False, False): cls.SLB,
245
+ (False, True): cls.MLB,
246
+ (True, False): cls.SLL,
247
+ (True, True): cls.MLL,
248
+ }[(literal, multiline)]
249
+
250
+ @property
251
+ def escaped_sequences(self) -> Collection[str]:
252
+ # https://toml.io/en/v1.0.0#string
253
+ escaped_in_basic = CONTROL_CHARS | {"\\"}
254
+ allowed_in_multiline = {"\n", "\r"}
255
+ return {
256
+ StringType.SLB: escaped_in_basic | {'"'},
257
+ StringType.MLB: (escaped_in_basic | {'"""'}) - allowed_in_multiline,
258
+ StringType.SLL: (),
259
+ StringType.MLL: (),
260
+ }[self]
261
+
262
+ @property
263
+ def invalid_sequences(self) -> Collection[str]:
264
+ # https://toml.io/en/v1.0.0#string
265
+ forbidden_in_literal = CONTROL_CHARS - {"\t"}
266
+ allowed_in_multiline = {"\n", "\r"}
267
+ return {
268
+ StringType.SLB: (),
269
+ StringType.MLB: (),
270
+ StringType.SLL: forbidden_in_literal | {"'"},
271
+ StringType.MLL: (forbidden_in_literal | {"'''"}) - allowed_in_multiline,
272
+ }[self]
273
+
274
+ @property
275
+ def unit(self) -> str:
276
+ return self.value[0]
277
+
278
+ def is_basic(self) -> bool:
279
+ return self in {StringType.SLB, StringType.MLB}
280
+
281
+ def is_literal(self) -> bool:
282
+ return self in {StringType.SLL, StringType.MLL}
283
+
284
+ def is_singleline(self) -> bool:
285
+ return self in {StringType.SLB, StringType.SLL}
286
+
287
+ def is_multiline(self) -> bool:
288
+ return self in {StringType.MLB, StringType.MLL}
289
+
290
+ def toggle(self) -> StringType:
291
+ return {
292
+ StringType.SLB: StringType.MLB,
293
+ StringType.MLB: StringType.SLB,
294
+ StringType.SLL: StringType.MLL,
295
+ StringType.MLL: StringType.SLL,
296
+ }[self]
297
+
298
+
299
+ class BoolType(Enum):
300
+ TRUE = "true"
301
+ FALSE = "false"
302
+
303
+ def __bool__(self):
304
+ return {BoolType.TRUE: True, BoolType.FALSE: False}[self]
305
+
306
+ def __iter__(self):
307
+ return iter(self.value)
308
+
309
+ def __len__(self):
310
+ return len(self.value)
311
+
312
+
313
+ @dataclasses.dataclass
314
+ class Trivia:
315
+ """
316
+ Trivia information (aka metadata).
317
+ """
318
+
319
+ # Whitespace before a value.
320
+ indent: str = ""
321
+ # Whitespace after a value, but before a comment.
322
+ comment_ws: str = ""
323
+ # Comment, starting with # character, or empty string if no comment.
324
+ comment: str = ""
325
+ # Trailing newline.
326
+ trail: str = "\n"
327
+
328
+ def copy(self) -> Trivia:
329
+ return dataclasses.replace(self)
330
+
331
+
332
+ class KeyType(Enum):
333
+ """
334
+ The type of a Key.
335
+
336
+ Keys can be bare (unquoted), or quoted using basic ("), or literal (')
337
+ quotes following the same escaping rules as single-line StringType.
338
+ """
339
+
340
+ Bare = ""
341
+ Basic = '"'
342
+ Literal = "'"
343
+
344
+
345
+ class Key(abc.ABC):
346
+ """Base class for a key"""
347
+
348
+ sep: str
349
+ _original: str
350
+ _keys: list[SingleKey]
351
+ _dotted: bool
352
+ key: str
353
+
354
+ @abc.abstractmethod
355
+ def __hash__(self) -> int:
356
+ pass
357
+
358
+ @abc.abstractmethod
359
+ def __eq__(self, __o: object) -> bool:
360
+ pass
361
+
362
+ def is_dotted(self) -> bool:
363
+ """If the key is followed by other keys"""
364
+ return self._dotted
365
+
366
+ def __iter__(self) -> Iterator[SingleKey]:
367
+ return iter(self._keys)
368
+
369
+ def concat(self, other: Key) -> DottedKey:
370
+ """Concatenate keys into a dotted key"""
371
+ keys = self._keys + other._keys
372
+ return DottedKey(keys, sep=self.sep)
373
+
374
+ def is_multi(self) -> bool:
375
+ """Check if the key contains multiple keys"""
376
+ return len(self._keys) > 1
377
+
378
+ def as_string(self) -> str:
379
+ """The TOML representation"""
380
+ return self._original
381
+
382
+ def __str__(self) -> str:
383
+ return self.as_string()
384
+
385
+ def __repr__(self) -> str:
386
+ return f"<Key {self.as_string()}>"
387
+
388
+
389
+ class SingleKey(Key):
390
+ """A single key"""
391
+
392
+ def __init__(
393
+ self,
394
+ k: str,
395
+ t: KeyType | None = None,
396
+ sep: str | None = None,
397
+ original: str | None = None,
398
+ ) -> None:
399
+ if t is None:
400
+ if not k or any(
401
+ c not in string.ascii_letters + string.digits + "-" + "_" for c in k
402
+ ):
403
+ t = KeyType.Basic
404
+ else:
405
+ t = KeyType.Bare
406
+
407
+ self.t = t
408
+ if sep is None:
409
+ sep = " = "
410
+
411
+ self.sep = sep
412
+ self.key = k
413
+ if original is None:
414
+ key_str = escape_string(k) if t == KeyType.Basic else k
415
+ original = f"{t.value}{key_str}{t.value}"
416
+
417
+ self._original = original
418
+ self._keys = [self]
419
+ self._dotted = False
420
+
421
+ @property
422
+ def delimiter(self) -> str:
423
+ """The delimiter: double quote/single quote/none"""
424
+ return self.t.value
425
+
426
+ def is_bare(self) -> bool:
427
+ """Check if the key is bare"""
428
+ return self.t == KeyType.Bare
429
+
430
+ def __hash__(self) -> int:
431
+ return hash(self.key)
432
+
433
+ def __eq__(self, other: Any) -> bool:
434
+ if isinstance(other, Key):
435
+ return isinstance(other, SingleKey) and self.key == other.key
436
+
437
+ return self.key == other
438
+
439
+
440
+ class DottedKey(Key):
441
+ def __init__(
442
+ self,
443
+ keys: Iterable[SingleKey],
444
+ sep: str | None = None,
445
+ original: str | None = None,
446
+ ) -> None:
447
+ self._keys = list(keys)
448
+ if original is None:
449
+ original = ".".join(k.as_string() for k in self._keys)
450
+
451
+ self.sep = " = " if sep is None else sep
452
+ self._original = original
453
+ self._dotted = False
454
+ self.key = ".".join(k.key for k in self._keys)
455
+
456
+ def __hash__(self) -> int:
457
+ return hash(tuple(self._keys))
458
+
459
+ def __eq__(self, __o: object) -> bool:
460
+ return isinstance(__o, DottedKey) and self._keys == __o._keys
461
+
462
+
463
+ class Item:
464
+ """
465
+ An item within a TOML document.
466
+ """
467
+
468
+ def __init__(self, trivia: Trivia) -> None:
469
+ self._trivia = trivia
470
+
471
+ @property
472
+ def trivia(self) -> Trivia:
473
+ """The trivia element associated with this item"""
474
+ return self._trivia
475
+
476
+ @property
477
+ def discriminant(self) -> int:
478
+ raise NotImplementedError()
479
+
480
+ def as_string(self) -> str:
481
+ """The TOML representation"""
482
+ raise NotImplementedError()
483
+
484
+ @property
485
+ def value(self) -> Any:
486
+ return self
487
+
488
+ def unwrap(self) -> Any:
489
+ """Returns as pure python object (ppo)"""
490
+ raise NotImplementedError()
491
+
492
+ # Helpers
493
+
494
+ def comment(self, comment: str) -> Item:
495
+ """Attach a comment to this item"""
496
+ if not comment.strip().startswith("#"):
497
+ comment = "# " + comment
498
+
499
+ self._trivia.comment_ws = " "
500
+ self._trivia.comment = comment
501
+
502
+ return self
503
+
504
+ def indent(self, indent: int) -> Item:
505
+ """Indent this item with given number of spaces"""
506
+ if self._trivia.indent.startswith("\n"):
507
+ self._trivia.indent = "\n" + " " * indent
508
+ else:
509
+ self._trivia.indent = " " * indent
510
+
511
+ return self
512
+
513
+ def is_boolean(self) -> bool:
514
+ return isinstance(self, Bool)
515
+
516
+ def is_table(self) -> bool:
517
+ return isinstance(self, Table)
518
+
519
+ def is_inline_table(self) -> bool:
520
+ return isinstance(self, InlineTable)
521
+
522
+ def is_aot(self) -> bool:
523
+ return isinstance(self, AoT)
524
+
525
+ def _getstate(self, protocol=3):
526
+ return (self._trivia,)
527
+
528
+ def __reduce__(self):
529
+ return self.__reduce_ex__(2)
530
+
531
+ def __reduce_ex__(self, protocol):
532
+ return self.__class__, self._getstate(protocol)
533
+
534
+
535
+ class Whitespace(Item):
536
+ """
537
+ A whitespace literal.
538
+ """
539
+
540
+ def __init__(self, s: str, fixed: bool = False) -> None:
541
+ self._s = s
542
+ self._fixed = fixed
543
+
544
+ @property
545
+ def s(self) -> str:
546
+ return self._s
547
+
548
+ @property
549
+ def value(self) -> str:
550
+ """The wrapped string of the whitespace"""
551
+ return self._s
552
+
553
+ @property
554
+ def trivia(self) -> Trivia:
555
+ raise RuntimeError("Called trivia on a Whitespace variant.")
556
+
557
+ @property
558
+ def discriminant(self) -> int:
559
+ return 0
560
+
561
+ def is_fixed(self) -> bool:
562
+ """If the whitespace is fixed, it can't be merged or discarded from the output."""
563
+ return self._fixed
564
+
565
+ def as_string(self) -> str:
566
+ return self._s
567
+
568
+ def __repr__(self) -> str:
569
+ return f"<{self.__class__.__name__} {repr(self._s)}>"
570
+
571
+ def _getstate(self, protocol=3):
572
+ return self._s, self._fixed
573
+
574
+
575
+ class Comment(Item):
576
+ """
577
+ A comment literal.
578
+ """
579
+
580
+ @property
581
+ def discriminant(self) -> int:
582
+ return 1
583
+
584
+ def as_string(self) -> str:
585
+ return (
586
+ f"{self._trivia.indent}{decode(self._trivia.comment)}{self._trivia.trail}"
587
+ )
588
+
589
+ def __str__(self) -> str:
590
+ return f"{self._trivia.indent}{decode(self._trivia.comment)}"
591
+
592
+
593
+ class Integer(Item, _CustomInt):
594
+ """
595
+ An integer literal.
596
+ """
597
+
598
+ def __new__(cls, value: int, trivia: Trivia, raw: str) -> Integer:
599
+ return int.__new__(cls, value)
600
+
601
+ def __init__(self, value: int, trivia: Trivia, raw: str) -> None:
602
+ super().__init__(trivia)
603
+ self._original = value
604
+ self._raw = raw
605
+ self._sign = False
606
+
607
+ if re.match(r"^[+\-]\d+$", raw):
608
+ self._sign = True
609
+
610
+ def unwrap(self) -> int:
611
+ return self._original
612
+
613
+ __int__ = unwrap
614
+
615
+ def __hash__(self) -> int:
616
+ return hash(self.unwrap())
617
+
618
+ @property
619
+ def discriminant(self) -> int:
620
+ return 2
621
+
622
+ @property
623
+ def value(self) -> int:
624
+ """The wrapped integer value"""
625
+ return self
626
+
627
+ def as_string(self) -> str:
628
+ return self._raw
629
+
630
+ def _new(self, result):
631
+ raw = str(result)
632
+ if self._sign:
633
+ sign = "+" if result >= 0 else "-"
634
+ raw = sign + raw
635
+
636
+ return Integer(result, self._trivia, raw)
637
+
638
+ def _getstate(self, protocol=3):
639
+ return int(self), self._trivia, self._raw
640
+
641
+ # int methods
642
+ __abs__ = wrap_method(int.__abs__)
643
+ __add__ = wrap_method(int.__add__)
644
+ __and__ = wrap_method(int.__and__)
645
+ __ceil__ = wrap_method(int.__ceil__)
646
+ __eq__ = int.__eq__
647
+ __floor__ = wrap_method(int.__floor__)
648
+ __floordiv__ = wrap_method(int.__floordiv__)
649
+ __invert__ = wrap_method(int.__invert__)
650
+ __le__ = int.__le__
651
+ __lshift__ = wrap_method(int.__lshift__)
652
+ __lt__ = int.__lt__
653
+ __mod__ = wrap_method(int.__mod__)
654
+ __mul__ = wrap_method(int.__mul__)
655
+ __neg__ = wrap_method(int.__neg__)
656
+ __or__ = wrap_method(int.__or__)
657
+ __pos__ = wrap_method(int.__pos__)
658
+ __pow__ = wrap_method(int.__pow__)
659
+ __radd__ = wrap_method(int.__radd__)
660
+ __rand__ = wrap_method(int.__rand__)
661
+ __rfloordiv__ = wrap_method(int.__rfloordiv__)
662
+ __rlshift__ = wrap_method(int.__rlshift__)
663
+ __rmod__ = wrap_method(int.__rmod__)
664
+ __rmul__ = wrap_method(int.__rmul__)
665
+ __ror__ = wrap_method(int.__ror__)
666
+ __round__ = wrap_method(int.__round__)
667
+ __rpow__ = wrap_method(int.__rpow__)
668
+ __rrshift__ = wrap_method(int.__rrshift__)
669
+ __rshift__ = wrap_method(int.__rshift__)
670
+ __rxor__ = wrap_method(int.__rxor__)
671
+ __trunc__ = wrap_method(int.__trunc__)
672
+ __xor__ = wrap_method(int.__xor__)
673
+
674
+ def __rtruediv__(self, other):
675
+ result = int.__rtruediv__(self, other)
676
+ if result is NotImplemented:
677
+ return result
678
+ return Float._new(self, result)
679
+
680
+ def __truediv__(self, other):
681
+ result = int.__truediv__(self, other)
682
+ if result is NotImplemented:
683
+ return result
684
+ return Float._new(self, result)
685
+
686
+
687
+ class Float(Item, _CustomFloat):
688
+ """
689
+ A float literal.
690
+ """
691
+
692
+ def __new__(cls, value: float, trivia: Trivia, raw: str) -> Float:
693
+ return float.__new__(cls, value)
694
+
695
+ def __init__(self, value: float, trivia: Trivia, raw: str) -> None:
696
+ super().__init__(trivia)
697
+ self._original = value
698
+ self._raw = raw
699
+ self._sign = False
700
+
701
+ if re.match(r"^[+\-].+$", raw):
702
+ self._sign = True
703
+
704
+ def unwrap(self) -> float:
705
+ return self._original
706
+
707
+ __float__ = unwrap
708
+
709
+ def __hash__(self) -> int:
710
+ return hash(self.unwrap())
711
+
712
+ @property
713
+ def discriminant(self) -> int:
714
+ return 3
715
+
716
+ @property
717
+ def value(self) -> float:
718
+ """The wrapped float value"""
719
+ return self
720
+
721
+ def as_string(self) -> str:
722
+ return self._raw
723
+
724
+ def _new(self, result):
725
+ raw = str(result)
726
+
727
+ if self._sign:
728
+ sign = "+" if result >= 0 else "-"
729
+ raw = sign + raw
730
+
731
+ return Float(result, self._trivia, raw)
732
+
733
+ def _getstate(self, protocol=3):
734
+ return float(self), self._trivia, self._raw
735
+
736
+ # float methods
737
+ __abs__ = wrap_method(float.__abs__)
738
+ __add__ = wrap_method(float.__add__)
739
+ __eq__ = float.__eq__
740
+ __floordiv__ = wrap_method(float.__floordiv__)
741
+ __le__ = float.__le__
742
+ __lt__ = float.__lt__
743
+ __mod__ = wrap_method(float.__mod__)
744
+ __mul__ = wrap_method(float.__mul__)
745
+ __neg__ = wrap_method(float.__neg__)
746
+ __pos__ = wrap_method(float.__pos__)
747
+ __pow__ = wrap_method(float.__pow__)
748
+ __radd__ = wrap_method(float.__radd__)
749
+ __rfloordiv__ = wrap_method(float.__rfloordiv__)
750
+ __rmod__ = wrap_method(float.__rmod__)
751
+ __rmul__ = wrap_method(float.__rmul__)
752
+ __round__ = wrap_method(float.__round__)
753
+ __rpow__ = wrap_method(float.__rpow__)
754
+ __rtruediv__ = wrap_method(float.__rtruediv__)
755
+ __truediv__ = wrap_method(float.__truediv__)
756
+ __trunc__ = float.__trunc__
757
+
758
+ if sys.version_info >= (3, 9):
759
+ __ceil__ = float.__ceil__
760
+ __floor__ = float.__floor__
761
+ else:
762
+ __ceil__ = math.ceil
763
+ __floor__ = math.floor
764
+
765
+
766
+ class Bool(Item):
767
+ """
768
+ A boolean literal.
769
+ """
770
+
771
+ def __init__(self, t: int, trivia: Trivia) -> None:
772
+ super().__init__(trivia)
773
+
774
+ self._value = bool(t)
775
+
776
+ def unwrap(self) -> bool:
777
+ return bool(self)
778
+
779
+ @property
780
+ def discriminant(self) -> int:
781
+ return 4
782
+
783
+ @property
784
+ def value(self) -> bool:
785
+ """The wrapped boolean value"""
786
+ return self._value
787
+
788
+ def as_string(self) -> str:
789
+ return str(self._value).lower()
790
+
791
+ def _getstate(self, protocol=3):
792
+ return self._value, self._trivia
793
+
794
+ def __bool__(self):
795
+ return self._value
796
+
797
+ __nonzero__ = __bool__
798
+
799
+ def __eq__(self, other):
800
+ if not isinstance(other, bool):
801
+ return NotImplemented
802
+
803
+ return other == self._value
804
+
805
+ def __hash__(self):
806
+ return hash(self._value)
807
+
808
+ def __repr__(self):
809
+ return repr(self._value)
810
+
811
+
812
+ class DateTime(Item, datetime):
813
+ """
814
+ A datetime literal.
815
+ """
816
+
817
+ def __new__(
818
+ cls,
819
+ year: int,
820
+ month: int,
821
+ day: int,
822
+ hour: int,
823
+ minute: int,
824
+ second: int,
825
+ microsecond: int,
826
+ tzinfo: tzinfo | None,
827
+ *_: Any,
828
+ **kwargs: Any,
829
+ ) -> datetime:
830
+ return datetime.__new__(
831
+ cls,
832
+ year,
833
+ month,
834
+ day,
835
+ hour,
836
+ minute,
837
+ second,
838
+ microsecond,
839
+ tzinfo=tzinfo,
840
+ **kwargs,
841
+ )
842
+
843
+ def __init__(
844
+ self,
845
+ year: int,
846
+ month: int,
847
+ day: int,
848
+ hour: int,
849
+ minute: int,
850
+ second: int,
851
+ microsecond: int,
852
+ tzinfo: tzinfo | None,
853
+ trivia: Trivia | None = None,
854
+ raw: str | None = None,
855
+ **kwargs: Any,
856
+ ) -> None:
857
+ super().__init__(trivia or Trivia())
858
+
859
+ self._raw = raw or self.isoformat()
860
+
861
+ def unwrap(self) -> datetime:
862
+ (
863
+ year,
864
+ month,
865
+ day,
866
+ hour,
867
+ minute,
868
+ second,
869
+ microsecond,
870
+ tzinfo,
871
+ _,
872
+ _,
873
+ ) = self._getstate()
874
+ return datetime(year, month, day, hour, minute, second, microsecond, tzinfo)
875
+
876
+ @property
877
+ def discriminant(self) -> int:
878
+ return 5
879
+
880
+ @property
881
+ def value(self) -> datetime:
882
+ return self
883
+
884
+ def as_string(self) -> str:
885
+ return self._raw
886
+
887
+ def __add__(self, other):
888
+ if PY38:
889
+ result = datetime(
890
+ self.year,
891
+ self.month,
892
+ self.day,
893
+ self.hour,
894
+ self.minute,
895
+ self.second,
896
+ self.microsecond,
897
+ self.tzinfo,
898
+ ).__add__(other)
899
+ else:
900
+ result = super().__add__(other)
901
+
902
+ return self._new(result)
903
+
904
+ def __sub__(self, other):
905
+ if PY38:
906
+ result = datetime(
907
+ self.year,
908
+ self.month,
909
+ self.day,
910
+ self.hour,
911
+ self.minute,
912
+ self.second,
913
+ self.microsecond,
914
+ self.tzinfo,
915
+ ).__sub__(other)
916
+ else:
917
+ result = super().__sub__(other)
918
+
919
+ if isinstance(result, datetime):
920
+ result = self._new(result)
921
+
922
+ return result
923
+
924
+ def replace(self, *args: Any, **kwargs: Any) -> datetime:
925
+ return self._new(super().replace(*args, **kwargs))
926
+
927
+ def astimezone(self, tz: tzinfo) -> datetime:
928
+ result = super().astimezone(tz)
929
+ if PY38:
930
+ return result
931
+ return self._new(result)
932
+
933
+ def _new(self, result) -> DateTime:
934
+ raw = result.isoformat()
935
+
936
+ return DateTime(
937
+ result.year,
938
+ result.month,
939
+ result.day,
940
+ result.hour,
941
+ result.minute,
942
+ result.second,
943
+ result.microsecond,
944
+ result.tzinfo,
945
+ self._trivia,
946
+ raw,
947
+ )
948
+
949
+ def _getstate(self, protocol=3):
950
+ return (
951
+ self.year,
952
+ self.month,
953
+ self.day,
954
+ self.hour,
955
+ self.minute,
956
+ self.second,
957
+ self.microsecond,
958
+ self.tzinfo,
959
+ self._trivia,
960
+ self._raw,
961
+ )
962
+
963
+
964
+ class Date(Item, date):
965
+ """
966
+ A date literal.
967
+ """
968
+
969
+ def __new__(cls, year: int, month: int, day: int, *_: Any) -> date:
970
+ return date.__new__(cls, year, month, day)
971
+
972
+ def __init__(
973
+ self, year: int, month: int, day: int, trivia: Trivia, raw: str
974
+ ) -> None:
975
+ super().__init__(trivia)
976
+
977
+ self._raw = raw
978
+
979
+ def unwrap(self) -> date:
980
+ (year, month, day, _, _) = self._getstate()
981
+ return date(year, month, day)
982
+
983
+ @property
984
+ def discriminant(self) -> int:
985
+ return 6
986
+
987
+ @property
988
+ def value(self) -> date:
989
+ return self
990
+
991
+ def as_string(self) -> str:
992
+ return self._raw
993
+
994
+ def __add__(self, other):
995
+ if PY38:
996
+ result = date(self.year, self.month, self.day).__add__(other)
997
+ else:
998
+ result = super().__add__(other)
999
+
1000
+ return self._new(result)
1001
+
1002
+ def __sub__(self, other):
1003
+ if PY38:
1004
+ result = date(self.year, self.month, self.day).__sub__(other)
1005
+ else:
1006
+ result = super().__sub__(other)
1007
+
1008
+ if isinstance(result, date):
1009
+ result = self._new(result)
1010
+
1011
+ return result
1012
+
1013
+ def replace(self, *args: Any, **kwargs: Any) -> date:
1014
+ return self._new(super().replace(*args, **kwargs))
1015
+
1016
+ def _new(self, result):
1017
+ raw = result.isoformat()
1018
+
1019
+ return Date(result.year, result.month, result.day, self._trivia, raw)
1020
+
1021
+ def _getstate(self, protocol=3):
1022
+ return (self.year, self.month, self.day, self._trivia, self._raw)
1023
+
1024
+
1025
+ class Time(Item, time):
1026
+ """
1027
+ A time literal.
1028
+ """
1029
+
1030
+ def __new__(
1031
+ cls,
1032
+ hour: int,
1033
+ minute: int,
1034
+ second: int,
1035
+ microsecond: int,
1036
+ tzinfo: tzinfo | None,
1037
+ *_: Any,
1038
+ ) -> time:
1039
+ return time.__new__(cls, hour, minute, second, microsecond, tzinfo)
1040
+
1041
+ def __init__(
1042
+ self,
1043
+ hour: int,
1044
+ minute: int,
1045
+ second: int,
1046
+ microsecond: int,
1047
+ tzinfo: tzinfo | None,
1048
+ trivia: Trivia,
1049
+ raw: str,
1050
+ ) -> None:
1051
+ super().__init__(trivia)
1052
+
1053
+ self._raw = raw
1054
+
1055
+ def unwrap(self) -> time:
1056
+ (hour, minute, second, microsecond, tzinfo, _, _) = self._getstate()
1057
+ return time(hour, minute, second, microsecond, tzinfo)
1058
+
1059
+ @property
1060
+ def discriminant(self) -> int:
1061
+ return 7
1062
+
1063
+ @property
1064
+ def value(self) -> time:
1065
+ return self
1066
+
1067
+ def as_string(self) -> str:
1068
+ return self._raw
1069
+
1070
+ def replace(self, *args: Any, **kwargs: Any) -> time:
1071
+ return self._new(super().replace(*args, **kwargs))
1072
+
1073
+ def _new(self, result):
1074
+ raw = result.isoformat()
1075
+
1076
+ return Time(
1077
+ result.hour,
1078
+ result.minute,
1079
+ result.second,
1080
+ result.microsecond,
1081
+ result.tzinfo,
1082
+ self._trivia,
1083
+ raw,
1084
+ )
1085
+
1086
+ def _getstate(self, protocol: int = 3) -> tuple:
1087
+ return (
1088
+ self.hour,
1089
+ self.minute,
1090
+ self.second,
1091
+ self.microsecond,
1092
+ self.tzinfo,
1093
+ self._trivia,
1094
+ self._raw,
1095
+ )
1096
+
1097
+
1098
+ class _ArrayItemGroup:
1099
+ __slots__ = ("value", "indent", "comma", "comment")
1100
+
1101
+ def __init__(
1102
+ self,
1103
+ value: Item | None = None,
1104
+ indent: Whitespace | None = None,
1105
+ comma: Whitespace | None = None,
1106
+ comment: Comment | None = None,
1107
+ ) -> None:
1108
+ self.value = value
1109
+ self.indent = indent
1110
+ self.comma = comma
1111
+ self.comment = comment
1112
+
1113
+ def __iter__(self) -> Iterator[Item]:
1114
+ return filter(
1115
+ lambda x: x is not None, (self.indent, self.value, self.comma, self.comment)
1116
+ )
1117
+
1118
+ def __repr__(self) -> str:
1119
+ return repr(tuple(self))
1120
+
1121
+ def is_whitespace(self) -> bool:
1122
+ return self.value is None and self.comment is None
1123
+
1124
+ def __bool__(self) -> bool:
1125
+ try:
1126
+ next(iter(self))
1127
+ except StopIteration:
1128
+ return False
1129
+ return True
1130
+
1131
+
1132
+ class Array(Item, _CustomList):
1133
+ """
1134
+ An array literal
1135
+ """
1136
+
1137
+ def __init__(
1138
+ self, value: list[Item], trivia: Trivia, multiline: bool = False
1139
+ ) -> None:
1140
+ super().__init__(trivia)
1141
+ list.__init__(
1142
+ self,
1143
+ [v for v in value if not isinstance(v, (Whitespace, Comment, Null))],
1144
+ )
1145
+ self._index_map: dict[int, int] = {}
1146
+ self._value = self._group_values(value)
1147
+ self._multiline = multiline
1148
+ self._reindex()
1149
+
1150
+ def _group_values(self, value: list[Item]) -> list[_ArrayItemGroup]:
1151
+ """Group the values into (indent, value, comma, comment) tuples"""
1152
+ groups = []
1153
+ this_group = _ArrayItemGroup()
1154
+ for item in value:
1155
+ if isinstance(item, Whitespace):
1156
+ if "," not in item.s:
1157
+ groups.append(this_group)
1158
+ this_group = _ArrayItemGroup(indent=item)
1159
+ else:
1160
+ if this_group.value is None:
1161
+ # when comma is met and no value is provided, add a dummy Null
1162
+ this_group.value = Null()
1163
+ this_group.comma = item
1164
+ elif isinstance(item, Comment):
1165
+ if this_group.value is None:
1166
+ this_group.value = Null()
1167
+ this_group.comment = item
1168
+ elif this_group.value is None:
1169
+ this_group.value = item
1170
+ else:
1171
+ groups.append(this_group)
1172
+ this_group = _ArrayItemGroup(value=item)
1173
+ groups.append(this_group)
1174
+ return [group for group in groups if group]
1175
+
1176
+ def unwrap(self) -> list[Any]:
1177
+ unwrapped = []
1178
+ for v in self:
1179
+ if hasattr(v, "unwrap"):
1180
+ unwrapped.append(v.unwrap())
1181
+ else:
1182
+ unwrapped.append(v)
1183
+ return unwrapped
1184
+
1185
+ @property
1186
+ def discriminant(self) -> int:
1187
+ return 8
1188
+
1189
+ @property
1190
+ def value(self) -> list:
1191
+ return self
1192
+
1193
+ def _iter_items(self) -> Iterator[Item]:
1194
+ for v in self._value:
1195
+ yield from v
1196
+
1197
+ def multiline(self, multiline: bool) -> Array:
1198
+ """Change the array to display in multiline or not.
1199
+
1200
+ :Example:
1201
+
1202
+ >>> a = item([1, 2, 3])
1203
+ >>> print(a.as_string())
1204
+ [1, 2, 3]
1205
+ >>> print(a.multiline(True).as_string())
1206
+ [
1207
+ 1,
1208
+ 2,
1209
+ 3,
1210
+ ]
1211
+ """
1212
+ self._multiline = multiline
1213
+
1214
+ return self
1215
+
1216
+ def as_string(self) -> str:
1217
+ if not self._multiline or not self._value:
1218
+ return f'[{"".join(v.as_string() for v in self._iter_items())}]'
1219
+
1220
+ s = "[\n"
1221
+ s += "".join(
1222
+ self.trivia.indent
1223
+ + " " * 4
1224
+ + v.value.as_string()
1225
+ + ("," if not isinstance(v.value, Null) else "")
1226
+ + (v.comment.as_string() if v.comment is not None else "")
1227
+ + "\n"
1228
+ for v in self._value
1229
+ if v.value is not None
1230
+ )
1231
+ s += self.trivia.indent + "]"
1232
+
1233
+ return s
1234
+
1235
+ def _reindex(self) -> None:
1236
+ self._index_map.clear()
1237
+ index = 0
1238
+ for i, v in enumerate(self._value):
1239
+ if v.value is None or isinstance(v.value, Null):
1240
+ continue
1241
+ self._index_map[index] = i
1242
+ index += 1
1243
+
1244
+ def add_line(
1245
+ self,
1246
+ *items: Any,
1247
+ indent: str = " ",
1248
+ comment: str | None = None,
1249
+ add_comma: bool = True,
1250
+ newline: bool = True,
1251
+ ) -> None:
1252
+ """Add multiple items in a line to control the format precisely.
1253
+ When add_comma is True, only accept actual values and
1254
+ ", " will be added between values automatically.
1255
+
1256
+ :Example:
1257
+
1258
+ >>> a = array()
1259
+ >>> a.add_line(1, 2, 3)
1260
+ >>> a.add_line(4, 5, 6)
1261
+ >>> a.add_line(indent="")
1262
+ >>> print(a.as_string())
1263
+ [
1264
+ 1, 2, 3,
1265
+ 4, 5, 6,
1266
+ ]
1267
+ """
1268
+ new_values: list[Item] = []
1269
+ first_indent = f"\n{indent}" if newline else indent
1270
+ if first_indent:
1271
+ new_values.append(Whitespace(first_indent))
1272
+ whitespace = ""
1273
+ data_values = []
1274
+ for i, el in enumerate(items):
1275
+ it = item(el, _parent=self)
1276
+ if isinstance(it, Comment) or add_comma and isinstance(el, Whitespace):
1277
+ raise ValueError(f"item type {type(it)} is not allowed in add_line")
1278
+ if not isinstance(it, Whitespace):
1279
+ if whitespace:
1280
+ new_values.append(Whitespace(whitespace))
1281
+ whitespace = ""
1282
+ new_values.append(it)
1283
+ data_values.append(it.value)
1284
+ if add_comma:
1285
+ new_values.append(Whitespace(","))
1286
+ if i != len(items) - 1:
1287
+ new_values.append(Whitespace(" "))
1288
+ elif "," not in it.s:
1289
+ whitespace += it.s
1290
+ else:
1291
+ new_values.append(it)
1292
+ if whitespace:
1293
+ new_values.append(Whitespace(whitespace))
1294
+ if comment:
1295
+ indent = " " if items else ""
1296
+ new_values.append(
1297
+ Comment(Trivia(indent=indent, comment=f"# {comment}", trail=""))
1298
+ )
1299
+ list.extend(self, data_values)
1300
+ if len(self._value) > 0:
1301
+ last_item = self._value[-1]
1302
+ last_value_item = next(
1303
+ (
1304
+ v
1305
+ for v in self._value[::-1]
1306
+ if v.value is not None and not isinstance(v.value, Null)
1307
+ ),
1308
+ None,
1309
+ )
1310
+ if last_value_item is not None:
1311
+ last_value_item.comma = Whitespace(",")
1312
+ if last_item.is_whitespace():
1313
+ self._value[-1:-1] = self._group_values(new_values)
1314
+ else:
1315
+ self._value.extend(self._group_values(new_values))
1316
+ else:
1317
+ self._value.extend(self._group_values(new_values))
1318
+ self._reindex()
1319
+
1320
+ def clear(self) -> None:
1321
+ """Clear the array."""
1322
+ list.clear(self)
1323
+ self._index_map.clear()
1324
+ self._value.clear()
1325
+
1326
+ def __len__(self) -> int:
1327
+ return list.__len__(self)
1328
+
1329
+ def __getitem__(self, key: int | slice) -> Any:
1330
+ rv = cast(Item, list.__getitem__(self, key))
1331
+ if rv.is_boolean():
1332
+ return bool(rv)
1333
+ return rv
1334
+
1335
+ def __setitem__(self, key: int | slice, value: Any) -> Any:
1336
+ it = item(value, _parent=self)
1337
+ list.__setitem__(self, key, it)
1338
+ if isinstance(key, slice):
1339
+ raise ValueError("slice assignment is not supported")
1340
+ if key < 0:
1341
+ key += len(self)
1342
+ self._value[self._index_map[key]].value = it
1343
+
1344
+ def insert(self, pos: int, value: Any) -> None:
1345
+ it = item(value, _parent=self)
1346
+ length = len(self)
1347
+ if not isinstance(it, (Comment, Whitespace)):
1348
+ list.insert(self, pos, it)
1349
+ if pos < 0:
1350
+ pos += length
1351
+ if pos < 0:
1352
+ pos = 0
1353
+
1354
+ idx = 0 # insert position of the self._value list
1355
+ default_indent = " "
1356
+ if pos < length:
1357
+ try:
1358
+ idx = self._index_map[pos]
1359
+ except KeyError as e:
1360
+ raise IndexError("list index out of range") from e
1361
+ else:
1362
+ idx = len(self._value)
1363
+ if idx >= 1 and self._value[idx - 1].is_whitespace():
1364
+ # The last item is a pure whitespace(\n ), insert before it
1365
+ idx -= 1
1366
+ if (
1367
+ self._value[idx].indent is not None
1368
+ and "\n" in self._value[idx].indent.s
1369
+ ):
1370
+ default_indent = "\n "
1371
+ indent: Item | None = None
1372
+ comma: Item | None = Whitespace(",") if pos < length else None
1373
+ if idx < len(self._value) and not self._value[idx].is_whitespace():
1374
+ # Prefer to copy the indentation from the item after
1375
+ indent = self._value[idx].indent
1376
+ if idx > 0:
1377
+ last_item = self._value[idx - 1]
1378
+ if indent is None:
1379
+ indent = last_item.indent
1380
+ if not isinstance(last_item.value, Null) and "\n" in default_indent:
1381
+ # Copy the comma from the last item if 1) it contains a value and
1382
+ # 2) the array is multiline
1383
+ comma = last_item.comma
1384
+ if last_item.comma is None and not isinstance(last_item.value, Null):
1385
+ # Add comma to the last item to separate it from the following items.
1386
+ last_item.comma = Whitespace(",")
1387
+ if indent is None and (idx > 0 or "\n" in default_indent):
1388
+ # apply default indent if it isn't the first item or the array is multiline.
1389
+ indent = Whitespace(default_indent)
1390
+ new_item = _ArrayItemGroup(value=it, indent=indent, comma=comma)
1391
+ self._value.insert(idx, new_item)
1392
+ self._reindex()
1393
+
1394
+ def __delitem__(self, key: int | slice):
1395
+ length = len(self)
1396
+ list.__delitem__(self, key)
1397
+
1398
+ if isinstance(key, slice):
1399
+ indices_to_remove = list(
1400
+ range(key.start or 0, key.stop or length, key.step or 1)
1401
+ )
1402
+ else:
1403
+ indices_to_remove = [length + key if key < 0 else key]
1404
+ for i in sorted(indices_to_remove, reverse=True):
1405
+ try:
1406
+ idx = self._index_map[i]
1407
+ except KeyError as e:
1408
+ if not isinstance(key, slice):
1409
+ raise IndexError("list index out of range") from e
1410
+ else:
1411
+ del self._value[idx]
1412
+ if (
1413
+ idx == 0
1414
+ and len(self._value) > 0
1415
+ and self._value[idx].indent
1416
+ and "\n" not in self._value[idx].indent.s
1417
+ ):
1418
+ # Remove the indentation of the first item if not newline
1419
+ self._value[idx].indent = None
1420
+ if len(self._value) > 0:
1421
+ v = self._value[-1]
1422
+ if not v.is_whitespace():
1423
+ # remove the comma of the last item
1424
+ v.comma = None
1425
+
1426
+ self._reindex()
1427
+
1428
+ def _getstate(self, protocol=3):
1429
+ return list(self._iter_items()), self._trivia, self._multiline
1430
+
1431
+
1432
+ class AbstractTable(Item, _CustomDict):
1433
+ """Common behaviour of both :class:`Table` and :class:`InlineTable`"""
1434
+
1435
+ def __init__(self, value: container.Container, trivia: Trivia):
1436
+ Item.__init__(self, trivia)
1437
+
1438
+ self._value = value
1439
+
1440
+ for k, v in self._value.body:
1441
+ if k is not None:
1442
+ dict.__setitem__(self, k.key, v)
1443
+
1444
+ def unwrap(self) -> dict[str, Any]:
1445
+ unwrapped = {}
1446
+ for k, v in self.items():
1447
+ if isinstance(k, Key):
1448
+ k = k.key
1449
+ if hasattr(v, "unwrap"):
1450
+ v = v.unwrap()
1451
+ unwrapped[k] = v
1452
+
1453
+ return unwrapped
1454
+
1455
+ @property
1456
+ def value(self) -> container.Container:
1457
+ return self._value
1458
+
1459
+ @overload
1460
+ def append(self: AT, key: None, value: Comment | Whitespace) -> AT:
1461
+ ...
1462
+
1463
+ @overload
1464
+ def append(self: AT, key: Key | str, value: Any) -> AT:
1465
+ ...
1466
+
1467
+ def append(self, key, value):
1468
+ raise NotImplementedError
1469
+
1470
+ @overload
1471
+ def add(self: AT, key: Comment | Whitespace) -> AT:
1472
+ ...
1473
+
1474
+ @overload
1475
+ def add(self: AT, key: Key | str, value: Any = ...) -> AT:
1476
+ ...
1477
+
1478
+ def add(self, key, value=None):
1479
+ if value is None:
1480
+ if not isinstance(key, (Comment, Whitespace)):
1481
+ msg = "Non comment/whitespace items must have an associated key"
1482
+ raise ValueError(msg)
1483
+
1484
+ key, value = None, key
1485
+
1486
+ return self.append(key, value)
1487
+
1488
+ def remove(self: AT, key: Key | str) -> AT:
1489
+ self._value.remove(key)
1490
+
1491
+ if isinstance(key, Key):
1492
+ key = key.key
1493
+
1494
+ if key is not None:
1495
+ dict.__delitem__(self, key)
1496
+
1497
+ return self
1498
+
1499
+ def setdefault(self, key: Key | str, default: Any) -> Any:
1500
+ super().setdefault(key, default)
1501
+ return self[key]
1502
+
1503
+ def __str__(self):
1504
+ return str(self.value)
1505
+
1506
+ def copy(self: AT) -> AT:
1507
+ return copy.copy(self)
1508
+
1509
+ def __repr__(self) -> str:
1510
+ return repr(self.value)
1511
+
1512
+ def __iter__(self) -> Iterator[str]:
1513
+ return iter(self._value)
1514
+
1515
+ def __len__(self) -> int:
1516
+ return len(self._value)
1517
+
1518
+ def __delitem__(self, key: Key | str) -> None:
1519
+ self.remove(key)
1520
+
1521
+ def __getitem__(self, key: Key | str) -> Item:
1522
+ return cast(Item, self._value[key])
1523
+
1524
+ def __setitem__(self, key: Key | str, value: Any) -> None:
1525
+ if not isinstance(value, Item):
1526
+ value = item(value, _parent=self)
1527
+
1528
+ is_replace = key in self
1529
+ self._value[key] = value
1530
+
1531
+ if key is not None:
1532
+ dict.__setitem__(self, key, value)
1533
+
1534
+ if is_replace:
1535
+ return
1536
+ m = re.match("(?s)^[^ ]*([ ]+).*$", self._trivia.indent)
1537
+ if not m:
1538
+ return
1539
+
1540
+ indent = m.group(1)
1541
+
1542
+ if not isinstance(value, Whitespace):
1543
+ m = re.match("(?s)^([^ ]*)(.*)$", value.trivia.indent)
1544
+ if not m:
1545
+ value.trivia.indent = indent
1546
+ else:
1547
+ value.trivia.indent = m.group(1) + indent + m.group(2)
1548
+
1549
+
1550
+ class Table(AbstractTable):
1551
+ """
1552
+ A table literal.
1553
+ """
1554
+
1555
+ def __init__(
1556
+ self,
1557
+ value: container.Container,
1558
+ trivia: Trivia,
1559
+ is_aot_element: bool,
1560
+ is_super_table: bool | None = None,
1561
+ name: str | None = None,
1562
+ display_name: str | None = None,
1563
+ ) -> None:
1564
+ super().__init__(value, trivia)
1565
+
1566
+ self.name = name
1567
+ self.display_name = display_name
1568
+ self._is_aot_element = is_aot_element
1569
+ self._is_super_table = is_super_table
1570
+
1571
+ @property
1572
+ def discriminant(self) -> int:
1573
+ return 9
1574
+
1575
+ def __copy__(self) -> Table:
1576
+ return type(self)(
1577
+ self._value.copy(),
1578
+ self._trivia.copy(),
1579
+ self._is_aot_element,
1580
+ self._is_super_table,
1581
+ self.name,
1582
+ self.display_name,
1583
+ )
1584
+
1585
+ def append(self, key: Key | str | None, _item: Any) -> Table:
1586
+ """
1587
+ Appends a (key, item) to the table.
1588
+ """
1589
+ if not isinstance(_item, Item):
1590
+ _item = item(_item, _parent=self)
1591
+
1592
+ self._value.append(key, _item)
1593
+
1594
+ if isinstance(key, Key):
1595
+ key = next(iter(key)).key
1596
+ _item = self._value[key]
1597
+
1598
+ if key is not None:
1599
+ dict.__setitem__(self, key, _item)
1600
+
1601
+ m = re.match(r"(?s)^[^ ]*([ ]+).*$", self._trivia.indent)
1602
+ if not m:
1603
+ return self
1604
+
1605
+ indent = m.group(1)
1606
+
1607
+ if not isinstance(_item, Whitespace):
1608
+ m = re.match("(?s)^([^ ]*)(.*)$", _item.trivia.indent)
1609
+ if not m:
1610
+ _item.trivia.indent = indent
1611
+ else:
1612
+ _item.trivia.indent = m.group(1) + indent + m.group(2)
1613
+
1614
+ return self
1615
+
1616
+ def raw_append(self, key: Key | str | None, _item: Any) -> Table:
1617
+ """Similar to :meth:`append` but does not copy indentation."""
1618
+ if not isinstance(_item, Item):
1619
+ _item = item(_item)
1620
+
1621
+ self._value.append(key, _item, validate=False)
1622
+
1623
+ if isinstance(key, Key):
1624
+ key = next(iter(key)).key
1625
+ _item = self._value[key]
1626
+
1627
+ if key is not None:
1628
+ dict.__setitem__(self, key, _item)
1629
+
1630
+ return self
1631
+
1632
+ def is_aot_element(self) -> bool:
1633
+ """True if the table is the direct child of an AOT element."""
1634
+ return self._is_aot_element
1635
+
1636
+ def is_super_table(self) -> bool:
1637
+ """A super table is the intermediate parent of a nested table as in [a.b.c].
1638
+ If true, it won't appear in the TOML representation."""
1639
+ if self._is_super_table is not None:
1640
+ return self._is_super_table
1641
+ # If the table has only one child and that child is a table, then it is a super table.
1642
+ if len(self) != 1:
1643
+ return False
1644
+ only_child = next(iter(self.values()))
1645
+ return isinstance(only_child, (Table, AoT))
1646
+
1647
+ def as_string(self) -> str:
1648
+ return self._value.as_string()
1649
+
1650
+ # Helpers
1651
+
1652
+ def indent(self, indent: int) -> Table:
1653
+ """Indent the table with given number of spaces."""
1654
+ super().indent(indent)
1655
+
1656
+ m = re.match("(?s)^[^ ]*([ ]+).*$", self._trivia.indent)
1657
+ if not m:
1658
+ indent_str = ""
1659
+ else:
1660
+ indent_str = m.group(1)
1661
+
1662
+ for _, item in self._value.body:
1663
+ if not isinstance(item, Whitespace):
1664
+ item.trivia.indent = indent_str + item.trivia.indent
1665
+
1666
+ return self
1667
+
1668
+ def invalidate_display_name(self):
1669
+ """Call ``invalidate_display_name`` on the contained tables"""
1670
+ self.display_name = None
1671
+
1672
+ for child in self.values():
1673
+ if hasattr(child, "invalidate_display_name"):
1674
+ child.invalidate_display_name()
1675
+
1676
+ def _getstate(self, protocol: int = 3) -> tuple:
1677
+ return (
1678
+ self._value,
1679
+ self._trivia,
1680
+ self._is_aot_element,
1681
+ self._is_super_table,
1682
+ self.name,
1683
+ self.display_name,
1684
+ )
1685
+
1686
+
1687
+ class InlineTable(AbstractTable):
1688
+ """
1689
+ An inline table literal.
1690
+ """
1691
+
1692
+ def __init__(
1693
+ self, value: container.Container, trivia: Trivia, new: bool = False
1694
+ ) -> None:
1695
+ super().__init__(value, trivia)
1696
+
1697
+ self._new = new
1698
+
1699
+ @property
1700
+ def discriminant(self) -> int:
1701
+ return 10
1702
+
1703
+ def append(self, key: Key | str | None, _item: Any) -> InlineTable:
1704
+ """
1705
+ Appends a (key, item) to the table.
1706
+ """
1707
+ if not isinstance(_item, Item):
1708
+ _item = item(_item, _parent=self)
1709
+
1710
+ if not isinstance(_item, (Whitespace, Comment)):
1711
+ if not _item.trivia.indent and len(self._value) > 0 and not self._new:
1712
+ _item.trivia.indent = " "
1713
+ if _item.trivia.comment:
1714
+ _item.trivia.comment = ""
1715
+
1716
+ self._value.append(key, _item)
1717
+
1718
+ if isinstance(key, Key):
1719
+ key = key.key
1720
+
1721
+ if key is not None:
1722
+ dict.__setitem__(self, key, _item)
1723
+
1724
+ return self
1725
+
1726
+ def as_string(self) -> str:
1727
+ buf = "{"
1728
+ last_item_idx = next(
1729
+ (
1730
+ i
1731
+ for i in range(len(self._value.body) - 1, -1, -1)
1732
+ if self._value.body[i][0] is not None
1733
+ ),
1734
+ None,
1735
+ )
1736
+ for i, (k, v) in enumerate(self._value.body):
1737
+ if k is None:
1738
+ if i == len(self._value.body) - 1:
1739
+ if self._new:
1740
+ buf = buf.rstrip(", ")
1741
+ else:
1742
+ buf = buf.rstrip(",")
1743
+
1744
+ buf += v.as_string()
1745
+
1746
+ continue
1747
+
1748
+ v_trivia_trail = v.trivia.trail.replace("\n", "")
1749
+ buf += (
1750
+ f"{v.trivia.indent}"
1751
+ f'{k.as_string() + ("." if k.is_dotted() else "")}'
1752
+ f"{k.sep}"
1753
+ f"{v.as_string()}"
1754
+ f"{v.trivia.comment}"
1755
+ f"{v_trivia_trail}"
1756
+ )
1757
+
1758
+ if last_item_idx is not None and i < last_item_idx:
1759
+ buf += ","
1760
+ if self._new:
1761
+ buf += " "
1762
+
1763
+ buf += "}"
1764
+
1765
+ return buf
1766
+
1767
+ def __setitem__(self, key: Key | str, value: Any) -> None:
1768
+ if hasattr(value, "trivia") and value.trivia.comment:
1769
+ value.trivia.comment = ""
1770
+ super().__setitem__(key, value)
1771
+
1772
+ def __copy__(self) -> InlineTable:
1773
+ return type(self)(self._value.copy(), self._trivia.copy(), self._new)
1774
+
1775
+ def _getstate(self, protocol: int = 3) -> tuple:
1776
+ return (self._value, self._trivia)
1777
+
1778
+
1779
+ class String(str, Item):
1780
+ """
1781
+ A string literal.
1782
+ """
1783
+
1784
+ def __new__(cls, t, value, original, trivia):
1785
+ return super().__new__(cls, value)
1786
+
1787
+ def __init__(self, t: StringType, _: str, original: str, trivia: Trivia) -> None:
1788
+ super().__init__(trivia)
1789
+
1790
+ self._t = t
1791
+ self._original = original
1792
+
1793
+ def unwrap(self) -> str:
1794
+ return str(self)
1795
+
1796
+ @property
1797
+ def discriminant(self) -> int:
1798
+ return 11
1799
+
1800
+ @property
1801
+ def value(self) -> str:
1802
+ return self
1803
+
1804
+ def as_string(self) -> str:
1805
+ return f"{self._t.value}{decode(self._original)}{self._t.value}"
1806
+
1807
+ def __add__(self: ItemT, other: str) -> ItemT:
1808
+ if not isinstance(other, str):
1809
+ return NotImplemented
1810
+ result = super().__add__(other)
1811
+ original = self._original + getattr(other, "_original", other)
1812
+
1813
+ return self._new(result, original)
1814
+
1815
+ def _new(self, result: str, original: str) -> String:
1816
+ return String(self._t, result, original, self._trivia)
1817
+
1818
+ def _getstate(self, protocol=3):
1819
+ return self._t, str(self), self._original, self._trivia
1820
+
1821
+ @classmethod
1822
+ def from_raw(cls, value: str, type_=StringType.SLB, escape=True) -> String:
1823
+ value = decode(value)
1824
+
1825
+ invalid = type_.invalid_sequences
1826
+ if any(c in value for c in invalid):
1827
+ raise InvalidStringError(value, invalid, type_.value)
1828
+
1829
+ escaped = type_.escaped_sequences
1830
+ string_value = escape_string(value, escaped) if escape and escaped else value
1831
+
1832
+ return cls(type_, decode(value), string_value, Trivia())
1833
+
1834
+
1835
+ class AoT(Item, _CustomList):
1836
+ """
1837
+ An array of table literal
1838
+ """
1839
+
1840
+ def __init__(
1841
+ self, body: list[Table], name: str | None = None, parsed: bool = False
1842
+ ) -> None:
1843
+ self.name = name
1844
+ self._body: list[Table] = []
1845
+ self._parsed = parsed
1846
+
1847
+ super().__init__(Trivia(trail=""))
1848
+
1849
+ for table in body:
1850
+ self.append(table)
1851
+
1852
+ def unwrap(self) -> list[dict[str, Any]]:
1853
+ unwrapped = []
1854
+ for t in self._body:
1855
+ if hasattr(t, "unwrap"):
1856
+ unwrapped.append(t.unwrap())
1857
+ else:
1858
+ unwrapped.append(t)
1859
+ return unwrapped
1860
+
1861
+ @property
1862
+ def body(self) -> list[Table]:
1863
+ return self._body
1864
+
1865
+ @property
1866
+ def discriminant(self) -> int:
1867
+ return 12
1868
+
1869
+ @property
1870
+ def value(self) -> list[dict[Any, Any]]:
1871
+ return [v.value for v in self._body]
1872
+
1873
+ def __len__(self) -> int:
1874
+ return len(self._body)
1875
+
1876
+ @overload
1877
+ def __getitem__(self, key: slice) -> list[Table]:
1878
+ ...
1879
+
1880
+ @overload
1881
+ def __getitem__(self, key: int) -> Table:
1882
+ ...
1883
+
1884
+ def __getitem__(self, key):
1885
+ return self._body[key]
1886
+
1887
+ def __setitem__(self, key: slice | int, value: Any) -> None:
1888
+ raise NotImplementedError
1889
+
1890
+ def __delitem__(self, key: slice | int) -> None:
1891
+ del self._body[key]
1892
+ list.__delitem__(self, key)
1893
+
1894
+ def insert(self, index: int, value: dict) -> None:
1895
+ value = item(value, _parent=self)
1896
+ if not isinstance(value, Table):
1897
+ raise ValueError(f"Unsupported insert value type: {type(value)}")
1898
+ length = len(self)
1899
+ if index < 0:
1900
+ index += length
1901
+ if index < 0:
1902
+ index = 0
1903
+ elif index >= length:
1904
+ index = length
1905
+ m = re.match("(?s)^[^ ]*([ ]+).*$", self._trivia.indent)
1906
+ if m:
1907
+ indent = m.group(1)
1908
+
1909
+ m = re.match("(?s)^([^ ]*)(.*)$", value.trivia.indent)
1910
+ if not m:
1911
+ value.trivia.indent = indent
1912
+ else:
1913
+ value.trivia.indent = m.group(1) + indent + m.group(2)
1914
+ prev_table = self._body[index - 1] if 0 < index and length else None
1915
+ next_table = self._body[index + 1] if index < length - 1 else None
1916
+ if not self._parsed:
1917
+ if prev_table and "\n" not in value.trivia.indent:
1918
+ value.trivia.indent = "\n" + value.trivia.indent
1919
+ if next_table and "\n" not in next_table.trivia.indent:
1920
+ next_table.trivia.indent = "\n" + next_table.trivia.indent
1921
+ self._body.insert(index, value)
1922
+ list.insert(self, index, value)
1923
+
1924
+ def invalidate_display_name(self):
1925
+ """Call ``invalidate_display_name`` on the contained tables"""
1926
+ for child in self:
1927
+ if hasattr(child, "invalidate_display_name"):
1928
+ child.invalidate_display_name()
1929
+
1930
+ def as_string(self) -> str:
1931
+ b = ""
1932
+ for table in self._body:
1933
+ b += table.as_string()
1934
+
1935
+ return b
1936
+
1937
+ def __repr__(self) -> str:
1938
+ return f"<AoT {self.value}>"
1939
+
1940
+ def _getstate(self, protocol=3):
1941
+ return self._body, self.name, self._parsed
1942
+
1943
+
1944
+ class Null(Item):
1945
+ """
1946
+ A null item.
1947
+ """
1948
+
1949
+ def __init__(self) -> None:
1950
+ super().__init__(Trivia(trail=""))
1951
+
1952
+ def unwrap(self) -> None:
1953
+ return None
1954
+
1955
+ @property
1956
+ def discriminant(self) -> int:
1957
+ return -1
1958
+
1959
+ @property
1960
+ def value(self) -> None:
1961
+ return None
1962
+
1963
+ def as_string(self) -> str:
1964
+ return ""
1965
+
1966
+ def _getstate(self, protocol=3) -> tuple:
1967
+ return ()