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
@@ -13,21 +13,19 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
 
16
+ import re
17
+ import time
16
18
  from collections import OrderedDict
17
19
  from contextlib import contextmanager
20
+ from datetime import datetime
18
21
  from itertools import zip_longest
19
- import re
20
- import time
21
22
 
22
23
  from robot.errors import (BreakLoop, ContinueLoop, DataError, ExecutionFailed,
23
24
  ExecutionFailures, ExecutionPassed, ExecutionStatus)
24
- from robot.result import (For as ForResult, While as WhileResult, If as IfResult,
25
- IfBranch as IfBranchResult, Try as TryResult,
26
- TryBranch as TryBranchResult)
27
25
  from robot.output import librarylogger as logger
28
- from robot.utils import (cut_assign_value, frange, get_error_message, get_timestamp,
29
- is_list_like, is_number, plural_or_not as s, secs_to_timestr,
30
- seq2str, split_from_equals, type_name, Matcher, timestr_to_secs)
26
+ from robot.utils import (cut_assign_value, frange, get_error_message, is_list_like,
27
+ is_number, normalize, plural_or_not as s, secs_to_timestr, seq2str,
28
+ split_from_equals, type_name, Matcher, timestr_to_secs)
31
29
  from robot.variables import is_dict_variable, evaluate_expression
32
30
 
33
31
  from .statusreporter import StatusReporter
@@ -43,12 +41,12 @@ class BodyRunner:
43
41
  self._run = run
44
42
  self._templated = templated
45
43
 
46
- def run(self, body):
44
+ def run(self, data, result):
47
45
  errors = []
48
46
  passed = None
49
- for step in body:
47
+ for item in data.body:
50
48
  try:
51
- step.run(self._context, self._run, self._templated)
49
+ item.run(result, self._context, self._run, self._templated)
52
50
  except ExecutionPassed as exception:
53
51
  exception.set_earlier_failures(errors)
54
52
  passed = exception
@@ -68,12 +66,12 @@ class KeywordRunner:
68
66
  self._context = context
69
67
  self._run = run
70
68
 
71
- def run(self, step, name=None):
69
+ def run(self, data, result, name=None):
72
70
  context = self._context
73
- runner = context.get_runner(name or step.name)
71
+ runner = context.get_runner(name or data.name)
74
72
  if context.dry_run:
75
- return runner.dry_run(step, context)
76
- return runner.run(step, context, self._run)
73
+ return runner.dry_run(data, result, context)
74
+ return runner.run(data, result, context, self._run)
77
75
 
78
76
 
79
77
  def ForRunner(context, flavor='IN', run=True, templated=False):
@@ -93,7 +91,7 @@ class ForInRunner:
93
91
  self._run = run
94
92
  self._templated = templated
95
93
 
96
- def run(self, data):
94
+ def run(self, data, result):
97
95
  error = None
98
96
  run = False
99
97
  if self._run:
@@ -101,8 +99,6 @@ class ForInRunner:
101
99
  error = DataError(data.error, syntax=True)
102
100
  else:
103
101
  run = True
104
- result = ForResult(data.variables, data.flavor, data.values, data.start,
105
- data.mode, data.fill)
106
102
  with StatusReporter(data, result, self._context, run) as status:
107
103
  if run:
108
104
  try:
@@ -143,7 +139,7 @@ class ForInRunner:
143
139
  def _get_values_for_rounds(self, data):
144
140
  if self._context.dry_run:
145
141
  return [None]
146
- values_per_round = len(data.variables)
142
+ values_per_round = len(data.assign)
147
143
  if self._is_dict_iteration(data.values):
148
144
  values = self._resolve_dict_values(data.values)
149
145
  values = self._map_dict_values_to_rounds(values, values_per_round)
@@ -213,18 +209,20 @@ class ForInRunner:
213
209
  f'value{s(values)}.')
214
210
 
215
211
  def _run_one_round(self, data, result, values=None, run=True):
216
- result = result.body.create_iteration()
212
+ iter_data = data.get_iteration()
213
+ iter_result = result.body.create_iteration()
217
214
  if values is not None:
218
215
  variables = self._context.variables
219
- else: # Not really run (earlier failure, unexecuted IF branch, dry-run)
216
+ else: # Not really run (earlier failure, un-executed IF branch, dry-run)
220
217
  variables = {}
221
- values = [''] * len(data.variables)
222
- for name, value in self._map_variables_and_values(data.variables, values):
218
+ values = [''] * len(data.assign)
219
+ for name, value in self._map_variables_and_values(data.assign, values):
223
220
  variables[name] = value
224
- result.variables[name] = cut_assign_value(value)
221
+ iter_data.assign[name] = value
222
+ iter_result.assign[name] = cut_assign_value(value)
225
223
  runner = BodyRunner(self._context, run, self._templated)
226
- with StatusReporter(data, result, self._context, run):
227
- runner.run(data.body)
224
+ with StatusReporter(iter_data, iter_result, self._context, run):
225
+ runner.run(iter_data, iter_result)
228
226
 
229
227
  def _map_variables_and_values(self, variables, values):
230
228
  if len(variables) == 1 and len(values) != 1:
@@ -274,13 +272,13 @@ class ForInZipRunner(ForInRunner):
274
272
  if not mode or self._context.dry_run:
275
273
  return None
276
274
  try:
277
- mode = self._context.variables.replace_string(mode).upper()
278
- if mode in ('STRICT', 'SHORTEST', 'LONGEST'):
279
- return mode
280
- raise DataError(f"Mode must be 'STRICT', 'SHORTEST' or 'LONGEST', "
281
- f"got '{mode}'.")
275
+ mode = self._context.variables.replace_string(mode)
276
+ if mode.upper() in ('STRICT', 'SHORTEST', 'LONGEST'):
277
+ return mode.upper()
278
+ raise DataError(f"Value '{mode}' is not accepted. Valid values "
279
+ f"are 'STRICT', 'SHORTEST' and 'LONGEST'.")
282
280
  except DataError as err:
283
- raise DataError(f'Invalid mode: {err}')
281
+ raise DataError(f'Invalid FOR IN ZIP mode: {err}')
284
282
 
285
283
  def _resolve_fill(self, fill):
286
284
  if not fill or self._context.dry_run:
@@ -288,7 +286,7 @@ class ForInZipRunner(ForInRunner):
288
286
  try:
289
287
  return self._context.variables.replace_scalar(fill)
290
288
  except DataError as err:
291
- raise DataError(f'Invalid fill value: {err}')
289
+ raise DataError(f'Invalid FOR IN ZIP fill value: {err}')
292
290
 
293
291
  def _resolve_dict_values(self, values):
294
292
  raise DataError('FOR IN ZIP loops do not support iterating over dictionaries.',
@@ -302,6 +300,8 @@ class ForInZipRunner(ForInRunner):
302
300
  return zip_longest(*values, fillvalue=self._fill)
303
301
  if self._mode == 'STRICT':
304
302
  self._validate_strict_lengths(values)
303
+ if self._mode is None:
304
+ self._deprecate_different_lengths(values)
305
305
  return zip(*values)
306
306
 
307
307
  def _validate_types(self, values):
@@ -316,12 +316,21 @@ class ForInZipRunner(ForInRunner):
316
316
  try:
317
317
  lengths.append(len(item))
318
318
  except TypeError:
319
- raise DataError(f"FOR IN ZIP items should have length in STRICT mode, "
320
- f"but item {index} does not.")
319
+ raise DataError(f"FOR IN ZIP items must have length in the STRICT "
320
+ f"mode, but item {index} does not.")
321
321
  if len(set(lengths)) > 1:
322
- raise DataError(f"FOR IN ZIP items should have equal lengths in STRICT "
322
+ raise DataError(f"FOR IN ZIP items must have equal lengths in the STRICT "
323
323
  f"mode, but lengths are {seq2str(lengths, quote='')}.")
324
324
 
325
+ def _deprecate_different_lengths(self, values):
326
+ try:
327
+ self._validate_strict_lengths(values)
328
+ except DataError as err:
329
+ logger.warn(f"FOR IN ZIP default mode will be changed from SHORTEST to "
330
+ f"STRICT in Robot Framework 8.0. Use 'mode=SHORTEST' to keep "
331
+ f"using the SHORTEST mode. If the mode is not changed, "
332
+ f"execution will fail like this in the future: {err}")
333
+
325
334
 
326
335
  class ForInEnumerateRunner(ForInRunner):
327
336
  flavor = 'IN ENUMERATE'
@@ -339,9 +348,9 @@ class ForInEnumerateRunner(ForInRunner):
339
348
  try:
340
349
  return int(start)
341
350
  except ValueError:
342
- raise DataError(f"Start value must be an integer, got '{start}'.")
351
+ raise DataError(f"Value must be an integer, got '{start}'.")
343
352
  except DataError as err:
344
- raise DataError(f'Invalid start value: {err}')
353
+ raise DataError(f'Invalid FOR IN ENUMERATE start value: {err}')
345
354
 
346
355
  def _map_dict_values_to_rounds(self, values, per_round):
347
356
  if per_round > 3:
@@ -370,15 +379,13 @@ class WhileRunner:
370
379
  self._run = run
371
380
  self._templated = templated
372
381
 
373
- def run(self, data):
382
+ def run(self, data, result):
374
383
  ctx = self._context
375
384
  error = None
376
385
  run = False
377
386
  limit = None
378
- loop_result = WhileResult(data.condition, data.limit,
379
- data.on_limit, data.on_limit_message,
380
- starttime=get_timestamp())
381
- iter_result = loop_result.body.create_iteration(starttime=get_timestamp())
387
+ result.start_time = datetime.now()
388
+ iter_result = result.body.create_iteration(start_time=datetime.now())
382
389
  if self._run:
383
390
  if data.error:
384
391
  error = DataError(data.error, syntax=True)
@@ -391,9 +398,10 @@ class WhileRunner:
391
398
  run = self._should_run(data.condition, ctx.variables)
392
399
  except DataError as err:
393
400
  error = err
394
- with StatusReporter(data, loop_result, self._context, run):
401
+ with StatusReporter(data, result, self._context, run):
402
+ iter_data = data.get_iteration()
395
403
  if ctx.dry_run or not run:
396
- self._run_iteration(data, iter_result, run)
404
+ self._run_iteration(iter_data, iter_result, run)
397
405
  if error:
398
406
  raise error
399
407
  return
@@ -401,7 +409,7 @@ class WhileRunner:
401
409
  while True:
402
410
  try:
403
411
  with limit:
404
- self._run_iteration(data, iter_result)
412
+ self._run_iteration(iter_data, iter_result)
405
413
  except (BreakLoop, ContinueLoop) as ctrl:
406
414
  if ctrl.earlier_failures:
407
415
  errors.extend(ctrl.earlier_failures.get_errors())
@@ -420,7 +428,8 @@ class WhileRunner:
420
428
  errors.extend(failed.get_errors())
421
429
  if not failed.can_continue(ctx, self._templated):
422
430
  break
423
- iter_result = loop_result.body.create_iteration(starttime=get_timestamp())
431
+ iter_result = result.body.create_iteration(start_time=datetime.now())
432
+ iter_data = data.get_iteration()
424
433
  if not self._should_run(data.condition, ctx.variables):
425
434
  break
426
435
  if errors:
@@ -429,7 +438,7 @@ class WhileRunner:
429
438
  def _run_iteration(self, data, result, run=True):
430
439
  runner = BodyRunner(self._context, run, self._templated)
431
440
  with StatusReporter(data, result, self._context, run):
432
- runner.run(data.body)
441
+ runner.run(data, result)
433
442
 
434
443
  def _should_run(self, condition, variables):
435
444
  if not condition:
@@ -450,13 +459,13 @@ class IfRunner:
450
459
  self._run = run
451
460
  self._templated = templated
452
461
 
453
- def run(self, data):
462
+ def run(self, data, result):
454
463
  with self._dry_run_recursion_detection(data) as recursive_dry_run:
455
464
  error = None
456
- with StatusReporter(data, IfResult(), self._context, self._run):
465
+ with StatusReporter(data, result, self._context, self._run):
457
466
  for branch in data.body:
458
467
  try:
459
- if self._run_if_branch(branch, recursive_dry_run, data.error):
468
+ if self._run_if_branch(branch, result, recursive_dry_run, data.error):
460
469
  self._run = False
461
470
  except ExecutionStatus as err:
462
471
  error = err
@@ -466,54 +475,52 @@ class IfRunner:
466
475
 
467
476
  @contextmanager
468
477
  def _dry_run_recursion_detection(self, data):
469
- dry_run = self._context.dry_run
470
- if dry_run:
471
- recursive_dry_run = data in self._dry_run_stack
472
- self._dry_run_stack.append(data)
478
+ if not self._context.dry_run:
479
+ yield False
473
480
  else:
474
- recursive_dry_run = False
475
- try:
476
- yield recursive_dry_run
477
- finally:
478
- if dry_run:
481
+ data = data.to_dict()
482
+ recursive = data in self._dry_run_stack
483
+ self._dry_run_stack.append(data)
484
+ try:
485
+ yield recursive
486
+ finally:
479
487
  self._dry_run_stack.pop()
480
488
 
481
- def _run_if_branch(self, branch, recursive_dry_run=False, syntax_error=None):
489
+ def _run_if_branch(self, data, result, recursive_dry_run=False, syntax_error=None):
482
490
  context = self._context
483
- result = IfBranchResult(branch.type, branch.condition, starttime=get_timestamp())
491
+ result = result.body.create_branch(data.type, data.condition,
492
+ start_time=datetime.now())
484
493
  error = None
485
494
  if syntax_error:
486
495
  run_branch = False
487
496
  error = DataError(syntax_error, syntax=True)
488
497
  else:
489
498
  try:
490
- run_branch = self._should_run_branch(branch, context, recursive_dry_run)
499
+ run_branch = self._should_run_branch(data, context, recursive_dry_run)
491
500
  except DataError as err:
492
501
  error = err
493
502
  run_branch = False
494
- with StatusReporter(branch, result, context, run_branch):
503
+ with StatusReporter(data, result, context, run_branch):
495
504
  runner = BodyRunner(context, run_branch, self._templated)
496
505
  if not recursive_dry_run:
497
- runner.run(branch.body)
506
+ runner.run(data, result)
498
507
  if error and self._run:
499
508
  raise error
500
509
  return run_branch
501
510
 
502
- def _should_run_branch(self, branch, context, recursive_dry_run=False):
503
- condition = branch.condition
504
- variables = context.variables
511
+ def _should_run_branch(self, data, context, recursive_dry_run=False):
505
512
  if context.dry_run:
506
513
  return not recursive_dry_run
507
514
  if not self._run:
508
515
  return False
509
- if condition is None:
516
+ if data.condition is None:
510
517
  return True
511
518
  try:
512
- return evaluate_expression(condition, variables.current,
519
+ return evaluate_expression(data.condition, context.variables.current,
513
520
  resolve_variables=True)
514
521
  except Exception:
515
522
  msg = get_error_message()
516
- raise DataError(f'Invalid {branch.type} condition: {msg}')
523
+ raise DataError(f'Invalid {data.type} condition: {msg}')
517
524
 
518
525
 
519
526
  class TryRunner:
@@ -523,39 +530,39 @@ class TryRunner:
523
530
  self._run = run
524
531
  self._templated = templated
525
532
 
526
- def run(self, data):
533
+ def run(self, data, result):
527
534
  run = self._run
528
- with StatusReporter(data, TryResult(), self._context, run):
535
+ with StatusReporter(data, result, self._context, run):
529
536
  if data.error:
530
- self._run_invalid(data)
537
+ self._run_invalid(data, result)
531
538
  return
532
- error = self._run_try(data, run)
539
+ error = self._run_try(data, result, run)
533
540
  run_excepts_or_else = self._should_run_excepts_or_else(error, run)
534
541
  if error:
535
- error = self._run_excepts(data, error, run=run_excepts_or_else)
536
- self._run_else(data, run=False)
542
+ error = self._run_excepts(data, result, error, run=run_excepts_or_else)
543
+ self._run_else(data, result, run=False)
537
544
  else:
538
- self._run_excepts(data, error, run=False)
539
- error = self._run_else(data, run=run_excepts_or_else)
540
- error = self._run_finally(data, run) or error
545
+ self._run_excepts(data, result, error, run=False)
546
+ error = self._run_else(data, result, run=run_excepts_or_else)
547
+ error = self._run_finally(data, result, run) or error
541
548
  if error:
542
549
  raise error
543
550
 
544
- def _run_invalid(self, data):
551
+ def _run_invalid(self, data, result):
545
552
  error_reported = False
546
553
  for branch in data.body:
547
- result = TryBranchResult(branch.type, branch.patterns, branch.pattern_type,
548
- branch.variable)
549
- with StatusReporter(branch, result, self._context, run=False, suppress=True):
554
+ branch_result = result.body.create_branch(branch.type, branch.patterns,
555
+ branch.pattern_type, branch.assign)
556
+ with StatusReporter(branch, branch_result, self._context, run=False, suppress=True):
550
557
  runner = BodyRunner(self._context, run=False, templated=self._templated)
551
- runner.run(branch.body)
558
+ runner.run(branch, branch_result)
552
559
  if not error_reported:
553
560
  error_reported = True
554
561
  raise DataError(data.error, syntax=True)
555
562
  raise ExecutionFailed(data.error, syntax=True)
556
563
 
557
- def _run_try(self, data, run):
558
- result = TryBranchResult(data.TRY)
564
+ def _run_try(self, data, result, run):
565
+ result = result.body.create_branch(data.TRY)
559
566
  return self._run_branch(data.try_branch, result, run)
560
567
 
561
568
  def _should_run_excepts_or_else(self, error, run):
@@ -565,19 +572,19 @@ class TryRunner:
565
572
  return True
566
573
  return not (error.skip or error.syntax or isinstance(error, ExecutionPassed))
567
574
 
568
- def _run_branch(self, branch, result, run=True, error=None):
575
+ def _run_branch(self, data, result, run=True, error=None):
569
576
  try:
570
- with StatusReporter(branch, result, self._context, run):
577
+ with StatusReporter(data, result, self._context, run):
571
578
  if error:
572
579
  raise error
573
580
  runner = BodyRunner(self._context, run, self._templated)
574
- runner.run(branch.body)
581
+ runner.run(data, result)
575
582
  except ExecutionStatus as err:
576
583
  return err
577
584
  else:
578
585
  return None
579
586
 
580
- def _run_excepts(self, data, error, run):
587
+ def _run_excepts(self, data, result, error, run):
581
588
  for branch in data.except_branches:
582
589
  try:
583
590
  run_branch = run and self._should_run_except(branch, error)
@@ -586,15 +593,15 @@ class TryRunner:
586
593
  pattern_error = err
587
594
  else:
588
595
  pattern_error = None
589
- result = TryBranchResult(branch.type, branch.patterns,
590
- branch.pattern_type, branch.variable)
596
+ branch_result = result.body.create_branch(branch.type, branch.patterns,
597
+ branch.pattern_type, branch.assign)
591
598
  if run_branch:
592
- if branch.variable:
593
- self._context.variables[branch.variable] = str(error)
594
- error = self._run_branch(branch, result, error=pattern_error)
599
+ if branch.assign:
600
+ self._context.variables[branch.assign] = str(error)
601
+ error = self._run_branch(branch, branch_result, error=pattern_error)
595
602
  run = False
596
603
  else:
597
- self._run_branch(branch, result, run=False)
604
+ self._run_branch(branch, branch_result, run=False)
598
605
  return error
599
606
 
600
607
  def _should_run_except(self, branch, error):
@@ -602,9 +609,9 @@ class TryRunner:
602
609
  return True
603
610
  matchers = {
604
611
  'GLOB': lambda m, p: Matcher(p, spaceless=False, caseless=False).match(m),
612
+ 'REGEXP': lambda m, p: re.fullmatch(p, m) is not None,
613
+ 'START': lambda m, p: m.startswith(p),
605
614
  'LITERAL': lambda m, p: m == p,
606
- 'REGEXP': lambda m, p: re.match(rf'{p}\Z', m) is not None,
607
- 'START': lambda m, p: m.startswith(p)
608
615
  }
609
616
  if branch.pattern_type:
610
617
  pattern_type = self._context.variables.replace_string(branch.pattern_type)
@@ -612,25 +619,25 @@ class TryRunner:
612
619
  pattern_type = 'LITERAL'
613
620
  matcher = matchers.get(pattern_type.upper())
614
621
  if not matcher:
615
- raise DataError(f"Invalid EXCEPT pattern type '{pattern_type}', "
616
- f"expected {seq2str(matchers, lastsep=' or ')}.")
622
+ raise DataError(f"Invalid EXCEPT pattern type '{pattern_type}'. "
623
+ f"Valid values are {seq2str(matchers)}.")
617
624
  for pattern in branch.patterns:
618
625
  if matcher(error.message, self._context.variables.replace_string(pattern)):
619
626
  return True
620
627
  return False
621
628
 
622
- def _run_else(self, data, run):
629
+ def _run_else(self, data, result, run):
623
630
  if data.else_branch:
624
- result = TryBranchResult(data.ELSE)
631
+ result = result.body.create_branch(data.ELSE)
625
632
  return self._run_branch(data.else_branch, result, run)
626
633
 
627
- def _run_finally(self, data, run):
634
+ def _run_finally(self, data, result, run):
628
635
  if data.finally_branch:
629
- result = TryBranchResult(data.FINALLY)
636
+ result = result.body.create_branch(data.FINALLY)
630
637
  try:
631
638
  with StatusReporter(data.finally_branch, result, self._context, run):
632
639
  runner = BodyRunner(self._context, run, self._templated)
633
- runner.run(data.finally_branch.body)
640
+ runner.run(data.finally_branch, result)
634
641
  except ExecutionStatus as err:
635
642
  return err
636
643
  else:
@@ -650,44 +657,55 @@ class WhileLimit:
650
657
  on_limit_message = variables.replace_string(on_limit_message)
651
658
  except DataError as err:
652
659
  raise DataError(f"Invalid WHILE loop 'on_limit_message': '{err}")
653
- on_limit = cls.parse_on_limit(variables, on_limit)
660
+ on_limit = cls._parse_on_limit(variables, on_limit)
654
661
  if not limit:
655
- return IterationCountLimit(DEFAULT_WHILE_LIMIT,
656
- on_limit, on_limit_message)
657
- value = variables.replace_string(limit)
658
- if value.upper() == 'NONE':
662
+ return IterationCountLimit(DEFAULT_WHILE_LIMIT, on_limit, on_limit_message)
663
+ limit = variables.replace_string(limit)
664
+ if limit.upper() == 'NONE':
659
665
  return NoLimit()
660
666
  try:
661
- count = int(value.replace(' ', ''))
667
+ count = cls._parse_limit_as_count(limit)
662
668
  except ValueError:
663
- pass
669
+ seconds = cls._parse_limit_as_timestr(limit)
670
+ return DurationLimit(seconds, on_limit, on_limit_message)
664
671
  else:
665
- if count <= 0:
666
- raise DataError(f"Invalid WHILE loop limit: Iteration count must be "
667
- f"a positive integer, got '{count}'.")
668
672
  return IterationCountLimit(count, on_limit, on_limit_message)
669
- try:
670
- secs = timestr_to_secs(value)
671
- except ValueError as err:
672
- raise DataError(f'Invalid WHILE loop limit: {err.args[0]}')
673
- else:
674
- return DurationLimit(secs, on_limit, on_limit_message)
675
673
 
676
674
  @classmethod
677
- def parse_on_limit(cls, variables, on_limit):
675
+ def _parse_on_limit(cls, variables, on_limit):
678
676
  if on_limit is None:
679
677
  return None
680
678
  try:
681
679
  on_limit = variables.replace_string(on_limit)
682
- if on_limit.upper() not in ['PASS', 'FAIL']:
683
- raise DataError("Value must be 'PASS' or 'FAIL'.")
680
+ if on_limit.upper() in ('PASS', 'FAIL'):
681
+ return on_limit.upper()
682
+ raise DataError(f"Value '{on_limit}' is not accepted. Valid values "
683
+ f"are 'PASS' and 'FAIL'.")
684
684
  except DataError as err:
685
- raise DataError(f"Invalid WHILE loop 'on_limit' value '{on_limit}': {err}")
686
- else:
687
- return on_limit.lower()
685
+ raise DataError(f"Invalid WHILE loop 'on_limit' value: {err}")
686
+
687
+ @classmethod
688
+ def _parse_limit_as_count(cls, limit):
689
+ limit = normalize(limit)
690
+ if limit.endswith('times'):
691
+ limit = limit[:-5]
692
+ elif limit.endswith('x'):
693
+ limit = limit[:-1]
694
+ count = int(limit)
695
+ if count <= 0:
696
+ raise DataError(f"Invalid WHILE loop limit: Iteration count must be "
697
+ f"a positive integer, got '{count}'.")
698
+ return count
699
+
700
+ @classmethod
701
+ def _parse_limit_as_timestr(cls, limit):
702
+ try:
703
+ return timestr_to_secs(limit)
704
+ except ValueError as err:
705
+ raise DataError(f'Invalid WHILE loop limit: {err.args[0]}')
688
706
 
689
707
  def limit_exceeded(self):
690
- on_limit_pass = self.on_limit == 'pass'
708
+ on_limit_pass = self.on_limit == 'PASS'
691
709
  if self.on_limit_message:
692
710
  raise LimitExceeded(on_limit_pass, self.on_limit_message)
693
711
  else:
@@ -26,7 +26,8 @@ from robot.parsing import (SuiteFile, SuiteDirectory, SuiteStructure,
26
26
  SuiteStructureBuilder, SuiteStructureVisitor)
27
27
  from robot.utils import Importer, seq2str, split_args_from_name_or_path, type_name
28
28
 
29
- from ..model import ResourceFile, TestSuite
29
+ from ..model import TestSuite
30
+ from ..resourcemodel import ResourceFile
30
31
  from .parsers import (CustomParser, JsonParser, NoInitFileDirectoryParser, Parser,
31
32
  RestParser, RobotParser)
32
33
  from .settings import TestDefaults
@@ -22,9 +22,10 @@ from robot.errors import DataError
22
22
  from robot.parsing import File, get_init_model, get_model, get_resource_model
23
23
  from robot.utils import FileReader, get_error_message, read_rest_data, type_name
24
24
 
25
+ from ..model import TestSuite
26
+ from ..resourcemodel import ResourceFile
25
27
  from .settings import FileSettings, InitFileSettings, TestDefaults
26
28
  from .transformers import ResourceBuilder, SuiteBuilder
27
- from ..model import ResourceFile, TestSuite
28
29
 
29
30
 
30
31
  class Parser(ABC):
@@ -53,23 +54,21 @@ class RobotParser(Parser):
53
54
  def parse_suite_file(self, source: Path, defaults: TestDefaults) -> TestSuite:
54
55
  model = get_model(self._get_source(source), data_only=True,
55
56
  curdir=self._get_curdir(source), lang=self.lang)
56
- suite = TestSuite(name=TestSuite.name_from_source(source, self.extensions),
57
- source=source)
58
- SuiteBuilder(suite, FileSettings(defaults)).build(model)
59
- return suite
57
+ model.source = source
58
+ return self.parse_model(model, defaults)
60
59
 
61
60
  def parse_init_file(self, source: Path, defaults: TestDefaults) -> TestSuite:
62
61
  model = get_init_model(self._get_source(source), data_only=True,
63
62
  curdir=self._get_curdir(source), lang=self.lang)
64
- directory = source.parent
65
- suite = TestSuite(name=TestSuite.name_from_source(directory),
66
- source=directory, rpa=None)
63
+ model.source = source
64
+ suite = TestSuite(name=TestSuite.name_from_source(source.parent),
65
+ source=source.parent, rpa=None)
67
66
  SuiteBuilder(suite, InitFileSettings(defaults)).build(model)
68
67
  return suite
69
68
 
70
69
  def parse_model(self, model: File, defaults: 'TestDefaults|None' = None) -> TestSuite:
71
- source = model.source
72
- suite = TestSuite(name=TestSuite.name_from_source(source), source=source)
70
+ name = TestSuite.name_from_source(model.source, self.extensions)
71
+ suite = TestSuite(name=name, source=model.source)
73
72
  SuiteBuilder(suite, FileSettings(defaults)).build(model)
74
73
  return suite
75
74
 
@@ -82,8 +81,8 @@ class RobotParser(Parser):
82
81
  def parse_resource_file(self, source: Path) -> ResourceFile:
83
82
  model = get_resource_model(self._get_source(source), data_only=True,
84
83
  curdir=self._get_curdir(source), lang=self.lang)
84
+ model.source = source
85
85
  resource = self.parse_resource_model(model)
86
- resource.source = source
87
86
  return resource
88
87
 
89
88
  def parse_resource_model(self, model: File) -> ResourceFile:
@@ -13,31 +13,23 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
 
16
- import sys
17
16
  from collections.abc import Sequence
17
+ from typing import TypedDict
18
18
 
19
19
  from ..model import TestCase
20
20
 
21
21
 
22
- if sys.version_info >= (3, 8):
23
- from typing import TypedDict
22
+ class OptionalItems(TypedDict, total=False):
23
+ args: 'Sequence[str]'
24
+ lineno: int
24
25
 
25
26
 
26
- class OptionalItems(TypedDict, total=False):
27
- args: 'Sequence[str]'
28
- lineno: int
27
+ class FixtureDict(OptionalItems):
28
+ """Dictionary containing setup or teardown info.
29
29
 
30
-
31
- class FixtureDict(OptionalItems):
32
- """Dictionary containing setup or teardown info.
33
-
34
- :attr:`args` and :attr:`lineno` are optional.
35
- """
36
- name: str
37
-
38
- else:
39
- class FixtureDict(dict):
40
- pass
30
+ :attr:`args` and :attr:`lineno` are optional.
31
+ """
32
+ name: str
41
33
 
42
34
 
43
35
  class TestDefaults: