robotframework 7.1rc1__zip → 7.1.1__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 (280) hide show
  1. {robotframework-7.1rc1 → robotframework-7.1.1}/BUILD.rst +5 -5
  2. {robotframework-7.1rc1 → robotframework-7.1.1}/PKG-INFO +2 -2
  3. {robotframework-7.1rc1 → robotframework-7.1.1}/setup.py +1 -1
  4. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/api/interfaces.py +45 -11
  5. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/conf/settings.py +7 -0
  6. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/errors.py +0 -2
  7. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/htmldata/template.py +0 -2
  8. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/libraries/BuiltIn.py +12 -0
  9. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/libraries/Collections.py +2 -3
  10. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/output/console/__init__.py +3 -3
  11. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/output/console/dotted.py +3 -3
  12. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/output/console/highlighting.py +40 -14
  13. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/output/console/verbose.py +7 -7
  14. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/output/logger.py +2 -2
  15. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/output/loggerhelper.py +3 -2
  16. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/rebot.py +3 -0
  17. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/run.py +3 -0
  18. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/running/arguments/typeinfo.py +1 -2
  19. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/running/bodyrunner.py +34 -19
  20. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/running/outputcapture.py +2 -1
  21. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/running/signalhandler.py +7 -3
  22. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/running/status.py +7 -3
  23. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/running/userkeywordrunner.py +4 -0
  24. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/variables/scopes.py +2 -1
  25. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/version.py +1 -1
  26. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robotframework.egg-info/PKG-INFO +2 -2
  27. {robotframework-7.1rc1 → robotframework-7.1.1}/AUTHORS.rst +0 -0
  28. {robotframework-7.1rc1 → robotframework-7.1.1}/CONTRIBUTING.rst +0 -0
  29. {robotframework-7.1rc1 → robotframework-7.1.1}/COPYRIGHT.txt +0 -0
  30. {robotframework-7.1rc1 → robotframework-7.1.1}/INSTALL.rst +0 -0
  31. {robotframework-7.1rc1 → robotframework-7.1.1}/LICENSE.txt +0 -0
  32. {robotframework-7.1rc1 → robotframework-7.1.1}/MANIFEST.in +0 -0
  33. {robotframework-7.1rc1 → robotframework-7.1.1}/README.rst +0 -0
  34. {robotframework-7.1rc1 → robotframework-7.1.1}/setup.cfg +0 -0
  35. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/__init__.py +0 -0
  36. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/__main__.py +0 -0
  37. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/api/__init__.py +0 -0
  38. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/api/deco.py +0 -0
  39. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/api/exceptions.py +0 -0
  40. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/api/logger.py +0 -0
  41. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/api/parsing.py +0 -0
  42. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/api/py.typed +0 -0
  43. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/conf/__init__.py +0 -0
  44. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/conf/gatherfailed.py +0 -0
  45. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/conf/languages.py +0 -0
  46. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/htmldata/__init__.py +0 -0
  47. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/htmldata/common/__init__.py +0 -0
  48. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/htmldata/common/js_disabled.css +0 -0
  49. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/htmldata/common/storage.js +0 -0
  50. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/htmldata/htmlfilewriter.py +0 -0
  51. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/htmldata/jsonwriter.py +0 -0
  52. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/htmldata/lib/__init__.py +0 -0
  53. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/htmldata/lib/jquery.highlight.min.js +0 -0
  54. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/htmldata/lib/jquery.min.js +0 -0
  55. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/htmldata/lib/jquery.tablesorter.min.js +0 -0
  56. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/htmldata/lib/jquery.tmpl.min.js +0 -0
  57. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/htmldata/lib/jsxcompressor.min.js +0 -0
  58. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/htmldata/libdoc/__init__.py +0 -0
  59. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/htmldata/libdoc/doc_formatting.css +0 -0
  60. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/htmldata/libdoc/libdoc.css +0 -0
  61. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/htmldata/libdoc/libdoc.html +0 -0
  62. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/htmldata/libdoc/print.css +0 -0
  63. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/htmldata/libdoc/pygments.css +0 -0
  64. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/htmldata/rebot/__init__.py +0 -0
  65. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/htmldata/rebot/common.css +0 -0
  66. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/htmldata/rebot/doc_formatting.css +0 -0
  67. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/htmldata/rebot/fileloading.js +0 -0
  68. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/htmldata/rebot/log.css +0 -0
  69. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/htmldata/rebot/log.html +0 -0
  70. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/htmldata/rebot/log.js +0 -0
  71. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/htmldata/rebot/model.js +0 -0
  72. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/htmldata/rebot/print.css +0 -0
  73. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/htmldata/rebot/report.css +0 -0
  74. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/htmldata/rebot/report.html +0 -0
  75. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/htmldata/rebot/testdata.js +0 -0
  76. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/htmldata/rebot/util.js +0 -0
  77. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/htmldata/rebot/view.js +0 -0
  78. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/htmldata/testdoc/__init__.py +0 -0
  79. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/htmldata/testdoc/testdoc.css +0 -0
  80. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/htmldata/testdoc/testdoc.html +0 -0
  81. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/libdoc.py +0 -0
  82. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/libdocpkg/__init__.py +0 -0
  83. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/libdocpkg/builder.py +0 -0
  84. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/libdocpkg/consoleviewer.py +0 -0
  85. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/libdocpkg/datatypes.py +0 -0
  86. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/libdocpkg/htmlutils.py +0 -0
  87. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/libdocpkg/htmlwriter.py +0 -0
  88. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/libdocpkg/jsonbuilder.py +0 -0
  89. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/libdocpkg/jsonwriter.py +0 -0
  90. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/libdocpkg/model.py +0 -0
  91. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/libdocpkg/output.py +0 -0
  92. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/libdocpkg/robotbuilder.py +0 -0
  93. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/libdocpkg/standardtypes.py +0 -0
  94. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/libdocpkg/writer.py +0 -0
  95. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/libdocpkg/xmlbuilder.py +0 -0
  96. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/libdocpkg/xmlwriter.py +0 -0
  97. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/libraries/DateTime.py +0 -0
  98. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/libraries/Dialogs.py +0 -0
  99. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/libraries/Easter.py +0 -0
  100. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/libraries/OperatingSystem.py +0 -0
  101. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/libraries/Process.py +0 -0
  102. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/libraries/Remote.py +0 -0
  103. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/libraries/Screenshot.py +0 -0
  104. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/libraries/String.py +0 -0
  105. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/libraries/Telnet.py +0 -0
  106. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/libraries/XML.py +0 -0
  107. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/libraries/__init__.py +0 -0
  108. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/libraries/dialogs_py.py +0 -0
  109. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/model/__init__.py +0 -0
  110. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/model/body.py +0 -0
  111. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/model/configurer.py +0 -0
  112. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/model/control.py +0 -0
  113. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/model/filter.py +0 -0
  114. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/model/fixture.py +0 -0
  115. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/model/itemlist.py +0 -0
  116. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/model/keyword.py +0 -0
  117. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/model/message.py +0 -0
  118. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/model/metadata.py +0 -0
  119. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/model/modelobject.py +0 -0
  120. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/model/modifier.py +0 -0
  121. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/model/namepatterns.py +0 -0
  122. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/model/statistics.py +0 -0
  123. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/model/stats.py +0 -0
  124. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/model/suitestatistics.py +0 -0
  125. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/model/tags.py +0 -0
  126. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/model/tagsetter.py +0 -0
  127. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/model/tagstatistics.py +0 -0
  128. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/model/testcase.py +0 -0
  129. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/model/testsuite.py +0 -0
  130. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/model/totalstatistics.py +0 -0
  131. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/model/visitor.py +0 -0
  132. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/output/__init__.py +0 -0
  133. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/output/console/quiet.py +0 -0
  134. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/output/debugfile.py +0 -0
  135. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/output/filelogger.py +0 -0
  136. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/output/librarylogger.py +0 -0
  137. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/output/listeners.py +0 -0
  138. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/output/loggerapi.py +0 -0
  139. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/output/output.py +0 -0
  140. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/output/pyloggingconf.py +0 -0
  141. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/output/stdoutlogsplitter.py +0 -0
  142. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/output/xmllogger.py +0 -0
  143. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/parsing/__init__.py +0 -0
  144. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/parsing/lexer/__init__.py +0 -0
  145. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/parsing/lexer/blocklexers.py +0 -0
  146. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/parsing/lexer/context.py +0 -0
  147. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/parsing/lexer/lexer.py +0 -0
  148. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/parsing/lexer/settings.py +0 -0
  149. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/parsing/lexer/statementlexers.py +0 -0
  150. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/parsing/lexer/tokenizer.py +0 -0
  151. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/parsing/lexer/tokens.py +0 -0
  152. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/parsing/model/__init__.py +0 -0
  153. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/parsing/model/blocks.py +0 -0
  154. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/parsing/model/statements.py +0 -0
  155. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/parsing/model/visitor.py +0 -0
  156. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/parsing/parser/__init__.py +0 -0
  157. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/parsing/parser/blockparsers.py +0 -0
  158. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/parsing/parser/fileparser.py +0 -0
  159. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/parsing/parser/parser.py +0 -0
  160. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/parsing/suitestructure.py +0 -0
  161. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/pythonpathsetter.py +0 -0
  162. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/reporting/__init__.py +0 -0
  163. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/reporting/expandkeywordmatcher.py +0 -0
  164. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/reporting/jsbuildingcontext.py +0 -0
  165. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/reporting/jsexecutionresult.py +0 -0
  166. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/reporting/jsmodelbuilders.py +0 -0
  167. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/reporting/jswriter.py +0 -0
  168. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/reporting/logreportwriters.py +0 -0
  169. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/reporting/outputwriter.py +0 -0
  170. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/reporting/resultwriter.py +0 -0
  171. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/reporting/stringcache.py +0 -0
  172. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/reporting/xunitwriter.py +0 -0
  173. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/result/__init__.py +0 -0
  174. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/result/configurer.py +0 -0
  175. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/result/executionerrors.py +0 -0
  176. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/result/executionresult.py +0 -0
  177. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/result/flattenkeywordmatcher.py +0 -0
  178. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/result/keywordremover.py +0 -0
  179. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/result/merger.py +0 -0
  180. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/result/messagefilter.py +0 -0
  181. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/result/model.py +0 -0
  182. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/result/modeldeprecation.py +0 -0
  183. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/result/resultbuilder.py +0 -0
  184. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/result/suiteteardownfailed.py +0 -0
  185. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/result/visitor.py +0 -0
  186. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/result/xmlelementhandlers.py +0 -0
  187. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/running/__init__.py +0 -0
  188. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/running/arguments/__init__.py +0 -0
  189. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/running/arguments/argumentconverter.py +0 -0
  190. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/running/arguments/argumentmapper.py +0 -0
  191. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/running/arguments/argumentparser.py +0 -0
  192. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/running/arguments/argumentresolver.py +0 -0
  193. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/running/arguments/argumentspec.py +0 -0
  194. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/running/arguments/argumentvalidator.py +0 -0
  195. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/running/arguments/customconverters.py +0 -0
  196. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/running/arguments/embedded.py +0 -0
  197. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/running/arguments/typeconverters.py +0 -0
  198. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/running/arguments/typeinfoparser.py +0 -0
  199. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/running/arguments/typevalidator.py +0 -0
  200. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/running/builder/__init__.py +0 -0
  201. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/running/builder/builders.py +0 -0
  202. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/running/builder/parsers.py +0 -0
  203. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/running/builder/settings.py +0 -0
  204. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/running/builder/transformers.py +0 -0
  205. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/running/context.py +0 -0
  206. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/running/dynamicmethods.py +0 -0
  207. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/running/importer.py +0 -0
  208. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/running/invalidkeyword.py +0 -0
  209. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/running/keywordfinder.py +0 -0
  210. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/running/keywordimplementation.py +0 -0
  211. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/running/librarykeyword.py +0 -0
  212. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/running/librarykeywordrunner.py +0 -0
  213. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/running/libraryscopes.py +0 -0
  214. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/running/model.py +0 -0
  215. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/running/namespace.py +0 -0
  216. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/running/randomizer.py +0 -0
  217. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/running/resourcemodel.py +0 -0
  218. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/running/runkwregister.py +0 -0
  219. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/running/statusreporter.py +0 -0
  220. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/running/suiterunner.py +0 -0
  221. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/running/testlibraries.py +0 -0
  222. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/running/timeouts/__init__.py +0 -0
  223. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/running/timeouts/nosupport.py +0 -0
  224. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/running/timeouts/posix.py +0 -0
  225. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/running/timeouts/windows.py +0 -0
  226. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/testdoc.py +0 -0
  227. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/utils/__init__.py +0 -0
  228. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/utils/application.py +0 -0
  229. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/utils/argumentparser.py +0 -0
  230. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/utils/asserts.py +0 -0
  231. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/utils/charwidth.py +0 -0
  232. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/utils/compress.py +0 -0
  233. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/utils/connectioncache.py +0 -0
  234. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/utils/dotdict.py +0 -0
  235. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/utils/encoding.py +0 -0
  236. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/utils/encodingsniffer.py +0 -0
  237. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/utils/error.py +0 -0
  238. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/utils/escaping.py +0 -0
  239. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/utils/etreewrapper.py +0 -0
  240. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/utils/filereader.py +0 -0
  241. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/utils/frange.py +0 -0
  242. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/utils/htmlformatters.py +0 -0
  243. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/utils/importer.py +0 -0
  244. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/utils/markuputils.py +0 -0
  245. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/utils/markupwriters.py +0 -0
  246. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/utils/match.py +0 -0
  247. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/utils/misc.py +0 -0
  248. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/utils/normalizing.py +0 -0
  249. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/utils/notset.py +0 -0
  250. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/utils/platform.py +0 -0
  251. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/utils/recommendations.py +0 -0
  252. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/utils/restreader.py +0 -0
  253. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/utils/robotenv.py +0 -0
  254. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/utils/robotinspect.py +0 -0
  255. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/utils/robotio.py +0 -0
  256. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/utils/robotpath.py +0 -0
  257. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/utils/robottime.py +0 -0
  258. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/utils/robottypes.py +0 -0
  259. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/utils/setter.py +0 -0
  260. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/utils/sortable.py +0 -0
  261. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/utils/text.py +0 -0
  262. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/utils/typehints.py +0 -0
  263. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/utils/unic.py +0 -0
  264. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/variables/__init__.py +0 -0
  265. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/variables/assigner.py +0 -0
  266. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/variables/evaluation.py +0 -0
  267. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/variables/filesetter.py +0 -0
  268. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/variables/finders.py +0 -0
  269. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/variables/notfound.py +0 -0
  270. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/variables/replacer.py +0 -0
  271. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/variables/resolvable.py +0 -0
  272. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/variables/search.py +0 -0
  273. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/variables/store.py +0 -0
  274. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/variables/tablesetter.py +0 -0
  275. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robot/variables/variables.py +0 -0
  276. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robotframework.egg-info/SOURCES.txt +0 -0
  277. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robotframework.egg-info/dependency_links.txt +0 -0
  278. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robotframework.egg-info/entry_points.txt +0 -0
  279. {robotframework-7.1rc1 → robotframework-7.1.1}/src/robotframework.egg-info/top_level.txt +0 -0
  280. {robotframework-7.1rc1 → robotframework-7.1.1}/tasks.py +0 -0
@@ -76,7 +76,7 @@ __ https://github.com/robotframework/robotframework/tree/master/atest#schema-val
76
76
  Preparation
77
77
  -----------
78
78
 
79
- 1. Check that you are on the master branch and have nothing left to commit,
79
+ 1. Check that you are on the right branch and have nothing left to commit,
80
80
  pull, or push::
81
81
 
82
82
  git branch
@@ -93,13 +93,13 @@ Preparation
93
93
 
94
94
  VERSION=<version>
95
95
 
96
- For example, ``VERSION=3.0.1`` or ``VERSION=3.1a2``.
96
+ For example, ``VERSION=7.1.1`` or ``VERSION=7.2a2``. No ``v`` prefix!
97
97
 
98
98
  Release notes
99
99
  -------------
100
100
 
101
- 1. Create personal `GitHub access token`__ to be able to access issue tracker
102
- programmatically. The token needs only the `repo/public_repo` scope.
101
+ 1. Create a personal `GitHub access token`__ to be able to access issue tracker
102
+ programmatically. The token needs only the ``repo/public_repo`` scope.
103
103
 
104
104
  2. Set GitHub user information into shell variables to ease running the
105
105
  ``invoke release-notes`` command in the next step::
@@ -119,7 +119,7 @@ Release notes
119
119
  <Set version_>`__. Omit the ``-w`` option if you just want to get release
120
120
  notes printed to the console, not written to a file.
121
121
 
122
- When generating release notes for a preview release like ``3.0.2rc1``,
122
+ When generating release notes for a preview release like ``7.2rc1``,
123
123
  the list of issues is only going to contain issues with that label
124
124
  (e.g. ``rc1``) or with a label of an earlier preview release (e.g.
125
125
  ``alpha1``, ``beta2``).
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: robotframework
3
- Version: 7.1rc1
3
+ Version: 7.1.1
4
4
  Summary: Generic automation framework for acceptance testing and robotic process automation (RPA)
5
5
  Home-page: https://robotframework.org
6
6
  Author: Pekka Klärck
@@ -10,7 +10,7 @@ Download-URL: https://pypi.org/project/robotframework
10
10
  Project-URL: Source, https://github.com/robotframework/robotframework
11
11
  Project-URL: Issue Tracker, https://github.com/robotframework/robotframework/issues
12
12
  Project-URL: Documentation, https://robotframework.org/robotframework
13
- Project-URL: Release Notes, https://github.com/robotframework/robotframework/blob/master/doc/releasenotes/rf-7.1rc1.rst
13
+ Project-URL: Release Notes, https://github.com/robotframework/robotframework/blob/master/doc/releasenotes/rf-7.1.1.rst
14
14
  Project-URL: Slack, http://slack.robotframework.org
15
15
  Description: Robot Framework
16
16
  ===============
@@ -6,7 +6,7 @@ from setuptools import find_packages, setup
6
6
 
7
7
  # Version number typically updated by running `invoke set-version <version>`.
8
8
  # Run `invoke --help set-version` or see tasks.py for details.
9
- VERSION = '7.1rc1'
9
+ VERSION = '7.1.1'
10
10
  with open(join(dirname(abspath(__file__)), 'README.rst')) as f:
11
11
  LONG_DESCRIPTION = f.read()
12
12
  base_url = 'https://github.com/robotframework/robotframework/blob/master'
@@ -478,20 +478,37 @@ class ListenerV2:
478
478
  def output_file(self, path: str):
479
479
  """Called after the output file has been created.
480
480
 
481
- At this point the file is guaranteed to be closed.
481
+ ``path`` is an absolute path to the output file or
482
+ a string ``None`` if creating the output file is disabled.
482
483
  """
483
484
 
484
485
  def log_file(self, path: str):
485
- """Called after the log file has been created."""
486
+ """Called after the log file has been created.
487
+
488
+ ``path`` is an absolute path to the log file.
489
+ Not called if creating the log file is disabled.
490
+ """
486
491
 
487
492
  def report_file(self, path: str):
488
- """Called after the report file has been created."""
493
+ """Called after the report file has been created.
494
+
495
+ ``path`` is an absolute path to the report file.
496
+ Not called if creating the report file is disabled.
497
+ """
489
498
 
490
499
  def xunit_file(self, path: str):
491
- """Called after the xunit compatible output file has been created."""
500
+ """Called after the xunit compatible output file has been created.
501
+
502
+ ``path`` is an absolute path to the xunit file.
503
+ Only called if creating the xunit file is enabled.
504
+ """
492
505
 
493
506
  def debug_file(self, path: str):
494
- """Called after the debug file has been created."""
507
+ """Called after the debug file has been created.
508
+
509
+ ``path`` is an absolute path to the debug file.
510
+ Only called if creating the debug file is enabled.
511
+ """
495
512
 
496
513
  def close(self):
497
514
  """Called when the whole execution ends.
@@ -915,23 +932,40 @@ class ListenerV3:
915
932
  the imported variable file.
916
933
  """
917
934
 
918
- def output_file(self, path: Path):
935
+ def output_file(self, path: 'Path | None'):
919
936
  """Called after the output file has been created.
920
937
 
921
- At this point the file is guaranteed to be closed.
938
+ ``path`` is an absolute path to the output file or
939
+ ``None`` if creating the output file is disabled.
922
940
  """
923
941
 
924
942
  def log_file(self, path: Path):
925
- """Called after the log file has been created."""
943
+ """Called after the log file has been created.
944
+
945
+ ``path`` is an absolute path to the log file.
946
+ Not called if creating the log file is disabled.
947
+ """
926
948
 
927
949
  def report_file(self, path: Path):
928
- """Called after the report file has been created."""
950
+ """Called after the report file has been created.
951
+
952
+ ``path`` is an absolute path to the report file.
953
+ Not called if creating the report file is disabled.
954
+ """
929
955
 
930
956
  def xunit_file(self, path: Path):
931
- """Called after the xunit compatible output file has been created."""
957
+ """Called after the xunit compatible output file has been created.
958
+
959
+ ``path`` is an absolute path to the xunit file.
960
+ Only called if creating the xunit file is enabled.
961
+ """
932
962
 
933
963
  def debug_file(self, path: Path):
934
- """Called after the debug file has been created."""
964
+ """Called after the debug file has been created.
965
+
966
+ ``path`` is an absolute path to the debug file.
967
+ Only called if creating the debug file is enabled.
968
+ """
935
969
 
936
970
  def close(self):
937
971
  """Called when the whole execution ends.
@@ -68,6 +68,7 @@ class _BaseSettings:
68
68
  'PreRebotModifiers': ('prerebotmodifier', []),
69
69
  'StatusRC' : ('statusrc', True),
70
70
  'ConsoleColors' : ('consolecolors', 'AUTO'),
71
+ 'ConsoleLinks' : ('consolelinks', 'AUTO'),
71
72
  'PythonPath' : ('pythonpath', []),
72
73
  'StdOut' : ('stdout', None),
73
74
  'StdErr' : ('stderr', None)}
@@ -454,6 +455,10 @@ class _BaseSettings:
454
455
  def console_colors(self):
455
456
  return self['ConsoleColors']
456
457
 
458
+ @property
459
+ def console_links(self):
460
+ return self['ConsoleLinks']
461
+
457
462
  @property
458
463
  def rpa(self):
459
464
  return self['RPA']
@@ -613,6 +618,7 @@ class RobotSettings(_BaseSettings):
613
618
  'type': self.console_type,
614
619
  'width': self.console_width,
615
620
  'colors': self.console_colors,
621
+ 'links': self.console_links,
616
622
  'markers': self.console_markers,
617
623
  'stdout': self['StdOut'],
618
624
  'stderr': self['StdErr']
@@ -736,6 +742,7 @@ class RebotSettings(_BaseSettings):
736
742
  def console_output_config(self):
737
743
  return {
738
744
  'colors': self.console_colors,
745
+ 'links': self.console_links,
739
746
  'stdout': self['StdOut'],
740
747
  'stderr': self['StdErr']
741
748
  }
@@ -148,8 +148,6 @@ class ExecutionStatus(RobotError):
148
148
  if templated:
149
149
  return context.continue_on_failure(default=True)
150
150
  if self.keyword_timeout:
151
- if context.in_teardown:
152
- self.keyword_timeout = False
153
151
  return False
154
152
  return self.continue_on_failure or context.continue_on_failure()
155
153
 
@@ -20,8 +20,6 @@ from pathlib import Path
20
20
 
21
21
 
22
22
  if sys.version_info < (3, 9) and not Path(__file__).exists(): # zipsafe
23
- # `importlib.resources.files` is new in Python 3.9, but that version does
24
- # not seem to be compatible with zipapp.
25
23
  try:
26
24
  from importlib_resources import files
27
25
  except ImportError:
@@ -2415,6 +2415,7 @@ class _RunKeyword(_BuiltInBase):
2415
2415
  try:
2416
2416
  return self.run_keyword(name, *args)
2417
2417
  except ExecutionFailed as err:
2418
+ self._reset_keyword_timeout_in_teardown(err, self._context)
2418
2419
  if err.dont_continue or err.skip:
2419
2420
  raise
2420
2421
  count -= 1
@@ -2434,6 +2435,17 @@ class _RunKeyword(_BuiltInBase):
2434
2435
  )
2435
2436
  self._sleep_in_parts(sleep_time)
2436
2437
 
2438
+ def _reset_keyword_timeout_in_teardown(self, err, context):
2439
+ # Keyword timeouts in teardowns have been converted to normal failures
2440
+ # to allow execution to continue on higher level:
2441
+ # https://github.com/robotframework/robotframework/issues/3398
2442
+ # We need to reset it here to not continue unnecessarily:
2443
+ # https://github.com/robotframework/robotframework/issues/5237
2444
+ if context.in_teardown:
2445
+ timeouts = [t for t in context.timeouts if t.type == 'Keyword']
2446
+ if timeouts and min(timeouts).timed_out():
2447
+ err.keyword_timeout = True
2448
+
2437
2449
  @run_keyword_variant(resolve=1)
2438
2450
  def set_variable_if(self, condition, *values):
2439
2451
  """Sets variable based on the given condition.
@@ -455,9 +455,8 @@ class _List:
455
455
  normalize = Normalizer(ignore_case).normalize
456
456
  list1 = normalize(list1)
457
457
  list2 = normalize(list2)
458
- diffs = ', '.join(str(item) for item in list2 if item not in list1)
459
- _verify_condition(not diffs,
460
- f'Following values were not found from first list: {diffs}',
458
+ diffs = [item for item in list2 if item not in list1]
459
+ _verify_condition(not diffs, f'Following values are missing: {seq2str(diffs)}',
461
460
  msg, values)
462
461
 
463
462
  def log_list(self, list_, level='INFO'):
@@ -20,13 +20,13 @@ from .quiet import NoOutput, QuietOutput
20
20
  from .verbose import VerboseOutput
21
21
 
22
22
 
23
- def ConsoleOutput(type='verbose', width=78, colors='AUTO', markers='AUTO',
23
+ def ConsoleOutput(type='verbose', width=78, colors='AUTO', links='AUTO', markers='AUTO',
24
24
  stdout=None, stderr=None):
25
25
  upper = type.upper()
26
26
  if upper == 'VERBOSE':
27
- return VerboseOutput(width, colors, markers, stdout, stderr)
27
+ return VerboseOutput(width, colors, links, markers, stdout, stderr)
28
28
  if upper == 'DOTTED':
29
- return DottedOutput(width, colors, stdout, stderr)
29
+ return DottedOutput(width, colors, links, stdout, stderr)
30
30
  if upper == 'QUIET':
31
31
  return QuietOutput(colors, stderr)
32
32
  if upper == 'NONE':
@@ -25,10 +25,10 @@ from ..loggerapi import LoggerApi
25
25
 
26
26
  class DottedOutput(LoggerApi):
27
27
 
28
- def __init__(self, width=78, colors='AUTO', stdout=None, stderr=None):
28
+ def __init__(self, width=78, colors='AUTO', links='AUTO', stdout=None, stderr=None):
29
29
  self.width = width
30
- self.stdout = HighlightingStream(stdout or sys.__stdout__, colors)
31
- self.stderr = HighlightingStream(stderr or sys.__stderr__, colors)
30
+ self.stdout = HighlightingStream(stdout or sys.__stdout__, colors, links)
31
+ self.stderr = HighlightingStream(stderr or sys.__stderr__, colors, links)
32
32
  self.markers_on_row = 0
33
33
 
34
34
  def start_suite(self, data, result):
@@ -42,11 +42,13 @@ from robot.utils import console_encode, isatty, WINDOWS
42
42
 
43
43
  class HighlightingStream:
44
44
 
45
- def __init__(self, stream, colors='AUTO'):
46
- self.stream = stream
47
- self._highlighter = self._get_highlighter(stream, colors)
45
+ def __init__(self, stream, colors='AUTO', links='AUTO'):
46
+ self.stream = stream or NullStream()
47
+ self._highlighter = self._get_highlighter(stream, colors, links)
48
48
 
49
- def _get_highlighter(self, stream, colors):
49
+ def _get_highlighter(self, stream, colors, links):
50
+ if not stream:
51
+ return NoHighlighting()
50
52
  options = {'AUTO': Highlighter if isatty(stream) else NoHighlighting,
51
53
  'ON': Highlighter,
52
54
  'OFF': NoHighlighting,
@@ -54,9 +56,12 @@ class HighlightingStream:
54
56
  try:
55
57
  highlighter = options[colors.upper()]
56
58
  except KeyError:
57
- raise DataError("Invalid console color value '%s'. Available "
58
- "'AUTO', 'ON', 'OFF' and 'ANSI'." % colors)
59
- return highlighter(stream)
59
+ raise DataError(f"Invalid console color value '{colors}'. "
60
+ f"Available 'AUTO', 'ON', 'OFF' and 'ANSI'.")
61
+ if links.upper() not in ('AUTO', 'OFF'):
62
+ raise DataError(f"Invalid console link value '{links}. "
63
+ f"Available 'AUTO' and 'OFF'.")
64
+ return highlighter(stream, links.upper() == 'AUTO')
60
65
 
61
66
  def write(self, text, flush=True):
62
67
  self._write(console_encode(text, stream=self.stream))
@@ -99,7 +104,7 @@ class HighlightingStream:
99
104
  def error(self, message, level):
100
105
  self.write('[ ', flush=False)
101
106
  self.highlight(level, flush=False)
102
- self.write(' ] %s\n' % message)
107
+ self.write(f' ] {message}\n')
103
108
 
104
109
  @contextmanager
105
110
  def _highlighting(self, status):
@@ -116,17 +121,26 @@ class HighlightingStream:
116
121
  highlighter.reset()
117
122
 
118
123
  def result_file(self, kind, path):
119
- path = self._highlighter.link(path)
124
+ path = self._highlighter.link(path) if path else 'NONE'
120
125
  self.write(f"{kind + ':':8} {path}\n")
121
126
 
122
127
 
123
- def Highlighter(stream):
128
+ class NullStream:
129
+
130
+ def write(self, text):
131
+ pass
132
+
133
+ def flush(self):
134
+ pass
135
+
136
+
137
+ def Highlighter(stream, links=True):
124
138
  if os.sep == '/':
125
- return AnsiHighlighter(stream)
139
+ return AnsiHighlighter(stream, links)
126
140
  if not windll:
127
141
  return NoHighlighting(stream)
128
142
  if virtual_terminal_enabled(stream):
129
- return AnsiHighlighter(stream)
143
+ return AnsiHighlighter(stream, links)
130
144
  return DosHighlighter(stream)
131
145
 
132
146
 
@@ -136,8 +150,9 @@ class AnsiHighlighter:
136
150
  YELLOW = '\033[33m'
137
151
  RESET = '\033[0m'
138
152
 
139
- def __init__(self, stream):
153
+ def __init__(self, stream, links=True):
140
154
  self._stream = stream
155
+ self._links = links
141
156
 
142
157
  def green(self):
143
158
  self._set_color(self.GREEN)
@@ -152,7 +167,15 @@ class AnsiHighlighter:
152
167
  self._set_color(self.RESET)
153
168
 
154
169
  def link(self, path):
155
- return f'\033]8;;file:///{path}\033\\{path}\033]8;;\033\\'
170
+ if not self._links:
171
+ return path
172
+ try:
173
+ uri = path.as_uri()
174
+ except ValueError:
175
+ return path
176
+ # Terminal hyperlink syntax is documented here:
177
+ # https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda
178
+ return f'\033]8;;{uri}\033\\{path}\033]8;;\033\\'
156
179
 
157
180
  def _set_color(self, color):
158
181
  self._stream.write(color)
@@ -160,6 +183,9 @@ class AnsiHighlighter:
160
183
 
161
184
  class NoHighlighting(AnsiHighlighter):
162
185
 
186
+ def __init__(self, stream=None, links=True):
187
+ super().__init__(stream, links)
188
+
163
189
  def link(self, path):
164
190
  return path
165
191
 
@@ -24,9 +24,9 @@ from ..loggerapi import LoggerApi
24
24
 
25
25
  class VerboseOutput(LoggerApi):
26
26
 
27
- def __init__(self, width=78, colors='AUTO', markers='AUTO', stdout=None,
28
- stderr=None):
29
- self.writer = VerboseWriter(width, colors, markers, stdout, stderr)
27
+ def __init__(self, width=78, colors='AUTO', links='AUTO', markers='AUTO',
28
+ stdout=None, stderr=None):
29
+ self.writer = VerboseWriter(width, colors, links, markers, stdout, stderr)
30
30
  self.started = False
31
31
  self.started_keywords = 0
32
32
  self.running_test = False
@@ -73,11 +73,11 @@ class VerboseOutput(LoggerApi):
73
73
  class VerboseWriter:
74
74
  _status_length = len('| PASS |')
75
75
 
76
- def __init__(self, width=78, colors='AUTO', markers='AUTO', stdout=None,
77
- stderr=None):
76
+ def __init__(self, width=78, colors='AUTO', links='AUTO', markers='AUTO',
77
+ stdout=None, stderr=None):
78
78
  self.width = width
79
- self.stdout = HighlightingStream(stdout or sys.__stdout__, colors)
80
- self.stderr = HighlightingStream(stderr or sys.__stderr__, colors)
79
+ self.stdout = HighlightingStream(stdout or sys.__stdout__, colors, links)
80
+ self.stderr = HighlightingStream(stderr or sys.__stderr__, colors, links)
81
81
  self._keyword_marker = KeywordMarker(self.stdout, markers)
82
82
  self._last_info = None
83
83
 
@@ -104,8 +104,8 @@ class Logger(AbstractLogger):
104
104
  self.close()
105
105
 
106
106
  def register_console_logger(self, type='verbose', width=78, colors='AUTO',
107
- markers='AUTO', stdout=None, stderr=None):
108
- logger = ConsoleOutput(type, width, colors, markers, stdout, stderr)
107
+ links='AUTO', markers='AUTO', stdout=None, stderr=None):
108
+ logger = ConsoleOutput(type, width, colors, links, markers, stdout, stderr)
109
109
  self._console_logger = self._wrap_and_relay(logger)
110
110
 
111
111
  def _wrap_and_relay(self, logger):
@@ -40,8 +40,9 @@ def write_to_console(msg, newline=True, stream='stdout'):
40
40
  if newline:
41
41
  msg += '\n'
42
42
  stream = sys.__stdout__ if stream.lower() != 'stderr' else sys.__stderr__
43
- stream.write(console_encode(msg, stream=stream))
44
- stream.flush()
43
+ if stream:
44
+ stream.write(console_encode(msg, stream=stream))
45
+ stream.flush()
45
46
 
46
47
 
47
48
  class AbstractLogger:
@@ -262,6 +262,9 @@ Options
262
262
  on: always use colors
263
263
  ansi: like `on` but use ANSI colors also on Windows
264
264
  off: disable colors altogether
265
+ --consolelinks auto|off Control making paths to results files hyperlinks.
266
+ auto: use links when colors are enabled (default)
267
+ off: disable links unconditionally
265
268
  -P --pythonpath path * Additional locations to add to the module search path
266
269
  that is used when importing Python based extensions.
267
270
  -A --argumentfile path * Text file to read more arguments from. File can have
@@ -341,6 +341,9 @@ Options
341
341
  on: always use colors
342
342
  ansi: like `on` but use ANSI colors also on Windows
343
343
  off: disable colors altogether
344
+ --consolelinks auto|off Control making paths to results files hyperlinks.
345
+ auto: use links when colors are enabled (default)
346
+ off: disable links unconditionally
344
347
  -K --consolemarkers auto|on|off Show markers on the console when top level
345
348
  keywords in a test case end. Values have same
346
349
  semantics as with --consolecolors.
@@ -175,8 +175,7 @@ class TypeInfo(metaclass=SetterAwareType):
175
175
  - a sequence of supported type hints to create a union from such as
176
176
  ``[int, float]`` or ``('int', 'list[int]')``
177
177
 
178
- In special cases, for example with dictionaries or sequences, using the
179
- more specialized methods like :meth:`from_dict` or :meth:`from_sequence`
178
+ In special cases using a more specialized method like :meth:`from_sequence`
180
179
  may be more appropriate than using this generic method.
181
180
  """
182
181
  if hint is NOT_SET:
@@ -383,7 +383,6 @@ class WhileRunner:
383
383
  ctx = self._context
384
384
  error = None
385
385
  run = False
386
- limit = None
387
386
  result.start_time = datetime.now()
388
387
  iter_result = result.body.create_iteration(start_time=datetime.now())
389
388
  if self._run:
@@ -391,15 +390,17 @@ class WhileRunner:
391
390
  error = DataError(data.error, syntax=True)
392
391
  elif not ctx.dry_run:
393
392
  try:
394
- limit = WhileLimit.create(data.limit,
395
- data.on_limit,
396
- data.on_limit_message,
397
- ctx.variables)
398
393
  run = self._should_run(data.condition, ctx.variables)
399
394
  except DataError as err:
400
395
  error = err
401
396
  with StatusReporter(data, result, self._context, run):
402
397
  iter_data = data.get_iteration()
398
+ if run:
399
+ try:
400
+ limit = WhileLimit.create(data, ctx.variables)
401
+ except DataError as err:
402
+ error = err
403
+ run = False
403
404
  if ctx.dry_run or not run:
404
405
  self._run_iteration(iter_data, iter_result, run)
405
406
  if error:
@@ -651,29 +652,34 @@ class WhileLimit:
651
652
  self.on_limit_message = on_limit_message
652
653
 
653
654
  @classmethod
654
- def create(cls, limit, on_limit, on_limit_message, variables):
655
- if on_limit_message:
656
- try:
657
- on_limit_message = variables.replace_string(on_limit_message)
658
- except DataError as err:
659
- raise DataError(f"Invalid WHILE loop 'on_limit_message': '{err}")
660
- on_limit = cls._parse_on_limit(variables, on_limit)
655
+ def create(cls, data, variables):
656
+ limit = cls._parse_limit(data.limit, variables)
657
+ on_limit = cls._parse_on_limit(data.on_limit, variables)
658
+ on_limit_msg = cls._parse_on_limit_message(data.on_limit_message, variables)
661
659
  if not limit:
662
- return IterationCountLimit(DEFAULT_WHILE_LIMIT, on_limit, on_limit_message)
663
- limit = variables.replace_string(limit)
660
+ return IterationCountLimit(DEFAULT_WHILE_LIMIT, on_limit, on_limit_msg)
664
661
  if limit.upper() == 'NONE':
665
662
  return NoLimit()
666
663
  try:
667
664
  count = cls._parse_limit_as_count(limit)
668
665
  except ValueError:
669
666
  seconds = cls._parse_limit_as_timestr(limit)
670
- return DurationLimit(seconds, on_limit, on_limit_message)
667
+ return DurationLimit(seconds, on_limit, on_limit_msg)
671
668
  else:
672
- return IterationCountLimit(count, on_limit, on_limit_message)
669
+ return IterationCountLimit(count, on_limit, on_limit_msg)
673
670
 
674
671
  @classmethod
675
- def _parse_on_limit(cls, variables, on_limit):
676
- if on_limit is None:
672
+ def _parse_limit(cls, limit, variables):
673
+ if not limit:
674
+ return None
675
+ try:
676
+ return variables.replace_string(limit)
677
+ except DataError as err:
678
+ raise DataError(f"Invalid WHILE loop limit: {err}")
679
+
680
+ @classmethod
681
+ def _parse_on_limit(cls, on_limit, variables):
682
+ if not on_limit:
677
683
  return None
678
684
  try:
679
685
  on_limit = variables.replace_string(on_limit)
@@ -682,7 +688,16 @@ class WhileLimit:
682
688
  raise DataError(f"Value '{on_limit}' is not accepted. Valid values "
683
689
  f"are 'PASS' and 'FAIL'.")
684
690
  except DataError as err:
685
- raise DataError(f"Invalid WHILE loop 'on_limit' value: {err}")
691
+ raise DataError(f"Invalid WHILE loop 'on_limit': {err}")
692
+
693
+ @classmethod
694
+ def _parse_on_limit_message(cls, on_limit_message, variables):
695
+ if not on_limit_message:
696
+ return None
697
+ try:
698
+ return variables.replace_string(on_limit_message)
699
+ except DataError as err:
700
+ raise DataError(f"Invalid WHILE loop 'on_limit_message': '{err}")
686
701
 
687
702
  @classmethod
688
703
  def _parse_limit_as_count(cls, limit):
@@ -52,7 +52,8 @@ class OutputCapturer:
52
52
  LOGGER.log_output(stdout)
53
53
  if stderr:
54
54
  LOGGER.log_output(stderr)
55
- sys.__stderr__.write(console_encode(stderr, stream=sys.__stderr__))
55
+ if sys.__stderr__:
56
+ sys.__stderr__.write(console_encode(stderr, stream=sys.__stderr__))
56
57
 
57
58
  def _release(self):
58
59
  stdout = self.stdout.release()
@@ -31,14 +31,18 @@ class _StopSignalMonitor:
31
31
 
32
32
  def __call__(self, signum, frame):
33
33
  self._signal_count += 1
34
- LOGGER.info('Received signal: %s.' % signum)
34
+ LOGGER.info(f'Received signal: {signum}.')
35
35
  if self._signal_count > 1:
36
- sys.__stderr__.write('Execution forcefully stopped.\n')
36
+ self._write_to_stderr('Execution forcefully stopped.')
37
37
  raise SystemExit()
38
- sys.__stderr__.write('Second signal will force exit.\n')
38
+ self._write_to_stderr('Second signal will force exit.')
39
39
  if self._running_keyword:
40
40
  self._stop_execution_gracefully()
41
41
 
42
+ def _write_to_stderr(self, message):
43
+ if sys.__stderr__:
44
+ sys.__stderr__.write(message + '\n')
45
+
42
46
  def _stop_execution_gracefully(self):
43
47
  raise ExecutionFailed('Execution terminated by signal', exit=True)
44
48
 
@@ -29,9 +29,13 @@ class Failure:
29
29
  self.teardown_skipped = None
30
30
 
31
31
  def __bool__(self):
32
- return bool(
33
- self.setup or self.test or self.teardown or
34
- self.setup_skipped or self.test_skipped or self.teardown_skipped
32
+ return (
33
+ self.setup is not None
34
+ or self.test is not None
35
+ or self.teardown is not None
36
+ or self.setup_skipped is not None
37
+ or self.test_skipped is not None
38
+ or self.teardown_skipped is not None
35
39
  )
36
40
 
37
41
 
@@ -85,6 +85,10 @@ class UserKeywordRunner:
85
85
  with context.timeout(timeout):
86
86
  exception, return_value = self._execute(kw, result, context)
87
87
  if exception and not exception.can_continue(context):
88
+ if context.in_teardown and exception.keyword_timeout:
89
+ # Allow execution to continue on teardowns after timeout.
90
+ # https://github.com/robotframework/robotframework/issues/3398
91
+ exception.keyword_timeout = False
88
92
  raise exception
89
93
  return_value = self._handle_return_value(return_value, variables)
90
94
  if exception:
@@ -192,7 +192,8 @@ class GlobalVariables(Variables):
192
192
  'include': Tags(settings.include),
193
193
  'exclude': Tags(settings.exclude),
194
194
  'skip': Tags(settings.skip),
195
- 'skip_on_failure': Tags(settings.skip_on_failure)
195
+ 'skip_on_failure': Tags(settings.skip_on_failure),
196
+ 'console_width': settings.console_width
196
197
  })),
197
198
  ('${/}', os.sep),
198
199
  ('${:}', os.pathsep),