robotframework 7.1rc2__zip → 7.2b1__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 (286) hide show
  1. {robotframework-7.1rc2 → robotframework-7.2b1}/BUILD.rst +7 -7
  2. {robotframework-7.1rc2 → robotframework-7.2b1}/PKG-INFO +2 -2
  3. {robotframework-7.1rc2 → robotframework-7.2b1}/setup.py +1 -1
  4. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/api/__init__.py +33 -9
  5. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/api/deco.py +8 -6
  6. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/api/interfaces.py +66 -15
  7. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/api/parsing.py +72 -68
  8. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/conf/languages.py +4 -3
  9. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/conf/settings.py +11 -10
  10. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/errors.py +3 -3
  11. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/htmldata/htmlfilewriter.py +3 -0
  12. robotframework-7.2b1/src/robot/htmldata/libdoc/libdoc.html +408 -0
  13. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/htmldata/rebot/log.html +1 -1
  14. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/htmldata/rebot/report.html +1 -1
  15. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/htmldata/rebot/testdata.js +1 -1
  16. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/htmldata/template.py +0 -2
  17. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/libdoc.py +19 -11
  18. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/libdocpkg/htmlwriter.py +7 -4
  19. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/libdocpkg/model.py +7 -5
  20. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/libdocpkg/writer.py +2 -2
  21. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/libraries/BuiltIn.py +121 -32
  22. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/libraries/Collections.py +20 -7
  23. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/model/__init__.py +3 -3
  24. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/model/body.py +48 -57
  25. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/model/control.py +35 -4
  26. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/model/message.py +13 -8
  27. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/model/modelobject.py +26 -0
  28. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/model/statistics.py +13 -9
  29. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/model/stats.py +12 -14
  30. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/model/suitestatistics.py +8 -9
  31. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/model/tags.py +10 -0
  32. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/model/tagstatistics.py +7 -8
  33. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/model/testcase.py +1 -0
  34. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/model/testsuite.py +1 -0
  35. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/model/totalstatistics.py +14 -21
  36. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/model/visitor.py +29 -3
  37. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/output/__init__.py +3 -2
  38. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/output/console/dotted.py +6 -3
  39. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/output/console/highlighting.py +18 -10
  40. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/output/debugfile.py +3 -3
  41. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/output/filelogger.py +7 -3
  42. robotframework-7.2b1/src/robot/output/jsonlogger.py +338 -0
  43. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/output/librarylogger.py +12 -11
  44. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/output/listeners.py +49 -47
  45. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/output/logger.py +33 -20
  46. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/output/loggerapi.py +6 -0
  47. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/output/loggerhelper.py +29 -57
  48. robotframework-7.2b1/src/robot/output/loglevel.py +54 -0
  49. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/output/output.py +21 -17
  50. robotframework-7.2b1/src/robot/output/outputfile.py +174 -0
  51. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/output/pyloggingconf.py +2 -0
  52. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/output/xmllogger.py +40 -169
  53. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/parsing/lexer/blocklexers.py +25 -12
  54. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/parsing/lexer/statementlexers.py +16 -7
  55. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/parsing/lexer/tokens.py +2 -1
  56. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/parsing/model/__init__.py +1 -1
  57. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/parsing/model/blocks.py +34 -2
  58. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/parsing/model/statements.py +32 -2
  59. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/parsing/parser/blockparsers.py +7 -2
  60. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/rebot.py +10 -2
  61. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/reporting/jsmodelbuilders.py +1 -1
  62. robotframework-7.2b1/src/robot/reporting/outputwriter.py +30 -0
  63. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/result/__init__.py +1 -1
  64. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/result/executionerrors.py +9 -9
  65. robotframework-7.2b1/src/robot/result/executionresult.py +331 -0
  66. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/result/messagefilter.py +14 -10
  67. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/result/model.py +90 -18
  68. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/result/resultbuilder.py +2 -5
  69. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/result/xmlelementhandlers.py +20 -9
  70. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/run.py +18 -6
  71. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/running/__init__.py +1 -1
  72. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/running/arguments/embedded.py +7 -6
  73. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/running/arguments/typeconverters.py +14 -2
  74. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/running/arguments/typeinfo.py +23 -4
  75. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/running/bodyrunner.py +41 -0
  76. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/running/builder/settings.py +2 -1
  77. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/running/builder/transformers.py +46 -20
  78. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/running/context.py +22 -11
  79. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/running/librarykeyword.py +1 -1
  80. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/running/librarykeywordrunner.py +29 -23
  81. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/running/model.py +31 -4
  82. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/running/outputcapture.py +2 -1
  83. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/running/signalhandler.py +7 -3
  84. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/running/status.py +49 -38
  85. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/running/statusreporter.py +1 -1
  86. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/running/suiterunner.py +22 -15
  87. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/running/userkeywordrunner.py +4 -0
  88. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/utils/importer.py +39 -23
  89. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/utils/unic.py +7 -8
  90. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/variables/evaluation.py +21 -2
  91. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/variables/replacer.py +20 -24
  92. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/variables/scopes.py +19 -9
  93. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/variables/variables.py +4 -1
  94. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/version.py +1 -1
  95. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robotframework.egg-info/PKG-INFO +2 -2
  96. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robotframework.egg-info/SOURCES.txt +3 -4
  97. robotframework-7.1rc2/src/robot/htmldata/libdoc/doc_formatting.css +0 -74
  98. robotframework-7.1rc2/src/robot/htmldata/libdoc/libdoc.css +0 -747
  99. robotframework-7.1rc2/src/robot/htmldata/libdoc/libdoc.html +0 -702
  100. robotframework-7.1rc2/src/robot/htmldata/libdoc/print.css +0 -11
  101. robotframework-7.1rc2/src/robot/htmldata/libdoc/pygments.css +0 -162
  102. robotframework-7.1rc2/src/robot/reporting/outputwriter.py +0 -48
  103. robotframework-7.1rc2/src/robot/result/executionresult.py +0 -201
  104. {robotframework-7.1rc2 → robotframework-7.2b1}/AUTHORS.rst +0 -0
  105. {robotframework-7.1rc2 → robotframework-7.2b1}/CONTRIBUTING.rst +0 -0
  106. {robotframework-7.1rc2 → robotframework-7.2b1}/COPYRIGHT.txt +0 -0
  107. {robotframework-7.1rc2 → robotframework-7.2b1}/INSTALL.rst +0 -0
  108. {robotframework-7.1rc2 → robotframework-7.2b1}/LICENSE.txt +0 -0
  109. {robotframework-7.1rc2 → robotframework-7.2b1}/MANIFEST.in +0 -0
  110. {robotframework-7.1rc2 → robotframework-7.2b1}/README.rst +0 -0
  111. {robotframework-7.1rc2 → robotframework-7.2b1}/setup.cfg +0 -0
  112. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/__init__.py +0 -0
  113. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/__main__.py +0 -0
  114. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/api/exceptions.py +0 -0
  115. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/api/logger.py +0 -0
  116. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/api/py.typed +0 -0
  117. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/conf/__init__.py +0 -0
  118. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/conf/gatherfailed.py +0 -0
  119. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/htmldata/__init__.py +0 -0
  120. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/htmldata/common/__init__.py +0 -0
  121. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/htmldata/common/js_disabled.css +0 -0
  122. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/htmldata/common/storage.js +0 -0
  123. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/htmldata/jsonwriter.py +0 -0
  124. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/htmldata/lib/__init__.py +0 -0
  125. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/htmldata/lib/jquery.highlight.min.js +0 -0
  126. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/htmldata/lib/jquery.min.js +0 -0
  127. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/htmldata/lib/jquery.tablesorter.min.js +0 -0
  128. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/htmldata/lib/jquery.tmpl.min.js +0 -0
  129. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/htmldata/lib/jsxcompressor.min.js +0 -0
  130. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/htmldata/libdoc/__init__.py +0 -0
  131. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/htmldata/rebot/__init__.py +0 -0
  132. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/htmldata/rebot/common.css +0 -0
  133. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/htmldata/rebot/doc_formatting.css +0 -0
  134. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/htmldata/rebot/fileloading.js +0 -0
  135. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/htmldata/rebot/log.css +0 -0
  136. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/htmldata/rebot/log.js +0 -0
  137. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/htmldata/rebot/model.js +0 -0
  138. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/htmldata/rebot/print.css +0 -0
  139. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/htmldata/rebot/report.css +0 -0
  140. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/htmldata/rebot/util.js +0 -0
  141. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/htmldata/rebot/view.js +0 -0
  142. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/htmldata/testdoc/__init__.py +0 -0
  143. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/htmldata/testdoc/testdoc.css +0 -0
  144. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/htmldata/testdoc/testdoc.html +0 -0
  145. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/libdocpkg/__init__.py +0 -0
  146. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/libdocpkg/builder.py +0 -0
  147. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/libdocpkg/consoleviewer.py +0 -0
  148. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/libdocpkg/datatypes.py +0 -0
  149. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/libdocpkg/htmlutils.py +0 -0
  150. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/libdocpkg/jsonbuilder.py +0 -0
  151. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/libdocpkg/jsonwriter.py +0 -0
  152. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/libdocpkg/output.py +0 -0
  153. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/libdocpkg/robotbuilder.py +0 -0
  154. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/libdocpkg/standardtypes.py +0 -0
  155. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/libdocpkg/xmlbuilder.py +0 -0
  156. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/libdocpkg/xmlwriter.py +0 -0
  157. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/libraries/DateTime.py +0 -0
  158. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/libraries/Dialogs.py +0 -0
  159. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/libraries/Easter.py +0 -0
  160. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/libraries/OperatingSystem.py +0 -0
  161. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/libraries/Process.py +0 -0
  162. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/libraries/Remote.py +0 -0
  163. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/libraries/Screenshot.py +0 -0
  164. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/libraries/String.py +0 -0
  165. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/libraries/Telnet.py +0 -0
  166. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/libraries/XML.py +0 -0
  167. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/libraries/__init__.py +0 -0
  168. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/libraries/dialogs_py.py +0 -0
  169. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/model/configurer.py +0 -0
  170. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/model/filter.py +0 -0
  171. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/model/fixture.py +0 -0
  172. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/model/itemlist.py +0 -0
  173. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/model/keyword.py +0 -0
  174. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/model/metadata.py +0 -0
  175. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/model/modifier.py +0 -0
  176. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/model/namepatterns.py +0 -0
  177. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/model/tagsetter.py +0 -0
  178. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/output/console/__init__.py +0 -0
  179. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/output/console/quiet.py +0 -0
  180. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/output/console/verbose.py +0 -0
  181. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/output/stdoutlogsplitter.py +0 -0
  182. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/parsing/__init__.py +0 -0
  183. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/parsing/lexer/__init__.py +0 -0
  184. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/parsing/lexer/context.py +0 -0
  185. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/parsing/lexer/lexer.py +0 -0
  186. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/parsing/lexer/settings.py +0 -0
  187. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/parsing/lexer/tokenizer.py +0 -0
  188. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/parsing/model/visitor.py +0 -0
  189. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/parsing/parser/__init__.py +0 -0
  190. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/parsing/parser/fileparser.py +0 -0
  191. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/parsing/parser/parser.py +0 -0
  192. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/parsing/suitestructure.py +0 -0
  193. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/pythonpathsetter.py +0 -0
  194. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/reporting/__init__.py +0 -0
  195. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/reporting/expandkeywordmatcher.py +0 -0
  196. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/reporting/jsbuildingcontext.py +0 -0
  197. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/reporting/jsexecutionresult.py +0 -0
  198. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/reporting/jswriter.py +0 -0
  199. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/reporting/logreportwriters.py +0 -0
  200. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/reporting/resultwriter.py +0 -0
  201. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/reporting/stringcache.py +0 -0
  202. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/reporting/xunitwriter.py +0 -0
  203. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/result/configurer.py +0 -0
  204. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/result/flattenkeywordmatcher.py +0 -0
  205. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/result/keywordremover.py +0 -0
  206. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/result/merger.py +0 -0
  207. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/result/modeldeprecation.py +0 -0
  208. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/result/suiteteardownfailed.py +0 -0
  209. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/result/visitor.py +0 -0
  210. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/running/arguments/__init__.py +0 -0
  211. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/running/arguments/argumentconverter.py +0 -0
  212. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/running/arguments/argumentmapper.py +0 -0
  213. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/running/arguments/argumentparser.py +0 -0
  214. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/running/arguments/argumentresolver.py +0 -0
  215. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/running/arguments/argumentspec.py +0 -0
  216. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/running/arguments/argumentvalidator.py +0 -0
  217. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/running/arguments/customconverters.py +0 -0
  218. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/running/arguments/typeinfoparser.py +0 -0
  219. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/running/arguments/typevalidator.py +0 -0
  220. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/running/builder/__init__.py +0 -0
  221. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/running/builder/builders.py +0 -0
  222. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/running/builder/parsers.py +0 -0
  223. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/running/dynamicmethods.py +0 -0
  224. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/running/importer.py +0 -0
  225. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/running/invalidkeyword.py +0 -0
  226. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/running/keywordfinder.py +0 -0
  227. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/running/keywordimplementation.py +0 -0
  228. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/running/libraryscopes.py +0 -0
  229. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/running/namespace.py +0 -0
  230. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/running/randomizer.py +0 -0
  231. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/running/resourcemodel.py +0 -0
  232. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/running/runkwregister.py +0 -0
  233. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/running/testlibraries.py +0 -0
  234. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/running/timeouts/__init__.py +0 -0
  235. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/running/timeouts/nosupport.py +0 -0
  236. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/running/timeouts/posix.py +0 -0
  237. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/running/timeouts/windows.py +0 -0
  238. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/testdoc.py +0 -0
  239. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/utils/__init__.py +0 -0
  240. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/utils/application.py +0 -0
  241. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/utils/argumentparser.py +0 -0
  242. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/utils/asserts.py +0 -0
  243. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/utils/charwidth.py +0 -0
  244. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/utils/compress.py +0 -0
  245. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/utils/connectioncache.py +0 -0
  246. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/utils/dotdict.py +0 -0
  247. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/utils/encoding.py +0 -0
  248. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/utils/encodingsniffer.py +0 -0
  249. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/utils/error.py +0 -0
  250. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/utils/escaping.py +0 -0
  251. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/utils/etreewrapper.py +0 -0
  252. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/utils/filereader.py +0 -0
  253. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/utils/frange.py +0 -0
  254. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/utils/htmlformatters.py +0 -0
  255. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/utils/markuputils.py +0 -0
  256. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/utils/markupwriters.py +0 -0
  257. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/utils/match.py +0 -0
  258. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/utils/misc.py +0 -0
  259. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/utils/normalizing.py +0 -0
  260. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/utils/notset.py +0 -0
  261. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/utils/platform.py +0 -0
  262. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/utils/recommendations.py +0 -0
  263. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/utils/restreader.py +0 -0
  264. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/utils/robotenv.py +0 -0
  265. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/utils/robotinspect.py +0 -0
  266. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/utils/robotio.py +0 -0
  267. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/utils/robotpath.py +0 -0
  268. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/utils/robottime.py +0 -0
  269. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/utils/robottypes.py +0 -0
  270. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/utils/setter.py +0 -0
  271. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/utils/sortable.py +0 -0
  272. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/utils/text.py +0 -0
  273. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/utils/typehints.py +0 -0
  274. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/variables/__init__.py +0 -0
  275. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/variables/assigner.py +0 -0
  276. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/variables/filesetter.py +0 -0
  277. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/variables/finders.py +0 -0
  278. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/variables/notfound.py +0 -0
  279. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/variables/resolvable.py +0 -0
  280. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/variables/search.py +0 -0
  281. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/variables/store.py +0 -0
  282. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robot/variables/tablesetter.py +0 -0
  283. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robotframework.egg-info/dependency_links.txt +0 -0
  284. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robotframework.egg-info/entry_points.txt +0 -0
  285. {robotframework-7.1rc2 → robotframework-7.2b1}/src/robotframework.egg-info/top_level.txt +0 -0
  286. {robotframework-7.1rc2 → robotframework-7.2b1}/tasks.py +0 -0
@@ -55,20 +55,21 @@ from .suiteteardownfailed import SuiteTeardownFailed, SuiteTeardownFailureHandle
55
55
  IT = TypeVar('IT', bound='IfBranch|TryBranch')
56
56
  FW = TypeVar('FW', bound='ForIteration|WhileIteration')
57
57
  BodyItemParent = Union['TestSuite', 'TestCase', 'Keyword', 'For', 'ForIteration', 'If',
58
- 'IfBranch', 'Try', 'TryBranch', 'While', 'WhileIteration', None]
58
+ 'IfBranch', 'Try', 'TryBranch', 'While', 'WhileIteration',
59
+ 'Group', None]
59
60
 
60
61
 
61
- class Body(model.BaseBody['Keyword', 'For', 'While', 'If', 'Try', 'Var', 'Return',
62
+ class Body(model.BaseBody['Keyword', 'For', 'While', 'Group', 'If', 'Try', 'Var', 'Return',
62
63
  'Continue', 'Break', 'Message', 'Error']):
63
64
  __slots__ = ()
64
65
 
65
66
 
66
- class Branches(model.BaseBranches['Keyword', 'For', 'While', 'If', 'Try', 'Var', 'Return',
67
+ class Branches(model.BaseBranches['Keyword', 'For', 'While', 'Group', 'If', 'Try', 'Var', 'Return',
67
68
  'Continue', 'Break', 'Message', 'Error', IT]):
68
69
  __slots__ = ()
69
70
 
70
71
 
71
- class Iterations(model.BaseIterations['Keyword', 'For', 'While', 'If', 'Try', 'Var', 'Return',
72
+ class Iterations(model.BaseIterations['Keyword', 'For', 'While', 'Group', 'If', 'Try', 'Var', 'Return',
72
73
  'Continue', 'Break', 'Message', 'Error', FW]):
73
74
  __slots__ = ()
74
75
 
@@ -79,16 +80,10 @@ class Iterations(model.BaseIterations['Keyword', 'For', 'While', 'If', 'Try', 'V
79
80
  class Message(model.Message):
80
81
  __slots__ = ()
81
82
 
82
- def to_dict(self) -> DataDict:
83
- data: DataDict = {
84
- 'type': self.type,
85
- 'message': self.message,
86
- 'level': self.level,
87
- 'html': self.html,
88
- }
89
- if self.timestamp:
90
- data['timestamp'] = self.timestamp.isoformat()
91
- return data
83
+ def to_dict(self, include_type=True) -> DataDict:
84
+ if not include_type:
85
+ return super().to_dict()
86
+ return {'type': self.type, **super().to_dict()}
92
87
 
93
88
 
94
89
  class StatusMixin:
@@ -407,6 +402,33 @@ class While(model.While, StatusMixin, DeprecatedAttributesMixin):
407
402
  return {**super().to_dict(), **StatusMixin.to_dict(self)}
408
403
 
409
404
 
405
+ @Body.register
406
+ class Group(model.Group, StatusMixin, DeprecatedAttributesMixin):
407
+ body_class = Body
408
+ __slots__ = ['status', 'message', '_start_time', '_end_time', '_elapsed_time']
409
+
410
+ def __init__(self, name: str = '',
411
+ status: str = 'FAIL',
412
+ message: str = '',
413
+ start_time: 'datetime|str|None' = None,
414
+ end_time: 'datetime|str|None' = None,
415
+ elapsed_time: 'timedelta|int|float|None' = None,
416
+ parent: BodyItemParent = None):
417
+ super().__init__(name, parent)
418
+ self.status = status
419
+ self.message = message
420
+ self.start_time = start_time
421
+ self.end_time = end_time
422
+ self.elapsed_time = elapsed_time
423
+
424
+ @property
425
+ def _log_name(self):
426
+ return self.name
427
+
428
+ def to_dict(self) -> DataDict:
429
+ return {**super().to_dict(), **StatusMixin.to_dict(self)}
430
+
431
+
410
432
  class IfBranch(model.IfBranch, StatusMixin, DeprecatedAttributesMixin):
411
433
  body_class = Body
412
434
  __slots__ = ['status', 'message', '_start_time', '_end_time', '_elapsed_time']
@@ -740,10 +762,10 @@ class Keyword(model.Keyword, StatusMixin):
740
762
 
741
763
  @setter
742
764
  def body(self, body: 'Sequence[BodyItem|DataDict]') -> Body:
743
- """Possible keyword body as a :class:`~.Body` object.
765
+ """Keyword body as a :class:`~.Body` object.
744
766
 
745
767
  Body can consist of child keywords, messages, and control structures
746
- such as IF/ELSE. Library keywords typically have an empty body.
768
+ such as IF/ELSE.
747
769
  """
748
770
  return self.body_class(self, body)
749
771
 
@@ -936,7 +958,12 @@ class TestCase(model.TestCase[Keyword], StatusMixin):
936
958
  return self.body_class(self, body)
937
959
 
938
960
  def to_dict(self) -> DataDict:
939
- return {**super().to_dict(), **StatusMixin.to_dict(self)}
961
+ return {'id': self.id, **super().to_dict(), **StatusMixin.to_dict(self)}
962
+
963
+ @classmethod
964
+ def from_dict(cls, data: DataDict) -> 'TestCase':
965
+ data.pop('id', None)
966
+ return super().from_dict(data)
940
967
 
941
968
 
942
969
  class TestSuite(model.TestSuite[Keyword, TestCase], StatusMixin):
@@ -1089,7 +1116,52 @@ class TestSuite(model.TestSuite[Keyword, TestCase], StatusMixin):
1089
1116
  self.visit(SuiteTeardownFailed(message, skipped=True))
1090
1117
 
1091
1118
  def to_dict(self) -> DataDict:
1092
- return {**super().to_dict(), **StatusMixin.to_dict(self)}
1119
+ return {'id': self.id, **super().to_dict(), **StatusMixin.to_dict(self)}
1120
+
1121
+ @classmethod
1122
+ def from_dict(cls, data: DataDict) -> 'TestSuite':
1123
+ """Create suite based on result data in a dictionary.
1124
+
1125
+ ``data`` can either contain only the suite data got, for example, from
1126
+ the :meth:`to_dict` method, or it can contain full result data with
1127
+ execution errors and other such information in addition to the suite data.
1128
+ In the latter case only the suite data is used, though.
1129
+
1130
+ Support for full result data is new in Robot Framework 7.2.
1131
+ """
1132
+ if 'suite' in data:
1133
+ data = data['suite']
1134
+ # `body` on the suite level means that a listener has logged something or
1135
+ # executed a keyword in a `start/end_suite` method. Throwing such data
1136
+ # away isn't great, but it's better than data being invalid and properly
1137
+ # handling it would be complicated. We handle such XML outputs (see
1138
+ # `xmlelementhandlers`), but with JSON there can even be one `body` in
1139
+ # the beginning and other at the end, and even preserving them both
1140
+ # would be hard.
1141
+ data.pop('body', None)
1142
+ data.pop('id', None)
1143
+ return super().from_dict(data)
1144
+
1145
+ @classmethod
1146
+ def from_json(cls, source: 'str|bytes|TextIO|Path') -> 'TestSuite':
1147
+ """Create suite based on results in JSON.
1148
+
1149
+ The data is given as the ``source`` parameter. It can be:
1150
+
1151
+ - a string containing the data directly,
1152
+ - an open file object where to read the data from, or
1153
+ - a path (``pathlib.Path`` or string) to a UTF-8 encoded file to read.
1154
+
1155
+ Supports JSON produced by :meth:`to_json` that contains only the suite
1156
+ information, as well as full result JSON that contains also execution
1157
+ errors and other information. In the latter case errors and all other
1158
+ information is silently ignored, though. If that is a problem,
1159
+ :class:`~robot.result.resultbuilder.ExecutionResult` should be used
1160
+ instead.
1161
+
1162
+ Support for full result JSON is new in Robot Framework 7.2.
1163
+ """
1164
+ return super().from_json(source)
1093
1165
 
1094
1166
  @overload
1095
1167
  def to_xml(self, file: None = None) -> str:
@@ -21,7 +21,6 @@ from .executionresult import CombinedResult, is_json_source, Result
21
21
  from .flattenkeywordmatcher import (create_flatten_message, FlattenByNameMatcher,
22
22
  FlattenByTypeMatcher, FlattenByTags)
23
23
  from .merger import Merger
24
- from .model import TestSuite
25
24
  from .xmlelementhandlers import XmlElementHandler
26
25
 
27
26
 
@@ -79,13 +78,11 @@ def _single_result(source, options):
79
78
 
80
79
  def _json_result(source, options):
81
80
  try:
82
- suite = TestSuite.from_json(source)
81
+ return Result.from_json(source, rpa=options.get('rpa'))
83
82
  except IOError as err:
84
83
  error = err.strerror
85
84
  except Exception:
86
85
  error = get_error_message()
87
- else:
88
- return Result(source, suite, rpa=options.pop('rpa', None))
89
86
  raise DataError(f"Reading JSON source '{source}' failed: {error}")
90
87
 
91
88
 
@@ -102,7 +99,7 @@ def _xml_result(source, options):
102
99
 
103
100
 
104
101
  class ExecutionResultBuilder:
105
- """Builds :class:`~.executionresult.Result` objects based on output files.
102
+ """Builds :class:`~.executionresult.Result` objects based on XML output files.
106
103
 
107
104
  Instead of using this builder directly, it is recommended to use the
108
105
  :func:`ExecutionResult` factory method.
@@ -86,8 +86,7 @@ class RobotHandler(ElementHandler):
86
86
  children = frozenset(('suite', 'statistics', 'errors'))
87
87
 
88
88
  def start(self, elem, result):
89
- generator = elem.get('generator', 'unknown').split()[0].upper()
90
- result.generated_by_robot = generator == 'ROBOT'
89
+ result.generator = elem.get('generator', 'unknown')
91
90
  result.generation_time = self._parse_generation_time(elem.get('generated'))
92
91
  if result.rpa is None:
93
92
  result.rpa = elem.get('rpa', 'false') == 'true'
@@ -120,7 +119,7 @@ class SuiteHandler(ElementHandler):
120
119
  def get_child_handler(self, tag):
121
120
  if tag == 'status':
122
121
  return StatusHandler(set_status=False)
123
- return ElementHandler.get_child_handler(self, tag)
122
+ return super().get_child_handler(tag)
124
123
 
125
124
 
126
125
  @ElementHandler.register
@@ -128,7 +127,7 @@ class TestHandler(ElementHandler):
128
127
  tag = 'test'
129
128
  # 'tags' is for RF < 4 compatibility.
130
129
  children = frozenset(('doc', 'tags', 'tag', 'timeout', 'status', 'kw', 'if', 'for',
131
- 'try', 'while', 'variable', 'return', 'break', 'continue',
130
+ 'try', 'while', 'group', 'variable', 'return', 'break', 'continue',
132
131
  'error', 'msg'))
133
132
 
134
133
  def start(self, elem, result):
@@ -144,7 +143,8 @@ class KeywordHandler(ElementHandler):
144
143
  # 'arguments', 'assign' and 'tags' are for RF < 4 compatibility.
145
144
  children = frozenset(('doc', 'arguments', 'arg', 'assign', 'var', 'tags', 'tag',
146
145
  'timeout', 'status', 'msg', 'kw', 'if', 'for', 'try',
147
- 'while', 'variable', 'return', 'break', 'continue', 'error'))
146
+ 'while', 'group', 'variable', 'return', 'break', 'continue',
147
+ 'error'))
148
148
 
149
149
  def start(self, elem, result):
150
150
  elem_type = elem.get('type')
@@ -228,12 +228,22 @@ class WhileHandler(ElementHandler):
228
228
  class IterationHandler(ElementHandler):
229
229
  tag = 'iter'
230
230
  children = frozenset(('var', 'doc', 'status', 'kw', 'if', 'for', 'msg', 'try',
231
- 'while', 'variable', 'return', 'break', 'continue', 'error'))
231
+ 'while', 'group', 'variable', 'return', 'break', 'continue', 'error'))
232
232
 
233
233
  def start(self, elem, result):
234
234
  return result.body.create_iteration()
235
235
 
236
236
 
237
+ @ElementHandler.register
238
+ class GroupHandler(ElementHandler):
239
+ tag = 'group'
240
+ children = frozenset(('status', 'kw', 'if', 'for', 'try', 'while', 'group', 'msg',
241
+ 'variable', 'return', 'break', 'continue', 'error'))
242
+
243
+ def start(self, elem, result):
244
+ return result.body.create_group(name=elem.get('name', ''))
245
+
246
+
237
247
  @ElementHandler.register
238
248
  class IfHandler(ElementHandler):
239
249
  tag = 'if'
@@ -246,8 +256,9 @@ class IfHandler(ElementHandler):
246
256
  @ElementHandler.register
247
257
  class BranchHandler(ElementHandler):
248
258
  tag = 'branch'
249
- children = frozenset(('status', 'kw', 'if', 'for', 'try', 'while', 'msg', 'doc',
250
- 'variable', 'return', 'pattern', 'break', 'continue', 'error'))
259
+ children = frozenset(('status', 'kw', 'if', 'for', 'try', 'while', 'group', 'msg',
260
+ 'doc', 'variable', 'return', 'pattern', 'break', 'continue',
261
+ 'error'))
251
262
 
252
263
  def start(self, elem, result):
253
264
  if 'variable' in elem.attrib: # RF < 7.0 compatibility.
@@ -314,7 +325,7 @@ class BreakHandler(ElementHandler):
314
325
  @ElementHandler.register
315
326
  class ErrorHandler(ElementHandler):
316
327
  tag = 'error'
317
- children = frozenset(('status', 'msg', 'value'))
328
+ children = frozenset(('status', 'msg', 'value', 'kw'))
318
329
 
319
330
  def start(self, elem, result):
320
331
  return result.body.create_error()
@@ -31,13 +31,14 @@ that can be used programmatically. Other code is for internal usage.
31
31
  """
32
32
 
33
33
  import sys
34
+ from threading import current_thread
34
35
 
35
36
  if __name__ == '__main__' and 'robot' not in sys.modules:
36
37
  import pythonpathsetter
37
38
 
38
39
  from robot.conf import RobotSettings
39
40
  from robot.model import ModelModifier
40
- from robot.output import LOGGER, pyloggingconf
41
+ from robot.output import librarylogger, LOGGER, pyloggingconf
41
42
  from robot.reporting import ResultWriter
42
43
  from robot.running.builder import TestSuiteBuilder
43
44
  from robot.utils import Application, text
@@ -238,7 +239,6 @@ Options
238
239
  pattern. Documentation is shown in `Test Details` and
239
240
  also as a tooltip in `Statistics by Tag`. Pattern can
240
241
  use `*`, `?` and `[]` as wildcards like --test.
241
- Documentation can contain formatting like --doc.
242
242
  Examples: --tagdoc mytag:Example
243
243
  --tagdoc "owner-*:Original author"
244
244
  --tagstatlink pattern:link:title * Add external links into `Statistics by
@@ -403,6 +403,17 @@ ROBOT_SYSLOG_LEVEL Log level to use when writing to the syslog file.
403
403
  ROBOT_INTERNAL_TRACES When set to any non-empty value, Robot Framework's
404
404
  internal methods are included in error tracebacks.
405
405
 
406
+ Return Codes
407
+ ============
408
+
409
+ 0 All tests passed.
410
+ 1-249 Returned number of tests failed.
411
+ 250 250 or more failures.
412
+ 251 Help or version information printed.
413
+ 252 Invalid data or command line options.
414
+ 253 Execution stopped by user.
415
+ 255 Unexpected internal error.
416
+
406
417
  Examples
407
418
  ========
408
419
 
@@ -459,16 +470,17 @@ class RobotFramework(Application):
459
470
  old_max_assign_length = text.MAX_ASSIGN_LENGTH
460
471
  text.MAX_ERROR_LINES = settings.max_error_lines
461
472
  text.MAX_ASSIGN_LENGTH = settings.max_assign_length
473
+ librarylogger.LOGGING_THREADS[0] = current_thread().name
462
474
  try:
463
475
  result = suite.run(settings)
464
476
  finally:
465
477
  text.MAX_ERROR_LINES = old_max_error_lines
466
478
  text.MAX_ASSIGN_LENGTH = old_max_assign_length
467
- LOGGER.info("Tests execution ended. Statistics:\n%s"
468
- % result.suite.stat_message)
479
+ librarylogger.LOGGING_THREADS[0] = 'MainThread'
480
+ LOGGER.info(f"Tests execution ended. "
481
+ f"Statistics:\n{result.suite.stat_message}")
469
482
  if settings.log or settings.report or settings.xunit:
470
- writer = ResultWriter(settings.output if settings.log
471
- else result)
483
+ writer = ResultWriter(settings.output if settings.log else result)
472
484
  writer.write_results(settings.get_rebot_settings())
473
485
  return result.return_code
474
486
 
@@ -120,7 +120,7 @@ from .context import EXECUTION_CONTEXTS
120
120
  from .keywordimplementation import KeywordImplementation
121
121
  from .invalidkeyword import InvalidKeyword
122
122
  from .librarykeyword import LibraryKeyword
123
- from .model import (Break, Continue, Error, For, ForIteration, If, IfBranch, Keyword,
123
+ from .model import (Break, Continue, Error, For, ForIteration, Group, If, IfBranch, Keyword,
124
124
  Return, TestCase, TestSuite, Try, TryBranch, Var, While,
125
125
  WhileIteration)
126
126
  from .resourcemodel import Import, ResourceFile, UserKeyword, Variable
@@ -68,7 +68,7 @@ class EmbeddedArguments:
68
68
 
69
69
 
70
70
  class EmbeddedArgumentParser:
71
- _regexp_extension = re.compile(r'(?<!\\)\(\?.+\)')
71
+ _inline_flag = re.compile(r'\(\?[aiLmsux]+(-[imsx]+)?\)')
72
72
  _regexp_group_start = re.compile(r'(?<!\\)\((.*?)\)')
73
73
  _escaped_curly = re.compile(r'(\\+)([{}])')
74
74
  _regexp_group_escape = r'(?:\1)'
@@ -104,7 +104,7 @@ class EmbeddedArgumentParser:
104
104
  return name, pattern, custom
105
105
 
106
106
  def _format_custom_regexp(self, pattern: str) -> str:
107
- for formatter in (self._regexp_extensions_are_not_allowed,
107
+ for formatter in (self._remove_inline_flags,
108
108
  self._make_groups_non_capturing,
109
109
  self._unescape_curly_braces,
110
110
  self._escape_escapes,
@@ -112,10 +112,11 @@ class EmbeddedArgumentParser:
112
112
  pattern = formatter(pattern)
113
113
  return pattern
114
114
 
115
- def _regexp_extensions_are_not_allowed(self, pattern: str) -> str:
116
- if self._regexp_extension.search(pattern):
117
- raise DataError('Regexp extensions are not allowed in embedded arguments.')
118
- return pattern
115
+ def _remove_inline_flags(self, pattern: str) -> str:
116
+ # Inline flags are included in custom regexp stored separately, but they
117
+ # must be removed from the full pattern.
118
+ match = self._inline_flag.match(pattern)
119
+ return pattern if match is None else pattern[match.end():]
119
120
 
120
121
  def _make_groups_non_capturing(self, pattern: str) -> str:
121
122
  return self._regexp_group_start.sub(self._regexp_group_escape, pattern)
@@ -51,7 +51,18 @@ class TypeConverter:
51
51
  languages: 'Languages|None' = None):
52
52
  self.type_info = type_info
53
53
  self.custom_converters = custom_converters
54
- self.languages = languages or Languages()
54
+ self.languages = languages
55
+
56
+ @property
57
+ def languages(self) -> Languages:
58
+ # Initialize only when needed to save time especially with Libdoc.
59
+ if self._languages is None:
60
+ self._languages = Languages()
61
+ return self._languages
62
+
63
+ @languages.setter
64
+ def languages(self, languages: 'Languages|None'):
65
+ self._languages = languages
55
66
 
56
67
  @classmethod
57
68
  def register(cls, converter: 'type[TypeConverter]') -> 'type[TypeConverter]':
@@ -749,7 +760,8 @@ class LiteralConverter(TypeConverter):
749
760
  return type_info.type is Literal
750
761
 
751
762
  def no_conversion_needed(self, value: Any) -> bool:
752
- return False
763
+ return any(value == expected and type(value) is type(expected)
764
+ for expected, _ in self.converters)
753
765
 
754
766
  def _handles_value(self, value):
755
767
  return True
@@ -175,8 +175,7 @@ class TypeInfo(metaclass=SetterAwareType):
175
175
  - a sequence of supported type hints to create a union from such as
176
176
  ``[int, float]`` or ``('int', 'list[int]')``
177
177
 
178
- In special cases, for example with dictionaries or sequences, using the
179
- more specialized methods like :meth:`from_dict` or :meth:`from_sequence`
178
+ In special cases using a more specialized method like :meth:`from_sequence`
180
179
  may be more appropriate than using this generic method.
181
180
  """
182
181
  if hint is NOT_SET:
@@ -283,6 +282,26 @@ class TypeInfo(metaclass=SetterAwareType):
283
282
  ``ValueError`` is conversion fails.
284
283
  :return: Converted value.
285
284
  """
285
+ converter = self.get_converter(custom_converters, languages)
286
+ return converter.convert(value, name, kind)
287
+
288
+ def get_converter(self,
289
+ custom_converters: 'CustomArgumentConverters|dict|None' = None,
290
+ languages: 'LanguagesLike' = None) -> TypeConverter:
291
+ """Get argument converter for this ``TypeInfo``.
292
+
293
+ :param custom_converters: Custom argument converters.
294
+ :param languages: Language configuration. During execution, uses the
295
+ current language configuration by default.
296
+ :raises: ``TypeError`` if there is no converter for this type.
297
+ :return: ``TypeConverter``.
298
+
299
+ The :meth:`convert` method handles the common conversion case, but this
300
+ method can be used if the converter is needed multiple times or its
301
+ needed also for other purposes than conversion.
302
+
303
+ New in Robot Framework 7.2.
304
+ """
286
305
  if isinstance(custom_converters, dict):
287
306
  custom_converters = CustomArgumentConverters.from_dict(custom_converters)
288
307
  if not languages and EXECUTION_CONTEXTS.current:
@@ -291,8 +310,8 @@ class TypeInfo(metaclass=SetterAwareType):
291
310
  languages = Languages(languages)
292
311
  converter = TypeConverter.converter_for(self, custom_converters, languages)
293
312
  if not converter:
294
- raise TypeError(f"No converter found for '{self}'.")
295
- return converter.convert(value, name, kind)
313
+ raise TypeError(f"Cannot convert type '{self}'.")
314
+ return converter
296
315
 
297
316
  def __str__(self):
298
317
  if self.is_union:
@@ -56,9 +56,18 @@ class BodyRunner:
56
56
  self._run = exception.can_continue(self._context, self._templated)
57
57
  if passed:
58
58
  raise passed
59
+ if errors and self._templated:
60
+ errors = self._handle_skip_with_templates(errors, result)
59
61
  if errors:
60
62
  raise ExecutionFailures(errors)
61
63
 
64
+ def _handle_skip_with_templates(self, errors, result):
65
+ if len(result.body) == 1 or not any(e.skip for e in errors):
66
+ return errors
67
+ if all(item.skipped for item in result.body):
68
+ raise ExecutionFailed('All iterations skipped.', skip=True)
69
+ return [e for e in errors if not e.skip]
70
+
62
71
 
63
72
  class KeywordRunner:
64
73
 
@@ -133,6 +142,8 @@ class ForInRunner:
133
142
  if not failed.can_continue(self._context, self._templated):
134
143
  break
135
144
  if errors:
145
+ if self._templated and len(errors) > 1 and all(e.skip for e in errors):
146
+ raise ExecutionFailed('All iterations skipped.', skip=True)
136
147
  raise ExecutionFailures(errors)
137
148
  return executed
138
149
 
@@ -452,6 +463,36 @@ class WhileRunner:
452
463
  raise DataError(f'Invalid WHILE loop condition: {msg}')
453
464
 
454
465
 
466
+ class GroupRunner:
467
+
468
+ def __init__(self, context, run=True, templated=False):
469
+ self._context = context
470
+ self._run = run
471
+ self._templated = templated
472
+
473
+ def run(self, data, result):
474
+ if self._run:
475
+ error = self._initialize(data, result)
476
+ run = error is None
477
+ else:
478
+ error = None
479
+ run = False
480
+ with StatusReporter(data, result, self._context, run=run):
481
+ runner = BodyRunner(self._context, run, self._templated)
482
+ runner.run(data, result)
483
+ if error:
484
+ raise error
485
+
486
+ def _initialize(self, data, result):
487
+ if data.error:
488
+ return DataError(data.error, syntax=True)
489
+ try:
490
+ result.name = self._context.variables.replace_string(result.name)
491
+ except DataError as err:
492
+ return err
493
+ return None
494
+
495
+
455
496
  class IfRunner:
456
497
  _dry_run_stack = []
457
498
 
@@ -50,7 +50,8 @@ class TestDefaults:
50
50
  def __init__(self, parent: 'TestDefaults|None' = None,
51
51
  setup: 'FixtureDict|None' = None,
52
52
  teardown: 'FixtureDict|None' = None,
53
- tags: 'Sequence[str]' = (), timeout: 'str|None' = None):
53
+ tags: 'Sequence[str]' = (),
54
+ timeout: 'str|None' = None):
54
55
  self.parent = parent
55
56
  self.setup = setup
56
57
  self.teardown = teardown