robotframework 7.1.1__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.1.1 → robotframework-7.2b1}/BUILD.rst +2 -2
  2. {robotframework-7.1.1 → robotframework-7.2b1}/PKG-INFO +2 -2
  3. {robotframework-7.1.1 → robotframework-7.2b1}/setup.py +1 -1
  4. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/api/__init__.py +33 -9
  5. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/api/deco.py +8 -6
  6. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/api/interfaces.py +21 -4
  7. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/api/parsing.py +72 -68
  8. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/conf/languages.py +4 -3
  9. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/conf/settings.py +11 -10
  10. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/errors.py +3 -1
  11. {robotframework-7.1.1 → 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.1.1 → robotframework-7.2b1}/src/robot/htmldata/rebot/log.html +1 -1
  14. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/htmldata/rebot/report.html +1 -1
  15. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/htmldata/rebot/testdata.js +1 -1
  16. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/libdoc.py +19 -11
  17. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/libdocpkg/htmlwriter.py +7 -4
  18. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/libdocpkg/model.py +7 -5
  19. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/libdocpkg/writer.py +2 -2
  20. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/libraries/BuiltIn.py +109 -32
  21. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/libraries/Collections.py +18 -4
  22. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/model/__init__.py +3 -3
  23. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/model/body.py +48 -57
  24. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/model/control.py +35 -4
  25. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/model/message.py +13 -8
  26. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/model/modelobject.py +26 -0
  27. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/model/statistics.py +13 -9
  28. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/model/stats.py +12 -14
  29. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/model/suitestatistics.py +8 -9
  30. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/model/tags.py +10 -0
  31. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/model/tagstatistics.py +7 -8
  32. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/model/testcase.py +1 -0
  33. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/model/testsuite.py +1 -0
  34. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/model/totalstatistics.py +14 -21
  35. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/model/visitor.py +29 -3
  36. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/output/__init__.py +3 -2
  37. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/output/console/dotted.py +6 -3
  38. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/output/debugfile.py +3 -3
  39. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/output/filelogger.py +7 -3
  40. robotframework-7.2b1/src/robot/output/jsonlogger.py +338 -0
  41. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/output/librarylogger.py +12 -11
  42. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/output/listeners.py +49 -47
  43. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/output/logger.py +33 -20
  44. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/output/loggerapi.py +6 -0
  45. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/output/loggerhelper.py +26 -55
  46. robotframework-7.2b1/src/robot/output/loglevel.py +54 -0
  47. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/output/output.py +21 -17
  48. robotframework-7.2b1/src/robot/output/outputfile.py +174 -0
  49. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/output/pyloggingconf.py +2 -0
  50. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/output/xmllogger.py +40 -169
  51. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/parsing/lexer/blocklexers.py +25 -12
  52. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/parsing/lexer/statementlexers.py +16 -7
  53. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/parsing/lexer/tokens.py +2 -1
  54. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/parsing/model/__init__.py +1 -1
  55. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/parsing/model/blocks.py +34 -2
  56. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/parsing/model/statements.py +32 -2
  57. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/parsing/parser/blockparsers.py +7 -2
  58. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/rebot.py +10 -2
  59. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/reporting/jsmodelbuilders.py +1 -1
  60. robotframework-7.2b1/src/robot/reporting/outputwriter.py +30 -0
  61. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/result/__init__.py +1 -1
  62. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/result/executionerrors.py +9 -9
  63. robotframework-7.2b1/src/robot/result/executionresult.py +331 -0
  64. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/result/messagefilter.py +14 -10
  65. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/result/model.py +90 -18
  66. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/result/resultbuilder.py +2 -5
  67. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/result/xmlelementhandlers.py +20 -9
  68. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/run.py +18 -6
  69. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/__init__.py +1 -1
  70. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/arguments/embedded.py +7 -6
  71. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/arguments/typeconverters.py +14 -2
  72. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/arguments/typeinfo.py +22 -2
  73. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/bodyrunner.py +41 -0
  74. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/builder/settings.py +2 -1
  75. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/builder/transformers.py +46 -20
  76. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/context.py +22 -11
  77. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/librarykeyword.py +1 -1
  78. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/librarykeywordrunner.py +29 -23
  79. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/model.py +31 -4
  80. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/status.py +42 -35
  81. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/statusreporter.py +1 -1
  82. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/suiterunner.py +22 -15
  83. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/importer.py +39 -23
  84. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/unic.py +7 -8
  85. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/variables/evaluation.py +21 -2
  86. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/variables/replacer.py +20 -24
  87. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/variables/scopes.py +17 -8
  88. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/variables/variables.py +4 -1
  89. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/version.py +1 -1
  90. {robotframework-7.1.1 → robotframework-7.2b1}/src/robotframework.egg-info/PKG-INFO +2 -2
  91. {robotframework-7.1.1 → robotframework-7.2b1}/src/robotframework.egg-info/SOURCES.txt +3 -4
  92. robotframework-7.1.1/src/robot/htmldata/libdoc/doc_formatting.css +0 -74
  93. robotframework-7.1.1/src/robot/htmldata/libdoc/libdoc.css +0 -747
  94. robotframework-7.1.1/src/robot/htmldata/libdoc/libdoc.html +0 -702
  95. robotframework-7.1.1/src/robot/htmldata/libdoc/print.css +0 -11
  96. robotframework-7.1.1/src/robot/htmldata/libdoc/pygments.css +0 -162
  97. robotframework-7.1.1/src/robot/reporting/outputwriter.py +0 -48
  98. robotframework-7.1.1/src/robot/result/executionresult.py +0 -201
  99. {robotframework-7.1.1 → robotframework-7.2b1}/AUTHORS.rst +0 -0
  100. {robotframework-7.1.1 → robotframework-7.2b1}/CONTRIBUTING.rst +0 -0
  101. {robotframework-7.1.1 → robotframework-7.2b1}/COPYRIGHT.txt +0 -0
  102. {robotframework-7.1.1 → robotframework-7.2b1}/INSTALL.rst +0 -0
  103. {robotframework-7.1.1 → robotframework-7.2b1}/LICENSE.txt +0 -0
  104. {robotframework-7.1.1 → robotframework-7.2b1}/MANIFEST.in +0 -0
  105. {robotframework-7.1.1 → robotframework-7.2b1}/README.rst +0 -0
  106. {robotframework-7.1.1 → robotframework-7.2b1}/setup.cfg +0 -0
  107. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/__init__.py +0 -0
  108. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/__main__.py +0 -0
  109. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/api/exceptions.py +0 -0
  110. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/api/logger.py +0 -0
  111. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/api/py.typed +0 -0
  112. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/conf/__init__.py +0 -0
  113. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/conf/gatherfailed.py +0 -0
  114. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/htmldata/__init__.py +0 -0
  115. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/htmldata/common/__init__.py +0 -0
  116. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/htmldata/common/js_disabled.css +0 -0
  117. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/htmldata/common/storage.js +0 -0
  118. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/htmldata/jsonwriter.py +0 -0
  119. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/htmldata/lib/__init__.py +0 -0
  120. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/htmldata/lib/jquery.highlight.min.js +0 -0
  121. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/htmldata/lib/jquery.min.js +0 -0
  122. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/htmldata/lib/jquery.tablesorter.min.js +0 -0
  123. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/htmldata/lib/jquery.tmpl.min.js +0 -0
  124. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/htmldata/lib/jsxcompressor.min.js +0 -0
  125. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/htmldata/libdoc/__init__.py +0 -0
  126. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/htmldata/rebot/__init__.py +0 -0
  127. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/htmldata/rebot/common.css +0 -0
  128. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/htmldata/rebot/doc_formatting.css +0 -0
  129. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/htmldata/rebot/fileloading.js +0 -0
  130. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/htmldata/rebot/log.css +0 -0
  131. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/htmldata/rebot/log.js +0 -0
  132. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/htmldata/rebot/model.js +0 -0
  133. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/htmldata/rebot/print.css +0 -0
  134. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/htmldata/rebot/report.css +0 -0
  135. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/htmldata/rebot/util.js +0 -0
  136. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/htmldata/rebot/view.js +0 -0
  137. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/htmldata/template.py +0 -0
  138. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/htmldata/testdoc/__init__.py +0 -0
  139. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/htmldata/testdoc/testdoc.css +0 -0
  140. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/htmldata/testdoc/testdoc.html +0 -0
  141. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/libdocpkg/__init__.py +0 -0
  142. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/libdocpkg/builder.py +0 -0
  143. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/libdocpkg/consoleviewer.py +0 -0
  144. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/libdocpkg/datatypes.py +0 -0
  145. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/libdocpkg/htmlutils.py +0 -0
  146. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/libdocpkg/jsonbuilder.py +0 -0
  147. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/libdocpkg/jsonwriter.py +0 -0
  148. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/libdocpkg/output.py +0 -0
  149. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/libdocpkg/robotbuilder.py +0 -0
  150. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/libdocpkg/standardtypes.py +0 -0
  151. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/libdocpkg/xmlbuilder.py +0 -0
  152. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/libdocpkg/xmlwriter.py +0 -0
  153. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/libraries/DateTime.py +0 -0
  154. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/libraries/Dialogs.py +0 -0
  155. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/libraries/Easter.py +0 -0
  156. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/libraries/OperatingSystem.py +0 -0
  157. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/libraries/Process.py +0 -0
  158. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/libraries/Remote.py +0 -0
  159. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/libraries/Screenshot.py +0 -0
  160. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/libraries/String.py +0 -0
  161. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/libraries/Telnet.py +0 -0
  162. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/libraries/XML.py +0 -0
  163. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/libraries/__init__.py +0 -0
  164. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/libraries/dialogs_py.py +0 -0
  165. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/model/configurer.py +0 -0
  166. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/model/filter.py +0 -0
  167. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/model/fixture.py +0 -0
  168. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/model/itemlist.py +0 -0
  169. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/model/keyword.py +0 -0
  170. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/model/metadata.py +0 -0
  171. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/model/modifier.py +0 -0
  172. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/model/namepatterns.py +0 -0
  173. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/model/tagsetter.py +0 -0
  174. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/output/console/__init__.py +0 -0
  175. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/output/console/highlighting.py +0 -0
  176. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/output/console/quiet.py +0 -0
  177. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/output/console/verbose.py +0 -0
  178. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/output/stdoutlogsplitter.py +0 -0
  179. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/parsing/__init__.py +0 -0
  180. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/parsing/lexer/__init__.py +0 -0
  181. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/parsing/lexer/context.py +0 -0
  182. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/parsing/lexer/lexer.py +0 -0
  183. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/parsing/lexer/settings.py +0 -0
  184. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/parsing/lexer/tokenizer.py +0 -0
  185. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/parsing/model/visitor.py +0 -0
  186. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/parsing/parser/__init__.py +0 -0
  187. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/parsing/parser/fileparser.py +0 -0
  188. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/parsing/parser/parser.py +0 -0
  189. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/parsing/suitestructure.py +0 -0
  190. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/pythonpathsetter.py +0 -0
  191. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/reporting/__init__.py +0 -0
  192. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/reporting/expandkeywordmatcher.py +0 -0
  193. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/reporting/jsbuildingcontext.py +0 -0
  194. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/reporting/jsexecutionresult.py +0 -0
  195. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/reporting/jswriter.py +0 -0
  196. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/reporting/logreportwriters.py +0 -0
  197. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/reporting/resultwriter.py +0 -0
  198. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/reporting/stringcache.py +0 -0
  199. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/reporting/xunitwriter.py +0 -0
  200. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/result/configurer.py +0 -0
  201. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/result/flattenkeywordmatcher.py +0 -0
  202. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/result/keywordremover.py +0 -0
  203. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/result/merger.py +0 -0
  204. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/result/modeldeprecation.py +0 -0
  205. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/result/suiteteardownfailed.py +0 -0
  206. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/result/visitor.py +0 -0
  207. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/arguments/__init__.py +0 -0
  208. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/arguments/argumentconverter.py +0 -0
  209. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/arguments/argumentmapper.py +0 -0
  210. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/arguments/argumentparser.py +0 -0
  211. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/arguments/argumentresolver.py +0 -0
  212. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/arguments/argumentspec.py +0 -0
  213. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/arguments/argumentvalidator.py +0 -0
  214. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/arguments/customconverters.py +0 -0
  215. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/arguments/typeinfoparser.py +0 -0
  216. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/arguments/typevalidator.py +0 -0
  217. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/builder/__init__.py +0 -0
  218. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/builder/builders.py +0 -0
  219. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/builder/parsers.py +0 -0
  220. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/dynamicmethods.py +0 -0
  221. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/importer.py +0 -0
  222. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/invalidkeyword.py +0 -0
  223. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/keywordfinder.py +0 -0
  224. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/keywordimplementation.py +0 -0
  225. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/libraryscopes.py +0 -0
  226. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/namespace.py +0 -0
  227. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/outputcapture.py +0 -0
  228. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/randomizer.py +0 -0
  229. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/resourcemodel.py +0 -0
  230. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/runkwregister.py +0 -0
  231. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/signalhandler.py +0 -0
  232. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/testlibraries.py +0 -0
  233. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/timeouts/__init__.py +0 -0
  234. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/timeouts/nosupport.py +0 -0
  235. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/timeouts/posix.py +0 -0
  236. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/timeouts/windows.py +0 -0
  237. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/running/userkeywordrunner.py +0 -0
  238. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/testdoc.py +0 -0
  239. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/__init__.py +0 -0
  240. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/application.py +0 -0
  241. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/argumentparser.py +0 -0
  242. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/asserts.py +0 -0
  243. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/charwidth.py +0 -0
  244. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/compress.py +0 -0
  245. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/connectioncache.py +0 -0
  246. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/dotdict.py +0 -0
  247. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/encoding.py +0 -0
  248. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/encodingsniffer.py +0 -0
  249. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/error.py +0 -0
  250. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/escaping.py +0 -0
  251. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/etreewrapper.py +0 -0
  252. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/filereader.py +0 -0
  253. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/frange.py +0 -0
  254. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/htmlformatters.py +0 -0
  255. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/markuputils.py +0 -0
  256. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/markupwriters.py +0 -0
  257. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/match.py +0 -0
  258. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/misc.py +0 -0
  259. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/normalizing.py +0 -0
  260. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/notset.py +0 -0
  261. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/platform.py +0 -0
  262. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/recommendations.py +0 -0
  263. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/restreader.py +0 -0
  264. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/robotenv.py +0 -0
  265. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/robotinspect.py +0 -0
  266. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/robotio.py +0 -0
  267. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/robotpath.py +0 -0
  268. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/robottime.py +0 -0
  269. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/robottypes.py +0 -0
  270. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/setter.py +0 -0
  271. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/sortable.py +0 -0
  272. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/text.py +0 -0
  273. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/utils/typehints.py +0 -0
  274. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/variables/__init__.py +0 -0
  275. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/variables/assigner.py +0 -0
  276. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/variables/filesetter.py +0 -0
  277. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/variables/finders.py +0 -0
  278. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/variables/notfound.py +0 -0
  279. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/variables/resolvable.py +0 -0
  280. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/variables/search.py +0 -0
  281. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/variables/store.py +0 -0
  282. {robotframework-7.1.1 → robotframework-7.2b1}/src/robot/variables/tablesetter.py +0 -0
  283. {robotframework-7.1.1 → robotframework-7.2b1}/src/robotframework.egg-info/dependency_links.txt +0 -0
  284. {robotframework-7.1.1 → robotframework-7.2b1}/src/robotframework.egg-info/entry_points.txt +0 -0
  285. {robotframework-7.1.1 → robotframework-7.2b1}/src/robotframework.egg-info/top_level.txt +0 -0
  286. {robotframework-7.1.1 → robotframework-7.2b1}/tasks.py +0 -0
@@ -0,0 +1,174 @@
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 pathlib import Path
17
+
18
+ from robot.errors import DataError
19
+ from robot.utils import get_error_message
20
+
21
+ from .loggerapi import LoggerApi
22
+ from .loglevel import LogLevel
23
+ from .jsonlogger import JsonLogger
24
+ from .xmllogger import LegacyXmlLogger, NullLogger, XmlLogger
25
+
26
+
27
+ class OutputFile(LoggerApi):
28
+
29
+ def __init__(self, path: 'Path|None', log_level: LogLevel, rpa: bool = False,
30
+ legacy_output: bool = False):
31
+ # `self.logger` is replaced with `NullLogger` when flattening.
32
+ self.logger = self.real_logger = self._get_logger(path, rpa, legacy_output)
33
+ self.is_logged = log_level.is_logged
34
+ self.flatten_level = 0
35
+ self.errors = []
36
+
37
+ def _get_logger(self, path, rpa, legacy_output):
38
+ if not path:
39
+ return NullLogger()
40
+ try:
41
+ file = open(path, 'w', encoding='UTF-8')
42
+ except Exception:
43
+ raise DataError(f"Opening output file '{path}' failed: "
44
+ f"{get_error_message()}")
45
+ if path.suffix.lower() == '.json':
46
+ return JsonLogger(file, rpa)
47
+ if legacy_output:
48
+ return LegacyXmlLogger(file, rpa)
49
+ return XmlLogger(file, rpa)
50
+
51
+ def start_suite(self, data, result):
52
+ self.logger.start_suite(result)
53
+
54
+ def end_suite(self, data, result):
55
+ self.logger.end_suite(result)
56
+
57
+ def start_test(self, data, result):
58
+ self.logger.start_test(result)
59
+
60
+ def end_test(self, data, result):
61
+ self.logger.end_test(result)
62
+
63
+ def start_keyword(self, data, result):
64
+ self.logger.start_keyword(result)
65
+ if result.tags.robot('flatten'):
66
+ self.flatten_level += 1
67
+ self.logger = NullLogger()
68
+
69
+ def end_keyword(self, data, result):
70
+ if self.flatten_level and result.tags.robot('flatten'):
71
+ self.flatten_level -= 1
72
+ if self.flatten_level == 0:
73
+ self.logger = self.real_logger
74
+ self.logger.end_keyword(result)
75
+
76
+ def start_for(self, data, result):
77
+ self.logger.start_for(result)
78
+
79
+ def end_for(self, data, result):
80
+ self.logger.end_for(result)
81
+
82
+ def start_for_iteration(self, data, result):
83
+ self.logger.start_for_iteration(result)
84
+
85
+ def end_for_iteration(self, data, result):
86
+ self.logger.end_for_iteration(result)
87
+
88
+ def start_while(self, data, result):
89
+ self.logger.start_while(result)
90
+
91
+ def end_while(self, data, result):
92
+ self.logger.end_while(result)
93
+
94
+ def start_while_iteration(self, data, result):
95
+ self.logger.start_while_iteration(result)
96
+
97
+ def end_while_iteration(self, data, result):
98
+ self.logger.end_while_iteration(result)
99
+
100
+ def start_if(self, data, result):
101
+ self.logger.start_if(result)
102
+
103
+ def end_if(self, data, result):
104
+ self.logger.end_if(result)
105
+
106
+ def start_if_branch(self, data, result):
107
+ self.logger.start_if_branch(result)
108
+
109
+ def end_if_branch(self, data, result):
110
+ self.logger.end_if_branch(result)
111
+
112
+ def start_try(self, data, result):
113
+ self.logger.start_try(result)
114
+
115
+ def end_try(self, data, result):
116
+ self.logger.end_try(result)
117
+
118
+ def start_try_branch(self, data, result):
119
+ self.logger.start_try_branch(result)
120
+
121
+ def end_try_branch(self, data, result):
122
+ self.logger.end_try_branch(result)
123
+
124
+ def start_group(self, data, result):
125
+ self.logger.start_group(result)
126
+
127
+ def end_group(self, data, result):
128
+ self.logger.end_group(result)
129
+
130
+ def start_var(self, data, result):
131
+ self.logger.start_var(result)
132
+
133
+ def end_var(self, data, result):
134
+ self.logger.end_var(result)
135
+
136
+ def start_break(self, data, result):
137
+ self.logger.start_break(result)
138
+
139
+ def end_break(self, data, result):
140
+ self.logger.end_break(result)
141
+
142
+ def start_continue(self, data, result):
143
+ self.logger.start_continue(result)
144
+
145
+ def end_continue(self, data, result):
146
+ self.logger.end_continue(result)
147
+
148
+ def start_return(self, data, result):
149
+ self.logger.start_return(result)
150
+
151
+ def end_return(self, data, result):
152
+ self.logger.end_return(result)
153
+
154
+ def start_error(self, data, result):
155
+ self.logger.start_error(result)
156
+
157
+ def end_error(self, data, result):
158
+ self.logger.end_error(result)
159
+
160
+ def log_message(self, message):
161
+ if self.is_logged(message):
162
+ # Use the real logger also when flattening.
163
+ self.real_logger.message(message)
164
+
165
+ def message(self, message):
166
+ if message.level in ('WARN', 'ERROR'):
167
+ self.errors.append(message)
168
+
169
+ def statistics(self, stats):
170
+ self.logger.statistics(stats)
171
+
172
+ def close(self):
173
+ self.logger.errors(self.errors)
174
+ self.logger.close()
@@ -36,6 +36,7 @@ def robot_handler_enabled(level):
36
36
  return
37
37
  handler = RobotHandler()
38
38
  old_raise = logging.raiseExceptions
39
+ old_level = root.level
39
40
  root.addHandler(handler)
40
41
  logging.raiseExceptions = False
41
42
  set_level(level)
@@ -43,6 +44,7 @@ def robot_handler_enabled(level):
43
44
  yield
44
45
  finally:
45
46
  root.removeHandler(handler)
47
+ root.setLevel(old_level)
46
48
  logging.raiseExceptions = old_raise
47
49
 
48
50
 
@@ -19,189 +19,43 @@ from robot.utils import NullMarkupWriter, XmlWriter
19
19
  from robot.version import get_full_version
20
20
  from robot.result import Keyword, TestCase, TestSuite, ResultVisitor
21
21
 
22
- from .loggerapi import LoggerApi
23
- from .loggerhelper import IsLogged
24
-
25
-
26
- class XmlLoggerAdapter(LoggerApi):
27
-
28
- def __init__(self, path, log_level='TRACE', rpa=False, generator='Robot',
29
- legacy_output=False):
30
- logger = XmlLogger if not legacy_output else LegacyXmlLogger
31
- self.logger = logger(path, log_level, rpa, generator)
32
-
33
- @property
34
- def flatten_level(self):
35
- return self.logger.flatten_level
36
-
37
- def close(self):
38
- self.logger.close()
39
-
40
- def set_log_level(self, level):
41
- return self.logger.set_log_level(level)
42
-
43
- def start_suite(self, data, result):
44
- self.logger.start_suite(result)
45
-
46
- def end_suite(self, data, result):
47
- self.logger.end_suite(result)
48
-
49
- def start_test(self, data, result):
50
- self.logger.start_test(result)
51
-
52
- def end_test(self, data, result):
53
- self.logger.end_test(result)
54
-
55
- def start_keyword(self, data, result):
56
- self.logger.start_keyword(result)
57
-
58
- def end_keyword(self, data, result):
59
- self.logger.end_keyword(result)
60
-
61
- def start_for(self, data, result):
62
- self.logger.start_for(result)
63
-
64
- def end_for(self, data, result):
65
- self.logger.end_for(result)
66
-
67
- def start_for_iteration(self, data, result):
68
- self.logger.start_for_iteration(result)
69
-
70
- def end_for_iteration(self, data, result):
71
- self.logger.end_for_iteration(result)
72
-
73
- def start_while(self, data, result):
74
- self.logger.start_while(result)
75
-
76
- def end_while(self, data, result):
77
- self.logger.end_while(result)
78
-
79
- def start_while_iteration(self, data, result):
80
- self.logger.start_while_iteration(result)
81
-
82
- def end_while_iteration(self, data, result):
83
- self.logger.end_while_iteration(result)
84
-
85
- def start_if(self, data, result):
86
- self.logger.start_if(result)
87
-
88
- def end_if(self, data, result):
89
- self.logger.end_if(result)
90
-
91
- def start_if_branch(self, data, result):
92
- self.logger.start_if_branch(result)
93
-
94
- def end_if_branch(self, data, result):
95
- self.logger.end_if_branch(result)
96
-
97
- def start_try(self, data, result):
98
- self.logger.start_try(result)
99
-
100
- def end_try(self, data, result):
101
- self.logger.end_try(result)
102
-
103
- def start_try_branch(self, data, result):
104
- self.logger.start_try_branch(result)
105
-
106
- def end_try_branch(self, data, result):
107
- self.logger.end_try_branch(result)
108
-
109
- def start_var(self, data, result):
110
- self.logger.start_var(result)
111
-
112
- def end_var(self, data, result):
113
- self.logger.end_var(result)
114
-
115
- def start_break(self, data, result):
116
- self.logger.start_break(result)
117
-
118
- def end_break(self, data, result):
119
- self.logger.end_break(result)
120
-
121
- def start_continue(self, data, result):
122
- self.logger.start_continue(result)
123
-
124
- def end_continue(self, data, result):
125
- self.logger.end_continue(result)
126
-
127
- def start_return(self, data, result):
128
- self.logger.start_return(result)
129
-
130
- def end_return(self, data, result):
131
- self.logger.end_return(result)
132
-
133
- def start_error(self, data, result):
134
- self.logger.start_error(result)
135
-
136
- def end_error(self, data, result):
137
- self.logger.end_error(result)
138
-
139
- def log_message(self, message):
140
- self.logger.log_message(message)
141
-
142
- def message(self, message):
143
- self.logger.message(message)
144
-
145
22
 
146
23
  class XmlLogger(ResultVisitor):
24
+ generator = 'Robot'
147
25
 
148
- def __init__(self, output, log_level='TRACE', rpa=False, generator='Robot',
149
- suite_only=False):
150
- self._log_message_is_logged = IsLogged(log_level)
151
- self._error_message_is_logged = IsLogged('WARN')
152
- # `_writer` is set to NullMarkupWriter when flattening, `_xml_writer` is not.
153
- self._writer = self._xml_writer = self._get_writer(output, rpa, generator,
154
- suite_only)
155
- self.flatten_level = 0
156
- self._errors = []
157
-
158
- def _get_writer(self, output, rpa, generator, suite_only):
159
- if not output:
160
- return NullMarkupWriter()
161
- writer = XmlWriter(output, write_empty=False, usage='output',
162
- preamble=not suite_only)
26
+ def __init__(self, output, rpa=False, suite_only=False):
27
+ self._writer = self._get_writer(output, preamble=not suite_only)
163
28
  if not suite_only:
164
- writer.start('robot', self._get_start_attrs(rpa, generator))
165
- return writer
29
+ self._writer.start('robot', self._get_start_attrs(rpa))
30
+
31
+ def _get_writer(self, output, preamble=True):
32
+ return XmlWriter(output, usage='output', write_empty=False, preamble=preamble)
166
33
 
167
- def _get_start_attrs(self, rpa, generator):
168
- return {'generator': get_full_version(generator),
34
+ def _get_start_attrs(self, rpa):
35
+ return {'generator': get_full_version(self.generator),
169
36
  'generated': datetime.now().isoformat(),
170
37
  'rpa': 'true' if rpa else 'false',
171
38
  'schemaversion': '5'}
172
39
 
173
40
  def close(self):
174
- self.start_errors()
175
- for msg in self._errors:
176
- self._write_message(msg)
177
- self.end_errors()
178
41
  self._writer.end('robot')
179
42
  self._writer.close()
180
43
 
181
- def set_log_level(self, level):
182
- return self._log_message_is_logged.set_level(level)
44
+ def visit_message(self, msg):
45
+ self._write_message(msg)
183
46
 
184
47
  def message(self, msg):
185
- if self._error_message_is_logged(msg.level):
186
- self._errors.append(msg)
187
-
188
- def log_message(self, msg):
189
- if self._log_message_is_logged(msg.level):
190
- self._write_message(msg)
48
+ self._write_message(msg)
191
49
 
192
50
  def _write_message(self, msg):
193
51
  attrs = {'time': msg.timestamp.isoformat() if msg.timestamp else None,
194
52
  'level': msg.level}
195
53
  if msg.html:
196
54
  attrs['html'] = 'true'
197
- # Use `_xml_writer`, not `_writer` to write messages also when flattening.
198
- self._xml_writer.element('msg', msg.message, attrs)
55
+ self._writer.element('msg', msg.message, attrs)
199
56
 
200
57
  def start_keyword(self, kw):
201
58
  self._writer.start('kw', self._get_start_keyword_attrs(kw))
202
- if kw.tags.robot('flatten'):
203
- self.flatten_level += 1
204
- self._writer = NullMarkupWriter()
205
59
 
206
60
  def _get_start_keyword_attrs(self, kw):
207
61
  attrs = {'name': kw.name, 'owner': kw.owner}
@@ -212,10 +66,6 @@ class XmlLogger(ResultVisitor):
212
66
  return attrs
213
67
 
214
68
  def end_keyword(self, kw):
215
- if kw.tags.robot('flatten'):
216
- self.flatten_level -= 1
217
- if self.flatten_level == 0:
218
- self._writer = self._xml_writer
219
69
  self._write_list('var', kw.assign)
220
70
  self._write_list('arg', [str(a) for a in kw.args])
221
71
  self._write_list('tag', kw.tags)
@@ -304,6 +154,13 @@ class XmlLogger(ResultVisitor):
304
154
  self._write_status(iteration)
305
155
  self._writer.end('iter')
306
156
 
157
+ def start_group(self, group):
158
+ self._writer.start('group', {'name': group.name})
159
+
160
+ def end_group(self, group):
161
+ self._write_status(group)
162
+ self._writer.end('group')
163
+
307
164
  def start_var(self, var):
308
165
  attr = {'name': var.name}
309
166
  if var.scope is not None:
@@ -375,6 +232,9 @@ class XmlLogger(ResultVisitor):
375
232
  self._write_status(suite)
376
233
  self._writer.end('suite')
377
234
 
235
+ def statistics(self, stats):
236
+ self.visit_statistics(stats)
237
+
378
238
  def start_statistics(self, stats):
379
239
  self._writer.start('statistics')
380
240
 
@@ -403,10 +263,13 @@ class XmlLogger(ResultVisitor):
403
263
  self._writer.element('stat', stat.name,
404
264
  stat.get_attributes(values_as_strings=True))
405
265
 
406
- def start_errors(self, errors=None):
266
+ def errors(self, errors):
267
+ self.visit_errors(errors)
268
+
269
+ def start_errors(self, errors):
407
270
  self._writer.start('errors')
408
271
 
409
- def end_errors(self, errors=None):
272
+ def end_errors(self, errors):
410
273
  self._writer.end('errors')
411
274
 
412
275
  def _write_list(self, tag, items):
@@ -422,8 +285,8 @@ class XmlLogger(ResultVisitor):
422
285
 
423
286
  class LegacyXmlLogger(XmlLogger):
424
287
 
425
- def _get_start_attrs(self, rpa, generator):
426
- return {'generator': get_full_version(generator),
288
+ def _get_start_attrs(self, rpa):
289
+ return {'generator': get_full_version(self.generator),
427
290
  'generated': self._datetime_to_timestamp(datetime.now()),
428
291
  'rpa': 'true' if rpa else 'false',
429
292
  'schemaversion': '4'}
@@ -457,5 +320,13 @@ class LegacyXmlLogger(XmlLogger):
457
320
  attrs = {'timestamp': ts, 'level': msg.level}
458
321
  if msg.html:
459
322
  attrs['html'] = 'true'
460
- # Use `_xml_writer`, not `_writer` to write messages also when flattening.
461
- self._xml_writer.element('msg', msg.message, attrs)
323
+ self._writer.element('msg', msg.message, attrs)
324
+
325
+
326
+ class NullLogger(XmlLogger):
327
+
328
+ def __init__(self):
329
+ super().__init__(None)
330
+
331
+ def _get_writer(self, output, preamble=True):
332
+ return NullMarkupWriter()
@@ -23,7 +23,7 @@ from .context import (FileContext, KeywordContext, LexingContext, SuiteFileConte
23
23
  from .statementlexers import (BreakLexer, CommentLexer, CommentSectionHeaderLexer,
24
24
  ContinueLexer, ElseHeaderLexer, ElseIfHeaderLexer,
25
25
  EndLexer, ExceptHeaderLexer, FinallyHeaderLexer,
26
- ForHeaderLexer, IfHeaderLexer, ImplicitCommentLexer,
26
+ ForHeaderLexer, GroupHeaderLexer, IfHeaderLexer, ImplicitCommentLexer,
27
27
  InlineIfHeaderLexer, InvalidSectionHeaderLexer,
28
28
  KeywordCallLexer, KeywordSectionHeaderLexer,
29
29
  KeywordSettingLexer, Lexer, ReturnLexer, SettingLexer,
@@ -202,7 +202,7 @@ class TestCaseLexer(TestOrKeywordLexer):
202
202
 
203
203
  def lexer_classes(self) -> 'tuple[type[Lexer], ...]':
204
204
  return (TestCaseSettingLexer, ForLexer, InlineIfLexer, IfLexer, TryLexer,
205
- WhileLexer, VarLexer, SyntaxErrorLexer, KeywordCallLexer)
205
+ WhileLexer, GroupLexer, VarLexer, SyntaxErrorLexer, KeywordCallLexer)
206
206
 
207
207
 
208
208
  class KeywordLexer(TestOrKeywordLexer):
@@ -213,7 +213,7 @@ class KeywordLexer(TestOrKeywordLexer):
213
213
 
214
214
  def lexer_classes(self) -> 'tuple[type[Lexer], ...]':
215
215
  return (KeywordSettingLexer, ForLexer, InlineIfLexer, IfLexer, TryLexer,
216
- WhileLexer, VarLexer, ReturnLexer, SyntaxErrorLexer, KeywordCallLexer)
216
+ WhileLexer, GroupLexer, VarLexer, ReturnLexer, SyntaxErrorLexer, KeywordCallLexer)
217
217
 
218
218
 
219
219
  class NestedBlockLexer(BlockLexer, ABC):
@@ -230,7 +230,7 @@ class NestedBlockLexer(BlockLexer, ABC):
230
230
  super().input(statement)
231
231
  lexer = self.lexers[-1]
232
232
  if isinstance(lexer, (ForHeaderLexer, IfHeaderLexer, TryHeaderLexer,
233
- WhileHeaderLexer)):
233
+ WhileHeaderLexer, GroupHeaderLexer)):
234
234
  self._block_level += 1
235
235
  if isinstance(lexer, EndLexer):
236
236
  self._block_level -= 1
@@ -243,8 +243,8 @@ class ForLexer(NestedBlockLexer):
243
243
 
244
244
  def lexer_classes(self) -> 'tuple[type[Lexer], ...]':
245
245
  return (ForHeaderLexer, InlineIfLexer, IfLexer, TryLexer, WhileLexer, EndLexer,
246
- VarLexer, ReturnLexer, ContinueLexer, BreakLexer, SyntaxErrorLexer,
247
- KeywordCallLexer)
246
+ GroupLexer, VarLexer, ReturnLexer, ContinueLexer, BreakLexer,
247
+ SyntaxErrorLexer, KeywordCallLexer)
248
248
 
249
249
 
250
250
  class WhileLexer(NestedBlockLexer):
@@ -254,8 +254,8 @@ class WhileLexer(NestedBlockLexer):
254
254
 
255
255
  def lexer_classes(self) -> 'tuple[type[Lexer], ...]':
256
256
  return (WhileHeaderLexer, ForLexer, InlineIfLexer, IfLexer, TryLexer, EndLexer,
257
- VarLexer, ReturnLexer, ContinueLexer, BreakLexer, SyntaxErrorLexer,
258
- KeywordCallLexer)
257
+ GroupLexer, VarLexer, ReturnLexer, ContinueLexer, BreakLexer,
258
+ SyntaxErrorLexer, KeywordCallLexer)
259
259
 
260
260
 
261
261
  class TryLexer(NestedBlockLexer):
@@ -266,7 +266,19 @@ class TryLexer(NestedBlockLexer):
266
266
  def lexer_classes(self) -> 'tuple[type[Lexer], ...]':
267
267
  return (TryHeaderLexer, ExceptHeaderLexer, ElseHeaderLexer, FinallyHeaderLexer,
268
268
  ForLexer, InlineIfLexer, IfLexer, WhileLexer, EndLexer, VarLexer,
269
- ReturnLexer, BreakLexer, ContinueLexer, SyntaxErrorLexer,
269
+ GroupLexer, ReturnLexer, BreakLexer, ContinueLexer, SyntaxErrorLexer,
270
+ KeywordCallLexer)
271
+
272
+
273
+ class GroupLexer(NestedBlockLexer):
274
+
275
+ def handles(self, statement: StatementTokens) -> bool:
276
+ return GroupHeaderLexer(self.ctx).handles(statement)
277
+
278
+ def lexer_classes(self) -> 'tuple[type[Lexer], ...]':
279
+ return (GroupHeaderLexer, InlineIfLexer, IfLexer,
280
+ ForLexer, TryLexer, WhileLexer, EndLexer, VarLexer,
281
+ ReturnLexer, ContinueLexer, BreakLexer, SyntaxErrorLexer,
270
282
  KeywordCallLexer)
271
283
 
272
284
 
@@ -277,8 +289,9 @@ class IfLexer(NestedBlockLexer):
277
289
 
278
290
  def lexer_classes(self) -> 'tuple[type[Lexer], ...]':
279
291
  return (InlineIfLexer, IfHeaderLexer, ElseIfHeaderLexer, ElseHeaderLexer,
280
- ForLexer, TryLexer, WhileLexer, EndLexer, VarLexer, ReturnLexer,
281
- ContinueLexer, BreakLexer, SyntaxErrorLexer, KeywordCallLexer)
292
+ ForLexer, TryLexer, WhileLexer, EndLexer, VarLexer, GroupLexer,
293
+ ReturnLexer, ContinueLexer, BreakLexer, SyntaxErrorLexer,
294
+ KeywordCallLexer)
282
295
 
283
296
 
284
297
  class InlineIfLexer(NestedBlockLexer):
@@ -293,7 +306,7 @@ class InlineIfLexer(NestedBlockLexer):
293
306
 
294
307
  def lexer_classes(self) -> 'tuple[type[Lexer], ...]':
295
308
  return (InlineIfHeaderLexer, ElseIfHeaderLexer, ElseHeaderLexer, VarLexer,
296
- ReturnLexer, ContinueLexer, BreakLexer, KeywordCallLexer)
309
+ GroupLexer, ReturnLexer, ContinueLexer, BreakLexer, KeywordCallLexer)
297
310
 
298
311
  def input(self, statement: StatementTokens):
299
312
  for part in self._split(statement):
@@ -135,17 +135,19 @@ class ImplicitCommentLexer(CommentLexer):
135
135
 
136
136
  def input(self, statement: StatementTokens):
137
137
  super().input(statement)
138
- if len(statement) == 1 and statement[0].value.lower().startswith('language:'):
139
- lang = statement[0].value.split(':', 1)[1].strip()
138
+ if statement[0].value.lower().startswith('language:'):
139
+ value = ' '.join(token.value for token in statement)
140
+ lang = value.split(':', 1)[1].strip()
140
141
  try:
141
142
  self.ctx.add_language(lang)
142
143
  except DataError:
143
- statement[0].set_error(
144
- f"Invalid language configuration: "
145
- f"Language '{lang}' not found nor importable as a language module."
146
- )
144
+ for token in statement:
145
+ token.set_error(f"Invalid language configuration: "
146
+ f"Language '{lang}' not found nor importable "
147
+ f"as a language module.")
147
148
  else:
148
- statement[0].type = Token.CONFIG
149
+ for token in statement:
150
+ token.type = Token.CONFIG
149
151
 
150
152
  def lex(self):
151
153
  for token in self.statement:
@@ -333,6 +335,13 @@ class WhileHeaderLexer(StatementLexer):
333
335
  self._lex_options('limit', 'on_limit', 'on_limit_message')
334
336
 
335
337
 
338
+ class GroupHeaderLexer(TypeAndArguments):
339
+ token_type = Token.GROUP
340
+
341
+ def handles(self, statement: StatementTokens) -> bool:
342
+ return statement[0].value == 'GROUP'
343
+
344
+
336
345
  class EndLexer(TypeAndArguments):
337
346
  token_type = Token.END
338
347
 
@@ -102,6 +102,7 @@ class Token:
102
102
  CONTINUE = 'CONTINUE'
103
103
  BREAK = 'BREAK'
104
104
  OPTION = 'OPTION'
105
+ GROUP = 'GROUP'
105
106
 
106
107
  SEPARATOR = 'SEPARATOR'
107
108
  COMMENT = 'COMMENT'
@@ -172,7 +173,7 @@ class Token:
172
173
  Token.END: 'END', Token.VAR: 'VAR', Token.CONTINUE: 'CONTINUE',
173
174
  Token.BREAK: 'BREAK', Token.RETURN_STATEMENT: 'RETURN',
174
175
  Token.CONTINUATION: '...', Token.EOL: '\n', Token.WITH_NAME: 'AS',
175
- Token.AS: 'AS'
176
+ Token.AS: 'AS', Token.GROUP: 'GROUP'
176
177
  }.get(type, '') # type: ignore
177
178
  self.value = cast(str, value)
178
179
  self.lineno = lineno
@@ -13,7 +13,7 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
 
16
- from .blocks import (Block, CommentSection, Container, File, For, If,
16
+ from .blocks import (Block, CommentSection, Container, File, For, If, Group,
17
17
  ImplicitCommentSection, InvalidSection, Keyword,
18
18
  KeywordSection, NestedBlock, Section, SettingSection,
19
19
  TestCase, TestCaseSection, Try, VariableSection, While)