robotframework 6.1.1__zip → 7.0__zip

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 (307) hide show
  1. {robotframework-6.1.1 → robotframework-7.0}/INSTALL.rst +25 -25
  2. {robotframework-6.1.1 → robotframework-7.0}/PKG-INFO +6 -8
  3. {robotframework-6.1.1 → robotframework-7.0}/README.rst +3 -2
  4. {robotframework-6.1.1 → robotframework-7.0}/setup.py +3 -6
  5. {robotframework-6.1.1 → robotframework-7.0}/src/robot/api/__init__.py +4 -1
  6. {robotframework-6.1.1 → robotframework-7.0}/src/robot/api/deco.py +60 -14
  7. {robotframework-6.1.1 → robotframework-7.0}/src/robot/api/exceptions.py +6 -6
  8. {robotframework-6.1.1 → robotframework-7.0}/src/robot/api/interfaces.py +402 -67
  9. {robotframework-6.1.1 → robotframework-7.0}/src/robot/api/logger.py +27 -20
  10. {robotframework-6.1.1 → robotframework-7.0}/src/robot/api/parsing.py +4 -2
  11. robotframework-7.0/src/robot/api/py.typed +0 -0
  12. {robotframework-6.1.1 → robotframework-7.0}/src/robot/conf/gatherfailed.py +2 -2
  13. {robotframework-6.1.1 → robotframework-7.0}/src/robot/conf/languages.py +0 -9
  14. {robotframework-6.1.1 → robotframework-7.0}/src/robot/conf/settings.py +21 -14
  15. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/common/storage.js +11 -6
  16. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/htmlfilewriter.py +1 -1
  17. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/libdoc/libdoc.css +10 -2
  18. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/libdoc/libdoc.html +10 -0
  19. robotframework-7.0/src/robot/htmldata/rebot/common.css +362 -0
  20. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/doc_formatting.css +13 -7
  21. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/log.css +51 -10
  22. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/log.html +14 -23
  23. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/model.js +2 -4
  24. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/report.css +83 -19
  25. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/report.html +22 -7
  26. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/testdata.js +10 -3
  27. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/view.js +84 -0
  28. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/template.py +3 -3
  29. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/builder.py +0 -8
  30. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/datatypes.py +9 -10
  31. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/htmlutils.py +4 -7
  32. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/jsonbuilder.py +38 -20
  33. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/model.py +21 -28
  34. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/robotbuilder.py +50 -31
  35. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/standardtypes.py +9 -1
  36. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/xmlbuilder.py +35 -20
  37. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/xmlwriter.py +18 -38
  38. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/BuiltIn.py +255 -205
  39. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/Collections.py +384 -240
  40. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/DateTime.py +73 -60
  41. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/OperatingSystem.py +6 -5
  42. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/Process.py +26 -27
  43. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/Remote.py +40 -36
  44. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/String.py +66 -76
  45. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/XML.py +66 -59
  46. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/__init__.py +2 -2
  47. {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/__init__.py +5 -5
  48. {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/body.py +44 -13
  49. {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/configurer.py +15 -11
  50. {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/control.py +226 -84
  51. {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/filter.py +31 -25
  52. {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/itemlist.py +9 -8
  53. robotframework-7.0/src/robot/model/keyword.py +77 -0
  54. {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/message.py +19 -10
  55. {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/modelobject.py +25 -7
  56. {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/namepatterns.py +3 -25
  57. {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/stats.py +9 -15
  58. {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/tags.py +1 -1
  59. {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/testcase.py +15 -27
  60. {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/testsuite.py +17 -26
  61. {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/visitor.py +35 -8
  62. robotframework-7.0/src/robot/output/console/dotted.py +90 -0
  63. {robotframework-6.1.1 → robotframework-7.0}/src/robot/output/console/quiet.py +3 -2
  64. {robotframework-6.1.1 → robotframework-7.0}/src/robot/output/console/verbose.py +61 -61
  65. {robotframework-6.1.1 → robotframework-7.0}/src/robot/output/debugfile.py +39 -24
  66. {robotframework-6.1.1 → robotframework-7.0}/src/robot/output/filelogger.py +18 -15
  67. {robotframework-6.1.1 → robotframework-7.0}/src/robot/output/librarylogger.py +3 -2
  68. robotframework-7.0/src/robot/output/listeners.py +753 -0
  69. {robotframework-6.1.1 → robotframework-7.0}/src/robot/output/logger.py +216 -80
  70. robotframework-7.0/src/robot/output/loggerapi.py +215 -0
  71. {robotframework-6.1.1 → robotframework-7.0}/src/robot/output/loggerhelper.py +23 -56
  72. robotframework-7.0/src/robot/output/output.py +185 -0
  73. {robotframework-6.1.1 → robotframework-7.0}/src/robot/output/stdoutlogsplitter.py +8 -5
  74. robotframework-7.0/src/robot/output/xmllogger.py +459 -0
  75. {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/lexer/blocklexers.py +17 -13
  76. {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/lexer/context.py +12 -2
  77. {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/lexer/lexer.py +1 -1
  78. {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/lexer/settings.py +6 -3
  79. {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/lexer/statementlexers.py +39 -10
  80. {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/lexer/tokens.py +27 -29
  81. {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/model/blocks.py +19 -6
  82. {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/model/statements.py +193 -94
  83. robotframework-7.0/src/robot/parsing/model/visitor.py +100 -0
  84. {robotframework-6.1.1 → robotframework-7.0}/src/robot/rebot.py +2 -0
  85. {robotframework-6.1.1 → robotframework-7.0}/src/robot/reporting/expandkeywordmatcher.py +1 -1
  86. {robotframework-6.1.1 → robotframework-7.0}/src/robot/reporting/jsbuildingcontext.py +8 -6
  87. {robotframework-6.1.1 → robotframework-7.0}/src/robot/reporting/jsmodelbuilders.py +88 -61
  88. {robotframework-6.1.1 → robotframework-7.0}/src/robot/reporting/logreportwriters.py +16 -10
  89. {robotframework-6.1.1 → robotframework-7.0}/src/robot/reporting/outputwriter.py +18 -2
  90. {robotframework-6.1.1 → robotframework-7.0}/src/robot/reporting/resultwriter.py +4 -4
  91. {robotframework-6.1.1 → robotframework-7.0}/src/robot/reporting/stringcache.py +3 -3
  92. {robotframework-6.1.1 → robotframework-7.0}/src/robot/reporting/xunitwriter.py +15 -21
  93. {robotframework-6.1.1 → robotframework-7.0}/src/robot/result/__init__.py +3 -2
  94. {robotframework-6.1.1 → robotframework-7.0}/src/robot/result/configurer.py +12 -9
  95. {robotframework-6.1.1 → robotframework-7.0}/src/robot/result/executionresult.py +56 -8
  96. {robotframework-6.1.1 → robotframework-7.0}/src/robot/result/flattenkeywordmatcher.py +48 -9
  97. robotframework-7.0/src/robot/result/keywordremover.py +207 -0
  98. {robotframework-6.1.1 → robotframework-7.0}/src/robot/result/merger.py +1 -1
  99. robotframework-7.0/src/robot/result/model.py +1185 -0
  100. {robotframework-6.1.1 → robotframework-7.0}/src/robot/result/modeldeprecation.py +9 -3
  101. {robotframework-6.1.1 → robotframework-7.0}/src/robot/result/resultbuilder.py +46 -36
  102. {robotframework-6.1.1 → robotframework-7.0}/src/robot/result/xmlelementhandlers.py +83 -43
  103. {robotframework-6.1.1 → robotframework-7.0}/src/robot/run.py +2 -0
  104. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/__init__.py +14 -4
  105. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/arguments/__init__.py +2 -1
  106. robotframework-7.0/src/robot/running/arguments/argumentconverter.py +100 -0
  107. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/arguments/argumentmapper.py +26 -24
  108. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/arguments/argumentparser.py +82 -60
  109. robotframework-7.0/src/robot/running/arguments/argumentresolver.py +158 -0
  110. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/arguments/argumentspec.py +83 -116
  111. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/arguments/argumentvalidator.py +33 -27
  112. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/arguments/customconverters.py +15 -12
  113. robotframework-7.0/src/robot/running/arguments/embedded.py +145 -0
  114. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/arguments/typeconverters.py +233 -213
  115. robotframework-7.0/src/robot/running/arguments/typeinfo.py +317 -0
  116. robotframework-7.0/src/robot/running/arguments/typeinfoparser.py +219 -0
  117. robotframework-7.0/src/robot/running/arguments/typevalidator.py +60 -0
  118. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/bodyrunner.py +147 -129
  119. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/builder/builders.py +2 -1
  120. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/builder/parsers.py +10 -11
  121. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/builder/settings.py +9 -17
  122. robotframework-7.0/src/robot/running/builder/transformers.py +535 -0
  123. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/context.py +113 -31
  124. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/dynamicmethods.py +62 -34
  125. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/importer.py +27 -49
  126. robotframework-7.0/src/robot/running/invalidkeyword.py +67 -0
  127. robotframework-7.0/src/robot/running/keywordfinder.py +91 -0
  128. robotframework-7.0/src/robot/running/keywordimplementation.py +164 -0
  129. robotframework-7.0/src/robot/running/librarykeyword.py +392 -0
  130. robotframework-7.0/src/robot/running/librarykeywordrunner.py +250 -0
  131. robotframework-7.0/src/robot/running/libraryscopes.py +115 -0
  132. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/model.py +195 -377
  133. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/namespace.py +124 -137
  134. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/outputcapture.py +20 -12
  135. robotframework-7.0/src/robot/running/resourcemodel.py +448 -0
  136. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/statusreporter.py +16 -13
  137. robotframework-7.0/src/robot/running/suiterunner.py +265 -0
  138. robotframework-7.0/src/robot/running/testlibraries.py +500 -0
  139. robotframework-7.0/src/robot/running/userkeywordrunner.py +260 -0
  140. {robotframework-6.1.1 → robotframework-7.0}/src/robot/testdoc.py +18 -13
  141. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/__init__.py +53 -35
  142. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/connectioncache.py +64 -59
  143. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/dotdict.py +3 -0
  144. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/encodingsniffer.py +1 -1
  145. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/escaping.py +19 -19
  146. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/importer.py +2 -2
  147. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/markupwriters.py +23 -15
  148. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/misc.py +1 -2
  149. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/normalizing.py +9 -24
  150. robotframework-7.0/src/robot/utils/notset.py +33 -0
  151. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/platform.py +15 -5
  152. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/robotio.py +9 -9
  153. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/robotpath.py +1 -0
  154. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/robottime.py +122 -90
  155. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/robottypes.py +21 -31
  156. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/setter.py +0 -5
  157. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/text.py +7 -4
  158. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/unic.py +2 -2
  159. {robotframework-6.1.1 → robotframework-7.0}/src/robot/variables/__init__.py +2 -2
  160. {robotframework-6.1.1 → robotframework-7.0}/src/robot/variables/assigner.py +17 -19
  161. {robotframework-6.1.1 → robotframework-7.0}/src/robot/variables/evaluation.py +20 -17
  162. {robotframework-6.1.1 → robotframework-7.0}/src/robot/variables/filesetter.py +80 -80
  163. {robotframework-6.1.1 → robotframework-7.0}/src/robot/variables/replacer.py +33 -36
  164. {robotframework-6.1.1 → robotframework-7.0}/src/robot/variables/scopes.py +17 -12
  165. {robotframework-6.1.1 → robotframework-7.0}/src/robot/variables/search.py +66 -41
  166. {robotframework-6.1.1 → robotframework-7.0}/src/robot/variables/store.py +14 -16
  167. robotframework-7.0/src/robot/variables/tablesetter.py +164 -0
  168. {robotframework-6.1.1 → robotframework-7.0}/src/robot/variables/variables.py +1 -1
  169. {robotframework-6.1.1 → robotframework-7.0}/src/robot/version.py +1 -1
  170. {robotframework-6.1.1 → robotframework-7.0}/src/robotframework.egg-info/PKG-INFO +6 -8
  171. {robotframework-6.1.1 → robotframework-7.0}/src/robotframework.egg-info/SOURCES.txt +10 -8
  172. {robotframework-6.1.1 → robotframework-7.0}/tasks.py +6 -6
  173. robotframework-6.1.1/src/robot/htmldata/rebot/common.css +0 -239
  174. robotframework-6.1.1/src/robot/libraries/Reserved.py +0 -48
  175. robotframework-6.1.1/src/robot/model/keyword.py +0 -173
  176. robotframework-6.1.1/src/robot/output/console/dotted.py +0 -90
  177. robotframework-6.1.1/src/robot/output/listenerarguments.py +0 -165
  178. robotframework-6.1.1/src/robot/output/listenermethods.py +0 -113
  179. robotframework-6.1.1/src/robot/output/listeners.py +0 -174
  180. robotframework-6.1.1/src/robot/output/output.py +0 -95
  181. robotframework-6.1.1/src/robot/output/xmllogger.py +0 -354
  182. robotframework-6.1.1/src/robot/parsing/model/visitor.py +0 -67
  183. robotframework-6.1.1/src/robot/result/keywordremover.py +0 -183
  184. robotframework-6.1.1/src/robot/result/model.py +0 -957
  185. robotframework-6.1.1/src/robot/running/arguments/argumentconverter.py +0 -79
  186. robotframework-6.1.1/src/robot/running/arguments/argumentresolver.py +0 -131
  187. robotframework-6.1.1/src/robot/running/arguments/embedded.py +0 -146
  188. robotframework-6.1.1/src/robot/running/arguments/typevalidator.py +0 -56
  189. robotframework-6.1.1/src/robot/running/builder/transformers.py +0 -642
  190. robotframework-6.1.1/src/robot/running/handlers.py +0 -321
  191. robotframework-6.1.1/src/robot/running/handlerstore.py +0 -66
  192. robotframework-6.1.1/src/robot/running/librarykeywordrunner.py +0 -238
  193. robotframework-6.1.1/src/robot/running/libraryscopes.py +0 -97
  194. robotframework-6.1.1/src/robot/running/modelcombiner.py +0 -32
  195. robotframework-6.1.1/src/robot/running/suiterunner.py +0 -248
  196. robotframework-6.1.1/src/robot/running/testlibraries.py +0 -423
  197. robotframework-6.1.1/src/robot/running/usererrorhandler.py +0 -75
  198. robotframework-6.1.1/src/robot/running/userkeyword.py +0 -111
  199. robotframework-6.1.1/src/robot/running/userkeywordrunner.py +0 -274
  200. robotframework-6.1.1/src/robot/variables/tablesetter.py +0 -156
  201. {robotframework-6.1.1 → robotframework-7.0}/AUTHORS.rst +0 -0
  202. {robotframework-6.1.1 → robotframework-7.0}/BUILD.rst +0 -0
  203. {robotframework-6.1.1 → robotframework-7.0}/CONTRIBUTING.rst +0 -0
  204. {robotframework-6.1.1 → robotframework-7.0}/COPYRIGHT.txt +0 -0
  205. {robotframework-6.1.1 → robotframework-7.0}/LICENSE.txt +0 -0
  206. {robotframework-6.1.1 → robotframework-7.0}/MANIFEST.in +0 -0
  207. {robotframework-6.1.1 → robotframework-7.0}/setup.cfg +0 -0
  208. {robotframework-6.1.1 → robotframework-7.0}/src/robot/__init__.py +0 -0
  209. {robotframework-6.1.1 → robotframework-7.0}/src/robot/__main__.py +0 -0
  210. {robotframework-6.1.1 → robotframework-7.0}/src/robot/conf/__init__.py +0 -0
  211. {robotframework-6.1.1 → robotframework-7.0}/src/robot/errors.py +0 -0
  212. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/__init__.py +0 -0
  213. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/common/__init__.py +0 -0
  214. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/common/js_disabled.css +0 -0
  215. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/jsonwriter.py +0 -0
  216. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/lib/__init__.py +0 -0
  217. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/lib/jquery.highlight.min.js +0 -0
  218. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/lib/jquery.min.js +0 -0
  219. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/lib/jquery.tablesorter.min.js +0 -0
  220. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/lib/jquery.tmpl.min.js +0 -0
  221. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/lib/jsxcompressor.min.js +0 -0
  222. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/libdoc/__init__.py +0 -0
  223. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/libdoc/doc_formatting.css +0 -0
  224. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/libdoc/print.css +0 -0
  225. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/libdoc/pygments.css +0 -0
  226. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/__init__.py +0 -0
  227. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/fileloading.js +0 -0
  228. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/log.js +0 -0
  229. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/print.css +0 -0
  230. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/util.js +0 -0
  231. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/testdoc/__init__.py +0 -0
  232. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/testdoc/testdoc.css +0 -0
  233. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/testdoc/testdoc.html +0 -0
  234. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdoc.py +0 -0
  235. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/__init__.py +0 -0
  236. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/consoleviewer.py +0 -0
  237. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/htmlwriter.py +0 -0
  238. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/jsonwriter.py +0 -0
  239. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/output.py +0 -0
  240. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/writer.py +0 -0
  241. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/Dialogs.py +0 -0
  242. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/Easter.py +0 -0
  243. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/Screenshot.py +0 -0
  244. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/Telnet.py +0 -0
  245. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/dialogs_py.py +0 -0
  246. {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/fixture.py +0 -0
  247. {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/metadata.py +0 -0
  248. {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/modifier.py +0 -0
  249. {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/statistics.py +0 -0
  250. {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/suitestatistics.py +0 -0
  251. {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/tagsetter.py +0 -0
  252. {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/tagstatistics.py +0 -0
  253. {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/totalstatistics.py +0 -0
  254. {robotframework-6.1.1 → robotframework-7.0}/src/robot/output/__init__.py +0 -0
  255. {robotframework-6.1.1 → robotframework-7.0}/src/robot/output/console/__init__.py +0 -0
  256. {robotframework-6.1.1 → robotframework-7.0}/src/robot/output/console/highlighting.py +0 -0
  257. {robotframework-6.1.1 → robotframework-7.0}/src/robot/output/pyloggingconf.py +0 -0
  258. {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/__init__.py +0 -0
  259. {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/lexer/__init__.py +0 -0
  260. {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/lexer/tokenizer.py +0 -0
  261. {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/model/__init__.py +0 -0
  262. {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/parser/__init__.py +0 -0
  263. {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/parser/blockparsers.py +0 -0
  264. {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/parser/fileparser.py +0 -0
  265. {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/parser/parser.py +0 -0
  266. {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/suitestructure.py +0 -0
  267. {robotframework-6.1.1 → robotframework-7.0}/src/robot/pythonpathsetter.py +0 -0
  268. {robotframework-6.1.1 → robotframework-7.0}/src/robot/reporting/__init__.py +0 -0
  269. {robotframework-6.1.1 → robotframework-7.0}/src/robot/reporting/jsexecutionresult.py +0 -0
  270. {robotframework-6.1.1 → robotframework-7.0}/src/robot/reporting/jswriter.py +0 -0
  271. {robotframework-6.1.1 → robotframework-7.0}/src/robot/result/executionerrors.py +0 -0
  272. {robotframework-6.1.1 → robotframework-7.0}/src/robot/result/messagefilter.py +0 -0
  273. {robotframework-6.1.1 → robotframework-7.0}/src/robot/result/suiteteardownfailed.py +0 -0
  274. {robotframework-6.1.1 → robotframework-7.0}/src/robot/result/visitor.py +0 -0
  275. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/builder/__init__.py +0 -0
  276. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/randomizer.py +0 -0
  277. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/runkwregister.py +0 -0
  278. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/signalhandler.py +0 -0
  279. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/status.py +0 -0
  280. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/timeouts/__init__.py +0 -0
  281. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/timeouts/posix.py +0 -0
  282. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/timeouts/windows.py +0 -0
  283. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/application.py +0 -0
  284. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/argumentparser.py +0 -0
  285. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/asserts.py +0 -0
  286. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/charwidth.py +0 -0
  287. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/compress.py +0 -0
  288. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/encoding.py +0 -0
  289. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/error.py +0 -0
  290. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/etreewrapper.py +0 -0
  291. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/filereader.py +0 -0
  292. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/frange.py +0 -0
  293. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/htmlformatters.py +0 -0
  294. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/markuputils.py +0 -0
  295. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/match.py +0 -0
  296. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/recommendations.py +0 -0
  297. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/restreader.py +0 -0
  298. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/robotenv.py +0 -0
  299. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/robotinspect.py +0 -0
  300. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/sortable.py +0 -0
  301. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/typehints.py +0 -0
  302. {robotframework-6.1.1 → robotframework-7.0}/src/robot/variables/finders.py +0 -0
  303. {robotframework-6.1.1 → robotframework-7.0}/src/robot/variables/notfound.py +0 -0
  304. {robotframework-6.1.1 → robotframework-7.0}/src/robot/variables/resolvable.py +0 -0
  305. {robotframework-6.1.1 → robotframework-7.0}/src/robotframework.egg-info/dependency_links.txt +0 -0
  306. {robotframework-6.1.1 → robotframework-7.0}/src/robotframework.egg-info/entry_points.txt +0 -0
  307. {robotframework-6.1.1 → robotframework-7.0}/src/robotframework.egg-info/top_level.txt +0 -0
@@ -0,0 +1,535 @@
1
+ # Copyright 2008-2015 Nokia Networks
2
+ # Copyright 2016- Robot Framework Foundation
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ from robot.errors import DataError
17
+ from robot.output import LOGGER
18
+ from robot.parsing import File, ModelVisitor, Token
19
+ from robot.utils import NormalizedDict
20
+ from robot.variables import VariableMatches
21
+
22
+ from ..model import For, If, IfBranch, TestSuite, TestCase, Try, TryBranch, While
23
+ from ..resourcemodel import ResourceFile, UserKeyword
24
+ from .settings import FileSettings
25
+
26
+
27
+ class SettingsBuilder(ModelVisitor):
28
+
29
+ def __init__(self, suite: TestSuite, settings: FileSettings):
30
+ self.suite = suite
31
+ self.settings = settings
32
+
33
+ def visit_Documentation(self, node):
34
+ self.suite.doc = node.value
35
+
36
+ def visit_Metadata(self, node):
37
+ self.suite.metadata[node.name] = node.value
38
+
39
+ def visit_SuiteName(self, node):
40
+ self.suite.name = node.value
41
+
42
+ def visit_SuiteSetup(self, node):
43
+ self.suite.setup.config(name=node.name, args=node.args,
44
+ lineno=node.lineno)
45
+
46
+ def visit_SuiteTeardown(self, node):
47
+ self.suite.teardown.config(name=node.name, args=node.args,
48
+ lineno=node.lineno)
49
+
50
+ def visit_TestSetup(self, node):
51
+ self.settings.test_setup = {'name': node.name, 'args': node.args,
52
+ 'lineno': node.lineno}
53
+
54
+ def visit_TestTeardown(self, node):
55
+ self.settings.test_teardown = {'name': node.name, 'args': node.args,
56
+ 'lineno': node.lineno}
57
+
58
+ def visit_TestTimeout(self, node):
59
+ self.settings.test_timeout = node.value
60
+
61
+ def visit_DefaultTags(self, node):
62
+ self.settings.default_tags = node.values
63
+
64
+ def visit_TestTags(self, node):
65
+ self.settings.test_tags = node.values
66
+
67
+ def visit_KeywordTags(self, node):
68
+ self.settings.keyword_tags = node.values
69
+
70
+ def visit_TestTemplate(self, node):
71
+ self.settings.test_template = node.value
72
+
73
+ def visit_LibraryImport(self, node):
74
+ self.suite.resource.imports.library(node.name, node.args, node.alias, node.lineno)
75
+
76
+ def visit_ResourceImport(self, node):
77
+ self.suite.resource.imports.resource(node.name, node.lineno)
78
+
79
+ def visit_VariablesImport(self, node):
80
+ self.suite.resource.imports.variables(node.name, node.args, node.lineno)
81
+
82
+ def visit_VariableSection(self, node):
83
+ pass
84
+
85
+ def visit_TestCaseSection(self, node):
86
+ pass
87
+
88
+ def visit_KeywordSection(self, node):
89
+ pass
90
+
91
+
92
+ class SuiteBuilder(ModelVisitor):
93
+
94
+ def __init__(self, suite: TestSuite, settings: FileSettings):
95
+ self.suite = suite
96
+ self.settings = settings
97
+ self.seen_keywords = NormalizedDict(ignore='_')
98
+ self.rpa = None
99
+
100
+ def build(self, model: File):
101
+ ErrorReporter(model.source).visit(model)
102
+ SettingsBuilder(self.suite, self.settings).visit(model)
103
+ self.visit(model)
104
+ if self.rpa is not None:
105
+ self.suite.rpa = self.rpa
106
+
107
+ def visit_SettingSection(self, node):
108
+ pass
109
+
110
+ def visit_Variable(self, node):
111
+ self.suite.resource.variables.create(name=node.name,
112
+ value=node.value,
113
+ separator=node.separator,
114
+ lineno=node.lineno,
115
+ error=format_error(node.errors))
116
+
117
+ def visit_TestCaseSection(self, node):
118
+ if self.rpa is None:
119
+ self.rpa = node.tasks
120
+ elif self.rpa != node.tasks:
121
+ raise DataError('One file cannot have both tests and tasks.')
122
+ self.generic_visit(node)
123
+
124
+ def visit_TestCase(self, node):
125
+ TestCaseBuilder(self.suite, self.settings).build(node)
126
+
127
+ def visit_Keyword(self, node):
128
+ KeywordBuilder(self.suite.resource, self.settings, self.seen_keywords).build(node)
129
+
130
+
131
+ class ResourceBuilder(ModelVisitor):
132
+
133
+ def __init__(self, resource: ResourceFile):
134
+ self.resource = resource
135
+ self.settings = FileSettings()
136
+ self.seen_keywords = NormalizedDict(ignore='_')
137
+
138
+ def build(self, model: File):
139
+ ErrorReporter(model.source, raise_on_invalid_header=True).visit(model)
140
+ self.visit(model)
141
+
142
+ def visit_Documentation(self, node):
143
+ self.resource.doc = node.value
144
+
145
+ def visit_KeywordTags(self, node):
146
+ self.settings.keyword_tags = node.values
147
+
148
+ def visit_LibraryImport(self, node):
149
+ self.resource.imports.library(node.name, node.args, node.alias, node.lineno)
150
+
151
+ def visit_ResourceImport(self, node):
152
+ self.resource.imports.resource(node.name, node.lineno)
153
+
154
+ def visit_VariablesImport(self, node):
155
+ self.resource.imports.variables(node.name, node.args, node.lineno)
156
+
157
+ def visit_Variable(self, node):
158
+ self.resource.variables.create(name=node.name,
159
+ value=node.value,
160
+ separator=node.separator,
161
+ lineno=node.lineno,
162
+ error=format_error(node.errors))
163
+
164
+ def visit_Keyword(self, node):
165
+ KeywordBuilder(self.resource, self.settings, self.seen_keywords).build(node)
166
+
167
+
168
+ class BodyBuilder(ModelVisitor):
169
+
170
+ def __init__(self, model: 'TestCase|UserKeyword|For|If|Try|While|None' = None):
171
+ self.model = model
172
+
173
+ def visit_For(self, node):
174
+ ForBuilder(self.model).build(node)
175
+
176
+ def visit_While(self, node):
177
+ WhileBuilder(self.model).build(node)
178
+
179
+ def visit_If(self, node):
180
+ IfBuilder(self.model).build(node)
181
+
182
+ def visit_Try(self, node):
183
+ TryBuilder(self.model).build(node)
184
+
185
+ def visit_KeywordCall(self, node):
186
+ self.model.body.create_keyword(name=node.keyword, args=node.args,
187
+ assign=node.assign, lineno=node.lineno)
188
+
189
+ def visit_TemplateArguments(self, node):
190
+ self.model.body.create_keyword(args=node.args, lineno=node.lineno)
191
+
192
+ def visit_Var(self, node):
193
+ self.model.body.create_var(node.name, node.value, node.scope, node.separator,
194
+ lineno=node.lineno, error=format_error(node.errors))
195
+
196
+ def visit_Return(self, node):
197
+ self.model.body.create_return(node.values, lineno=node.lineno,
198
+ error=format_error(node.errors))
199
+
200
+ def visit_Continue(self, node):
201
+ self.model.body.create_continue(lineno=node.lineno,
202
+ error=format_error(node.errors))
203
+
204
+ def visit_Break(self, node):
205
+ self.model.body.create_break(lineno=node.lineno,
206
+ error=format_error(node.errors))
207
+
208
+ def visit_Error(self, node):
209
+ self.model.body.create_error(node.values, lineno=node.lineno,
210
+ error=format_error(node.errors))
211
+
212
+
213
+ class TestCaseBuilder(BodyBuilder):
214
+ model: TestCase
215
+
216
+ def __init__(self, suite: TestSuite, settings: FileSettings):
217
+ super().__init__(suite.tests.create())
218
+ self.settings = settings
219
+ self._test_has_tags = False
220
+
221
+ def build(self, node):
222
+ settings = self.settings
223
+ # Possible parsing errors aren't reported further with tests because:
224
+ # - We only validate that test body or name isn't empty.
225
+ # - That is validated again during execution.
226
+ # - This way e.g. model modifiers can add content to body.
227
+ self.model.config(name=node.name, tags=settings.test_tags,
228
+ timeout=settings.test_timeout,
229
+ template=settings.test_template,
230
+ lineno=node.lineno)
231
+ if settings.test_setup:
232
+ self.model.setup.config(**settings.test_setup)
233
+ if settings.test_teardown:
234
+ self.model.teardown.config(**settings.test_teardown)
235
+ self.generic_visit(node)
236
+ if not self._test_has_tags:
237
+ self.model.tags.add(settings.default_tags)
238
+ if self.model.template:
239
+ self._set_template(self.model, self.model.template)
240
+
241
+ def _set_template(self, parent, template):
242
+ for item in parent.body:
243
+ if item.type == item.FOR:
244
+ self._set_template(item, template)
245
+ elif item.type == item.IF_ELSE_ROOT:
246
+ for branch in item.body:
247
+ self._set_template(branch, template)
248
+ elif item.type == item.KEYWORD:
249
+ name, args = self._format_template(template, item.args)
250
+ item.name = name
251
+ item.args = args
252
+
253
+ def _format_template(self, template, arguments):
254
+ matches = VariableMatches(template, identifiers='$')
255
+ count = len(matches)
256
+ if count == 0 or count != len(arguments):
257
+ return template, arguments
258
+ temp = []
259
+ for match, arg in zip(matches, arguments):
260
+ temp[-1:] = [match.before, arg, match.after]
261
+ return ''.join(temp), ()
262
+
263
+ def visit_Documentation(self, node):
264
+ self.model.doc = node.value
265
+
266
+ def visit_Setup(self, node):
267
+ self.model.setup.config(name=node.name, args=node.args, lineno=node.lineno)
268
+
269
+ def visit_Teardown(self, node):
270
+ self.model.teardown.config(name=node.name, args=node.args, lineno=node.lineno)
271
+
272
+ def visit_Timeout(self, node):
273
+ self.model.timeout = node.value
274
+
275
+ def visit_Tags(self, node):
276
+ for tag in node.values:
277
+ if tag.startswith('-'):
278
+ self.model.tags.remove(tag[1:])
279
+ else:
280
+ self.model.tags.add(tag)
281
+ self._test_has_tags = True
282
+
283
+ def visit_Template(self, node):
284
+ self.model.template = node.value
285
+
286
+
287
+ class KeywordBuilder(BodyBuilder):
288
+ model: UserKeyword
289
+
290
+ def __init__(self, resource: ResourceFile, settings: FileSettings,
291
+ seen_keywords: NormalizedDict):
292
+ super().__init__(resource.keywords.create(tags=settings.keyword_tags))
293
+ self.resource = resource
294
+ self.seen_keywords = seen_keywords
295
+ self.return_setting = None
296
+
297
+ def build(self, node):
298
+ kw = self.model
299
+ try:
300
+ # Validate only name here. Reporting all parsing errors would report also
301
+ # body being empty, but we want to validate it only at parsing time.
302
+ if not node.name:
303
+ raise DataError('User keyword name cannot be empty.')
304
+ kw.config(name=node.name, lineno=node.lineno)
305
+ except DataError as err:
306
+ # Errors other than name being empty mean that name contains invalid
307
+ # embedded arguments. Need to set `_name` to bypass `@property`.
308
+ kw.config(_name=node.name, lineno=node.lineno, error=str(err))
309
+ self._report_error(node, err)
310
+ self.generic_visit(node)
311
+ if self.return_setting:
312
+ kw.body.create_return(self.return_setting)
313
+ if not kw.embedded:
314
+ self._handle_duplicates(kw, self.seen_keywords, node)
315
+
316
+ def _report_error(self, node, error):
317
+ error = f"Creating keyword '{self.model.name}' failed: {error}"
318
+ ErrorReporter(self.model.source).report_error(node, error)
319
+
320
+ def _handle_duplicates(self, kw, seen, node):
321
+ if kw.name in seen:
322
+ error = 'Keyword with same name defined multiple times.'
323
+ seen[kw.name].error = error
324
+ self.resource.keywords.pop()
325
+ self._report_error(node, error)
326
+ else:
327
+ seen[kw.name] = kw
328
+
329
+ def visit_Documentation(self, node):
330
+ self.model.doc = node.value
331
+
332
+ def visit_Arguments(self, node):
333
+ if node.errors:
334
+ error = 'Invalid argument specification: ' + format_error(node.errors)
335
+ self.model.error = error
336
+ self._report_error(node, error)
337
+ else:
338
+ self.model.args = node.values
339
+
340
+ def visit_Tags(self, node):
341
+ for tag in node.values:
342
+ if tag.startswith('-'):
343
+ self.model.tags.remove(tag[1:])
344
+ else:
345
+ self.model.tags.add(tag)
346
+
347
+ def visit_ReturnSetting(self, node):
348
+ ErrorReporter(self.model.source).visit(node)
349
+ self.return_setting = node.values
350
+
351
+ def visit_Timeout(self, node):
352
+ self.model.timeout = node.value
353
+
354
+ def visit_Setup(self, node):
355
+ self.model.setup.config(name=node.name, args=node.args, lineno=node.lineno)
356
+
357
+ def visit_Teardown(self, node):
358
+ self.model.teardown.config(name=node.name, args=node.args, lineno=node.lineno)
359
+
360
+ def visit_KeywordCall(self, node):
361
+ self.model.body.create_keyword(name=node.keyword, args=node.args,
362
+ assign=node.assign, lineno=node.lineno)
363
+
364
+
365
+ class ForBuilder(BodyBuilder):
366
+ model: For
367
+
368
+ def __init__(self, parent: 'TestCase|UserKeyword|For|If|Try|While'):
369
+ super().__init__(parent.body.create_for())
370
+
371
+ def build(self, node):
372
+ error = format_error(self._get_errors(node))
373
+ self.model.config(assign=node.assign, flavor=node.flavor, values=node.values,
374
+ start=node.start, mode=node.mode, fill=node.fill,
375
+ lineno=node.lineno, error=error)
376
+ for step in node.body:
377
+ self.visit(step)
378
+ return self.model
379
+
380
+ def _get_errors(self, node):
381
+ errors = node.header.errors + node.errors
382
+ if node.end:
383
+ errors += node.end.errors
384
+ return errors
385
+
386
+
387
+ class IfBuilder(BodyBuilder):
388
+ model: 'IfBranch|None'
389
+
390
+ def __init__(self, parent: 'TestCase|UserKeyword|For|If|Try|While'):
391
+ super().__init__()
392
+ self.root = parent.body.create_if()
393
+
394
+ def build(self, node):
395
+ self.root.config(lineno=node.lineno, error=format_error(self._get_errors(node)))
396
+ assign = node.assign
397
+ node_type = None
398
+ while node:
399
+ node_type = node.type if node.type != 'INLINE IF' else 'IF'
400
+ self.model = self.root.body.create_branch(node_type, node.condition,
401
+ lineno=node.lineno)
402
+ for step in node.body:
403
+ self.visit(step)
404
+ if assign:
405
+ for item in self.model.body:
406
+ # Having assign when model item doesn't support assign is an error,
407
+ # but it has been handled already when model was validated.
408
+ if hasattr(item, 'assign'):
409
+ item.assign = assign
410
+ node = node.orelse
411
+ # Smallish hack to make sure assignment is always run.
412
+ if assign and node_type != 'ELSE':
413
+ self.root.body.create_branch('ELSE').body.create_keyword(
414
+ assign=assign, name='BuiltIn.Set Variable', args=['${NONE}']
415
+ )
416
+ return self.root
417
+
418
+ def _get_errors(self, node):
419
+ errors = node.header.errors + node.errors
420
+ if node.orelse:
421
+ errors += self._get_errors(node.orelse)
422
+ if node.end:
423
+ errors += node.end.errors
424
+ return errors
425
+
426
+
427
+ class TryBuilder(BodyBuilder):
428
+ model: 'TryBranch|None'
429
+
430
+ def __init__(self, parent: 'TestCase|UserKeyword|For|If|Try|While'):
431
+ super().__init__()
432
+ self.root = parent.body.create_try()
433
+ self.template_error = None
434
+
435
+ def build(self, node):
436
+ self.root.config(lineno=node.lineno)
437
+ errors = self._get_errors(node)
438
+ while node:
439
+ self.model = self.root.body.create_branch(node.type, node.patterns,
440
+ node.pattern_type, node.assign,
441
+ lineno=node.lineno)
442
+ for step in node.body:
443
+ self.visit(step)
444
+ node = node.next
445
+ if self.template_error:
446
+ errors += (self.template_error,)
447
+ if errors:
448
+ self.root.error = format_error(errors)
449
+ return self.root
450
+
451
+ def _get_errors(self, node):
452
+ errors = node.header.errors + node.errors
453
+ if node.next:
454
+ errors += self._get_errors(node.next)
455
+ if node.end:
456
+ errors += node.end.errors
457
+ return errors
458
+
459
+ def visit_TemplateArguments(self, node):
460
+ self.template_error = 'Templates cannot be used with TRY.'
461
+
462
+
463
+ class WhileBuilder(BodyBuilder):
464
+ model: While
465
+
466
+ def __init__(self, parent: 'TestCase|UserKeyword|For|If|Try|While'):
467
+ super().__init__(parent.body.create_while())
468
+
469
+ def build(self, node):
470
+ error = format_error(self._get_errors(node))
471
+ self.model.config(condition=node.condition, limit=node.limit,
472
+ on_limit=node.on_limit, on_limit_message=node.on_limit_message,
473
+ lineno=node.lineno, error=error)
474
+ for step in node.body:
475
+ self.visit(step)
476
+ return self.model
477
+
478
+ def _get_errors(self, node):
479
+ errors = node.header.errors + node.errors
480
+ if node.end:
481
+ errors += node.end.errors
482
+ return errors
483
+
484
+
485
+ def format_error(errors):
486
+ if not errors:
487
+ return None
488
+ if len(errors) == 1:
489
+ return errors[0]
490
+ return '\n- '.join(('Multiple errors:',) + errors)
491
+
492
+
493
+ class ErrorReporter(ModelVisitor):
494
+
495
+ def __init__(self, source, raise_on_invalid_header=False):
496
+ self.source = source
497
+ self.raise_on_invalid_header = raise_on_invalid_header
498
+
499
+ def visit_TestCase(self, node):
500
+ pass
501
+
502
+ def visit_Keyword(self, node):
503
+ pass
504
+
505
+ def visit_ReturnSetting(self, node):
506
+ # Empty 'visit_Keyword' above prevents calling this when visiting the whole
507
+ # model, but 'KeywordBuilder.visit_ReturnSetting' visits the node it gets.
508
+ self.report_error(node.get_token(Token.RETURN_SETTING), warn=True)
509
+
510
+ def visit_SectionHeader(self, node):
511
+ token = node.get_token(*Token.HEADER_TOKENS)
512
+ if not token.error:
513
+ return
514
+ if token.type == Token.INVALID_HEADER:
515
+ self.report_error(token, throw=self.raise_on_invalid_header)
516
+ else:
517
+ # Errors, other than totally invalid headers, can occur only with
518
+ # deprecated singular headers, and we want to report them as warnings.
519
+ # A more generic solution for separating errors and warnings would be good.
520
+ self.report_error(token, warn=True)
521
+
522
+ def visit_Error(self, node):
523
+ for token in node.get_tokens(Token.ERROR):
524
+ self.report_error(token)
525
+
526
+ def report_error(self, source, error=None, warn=False, throw=False):
527
+ if not error:
528
+ if isinstance(source, Token):
529
+ error = source.error
530
+ else:
531
+ error = format_error(source.errors)
532
+ message = f"Error in file '{self.source}' on line {source.lineno}: {error}"
533
+ if throw:
534
+ raise DataError(message)
535
+ LOGGER.write(message, level='WARN' if warn else 'ERROR')