robotframework 7.0.1rc2__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.1rc2 → robotframework-7.1}/PKG-INFO +3 -2
  2. {robotframework-7.0.1rc2 → robotframework-7.1}/setup.py +2 -1
  3. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/api/interfaces.py +32 -0
  4. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/conf/languages.py +73 -18
  5. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/conf/settings.py +8 -1
  6. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/htmldata/rebot/model.js +22 -33
  7. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/htmldata/template.py +0 -2
  8. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/libdocpkg/jsonbuilder.py +1 -1
  9. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/libraries/BuiltIn.py +16 -3
  10. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/libraries/Collections.py +2 -3
  11. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/libraries/DateTime.py +3 -2
  12. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/libraries/Dialogs.py +12 -4
  13. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/libraries/OperatingSystem.py +4 -4
  14. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/libraries/Process.py +7 -3
  15. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/libraries/String.py +4 -1
  16. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/libraries/dialogs_py.py +17 -1
  17. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/model/modelobject.py +1 -6
  18. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/output/console/__init__.py +3 -3
  19. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/output/console/dotted.py +4 -4
  20. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/output/console/highlighting.py +90 -65
  21. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/output/console/verbose.py +10 -10
  22. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/output/listeners.py +61 -217
  23. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/output/logger.py +32 -16
  24. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/output/loggerapi.py +11 -0
  25. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/output/loggerhelper.py +6 -1
  26. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/output/output.py +2 -1
  27. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/parsing/model/statements.py +1 -1
  28. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/rebot.py +3 -0
  29. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/result/executionresult.py +1 -0
  30. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/result/model.py +1 -1
  31. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/result/resultbuilder.py +12 -11
  32. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/result/xmlelementhandlers.py +12 -0
  33. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/run.py +3 -0
  34. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/running/__init__.py +1 -1
  35. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/running/arguments/argumentresolver.py +15 -11
  36. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/running/arguments/argumentspec.py +2 -2
  37. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/running/arguments/argumentvalidator.py +0 -8
  38. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/running/arguments/embedded.py +2 -2
  39. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/running/bodyrunner.py +34 -19
  40. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/running/invalidkeyword.py +4 -1
  41. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/running/keywordimplementation.py +9 -5
  42. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/running/librarykeyword.py +19 -9
  43. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/running/librarykeywordrunner.py +25 -19
  44. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/running/model.py +45 -26
  45. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/running/namespace.py +20 -26
  46. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/running/resourcemodel.py +9 -1
  47. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/running/statusreporter.py +9 -4
  48. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/running/testlibraries.py +2 -2
  49. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/running/userkeywordrunner.py +10 -7
  50. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/utils/encodingsniffer.py +3 -1
  51. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/utils/robottime.py +5 -3
  52. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/variables/evaluation.py +1 -4
  53. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/variables/scopes.py +2 -1
  54. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/variables/tablesetter.py +17 -20
  55. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/version.py +1 -1
  56. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robotframework.egg-info/PKG-INFO +3 -2
  57. {robotframework-7.0.1rc2 → robotframework-7.1}/AUTHORS.rst +0 -0
  58. {robotframework-7.0.1rc2 → robotframework-7.1}/BUILD.rst +0 -0
  59. {robotframework-7.0.1rc2 → robotframework-7.1}/CONTRIBUTING.rst +0 -0
  60. {robotframework-7.0.1rc2 → robotframework-7.1}/COPYRIGHT.txt +0 -0
  61. {robotframework-7.0.1rc2 → robotframework-7.1}/INSTALL.rst +0 -0
  62. {robotframework-7.0.1rc2 → robotframework-7.1}/LICENSE.txt +0 -0
  63. {robotframework-7.0.1rc2 → robotframework-7.1}/MANIFEST.in +0 -0
  64. {robotframework-7.0.1rc2 → robotframework-7.1}/README.rst +0 -0
  65. {robotframework-7.0.1rc2 → robotframework-7.1}/setup.cfg +0 -0
  66. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/__init__.py +0 -0
  67. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/__main__.py +0 -0
  68. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/api/__init__.py +0 -0
  69. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/api/deco.py +0 -0
  70. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/api/exceptions.py +0 -0
  71. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/api/logger.py +0 -0
  72. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/api/parsing.py +0 -0
  73. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/api/py.typed +0 -0
  74. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/conf/__init__.py +0 -0
  75. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/conf/gatherfailed.py +0 -0
  76. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/errors.py +0 -0
  77. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/htmldata/__init__.py +0 -0
  78. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/htmldata/common/__init__.py +0 -0
  79. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/htmldata/common/js_disabled.css +0 -0
  80. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/htmldata/common/storage.js +0 -0
  81. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/htmldata/htmlfilewriter.py +0 -0
  82. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/htmldata/jsonwriter.py +0 -0
  83. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/htmldata/lib/__init__.py +0 -0
  84. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/htmldata/lib/jquery.highlight.min.js +0 -0
  85. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/htmldata/lib/jquery.min.js +0 -0
  86. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/htmldata/lib/jquery.tablesorter.min.js +0 -0
  87. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/htmldata/lib/jquery.tmpl.min.js +0 -0
  88. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/htmldata/lib/jsxcompressor.min.js +0 -0
  89. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/htmldata/libdoc/__init__.py +0 -0
  90. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/htmldata/libdoc/doc_formatting.css +0 -0
  91. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/htmldata/libdoc/libdoc.css +0 -0
  92. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/htmldata/libdoc/libdoc.html +0 -0
  93. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/htmldata/libdoc/print.css +0 -0
  94. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/htmldata/libdoc/pygments.css +0 -0
  95. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/htmldata/rebot/__init__.py +0 -0
  96. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/htmldata/rebot/common.css +0 -0
  97. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/htmldata/rebot/doc_formatting.css +0 -0
  98. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/htmldata/rebot/fileloading.js +0 -0
  99. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/htmldata/rebot/log.css +0 -0
  100. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/htmldata/rebot/log.html +0 -0
  101. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/htmldata/rebot/log.js +0 -0
  102. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/htmldata/rebot/print.css +0 -0
  103. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/htmldata/rebot/report.css +0 -0
  104. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/htmldata/rebot/report.html +0 -0
  105. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/htmldata/rebot/testdata.js +0 -0
  106. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/htmldata/rebot/util.js +0 -0
  107. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/htmldata/rebot/view.js +0 -0
  108. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/htmldata/testdoc/__init__.py +0 -0
  109. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/htmldata/testdoc/testdoc.css +0 -0
  110. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/htmldata/testdoc/testdoc.html +0 -0
  111. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/libdoc.py +0 -0
  112. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/libdocpkg/__init__.py +0 -0
  113. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/libdocpkg/builder.py +0 -0
  114. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/libdocpkg/consoleviewer.py +0 -0
  115. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/libdocpkg/datatypes.py +0 -0
  116. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/libdocpkg/htmlutils.py +0 -0
  117. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/libdocpkg/htmlwriter.py +0 -0
  118. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/libdocpkg/jsonwriter.py +0 -0
  119. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/libdocpkg/model.py +0 -0
  120. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/libdocpkg/output.py +0 -0
  121. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/libdocpkg/robotbuilder.py +0 -0
  122. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/libdocpkg/standardtypes.py +0 -0
  123. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/libdocpkg/writer.py +0 -0
  124. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/libdocpkg/xmlbuilder.py +0 -0
  125. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/libdocpkg/xmlwriter.py +0 -0
  126. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/libraries/Easter.py +0 -0
  127. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/libraries/Remote.py +0 -0
  128. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/libraries/Screenshot.py +0 -0
  129. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/libraries/Telnet.py +0 -0
  130. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/libraries/XML.py +0 -0
  131. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/libraries/__init__.py +0 -0
  132. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/model/__init__.py +0 -0
  133. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/model/body.py +0 -0
  134. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/model/configurer.py +0 -0
  135. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/model/control.py +0 -0
  136. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/model/filter.py +0 -0
  137. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/model/fixture.py +0 -0
  138. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/model/itemlist.py +0 -0
  139. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/model/keyword.py +0 -0
  140. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/model/message.py +0 -0
  141. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/model/metadata.py +0 -0
  142. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/model/modifier.py +0 -0
  143. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/model/namepatterns.py +0 -0
  144. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/model/statistics.py +0 -0
  145. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/model/stats.py +0 -0
  146. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/model/suitestatistics.py +0 -0
  147. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/model/tags.py +0 -0
  148. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/model/tagsetter.py +0 -0
  149. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/model/tagstatistics.py +0 -0
  150. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/model/testcase.py +0 -0
  151. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/model/testsuite.py +0 -0
  152. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/model/totalstatistics.py +0 -0
  153. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/model/visitor.py +0 -0
  154. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/output/__init__.py +0 -0
  155. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/output/console/quiet.py +0 -0
  156. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/output/debugfile.py +0 -0
  157. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/output/filelogger.py +0 -0
  158. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/output/librarylogger.py +0 -0
  159. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/output/pyloggingconf.py +0 -0
  160. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/output/stdoutlogsplitter.py +0 -0
  161. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/output/xmllogger.py +0 -0
  162. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/parsing/__init__.py +0 -0
  163. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/parsing/lexer/__init__.py +0 -0
  164. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/parsing/lexer/blocklexers.py +0 -0
  165. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/parsing/lexer/context.py +0 -0
  166. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/parsing/lexer/lexer.py +0 -0
  167. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/parsing/lexer/settings.py +0 -0
  168. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/parsing/lexer/statementlexers.py +0 -0
  169. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/parsing/lexer/tokenizer.py +0 -0
  170. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/parsing/lexer/tokens.py +0 -0
  171. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/parsing/model/__init__.py +0 -0
  172. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/parsing/model/blocks.py +0 -0
  173. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/parsing/model/visitor.py +0 -0
  174. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/parsing/parser/__init__.py +0 -0
  175. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/parsing/parser/blockparsers.py +0 -0
  176. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/parsing/parser/fileparser.py +0 -0
  177. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/parsing/parser/parser.py +0 -0
  178. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/parsing/suitestructure.py +0 -0
  179. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/pythonpathsetter.py +0 -0
  180. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/reporting/__init__.py +0 -0
  181. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/reporting/expandkeywordmatcher.py +0 -0
  182. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/reporting/jsbuildingcontext.py +0 -0
  183. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/reporting/jsexecutionresult.py +0 -0
  184. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/reporting/jsmodelbuilders.py +0 -0
  185. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/reporting/jswriter.py +0 -0
  186. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/reporting/logreportwriters.py +0 -0
  187. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/reporting/outputwriter.py +0 -0
  188. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/reporting/resultwriter.py +0 -0
  189. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/reporting/stringcache.py +0 -0
  190. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/reporting/xunitwriter.py +0 -0
  191. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/result/__init__.py +0 -0
  192. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/result/configurer.py +0 -0
  193. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/result/executionerrors.py +0 -0
  194. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/result/flattenkeywordmatcher.py +0 -0
  195. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/result/keywordremover.py +0 -0
  196. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/result/merger.py +0 -0
  197. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/result/messagefilter.py +0 -0
  198. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/result/modeldeprecation.py +0 -0
  199. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/result/suiteteardownfailed.py +0 -0
  200. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/result/visitor.py +0 -0
  201. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/running/arguments/__init__.py +0 -0
  202. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/running/arguments/argumentconverter.py +0 -0
  203. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/running/arguments/argumentmapper.py +0 -0
  204. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/running/arguments/argumentparser.py +0 -0
  205. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/running/arguments/customconverters.py +0 -0
  206. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/running/arguments/typeconverters.py +0 -0
  207. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/running/arguments/typeinfo.py +0 -0
  208. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/running/arguments/typeinfoparser.py +0 -0
  209. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/running/arguments/typevalidator.py +0 -0
  210. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/running/builder/__init__.py +0 -0
  211. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/running/builder/builders.py +0 -0
  212. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/running/builder/parsers.py +0 -0
  213. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/running/builder/settings.py +0 -0
  214. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/running/builder/transformers.py +0 -0
  215. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/running/context.py +0 -0
  216. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/running/dynamicmethods.py +0 -0
  217. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/running/importer.py +0 -0
  218. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/running/keywordfinder.py +0 -0
  219. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/running/libraryscopes.py +0 -0
  220. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/running/outputcapture.py +0 -0
  221. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/running/randomizer.py +0 -0
  222. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/running/runkwregister.py +0 -0
  223. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/running/signalhandler.py +0 -0
  224. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/running/status.py +0 -0
  225. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/running/suiterunner.py +0 -0
  226. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/running/timeouts/__init__.py +0 -0
  227. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/running/timeouts/nosupport.py +0 -0
  228. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/running/timeouts/posix.py +0 -0
  229. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/running/timeouts/windows.py +0 -0
  230. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/testdoc.py +0 -0
  231. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/utils/__init__.py +0 -0
  232. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/utils/application.py +0 -0
  233. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/utils/argumentparser.py +0 -0
  234. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/utils/asserts.py +0 -0
  235. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/utils/charwidth.py +0 -0
  236. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/utils/compress.py +0 -0
  237. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/utils/connectioncache.py +0 -0
  238. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/utils/dotdict.py +0 -0
  239. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/utils/encoding.py +0 -0
  240. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/utils/error.py +0 -0
  241. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/utils/escaping.py +0 -0
  242. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/utils/etreewrapper.py +0 -0
  243. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/utils/filereader.py +0 -0
  244. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/utils/frange.py +0 -0
  245. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/utils/htmlformatters.py +0 -0
  246. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/utils/importer.py +0 -0
  247. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/utils/markuputils.py +0 -0
  248. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/utils/markupwriters.py +0 -0
  249. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/utils/match.py +0 -0
  250. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/utils/misc.py +0 -0
  251. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/utils/normalizing.py +0 -0
  252. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/utils/notset.py +0 -0
  253. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/utils/platform.py +0 -0
  254. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/utils/recommendations.py +0 -0
  255. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/utils/restreader.py +0 -0
  256. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/utils/robotenv.py +0 -0
  257. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/utils/robotinspect.py +0 -0
  258. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/utils/robotio.py +0 -0
  259. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/utils/robotpath.py +0 -0
  260. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/utils/robottypes.py +0 -0
  261. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/utils/setter.py +0 -0
  262. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/utils/sortable.py +0 -0
  263. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/utils/text.py +0 -0
  264. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/utils/typehints.py +0 -0
  265. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/utils/unic.py +0 -0
  266. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/variables/__init__.py +0 -0
  267. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/variables/assigner.py +0 -0
  268. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/variables/filesetter.py +0 -0
  269. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/variables/finders.py +0 -0
  270. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/variables/notfound.py +0 -0
  271. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/variables/replacer.py +0 -0
  272. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/variables/resolvable.py +0 -0
  273. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/variables/search.py +0 -0
  274. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/variables/store.py +0 -0
  275. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robot/variables/variables.py +0 -0
  276. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robotframework.egg-info/SOURCES.txt +0 -0
  277. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robotframework.egg-info/dependency_links.txt +0 -0
  278. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robotframework.egg-info/entry_points.txt +0 -0
  279. {robotframework-7.0.1rc2 → robotframework-7.1}/src/robotframework.egg-info/top_level.txt +0 -0
  280. {robotframework-7.0.1rc2 → robotframework-7.1}/tasks.py +0 -0
@@ -49,32 +49,38 @@ class LibraryKeywordRunner:
49
49
  with StatusReporter(data, result, context, run, implementation=kw):
50
50
  if run:
51
51
  with assignment.assigner(context) as assigner:
52
- return_value = self._run(kw, data.args, result, context)
52
+ return_value = self._run(data, kw, context)
53
53
  assigner.assign(return_value)
54
54
  return return_value
55
55
 
56
56
  def _config_result(self, result: KeywordResult, data: KeywordData,
57
57
  kw: 'LibraryKeyword', assignment):
58
+ args = tuple(data.args)
59
+ if data.named_args:
60
+ args += tuple(f'{n}={v}' for n, v in data.named_args.items())
58
61
  result.config(name=self.name,
59
62
  owner=kw.owner.name,
60
63
  doc=kw.short_doc,
61
- args=data.args,
64
+ args=args,
62
65
  assign=tuple(assignment),
63
66
  tags=kw.tags,
64
67
  type=data.type)
65
68
 
66
- def _run(self, kw: 'LibraryKeyword', args, result: KeywordResult, context):
69
+ def _run(self, data: KeywordData, kw: 'LibraryKeyword', context):
67
70
  if self.pre_run_messages:
68
71
  for message in self.pre_run_messages:
69
72
  context.output.message(message)
70
73
  variables = context.variables if not context.dry_run else None
71
- positional, named = kw.resolve_arguments(args, variables, self.languages)
74
+ positional, named = self._resolve_arguments(data, kw, variables)
72
75
  context.output.trace(lambda: self._trace_log_args(positional, named),
73
76
  write_if_flat=False)
74
77
  if kw.error:
75
78
  raise DataError(kw.error)
76
79
  return self._execute(kw.method, positional, named, context)
77
80
 
81
+ def _resolve_arguments(self, data: KeywordData, kw: 'LibraryKeyword', variables=None):
82
+ return kw.resolve_arguments(data.args, data.named_args, variables, self.languages)
83
+
78
84
  def _trace_log_args(self, positional, named):
79
85
  args = [prepr(arg) for arg in positional]
80
86
  args += ['%s=%s' % (safe_str(n), prepr(v)) for n, v in named]
@@ -127,18 +133,20 @@ class LibraryKeywordRunner:
127
133
  self._config_result(result, data, kw, assignment)
128
134
  with StatusReporter(data, result, context, run=False, implementation=kw):
129
135
  assignment.validate_assignment()
130
- self._dry_run(kw, data.args, result, context)
136
+ if self._executed_in_dry_run(kw):
137
+ self._run(data, kw, context)
138
+ else:
139
+ self._resolve_arguments(data, kw)
140
+ self._end_dry_run(data, kw, result, context)
131
141
 
132
- def _dry_run(self, kw: 'LibraryKeyword', args, result: KeywordResult, context):
133
- if self._executed_in_dry_run(kw):
134
- self._run(kw, args, result, context)
135
- else:
136
- kw.resolve_arguments(args, languages=self.languages)
142
+ def _end_dry_run(self, data: KeywordData, kw: 'LibraryKeyword',
143
+ result: KeywordResult, context):
144
+ pass
137
145
 
138
146
  def _executed_in_dry_run(self, kw: 'LibraryKeyword'):
139
147
  return (kw.owner.name == 'BuiltIn'
140
148
  and kw.name in ('Import Library', 'Set Library Search Order',
141
- 'Set Tags', 'Remove Tags'))
149
+ 'Set Tags', 'Remove Tags', 'Import Resource'))
142
150
 
143
151
 
144
152
  class EmbeddedArgumentsRunner(LibraryKeywordRunner):
@@ -147,11 +155,9 @@ class EmbeddedArgumentsRunner(LibraryKeywordRunner):
147
155
  super().__init__(keyword, name)
148
156
  self.embedded_args = keyword.embedded.match(name).groups()
149
157
 
150
- def _run(self, kw: 'LibraryKeyword', args, result: KeywordResult, context):
151
- return super()._run(kw, self.embedded_args + args, result, context)
152
-
153
- def _dry_run(self, kw: 'LibraryKeyword', args, result: KeywordResult, context):
154
- return super()._dry_run(kw, self.embedded_args + args, result, context)
158
+ def _resolve_arguments(self, data: KeywordData, kw: 'LibraryKeyword', variables=None):
159
+ return kw.resolve_arguments(self.embedded_args + data.args, data.named_args,
160
+ variables, self.languages)
155
161
 
156
162
  def _config_result(self, result: KeywordResult, data: KeywordData,
157
163
  kw: 'LibraryKeyword', assignment):
@@ -177,12 +183,12 @@ class RunKeywordRunner(LibraryKeywordRunner):
177
183
  finally:
178
184
  STOP_SIGNAL_MONITOR.stop_running_keyword()
179
185
 
180
- def _dry_run(self, kw: 'LibraryKeyword', args, result: KeywordResult, context):
181
- super()._dry_run(kw, args, result, context)
186
+ def _end_dry_run(self, data: KeywordData, kw: 'LibraryKeyword',
187
+ result: KeywordResult, context):
182
188
  wrapper = UserKeyword(name=kw.name,
183
189
  doc="Wraps keywords executed by '{kw.name}' in dry-run.",
184
190
  parent=kw.parent)
185
- wrapper.body = [k for k in self._get_dry_run_keywords(kw, args)
191
+ wrapper.body = [k for k in self._get_dry_run_keywords(kw, data.args)
186
192
  if not contains_variable(k.name)]
187
193
  BodyRunner(context).run(wrapper, result)
188
194
 
@@ -43,7 +43,7 @@ from robot.conf import RobotSettings
43
43
  from robot.errors import BreakLoop, ContinueLoop, DataError, ReturnFromKeyword, VariableError
44
44
  from robot.model import BodyItem, DataDict, TestSuites
45
45
  from robot.output import LOGGER, Output, pyloggingconf
46
- from robot.utils import setter
46
+ from robot.utils import format_assign_message, setter
47
47
  from robot.variables import VariableResolver
48
48
 
49
49
  from .bodyrunner import ForRunner, IfRunner, KeywordRunner, TryRunner, WhileRunner
@@ -84,7 +84,13 @@ class Argument:
84
84
  """A temporary API for creating named arguments with non-string values.
85
85
 
86
86
  This class was added in RF 7.0.1 (#5031) after a failed attempt to add a public
87
- API for this purpose in RF 7.0 (#5000). A better, public API is planned for RF 7.1.
87
+ API for this purpose in RF 7.0 (#5000). A better public API that allows passing
88
+ named arguments separately was added in RF 7.1 (#5143).
89
+
90
+ If you need to support also RF 7.0, you can pass named arguments as two-item tuples
91
+ like `(name, value)` and positional arguments as one-item tuples like `(value,)`.
92
+ That approach does not work anymore in RF 7.0.1, though, so the code needs to be
93
+ conditional depending on Robot Framework version.
88
94
 
89
95
  The main limitation of this class is that it is not compatible with the JSON model.
90
96
  The current plan is to remove this in the future, possibly already in RF 8.0, but
@@ -116,24 +122,33 @@ class Keyword(model.Keyword, WithSource):
116
122
  The actual keyword that is executed depends on the context where this model
117
123
  is executed.
118
124
 
119
- Arguments originating from normal Robot Framework data are stored as list of
120
- strings in the exact same format as in the data. This means that arguments can
121
- have variables and escape characters, and that named arguments are specified
122
- using the ``name=value`` syntax.
125
+ Arguments originating from normal Robot Framework data are stored in the
126
+ :attr:`args` attribute as a tuple of strings in the exact same format as in
127
+ the data. This means that arguments can have variables and escape characters,
128
+ and that named arguments are specified using the ``name=value`` syntax.
129
+
130
+ When creating keywords programmatically, it is possible to set :attr:`named_args`
131
+ separately and use :attr:`args` only for positional arguments. Argument values
132
+ do not need to be strings, but also in this case strings can contain variables
133
+ and normal Robot Framework escaping rules must be taken into account.
123
134
  """
124
- __slots__ = ['lineno']
135
+ __slots__ = ['named_args', 'lineno']
125
136
 
126
137
  def __init__(self, name: str = '',
127
138
  args: 'Sequence[str|Argument|Any]' = (),
139
+ named_args: 'Mapping[str, Any]|None' = None,
128
140
  assign: Sequence[str] = (),
129
141
  type: str = BodyItem.KEYWORD,
130
142
  parent: BodyItemParent = None,
131
143
  lineno: 'int|None' = None):
132
144
  super().__init__(name, args, assign, type, parent)
145
+ self.named_args = named_args
133
146
  self.lineno = lineno
134
147
 
135
148
  def to_dict(self) -> DataDict:
136
149
  data = super().to_dict()
150
+ if self.named_args is not None:
151
+ data['named_args'] = self.named_args
137
152
  if self.lineno:
138
153
  data['lineno'] = self.lineno
139
154
  return data
@@ -359,35 +374,39 @@ class Var(model.Var, WithSource):
359
374
  def run(self, result, context, run=True, templated=False):
360
375
  result = result.body.create_var(self.name, self.value, self.scope, self.separator)
361
376
  with StatusReporter(self, result, context, run):
362
- if run:
363
- if self.error:
364
- raise DataError(self.error, syntax=True)
365
- if not context.dry_run:
366
- scope = self._get_scope(context.variables)
367
- setter = getattr(context.variables, f'set_{scope}')
368
- try:
369
- resolver = VariableResolver.from_variable(self)
370
- setter(self._resolve_name(self.name, context.variables),
371
- resolver.resolve(context.variables))
372
- except DataError as err:
373
- raise VariableError(f"Setting variable '{self.name}' failed: {err}")
377
+ if self.error and run:
378
+ raise DataError(self.error, syntax=True)
379
+ if not run or context.dry_run:
380
+ return
381
+ scope, config = self._get_scope(context.variables)
382
+ set_variable = getattr(context.variables, f'set_{scope}')
383
+ try:
384
+ name, value = self._resolve_name_and_value(context.variables)
385
+ set_variable(name, value, **config)
386
+ context.info(format_assign_message(name, value))
387
+ except DataError as err:
388
+ raise VariableError(f"Setting variable '{self.name}' failed: {err}")
374
389
 
375
390
  def _get_scope(self, variables):
376
391
  if not self.scope:
377
- return 'local'
392
+ return 'local', {}
378
393
  try:
379
394
  scope = variables.replace_string(self.scope)
380
395
  if scope.upper() == 'TASK':
381
- return 'test'
382
- if scope.upper() in ('GLOBAL', 'SUITE', 'TEST', 'LOCAL'):
383
- return scope.lower()
396
+ return 'test', {}
397
+ if scope.upper() == 'SUITES':
398
+ return 'suite', {'children': True}
399
+ if scope.upper() in ('LOCAL', 'TEST', 'SUITE', 'GLOBAL'):
400
+ return scope.lower(), {}
384
401
  raise DataError(f"Value '{scope}' is not accepted. Valid values are "
385
- f"'GLOBAL', 'SUITE', 'TEST', 'TASK' and 'LOCAL'.")
402
+ f"'LOCAL', 'TEST', 'TASK', 'SUITE', 'SUITES' and 'GLOBAL'.")
386
403
  except DataError as err:
387
404
  raise DataError(f"Invalid VAR scope: {err}")
388
405
 
389
- def _resolve_name(self, name, variables):
390
- return name[:2] + variables.replace_string(name[2:-1]) + '}'
406
+ def _resolve_name_and_value(self, variables):
407
+ name = self.name[:2] + variables.replace_string(self.name[2:-1]) + '}'
408
+ value = VariableResolver.from_variable(self).resolve(variables)
409
+ return name, value
391
410
 
392
411
  def to_dict(self) -> DataDict:
393
412
  data = super().to_dict()
@@ -87,9 +87,7 @@ class Namespace:
87
87
  self.variables.set_from_variable_section(resource.variables, overwrite)
88
88
  self._kw_store.resources[path] = resource
89
89
  self._handle_imports(resource.imports)
90
- LOGGER.imported("Resource", resource.name,
91
- importer=str(import_setting.source),
92
- source=path)
90
+ LOGGER.resource_import(resource, import_setting)
93
91
  else:
94
92
  LOGGER.info(f"Resource file '{path}' already imported by "
95
93
  f"suite '{self._suite_name}'.")
@@ -109,10 +107,10 @@ class Namespace:
109
107
  if overwrite or (path, args) not in self._imported_variable_files:
110
108
  self._imported_variable_files.add((path, args))
111
109
  self.variables.set_from_file(path, args, overwrite)
112
- LOGGER.imported("Variables", os.path.basename(path),
113
- args=list(args),
114
- importer=str(import_setting.source),
115
- source=path)
110
+ LOGGER.variables_import({'name': os.path.basename(path),
111
+ 'args': args,
112
+ 'source': path},
113
+ importer=import_setting)
116
114
  else:
117
115
  msg = f"Variable file '{path}'"
118
116
  if args:
@@ -131,11 +129,7 @@ class Namespace:
131
129
  f"'{self._suite_name}'.")
132
130
  return
133
131
  if notify:
134
- LOGGER.imported("Library", lib.name,
135
- args=list(import_setting.args),
136
- originalname=lib.real_name,
137
- importer=str(import_setting.source),
138
- source=str(lib.source or ''))
132
+ LOGGER.library_import(lib, import_setting)
139
133
  self._kw_store.libraries[lib.name] = lib
140
134
  lib.scope_manager.start_suite()
141
135
  if self._running_test:
@@ -287,30 +281,30 @@ class KeywordStore:
287
281
  else:
288
282
  raise KeywordError(message)
289
283
 
290
- def _get_runner(self, name):
284
+ def _get_runner(self, name, strip_bdd_prefix=True):
291
285
  if not name:
292
286
  raise DataError('Keyword name cannot be empty.')
293
287
  if not is_string(name):
294
288
  raise DataError('Keyword name must be a string.')
295
- runner = self._get_runner_from_suite_file(name)
289
+ runner = None
290
+ if strip_bdd_prefix:
291
+ runner = self._get_bdd_style_runner(name)
292
+ if not runner:
293
+ runner = self._get_runner_from_suite_file(name)
296
294
  if not runner and '.' in name:
297
295
  runner = self._get_explicit_runner(name)
298
296
  if not runner:
299
297
  runner = self._get_implicit_runner(name)
300
- if not runner:
301
- runner = self._get_bdd_style_runner(name, self.languages.bdd_prefixes)
302
298
  return runner
303
299
 
304
- def _get_bdd_style_runner(self, name, prefixes):
305
- parts = name.split()
306
- for index in range(1, len(parts)):
307
- prefix = ' '.join(parts[:index]).title()
308
- if prefix in prefixes:
309
- runner = self._get_runner(' '.join(parts[index:]))
310
- if runner:
311
- runner = copy.copy(runner)
312
- runner.name = name
313
- return runner
300
+ def _get_bdd_style_runner(self, name):
301
+ match = self.languages.bdd_prefix_regexp.match(name)
302
+ if match:
303
+ runner = self._get_runner(name[match.end():], strip_bdd_prefix=False)
304
+ if runner:
305
+ runner = copy.copy(runner)
306
+ runner.name = name
307
+ return runner
314
308
  return None
315
309
 
316
310
  def _get_implicit_runner(self, name):
@@ -28,10 +28,13 @@ from .model import Body, BodyItemParent, Keyword, TestSuite
28
28
  from .userkeywordrunner import UserKeywordRunner, EmbeddedArgumentsRunner
29
29
 
30
30
  if TYPE_CHECKING:
31
+ from robot.conf import LanguagesLike
31
32
  from robot.parsing import File
32
33
 
33
34
 
34
35
  class ResourceFile(ModelObject):
36
+ """Represents a resource file."""
37
+
35
38
  repr_args = ('source',)
36
39
  __slots__ = ('_source', 'owner', 'doc', 'keyword_finder')
37
40
 
@@ -234,7 +237,8 @@ class UserKeyword(KeywordImplementation):
234
237
  """
235
238
  return bool(self._teardown)
236
239
 
237
- def create_runner(self, name: 'str|None', languages=None) \
240
+ def create_runner(self, name: 'str|None',
241
+ languages: 'LanguagesLike' = None) \
238
242
  -> 'UserKeywordRunner|EmbeddedArgumentsRunner':
239
243
  if self.embedded:
240
244
  return EmbeddedArgumentsRunner(self, name)
@@ -317,8 +321,12 @@ class Variable(ModelObject):
317
321
  data['error'] = self.error
318
322
  return data
319
323
 
324
+ def _include_in_repr(self, name: str, value: Any) -> bool:
325
+ return not (name == 'separator' and value is None)
326
+
320
327
 
321
328
  class Import(ModelObject):
329
+ """Represents library, resource file or variable file import."""
322
330
  repr_args = ('type', 'name', 'args', 'alias')
323
331
  LIBRARY = 'LIBRARY'
324
332
  RESOURCE = 'RESOURCE'
@@ -52,10 +52,10 @@ class StatusReporter:
52
52
  message = ' ' + doc.split('*', 2)[-1].strip()
53
53
  self.context.warn(f"Keyword '{name}' is deprecated.{message}")
54
54
 
55
- def __exit__(self, exc_type, exc_val, exc_tb):
55
+ def __exit__(self, exc_type, exc_value, exc_traceback):
56
56
  context = self.context
57
57
  result = self.result
58
- failure = self._get_failure(exc_type, exc_val, exc_tb, context)
58
+ failure = self._get_failure(exc_value, context)
59
59
  if failure is None:
60
60
  result.status = self.pass_status
61
61
  else:
@@ -65,12 +65,17 @@ class StatusReporter:
65
65
  if self.initial_test_status == 'PASS':
66
66
  context.test.status = result.status
67
67
  result.elapsed_time = datetime.now() - result.start_time
68
+ orig_status = (result.status, result.message)
68
69
  context.end_body_item(self.data, result, self.implementation)
69
- if failure is not exc_val and not self.suppress:
70
+ if orig_status != (result.status, result.message):
71
+ if result.passed or result.not_run:
72
+ return True
73
+ raise ExecutionFailed(result.message, skip=result.skipped)
74
+ if failure is not exc_value and not self.suppress:
70
75
  raise failure
71
76
  return self.suppress
72
77
 
73
- def _get_failure(self, exc_type, exc_value, exc_tb, context):
78
+ def _get_failure(self, exc_value, context):
74
79
  if exc_value is None:
75
80
  return None
76
81
  if isinstance(exc_value, ExecutionStatus):
@@ -171,7 +171,7 @@ class TestLibrary:
171
171
  if inspect.ismodule(code):
172
172
  lib = cls.from_module(code, name, real_name, source, create_keywords, logger)
173
173
  if args: # Resolving arguments reports an error.
174
- lib.init.resolve_arguments(args, variables)
174
+ lib.init.resolve_arguments(args, variables=variables)
175
175
  return lib
176
176
  return cls.from_class(code, name, real_name, source, args or (), variables,
177
177
  create_keywords, logger)
@@ -316,7 +316,7 @@ class ClassLibrary(TestLibrary):
316
316
  logger=LOGGER) -> 'ClassLibrary':
317
317
  init = LibraryInit.from_class(klass)
318
318
  library = cls(klass, init, name, real_name, source, logger)
319
- positional, named = init.args.resolve(args, variables)
319
+ positional, named = init.args.resolve(args, variables=variables)
320
320
  init.positional, init.named = list(positional), dict(named)
321
321
  if create_keywords:
322
322
  library.create_keywords()
@@ -55,13 +55,16 @@ class UserKeywordRunner:
55
55
 
56
56
  def _config_result(self, result: KeywordResult, data: KeywordData,
57
57
  kw: 'UserKeyword', assignment, variables):
58
+ args = tuple(data.args)
59
+ if data.named_args:
60
+ args += tuple(f'{n}={v}' for n, v in data.named_args.items())
58
61
  doc = variables.replace_string(kw.doc, ignore_errors=True)
59
62
  doc, tags = split_tags_from_doc(doc)
60
63
  tags = variables.replace_list(kw.tags, ignore_errors=True) + tags
61
64
  result.config(name=self.name,
62
65
  owner=kw.owner.name,
63
66
  doc=getshortdoc(doc),
64
- args=data.args,
67
+ args=args,
65
68
  assign=tuple(assignment),
66
69
  tags=tags,
67
70
  type=data.type)
@@ -71,7 +74,7 @@ class UserKeywordRunner:
71
74
  for message in self.pre_run_messages:
72
75
  context.output.message(message)
73
76
  variables = context.variables
74
- positional, named = self._resolve_arguments(kw, data.args, variables)
77
+ positional, named = self._resolve_arguments(data, kw, variables)
75
78
  with context.user_keyword(kw):
76
79
  self._set_arguments(kw, positional, named, context)
77
80
  if kw.timeout:
@@ -89,8 +92,8 @@ class UserKeywordRunner:
89
92
  raise exception
90
93
  return return_value
91
94
 
92
- def _resolve_arguments(self, kw: 'UserKeyword', args, variables=None):
93
- return kw.resolve_arguments(args, variables)
95
+ def _resolve_arguments(self, data: KeywordData, kw: 'UserKeyword', variables=None):
96
+ return kw.resolve_arguments(data.args, data.named_args, variables)
94
97
 
95
98
  def _set_arguments(self, kw: 'UserKeyword', positional, named, context):
96
99
  variables = context.variables
@@ -222,7 +225,7 @@ class UserKeywordRunner:
222
225
  if self.pre_run_messages:
223
226
  for message in self.pre_run_messages:
224
227
  context.output.message(message)
225
- self._resolve_arguments(kw, data.args)
228
+ self._resolve_arguments(data, kw)
226
229
  with context.user_keyword(kw):
227
230
  if kw.timeout:
228
231
  timeout = KeywordTimeout(kw.timeout, context.variables)
@@ -238,8 +241,8 @@ class EmbeddedArgumentsRunner(UserKeywordRunner):
238
241
  super().__init__(keyword, name)
239
242
  self.embedded_args = keyword.embedded.match(name).groups()
240
243
 
241
- def _resolve_arguments(self, kw: 'UserKeyword', args, variables=None):
242
- result = super()._resolve_arguments(kw, args, variables)
244
+ def _resolve_arguments(self, data: KeywordData, kw: 'UserKeyword', variables=None):
245
+ result = super()._resolve_arguments(data, kw, variables)
243
246
  if variables:
244
247
  embedded = [variables.replace_scalar(e) for e in self.embedded_args]
245
248
  self.embedded_args = kw.embedded.map(embedded)
@@ -18,7 +18,7 @@ import sys
18
18
  import locale
19
19
 
20
20
  from .misc import isatty
21
- from .platform import UNIXY, WINDOWS
21
+ from .platform import PY_VERSION, UNIXY, WINDOWS
22
22
 
23
23
 
24
24
  if UNIXY:
@@ -53,6 +53,8 @@ def _get_encoding(platform_getters, default):
53
53
 
54
54
 
55
55
  def _get_python_system_encoding():
56
+ if PY_VERSION >= (3, 11):
57
+ return locale.getencoding()
56
58
  # ValueError occurs with PyPy 3.10 if language config is invalid.
57
59
  # https://foss.heptapod.net/pypy/pypy/-/issues/3975
58
60
  try:
@@ -86,7 +86,7 @@ def _time_string_to_secs(timestr):
86
86
  timestr = _normalize_timestr(timestr)
87
87
  if not timestr:
88
88
  return None
89
- nanos = micros = millis = secs = mins = hours = days = 0
89
+ nanos = micros = millis = secs = mins = hours = days = weeks = 0
90
90
  if timestr[0] == '-':
91
91
  sign = -1
92
92
  timestr = timestr[1:]
@@ -102,13 +102,14 @@ def _time_string_to_secs(timestr):
102
102
  elif c == 'm': mins = float(''.join(temp)); temp = []
103
103
  elif c == 'h': hours = float(''.join(temp)); temp = []
104
104
  elif c == 'd': days = float(''.join(temp)); temp = []
105
+ elif c == 'w': weeks = float(''.join(temp)); temp = []
105
106
  else: temp.append(c)
106
107
  except ValueError:
107
108
  return None
108
109
  if temp:
109
110
  return None
110
111
  return sign * (nanos/1E9 + micros/1E6 + millis/1000 + secs +
111
- mins*60 + hours*60*60 + days*60*60*24)
112
+ mins*60 + hours*60*60 + days*60*60*24 + weeks*60*60*24*7)
112
113
 
113
114
 
114
115
  def _normalize_timestr(timestr):
@@ -120,7 +121,8 @@ def _normalize_timestr(timestr):
120
121
  ('s', ['second', 'sec']),
121
122
  ('m', ['minute', 'min']),
122
123
  ('h', ['hour']),
123
- ('d', ['day'])]:
124
+ ('d', ['day']),
125
+ ('w', ['week'])]:
124
126
  plural_aliases = [a+'s' for a in aliases if not a.endswith('s')]
125
127
  for alias in plural_aliases + aliases:
126
128
  if alias in timestr:
@@ -27,9 +27,6 @@ from .search import VariableMatches
27
27
  from .notfound import variable_not_found
28
28
 
29
29
 
30
- PYTHON_BUILTINS = set(builtins.__dict__)
31
-
32
-
33
30
  def evaluate_expression(expression, variables, modules=None, namespace=None,
34
31
  resolve_variables=False):
35
32
  original = expression
@@ -146,7 +143,7 @@ class EvaluationNamespace(MutableMapping):
146
143
  self.namespace.pop(key)
147
144
 
148
145
  def _import_module(self, name):
149
- if name in PYTHON_BUILTINS:
146
+ if hasattr(builtins, name):
150
147
  raise KeyError
151
148
  try:
152
149
  return __import__(name)
@@ -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),
@@ -13,8 +13,7 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
 
16
- from contextlib import contextmanager
17
- from typing import Sequence, TYPE_CHECKING
16
+ from typing import Any, Sequence, TYPE_CHECKING
18
17
 
19
18
  from robot.errors import DataError
20
19
  from robot.utils import DotDict, split_from_equals
@@ -23,7 +22,7 @@ from .resolvable import Resolvable
23
22
  from .search import is_assign, is_list_variable, is_dict_variable
24
23
 
25
24
  if TYPE_CHECKING:
26
- from robot.running.model import Var, Variable
25
+ from robot.running import Var, Variable
27
26
  from .store import VariableStore
28
27
 
29
28
 
@@ -35,8 +34,8 @@ class VariableTableSetter:
35
34
  def set(self, variables: 'Sequence[Variable]', overwrite: bool = False):
36
35
  for var in variables:
37
36
  try:
38
- value = VariableResolver.from_variable(var)
39
- self.store.add(var.name, value, overwrite)
37
+ resolver = VariableResolver.from_variable(var)
38
+ self.store.add(var.name, resolver, overwrite)
40
39
  except DataError as err:
41
40
  var.report_error(str(err))
42
41
 
@@ -46,7 +45,8 @@ class VariableResolver(Resolvable):
46
45
  def __init__(self, value: Sequence[str], error_reporter=None):
47
46
  self.value = tuple(value)
48
47
  self.error_reporter = error_reporter
49
- self._resolving = False
48
+ self.resolving = False
49
+ self.resolved = False
50
50
 
51
51
  @classmethod
52
52
  def from_name_and_value(cls, name: str, value: 'str|Sequence[str]',
@@ -69,22 +69,19 @@ class VariableResolver(Resolvable):
69
69
  return cls.from_name_and_value(var.name, var.value, var.separator,
70
70
  getattr(var, 'report_error', None))
71
71
 
72
- def resolve(self, variables):
73
- with self._avoid_recursion:
74
- return self._replace_variables(variables)
75
-
76
- @property
77
- @contextmanager
78
- def _avoid_recursion(self):
79
- if self._resolving:
72
+ def resolve(self, variables) -> Any:
73
+ if self.resolving:
80
74
  raise DataError('Recursive variable definition.')
81
- self._resolving = True
82
- try:
83
- yield
84
- finally:
85
- self._resolving = False
75
+ if not self.resolved:
76
+ self.resolving = True
77
+ try:
78
+ self.value = self._replace_variables(variables)
79
+ finally:
80
+ self.resolving = False
81
+ self.resolved = True
82
+ return self.value
86
83
 
87
- def _replace_variables(self, variables):
84
+ def _replace_variables(self, variables) -> Any:
88
85
  raise NotImplementedError
89
86
 
90
87
  def report_error(self, error):
@@ -18,7 +18,7 @@ import sys
18
18
 
19
19
  # Version number typically updated by running `invoke set-version <version>`.
20
20
  # Run `invoke --help set-version` or see tasks.py for details.
21
- VERSION = '7.0.1rc2'
21
+ VERSION = '7.1'
22
22
 
23
23
 
24
24
  def get_version(naked=False):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: robotframework
3
- Version: 7.0.1rc2
3
+ Version: 7.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.0.1rc2.rst
13
+ Project-URL: Release Notes, https://github.com/robotframework/robotframework/blob/master/doc/releasenotes/rf-7.1.rst
14
14
  Project-URL: Slack, http://slack.robotframework.org
15
15
  Description: Robot Framework
16
16
  ===============
@@ -176,6 +176,7 @@ Classifier: Programming Language :: Python :: 3.9
176
176
  Classifier: Programming Language :: Python :: 3.10
177
177
  Classifier: Programming Language :: Python :: 3.11
178
178
  Classifier: Programming Language :: Python :: 3.12
179
+ Classifier: Programming Language :: Python :: 3.13
179
180
  Classifier: Programming Language :: Python :: Implementation :: CPython
180
181
  Classifier: Programming Language :: Python :: Implementation :: PyPy
181
182
  Classifier: Topic :: Software Development :: Testing