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
@@ -16,6 +16,7 @@
16
16
  import os.path
17
17
  from abc import ABC
18
18
  from pathlib import Path
19
+ from typing import Any, Iterable
19
20
 
20
21
  from robot.errors import DataError, TimeoutError
21
22
  from robot.model import BodyItem
@@ -23,15 +24,17 @@ from robot.utils import (get_error_details, Importer, safe_str,
23
24
  split_args_from_name_or_path, type_name)
24
25
 
25
26
  from .loggerapi import LoggerApi
26
- from .loggerhelper import IsLogged
27
27
  from .logger import LOGGER
28
+ from .loglevel import LogLevel
28
29
 
29
30
 
30
31
  class Listeners:
31
32
  _listeners: 'list[ListenerFacade]'
32
33
 
33
- def __init__(self, listeners=(), log_level='INFO'):
34
- self._is_logged = IsLogged(log_level)
34
+ def __init__(self, listeners: Iterable['str|Any'] = (),
35
+ log_level: 'LogLevel|str' = 'INFO'):
36
+ self._log_level = log_level \
37
+ if isinstance(log_level, LogLevel) else LogLevel(log_level)
35
38
  self._listeners = self._import_listeners(listeners)
36
39
 
37
40
  # Must be property to allow LibraryListeners to override it.
@@ -67,8 +70,8 @@ class Listeners:
67
70
  # Modules have `__name__`, with others better to use `type_name`.
68
71
  name = getattr(listener, '__name__', None) or type_name(listener)
69
72
  if self._get_version(listener) == 2:
70
- return ListenerV2Facade(listener, name, self._is_logged, library)
71
- return ListenerV3Facade(listener, name, self._is_logged, library)
73
+ return ListenerV2Facade(listener, name, self._log_level, library)
74
+ return ListenerV3Facade(listener, name, self._log_level, library)
72
75
 
73
76
  def _get_version(self, listener):
74
77
  version = getattr(listener, 'ROBOT_LISTENER_API_VERSION', 3)
@@ -80,9 +83,6 @@ class Listeners:
80
83
  raise DataError(f"Unsupported API version '{version}'.")
81
84
  return version
82
85
 
83
- def set_log_level(self, level):
84
- self._is_logged.set_level(level)
85
-
86
86
  def __iter__(self):
87
87
  return iter(self.listeners)
88
88
 
@@ -93,7 +93,7 @@ class Listeners:
93
93
  class LibraryListeners(Listeners):
94
94
  _listeners: 'list[list[ListenerFacade]]'
95
95
 
96
- def __init__(self, log_level='INFO'):
96
+ def __init__(self, log_level: 'LogLevel|str' = 'INFO'):
97
97
  super().__init__(log_level=log_level)
98
98
 
99
99
  @property
@@ -122,10 +122,10 @@ class LibraryListeners(Listeners):
122
122
 
123
123
  class ListenerFacade(LoggerApi, ABC):
124
124
 
125
- def __init__(self, listener, name, is_logged, library=None):
125
+ def __init__(self, listener, name, log_level, library=None):
126
126
  self.listener = listener
127
127
  self.name = name
128
- self._is_logged = is_logged
128
+ self._is_logged = log_level.is_logged
129
129
  self.library = library
130
130
  self.priority = self._get_priority(listener)
131
131
 
@@ -141,7 +141,7 @@ class ListenerFacade(LoggerApi, ABC):
141
141
  method = getattr(self.listener, method_name, None)
142
142
  if method:
143
143
  return ListenerMethod(method, self.name)
144
- return ListenerMethod(None, self.name) if fallback is None else fallback
144
+ return fallback or ListenerMethod(None, self.name)
145
145
 
146
146
  def _get_method_names(self, name):
147
147
  names = [name, self._to_camelCase(name)] if '_' in name else [name]
@@ -156,8 +156,8 @@ class ListenerFacade(LoggerApi, ABC):
156
156
 
157
157
  class ListenerV3Facade(ListenerFacade):
158
158
 
159
- def __init__(self, listener, name, is_logged, library=None):
160
- super().__init__(listener, name, is_logged, library)
159
+ def __init__(self, listener, name, log_level, library=None):
160
+ super().__init__(listener, name, log_level, library)
161
161
  get = self._get_method
162
162
  # Suite
163
163
  self.start_suite = get('start_suite')
@@ -166,8 +166,8 @@ class ListenerV3Facade(ListenerFacade):
166
166
  self.start_test = get('start_test')
167
167
  self.end_test = get('end_test')
168
168
  # Fallbacks for body items
169
- start_body_item = self._get_method('start_body_item')
170
- end_body_item = self._get_method('end_body_item')
169
+ start_body_item = get('start_body_item')
170
+ end_body_item = get('end_body_item')
171
171
  # Keywords
172
172
  self.start_keyword = get('start_keyword', start_body_item)
173
173
  self.end_keyword = get('end_keyword', end_body_item)
@@ -197,6 +197,9 @@ class ListenerV3Facade(ListenerFacade):
197
197
  self.end_while = get('end_while', end_body_item)
198
198
  self.start_while_iteration = get('start_while_iteration', start_body_item)
199
199
  self.end_while_iteration = get('end_while_iteration', end_body_item)
200
+ # GROUP
201
+ self.start_group = get('start_group', start_body_item)
202
+ self.end_group = get('end_group', end_body_item)
200
203
  # VAR
201
204
  self.start_var = get('start_var', start_body_item)
202
205
  self.end_var = get('end_var', end_body_item)
@@ -265,38 +268,39 @@ class ListenerV3Facade(ListenerFacade):
265
268
  self.end_keyword(data, result)
266
269
 
267
270
  def log_message(self, message):
268
- if self._is_logged(message.level):
271
+ if self._is_logged(message):
269
272
  self._log_message(message)
270
273
 
271
274
 
272
275
  class ListenerV2Facade(ListenerFacade):
273
276
 
274
- def __init__(self, listener, name, is_logged, library=None):
275
- super().__init__(listener, name, is_logged, library)
277
+ def __init__(self, listener, name, log_level, library=None):
278
+ super().__init__(listener, name, log_level, library)
279
+ get = self._get_method
276
280
  # Suite
277
- self._start_suite = self._get_method('start_suite')
278
- self._end_suite = self._get_method('end_suite')
281
+ self._start_suite = get('start_suite')
282
+ self._end_suite = get('end_suite')
279
283
  # Test
280
- self._start_test = self._get_method('start_test')
281
- self._end_test = self._get_method('end_test')
284
+ self._start_test = get('start_test')
285
+ self._end_test = get('end_test')
282
286
  # Keyword and control structures
283
- self._start_kw = self._get_method('start_keyword')
284
- self._end_kw = self._get_method('end_keyword')
287
+ self._start_kw = get('start_keyword')
288
+ self._end_kw = get('end_keyword')
285
289
  # Messages
286
- self._log_message = self._get_method('log_message')
287
- self._message = self._get_method('message')
290
+ self._log_message = get('log_message')
291
+ self._message = get('message')
288
292
  # Imports
289
- self._library_import = self._get_method('library_import')
290
- self._resource_import = self._get_method('resource_import')
291
- self._variables_import = self._get_method('variables_import')
293
+ self._library_import = get('library_import')
294
+ self._resource_import = get('resource_import')
295
+ self._variables_import = get('variables_import')
292
296
  # Result files
293
- self._output_file = self._get_method('output_file')
294
- self._report_file = self._get_method('report_file')
295
- self._log_file = self._get_method('log_file')
296
- self._xunit_file = self._get_method('xunit_file')
297
- self._debug_file = self._get_method('debug_file')
297
+ self._output_file = get('output_file')
298
+ self._report_file = get('report_file')
299
+ self._log_file = get('log_file')
300
+ self._xunit_file = get('xunit_file')
301
+ self._debug_file = get('debug_file')
298
302
  # Close
299
- self._close = self._get_method('close')
303
+ self._close = get('close')
300
304
 
301
305
  def start_suite(self, data, result):
302
306
  self._start_suite(result.name, self._suite_attrs(data, result))
@@ -363,6 +367,12 @@ class ListenerV2Facade(ListenerFacade):
363
367
  def end_while_iteration(self, data, result):
364
368
  self._end_kw(result._log_name, self._attrs(data, result, end=True))
365
369
 
370
+ def start_group(self, data, result):
371
+ self._start_kw(result._log_name, self._attrs(data, result, name=result.name))
372
+
373
+ def end_group(self, data, result):
374
+ self._end_kw(result._log_name, self._attrs(data, result, name=result.name, end=True))
375
+
366
376
  def start_if_branch(self, data, result):
367
377
  extra = {'condition': result.condition} if result.type != result.ELSE else {}
368
378
  self._start_kw(result._log_name, self._attrs(data, result, **extra))
@@ -430,7 +440,7 @@ class ListenerV2Facade(ListenerFacade):
430
440
  return {'name': result.name, 'value': value, 'scope': result.scope or 'LOCAL'}
431
441
 
432
442
  def log_message(self, message):
433
- if self._is_logged(message.level):
443
+ if self._is_logged(message):
434
444
  self._log_message(self._message_attributes(message))
435
445
 
436
446
  def message(self, message):
@@ -566,21 +576,15 @@ class ListenerV2Facade(ListenerFacade):
566
576
 
567
577
 
568
578
  class ListenerMethod:
569
- # Flag to avoid recursive listener calls.
570
- called = False
571
579
 
572
580
  def __init__(self, method, name):
573
581
  self.method = method
574
582
  self.listener_name = name
575
583
 
576
584
  def __call__(self, *args):
577
- if self.method is None:
578
- return
579
- if self.called:
580
- return
581
585
  try:
582
- ListenerMethod.called = True
583
- self.method(*args)
586
+ if self.method is not None:
587
+ self.method(*args)
584
588
  except TimeoutError:
585
589
  # Propagate possible timeouts:
586
590
  # https://github.com/robotframework/robotframework/issues/2763
@@ -590,8 +594,6 @@ class ListenerMethod:
590
594
  LOGGER.error(f"Calling method '{self.method.__name__}' of listener "
591
595
  f"'{self.listener_name}' failed: {message}")
592
596
  LOGGER.info(f"Details:\n{details}")
593
- finally:
594
- ListenerMethod.called = False
595
597
 
596
598
  def __bool__(self):
597
599
  return self.method is not None
@@ -26,19 +26,15 @@ from .stdoutlogsplitter import StdoutLogSplitter
26
26
 
27
27
  def start_body_item(method):
28
28
  def wrapper(self, *args):
29
- # TODO: Could _prev_log_message_handlers be used also here?
30
- self._started_keywords += 1
31
- self.log_message = self._log_message
29
+ self._log_message_parents.append(args[-1])
32
30
  method(self, *args)
33
31
  return wrapper
34
32
 
35
33
 
36
34
  def end_body_item(method):
37
35
  def wrapper(self, *args):
38
- self._started_keywords -= 1
39
36
  method(self, *args)
40
- if not self._started_keywords:
41
- self.log_message = self.message
37
+ self._log_message_parents.pop()
42
38
  return wrapper
43
39
 
44
40
 
@@ -55,16 +51,16 @@ class Logger(AbstractLogger):
55
51
  def __init__(self, register_console_logger=True):
56
52
  self._console_logger = None
57
53
  self._syslog = None
58
- self._xml_logger = None
54
+ self._output_file = None
59
55
  self._cli_listeners = None
60
56
  self._lib_listeners = None
61
57
  self._other_loggers = []
62
58
  self._message_cache = []
63
59
  self._log_message_cache = None
64
- self._started_keywords = 0
60
+ self._log_message_parents = []
61
+ self._library_import_logging = 0
65
62
  self._error_occurred = False
66
63
  self._error_listener = None
67
- self._prev_log_message_handlers = []
68
64
  self._enabled = 0
69
65
  self._cache_only = False
70
66
  if register_console_logger:
@@ -79,14 +75,14 @@ class Logger(AbstractLogger):
79
75
  @property
80
76
  def start_loggers(self):
81
77
  loggers = (self._other_loggers
82
- + [self._console_logger, self._syslog, self._xml_logger]
78
+ + [self._console_logger, self._syslog, self._output_file]
83
79
  + self._listeners)
84
80
  return [logger for logger in loggers if logger]
85
81
 
86
82
  @property
87
83
  def end_loggers(self):
88
84
  loggers = (self._listeners
89
- + [self._console_logger, self._syslog, self._xml_logger]
85
+ + [self._console_logger, self._syslog, self._output_file]
90
86
  + self._other_loggers)
91
87
  return [logger for logger in loggers if logger]
92
88
 
@@ -133,11 +129,11 @@ class Logger(AbstractLogger):
133
129
  else:
134
130
  self._syslog = self._wrap_and_relay(syslog)
135
131
 
136
- def register_xml_logger(self, logger):
137
- self._xml_logger = self._wrap_and_relay(logger)
132
+ def register_output_file(self, logger):
133
+ self._output_file = self._wrap_and_relay(logger)
138
134
 
139
- def unregister_xml_logger(self):
140
- self._xml_logger = None
135
+ def unregister_output_file(self):
136
+ self._output_file = None
141
137
 
142
138
  def register_listeners(self, listeners, library_listeners):
143
139
  self._cli_listeners = listeners
@@ -196,6 +192,12 @@ class Logger(AbstractLogger):
196
192
  for msg in messages or ():
197
193
  self._log_message(msg, no_cache=True)
198
194
 
195
+ def log_message(self, msg, no_cache=False):
196
+ if self._log_message_parents and not self._library_import_logging:
197
+ self._log_message(msg, no_cache)
198
+ else:
199
+ self.message(msg)
200
+
199
201
  def _log_message(self, msg, no_cache=False):
200
202
  """Log messages written (mainly) by libraries."""
201
203
  if self._log_message_cache is not None and not no_cache:
@@ -204,21 +206,20 @@ class Logger(AbstractLogger):
204
206
  return
205
207
  for logger in self:
206
208
  logger.log_message(msg)
209
+ if self._log_message_parents and self._output_file.is_logged(msg):
210
+ self._log_message_parents[-1].body.append(msg)
207
211
  if msg.level in ('WARN', 'ERROR'):
208
212
  self.message(msg)
209
213
 
210
- log_message = message
211
-
212
214
  def log_output(self, output):
213
215
  for msg in StdoutLogSplitter(output):
214
216
  self.log_message(msg)
215
217
 
216
218
  def enable_library_import_logging(self):
217
- self._prev_log_message_handlers.append(self.log_message)
218
- self.log_message = self.message
219
+ self._library_import_logging += 1
219
220
 
220
221
  def disable_library_import_logging(self):
221
- self.log_message = self._prev_log_message_handlers.pop()
222
+ self._library_import_logging -= 1
222
223
 
223
224
  def start_suite(self, data, result):
224
225
  for logger in self.start_loggers:
@@ -229,12 +230,14 @@ class Logger(AbstractLogger):
229
230
  logger.end_suite(data, result)
230
231
 
231
232
  def start_test(self, data, result):
233
+ self._log_message_parents.append(result)
232
234
  for logger in self.start_loggers:
233
235
  logger.start_test(data, result)
234
236
 
235
237
  def end_test(self, data, result):
236
238
  for logger in self.end_loggers:
237
239
  logger.end_test(data, result)
240
+ self._log_message_parents.pop()
238
241
 
239
242
  @start_body_item
240
243
  def start_keyword(self, data, result):
@@ -316,6 +319,16 @@ class Logger(AbstractLogger):
316
319
  for logger in self.end_loggers:
317
320
  logger.end_while_iteration(data, result)
318
321
 
322
+ @start_body_item
323
+ def start_group(self, data, result):
324
+ for logger in self.start_loggers:
325
+ logger.start_group(data, result)
326
+
327
+ @end_body_item
328
+ def end_group(self, data, result):
329
+ for logger in self.end_loggers:
330
+ logger.end_group(data, result)
331
+
319
332
  @start_body_item
320
333
  def start_if(self, data, result):
321
334
  for logger in self.start_loggers:
@@ -98,6 +98,12 @@ class LoggerApi:
98
98
  result: 'result.WhileIteration'):
99
99
  self.end_body_item(data, result)
100
100
 
101
+ def start_group(self, data: 'running.Group', result: 'result.Group'):
102
+ self.start_body_item(data, result)
103
+
104
+ def end_group(self, data: 'running.Group', result: 'result.Group'):
105
+ self.end_body_item(data, result)
106
+
101
107
  def start_if(self, data: 'running.If', result: 'result.If'):
102
108
  self.start_body_item(data, result)
103
109
 
@@ -18,20 +18,13 @@ from datetime import datetime
18
18
  from typing import Callable, Literal
19
19
 
20
20
  from robot.errors import DataError
21
- from robot.model import Message as BaseMessage, MessageLevel
22
- from robot.utils import console_encode, safe_str
23
-
24
-
25
- LEVELS = {
26
- 'NONE' : 7,
27
- 'SKIP' : 6,
28
- 'FAIL' : 5,
29
- 'ERROR' : 4,
30
- 'WARN' : 3,
31
- 'INFO' : 2,
32
- 'DEBUG' : 1,
33
- 'TRACE' : 0,
34
- }
21
+ from robot.model import MessageLevel
22
+ from robot.result import Message as BaseMessage
23
+ from robot.utils import console_encode
24
+
25
+ from .loglevel import LEVELS
26
+
27
+
35
28
  PseudoLevel = Literal['HTML', 'CONSOLE']
36
29
 
37
30
 
@@ -47,12 +40,6 @@ def write_to_console(msg, newline=True, stream='stdout'):
47
40
 
48
41
  class AbstractLogger:
49
42
 
50
- def __init__(self, level='TRACE'):
51
- self._is_logged = IsLogged(level)
52
-
53
- def set_level(self, level):
54
- return self._is_logged.set_level(level)
55
-
56
43
  def trace(self, msg):
57
44
  self.write(msg, 'TRACE')
58
45
 
@@ -90,9 +77,22 @@ class AbstractLogger:
90
77
 
91
78
 
92
79
  class Message(BaseMessage):
80
+ """Represents message logged during execution.
81
+
82
+ Most messages are logged by libraries. They typically log strings, but
83
+ possible non-string items have been converted to strings already before
84
+ they end up here.
85
+
86
+ In addition to strings, Robot Framework itself logs also callables to make
87
+ constructing messages that are not typically needed lazy. Such messages are
88
+ resolved when they are accessed.
89
+
90
+ Listeners can remove messages by setting the `message` attribute to `None`.
91
+ These messages are not written to the output.xml at all.
92
+ """
93
93
  __slots__ = ['_message']
94
94
 
95
- def __init__(self, message: 'str|Callable[[], str]',
95
+ def __init__(self, message: 'str|None|Callable[[], str|None]' = '',
96
96
  level: 'MessageLevel|PseudoLevel' = 'INFO',
97
97
  html: bool = False,
98
98
  timestamp: 'datetime|str|None' = None):
@@ -110,45 +110,16 @@ class Message(BaseMessage):
110
110
  raise DataError(f"Invalid log level '{level}'.")
111
111
 
112
112
  @property
113
- def message(self) -> str:
113
+ def message(self) -> 'str|None':
114
114
  self.resolve_delayed_message()
115
115
  return self._message
116
116
 
117
117
  @message.setter
118
- def message(self, message: 'str|Callable[[], str]'):
119
- if not callable(message):
120
- if not isinstance(message, str):
121
- message = safe_str(message)
122
- if '\r\n' in message:
123
- message = message.replace('\r\n', '\n')
118
+ def message(self, message: 'str|None|Callable[[], str|None]'):
119
+ if isinstance(message, str) and '\r\n' in message:
120
+ message = message.replace('\r\n', '\n')
124
121
  self._message = message
125
122
 
126
123
  def resolve_delayed_message(self):
127
124
  if callable(self._message):
128
- self._message = self._message()
129
-
130
-
131
- class IsLogged:
132
-
133
- def __init__(self, level):
134
- self.level = level.upper()
135
- self._int_level = self._level_to_int(level)
136
-
137
- def __call__(self, level):
138
- return self._level_to_int(level) >= self._int_level
139
-
140
- def set_level(self, level):
141
- old = self.level
142
- self.__init__(level)
143
- return old
144
-
145
- @classmethod
146
- def validate_level(cls, level):
147
- cls._level_to_int(level)
148
-
149
- @classmethod
150
- def _level_to_int(cls, level):
151
- try:
152
- return LEVELS[level.upper()]
153
- except KeyError:
154
- raise DataError("Invalid log level '%s'." % level)
125
+ self.message = self._message()
@@ -0,0 +1,54 @@
1
+ # Copyright 2008-2015 Nokia Networks
2
+ # Copyright 2016- Robot Framework Foundation
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ from typing import TYPE_CHECKING
17
+
18
+ from robot.errors import DataError
19
+
20
+ if TYPE_CHECKING:
21
+ from .loggerhelper import Message
22
+
23
+
24
+ LEVELS = {
25
+ 'NONE' : 7,
26
+ 'SKIP' : 6,
27
+ 'FAIL' : 5,
28
+ 'ERROR' : 4,
29
+ 'WARN' : 3,
30
+ 'INFO' : 2,
31
+ 'DEBUG' : 1,
32
+ 'TRACE' : 0,
33
+ }
34
+
35
+
36
+ class LogLevel:
37
+
38
+ def __init__(self, level):
39
+ self.priority = self._get_priority(level)
40
+ self.level = level.upper()
41
+
42
+ def is_logged(self, msg: 'Message'):
43
+ return LEVELS[msg.level] >= self.priority and msg.message is not None
44
+
45
+ def set(self, level):
46
+ old = self.level
47
+ self.__init__(level)
48
+ return old
49
+
50
+ def _get_priority(self, level):
51
+ try:
52
+ return LEVELS[level.upper()]
53
+ except KeyError:
54
+ raise DataError(f"Invalid log level '{level}'.")
@@ -18,19 +18,19 @@ from .debugfile import DebugFile
18
18
  from .listeners import Listeners, LibraryListeners
19
19
  from .logger import LOGGER
20
20
  from .loggerapi import LoggerApi
21
- from .loggerhelper import AbstractLogger, IsLogged
22
- from .xmllogger import XmlLoggerAdapter
21
+ from .loggerhelper import AbstractLogger
22
+ from .loglevel import LogLevel
23
+ from .outputfile import OutputFile
23
24
 
24
25
 
25
26
  class Output(AbstractLogger, LoggerApi):
26
27
 
27
28
  def __init__(self, settings):
28
- AbstractLogger.__init__(self)
29
- self._xml_logger = XmlLoggerAdapter(settings.output, settings.log_level,
30
- settings.rpa,
31
- legacy_output=settings.legacy_output)
32
- self.listeners = Listeners(settings.listeners, settings.log_level)
33
- self.library_listeners = LibraryListeners(settings.log_level)
29
+ self.log_level = LogLevel(settings.log_level)
30
+ self.output_file = OutputFile(settings.output, self.log_level, settings.rpa,
31
+ legacy_output=settings.legacy_output)
32
+ self.listeners = Listeners(settings.listeners, self.log_level)
33
+ self.library_listeners = LibraryListeners(self.log_level)
34
34
  self._register_loggers(DebugFile(settings.debug_file))
35
35
  self._settings = settings
36
36
 
@@ -39,7 +39,7 @@ class Output(AbstractLogger, LoggerApi):
39
39
  return self._settings.log_level
40
40
 
41
41
  def _register_loggers(self, debug_file):
42
- LOGGER.register_xml_logger(self._xml_logger)
42
+ LOGGER.register_output_file(self.output_file)
43
43
  LOGGER.register_listeners(self.listeners or None, self.library_listeners)
44
44
  if debug_file:
45
45
  LOGGER.register_logger(debug_file)
@@ -52,9 +52,9 @@ class Output(AbstractLogger, LoggerApi):
52
52
  return LOGGER.delayed_logging
53
53
 
54
54
  def close(self, result):
55
- self._xml_logger.logger.visit_statistics(result.statistics)
56
- self._xml_logger.close()
57
- LOGGER.unregister_xml_logger()
55
+ self.output_file.statistics(result.statistics)
56
+ self.output_file.close()
57
+ LOGGER.unregister_output_file()
58
58
  LOGGER.output_file(self._settings['Output'])
59
59
 
60
60
  def start_suite(self, data, result):
@@ -117,6 +117,12 @@ class Output(AbstractLogger, LoggerApi):
117
117
  def end_while_iteration(self, data, result):
118
118
  LOGGER.end_while_iteration(data, result)
119
119
 
120
+ def start_group(self, data, result):
121
+ LOGGER.start_group(data, result)
122
+
123
+ def end_group(self, data, result):
124
+ LOGGER.end_group(data, result)
125
+
120
126
  def start_if(self, data, result):
121
127
  LOGGER.start_if(data, result)
122
128
 
@@ -175,12 +181,10 @@ class Output(AbstractLogger, LoggerApi):
175
181
  LOGGER.log_message(msg)
176
182
 
177
183
  def trace(self, msg, write_if_flat=True):
178
- if write_if_flat or not self._xml_logger.flatten_level:
184
+ if write_if_flat or not self.output_file.flatten_level:
179
185
  self.write(msg, 'TRACE')
180
186
 
181
187
  def set_log_level(self, level):
182
- IsLogged.validate_level(level)
188
+ old = self.log_level.set(level)
183
189
  pyloggingconf.set_level(level)
184
- self.listeners.set_log_level(level)
185
- self.library_listeners.set_log_level(level)
186
- return self._xml_logger.set_log_level(level)
190
+ return old