robotframework 6.1rc1__zip → 7.0__zip

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (307) hide show
  1. {robotframework-6.1rc1 → robotframework-7.0}/INSTALL.rst +25 -25
  2. {robotframework-6.1rc1 → robotframework-7.0}/PKG-INFO +6 -8
  3. {robotframework-6.1rc1 → robotframework-7.0}/README.rst +3 -2
  4. {robotframework-6.1rc1 → robotframework-7.0}/setup.py +3 -6
  5. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/api/__init__.py +4 -1
  6. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/api/deco.py +60 -14
  7. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/api/exceptions.py +6 -6
  8. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/api/interfaces.py +403 -68
  9. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/api/logger.py +27 -20
  10. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/api/parsing.py +4 -2
  11. robotframework-7.0/src/robot/api/py.typed +0 -0
  12. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/conf/gatherfailed.py +2 -2
  13. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/conf/languages.py +61 -25
  14. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/conf/settings.py +21 -14
  15. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/common/storage.js +11 -6
  16. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/htmlfilewriter.py +1 -1
  17. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/libdoc/libdoc.css +10 -2
  18. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/libdoc/libdoc.html +10 -0
  19. robotframework-7.0/src/robot/htmldata/rebot/common.css +362 -0
  20. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/doc_formatting.css +13 -7
  21. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/log.css +51 -10
  22. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/log.html +14 -23
  23. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/model.js +2 -4
  24. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/report.css +83 -19
  25. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/report.html +22 -7
  26. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/testdata.js +10 -3
  27. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/view.js +84 -0
  28. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/template.py +3 -3
  29. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/builder.py +0 -8
  30. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/datatypes.py +9 -10
  31. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/htmlutils.py +4 -7
  32. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/jsonbuilder.py +38 -20
  33. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/model.py +21 -28
  34. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/robotbuilder.py +50 -31
  35. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/standardtypes.py +9 -1
  36. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/xmlbuilder.py +35 -20
  37. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/xmlwriter.py +18 -38
  38. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/BuiltIn.py +255 -205
  39. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/Collections.py +384 -240
  40. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/DateTime.py +73 -60
  41. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/OperatingSystem.py +6 -5
  42. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/Process.py +26 -27
  43. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/Remote.py +40 -36
  44. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/String.py +66 -76
  45. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/XML.py +66 -59
  46. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/__init__.py +2 -2
  47. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/dialogs_py.py +14 -2
  48. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/__init__.py +5 -5
  49. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/body.py +44 -13
  50. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/configurer.py +19 -15
  51. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/control.py +230 -88
  52. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/filter.py +31 -25
  53. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/itemlist.py +9 -8
  54. robotframework-7.0/src/robot/model/keyword.py +77 -0
  55. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/message.py +19 -10
  56. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/modelobject.py +27 -15
  57. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/modifier.py +1 -1
  58. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/namepatterns.py +3 -25
  59. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/stats.py +9 -15
  60. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/tags.py +1 -1
  61. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/testcase.py +15 -27
  62. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/testsuite.py +44 -28
  63. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/visitor.py +35 -8
  64. robotframework-7.0/src/robot/output/console/dotted.py +90 -0
  65. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/output/console/quiet.py +3 -2
  66. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/output/console/verbose.py +61 -61
  67. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/output/debugfile.py +39 -24
  68. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/output/filelogger.py +18 -15
  69. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/output/librarylogger.py +3 -2
  70. robotframework-7.0/src/robot/output/listeners.py +753 -0
  71. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/output/logger.py +216 -80
  72. robotframework-7.0/src/robot/output/loggerapi.py +215 -0
  73. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/output/loggerhelper.py +23 -56
  74. robotframework-7.0/src/robot/output/output.py +185 -0
  75. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/output/stdoutlogsplitter.py +8 -5
  76. robotframework-7.0/src/robot/output/xmllogger.py +459 -0
  77. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/lexer/blocklexers.py +17 -13
  78. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/lexer/context.py +12 -2
  79. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/lexer/lexer.py +1 -1
  80. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/lexer/settings.py +6 -3
  81. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/lexer/statementlexers.py +39 -10
  82. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/lexer/tokens.py +27 -29
  83. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/model/blocks.py +19 -6
  84. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/model/statements.py +193 -94
  85. robotframework-7.0/src/robot/parsing/model/visitor.py +100 -0
  86. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/rebot.py +2 -0
  87. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/reporting/expandkeywordmatcher.py +1 -1
  88. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/reporting/jsbuildingcontext.py +8 -6
  89. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/reporting/jsmodelbuilders.py +88 -61
  90. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/reporting/logreportwriters.py +16 -10
  91. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/reporting/outputwriter.py +18 -2
  92. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/reporting/resultwriter.py +4 -4
  93. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/reporting/stringcache.py +3 -3
  94. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/reporting/xunitwriter.py +15 -21
  95. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/result/__init__.py +3 -2
  96. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/result/configurer.py +12 -9
  97. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/result/executionresult.py +56 -8
  98. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/result/flattenkeywordmatcher.py +48 -9
  99. robotframework-7.0/src/robot/result/keywordremover.py +207 -0
  100. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/result/merger.py +1 -1
  101. robotframework-7.0/src/robot/result/model.py +1185 -0
  102. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/result/modeldeprecation.py +9 -3
  103. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/result/resultbuilder.py +46 -36
  104. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/result/xmlelementhandlers.py +83 -43
  105. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/run.py +3 -1
  106. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/__init__.py +14 -4
  107. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/arguments/__init__.py +2 -1
  108. robotframework-7.0/src/robot/running/arguments/argumentconverter.py +100 -0
  109. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/arguments/argumentmapper.py +26 -24
  110. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/arguments/argumentparser.py +85 -61
  111. robotframework-7.0/src/robot/running/arguments/argumentresolver.py +158 -0
  112. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/arguments/argumentspec.py +83 -116
  113. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/arguments/argumentvalidator.py +33 -27
  114. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/arguments/customconverters.py +15 -12
  115. robotframework-7.0/src/robot/running/arguments/embedded.py +145 -0
  116. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/arguments/typeconverters.py +268 -220
  117. robotframework-7.0/src/robot/running/arguments/typeinfo.py +317 -0
  118. robotframework-7.0/src/robot/running/arguments/typeinfoparser.py +219 -0
  119. robotframework-7.0/src/robot/running/arguments/typevalidator.py +60 -0
  120. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/bodyrunner.py +147 -129
  121. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/builder/builders.py +17 -26
  122. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/builder/parsers.py +17 -11
  123. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/builder/settings.py +9 -17
  124. robotframework-7.0/src/robot/running/builder/transformers.py +535 -0
  125. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/context.py +113 -31
  126. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/dynamicmethods.py +62 -34
  127. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/importer.py +27 -49
  128. robotframework-7.0/src/robot/running/invalidkeyword.py +67 -0
  129. robotframework-7.0/src/robot/running/keywordfinder.py +91 -0
  130. robotframework-7.0/src/robot/running/keywordimplementation.py +164 -0
  131. robotframework-7.0/src/robot/running/librarykeyword.py +392 -0
  132. robotframework-7.0/src/robot/running/librarykeywordrunner.py +250 -0
  133. robotframework-7.0/src/robot/running/libraryscopes.py +115 -0
  134. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/model.py +198 -337
  135. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/namespace.py +124 -137
  136. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/outputcapture.py +20 -12
  137. robotframework-7.0/src/robot/running/resourcemodel.py +448 -0
  138. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/statusreporter.py +16 -13
  139. robotframework-7.0/src/robot/running/suiterunner.py +265 -0
  140. robotframework-7.0/src/robot/running/testlibraries.py +500 -0
  141. robotframework-7.0/src/robot/running/userkeywordrunner.py +260 -0
  142. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/testdoc.py +18 -13
  143. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/__init__.py +53 -35
  144. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/connectioncache.py +64 -59
  145. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/dotdict.py +3 -0
  146. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/encodingsniffer.py +9 -4
  147. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/escaping.py +19 -19
  148. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/importer.py +2 -2
  149. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/markupwriters.py +23 -15
  150. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/misc.py +1 -2
  151. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/normalizing.py +9 -24
  152. robotframework-7.0/src/robot/utils/notset.py +33 -0
  153. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/platform.py +15 -5
  154. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/robotio.py +9 -9
  155. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/robotpath.py +1 -0
  156. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/robottime.py +122 -90
  157. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/robottypes.py +21 -31
  158. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/setter.py +0 -5
  159. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/text.py +7 -4
  160. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/unic.py +2 -2
  161. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/variables/__init__.py +2 -2
  162. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/variables/assigner.py +17 -19
  163. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/variables/evaluation.py +20 -17
  164. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/variables/filesetter.py +80 -80
  165. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/variables/replacer.py +33 -36
  166. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/variables/scopes.py +17 -12
  167. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/variables/search.py +66 -41
  168. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/variables/store.py +14 -16
  169. robotframework-7.0/src/robot/variables/tablesetter.py +164 -0
  170. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/variables/variables.py +1 -1
  171. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/version.py +1 -1
  172. {robotframework-6.1rc1 → robotframework-7.0}/src/robotframework.egg-info/PKG-INFO +6 -8
  173. {robotframework-6.1rc1 → robotframework-7.0}/src/robotframework.egg-info/SOURCES.txt +10 -8
  174. {robotframework-6.1rc1 → robotframework-7.0}/tasks.py +6 -6
  175. robotframework-6.1rc1/src/robot/htmldata/rebot/common.css +0 -239
  176. robotframework-6.1rc1/src/robot/libraries/Reserved.py +0 -48
  177. robotframework-6.1rc1/src/robot/model/keyword.py +0 -173
  178. robotframework-6.1rc1/src/robot/output/console/dotted.py +0 -90
  179. robotframework-6.1rc1/src/robot/output/listenerarguments.py +0 -165
  180. robotframework-6.1rc1/src/robot/output/listenermethods.py +0 -113
  181. robotframework-6.1rc1/src/robot/output/listeners.py +0 -174
  182. robotframework-6.1rc1/src/robot/output/output.py +0 -95
  183. robotframework-6.1rc1/src/robot/output/xmllogger.py +0 -354
  184. robotframework-6.1rc1/src/robot/parsing/model/visitor.py +0 -67
  185. robotframework-6.1rc1/src/robot/result/keywordremover.py +0 -183
  186. robotframework-6.1rc1/src/robot/result/model.py +0 -957
  187. robotframework-6.1rc1/src/robot/running/arguments/argumentconverter.py +0 -79
  188. robotframework-6.1rc1/src/robot/running/arguments/argumentresolver.py +0 -131
  189. robotframework-6.1rc1/src/robot/running/arguments/embedded.py +0 -146
  190. robotframework-6.1rc1/src/robot/running/arguments/typevalidator.py +0 -56
  191. robotframework-6.1rc1/src/robot/running/builder/transformers.py +0 -642
  192. robotframework-6.1rc1/src/robot/running/handlers.py +0 -321
  193. robotframework-6.1rc1/src/robot/running/handlerstore.py +0 -66
  194. robotframework-6.1rc1/src/robot/running/librarykeywordrunner.py +0 -238
  195. robotframework-6.1rc1/src/robot/running/libraryscopes.py +0 -97
  196. robotframework-6.1rc1/src/robot/running/modelcombiner.py +0 -32
  197. robotframework-6.1rc1/src/robot/running/suiterunner.py +0 -249
  198. robotframework-6.1rc1/src/robot/running/testlibraries.py +0 -420
  199. robotframework-6.1rc1/src/robot/running/usererrorhandler.py +0 -75
  200. robotframework-6.1rc1/src/robot/running/userkeyword.py +0 -111
  201. robotframework-6.1rc1/src/robot/running/userkeywordrunner.py +0 -274
  202. robotframework-6.1rc1/src/robot/variables/tablesetter.py +0 -156
  203. {robotframework-6.1rc1 → robotframework-7.0}/AUTHORS.rst +0 -0
  204. {robotframework-6.1rc1 → robotframework-7.0}/BUILD.rst +0 -0
  205. {robotframework-6.1rc1 → robotframework-7.0}/CONTRIBUTING.rst +0 -0
  206. {robotframework-6.1rc1 → robotframework-7.0}/COPYRIGHT.txt +0 -0
  207. {robotframework-6.1rc1 → robotframework-7.0}/LICENSE.txt +0 -0
  208. {robotframework-6.1rc1 → robotframework-7.0}/MANIFEST.in +0 -0
  209. {robotframework-6.1rc1 → robotframework-7.0}/setup.cfg +0 -0
  210. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/__init__.py +0 -0
  211. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/__main__.py +0 -0
  212. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/conf/__init__.py +0 -0
  213. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/errors.py +0 -0
  214. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/__init__.py +0 -0
  215. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/common/__init__.py +0 -0
  216. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/common/js_disabled.css +0 -0
  217. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/jsonwriter.py +0 -0
  218. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/lib/__init__.py +0 -0
  219. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/lib/jquery.highlight.min.js +0 -0
  220. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/lib/jquery.min.js +0 -0
  221. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/lib/jquery.tablesorter.min.js +0 -0
  222. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/lib/jquery.tmpl.min.js +0 -0
  223. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/lib/jsxcompressor.min.js +0 -0
  224. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/libdoc/__init__.py +0 -0
  225. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/libdoc/doc_formatting.css +0 -0
  226. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/libdoc/print.css +0 -0
  227. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/libdoc/pygments.css +0 -0
  228. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/__init__.py +0 -0
  229. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/fileloading.js +0 -0
  230. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/log.js +0 -0
  231. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/print.css +0 -0
  232. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/util.js +0 -0
  233. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/testdoc/__init__.py +0 -0
  234. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/testdoc/testdoc.css +0 -0
  235. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/testdoc/testdoc.html +0 -0
  236. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdoc.py +0 -0
  237. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/__init__.py +0 -0
  238. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/consoleviewer.py +0 -0
  239. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/htmlwriter.py +0 -0
  240. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/jsonwriter.py +0 -0
  241. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/output.py +0 -0
  242. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/writer.py +0 -0
  243. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/Dialogs.py +0 -0
  244. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/Easter.py +0 -0
  245. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/Screenshot.py +0 -0
  246. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/Telnet.py +0 -0
  247. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/fixture.py +0 -0
  248. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/metadata.py +0 -0
  249. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/statistics.py +0 -0
  250. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/suitestatistics.py +0 -0
  251. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/tagsetter.py +0 -0
  252. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/tagstatistics.py +0 -0
  253. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/totalstatistics.py +0 -0
  254. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/output/__init__.py +0 -0
  255. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/output/console/__init__.py +0 -0
  256. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/output/console/highlighting.py +0 -0
  257. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/output/pyloggingconf.py +0 -0
  258. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/__init__.py +0 -0
  259. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/lexer/__init__.py +0 -0
  260. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/lexer/tokenizer.py +0 -0
  261. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/model/__init__.py +0 -0
  262. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/parser/__init__.py +0 -0
  263. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/parser/blockparsers.py +0 -0
  264. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/parser/fileparser.py +0 -0
  265. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/parser/parser.py +0 -0
  266. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/suitestructure.py +0 -0
  267. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/pythonpathsetter.py +0 -0
  268. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/reporting/__init__.py +0 -0
  269. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/reporting/jsexecutionresult.py +0 -0
  270. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/reporting/jswriter.py +0 -0
  271. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/result/executionerrors.py +0 -0
  272. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/result/messagefilter.py +0 -0
  273. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/result/suiteteardownfailed.py +0 -0
  274. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/result/visitor.py +0 -0
  275. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/builder/__init__.py +0 -0
  276. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/randomizer.py +0 -0
  277. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/runkwregister.py +0 -0
  278. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/signalhandler.py +0 -0
  279. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/status.py +0 -0
  280. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/timeouts/__init__.py +0 -0
  281. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/timeouts/posix.py +0 -0
  282. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/timeouts/windows.py +0 -0
  283. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/application.py +0 -0
  284. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/argumentparser.py +0 -0
  285. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/asserts.py +0 -0
  286. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/charwidth.py +0 -0
  287. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/compress.py +0 -0
  288. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/encoding.py +0 -0
  289. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/error.py +0 -0
  290. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/etreewrapper.py +0 -0
  291. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/filereader.py +0 -0
  292. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/frange.py +0 -0
  293. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/htmlformatters.py +0 -0
  294. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/markuputils.py +0 -0
  295. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/match.py +0 -0
  296. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/recommendations.py +0 -0
  297. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/restreader.py +0 -0
  298. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/robotenv.py +0 -0
  299. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/robotinspect.py +0 -0
  300. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/sortable.py +0 -0
  301. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/typehints.py +0 -0
  302. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/variables/finders.py +0 -0
  303. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/variables/notfound.py +0 -0
  304. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/variables/resolvable.py +0 -0
  305. {robotframework-6.1rc1 → robotframework-7.0}/src/robotframework.egg-info/dependency_links.txt +0 -0
  306. {robotframework-6.1rc1 → robotframework-7.0}/src/robotframework.egg-info/entry_points.txt +0 -0
  307. {robotframework-6.1rc1 → robotframework-7.0}/src/robotframework.egg-info/top_level.txt +0 -0
@@ -0,0 +1,753 @@
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
+ import os.path
17
+ from abc import ABC
18
+ from pathlib import Path
19
+
20
+ from robot.errors import DataError, TimeoutError
21
+ from robot.model import BodyItem
22
+ from robot.utils import (get_error_details, Importer, safe_str,
23
+ split_args_from_name_or_path, type_name)
24
+
25
+ from .loggerapi import LoggerApi
26
+ from .loggerhelper import IsLogged
27
+ from .logger import LOGGER
28
+
29
+
30
+ class Listeners(LoggerApi):
31
+ _listeners: 'list[ListenerFacade]'
32
+
33
+ def __init__(self, listeners=(), log_level='INFO'):
34
+ self._is_logged = IsLogged(log_level)
35
+ self._listeners = self._import_listeners(listeners)
36
+
37
+ def _import_listeners(self, listeners, library=None) -> 'list[ListenerFacade]':
38
+ imported = []
39
+ for listener_source in listeners:
40
+ try:
41
+ listener = self._import_listener(listener_source, library)
42
+ except DataError as err:
43
+ name = listener_source \
44
+ if isinstance(listener_source, str) else type_name(listener_source)
45
+ msg = f"Taking listener '{name}' into use failed: {err}"
46
+ if library:
47
+ raise DataError(msg)
48
+ LOGGER.error(msg)
49
+ else:
50
+ imported.append(listener)
51
+ return imported
52
+
53
+ def _import_listener(self, listener, library=None) -> 'ListenerFacade':
54
+ if library and isinstance(listener, str) and listener.upper() == 'SELF':
55
+ listener = library.instance
56
+ if isinstance(listener, str):
57
+ name, args = split_args_from_name_or_path(listener)
58
+ importer = Importer('listener', logger=LOGGER)
59
+ listener = importer.import_class_or_module(os.path.normpath(name),
60
+ instantiate_with_args=args)
61
+ else:
62
+ # Modules have `__name__`, with others better to use `type_name`.
63
+ name = getattr(listener, '__name__', None) or type_name(listener)
64
+ if self._get_version(listener) == 2:
65
+ return ListenerV2Facade(listener, name, library)
66
+ return ListenerV3Facade(listener, name, library)
67
+
68
+ def _get_version(self, listener):
69
+ version = getattr(listener, 'ROBOT_LISTENER_API_VERSION', 3)
70
+ try:
71
+ version = int(version)
72
+ if version not in (2, 3):
73
+ raise ValueError
74
+ except (ValueError, TypeError):
75
+ raise DataError(f"Unsupported API version '{version}'.")
76
+ return version
77
+
78
+ # Must be property to allow LibraryListeners to override it.
79
+ @property
80
+ def listeners(self):
81
+ return self._listeners
82
+
83
+ def start_suite(self, data, result):
84
+ for listener in self.listeners:
85
+ listener.start_suite(data, result)
86
+
87
+ def end_suite(self, data, result):
88
+ for listener in self.listeners:
89
+ listener.end_suite(data, result)
90
+
91
+ def start_test(self, data, result):
92
+ for listener in self.listeners:
93
+ listener.start_test(data, result)
94
+
95
+ def end_test(self, data, result):
96
+ for listener in self.listeners:
97
+ listener.end_test(data, result)
98
+
99
+ def start_keyword(self, data, result):
100
+ for listener in self.listeners:
101
+ listener.start_keyword(data, result)
102
+
103
+ def end_keyword(self, data, result):
104
+ for listener in self.listeners:
105
+ listener.end_keyword(data, result)
106
+
107
+ def start_user_keyword(self, data, implementation, result):
108
+ for listener in self.listeners:
109
+ listener.start_user_keyword(data, implementation, result)
110
+
111
+ def end_user_keyword(self, data, implementation, result):
112
+ for listener in self.listeners:
113
+ listener.end_user_keyword(data, implementation, result)
114
+
115
+ def start_library_keyword(self, data, implementation, result):
116
+ for listener in self.listeners:
117
+ listener.start_library_keyword(data, implementation, result)
118
+
119
+ def end_library_keyword(self, data, implementation, result):
120
+ for listener in self.listeners:
121
+ listener.end_library_keyword(data, implementation, result)
122
+
123
+ def start_invalid_keyword(self, data, implementation, result):
124
+ for listener in self.listeners:
125
+ listener.start_invalid_keyword(data, implementation, result)
126
+
127
+ def end_invalid_keyword(self, data, implementation, result):
128
+ for listener in self.listeners:
129
+ listener.end_invalid_keyword(data, implementation, result)
130
+
131
+ def start_for(self, data, result):
132
+ for listener in self.listeners:
133
+ listener.start_for(data, result)
134
+
135
+ def end_for(self, data, result):
136
+ for listener in self.listeners:
137
+ listener.end_for(data, result)
138
+
139
+ def start_for_iteration(self, data, result):
140
+ for listener in self.listeners:
141
+ listener.start_for_iteration(data, result)
142
+
143
+ def end_for_iteration(self, data, result):
144
+ for listener in self.listeners:
145
+ listener.end_for_iteration(data, result)
146
+
147
+ def start_while(self, data, result):
148
+ for listener in self.listeners:
149
+ listener.start_while(data, result)
150
+
151
+ def end_while(self, data, result):
152
+ for listener in self.listeners:
153
+ listener.end_while(data, result)
154
+
155
+ def start_while_iteration(self, data, result):
156
+ for listener in self.listeners:
157
+ listener.start_while_iteration(data, result)
158
+
159
+ def end_while_iteration(self, data, result):
160
+ for listener in self.listeners:
161
+ listener.end_while_iteration(data, result)
162
+
163
+ def start_if(self, data, result):
164
+ for listener in self.listeners:
165
+ listener.start_if(data, result)
166
+
167
+ def end_if(self, data, result):
168
+ for listener in self.listeners:
169
+ listener.end_if(data, result)
170
+
171
+ def start_if_branch(self, data, result):
172
+ for listener in self.listeners:
173
+ listener.start_if_branch(data, result)
174
+
175
+ def end_if_branch(self, data, result):
176
+ for listener in self.listeners:
177
+ listener.end_if_branch(data, result)
178
+
179
+ def start_try(self, data, result):
180
+ for listener in self.listeners:
181
+ listener.start_try(data, result)
182
+
183
+ def end_try(self, data, result):
184
+ for listener in self.listeners:
185
+ listener.end_try(data, result)
186
+
187
+ def start_try_branch(self, data, result):
188
+ for listener in self.listeners:
189
+ listener.start_try_branch(data, result)
190
+
191
+ def end_try_branch(self, data, result):
192
+ for listener in self.listeners:
193
+ listener.end_try_branch(data, result)
194
+
195
+ def start_return(self, data, result):
196
+ for listener in self.listeners:
197
+ listener.start_return(data, result)
198
+
199
+ def end_return(self, data, result):
200
+ for listener in self.listeners:
201
+ listener.end_return(data, result)
202
+
203
+ def start_continue(self, data, result):
204
+ for listener in self.listeners:
205
+ listener.start_continue(data, result)
206
+
207
+ def end_continue(self, data, result):
208
+ for listener in self.listeners:
209
+ listener.end_continue(data, result)
210
+
211
+ def start_break(self, data, result):
212
+ for listener in self.listeners:
213
+ listener.start_break(data, result)
214
+
215
+ def end_break(self, data, result):
216
+ for listener in self.listeners:
217
+ listener.end_break(data, result)
218
+
219
+ def start_error(self, data, result):
220
+ for listener in self.listeners:
221
+ listener.start_error(data, result)
222
+
223
+ def end_error(self, data, result):
224
+ for listener in self.listeners:
225
+ listener.end_error(data, result)
226
+
227
+ def start_var(self, data, result):
228
+ for listener in self.listeners:
229
+ listener.start_var(data, result)
230
+
231
+ def end_var(self, data, result):
232
+ for listener in self.listeners:
233
+ listener.end_var(data, result)
234
+
235
+ def set_log_level(self, level):
236
+ self._is_logged.set_level(level)
237
+
238
+ def log_message(self, message):
239
+ if self._is_logged(message.level):
240
+ for listener in self.listeners:
241
+ listener.log_message(message)
242
+
243
+ def message(self, message):
244
+ for listener in self.listeners:
245
+ listener.message(message)
246
+
247
+ def imported(self, import_type, name, attrs):
248
+ for listener in self.listeners:
249
+ listener.imported(import_type, name, attrs)
250
+
251
+ def output_file(self, path):
252
+ for listener in self.listeners:
253
+ listener.output_file(path)
254
+
255
+ def report_file(self, path):
256
+ for listener in self.listeners:
257
+ listener.report_file(path)
258
+
259
+ def log_file(self, path):
260
+ for listener in self.listeners:
261
+ listener.log_file(path)
262
+
263
+ def xunit_file(self, path):
264
+ for listener in self.listeners:
265
+ listener.xunit_file(path)
266
+
267
+ def debug_file(self, path):
268
+ for listener in self.listeners:
269
+ listener.debug_file(path)
270
+
271
+ def close(self):
272
+ for listener in self.listeners:
273
+ listener.close()
274
+
275
+ def __bool__(self):
276
+ return bool(self.listeners)
277
+
278
+
279
+ class LibraryListeners(Listeners):
280
+ _listeners: 'list[list[ListenerFacade]]'
281
+
282
+ def __init__(self, log_level='INFO'):
283
+ super().__init__(log_level=log_level)
284
+
285
+ @property
286
+ def listeners(self):
287
+ return self._listeners[-1] if self._listeners else []
288
+
289
+ def new_suite_scope(self):
290
+ self._listeners.append([])
291
+
292
+ def discard_suite_scope(self):
293
+ self._listeners.pop()
294
+
295
+ def register(self, library):
296
+ listeners = self._import_listeners(library.listeners, library=library)
297
+ self._listeners[-1].extend(listeners)
298
+
299
+ def close(self):
300
+ pass
301
+
302
+ def unregister(self, library, close=False):
303
+ remaining = []
304
+ for listener in self._listeners[-1]:
305
+ if listener.library is not library:
306
+ remaining.append(listener)
307
+ elif close:
308
+ listener.close()
309
+ self._listeners[-1] = remaining
310
+
311
+
312
+ class ListenerFacade(LoggerApi, ABC):
313
+
314
+ def __init__(self, listener, name, library=None):
315
+ self.listener = listener
316
+ self.name = name
317
+ self.library = library
318
+
319
+ def _get_method(self, name, fallback=None):
320
+ for method_name in self._get_method_names(name):
321
+ method = getattr(self.listener, method_name, None)
322
+ if method:
323
+ return ListenerMethod(method, self.name)
324
+ return ListenerMethod(None, self.name) if fallback is None else fallback
325
+
326
+ def _get_method_names(self, name):
327
+ names = [name, self._to_camelCase(name)] if '_' in name else [name]
328
+ if self.library is not None:
329
+ names += ['_' + name for name in names]
330
+ return names
331
+
332
+ def _to_camelCase(self, name):
333
+ first, *rest = name.split('_')
334
+ return ''.join([first] + [part.capitalize() for part in rest])
335
+
336
+
337
+ class ListenerV3Facade(ListenerFacade):
338
+
339
+ def __init__(self, listener, name, library=None):
340
+ super().__init__(listener, name, library)
341
+ get = self._get_method
342
+ # Suite
343
+ self.start_suite = get('start_suite')
344
+ self.end_suite = get('end_suite')
345
+ # Test
346
+ self.start_test = get('start_test')
347
+ self.end_test = get('end_test')
348
+ # Fallbacks for body items
349
+ start_body_item = self._get_method('start_body_item')
350
+ end_body_item = self._get_method('end_body_item')
351
+ # Keywords
352
+ self.start_keyword = get('start_keyword', start_body_item)
353
+ self.end_keyword = get('end_keyword', end_body_item)
354
+ self._start_user_keyword = get('start_user_keyword')
355
+ self._end_user_keyword = get('end_user_keyword')
356
+ self._start_library_keyword = get('start_library_keyword')
357
+ self._end_library_keyword = get('end_library_keyword')
358
+ self._start_invalid_keyword = get('start_invalid_keyword')
359
+ self._end_invalid_keyword = get('end_invalid_keyword')
360
+ # IF
361
+ self.start_if = get('start_if', start_body_item)
362
+ self.end_if = get('end_if', end_body_item)
363
+ self.start_if_branch = get('start_if_branch', start_body_item)
364
+ self.end_if_branch = get('end_if_branch', end_body_item)
365
+ # TRY
366
+ self.start_try = get('start_try', start_body_item)
367
+ self.end_try = get('end_try', end_body_item)
368
+ self.start_try_branch = get('start_try_branch', start_body_item)
369
+ self.end_try_branch = get('end_try_branch', end_body_item)
370
+ # FOR
371
+ self.start_for = get('start_for', start_body_item)
372
+ self.end_for = get('end_for', end_body_item)
373
+ self.start_for_iteration = get('start_for_iteration', start_body_item)
374
+ self.end_for_iteration = get('end_for_iteration', end_body_item)
375
+ # WHILE
376
+ self.start_while = get('start_while', start_body_item)
377
+ self.end_while = get('end_while', end_body_item)
378
+ self.start_while_iteration = get('start_while_iteration', start_body_item)
379
+ self.end_while_iteration = get('end_while_iteration', end_body_item)
380
+ # VAR
381
+ self.start_var = get('start_var', start_body_item)
382
+ self.end_var = get('end_var', end_body_item)
383
+ # BREAK
384
+ self.start_break = get('start_break', start_body_item)
385
+ self.end_break = get('end_break', end_body_item)
386
+ # CONTINUE
387
+ self.start_continue = get('start_continue', start_body_item)
388
+ self.end_continue = get('end_continue', end_body_item)
389
+ # RETURN
390
+ self.start_return = get('start_return', start_body_item)
391
+ self.end_return = get('end_return', end_body_item)
392
+ # ERROR
393
+ self.start_error = get('start_error', start_body_item)
394
+ self.end_error = get('end_error', end_body_item)
395
+ # Messages
396
+ self.log_message = get('log_message')
397
+ self.message = get('message')
398
+ # Result files
399
+ self.output_file = self._get_method('output_file')
400
+ self.report_file = self._get_method('report_file')
401
+ self.log_file = self._get_method('log_file')
402
+ self.xunit_file = self._get_method('xunit_file')
403
+ self.debug_file = self._get_method('debug_file')
404
+ # Close
405
+ self.close = get('close')
406
+
407
+ def start_user_keyword(self, data, implementation, result):
408
+ if self._start_user_keyword:
409
+ self._start_user_keyword(data, implementation, result)
410
+ else:
411
+ self.start_keyword(data, result)
412
+
413
+ def end_user_keyword(self, data, implementation, result):
414
+ if self._end_user_keyword:
415
+ self._end_user_keyword(data, implementation, result)
416
+ else:
417
+ self.end_keyword(data, result)
418
+
419
+ def start_library_keyword(self, data, implementation, result):
420
+ if self._start_library_keyword:
421
+ self._start_library_keyword(data, implementation, result)
422
+ else:
423
+ self.start_keyword(data, result)
424
+
425
+ def end_library_keyword(self, data, implementation, result):
426
+ if self._end_library_keyword:
427
+ self._end_library_keyword(data, implementation, result)
428
+ else:
429
+ self.end_keyword(data, result)
430
+
431
+ def start_invalid_keyword(self, data, implementation, result):
432
+ if self._start_invalid_keyword:
433
+ self._start_invalid_keyword(data, implementation, result)
434
+ else:
435
+ self.start_keyword(data, result)
436
+
437
+ def end_invalid_keyword(self, data, implementation, result):
438
+ if self._end_invalid_keyword:
439
+ self._end_invalid_keyword(data, implementation, result)
440
+ else:
441
+ self.end_keyword(data, result)
442
+
443
+
444
+ class ListenerV2Facade(ListenerFacade):
445
+
446
+ def __init__(self, listener, name, library=None):
447
+ super().__init__(listener, name, library)
448
+ # Suite
449
+ self._start_suite = self._get_method('start_suite')
450
+ self._end_suite = self._get_method('end_suite')
451
+ # Test
452
+ self._start_test = self._get_method('start_test')
453
+ self._end_test = self._get_method('end_test')
454
+ # Keyword and control structures
455
+ self._start_kw = self._get_method('start_keyword')
456
+ self._end_kw = self._get_method('end_keyword')
457
+ # Messages
458
+ self._log_message = self._get_method('log_message')
459
+ self._message = self._get_method('message')
460
+ # Result files
461
+ self._output_file = self._get_method('output_file')
462
+ self._report_file = self._get_method('report_file')
463
+ self._log_file = self._get_method('log_file')
464
+ self._xunit_file = self._get_method('xunit_file')
465
+ self._debug_file = self._get_method('debug_file')
466
+ # Close
467
+ self._close = self._get_method('close')
468
+
469
+ def imported(self, import_type: str, name: str, attrs):
470
+ method = self._get_method(f'{import_type.lower()}_import')
471
+ method(name, attrs)
472
+
473
+ def start_suite(self, data, result):
474
+ self._start_suite(result.name, self._suite_attrs(data, result))
475
+
476
+ def end_suite(self, data, result):
477
+ self._end_suite(result.name, self._suite_attrs(data, result, end=True))
478
+
479
+ def start_test(self, data, result):
480
+ self._start_test(result.name, self._test_attrs(data, result))
481
+
482
+ def end_test(self, data, result):
483
+ self._end_test(result.name, self._test_attrs(data, result, end=True))
484
+
485
+ def start_keyword(self, data, result):
486
+ self._start_kw(result.full_name, self._keyword_attrs(data, result))
487
+
488
+ def end_keyword(self, data, result):
489
+ self._end_kw(result.full_name, self._keyword_attrs(data, result, end=True))
490
+
491
+ def start_for(self, data, result):
492
+ extra = self._for_extra_attrs(result)
493
+ self._start_kw(result._log_name, self._attrs(data, result, **extra))
494
+
495
+ def end_for(self, data, result):
496
+ extra = self._for_extra_attrs(result)
497
+ self._end_kw(result._log_name, self._attrs(data, result, **extra, end=True))
498
+
499
+ def _for_extra_attrs(self, result):
500
+ extra = {
501
+ 'variables': list(result.assign),
502
+ 'flavor': result.flavor or '',
503
+ 'values': list(result.values)
504
+ }
505
+ if result.flavor == 'IN ENUMERATE':
506
+ extra['start'] = result.start
507
+ elif result.flavor == 'IN ZIP':
508
+ extra['fill'] = result.fill
509
+ extra['mode'] = result.mode
510
+ return extra
511
+
512
+ def start_for_iteration(self, data, result):
513
+ attrs = self._attrs(data, result, variables=dict(result.assign))
514
+ self._start_kw(result._log_name, attrs)
515
+
516
+ def end_for_iteration(self, data, result):
517
+ attrs = self._attrs(data, result, variables=dict(result.assign), end=True)
518
+ self._end_kw(result._log_name, attrs)
519
+
520
+ def start_while(self, data, result):
521
+ attrs = self._attrs(data, result, condition=result.condition,
522
+ limit=result.limit, on_limit=result.on_limit,
523
+ on_limit_message=result.on_limit_message)
524
+ self._start_kw(result._log_name, attrs)
525
+
526
+ def end_while(self, data, result):
527
+ attrs = self._attrs(data, result, condition=result.condition,
528
+ limit=result.limit, on_limit=result.on_limit,
529
+ on_limit_message=result.on_limit_message, end=True)
530
+ self._end_kw(result._log_name, attrs)
531
+
532
+ def start_while_iteration(self, data, result):
533
+ self._start_kw(result._log_name, self._attrs(data, result))
534
+
535
+ def end_while_iteration(self, data, result):
536
+ self._end_kw(result._log_name, self._attrs(data, result, end=True))
537
+
538
+ def start_if_branch(self, data, result):
539
+ extra = {'condition': result.condition} if result.type != result.ELSE else {}
540
+ self._start_kw(result._log_name, self._attrs(data, result, **extra))
541
+
542
+ def end_if_branch(self, data, result):
543
+ extra = {'condition': result.condition} if result.type != result.ELSE else {}
544
+ self._end_kw(result._log_name, self._attrs(data, result, **extra, end=True))
545
+
546
+ def start_try_branch(self, data, result):
547
+ extra = self._try_extra_attrs(result)
548
+ self._start_kw(result._log_name, self._attrs(data, result, **extra))
549
+
550
+ def end_try_branch(self, data, result):
551
+ extra = self._try_extra_attrs(result)
552
+ self._end_kw(result._log_name, self._attrs(data, result, **extra, end=True))
553
+
554
+ def _try_extra_attrs(self, result):
555
+ if result.type == BodyItem.EXCEPT:
556
+ return {
557
+ 'patterns': list(result.patterns),
558
+ 'pattern_type': result.pattern_type,
559
+ 'variable': result.assign
560
+ }
561
+ return {}
562
+
563
+ def start_return(self, data, result):
564
+ attrs = self._attrs(data, result, values=list(result.values))
565
+ self._start_kw(result._log_name, attrs)
566
+
567
+ def end_return(self, data, result):
568
+ attrs = self._attrs(data, result, values=list(result.values), end=True)
569
+ self._end_kw(result._log_name, attrs)
570
+
571
+ def start_continue(self, data, result):
572
+ self._start_kw(result._log_name, self._attrs(data, result))
573
+
574
+ def end_continue(self, data, result):
575
+ self._end_kw(result._log_name, self._attrs(data, result, end=True))
576
+
577
+ def start_break(self, data, result):
578
+ self._start_kw(result._log_name, self._attrs(data, result))
579
+
580
+ def end_break(self, data, result):
581
+ self._end_kw(result._log_name, self._attrs(data, result, end=True))
582
+
583
+ def start_error(self, data, result):
584
+ self._start_kw(result._log_name, self._attrs(data, result))
585
+
586
+ def end_error(self, data, result):
587
+ self._end_kw(result._log_name, self._attrs(data, result, end=True))
588
+
589
+ def start_var(self, data, result):
590
+ extra = self._var_extra_attrs(result)
591
+ self._start_kw(result._log_name, self._attrs(data, result, **extra))
592
+
593
+ def end_var(self, data, result):
594
+ extra = self._var_extra_attrs(result)
595
+ self._end_kw(result._log_name, self._attrs(data, result, **extra, end=True))
596
+
597
+ def _var_extra_attrs(self, result):
598
+ if result.name.startswith('$'):
599
+ value = (result.separator or ' ').join(result.value)
600
+ else:
601
+ value = list(result.value)
602
+ return {'name': result.name, 'value': value, 'scope': result.scope or 'LOCAL'}
603
+
604
+ def log_message(self, message):
605
+ self._log_message(self._message_attributes(message))
606
+
607
+ def message(self, message):
608
+ self._message(self._message_attributes(message))
609
+
610
+ def output_file(self, path: Path):
611
+ self._output_file(str(path))
612
+
613
+ def report_file(self, path: Path):
614
+ self._report_file(str(path))
615
+
616
+ def log_file(self, path: Path):
617
+ self._log_file(str(path))
618
+
619
+ def xunit_file(self, path: Path):
620
+ self._xunit_file(str(path))
621
+
622
+ def debug_file(self, path: Path):
623
+ self._debug_file(str(path))
624
+
625
+ def _suite_attrs(self, data, result, end=False):
626
+ attrs = {
627
+ 'id': data.id,
628
+ 'doc': result.doc,
629
+ 'metadata': dict(result.metadata),
630
+ 'starttime': result.starttime,
631
+ 'longname': result.full_name,
632
+ 'tests': [t.name for t in data.tests],
633
+ 'suites': [s.name for s in data.suites],
634
+ 'totaltests': data.test_count,
635
+ 'source': str(data.source or '')
636
+ }
637
+ if end:
638
+ attrs.update({
639
+ 'endtime': result.endtime,
640
+ 'elapsedtime': result.elapsedtime,
641
+ 'status': result.status,
642
+ 'message': result.message,
643
+ 'statistics': result.stat_message
644
+ })
645
+ return attrs
646
+
647
+ def _test_attrs(self, data, result, end=False):
648
+ attrs = {
649
+ 'id': data.id,
650
+ 'doc': result.doc,
651
+ 'tags': list(result.tags),
652
+ 'lineno': data.lineno,
653
+ 'starttime': result.starttime,
654
+ 'longname': result.full_name,
655
+ 'source': str(data.source or ''),
656
+ 'template': data.template or '',
657
+ 'originalname': data.name
658
+ }
659
+ if end:
660
+ attrs.update({
661
+ 'endtime': result.endtime,
662
+ 'elapsedtime': result.elapsedtime,
663
+ 'status': result.status,
664
+ 'message': result.message,
665
+ })
666
+ return attrs
667
+
668
+ def _keyword_attrs(self, data, result, end=False):
669
+ attrs = {
670
+ 'doc': result.doc,
671
+ 'lineno': data.lineno,
672
+ 'type': result.type,
673
+ 'status': result.status,
674
+ 'starttime': result.starttime,
675
+ 'source': str(data.source or ''),
676
+ 'kwname': result.name or '',
677
+ 'libname': result.owner or '',
678
+ 'args': [a if isinstance(a, str) else safe_str(a) for a in result.args],
679
+ 'assign': list(result.assign),
680
+ 'tags': list(result.tags)
681
+ }
682
+ if end:
683
+ attrs.update({
684
+ 'endtime': result.endtime,
685
+ 'elapsedtime': result.elapsedtime
686
+ })
687
+ return attrs
688
+
689
+ def _attrs(self, data, result, end=False, **extra):
690
+ attrs = {
691
+ 'doc': '',
692
+ 'lineno': data.lineno,
693
+ 'type': result.type,
694
+ 'status': result.status,
695
+ 'starttime': result.starttime,
696
+ 'source': str(data.source or ''),
697
+ 'kwname': result._log_name,
698
+ 'libname': '',
699
+ 'args': [],
700
+ 'assign': [],
701
+ 'tags': []
702
+ }
703
+ attrs.update(**extra)
704
+ if end:
705
+ attrs.update({
706
+ 'endtime': result.endtime,
707
+ 'elapsedtime': result.elapsedtime
708
+ })
709
+ return attrs
710
+
711
+ def _message_attributes(self, msg):
712
+ # Timestamp in our legacy format.
713
+ timestamp = msg.timestamp.isoformat(' ', timespec='milliseconds').replace('-', '')
714
+ attrs = {'timestamp': timestamp,
715
+ 'message': msg.message,
716
+ 'level': msg.level,
717
+ 'html': 'yes' if msg.html else 'no'}
718
+ return attrs
719
+
720
+ def close(self):
721
+ self._close()
722
+
723
+
724
+ class ListenerMethod:
725
+ # Flag to avoid recursive listener calls.
726
+ called = False
727
+
728
+ def __init__(self, method, name):
729
+ self.method = method
730
+ self.listener_name = name
731
+
732
+ def __call__(self, *args):
733
+ if self.method is None:
734
+ return
735
+ if self.called:
736
+ return
737
+ try:
738
+ ListenerMethod.called = True
739
+ self.method(*args)
740
+ except TimeoutError:
741
+ # Propagate possible timeouts:
742
+ # https://github.com/robotframework/robotframework/issues/2763
743
+ raise
744
+ except Exception:
745
+ message, details = get_error_details()
746
+ LOGGER.error(f"Calling method '{self.method.__name__}' of listener "
747
+ f"'{self.listener_name}' failed: {message}")
748
+ LOGGER.info(f"Details:\n{details}")
749
+ finally:
750
+ ListenerMethod.called = False
751
+
752
+ def __bool__(self):
753
+ return self.method is not None