robotframework 7.0.1rc1__zip → 7.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.0.1rc1 → robotframework-7.1}/PKG-INFO +3 -2
  2. {robotframework-7.0.1rc1 → robotframework-7.1}/setup.py +2 -1
  3. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/api/interfaces.py +32 -0
  4. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/conf/languages.py +73 -18
  5. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/conf/settings.py +8 -1
  6. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/htmldata/rebot/model.js +22 -33
  7. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/htmldata/template.py +0 -2
  8. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/libdocpkg/jsonbuilder.py +1 -1
  9. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/libraries/BuiltIn.py +16 -3
  10. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/libraries/Collections.py +2 -3
  11. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/libraries/DateTime.py +3 -2
  12. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/libraries/Dialogs.py +12 -4
  13. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/libraries/OperatingSystem.py +4 -4
  14. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/libraries/Process.py +7 -3
  15. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/libraries/String.py +4 -1
  16. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/libraries/dialogs_py.py +17 -1
  17. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/model/modelobject.py +1 -6
  18. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/output/console/__init__.py +3 -3
  19. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/output/console/dotted.py +4 -4
  20. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/output/console/highlighting.py +90 -65
  21. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/output/console/verbose.py +10 -10
  22. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/output/listeners.py +61 -217
  23. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/output/logger.py +32 -16
  24. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/output/loggerapi.py +11 -0
  25. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/output/loggerhelper.py +6 -1
  26. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/output/output.py +2 -1
  27. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/parsing/model/statements.py +1 -1
  28. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/rebot.py +3 -0
  29. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/result/executionresult.py +1 -0
  30. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/result/model.py +1 -1
  31. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/result/resultbuilder.py +12 -11
  32. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/result/xmlelementhandlers.py +12 -0
  33. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/run.py +3 -0
  34. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/__init__.py +1 -1
  35. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/arguments/argumentresolver.py +18 -11
  36. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/arguments/argumentspec.py +2 -2
  37. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/arguments/argumentvalidator.py +0 -8
  38. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/arguments/embedded.py +2 -2
  39. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/bodyrunner.py +34 -19
  40. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/invalidkeyword.py +4 -1
  41. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/keywordimplementation.py +9 -5
  42. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/librarykeyword.py +19 -9
  43. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/librarykeywordrunner.py +25 -19
  44. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/model.py +69 -27
  45. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/namespace.py +20 -26
  46. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/resourcemodel.py +9 -1
  47. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/statusreporter.py +9 -4
  48. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/testlibraries.py +2 -2
  49. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/userkeywordrunner.py +10 -7
  50. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/encodingsniffer.py +3 -1
  51. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/robottime.py +5 -3
  52. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/variables/evaluation.py +1 -4
  53. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/variables/scopes.py +2 -1
  54. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/variables/tablesetter.py +17 -20
  55. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/version.py +1 -1
  56. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robotframework.egg-info/PKG-INFO +3 -2
  57. {robotframework-7.0.1rc1 → robotframework-7.1}/AUTHORS.rst +0 -0
  58. {robotframework-7.0.1rc1 → robotframework-7.1}/BUILD.rst +0 -0
  59. {robotframework-7.0.1rc1 → robotframework-7.1}/CONTRIBUTING.rst +0 -0
  60. {robotframework-7.0.1rc1 → robotframework-7.1}/COPYRIGHT.txt +0 -0
  61. {robotframework-7.0.1rc1 → robotframework-7.1}/INSTALL.rst +0 -0
  62. {robotframework-7.0.1rc1 → robotframework-7.1}/LICENSE.txt +0 -0
  63. {robotframework-7.0.1rc1 → robotframework-7.1}/MANIFEST.in +0 -0
  64. {robotframework-7.0.1rc1 → robotframework-7.1}/README.rst +0 -0
  65. {robotframework-7.0.1rc1 → robotframework-7.1}/setup.cfg +0 -0
  66. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/__init__.py +0 -0
  67. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/__main__.py +0 -0
  68. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/api/__init__.py +0 -0
  69. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/api/deco.py +0 -0
  70. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/api/exceptions.py +0 -0
  71. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/api/logger.py +0 -0
  72. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/api/parsing.py +0 -0
  73. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/api/py.typed +0 -0
  74. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/conf/__init__.py +0 -0
  75. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/conf/gatherfailed.py +0 -0
  76. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/errors.py +0 -0
  77. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/htmldata/__init__.py +0 -0
  78. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/htmldata/common/__init__.py +0 -0
  79. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/htmldata/common/js_disabled.css +0 -0
  80. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/htmldata/common/storage.js +0 -0
  81. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/htmldata/htmlfilewriter.py +0 -0
  82. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/htmldata/jsonwriter.py +0 -0
  83. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/htmldata/lib/__init__.py +0 -0
  84. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/htmldata/lib/jquery.highlight.min.js +0 -0
  85. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/htmldata/lib/jquery.min.js +0 -0
  86. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/htmldata/lib/jquery.tablesorter.min.js +0 -0
  87. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/htmldata/lib/jquery.tmpl.min.js +0 -0
  88. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/htmldata/lib/jsxcompressor.min.js +0 -0
  89. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/htmldata/libdoc/__init__.py +0 -0
  90. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/htmldata/libdoc/doc_formatting.css +0 -0
  91. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/htmldata/libdoc/libdoc.css +0 -0
  92. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/htmldata/libdoc/libdoc.html +0 -0
  93. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/htmldata/libdoc/print.css +0 -0
  94. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/htmldata/libdoc/pygments.css +0 -0
  95. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/htmldata/rebot/__init__.py +0 -0
  96. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/htmldata/rebot/common.css +0 -0
  97. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/htmldata/rebot/doc_formatting.css +0 -0
  98. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/htmldata/rebot/fileloading.js +0 -0
  99. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/htmldata/rebot/log.css +0 -0
  100. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/htmldata/rebot/log.html +0 -0
  101. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/htmldata/rebot/log.js +0 -0
  102. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/htmldata/rebot/print.css +0 -0
  103. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/htmldata/rebot/report.css +0 -0
  104. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/htmldata/rebot/report.html +0 -0
  105. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/htmldata/rebot/testdata.js +0 -0
  106. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/htmldata/rebot/util.js +0 -0
  107. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/htmldata/rebot/view.js +0 -0
  108. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/htmldata/testdoc/__init__.py +0 -0
  109. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/htmldata/testdoc/testdoc.css +0 -0
  110. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/htmldata/testdoc/testdoc.html +0 -0
  111. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/libdoc.py +0 -0
  112. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/libdocpkg/__init__.py +0 -0
  113. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/libdocpkg/builder.py +0 -0
  114. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/libdocpkg/consoleviewer.py +0 -0
  115. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/libdocpkg/datatypes.py +0 -0
  116. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/libdocpkg/htmlutils.py +0 -0
  117. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/libdocpkg/htmlwriter.py +0 -0
  118. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/libdocpkg/jsonwriter.py +0 -0
  119. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/libdocpkg/model.py +0 -0
  120. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/libdocpkg/output.py +0 -0
  121. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/libdocpkg/robotbuilder.py +0 -0
  122. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/libdocpkg/standardtypes.py +0 -0
  123. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/libdocpkg/writer.py +0 -0
  124. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/libdocpkg/xmlbuilder.py +0 -0
  125. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/libdocpkg/xmlwriter.py +0 -0
  126. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/libraries/Easter.py +0 -0
  127. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/libraries/Remote.py +0 -0
  128. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/libraries/Screenshot.py +0 -0
  129. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/libraries/Telnet.py +0 -0
  130. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/libraries/XML.py +0 -0
  131. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/libraries/__init__.py +0 -0
  132. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/model/__init__.py +0 -0
  133. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/model/body.py +0 -0
  134. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/model/configurer.py +0 -0
  135. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/model/control.py +0 -0
  136. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/model/filter.py +0 -0
  137. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/model/fixture.py +0 -0
  138. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/model/itemlist.py +0 -0
  139. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/model/keyword.py +0 -0
  140. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/model/message.py +0 -0
  141. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/model/metadata.py +0 -0
  142. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/model/modifier.py +0 -0
  143. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/model/namepatterns.py +0 -0
  144. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/model/statistics.py +0 -0
  145. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/model/stats.py +0 -0
  146. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/model/suitestatistics.py +0 -0
  147. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/model/tags.py +0 -0
  148. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/model/tagsetter.py +0 -0
  149. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/model/tagstatistics.py +0 -0
  150. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/model/testcase.py +0 -0
  151. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/model/testsuite.py +0 -0
  152. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/model/totalstatistics.py +0 -0
  153. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/model/visitor.py +0 -0
  154. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/output/__init__.py +0 -0
  155. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/output/console/quiet.py +0 -0
  156. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/output/debugfile.py +0 -0
  157. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/output/filelogger.py +0 -0
  158. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/output/librarylogger.py +0 -0
  159. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/output/pyloggingconf.py +0 -0
  160. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/output/stdoutlogsplitter.py +0 -0
  161. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/output/xmllogger.py +0 -0
  162. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/parsing/__init__.py +0 -0
  163. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/parsing/lexer/__init__.py +0 -0
  164. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/parsing/lexer/blocklexers.py +0 -0
  165. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/parsing/lexer/context.py +0 -0
  166. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/parsing/lexer/lexer.py +0 -0
  167. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/parsing/lexer/settings.py +0 -0
  168. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/parsing/lexer/statementlexers.py +0 -0
  169. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/parsing/lexer/tokenizer.py +0 -0
  170. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/parsing/lexer/tokens.py +0 -0
  171. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/parsing/model/__init__.py +0 -0
  172. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/parsing/model/blocks.py +0 -0
  173. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/parsing/model/visitor.py +0 -0
  174. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/parsing/parser/__init__.py +0 -0
  175. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/parsing/parser/blockparsers.py +0 -0
  176. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/parsing/parser/fileparser.py +0 -0
  177. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/parsing/parser/parser.py +0 -0
  178. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/parsing/suitestructure.py +0 -0
  179. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/pythonpathsetter.py +0 -0
  180. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/reporting/__init__.py +0 -0
  181. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/reporting/expandkeywordmatcher.py +0 -0
  182. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/reporting/jsbuildingcontext.py +0 -0
  183. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/reporting/jsexecutionresult.py +0 -0
  184. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/reporting/jsmodelbuilders.py +0 -0
  185. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/reporting/jswriter.py +0 -0
  186. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/reporting/logreportwriters.py +0 -0
  187. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/reporting/outputwriter.py +0 -0
  188. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/reporting/resultwriter.py +0 -0
  189. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/reporting/stringcache.py +0 -0
  190. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/reporting/xunitwriter.py +0 -0
  191. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/result/__init__.py +0 -0
  192. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/result/configurer.py +0 -0
  193. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/result/executionerrors.py +0 -0
  194. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/result/flattenkeywordmatcher.py +0 -0
  195. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/result/keywordremover.py +0 -0
  196. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/result/merger.py +0 -0
  197. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/result/messagefilter.py +0 -0
  198. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/result/modeldeprecation.py +0 -0
  199. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/result/suiteteardownfailed.py +0 -0
  200. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/result/visitor.py +0 -0
  201. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/arguments/__init__.py +0 -0
  202. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/arguments/argumentconverter.py +0 -0
  203. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/arguments/argumentmapper.py +0 -0
  204. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/arguments/argumentparser.py +0 -0
  205. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/arguments/customconverters.py +0 -0
  206. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/arguments/typeconverters.py +0 -0
  207. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/arguments/typeinfo.py +0 -0
  208. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/arguments/typeinfoparser.py +0 -0
  209. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/arguments/typevalidator.py +0 -0
  210. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/builder/__init__.py +0 -0
  211. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/builder/builders.py +0 -0
  212. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/builder/parsers.py +0 -0
  213. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/builder/settings.py +0 -0
  214. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/builder/transformers.py +0 -0
  215. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/context.py +0 -0
  216. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/dynamicmethods.py +0 -0
  217. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/importer.py +0 -0
  218. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/keywordfinder.py +0 -0
  219. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/libraryscopes.py +0 -0
  220. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/outputcapture.py +0 -0
  221. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/randomizer.py +0 -0
  222. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/runkwregister.py +0 -0
  223. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/signalhandler.py +0 -0
  224. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/status.py +0 -0
  225. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/suiterunner.py +0 -0
  226. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/timeouts/__init__.py +0 -0
  227. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/timeouts/nosupport.py +0 -0
  228. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/timeouts/posix.py +0 -0
  229. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/timeouts/windows.py +0 -0
  230. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/testdoc.py +0 -0
  231. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/__init__.py +0 -0
  232. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/application.py +0 -0
  233. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/argumentparser.py +0 -0
  234. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/asserts.py +0 -0
  235. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/charwidth.py +0 -0
  236. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/compress.py +0 -0
  237. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/connectioncache.py +0 -0
  238. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/dotdict.py +0 -0
  239. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/encoding.py +0 -0
  240. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/error.py +0 -0
  241. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/escaping.py +0 -0
  242. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/etreewrapper.py +0 -0
  243. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/filereader.py +0 -0
  244. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/frange.py +0 -0
  245. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/htmlformatters.py +0 -0
  246. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/importer.py +0 -0
  247. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/markuputils.py +0 -0
  248. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/markupwriters.py +0 -0
  249. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/match.py +0 -0
  250. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/misc.py +0 -0
  251. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/normalizing.py +0 -0
  252. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/notset.py +0 -0
  253. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/platform.py +0 -0
  254. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/recommendations.py +0 -0
  255. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/restreader.py +0 -0
  256. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/robotenv.py +0 -0
  257. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/robotinspect.py +0 -0
  258. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/robotio.py +0 -0
  259. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/robotpath.py +0 -0
  260. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/robottypes.py +0 -0
  261. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/setter.py +0 -0
  262. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/sortable.py +0 -0
  263. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/text.py +0 -0
  264. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/typehints.py +0 -0
  265. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/unic.py +0 -0
  266. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/variables/__init__.py +0 -0
  267. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/variables/assigner.py +0 -0
  268. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/variables/filesetter.py +0 -0
  269. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/variables/finders.py +0 -0
  270. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/variables/notfound.py +0 -0
  271. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/variables/replacer.py +0 -0
  272. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/variables/resolvable.py +0 -0
  273. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/variables/search.py +0 -0
  274. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/variables/store.py +0 -0
  275. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/variables/variables.py +0 -0
  276. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robotframework.egg-info/SOURCES.txt +0 -0
  277. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robotframework.egg-info/dependency_links.txt +0 -0
  278. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robotframework.egg-info/entry_points.txt +0 -0
  279. {robotframework-7.0.1rc1 → robotframework-7.1}/src/robotframework.egg-info/top_level.txt +0 -0
  280. {robotframework-7.0.1rc1 → robotframework-7.1}/tasks.py +0 -0
@@ -56,8 +56,8 @@ class Logger(AbstractLogger):
56
56
  self._console_logger = None
57
57
  self._syslog = None
58
58
  self._xml_logger = None
59
- self._listeners = None
60
- self._library_listeners = None
59
+ self._cli_listeners = None
60
+ self._lib_listeners = None
61
61
  self._other_loggers = []
62
62
  self._message_cache = []
63
63
  self._log_message_cache = None
@@ -70,17 +70,25 @@ class Logger(AbstractLogger):
70
70
  if register_console_logger:
71
71
  self.register_console_logger()
72
72
 
73
+ @property
74
+ def _listeners(self):
75
+ cli_listeners = list(self._cli_listeners or [])
76
+ lib_listeners = list(self._lib_listeners or [])
77
+ return sorted(cli_listeners + lib_listeners, key=lambda li: -li.priority)
78
+
73
79
  @property
74
80
  def start_loggers(self):
75
- loggers = [self._console_logger, self._syslog, self._xml_logger,
76
- self._listeners, self._library_listeners]
77
- return [logger for logger in self._other_loggers + loggers if logger]
81
+ loggers = (self._other_loggers
82
+ + [self._console_logger, self._syslog, self._xml_logger]
83
+ + self._listeners)
84
+ return [logger for logger in loggers if logger]
78
85
 
79
86
  @property
80
87
  def end_loggers(self):
81
- loggers = [self._listeners, self._library_listeners,
82
- self._console_logger, self._syslog, self._xml_logger]
83
- return [logger for logger in loggers + self._other_loggers if logger]
88
+ loggers = (self._listeners
89
+ + [self._console_logger, self._syslog, self._xml_logger]
90
+ + self._other_loggers)
91
+ return [logger for logger in loggers if logger]
84
92
 
85
93
  def __iter__(self):
86
94
  return iter(self.end_loggers)
@@ -96,8 +104,8 @@ class Logger(AbstractLogger):
96
104
  self.close()
97
105
 
98
106
  def register_console_logger(self, type='verbose', width=78, colors='AUTO',
99
- markers='AUTO', stdout=None, stderr=None):
100
- 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)
101
109
  self._console_logger = self._wrap_and_relay(logger)
102
110
 
103
111
  def _wrap_and_relay(self, logger):
@@ -132,10 +140,10 @@ class Logger(AbstractLogger):
132
140
  self._xml_logger = None
133
141
 
134
142
  def register_listeners(self, listeners, library_listeners):
135
- self._listeners = listeners
136
- self._library_listeners = library_listeners
137
- if listeners:
138
- self._relay_cached_messages(listeners)
143
+ self._cli_listeners = listeners
144
+ self._lib_listeners = library_listeners
145
+ for listener in listeners or ():
146
+ self._relay_cached_messages(listener)
139
147
 
140
148
  def register_logger(self, *loggers):
141
149
  for logger in loggers:
@@ -398,9 +406,17 @@ class Logger(AbstractLogger):
398
406
  for logger in self.end_loggers:
399
407
  logger.end_error(data, result)
400
408
 
401
- def imported(self, import_type, name, **attrs):
409
+ def library_import(self, library, importer):
410
+ for logger in self:
411
+ logger.library_import(library, importer)
412
+
413
+ def resource_import(self, resource, importer):
414
+ for logger in self:
415
+ logger.resource_import(resource, importer)
416
+
417
+ def variables_import(self, variables, importer):
402
418
  for logger in self:
403
- logger.imported(import_type, name, attrs)
419
+ logger.variables_import(variables, importer)
404
420
 
405
421
  def output_file(self, path):
406
422
  for logger in self:
@@ -211,5 +211,16 @@ class LoggerApi:
211
211
  def imported(self, import_type: str, name: str, attrs):
212
212
  pass
213
213
 
214
+ def library_import(self, library: 'running.TestLibrary',
215
+ importer: 'running.Import'):
216
+ pass
217
+
218
+ def resource_import(self, resource: 'running.ResourceFile',
219
+ importer: 'running.Import'):
220
+ pass
221
+
222
+ def variables_import(self, attrs: dict, importer: 'running.Import'):
223
+ pass
224
+
214
225
  def close(self):
215
226
  pass
@@ -141,7 +141,12 @@ class IsLogged:
141
141
  self.__init__(level)
142
142
  return old
143
143
 
144
- def _level_to_int(self, level):
144
+ @classmethod
145
+ def validate_level(cls, level):
146
+ cls._level_to_int(level)
147
+
148
+ @classmethod
149
+ def _level_to_int(cls, level):
145
150
  try:
146
151
  return LEVELS[level.upper()]
147
152
  except KeyError:
@@ -18,7 +18,7 @@ from .debugfile import DebugFile
18
18
  from .listeners import Listeners, LibraryListeners
19
19
  from .logger import LOGGER
20
20
  from .loggerapi import LoggerApi
21
- from .loggerhelper import AbstractLogger
21
+ from .loggerhelper import AbstractLogger, IsLogged
22
22
  from .xmllogger import XmlLoggerAdapter
23
23
 
24
24
 
@@ -179,6 +179,7 @@ class Output(AbstractLogger, LoggerApi):
179
179
  self.write(msg, 'TRACE')
180
180
 
181
181
  def set_log_level(self, level):
182
+ IsLogged.validate_level(level)
182
183
  pyloggingconf.set_level(level)
183
184
  self.listeners.set_log_level(level)
184
185
  self.library_listeners.set_log_level(level)
@@ -1208,7 +1208,7 @@ class WhileHeader(Statement):
1208
1208
  class Var(Statement):
1209
1209
  type = Token.VAR
1210
1210
  options = {
1211
- 'scope': ('GLOBAL', 'SUITE', 'TEST', 'TASK', 'LOCAL'),
1211
+ 'scope': ('LOCAL', 'TEST', 'TASK', 'SUITE', 'SUITES', 'GLOBAL'),
1212
1212
  'separator': None
1213
1213
  }
1214
1214
 
@@ -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
@@ -64,6 +64,7 @@ class Result:
64
64
  #: :class:`~.executionerrors.ExecutionErrors` object.
65
65
  self.errors = errors or ExecutionErrors()
66
66
  self.generated_by_robot = True
67
+ self.generation_time = None
67
68
  self._status_rc = True
68
69
  self._stat_config = {}
69
70
  self.rpa = rpa
@@ -1133,7 +1133,7 @@ class TestSuite(model.TestSuite[Keyword, TestCase], StatusMixin):
1133
1133
  if output is None:
1134
1134
  output = StringIO()
1135
1135
  elif isinstance(output, (Path, str)):
1136
- output = open(output, 'w')
1136
+ output = open(output, 'w', encoding='UTF-8')
1137
1137
  close = True
1138
1138
  return output, close
1139
1139
 
@@ -13,8 +13,6 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
 
16
- from pathlib import Path
17
-
18
16
  from robot.errors import DataError
19
17
  from robot.model import SuiteVisitor
20
18
  from robot.utils import ET, ETSource, get_error_message
@@ -82,9 +80,13 @@ def _single_result(source, options):
82
80
  def _json_result(source, options):
83
81
  try:
84
82
  suite = TestSuite.from_json(source)
83
+ except IOError as err:
84
+ error = err.strerror
85
85
  except Exception:
86
- raise DataError(f"Reading JSON source '{source}' failed: {get_error_message()}")
87
- return Result(source, suite, rpa=options.pop('rpa', None))
86
+ error = get_error_message()
87
+ else:
88
+ return Result(source, suite, rpa=options.pop('rpa', None))
89
+ raise DataError(f"Reading JSON source '{source}' failed: {error}")
88
90
 
89
91
 
90
92
  def _xml_result(source, options):
@@ -150,27 +152,27 @@ class ExecutionResultBuilder:
150
152
  elem.clear()
151
153
 
152
154
  def _omit_keywords(self, context):
153
- omitted_kws = 0
155
+ omitted_elements = {'kw', 'for', 'while', 'if', 'try'}
156
+ omitted = 0
154
157
  for event, elem in context:
155
158
  # Teardowns aren't omitted yet to allow checking suite teardown status.
156
159
  # They'll be removed later when not needed in `build()`.
157
- omit = elem.tag in ('kw', 'for', 'if') and elem.get('type') != 'TEARDOWN'
160
+ omit = elem.tag in omitted_elements and elem.get('type') != 'TEARDOWN'
158
161
  start = event == 'start'
159
162
  if omit and start:
160
- omitted_kws += 1
161
- if not omitted_kws:
163
+ omitted += 1
164
+ if not omitted:
162
165
  yield event, elem
163
166
  elif not start:
164
167
  elem.clear()
165
168
  if omit and not start:
166
- omitted_kws -= 1
169
+ omitted -= 1
167
170
 
168
171
  def _flatten_keywords(self, context, flattened):
169
172
  # Performance optimized. Do not change without profiling!
170
173
  name_match, by_name = self._get_matcher(FlattenByNameMatcher, flattened)
171
174
  type_match, by_type = self._get_matcher(FlattenByTypeMatcher, flattened)
172
175
  started = -1 # if 0 or more, we are flattening
173
- tags = []
174
176
  containers = {'kw', 'for', 'while', 'iter', 'if', 'try'}
175
177
  inside = 0 # to make sure we don't read tags from a test
176
178
  for event, elem in context:
@@ -185,7 +187,6 @@ class ExecutionResultBuilder:
185
187
  started = 0
186
188
  elif by_type and type_match(tag):
187
189
  started = 0
188
- tags = []
189
190
  else:
190
191
  if tag in containers:
191
192
  inside -= 1
@@ -60,6 +60,9 @@ class ElementHandler:
60
60
 
61
61
  def _legacy_timestamp(self, elem, attr_name):
62
62
  ts = elem.get(attr_name)
63
+ return self._parse_legacy_timestamp(ts)
64
+
65
+ def _parse_legacy_timestamp(self, ts):
63
66
  if ts == 'N/A' or not ts:
64
67
  return None
65
68
  ts = ts.ljust(24, '0')
@@ -85,10 +88,19 @@ class RobotHandler(ElementHandler):
85
88
  def start(self, elem, result):
86
89
  generator = elem.get('generator', 'unknown').split()[0].upper()
87
90
  result.generated_by_robot = generator == 'ROBOT'
91
+ result.generation_time = self._parse_generation_time(elem.get('generated'))
88
92
  if result.rpa is None:
89
93
  result.rpa = elem.get('rpa', 'false') == 'true'
90
94
  return result
91
95
 
96
+ def _parse_generation_time(self, generated):
97
+ if not generated:
98
+ return None
99
+ try:
100
+ return datetime.fromisoformat(generated)
101
+ except ValueError:
102
+ return self._parse_legacy_timestamp(generated)
103
+
92
104
 
93
105
  @ElementHandler.register
94
106
  class SuiteHandler(ElementHandler):
@@ -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.
@@ -123,6 +123,6 @@ from .librarykeyword import LibraryKeyword
123
123
  from .model import (Break, Continue, Error, For, ForIteration, If, IfBranch, Keyword,
124
124
  Return, TestCase, TestSuite, Try, TryBranch, Var, While,
125
125
  WhileIteration)
126
- from .resourcemodel import ResourceFile, UserKeyword
126
+ from .resourcemodel import Import, ResourceFile, UserKeyword, Variable
127
127
  from .runkwregister import RUN_KW_REGISTER
128
128
  from .testlibraries import TestLibrary
@@ -20,6 +20,7 @@ from robot.utils import is_dict_like, split_from_equals
20
20
  from robot.variables import is_dict_variable
21
21
 
22
22
  from .argumentvalidator import ArgumentValidator
23
+ from ..model import Argument
23
24
 
24
25
  if TYPE_CHECKING:
25
26
  from .argumentspec import ArgumentSpec
@@ -37,8 +38,11 @@ class ArgumentResolver:
37
38
  self.dict_to_kwargs = DictToKwargs(spec, dict_to_kwargs)
38
39
  self.argument_validator = ArgumentValidator(spec)
39
40
 
40
- def resolve(self, arguments, variables=None):
41
- positional, named = self.named_resolver.resolve(arguments, variables)
41
+ def resolve(self, args, named_args=None, variables=None):
42
+ if named_args is None:
43
+ positional, named = self.named_resolver.resolve(args, variables)
44
+ else:
45
+ positional, named = args, list(named_args.items())
42
46
  positional, named = self.variable_replacer.replace(positional, named, variables)
43
47
  positional, named = self.dict_to_kwargs.handle(positional, named)
44
48
  self.argument_validator.validate(positional, named, dryrun=variables is None)
@@ -51,14 +55,15 @@ class NamedArgumentResolver:
51
55
  self.spec = spec
52
56
 
53
57
  def resolve(self, arguments, variables=None):
54
- spec = self.spec
55
- positional = list(arguments[:len(spec.embedded)])
58
+ known_positional_count = max(len(self.spec.positional_only),
59
+ len(self.spec.embedded))
60
+ positional = list(arguments[:known_positional_count])
56
61
  named = []
57
- for arg in arguments[len(spec.embedded):]:
62
+ for arg in arguments[known_positional_count:]:
58
63
  if is_dict_variable(arg):
59
64
  named.append(arg)
60
65
  else:
61
- name, value = self._split_named(arg, named, variables, spec)
66
+ name, value = self._split_named(arg, named, variables)
62
67
  if name is not None:
63
68
  named.append((name, value))
64
69
  elif named:
@@ -67,21 +72,23 @@ class NamedArgumentResolver:
67
72
  positional.append(value)
68
73
  return positional, named
69
74
 
70
- def _split_named(self, arg, previous_named, variables, spec):
75
+ def _split_named(self, arg, previous_named, variables):
76
+ if isinstance(arg, Argument):
77
+ return arg.name, arg.value
71
78
  name, value = split_from_equals(arg)
72
- if value is None or not self._is_named(name, previous_named, variables, spec):
79
+ if value is None or not self._is_named(name, previous_named, variables):
73
80
  return None, arg
74
81
  return name, value
75
82
 
76
- def _is_named(self, name, previous_named, variables, spec):
77
- if previous_named or spec.var_named:
83
+ def _is_named(self, name, previous_named, variables):
84
+ if previous_named or self.spec.var_named:
78
85
  return True
79
86
  if variables:
80
87
  try:
81
88
  name = variables.replace_scalar(name)
82
89
  except DataError:
83
90
  return False
84
- return name in spec.named
91
+ return name in self.spec.named
85
92
 
86
93
  def _raise_positional_after_named(self):
87
94
  raise DataError(f"{self.spec.type.capitalize()} '{self.spec.name}' "
@@ -96,12 +96,12 @@ class ArgumentSpec(metaclass=SetterAwareType):
96
96
  return (self.positional_only + self.positional_or_named + var_positional +
97
97
  self.named_only + var_named)
98
98
 
99
- def resolve(self, arguments, variables=None, converters=None,
99
+ def resolve(self, args, named_args=None, variables=None, converters=None,
100
100
  resolve_named=True, resolve_args_until=None,
101
101
  dict_to_kwargs=False, languages=None) -> 'tuple[list, list]':
102
102
  resolver = ArgumentResolver(self, resolve_named, resolve_args_until,
103
103
  dict_to_kwargs)
104
- positional, named = resolver.resolve(arguments, variables)
104
+ positional, named = resolver.resolve(args, named_args, variables)
105
105
  return self.convert(positional, named, converters, dry_run=not variables,
106
106
  languages=languages)
107
107
 
@@ -34,7 +34,6 @@ class ArgumentValidator:
34
34
  any(is_dict_variable(arg) for arg in named)):
35
35
  return
36
36
  self._validate_no_multiple_values(positional, named, self.spec)
37
- self._validate_no_positional_only_as_named(named, self.spec)
38
37
  self._validate_positional_limits(positional, named, self.spec)
39
38
  self._validate_no_mandatory_missing(positional, named, self.spec)
40
39
  self._validate_no_named_only_missing(named, self.spec)
@@ -49,13 +48,6 @@ class ArgumentValidator:
49
48
  name = f"'{self.spec.name}' " if self.spec.name else ''
50
49
  raise DataError(f"{self.spec.type.capitalize()} {name}{message}.")
51
50
 
52
- def _validate_no_positional_only_as_named(self, named, spec):
53
- if not spec.var_named:
54
- for name in named:
55
- if name in spec.positional_only:
56
- self._raise_error(f"does not accept argument '{name}' as named "
57
- f"argument")
58
-
59
51
  def _validate_positional_limits(self, positional, named, spec):
60
52
  count = len(positional) + self._named_positionals(named, spec)
61
53
  if not spec.minargs <= count <= spec.maxargs:
@@ -80,7 +80,7 @@ class EmbeddedArgumentParser:
80
80
  args = []
81
81
  custom_patterns = {}
82
82
  after = string
83
- for match in VariableMatches(string, identifiers='$'):
83
+ for match in VariableMatches(' '.join(string.split()), identifiers='$'):
84
84
  arg, pattern, is_custom = self._get_name_and_pattern(match.base)
85
85
  args.append(arg)
86
86
  if is_custom:
@@ -139,7 +139,7 @@ class EmbeddedArgumentParser:
139
139
 
140
140
  def _compile_regexp(self, pattern: str) -> re.Pattern:
141
141
  try:
142
- return re.compile(''.join(pattern), re.IGNORECASE)
142
+ return re.compile(pattern.replace(r'\ ', r'\s'), re.IGNORECASE)
143
143
  except Exception:
144
144
  raise DataError(f"Compiling embedded arguments regexp failed: "
145
145
  f"{get_error_message()}")
@@ -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):
@@ -54,9 +54,12 @@ class InvalidKeywordRunner:
54
54
 
55
55
  def run(self, data: KeywordData, result: KeywordResult, context, run=True):
56
56
  kw = self.keyword.bind(data)
57
+ args = tuple(data.args)
58
+ if data.named_args:
59
+ args += tuple(f'{n}={v}' for n, v in data.named_args.items())
57
60
  result.config(name=self.name,
58
61
  owner=kw.owner.name if kw.owner else None,
59
- args=data.args,
62
+ args=args,
60
63
  assign=tuple(VariableAssignment(data.assign)),
61
64
  type=data.type)
62
65
  with StatusReporter(data, result, context, run, implementation=kw):
@@ -14,7 +14,7 @@
14
14
  # limitations under the License.
15
15
 
16
16
  from pathlib import Path
17
- from typing import Any, Literal, Sequence, TYPE_CHECKING
17
+ from typing import Any, Literal, Mapping, Sequence, TYPE_CHECKING
18
18
 
19
19
  from robot.model import ModelObject, Tags
20
20
  from robot.utils import eq, getshortdoc, setter
@@ -23,6 +23,8 @@ from .arguments import ArgInfo, ArgumentSpec, EmbeddedArguments
23
23
  from .model import BodyItemParent, Keyword
24
24
 
25
25
  if TYPE_CHECKING:
26
+ from robot.conf import LanguagesLike
27
+
26
28
  from .librarykeywordrunner import LibraryKeywordRunner
27
29
  from .resourcemodel import ResourceFile
28
30
  from .testlibraries import TestLibrary
@@ -141,11 +143,13 @@ class KeywordImplementation(ModelObject):
141
143
  return self.embedded.match(name) is not None
142
144
  return eq(self.name, name, ignore='_')
143
145
 
144
- def resolve_arguments(self, args: Sequence[str], variables=None,
145
- languages=None) -> 'tuple[list, list]':
146
- return self.args.resolve(args, variables, languages=languages)
146
+ def resolve_arguments(self, args: 'Sequence[str|Any]',
147
+ named_args: 'Mapping[str, Any]|None' = None,
148
+ variables=None,
149
+ languages: 'LanguagesLike' = None) -> 'tuple[list, list]':
150
+ return self.args.resolve(args, named_args, variables, languages=languages)
147
151
 
148
- def create_runner(self, name: 'str|None', languages=None) \
152
+ def create_runner(self, name: 'str|None', languages: 'LanguagesLike' = None) \
149
153
  -> 'LibraryKeywordRunner|UserKeywordRunner':
150
154
  raise NotImplementedError
151
155
 
@@ -16,7 +16,7 @@
16
16
  import inspect
17
17
  from os.path import normpath
18
18
  from pathlib import Path
19
- from typing import Any, Callable, Generic, Sequence, TypeVar, TYPE_CHECKING
19
+ from typing import Any, Callable, Generic, Mapping, Sequence, TypeVar, TYPE_CHECKING
20
20
 
21
21
  from robot.model import Tags
22
22
  from robot.errors import DataError
@@ -29,10 +29,13 @@ from .dynamicmethods import (GetKeywordArguments, GetKeywordDocumentation,
29
29
  RunKeyword)
30
30
  from .model import BodyItemParent, Keyword
31
31
  from .keywordimplementation import KeywordImplementation
32
- from .librarykeywordrunner import EmbeddedArgumentsRunner, LibraryKeywordRunner, RunKeywordRunner
32
+ from .librarykeywordrunner import (EmbeddedArgumentsRunner, LibraryKeywordRunner,
33
+ RunKeywordRunner)
33
34
  from .runkwregister import RUN_KW_REGISTER
34
35
 
35
36
  if TYPE_CHECKING:
37
+ from robot.conf import LanguagesLike
38
+
36
39
  from .testlibraries import DynamicLibrary, TestLibrary
37
40
 
38
41
 
@@ -73,7 +76,8 @@ class LibraryKeyword(KeywordImplementation):
73
76
  return start_lineno + increment
74
77
  return start_lineno
75
78
 
76
- def create_runner(self, name: 'str|None', languages=None) -> LibraryKeywordRunner:
79
+ def create_runner(self, name: 'str|None',
80
+ languages: 'LanguagesLike' = None) -> LibraryKeywordRunner:
77
81
  if self.embedded:
78
82
  return EmbeddedArgumentsRunner(self, name)
79
83
  if self._resolve_args_until is not None:
@@ -81,10 +85,13 @@ class LibraryKeyword(KeywordImplementation):
81
85
  return RunKeywordRunner(self, execute_in_dry_run=dry_run)
82
86
  return LibraryKeywordRunner(self, languages=languages)
83
87
 
84
- def resolve_arguments(self, args: Sequence[str], variables=None,
85
- languages=None) -> 'tuple[list, list]':
88
+ def resolve_arguments(self, args: 'Sequence[str|Any]',
89
+ named_args: 'Mapping[str, Any]|None' = None,
90
+ variables=None,
91
+ languages: 'LanguagesLike' = None) -> 'tuple[list, list]':
86
92
  resolve_args_until = self._resolve_args_until
87
- positional, named = self.args.resolve(args, variables, self.owner.converters,
93
+ positional, named = self.args.resolve(args, named_args, variables,
94
+ self.owner.converters,
88
95
  resolve_named=resolve_args_until is None,
89
96
  resolve_args_until=resolve_args_until,
90
97
  languages=languages)
@@ -198,9 +205,12 @@ class DynamicKeyword(LibraryKeyword):
198
205
  def from_name(cls, name: str, owner: 'DynamicLibrary') -> 'DynamicKeyword':
199
206
  return DynamicKeywordCreator(name, owner).create()
200
207
 
201
- def resolve_arguments(self, arguments, variables=None,
202
- languages=None) -> 'tuple[list, list]':
203
- positional, named = super().resolve_arguments(arguments, variables, languages)
208
+ def resolve_arguments(self, args: 'Sequence[str|Any]',
209
+ named_args: 'Mapping[str, Any]|None' = None,
210
+ variables=None,
211
+ languages: 'LanguagesLike' = None) -> 'tuple[list, list]':
212
+ positional, named = super().resolve_arguments(args, named_args, variables,
213
+ languages)
204
214
  if not self.owner.supports_named_args:
205
215
  positional, named = self.args.map(positional, named)
206
216
  return positional, named