robotframework 6.1rc1__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.1rc1 → robotframework-7.0}/INSTALL.rst +25 -25
  2. {robotframework-6.1rc1 → robotframework-7.0}/PKG-INFO +6 -8
  3. {robotframework-6.1rc1 → robotframework-7.0}/README.rst +3 -2
  4. {robotframework-6.1rc1 → robotframework-7.0}/setup.py +3 -6
  5. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/api/__init__.py +4 -1
  6. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/api/deco.py +60 -14
  7. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/api/exceptions.py +6 -6
  8. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/api/interfaces.py +403 -68
  9. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/api/logger.py +27 -20
  10. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/api/parsing.py +4 -2
  11. robotframework-7.0/src/robot/api/py.typed +0 -0
  12. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/conf/gatherfailed.py +2 -2
  13. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/conf/languages.py +61 -25
  14. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/conf/settings.py +21 -14
  15. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/common/storage.js +11 -6
  16. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/htmlfilewriter.py +1 -1
  17. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/libdoc/libdoc.css +10 -2
  18. {robotframework-6.1rc1 → 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.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/doc_formatting.css +13 -7
  21. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/log.css +51 -10
  22. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/log.html +14 -23
  23. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/model.js +2 -4
  24. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/report.css +83 -19
  25. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/report.html +22 -7
  26. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/testdata.js +10 -3
  27. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/view.js +84 -0
  28. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/template.py +3 -3
  29. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/builder.py +0 -8
  30. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/datatypes.py +9 -10
  31. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/htmlutils.py +4 -7
  32. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/jsonbuilder.py +38 -20
  33. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/model.py +21 -28
  34. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/robotbuilder.py +50 -31
  35. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/standardtypes.py +9 -1
  36. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/xmlbuilder.py +35 -20
  37. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/xmlwriter.py +18 -38
  38. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/BuiltIn.py +255 -205
  39. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/Collections.py +384 -240
  40. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/DateTime.py +73 -60
  41. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/OperatingSystem.py +6 -5
  42. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/Process.py +26 -27
  43. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/Remote.py +40 -36
  44. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/String.py +66 -76
  45. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/XML.py +66 -59
  46. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/__init__.py +2 -2
  47. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/dialogs_py.py +14 -2
  48. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/__init__.py +5 -5
  49. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/body.py +44 -13
  50. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/configurer.py +19 -15
  51. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/control.py +230 -88
  52. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/filter.py +31 -25
  53. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/itemlist.py +9 -8
  54. robotframework-7.0/src/robot/model/keyword.py +77 -0
  55. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/message.py +19 -10
  56. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/modelobject.py +27 -15
  57. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/modifier.py +1 -1
  58. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/namepatterns.py +3 -25
  59. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/stats.py +9 -15
  60. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/tags.py +1 -1
  61. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/testcase.py +15 -27
  62. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/testsuite.py +44 -28
  63. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/visitor.py +35 -8
  64. robotframework-7.0/src/robot/output/console/dotted.py +90 -0
  65. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/output/console/quiet.py +3 -2
  66. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/output/console/verbose.py +61 -61
  67. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/output/debugfile.py +39 -24
  68. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/output/filelogger.py +18 -15
  69. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/output/librarylogger.py +3 -2
  70. robotframework-7.0/src/robot/output/listeners.py +753 -0
  71. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/output/logger.py +216 -80
  72. robotframework-7.0/src/robot/output/loggerapi.py +215 -0
  73. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/output/loggerhelper.py +23 -56
  74. robotframework-7.0/src/robot/output/output.py +185 -0
  75. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/output/stdoutlogsplitter.py +8 -5
  76. robotframework-7.0/src/robot/output/xmllogger.py +459 -0
  77. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/lexer/blocklexers.py +17 -13
  78. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/lexer/context.py +12 -2
  79. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/lexer/lexer.py +1 -1
  80. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/lexer/settings.py +6 -3
  81. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/lexer/statementlexers.py +39 -10
  82. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/lexer/tokens.py +27 -29
  83. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/model/blocks.py +19 -6
  84. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/model/statements.py +193 -94
  85. robotframework-7.0/src/robot/parsing/model/visitor.py +100 -0
  86. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/rebot.py +2 -0
  87. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/reporting/expandkeywordmatcher.py +1 -1
  88. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/reporting/jsbuildingcontext.py +8 -6
  89. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/reporting/jsmodelbuilders.py +88 -61
  90. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/reporting/logreportwriters.py +16 -10
  91. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/reporting/outputwriter.py +18 -2
  92. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/reporting/resultwriter.py +4 -4
  93. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/reporting/stringcache.py +3 -3
  94. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/reporting/xunitwriter.py +15 -21
  95. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/result/__init__.py +3 -2
  96. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/result/configurer.py +12 -9
  97. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/result/executionresult.py +56 -8
  98. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/result/flattenkeywordmatcher.py +48 -9
  99. robotframework-7.0/src/robot/result/keywordremover.py +207 -0
  100. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/result/merger.py +1 -1
  101. robotframework-7.0/src/robot/result/model.py +1185 -0
  102. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/result/modeldeprecation.py +9 -3
  103. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/result/resultbuilder.py +46 -36
  104. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/result/xmlelementhandlers.py +83 -43
  105. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/run.py +3 -1
  106. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/__init__.py +14 -4
  107. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/arguments/__init__.py +2 -1
  108. robotframework-7.0/src/robot/running/arguments/argumentconverter.py +100 -0
  109. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/arguments/argumentmapper.py +26 -24
  110. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/arguments/argumentparser.py +85 -61
  111. robotframework-7.0/src/robot/running/arguments/argumentresolver.py +158 -0
  112. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/arguments/argumentspec.py +83 -116
  113. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/arguments/argumentvalidator.py +33 -27
  114. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/arguments/customconverters.py +15 -12
  115. robotframework-7.0/src/robot/running/arguments/embedded.py +145 -0
  116. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/arguments/typeconverters.py +268 -220
  117. robotframework-7.0/src/robot/running/arguments/typeinfo.py +317 -0
  118. robotframework-7.0/src/robot/running/arguments/typeinfoparser.py +219 -0
  119. robotframework-7.0/src/robot/running/arguments/typevalidator.py +60 -0
  120. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/bodyrunner.py +147 -129
  121. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/builder/builders.py +17 -26
  122. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/builder/parsers.py +17 -11
  123. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/builder/settings.py +9 -17
  124. robotframework-7.0/src/robot/running/builder/transformers.py +535 -0
  125. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/context.py +113 -31
  126. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/dynamicmethods.py +62 -34
  127. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/importer.py +27 -49
  128. robotframework-7.0/src/robot/running/invalidkeyword.py +67 -0
  129. robotframework-7.0/src/robot/running/keywordfinder.py +91 -0
  130. robotframework-7.0/src/robot/running/keywordimplementation.py +164 -0
  131. robotframework-7.0/src/robot/running/librarykeyword.py +392 -0
  132. robotframework-7.0/src/robot/running/librarykeywordrunner.py +250 -0
  133. robotframework-7.0/src/robot/running/libraryscopes.py +115 -0
  134. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/model.py +198 -337
  135. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/namespace.py +124 -137
  136. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/outputcapture.py +20 -12
  137. robotframework-7.0/src/robot/running/resourcemodel.py +448 -0
  138. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/statusreporter.py +16 -13
  139. robotframework-7.0/src/robot/running/suiterunner.py +265 -0
  140. robotframework-7.0/src/robot/running/testlibraries.py +500 -0
  141. robotframework-7.0/src/robot/running/userkeywordrunner.py +260 -0
  142. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/testdoc.py +18 -13
  143. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/__init__.py +53 -35
  144. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/connectioncache.py +64 -59
  145. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/dotdict.py +3 -0
  146. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/encodingsniffer.py +9 -4
  147. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/escaping.py +19 -19
  148. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/importer.py +2 -2
  149. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/markupwriters.py +23 -15
  150. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/misc.py +1 -2
  151. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/normalizing.py +9 -24
  152. robotframework-7.0/src/robot/utils/notset.py +33 -0
  153. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/platform.py +15 -5
  154. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/robotio.py +9 -9
  155. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/robotpath.py +1 -0
  156. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/robottime.py +122 -90
  157. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/robottypes.py +21 -31
  158. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/setter.py +0 -5
  159. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/text.py +7 -4
  160. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/unic.py +2 -2
  161. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/variables/__init__.py +2 -2
  162. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/variables/assigner.py +17 -19
  163. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/variables/evaluation.py +20 -17
  164. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/variables/filesetter.py +80 -80
  165. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/variables/replacer.py +33 -36
  166. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/variables/scopes.py +17 -12
  167. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/variables/search.py +66 -41
  168. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/variables/store.py +14 -16
  169. robotframework-7.0/src/robot/variables/tablesetter.py +164 -0
  170. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/variables/variables.py +1 -1
  171. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/version.py +1 -1
  172. {robotframework-6.1rc1 → robotframework-7.0}/src/robotframework.egg-info/PKG-INFO +6 -8
  173. {robotframework-6.1rc1 → robotframework-7.0}/src/robotframework.egg-info/SOURCES.txt +10 -8
  174. {robotframework-6.1rc1 → robotframework-7.0}/tasks.py +6 -6
  175. robotframework-6.1rc1/src/robot/htmldata/rebot/common.css +0 -239
  176. robotframework-6.1rc1/src/robot/libraries/Reserved.py +0 -48
  177. robotframework-6.1rc1/src/robot/model/keyword.py +0 -173
  178. robotframework-6.1rc1/src/robot/output/console/dotted.py +0 -90
  179. robotframework-6.1rc1/src/robot/output/listenerarguments.py +0 -165
  180. robotframework-6.1rc1/src/robot/output/listenermethods.py +0 -113
  181. robotframework-6.1rc1/src/robot/output/listeners.py +0 -174
  182. robotframework-6.1rc1/src/robot/output/output.py +0 -95
  183. robotframework-6.1rc1/src/robot/output/xmllogger.py +0 -354
  184. robotframework-6.1rc1/src/robot/parsing/model/visitor.py +0 -67
  185. robotframework-6.1rc1/src/robot/result/keywordremover.py +0 -183
  186. robotframework-6.1rc1/src/robot/result/model.py +0 -957
  187. robotframework-6.1rc1/src/robot/running/arguments/argumentconverter.py +0 -79
  188. robotframework-6.1rc1/src/robot/running/arguments/argumentresolver.py +0 -131
  189. robotframework-6.1rc1/src/robot/running/arguments/embedded.py +0 -146
  190. robotframework-6.1rc1/src/robot/running/arguments/typevalidator.py +0 -56
  191. robotframework-6.1rc1/src/robot/running/builder/transformers.py +0 -642
  192. robotframework-6.1rc1/src/robot/running/handlers.py +0 -321
  193. robotframework-6.1rc1/src/robot/running/handlerstore.py +0 -66
  194. robotframework-6.1rc1/src/robot/running/librarykeywordrunner.py +0 -238
  195. robotframework-6.1rc1/src/robot/running/libraryscopes.py +0 -97
  196. robotframework-6.1rc1/src/robot/running/modelcombiner.py +0 -32
  197. robotframework-6.1rc1/src/robot/running/suiterunner.py +0 -249
  198. robotframework-6.1rc1/src/robot/running/testlibraries.py +0 -420
  199. robotframework-6.1rc1/src/robot/running/usererrorhandler.py +0 -75
  200. robotframework-6.1rc1/src/robot/running/userkeyword.py +0 -111
  201. robotframework-6.1rc1/src/robot/running/userkeywordrunner.py +0 -274
  202. robotframework-6.1rc1/src/robot/variables/tablesetter.py +0 -156
  203. {robotframework-6.1rc1 → robotframework-7.0}/AUTHORS.rst +0 -0
  204. {robotframework-6.1rc1 → robotframework-7.0}/BUILD.rst +0 -0
  205. {robotframework-6.1rc1 → robotframework-7.0}/CONTRIBUTING.rst +0 -0
  206. {robotframework-6.1rc1 → robotframework-7.0}/COPYRIGHT.txt +0 -0
  207. {robotframework-6.1rc1 → robotframework-7.0}/LICENSE.txt +0 -0
  208. {robotframework-6.1rc1 → robotframework-7.0}/MANIFEST.in +0 -0
  209. {robotframework-6.1rc1 → robotframework-7.0}/setup.cfg +0 -0
  210. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/__init__.py +0 -0
  211. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/__main__.py +0 -0
  212. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/conf/__init__.py +0 -0
  213. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/errors.py +0 -0
  214. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/__init__.py +0 -0
  215. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/common/__init__.py +0 -0
  216. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/common/js_disabled.css +0 -0
  217. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/jsonwriter.py +0 -0
  218. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/lib/__init__.py +0 -0
  219. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/lib/jquery.highlight.min.js +0 -0
  220. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/lib/jquery.min.js +0 -0
  221. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/lib/jquery.tablesorter.min.js +0 -0
  222. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/lib/jquery.tmpl.min.js +0 -0
  223. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/lib/jsxcompressor.min.js +0 -0
  224. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/libdoc/__init__.py +0 -0
  225. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/libdoc/doc_formatting.css +0 -0
  226. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/libdoc/print.css +0 -0
  227. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/libdoc/pygments.css +0 -0
  228. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/__init__.py +0 -0
  229. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/fileloading.js +0 -0
  230. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/log.js +0 -0
  231. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/print.css +0 -0
  232. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/util.js +0 -0
  233. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/testdoc/__init__.py +0 -0
  234. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/testdoc/testdoc.css +0 -0
  235. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/testdoc/testdoc.html +0 -0
  236. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdoc.py +0 -0
  237. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/__init__.py +0 -0
  238. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/consoleviewer.py +0 -0
  239. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/htmlwriter.py +0 -0
  240. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/jsonwriter.py +0 -0
  241. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/output.py +0 -0
  242. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/writer.py +0 -0
  243. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/Dialogs.py +0 -0
  244. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/Easter.py +0 -0
  245. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/Screenshot.py +0 -0
  246. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/Telnet.py +0 -0
  247. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/fixture.py +0 -0
  248. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/metadata.py +0 -0
  249. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/statistics.py +0 -0
  250. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/suitestatistics.py +0 -0
  251. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/tagsetter.py +0 -0
  252. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/tagstatistics.py +0 -0
  253. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/totalstatistics.py +0 -0
  254. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/output/__init__.py +0 -0
  255. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/output/console/__init__.py +0 -0
  256. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/output/console/highlighting.py +0 -0
  257. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/output/pyloggingconf.py +0 -0
  258. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/__init__.py +0 -0
  259. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/lexer/__init__.py +0 -0
  260. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/lexer/tokenizer.py +0 -0
  261. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/model/__init__.py +0 -0
  262. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/parser/__init__.py +0 -0
  263. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/parser/blockparsers.py +0 -0
  264. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/parser/fileparser.py +0 -0
  265. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/parser/parser.py +0 -0
  266. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/suitestructure.py +0 -0
  267. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/pythonpathsetter.py +0 -0
  268. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/reporting/__init__.py +0 -0
  269. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/reporting/jsexecutionresult.py +0 -0
  270. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/reporting/jswriter.py +0 -0
  271. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/result/executionerrors.py +0 -0
  272. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/result/messagefilter.py +0 -0
  273. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/result/suiteteardownfailed.py +0 -0
  274. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/result/visitor.py +0 -0
  275. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/builder/__init__.py +0 -0
  276. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/randomizer.py +0 -0
  277. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/runkwregister.py +0 -0
  278. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/signalhandler.py +0 -0
  279. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/status.py +0 -0
  280. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/timeouts/__init__.py +0 -0
  281. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/timeouts/posix.py +0 -0
  282. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/timeouts/windows.py +0 -0
  283. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/application.py +0 -0
  284. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/argumentparser.py +0 -0
  285. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/asserts.py +0 -0
  286. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/charwidth.py +0 -0
  287. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/compress.py +0 -0
  288. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/encoding.py +0 -0
  289. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/error.py +0 -0
  290. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/etreewrapper.py +0 -0
  291. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/filereader.py +0 -0
  292. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/frange.py +0 -0
  293. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/htmlformatters.py +0 -0
  294. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/markuputils.py +0 -0
  295. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/match.py +0 -0
  296. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/recommendations.py +0 -0
  297. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/restreader.py +0 -0
  298. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/robotenv.py +0 -0
  299. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/robotinspect.py +0 -0
  300. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/sortable.py +0 -0
  301. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/typehints.py +0 -0
  302. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/variables/finders.py +0 -0
  303. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/variables/notfound.py +0 -0
  304. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/variables/resolvable.py +0 -0
  305. {robotframework-6.1rc1 → robotframework-7.0}/src/robotframework.egg-info/dependency_links.txt +0 -0
  306. {robotframework-6.1rc1 → robotframework-7.0}/src/robotframework.egg-info/entry_points.txt +0 -0
  307. {robotframework-6.1rc1 → robotframework-7.0}/src/robotframework.egg-info/top_level.txt +0 -0
@@ -13,28 +13,34 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
 
16
+ import warnings
17
+
16
18
  from robot.model import Tags
17
19
 
18
20
 
19
21
  def deprecated(method):
20
22
  def wrapper(self, *args, **kws):
21
23
  """Deprecated."""
24
+ warnings.warn(f"'robot.result.{type(self).__name__}.{method.__name__}' is "
25
+ f"deprecated and will be removed in Robot Framework 8.0.",
26
+ stacklevel=1)
22
27
  return method(self, *args, **kws)
23
28
  return wrapper
24
29
 
25
30
 
26
31
  class DeprecatedAttributesMixin:
27
32
  __slots__ = []
33
+ _log_name = ''
28
34
 
29
35
  @property
30
36
  @deprecated
31
37
  def name(self):
32
- return ''
38
+ return self._log_name
33
39
 
34
40
  @property
35
41
  @deprecated
36
42
  def kwname(self):
37
- return self.name
43
+ return self._log_name
38
44
 
39
45
  @property
40
46
  @deprecated
@@ -63,5 +69,5 @@ class DeprecatedAttributesMixin:
63
69
 
64
70
  @property
65
71
  @deprecated
66
- def message(self):
72
+ def doc(self):
67
73
  return ''
@@ -13,35 +13,43 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
 
16
+ from pathlib import Path
17
+
16
18
  from robot.errors import DataError
17
19
  from robot.model import SuiteVisitor
18
20
  from robot.utils import ET, ETSource, get_error_message
19
21
 
20
- from .executionresult import Result, CombinedResult
21
- from .flattenkeywordmatcher import (FlattenByNameMatcher, FlattenByTypeMatcher,
22
- FlattenByTagMatcher)
22
+ from .executionresult import CombinedResult, is_json_source, Result
23
+ from .flattenkeywordmatcher import (create_flatten_message, FlattenByNameMatcher,
24
+ FlattenByTypeMatcher, FlattenByTags)
23
25
  from .merger import Merger
26
+ from .model import TestSuite
24
27
  from .xmlelementhandlers import XmlElementHandler
25
28
 
26
29
 
27
30
  def ExecutionResult(*sources, **options):
28
31
  """Factory method to constructs :class:`~.executionresult.Result` objects.
29
32
 
30
- :param sources: XML source(s) containing execution results.
31
- Can be specified as paths, opened file objects, or strings/bytes
32
- containing XML directly. Support for bytes is new in RF 3.2.
33
+ :param sources: XML or JSON source(s) containing execution results.
34
+ Can be specified as paths (``pathlib.Path`` or ``str``), opened file
35
+ objects, or strings/bytes containing XML/JSON directly.
33
36
  :param options: Configuration options.
34
37
  Using ``merge=True`` causes multiple results to be combined so that
35
38
  tests in the latter results replace the ones in the original.
36
39
  Setting ``rpa`` either to ``True`` (RPA mode) or ``False`` (test
37
- automation) sets execution mode explicitly. By default it is got
40
+ automation) sets execution mode explicitly. By default, it is got
38
41
  from processed output files and conflicting modes cause an error.
39
42
  Other options are passed directly to the
40
43
  :class:`ExecutionResultBuilder` object used internally.
41
44
  :returns: :class:`~.executionresult.Result` instance.
42
45
 
43
- Should be imported by external code via the :mod:`robot.api` package.
44
- See the :mod:`robot.result` package for a usage example.
46
+ A source is considered to be JSON in these cases:
47
+ - It is a path with a ``.json`` suffix.
48
+ - It is an open file that has a ``name`` attribute with a ``.json`` suffix.
49
+ - It is string or bytes starting with ``{`` and ending with ``}``.
50
+
51
+ This method should be imported by external code via the :mod:`robot.api`
52
+ package. See the :mod:`robot.result` package for a usage example.
45
53
  """
46
54
  if not sources:
47
55
  raise DataError('One or more data source needed.')
@@ -66,13 +74,27 @@ def _combine_results(sources, options):
66
74
 
67
75
 
68
76
  def _single_result(source, options):
77
+ if is_json_source(source):
78
+ return _json_result(source, options)
79
+ return _xml_result(source, options)
80
+
81
+
82
+ def _json_result(source, options):
83
+ try:
84
+ suite = TestSuite.from_json(source)
85
+ except Exception:
86
+ raise DataError(f"Reading JSON source '{source}' failed: {get_error_message()}")
87
+ return Result(source, suite, rpa=options.pop('rpa', None))
88
+
89
+
90
+ def _xml_result(source, options):
69
91
  ets = ETSource(source)
70
92
  result = Result(source, rpa=options.pop('rpa', None))
71
93
  try:
72
94
  return ExecutionResultBuilder(ets, **options).build(result)
73
95
  except IOError as err:
74
96
  error = err.strerror
75
- except:
97
+ except Exception:
76
98
  error = get_error_message()
77
99
  raise DataError(f"Reading XML source '{ets}' failed: {error}")
78
100
 
@@ -106,6 +128,10 @@ class ExecutionResultBuilder:
106
128
  with self._source as source:
107
129
  self._parse(source, handler.start, handler.end)
108
130
  result.handle_suite_teardown_failures()
131
+ if self._flattened_keywords:
132
+ # Tags are nowadays written after keyword content, so we cannot
133
+ # flatten based on them when parsing output.xml.
134
+ result.suite.visit(FlattenByTags(self._flattened_keywords))
109
135
  if not self._include_keywords:
110
136
  result.suite.visit(RemoveKeywords())
111
137
  return result
@@ -143,49 +169,33 @@ class ExecutionResultBuilder:
143
169
  # Performance optimized. Do not change without profiling!
144
170
  name_match, by_name = self._get_matcher(FlattenByNameMatcher, flattened)
145
171
  type_match, by_type = self._get_matcher(FlattenByTypeMatcher, flattened)
146
- tags_match, by_tags = self._get_matcher(FlattenByTagMatcher, flattened)
147
- started = -1 # if 0 or more, we are flattening
172
+ started = -1 # if 0 or more, we are flattening
148
173
  tags = []
149
174
  containers = {'kw', 'for', 'while', 'iter', 'if', 'try'}
150
- inside_kw = 0 # to make sure we don't read tags from a test
151
- seen_doc = False
175
+ inside = 0 # to make sure we don't read tags from a test
152
176
  for event, elem in context:
153
177
  tag = elem.tag
154
- start = event == 'start'
155
- end = not start
156
- if start:
178
+ if event == 'start':
157
179
  if tag in containers:
158
- inside_kw += 1
180
+ inside += 1
159
181
  if started >= 0:
160
182
  started += 1
161
- elif by_name and name_match(elem.get('name', ''), elem.get('library')):
183
+ elif by_name and name_match(elem.get('name', ''), elem.get('owner')
184
+ or elem.get('library')):
162
185
  started = 0
163
- seen_doc = False
164
186
  elif by_type and type_match(tag):
165
187
  started = 0
166
- seen_doc = False
167
188
  tags = []
168
189
  else:
169
190
  if tag in containers:
170
- inside_kw -= 1
171
- if started == 0 and not seen_doc:
172
- doc = ET.Element('doc')
173
- doc.text = '_*Content flattened.*_'
174
- yield 'start', doc
175
- yield 'end', doc
176
- elif by_tags and inside_kw and started < 0 and tag == 'tag':
177
- tags.append(elem.text or '')
178
- if tags_match(tags):
179
- started = 0
180
- seen_doc = False
181
- elif started == 0 and tag == 'doc':
182
- seen_doc = True
183
- elem.text = f"{elem.text or ''}\n\n_*Content flattened.*_".strip()
191
+ inside -= 1
192
+ elif started == 0 and tag == 'status':
193
+ elem.text = create_flatten_message(elem.text)
184
194
  if started <= 0 or tag == 'msg':
185
195
  yield event, elem
186
196
  else:
187
197
  elem.clear()
188
- if started >= 0 and end and tag in containers:
198
+ if started >= 0 and event == 'end' and tag in containers:
189
199
  started -= 1
190
200
 
191
201
  def _get_matcher(self, matcher_class, flattened):
@@ -13,6 +13,8 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
 
16
+ from datetime import datetime
17
+
16
18
  from robot.errors import DataError
17
19
 
18
20
 
@@ -47,8 +49,6 @@ class ElementHandler:
47
49
 
48
50
  def get_child_handler(self, tag):
49
51
  if tag not in self.children:
50
- if not self.tag:
51
- raise DataError(f"Incompatible root element '{tag}'.")
52
52
  raise DataError(f"Incompatible child element '{tag}' for '{self.tag}'.")
53
53
  return self.element_handlers[tag]
54
54
 
@@ -58,13 +58,23 @@ class ElementHandler:
58
58
  def end(self, elem, result):
59
59
  pass
60
60
 
61
- def _timestamp(self, elem, attr_name):
62
- timestamp = elem.get(attr_name)
63
- return timestamp if timestamp != 'N/A' else None
61
+ def _legacy_timestamp(self, elem, attr_name):
62
+ ts = elem.get(attr_name)
63
+ if ts == 'N/A' or not ts:
64
+ return None
65
+ ts = ts.ljust(24, '0')
66
+ return datetime(int(ts[:4]), int(ts[4:6]), int(ts[6:8]),
67
+ int(ts[9:11]), int(ts[12:14]), int(ts[15:17]), int(ts[18:24]))
64
68
 
65
69
 
66
70
  class RootHandler(ElementHandler):
67
- children = frozenset(('robot',))
71
+ children = frozenset(('robot', 'suite'))
72
+
73
+ def get_child_handler(self, tag):
74
+ try:
75
+ return super().get_child_handler(tag)
76
+ except DataError:
77
+ raise DataError(f"Incompatible root element '{tag}'.")
68
78
 
69
79
 
70
80
  @ElementHandler.register
@@ -106,7 +116,8 @@ class TestHandler(ElementHandler):
106
116
  tag = 'test'
107
117
  # 'tags' is for RF < 4 compatibility.
108
118
  children = frozenset(('doc', 'tags', 'tag', 'timeout', 'status', 'kw', 'if', 'for',
109
- 'try', 'while', 'return', 'break', 'continue', 'error', 'msg'))
119
+ 'try', 'while', 'variable', 'return', 'break', 'continue',
120
+ 'error', 'msg'))
110
121
 
111
122
  def start(self, elem, result):
112
123
  lineno = elem.get('line')
@@ -121,7 +132,7 @@ class KeywordHandler(ElementHandler):
121
132
  # 'arguments', 'assign' and 'tags' are for RF < 4 compatibility.
122
133
  children = frozenset(('doc', 'arguments', 'arg', 'assign', 'var', 'tags', 'tag',
123
134
  'timeout', 'status', 'msg', 'kw', 'if', 'for', 'try',
124
- 'while', 'return', 'break', 'continue', 'error'))
135
+ 'while', 'variable', 'return', 'break', 'continue', 'error'))
125
136
 
126
137
  def start(self, elem, result):
127
138
  elem_type = elem.get('type')
@@ -136,9 +147,15 @@ class KeywordHandler(ElementHandler):
136
147
  body = result.body
137
148
  except AttributeError:
138
149
  body = self._get_body_for_suite_level_keyword(result)
139
- return body.create_keyword(kwname=elem.get('name', ''),
140
- libname=elem.get('library'),
141
- sourcename=elem.get('sourcename'))
150
+ return body.create_keyword(**self._get_keyword_attrs(elem))
151
+
152
+ def _get_keyword_attrs(self, elem):
153
+ # 'library' and 'sourcename' are RF < 7 compatibility.
154
+ return {
155
+ 'name': elem.get('name', ''),
156
+ 'owner': elem.get('owner') or elem.get('library'),
157
+ 'source_name': elem.get('source_name') or elem.get('sourcename')
158
+ }
142
159
 
143
160
  def _get_body_for_suite_level_keyword(self, result):
144
161
  # Someone, most likely a listener, has created a `<kw>` element on suite level.
@@ -149,24 +166,22 @@ class KeywordHandler(ElementHandler):
149
166
  kw_type = 'teardown' if result.tests or result.suites else 'setup'
150
167
  keyword = getattr(result, kw_type)
151
168
  if not keyword:
152
- keyword.config(kwname=f'Implicit {kw_type}', status=keyword.PASS)
169
+ keyword.config(name=f'Implicit {kw_type}', status=keyword.PASS)
153
170
  return keyword.body
154
171
 
155
172
  def _create_setup(self, elem, result):
156
- return result.setup.config(kwname=elem.get('name', ''),
157
- libname=elem.get('library'))
173
+ return result.setup.config(**self._get_keyword_attrs(elem))
158
174
 
159
175
  def _create_teardown(self, elem, result):
160
- return result.teardown.config(kwname=elem.get('name', ''),
161
- libname=elem.get('library'))
176
+ return result.teardown.config(**self._get_keyword_attrs(elem))
162
177
 
163
178
  # RF < 4 compatibility.
164
179
 
165
180
  def _create_for(self, elem, result):
166
- return result.body.create_keyword(kwname=elem.get('name'), type='FOR')
181
+ return result.body.create_keyword(name=elem.get('name'), type='FOR')
167
182
 
168
183
  def _create_foritem(self, elem, result):
169
- return result.body.create_keyword(kwname=elem.get('name'), type='ITERATION')
184
+ return result.body.create_keyword(name=elem.get('name'), type='ITERATION')
170
185
 
171
186
  _create_iteration = _create_foritem
172
187
 
@@ -201,7 +216,7 @@ class WhileHandler(ElementHandler):
201
216
  class IterationHandler(ElementHandler):
202
217
  tag = 'iter'
203
218
  children = frozenset(('var', 'doc', 'status', 'kw', 'if', 'for', 'msg', 'try',
204
- 'while', 'return', 'break', 'continue', 'error'))
219
+ 'while', 'variable', 'return', 'break', 'continue', 'error'))
205
220
 
206
221
  def start(self, elem, result):
207
222
  return result.body.create_iteration()
@@ -220,9 +235,11 @@ class IfHandler(ElementHandler):
220
235
  class BranchHandler(ElementHandler):
221
236
  tag = 'branch'
222
237
  children = frozenset(('status', 'kw', 'if', 'for', 'try', 'while', 'msg', 'doc',
223
- 'return', 'pattern', 'break', 'continue', 'error'))
238
+ 'variable', 'return', 'pattern', 'break', 'continue', 'error'))
224
239
 
225
240
  def start(self, elem, result):
241
+ if 'variable' in elem.attrib: # RF < 7.0 compatibility.
242
+ elem.attrib['assign'] = elem.attrib.pop('variable')
226
243
  return result.body.create_branch(**elem.attrib)
227
244
 
228
245
 
@@ -244,10 +261,21 @@ class PatternHandler(ElementHandler):
244
261
  result.patterns += (elem.text or '',)
245
262
 
246
263
 
264
+ @ElementHandler.register
265
+ class VariableHandler(ElementHandler):
266
+ tag = 'variable'
267
+ children = frozenset(('var', 'status', 'msg', 'kw'))
268
+
269
+ def start(self, elem, result):
270
+ return result.body.create_var(name=elem.get('name', ''),
271
+ scope=elem.get('scope'),
272
+ separator=elem.get('separator'))
273
+
274
+
247
275
  @ElementHandler.register
248
276
  class ReturnHandler(ElementHandler):
249
277
  tag = 'return'
250
- children = frozenset(('status', 'value', 'msg', 'kw'))
278
+ children = frozenset(('value', 'status', 'msg', 'kw'))
251
279
 
252
280
  def start(self, elem, result):
253
281
  return result.body.create_return()
@@ -285,11 +313,23 @@ class MessageHandler(ElementHandler):
285
313
  tag = 'msg'
286
314
 
287
315
  def end(self, elem, result):
288
- html_true = ('true', 'yes') # 'yes' is compatibility for RF < 4.
289
- result.body.create_message(elem.text or '',
290
- elem.get('level', 'INFO'),
291
- elem.get('html') in html_true,
292
- self._timestamp(elem, 'timestamp'))
316
+ self._create_message(elem, result.body.create_message)
317
+
318
+ def _create_message(self, elem, creator):
319
+ if 'time' in elem.attrib: # RF >= 7
320
+ timestamp = elem.attrib['time']
321
+ else: # RF < 7
322
+ timestamp = self._legacy_timestamp(elem, 'timestamp')
323
+ creator(elem.text or '',
324
+ elem.get('level', 'INFO'),
325
+ elem.get('html') in ('true', 'yes'), # 'yes' is RF < 4 compatibility
326
+ timestamp)
327
+
328
+
329
+ class ErrorMessageHandler(MessageHandler):
330
+
331
+ def end(self, elem, result):
332
+ self._create_message(elem, result.messages.create)
293
333
 
294
334
 
295
335
  @ElementHandler.register
@@ -302,8 +342,12 @@ class StatusHandler(ElementHandler):
302
342
  def end(self, elem, result):
303
343
  if self.set_status:
304
344
  result.status = elem.get('status', 'FAIL')
305
- result.starttime = self._timestamp(elem, 'starttime')
306
- result.endtime = self._timestamp(elem, 'endtime')
345
+ if 'start' in elem.attrib: # RF >= 7
346
+ result.start_time = elem.attrib['start']
347
+ result.elapsed_time = float(elem.attrib['elapsed'])
348
+ else: # RF < 7
349
+ result.start_time = self._legacy_timestamp(elem, 'starttime')
350
+ result.end_time = self._legacy_timestamp(elem, 'endtime')
307
351
  if elem.text:
308
352
  result.message = elem.text
309
353
 
@@ -313,7 +357,13 @@ class DocHandler(ElementHandler):
313
357
  tag = 'doc'
314
358
 
315
359
  def end(self, elem, result):
316
- result.doc = elem.text or ''
360
+ try:
361
+ result.doc = elem.text or ''
362
+ except AttributeError:
363
+ # With RF < 7 control structures can have `<doc>` containing information
364
+ # about flattening or removing date. Nowadays, they don't have `doc`
365
+ # attribute at all and `message` is used for this information.
366
+ result.message = elem.text or ''
317
367
 
318
368
 
319
369
  @ElementHandler.register
@@ -372,12 +422,12 @@ class VarHandler(ElementHandler):
372
422
 
373
423
  def end(self, elem, result):
374
424
  value = elem.text or ''
375
- if result.type == result.KEYWORD:
425
+ if result.type in (result.KEYWORD, result.FOR):
376
426
  result.assign += (value,)
377
- elif result.type == result.FOR:
378
- result.variables += (value,)
379
427
  elif result.type == result.ITERATION:
380
- result.variables[elem.get('name')] = value
428
+ result.assign[elem.get('name')] = value
429
+ elif result.type == result.VAR:
430
+ result.value += (value,)
381
431
  else:
382
432
  raise DataError(f"Invalid element '{elem}' for result '{result!r}'.")
383
433
 
@@ -415,16 +465,6 @@ class ErrorsHandler(ElementHandler):
415
465
  return ErrorMessageHandler()
416
466
 
417
467
 
418
- class ErrorMessageHandler(ElementHandler):
419
-
420
- def end(self, elem, result):
421
- html_true = ('true', 'yes') # 'yes' is compatibility for RF < 4.
422
- result.messages.create(elem.text or '',
423
- elem.get('level', 'INFO'),
424
- elem.get('html') in html_true,
425
- self._timestamp(elem, 'timestamp'))
426
-
427
-
428
468
  @ElementHandler.register
429
469
  class StatisticsHandler(ElementHandler):
430
470
  tag = 'statistics'
@@ -176,6 +176,8 @@ Options
176
176
  can also be further processed with Rebot tool. Can be
177
177
  disabled by giving a special value `NONE`.
178
178
  Default: output.xml
179
+ --legacyoutput Create XML output file in format compatible with
180
+ Robot Framework 6.x and earlier.
179
181
  -l --log file HTML log file. Can be disabled by giving a special
180
182
  value `NONE`. Default: log.html
181
183
  Examples: `--log mylog.html`, `-l NONE`
@@ -444,11 +446,11 @@ class RobotFramework(Application):
444
446
  lang=settings.languages,
445
447
  allow_empty_suite=settings.run_empty_suite)
446
448
  suite = builder.build(*datasources)
447
- settings.rpa = suite.rpa
448
449
  if settings.pre_run_modifiers:
449
450
  suite.visit(ModelModifier(settings.pre_run_modifiers,
450
451
  settings.run_empty_suite, LOGGER))
451
452
  suite.configure(**settings.suite_config)
453
+ settings.rpa = suite.validate_execution_mode()
452
454
  with pyloggingconf.robot_handler_enabled(settings.log_level):
453
455
  old_max_error_lines = text.MAX_ERROR_LINES
454
456
  old_max_assign_length = text.MAX_ASSIGN_LENGTH
@@ -32,6 +32,12 @@ The public API of this module consists of the following objects:
32
32
  :mod:`robot.running.model` module. These classes are typically only needed
33
33
  in type hints.
34
34
 
35
+ * Keyword implementation related classes :class:`~robot.running.resourcemodel.UserKeyword`,
36
+ :class:`~robot.running.librarykeyword.LibraryKeyword`,
37
+ :class:`~robot.running.invalidkeyword.InvalidKeyword` and their common base class
38
+ :class:`~robot.running.keywordimplementation.KeywordImplementation`. Also these
39
+ classes are mainly needed in type hints.
40
+
35
41
  * :class:`~robot.running.builder.settings.TestDefaults` that is part of the
36
42
  `external parsing API`__ and also typically needed only in type hints.
37
43
 
@@ -43,6 +49,7 @@ the :mod:`robot.api` package.
43
49
 
44
50
  .. note:: Prior to Robot Framework 6.1, only some classes in
45
51
  :mod:`robot.running.model` were exposed via :mod:`robot.running`.
52
+ Keyword implementation related classes are new in Robot Framework 7.0.
46
53
 
47
54
  Examples
48
55
  --------
@@ -110,9 +117,12 @@ the results is possible using the
110
117
  from .arguments import ArgInfo, ArgumentSpec, TypeConverter, TypeInfo
111
118
  from .builder import ResourceFileBuilder, TestDefaults, TestSuiteBuilder
112
119
  from .context import EXECUTION_CONTEXTS
113
- from .model import (Break, Continue, Error, For, If, IfBranch, Keyword, Return,
114
- TestCase, TestSuite, Try, TryBranch, While)
120
+ from .keywordimplementation import KeywordImplementation
121
+ from .invalidkeyword import InvalidKeyword
122
+ from .librarykeyword import LibraryKeyword
123
+ from .model import (Break, Continue, Error, For, ForIteration, If, IfBranch, Keyword,
124
+ Return, TestCase, TestSuite, Try, TryBranch, Var, While,
125
+ WhileIteration)
126
+ from .resourcemodel import ResourceFile, UserKeyword
115
127
  from .runkwregister import RUN_KW_REGISTER
116
128
  from .testlibraries import TestLibrary
117
- from .usererrorhandler import UserErrorHandler
118
- from .userkeyword import UserLibrary
@@ -16,7 +16,8 @@
16
16
  from .argumentmapper import DefaultValue
17
17
  from .argumentparser import (DynamicArgumentParser, PythonArgumentParser,
18
18
  UserKeywordArgumentParser)
19
- from .argumentspec import ArgInfo, ArgumentSpec, TypeInfo
19
+ from .argumentspec import ArgInfo, ArgumentSpec
20
20
  from .embedded import EmbeddedArguments
21
21
  from .customconverters import CustomArgumentConverters
22
22
  from .typeconverters import TypeConverter
23
+ from .typeinfo import TypeInfo
@@ -0,0 +1,100 @@
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 typing import TYPE_CHECKING
17
+
18
+ from robot.variables import contains_variable
19
+
20
+ from .typeinfo import TypeInfo
21
+
22
+ if TYPE_CHECKING:
23
+ from robot.conf import LanguagesLike
24
+
25
+ from .argumentspec import ArgumentSpec
26
+ from .customconverters import CustomArgumentConverters
27
+
28
+
29
+ class ArgumentConverter:
30
+
31
+ def __init__(self, arg_spec: 'ArgumentSpec',
32
+ custom_converters: 'CustomArgumentConverters',
33
+ dry_run: bool = False,
34
+ languages: 'LanguagesLike' = None):
35
+ self.spec = arg_spec
36
+ self.custom_converters = custom_converters
37
+ self.dry_run = dry_run
38
+ self.languages = languages
39
+
40
+ def convert(self, positional, named):
41
+ return self._convert_positional(positional), self._convert_named(named)
42
+
43
+ def _convert_positional(self, positional):
44
+ names = self.spec.positional
45
+ converted = [self._convert(name, value)
46
+ for name, value in zip(names, positional)]
47
+ if self.spec.var_positional:
48
+ converted.extend(self._convert(self.spec.var_positional, value)
49
+ for value in positional[len(names):])
50
+ return converted
51
+
52
+ def _convert_named(self, named):
53
+ names = set(self.spec.positional) | set(self.spec.named_only)
54
+ var_named = self.spec.var_named
55
+ return [(name, self._convert(name if name in names else var_named, value))
56
+ for name, value in named]
57
+
58
+ def _convert(self, name, value):
59
+ spec = self.spec
60
+ if (spec.types is None
61
+ or self.dry_run and contains_variable(value, identifiers='$@&%')):
62
+ return value
63
+ conversion_error = None
64
+ # Don't convert None if argument has None as a default value.
65
+ # Python < 3.11 adds None to type hints automatically when using None as
66
+ # a default value which preserves None automatically. This code keeps
67
+ # the same behavior also with newer Python versions. We can consider
68
+ # changing this once Python 3.11 is our minimum supported version.
69
+ if value is None and name in spec.defaults and spec.defaults[name] is None:
70
+ return value
71
+ # Primarily convert arguments based on type hints.
72
+ if name in spec.types:
73
+ info: TypeInfo = spec.types[name]
74
+ try:
75
+ return info.convert(value, name, self.custom_converters, self.languages)
76
+ except ValueError as err:
77
+ conversion_error = err
78
+ except TypeError:
79
+ pass
80
+ # Try conversion also based on the default value type. We probably should
81
+ # do this only if there is no explicit type hint, but Python < 3.11
82
+ # handling `arg: type = None` differently than newer versions would mean
83
+ # that conversion behavior depends on the Python version. Once Python 3.11
84
+ # is our minimum supported version, we can consider reopening
85
+ # https://github.com/robotframework/robotframework/issues/4881
86
+ if name in spec.defaults:
87
+ typ = type(spec.defaults[name])
88
+ if typ == str: # Don't convert arguments to strings.
89
+ info = TypeInfo()
90
+ elif typ == int: # Try also conversion to float.
91
+ info = TypeInfo.from_sequence([int, float])
92
+ else:
93
+ info = TypeInfo.from_type(typ)
94
+ try:
95
+ return info.convert(value, name, languages=self.languages)
96
+ except (ValueError, TypeError):
97
+ pass
98
+ if conversion_error:
99
+ raise conversion_error
100
+ return value