robotframework 6.1rc1__zip → 7.0a1__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 (288) hide show
  1. {robotframework-6.1rc1/src/robotframework.egg-info → robotframework-7.0a1}/PKG-INFO +3 -6
  2. {robotframework-6.1rc1 → robotframework-7.0a1}/setup.py +2 -5
  3. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/api/interfaces.py +36 -49
  4. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/api/parsing.py +4 -2
  5. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/conf/gatherfailed.py +2 -2
  6. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/conf/languages.py +61 -25
  7. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/conf/settings.py +8 -5
  8. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/rebot/log.css +4 -0
  9. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/rebot/log.html +9 -1
  10. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/rebot/model.js +2 -4
  11. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/rebot/testdata.js +10 -3
  12. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/template.py +3 -3
  13. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libdocpkg/builder.py +0 -8
  14. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libdocpkg/datatypes.py +9 -10
  15. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libdocpkg/htmlutils.py +4 -7
  16. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libdocpkg/jsonbuilder.py +14 -10
  17. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libdocpkg/model.py +13 -25
  18. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libdocpkg/robotbuilder.py +14 -4
  19. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libdocpkg/xmlbuilder.py +8 -8
  20. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libdocpkg/xmlwriter.py +12 -38
  21. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libraries/BuiltIn.py +215 -189
  22. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libraries/Collections.py +2 -9
  23. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libraries/DateTime.py +1 -1
  24. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libraries/OperatingSystem.py +4 -3
  25. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libraries/Process.py +26 -27
  26. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libraries/Remote.py +40 -36
  27. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libraries/String.py +4 -4
  28. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libraries/XML.py +7 -8
  29. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libraries/__init__.py +2 -2
  30. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libraries/dialogs_py.py +14 -2
  31. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/__init__.py +4 -4
  32. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/body.py +14 -6
  33. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/configurer.py +19 -15
  34. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/control.py +155 -85
  35. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/filter.py +31 -25
  36. robotframework-7.0a1/src/robot/model/keyword.py +70 -0
  37. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/message.py +19 -10
  38. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/modelobject.py +2 -8
  39. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/modifier.py +1 -1
  40. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/namepatterns.py +3 -25
  41. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/stats.py +9 -15
  42. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/tags.py +1 -1
  43. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/testcase.py +12 -21
  44. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/testsuite.py +43 -24
  45. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/visitor.py +35 -8
  46. robotframework-7.0a1/src/robot/output/console/dotted.py +90 -0
  47. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/output/console/quiet.py +3 -2
  48. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/output/console/verbose.py +60 -60
  49. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/output/debugfile.py +36 -23
  50. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/output/filelogger.py +16 -13
  51. robotframework-7.0a1/src/robot/output/listeners.py +586 -0
  52. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/output/logger.py +164 -77
  53. robotframework-7.0a1/src/robot/output/loggerapi.py +152 -0
  54. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/output/loggerhelper.py +23 -56
  55. robotframework-7.0a1/src/robot/output/output.py +158 -0
  56. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/output/stdoutlogsplitter.py +8 -5
  57. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/output/xmllogger.py +163 -109
  58. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/parsing/lexer/blocklexers.py +17 -13
  59. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/parsing/lexer/context.py +12 -2
  60. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/parsing/lexer/lexer.py +1 -1
  61. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/parsing/lexer/settings.py +6 -3
  62. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/parsing/lexer/statementlexers.py +39 -10
  63. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/parsing/lexer/tokens.py +27 -29
  64. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/parsing/model/blocks.py +19 -6
  65. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/parsing/model/statements.py +184 -84
  66. robotframework-7.0a1/src/robot/parsing/model/visitor.py +102 -0
  67. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/reporting/expandkeywordmatcher.py +1 -1
  68. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/reporting/jsbuildingcontext.py +8 -6
  69. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/reporting/jsmodelbuilders.py +88 -61
  70. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/reporting/stringcache.py +4 -3
  71. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/reporting/xunitwriter.py +15 -21
  72. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/result/__init__.py +3 -2
  73. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/result/configurer.py +12 -9
  74. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/result/flattenkeywordmatcher.py +8 -8
  75. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/result/keywordremover.py +71 -54
  76. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/result/merger.py +1 -1
  77. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/result/model.py +400 -316
  78. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/result/modeldeprecation.py +9 -3
  79. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/result/resultbuilder.py +21 -23
  80. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/result/xmlelementhandlers.py +76 -40
  81. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/run.py +1 -1
  82. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/__init__.py +1 -1
  83. robotframework-7.0a1/src/robot/running/arguments/argumentconverter.py +101 -0
  84. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/arguments/argumentmapper.py +16 -14
  85. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/arguments/argumentparser.py +3 -1
  86. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/arguments/argumentresolver.py +41 -33
  87. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/arguments/argumentspec.py +24 -90
  88. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/arguments/argumentvalidator.py +34 -27
  89. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/arguments/customconverters.py +14 -11
  90. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/arguments/embedded.py +23 -26
  91. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/arguments/typeconverters.py +210 -220
  92. robotframework-7.0a1/src/robot/running/arguments/typeinfo.py +367 -0
  93. robotframework-7.0a1/src/robot/running/arguments/typevalidator.py +62 -0
  94. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/bodyrunner.py +83 -68
  95. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/builder/builders.py +15 -25
  96. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/builder/parsers.py +15 -10
  97. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/builder/settings.py +9 -17
  98. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/builder/transformers.py +166 -308
  99. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/context.py +80 -25
  100. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/handlers.py +11 -16
  101. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/handlerstore.py +1 -1
  102. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/librarykeywordrunner.py +9 -17
  103. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/model.py +156 -36
  104. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/namespace.py +18 -19
  105. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/statusreporter.py +13 -12
  106. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/suiterunner.py +18 -21
  107. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/testlibraries.py +35 -39
  108. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/usererrorhandler.py +8 -8
  109. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/userkeyword.py +13 -8
  110. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/userkeywordrunner.py +18 -21
  111. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/testdoc.py +18 -13
  112. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/__init__.py +50 -35
  113. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/connectioncache.py +64 -59
  114. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/encodingsniffer.py +9 -4
  115. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/escaping.py +11 -9
  116. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/markupwriters.py +20 -13
  117. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/normalizing.py +9 -24
  118. robotframework-7.0a1/src/robot/utils/notset.py +33 -0
  119. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/platform.py +15 -5
  120. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/robotpath.py +1 -0
  121. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/robottime.py +120 -88
  122. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/robottypes.py +16 -31
  123. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/setter.py +0 -5
  124. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/text.py +7 -4
  125. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/unic.py +2 -2
  126. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/variables/__init__.py +2 -2
  127. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/variables/assigner.py +17 -19
  128. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/variables/evaluation.py +20 -17
  129. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/variables/filesetter.py +80 -80
  130. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/variables/replacer.py +33 -36
  131. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/variables/scopes.py +3 -3
  132. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/variables/search.py +66 -41
  133. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/variables/store.py +14 -16
  134. robotframework-7.0a1/src/robot/variables/tablesetter.py +164 -0
  135. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/variables/variables.py +1 -1
  136. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/version.py +1 -1
  137. {robotframework-6.1rc1 → robotframework-7.0a1/src/robotframework.egg-info}/PKG-INFO +3 -6
  138. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robotframework.egg-info/SOURCES.txt +3 -4
  139. {robotframework-6.1rc1 → robotframework-7.0a1}/tasks.py +6 -6
  140. robotframework-6.1rc1/src/robot/libraries/Reserved.py +0 -48
  141. robotframework-6.1rc1/src/robot/model/keyword.py +0 -173
  142. robotframework-6.1rc1/src/robot/output/console/dotted.py +0 -90
  143. robotframework-6.1rc1/src/robot/output/listenerarguments.py +0 -165
  144. robotframework-6.1rc1/src/robot/output/listenermethods.py +0 -113
  145. robotframework-6.1rc1/src/robot/output/listeners.py +0 -174
  146. robotframework-6.1rc1/src/robot/output/output.py +0 -95
  147. robotframework-6.1rc1/src/robot/parsing/model/visitor.py +0 -67
  148. robotframework-6.1rc1/src/robot/running/arguments/argumentconverter.py +0 -79
  149. robotframework-6.1rc1/src/robot/running/arguments/typevalidator.py +0 -56
  150. robotframework-6.1rc1/src/robot/running/modelcombiner.py +0 -32
  151. robotframework-6.1rc1/src/robot/variables/tablesetter.py +0 -156
  152. {robotframework-6.1rc1 → robotframework-7.0a1}/AUTHORS.rst +0 -0
  153. {robotframework-6.1rc1 → robotframework-7.0a1}/BUILD.rst +0 -0
  154. {robotframework-6.1rc1 → robotframework-7.0a1}/CONTRIBUTING.rst +0 -0
  155. {robotframework-6.1rc1 → robotframework-7.0a1}/COPYRIGHT.txt +0 -0
  156. {robotframework-6.1rc1 → robotframework-7.0a1}/INSTALL.rst +0 -0
  157. {robotframework-6.1rc1 → robotframework-7.0a1}/LICENSE.txt +0 -0
  158. {robotframework-6.1rc1 → robotframework-7.0a1}/MANIFEST.in +0 -0
  159. {robotframework-6.1rc1 → robotframework-7.0a1}/README.rst +0 -0
  160. {robotframework-6.1rc1 → robotframework-7.0a1}/setup.cfg +0 -0
  161. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/__init__.py +0 -0
  162. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/__main__.py +0 -0
  163. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/api/__init__.py +0 -0
  164. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/api/deco.py +0 -0
  165. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/api/exceptions.py +0 -0
  166. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/api/logger.py +0 -0
  167. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/conf/__init__.py +0 -0
  168. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/errors.py +0 -0
  169. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/__init__.py +0 -0
  170. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/common/__init__.py +0 -0
  171. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/common/js_disabled.css +0 -0
  172. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/common/storage.js +0 -0
  173. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/htmlfilewriter.py +0 -0
  174. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/jsonwriter.py +0 -0
  175. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/lib/__init__.py +0 -0
  176. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/lib/jquery.highlight.min.js +0 -0
  177. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/lib/jquery.min.js +0 -0
  178. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/lib/jquery.tablesorter.min.js +0 -0
  179. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/lib/jquery.tmpl.min.js +0 -0
  180. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/lib/jsxcompressor.min.js +0 -0
  181. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/libdoc/__init__.py +0 -0
  182. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/libdoc/doc_formatting.css +0 -0
  183. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/libdoc/libdoc.css +0 -0
  184. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/libdoc/libdoc.html +0 -0
  185. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/libdoc/print.css +0 -0
  186. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/libdoc/pygments.css +0 -0
  187. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/rebot/__init__.py +0 -0
  188. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/rebot/common.css +0 -0
  189. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/rebot/doc_formatting.css +0 -0
  190. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/rebot/fileloading.js +0 -0
  191. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/rebot/log.js +0 -0
  192. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/rebot/print.css +0 -0
  193. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/rebot/report.css +0 -0
  194. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/rebot/report.html +0 -0
  195. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/rebot/util.js +0 -0
  196. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/rebot/view.js +0 -0
  197. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/testdoc/__init__.py +0 -0
  198. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/testdoc/testdoc.css +0 -0
  199. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/testdoc/testdoc.html +0 -0
  200. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libdoc.py +0 -0
  201. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libdocpkg/__init__.py +0 -0
  202. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libdocpkg/consoleviewer.py +0 -0
  203. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libdocpkg/htmlwriter.py +0 -0
  204. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libdocpkg/jsonwriter.py +0 -0
  205. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libdocpkg/output.py +0 -0
  206. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libdocpkg/standardtypes.py +0 -0
  207. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libdocpkg/writer.py +0 -0
  208. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libraries/Dialogs.py +0 -0
  209. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libraries/Easter.py +0 -0
  210. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libraries/Screenshot.py +0 -0
  211. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libraries/Telnet.py +0 -0
  212. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/fixture.py +0 -0
  213. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/itemlist.py +0 -0
  214. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/metadata.py +0 -0
  215. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/statistics.py +0 -0
  216. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/suitestatistics.py +0 -0
  217. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/tagsetter.py +0 -0
  218. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/tagstatistics.py +0 -0
  219. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/totalstatistics.py +0 -0
  220. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/output/__init__.py +0 -0
  221. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/output/console/__init__.py +0 -0
  222. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/output/console/highlighting.py +0 -0
  223. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/output/librarylogger.py +0 -0
  224. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/output/pyloggingconf.py +0 -0
  225. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/parsing/__init__.py +0 -0
  226. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/parsing/lexer/__init__.py +0 -0
  227. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/parsing/lexer/tokenizer.py +0 -0
  228. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/parsing/model/__init__.py +0 -0
  229. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/parsing/parser/__init__.py +0 -0
  230. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/parsing/parser/blockparsers.py +0 -0
  231. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/parsing/parser/fileparser.py +0 -0
  232. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/parsing/parser/parser.py +0 -0
  233. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/parsing/suitestructure.py +0 -0
  234. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/pythonpathsetter.py +0 -0
  235. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/rebot.py +0 -0
  236. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/reporting/__init__.py +0 -0
  237. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/reporting/jsexecutionresult.py +0 -0
  238. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/reporting/jswriter.py +0 -0
  239. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/reporting/logreportwriters.py +0 -0
  240. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/reporting/outputwriter.py +0 -0
  241. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/reporting/resultwriter.py +0 -0
  242. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/result/executionerrors.py +0 -0
  243. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/result/executionresult.py +0 -0
  244. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/result/messagefilter.py +0 -0
  245. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/result/suiteteardownfailed.py +0 -0
  246. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/result/visitor.py +0 -0
  247. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/arguments/__init__.py +0 -0
  248. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/builder/__init__.py +0 -0
  249. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/dynamicmethods.py +0 -0
  250. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/importer.py +0 -0
  251. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/libraryscopes.py +0 -0
  252. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/outputcapture.py +0 -0
  253. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/randomizer.py +0 -0
  254. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/runkwregister.py +0 -0
  255. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/signalhandler.py +0 -0
  256. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/status.py +0 -0
  257. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/timeouts/__init__.py +0 -0
  258. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/timeouts/posix.py +0 -0
  259. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/timeouts/windows.py +0 -0
  260. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/application.py +0 -0
  261. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/argumentparser.py +0 -0
  262. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/asserts.py +0 -0
  263. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/charwidth.py +0 -0
  264. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/compress.py +0 -0
  265. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/dotdict.py +0 -0
  266. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/encoding.py +0 -0
  267. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/error.py +0 -0
  268. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/etreewrapper.py +0 -0
  269. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/filereader.py +0 -0
  270. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/frange.py +0 -0
  271. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/htmlformatters.py +0 -0
  272. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/importer.py +0 -0
  273. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/markuputils.py +0 -0
  274. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/match.py +0 -0
  275. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/misc.py +0 -0
  276. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/recommendations.py +0 -0
  277. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/restreader.py +0 -0
  278. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/robotenv.py +0 -0
  279. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/robotinspect.py +0 -0
  280. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/robotio.py +0 -0
  281. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/sortable.py +0 -0
  282. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/typehints.py +0 -0
  283. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/variables/finders.py +0 -0
  284. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/variables/notfound.py +0 -0
  285. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/variables/resolvable.py +0 -0
  286. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robotframework.egg-info/dependency_links.txt +0 -0
  287. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robotframework.egg-info/entry_points.txt +0 -0
  288. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robotframework.egg-info/top_level.txt +0 -0
@@ -36,7 +36,7 @@ from robot.utils import (DotDict, escape, format_assign_message, get_error_messa
36
36
  from robot.utils.asserts import assert_equal, assert_not_equal
37
37
  from robot.variables import (evaluate_expression, is_dict_variable,
38
38
  is_list_variable, search_variable,
39
- DictVariableTableValue, VariableTableValue)
39
+ DictVariableResolver, VariableResolver)
40
40
  from robot.version import get_version
41
41
 
42
42
 
@@ -153,8 +153,8 @@ class _Converter(_BuiltInBase):
153
153
  return int(item, self._convert_to_integer(base))
154
154
  return int(item)
155
155
  except:
156
- raise RuntimeError("'%s' cannot be converted to an integer: %s"
157
- % (orig, get_error_message()))
156
+ raise RuntimeError(f"'{orig}' cannot be converted to an integer: "
157
+ f"{get_error_message()}")
158
158
 
159
159
  def _get_base(self, item, base):
160
160
  if not is_string(item):
@@ -300,8 +300,8 @@ class _Converter(_BuiltInBase):
300
300
  try:
301
301
  return float(self._convert_to_integer(item))
302
302
  except RuntimeError:
303
- raise RuntimeError("'%s' cannot be converted to a floating "
304
- "point number: %s" % (item, error))
303
+ raise RuntimeError(f"'{item}' cannot be converted to a floating "
304
+ f"point number: {error}")
305
305
 
306
306
  def convert_to_string(self, item):
307
307
  """Converts the given item to a Unicode string.
@@ -380,12 +380,12 @@ class _Converter(_BuiltInBase):
380
380
  """
381
381
  try:
382
382
  try:
383
- ordinals = getattr(self, '_get_ordinals_from_%s' % input_type)
383
+ ordinals = getattr(self, f'_get_ordinals_from_{input_type}')
384
384
  except AttributeError:
385
- raise RuntimeError("Invalid input type '%s'." % input_type)
385
+ raise RuntimeError(f"Invalid input type '{input_type}'.")
386
386
  return bytes(bytearray(o for o in ordinals(input)))
387
387
  except:
388
- raise RuntimeError("Creating bytes failed: %s" % get_error_message())
388
+ raise RuntimeError("Creating bytes failed: " + get_error_message())
389
389
 
390
390
  def _get_ordinals_from_text(self, input):
391
391
  for char in input:
@@ -395,8 +395,7 @@ class _Converter(_BuiltInBase):
395
395
  def _test_ordinal(self, ordinal, original, type):
396
396
  if 0 <= ordinal <= 255:
397
397
  return ordinal
398
- raise RuntimeError("%s '%s' cannot be represented as a byte."
399
- % (type, original))
398
+ raise RuntimeError(f"{type} '{original}' cannot be represented as a byte.")
400
399
 
401
400
  def _get_ordinals_from_int(self, input):
402
401
  if is_string(input):
@@ -422,7 +421,7 @@ class _Converter(_BuiltInBase):
422
421
  return input
423
422
  input = ''.join(input.split())
424
423
  if len(input) % length != 0:
425
- raise RuntimeError('Expected input to be multiple of %d.' % length)
424
+ raise RuntimeError(f'Expected input to be multiple of {length}.')
426
425
  return (input[i:i+length] for i in range(0, len(input), length))
427
426
 
428
427
  def create_list(self, *items):
@@ -472,7 +471,7 @@ class _Converter(_BuiltInBase):
472
471
  """
473
472
  separate, combined = self._split_dict_items(items)
474
473
  result = DotDict(self._format_separate_dict_items(separate))
475
- combined = DictVariableTableValue(combined).resolve(self._variables)
474
+ combined = DictVariableResolver(combined).resolve(self._variables)
476
475
  result.update(combined)
477
476
  return result
478
477
 
@@ -488,8 +487,8 @@ class _Converter(_BuiltInBase):
488
487
  def _format_separate_dict_items(self, separate):
489
488
  separate = self._variables.replace_list(separate)
490
489
  if len(separate) % 2 != 0:
491
- raise DataError('Expected even number of keys and values, got %d.'
492
- % len(separate))
490
+ raise DataError(f'Expected even number of keys and values, '
491
+ f'got {len(separate)}.')
493
492
  return [separate[i:i+2] for i in range(0, len(separate), 2)]
494
493
 
495
494
 
@@ -549,7 +548,7 @@ class _Verify(_BuiltInBase):
549
548
  and how ``msg`` can be used to override the default error message.
550
549
  """
551
550
  if self._is_true(condition):
552
- raise AssertionError(msg or "'%s' should not be true." % condition)
551
+ raise AssertionError(msg or f"'{condition}' should not be true.")
553
552
 
554
553
  def should_be_true(self, condition, msg=None):
555
554
  """Fails if the given condition is not true.
@@ -580,7 +579,7 @@ class _Verify(_BuiltInBase):
580
579
  | Should Be True | $status == 'PASS' | # Expected string must be quoted |
581
580
  """
582
581
  if not self._is_true(condition):
583
- raise AssertionError(msg or "'%s' should be true." % condition)
582
+ raise AssertionError(msg or f"'{condition}' should be true.")
584
583
 
585
584
  def should_be_equal(self, first, second, msg=None, values=True,
586
585
  ignore_case=False, formatter='str', strip_spaces=False,
@@ -627,8 +626,8 @@ class _Verify(_BuiltInBase):
627
626
  self._log_types_at_info_if_different(first, second)
628
627
  if is_string(first) and is_string(second):
629
628
  if ignore_case:
630
- first = first.lower()
631
- second = second.lower()
629
+ first = first.casefold()
630
+ second = second.casefold()
632
631
  if strip_spaces:
633
632
  first = self._strip_spaces(first, strip_spaces)
634
633
  second = self._strip_spaces(second, strip_spaces)
@@ -655,14 +654,14 @@ class _Verify(_BuiltInBase):
655
654
  second_lines = second.splitlines(True)
656
655
  if len(first_lines) < 3 or len(second_lines) < 3:
657
656
  return
658
- self.log("%s\n\n!=\n\n%s" % (first.rstrip(), second.rstrip()))
657
+ self.log(f"{first.rstrip()}\n\n!=\n\n{second.rstrip()}")
659
658
  diffs = list(difflib.unified_diff(first_lines, second_lines,
660
659
  fromfile='first', tofile='second',
661
660
  lineterm=''))
662
661
  diffs[3:] = [item[0] + formatter(item[1:]).rstrip() for item in diffs[3:]]
663
662
  prefix = 'Multiline strings are different:'
664
663
  if msg:
665
- prefix = '%s: %s' % (msg, prefix)
664
+ prefix = f'{msg}: {prefix}'
666
665
  raise AssertionError('\n'.join([prefix] + diffs))
667
666
 
668
667
  def _include_values(self, values):
@@ -709,8 +708,8 @@ class _Verify(_BuiltInBase):
709
708
  self._log_types_at_info_if_different(first, second)
710
709
  if is_string(first) and is_string(second):
711
710
  if ignore_case:
712
- first = first.lower()
713
- second = second.lower()
711
+ first = first.casefold()
712
+ second = second.casefold()
714
713
  if strip_spaces:
715
714
  first = self._strip_spaces(first, strip_spaces)
716
715
  second = self._strip_spaces(second, strip_spaces)
@@ -845,8 +844,8 @@ class _Verify(_BuiltInBase):
845
844
  first = safe_str(first)
846
845
  second = safe_str(second)
847
846
  if ignore_case:
848
- first = first.lower()
849
- second = second.lower()
847
+ first = first.casefold()
848
+ second = second.casefold()
850
849
  if strip_spaces:
851
850
  first = self._strip_spaces(first, strip_spaces)
852
851
  second = self._strip_spaces(second, strip_spaces)
@@ -886,8 +885,8 @@ class _Verify(_BuiltInBase):
886
885
  first = safe_str(first)
887
886
  second = safe_str(second)
888
887
  if ignore_case:
889
- first = first.lower()
890
- second = second.lower()
888
+ first = first.casefold()
889
+ second = second.casefold()
891
890
  if strip_spaces:
892
891
  first = self._strip_spaces(first, strip_spaces)
893
892
  second = self._strip_spaces(second, strip_spaces)
@@ -906,8 +905,8 @@ class _Verify(_BuiltInBase):
906
905
  of the ``ignore_case``, ``strip_spaces``, and ``collapse_spaces`` options.
907
906
  """
908
907
  if ignore_case:
909
- str1 = str1.lower()
910
- str2 = str2.lower()
908
+ str1 = str1.casefold()
909
+ str2 = str2.casefold()
911
910
  if strip_spaces:
912
911
  str1 = self._strip_spaces(str1, strip_spaces)
913
912
  str2 = self._strip_spaces(str2, strip_spaces)
@@ -927,8 +926,8 @@ class _Verify(_BuiltInBase):
927
926
  of the ``ignore_case``, ``strip_spaces``, and ``collapse_spaces`` options.
928
927
  """
929
928
  if ignore_case:
930
- str1 = str1.lower()
931
- str2 = str2.lower()
929
+ str1 = str1.casefold()
930
+ str2 = str2.casefold()
932
931
  if strip_spaces:
933
932
  str1 = self._strip_spaces(str1, strip_spaces)
934
933
  str2 = self._strip_spaces(str2, strip_spaces)
@@ -949,8 +948,8 @@ class _Verify(_BuiltInBase):
949
948
  of the ``ignore_case``, ``strip_spaces``, and ``collapse_spaces`` options.
950
949
  """
951
950
  if ignore_case:
952
- str1 = str1.lower()
953
- str2 = str2.lower()
951
+ str1 = str1.casefold()
952
+ str2 = str2.casefold()
954
953
  if strip_spaces:
955
954
  str1 = self._strip_spaces(str1, strip_spaces)
956
955
  str2 = self._strip_spaces(str2, strip_spaces)
@@ -970,8 +969,8 @@ class _Verify(_BuiltInBase):
970
969
  of the ``ignore_case``, ``strip_spaces``, and ``collapse_spaces`` options.
971
970
  """
972
971
  if ignore_case:
973
- str1 = str1.lower()
974
- str2 = str2.lower()
972
+ str1 = str1.casefold()
973
+ str2 = str2.casefold()
975
974
  if strip_spaces:
976
975
  str1 = self._strip_spaces(str1, strip_spaces)
977
976
  str2 = self._strip_spaces(str2, strip_spaces)
@@ -1018,11 +1017,11 @@ class _Verify(_BuiltInBase):
1018
1017
  # case-insensitive comparisons.
1019
1018
  orig_container = container
1020
1019
  if ignore_case and is_string(item):
1021
- item = item.lower()
1020
+ item = item.casefold()
1022
1021
  if is_string(container):
1023
- container = container.lower()
1022
+ container = container.casefold()
1024
1023
  elif is_list_like(container):
1025
- container = set(x.lower() if is_string(x) else x for x in container)
1024
+ container = set(x.casefold() if is_string(x) else x for x in container)
1026
1025
  if strip_spaces and is_string(item):
1027
1026
  item = self._strip_spaces(item, strip_spaces)
1028
1027
  if is_string(container):
@@ -1074,11 +1073,11 @@ class _Verify(_BuiltInBase):
1074
1073
  """
1075
1074
  orig_container = container
1076
1075
  if ignore_case and is_string(item):
1077
- item = item.lower()
1076
+ item = item.casefold()
1078
1077
  if is_string(container):
1079
- container = container.lower()
1078
+ container = container.casefold()
1080
1079
  elif is_list_like(container):
1081
- container = set(x.lower() if is_string(x) else x for x in container)
1080
+ container = set(x.casefold() if is_string(x) else x for x in container)
1082
1081
  if strip_spaces and is_string(item):
1083
1082
  item = self._strip_spaces(item, strip_spaces)
1084
1083
  if is_string(container):
@@ -1123,17 +1122,17 @@ class _Verify(_BuiltInBase):
1123
1122
  strip_spaces = configuration.pop('strip_spaces', False)
1124
1123
  collapse_spaces = is_truthy(configuration.pop('collapse_spaces', False))
1125
1124
  if configuration:
1126
- raise RuntimeError("Unsupported configuration parameter%s: %s."
1127
- % (s(configuration), seq2str(sorted(configuration))))
1125
+ raise RuntimeError(f"Unsupported configuration parameter{s(configuration)}: "
1126
+ f"{seq2str(sorted(configuration))}.")
1128
1127
  if not items:
1129
1128
  raise RuntimeError('One or more items required.')
1130
1129
  orig_container = container
1131
1130
  if ignore_case:
1132
- items = [x.lower() if is_string(x) else x for x in items]
1131
+ items = [x.casefold() if is_string(x) else x for x in items]
1133
1132
  if is_string(container):
1134
- container = container.lower()
1133
+ container = container.casefold()
1135
1134
  elif is_list_like(container):
1136
- container = set(x.lower() if is_string(x) else x for x in container)
1135
+ container = set(x.casefold() if is_string(x) else x for x in container)
1137
1136
  if strip_spaces:
1138
1137
  items = [self._strip_spaces(x, strip_spaces) for x in items]
1139
1138
  if is_string(container):
@@ -1181,17 +1180,17 @@ class _Verify(_BuiltInBase):
1181
1180
  strip_spaces = configuration.pop('strip_spaces', False)
1182
1181
  collapse_spaces = is_truthy(configuration.pop('collapse_spaces', False))
1183
1182
  if configuration:
1184
- raise RuntimeError("Unsupported configuration parameter%s: %s."
1185
- % (s(configuration), seq2str(sorted(configuration))))
1183
+ raise RuntimeError(f"Unsupported configuration parameter{s(configuration)}: "
1184
+ f"{seq2str(sorted(configuration))}.")
1186
1185
  if not items:
1187
1186
  raise RuntimeError('One or more items required.')
1188
1187
  orig_container = container
1189
1188
  if ignore_case:
1190
- items = [x.lower() if is_string(x) else x for x in items]
1189
+ items = [x.casefold() if is_string(x) else x for x in items]
1191
1190
  if is_string(container):
1192
- container = container.lower()
1191
+ container = container.casefold()
1193
1192
  elif is_list_like(container):
1194
- container = set(x.lower() if is_string(x) else x for x in container)
1193
+ container = set(x.casefold() if is_string(x) else x for x in container)
1195
1194
  if strip_spaces:
1196
1195
  items = [self._strip_spaces(x, strip_spaces) for x in items]
1197
1196
  if is_string(container):
@@ -1247,11 +1246,11 @@ class _Verify(_BuiltInBase):
1247
1246
  orig_container = container
1248
1247
  if is_string(item):
1249
1248
  if ignore_case:
1250
- item = item.lower()
1249
+ item = item.casefold()
1251
1250
  if is_string(container):
1252
- container = container.lower()
1251
+ container = container.casefold()
1253
1252
  elif is_list_like(container):
1254
- container = [x.lower() if is_string(x) else x for x in container]
1253
+ container = [x.casefold() if is_string(x) else x for x in container]
1255
1254
  if strip_spaces:
1256
1255
  item = self._strip_spaces(item, strip_spaces)
1257
1256
  if is_string(container):
@@ -1266,8 +1265,8 @@ class _Verify(_BuiltInBase):
1266
1265
  container = [self._collapse_spaces(x) for x in container]
1267
1266
  x = self.get_count(container, item)
1268
1267
  if not msg:
1269
- msg = "%r contains '%s' %d time%s, not %d time%s." \
1270
- % (orig_container, item, x, s(x), count, s(count))
1268
+ msg = (f"{orig_container!r} contains '{item}' {x} time{s(x)}, "
1269
+ f"not {count} time{s(count)}.")
1271
1270
  self.should_be_equal_as_integers(x, count, msg, values=False)
1272
1271
 
1273
1272
  def get_count(self, container, item):
@@ -1284,10 +1283,10 @@ class _Verify(_BuiltInBase):
1284
1283
  try:
1285
1284
  container = list(container)
1286
1285
  except:
1287
- raise RuntimeError("Converting '%s' to list failed: %s"
1288
- % (container, get_error_message()))
1286
+ raise RuntimeError(f"Converting '{container}' to list failed: "
1287
+ f"{get_error_message()}")
1289
1288
  count = container.count(item)
1290
- self.log('Item found from container %d time%s.' % (count, s(count)))
1289
+ self.log(f'Item found from container {count} time{s(count)}.')
1291
1290
  return count
1292
1291
 
1293
1292
  def should_not_match(self, string, pattern, msg=None, values=True,
@@ -1407,7 +1406,7 @@ class _Verify(_BuiltInBase):
1407
1406
  Empty`.
1408
1407
  """
1409
1408
  length = self._get_length(item)
1410
- self.log('Length is %d' % length)
1409
+ self.log(f'Length is {length}.')
1411
1410
  return length
1412
1411
 
1413
1412
  def _get_length(self, item):
@@ -1431,7 +1430,7 @@ class _Verify(_BuiltInBase):
1431
1430
  except RERAISED_EXCEPTIONS:
1432
1431
  raise
1433
1432
  except:
1434
- raise RuntimeError("Could not get length of '%s'." % item)
1433
+ raise RuntimeError(f"Could not get length of '{item}'.")
1435
1434
 
1436
1435
  def length_should_be(self, item, length, msg=None):
1437
1436
  """Verifies that the length of the given item is correct.
@@ -1442,8 +1441,8 @@ class _Verify(_BuiltInBase):
1442
1441
  length = self._convert_to_integer(length)
1443
1442
  actual = self.get_length(item)
1444
1443
  if actual != length:
1445
- raise AssertionError(msg or "Length of '%s' should be %d but is %d."
1446
- % (item, length, actual))
1444
+ raise AssertionError(msg or f"Length of '{item}' should be {length} "
1445
+ f"but is {actual}.")
1447
1446
 
1448
1447
  def should_be_empty(self, item, msg=None):
1449
1448
  """Verifies that the given item is empty.
@@ -1452,7 +1451,7 @@ class _Verify(_BuiltInBase):
1452
1451
  default error message can be overridden with the ``msg`` argument.
1453
1452
  """
1454
1453
  if self.get_length(item) > 0:
1455
- raise AssertionError(msg or "'%s' should be empty." % (item,))
1454
+ raise AssertionError(msg or f"'{item}' should be empty.")
1456
1455
 
1457
1456
  def should_not_be_empty(self, item, msg=None):
1458
1457
  """Verifies that the given item is not empty.
@@ -1461,18 +1460,18 @@ class _Verify(_BuiltInBase):
1461
1460
  default error message can be overridden with the ``msg`` argument.
1462
1461
  """
1463
1462
  if self.get_length(item) == 0:
1464
- raise AssertionError(msg or "'%s' should not be empty." % (item,))
1463
+ raise AssertionError(msg or f"'{item}' should not be empty.")
1465
1464
 
1466
1465
  def _get_string_msg(self, item1, item2, custom_message, include_values,
1467
1466
  delimiter, quote_item1=True, quote_item2=True):
1468
1467
  if custom_message and not self._include_values(include_values):
1469
1468
  return custom_message
1470
- item1 = "'%s'" % safe_str(item1) if quote_item1 else safe_str(item1)
1471
- item2 = "'%s'" % safe_str(item2) if quote_item2 else safe_str(item2)
1472
- default_message = '%s %s %s' % (item1, delimiter, item2)
1469
+ item1 = f"'{safe_str(item1)}'" if quote_item1 else safe_str(item1)
1470
+ item2 = f"'{safe_str(item2)}'" if quote_item2 else safe_str(item2)
1471
+ default_message = f'{item1} {delimiter} {item2}'
1473
1472
  if not custom_message:
1474
1473
  return default_message
1475
- return '%s: %s' % (custom_message, default_message)
1474
+ return f'{custom_message}: {default_message}'
1476
1475
 
1477
1476
 
1478
1477
  class _Variables(_BuiltInBase):
@@ -1533,7 +1532,7 @@ class _Variables(_BuiltInBase):
1533
1532
  def log_variables(self, level='INFO'):
1534
1533
  """Logs all variables in the current scope with given log level."""
1535
1534
  variables = self.get_variables()
1536
- for name in sorted(variables, key=lambda s: s[2:-1].lower()):
1535
+ for name in sorted(variables, key=lambda s: s[2:-1].casefold()):
1537
1536
  name, value = self._get_logged_variable(name, variables)
1538
1537
  msg = format_assign_message(name, value, cut_long=False)
1539
1538
  self.log(msg, level)
@@ -1569,7 +1568,7 @@ class _Variables(_BuiltInBase):
1569
1568
  self._variables.replace_scalar(name)
1570
1569
  except VariableError:
1571
1570
  raise AssertionError(self._variables.replace_string(msg)
1572
- if msg else "Variable '%s' does not exist." % name)
1571
+ if msg else f"Variable '{name}' does not exist.")
1573
1572
 
1574
1573
  @run_keyword_variant(resolve=0)
1575
1574
  def variable_should_not_exist(self, name, msg=None):
@@ -1591,14 +1590,14 @@ class _Variables(_BuiltInBase):
1591
1590
  pass
1592
1591
  else:
1593
1592
  raise AssertionError(self._variables.replace_string(msg)
1594
- if msg else "Variable '%s' exists." % name)
1593
+ if msg else f"Variable '{name}' exists.")
1595
1594
 
1596
1595
  def replace_variables(self, text):
1597
1596
  """Replaces variables in the given text with their current values.
1598
1597
 
1599
1598
  If the text contains undefined variables, this keyword fails.
1600
1599
  If the given ``text`` contains only a single variable, its value is
1601
- returned as-is and it can be any object. Otherwise this keyword
1600
+ returned as-is and it can be any object. Otherwise, this keyword
1602
1601
  always returns a string.
1603
1602
 
1604
1603
  Example:
@@ -1621,16 +1620,23 @@ class _Variables(_BuiltInBase):
1621
1620
  It is recommended to use `Create List` when creating new lists.
1622
1621
 
1623
1622
  Examples:
1624
- | ${hi} = | Set Variable | Hello, world! |
1625
- | ${hi2} = | Set Variable | I said: ${hi} |
1626
- | ${var1} | ${var2} = | Set Variable | Hello | world |
1627
- | @{list} = | Set Variable | ${list with some items} |
1628
- | ${item1} | ${item2} = | Set Variable | ${list with 2 items} |
1623
+ | ${hi} = Set Variable Hello, world!
1624
+ | ${hi2} = Set Variable I said: ${hi}
1625
+ | ${var1} ${var2} = Set Variable Hello world
1626
+ | @{list} = Set Variable ${list with some items}
1627
+ | ${item1} ${item2} = Set Variable ${list with 2 items}
1629
1628
 
1630
1629
  Variables created with this keyword are available only in the
1631
1630
  scope where they are created. See `Set Global Variable`,
1632
1631
  `Set Test Variable` and `Set Suite Variable` for information on how to
1633
1632
  set variables so that they are available also in a larger scope.
1633
+
1634
+ *NOTE:* The ``VAR`` syntax introduced in Robot Framework 7.0 is generally
1635
+ recommended over this keyword. The basic usage is shown below and the Robot
1636
+ Framework User Guide explains the syntax in detail.
1637
+
1638
+ | VAR ${hi} Hello, world!
1639
+ | VAR ${hi2} I said: ${hi}
1634
1640
  """
1635
1641
  if len(values) == 0:
1636
1642
  return ''
@@ -1670,10 +1676,13 @@ class _Variables(_BuiltInBase):
1670
1676
  ``${name}``.
1671
1677
 
1672
1678
  See also `Set Global Variable` and `Set Test Variable`.
1679
+
1680
+ *NOTE:* The ``VAR`` syntax introduced in Robot Framework 7.0 is recommended
1681
+ over this keyword.
1673
1682
  """
1674
1683
  name = self._get_var_name(name)
1675
1684
  value = self._get_var_value(name, values)
1676
- self._variables.set_local_variable(name, value)
1685
+ self._variables.set_local(name, value)
1677
1686
  self._log_set_variable(name, value)
1678
1687
 
1679
1688
  @run_keyword_variant(resolve=0)
@@ -1696,6 +1705,9 @@ class _Variables(_BuiltInBase):
1696
1705
 
1697
1706
  When creating automated tasks, not tests, it is possible to use `Set
1698
1707
  Task Variable`. See also `Set Global Variable` and `Set Local Variable`.
1708
+
1709
+ *NOTE:* The ``VAR`` syntax introduced in Robot Framework 7.0 is recommended
1710
+ over this keyword.
1699
1711
  """
1700
1712
  name = self._get_var_name(name)
1701
1713
  value = self._get_var_value(name, values)
@@ -1708,6 +1720,9 @@ class _Variables(_BuiltInBase):
1708
1720
 
1709
1721
  This is an alias for `Set Test Variable` that is more applicable when
1710
1722
  creating tasks, not tests.
1723
+
1724
+ *NOTE:* The ``VAR`` syntax introduced in Robot Framework 7.0 is recommended
1725
+ over this keyword.
1711
1726
  """
1712
1727
  self.set_test_variable(name, *values)
1713
1728
 
@@ -1760,6 +1775,14 @@ class _Variables(_BuiltInBase):
1760
1775
  | Set Suite Variable &DICT &{EMPTY}
1761
1776
 
1762
1777
  See also `Set Global Variable`, `Set Test Variable` and `Set Local Variable`.
1778
+
1779
+ *NOTE:* The ``VAR`` syntax introduced in Robot Framework 7.0 is recommended
1780
+ over this keyword. The basic usage is shown below and the Robot Framework
1781
+ User Guide explains the syntax in detail.
1782
+
1783
+ | VAR ${SCALAR} Hello, world! scope=SUITE
1784
+ | VAR @{LIST} First item Second item scope=SUITE
1785
+ | VAR &{DICT} key=value foo=bar scope=SUITE
1763
1786
  """
1764
1787
  name = self._get_var_name(name)
1765
1788
  if values and is_string(values[-1]) and values[-1].startswith('children='):
@@ -1793,6 +1816,9 @@ class _Variables(_BuiltInBase):
1793
1816
  section for information why it is recommended to give the variable name
1794
1817
  in escaped format like ``$name`` or ``\${name}`` instead of the normal
1795
1818
  ``${name}``.
1819
+
1820
+ *NOTE:* The ``VAR`` syntax introduced in Robot Framework 7.0 is recommended
1821
+ over this keyword.
1796
1822
  """
1797
1823
  name = self._get_var_name(name)
1798
1824
  value = self._get_var_value(name, values)
@@ -1814,7 +1840,7 @@ class _Variables(_BuiltInBase):
1814
1840
  match.resolve_base(self._variables)
1815
1841
  valid = match.is_assign() if require_assign else match.is_variable()
1816
1842
  if not valid:
1817
- raise DataError("Invalid variable name '%s'." % name)
1843
+ raise DataError(f"Invalid variable name '{name}'.")
1818
1844
  return str(match)
1819
1845
 
1820
1846
  def _resolve_var_name(self, name):
@@ -1823,7 +1849,7 @@ class _Variables(_BuiltInBase):
1823
1849
  if len(name) < 2 or name[0] not in '$@&':
1824
1850
  raise ValueError
1825
1851
  if name[1] != '{':
1826
- name = '%s{%s}' % (name[0], name[1:])
1852
+ name = f'{name[0]}{{{name[1:]}}}'
1827
1853
  match = search_variable(name, identifiers='$@&', ignore_errors=True)
1828
1854
  match.resolve_base(self._variables)
1829
1855
  if not match.is_assign():
@@ -1839,11 +1865,12 @@ class _Variables(_BuiltInBase):
1839
1865
  # handling non-string values somehow. For details see
1840
1866
  # https://github.com/robotframework/robotframework/issues/1919
1841
1867
  if len(values) != 1 or is_list_variable(values[0]):
1842
- raise DataError("Setting list value to scalar variable '%s' "
1843
- "is not supported anymore. Create list "
1844
- "variable '@%s' instead." % (name, name[1:]))
1868
+ raise DataError(f"Setting list value to scalar variable '{name}' "
1869
+ f"is not supported anymore. Create list variable "
1870
+ f"'@{name[1:]}' instead.")
1845
1871
  return self._variables.replace_scalar(values[0])
1846
- return VariableTableValue(values, name).resolve(self._variables)
1872
+ resolver = VariableResolver.from_name_and_value(name, values)
1873
+ return resolver.resolve(self._variables)
1847
1874
 
1848
1875
  def _log_set_variable(self, name, value):
1849
1876
  self.log(format_assign_message(name, value))
@@ -1870,14 +1897,14 @@ class _RunKeyword(_BuiltInBase):
1870
1897
  ctx = self._context
1871
1898
  if not (ctx.dry_run or self._accepts_embedded_arguments(name, ctx)):
1872
1899
  name, args = self._replace_variables_in_name([name] + list(args))
1873
- parent = ctx.steps[-1] if ctx.steps else (ctx.test or ctx.suite)
1900
+ parent = ctx.steps[-1][0] if ctx.steps else (ctx.test or ctx.suite)
1874
1901
  kw = Keyword(name, args=args, parent=parent,
1875
1902
  lineno=getattr(parent, 'lineno', None))
1876
1903
  return kw.run(ctx)
1877
1904
 
1878
1905
  def _accepts_embedded_arguments(self, name, ctx):
1879
1906
  if '{' in name:
1880
- runner = ctx.get_runner(name)
1907
+ runner = ctx.get_runner(name, recommend_on_failure=False)
1881
1908
  return runner and hasattr(runner, 'embedded_args')
1882
1909
  return False
1883
1910
 
@@ -2048,7 +2075,7 @@ class _RunKeyword(_BuiltInBase):
2048
2075
  index = list(args).index(control_word)
2049
2076
  branch = self._variables.replace_list(args[index+1:], required)
2050
2077
  if len(branch) < required:
2051
- raise DataError('%s requires %s.' % (control_word, required_error))
2078
+ raise DataError(f'{control_word} requires {required_error}.')
2052
2079
  return args[:index], branch
2053
2080
 
2054
2081
  @run_keyword_variant(resolve=1, dry_run=True)
@@ -2105,7 +2132,7 @@ class _RunKeyword(_BuiltInBase):
2105
2132
  """
2106
2133
  status, message = self.run_keyword_and_ignore_error(name, *args)
2107
2134
  if status == 'FAIL':
2108
- logger.warn("Executing keyword '%s' failed:\n%s" % (name, message))
2135
+ logger.warn(f"Executing keyword '{name}' failed:\n{message}")
2109
2136
  return status, message
2110
2137
 
2111
2138
  @run_keyword_variant(resolve=0, dry_run=True)
@@ -2206,11 +2233,9 @@ class _RunKeyword(_BuiltInBase):
2206
2233
  raise
2207
2234
  error = err.message
2208
2235
  else:
2209
- raise AssertionError("Expected error '%s' did not occur."
2210
- % expected_error)
2236
+ raise AssertionError(f"Expected error '{expected_error}' did not occur.")
2211
2237
  if not self._error_is_expected(error, expected_error):
2212
- raise AssertionError("Expected error '%s' but got '%s'."
2213
- % (expected_error, error))
2238
+ raise AssertionError(f"Expected error '{expected_error}' but got '{error}'.")
2214
2239
  return error
2215
2240
 
2216
2241
  def _error_is_expected(self, error, expected_error):
@@ -2218,7 +2243,7 @@ class _RunKeyword(_BuiltInBase):
2218
2243
  matchers = {'GLOB': glob,
2219
2244
  'EQUALS': lambda s, p: s == p,
2220
2245
  'STARTS': lambda s, p: s.startswith(p),
2221
- 'REGEXP': lambda s, p: re.match(p + r'\Z', s) is not None}
2246
+ 'REGEXP': lambda s, p: re.fullmatch(p, s) is not None}
2222
2247
  prefixes = tuple(prefix + ':' for prefix in matchers)
2223
2248
  if not expected_error.startswith(prefixes):
2224
2249
  return glob(error, expected_error)
@@ -2287,21 +2312,20 @@ class _RunKeyword(_BuiltInBase):
2287
2312
 
2288
2313
  def _keywords_repeated_by_count(self, count, name, args):
2289
2314
  if count <= 0:
2290
- self.log("Keyword '%s' repeated zero times." % name)
2315
+ self.log(f"Keyword '{name}' repeated zero times.")
2291
2316
  for i in range(count):
2292
- self.log("Repeating keyword, round %d/%d." % (i + 1, count))
2317
+ self.log(f"Repeating keyword, round {i+1}/{count}.")
2293
2318
  yield name, args
2294
2319
 
2295
2320
  def _keywords_repeated_by_timeout(self, timeout, name, args):
2296
2321
  if timeout <= 0:
2297
- self.log("Keyword '%s' repeated zero times." % name)
2298
- repeat_round = 0
2322
+ self.log(f"Keyword '{name}' repeated zero times.")
2323
+ round = 0
2299
2324
  maxtime = time.time() + timeout
2300
2325
  while time.time() < maxtime:
2301
- repeat_round += 1
2302
- self.log("Repeating keyword, round %d, %s remaining."
2303
- % (repeat_round,
2304
- secs_to_timestr(maxtime - time.time(), compact=True)))
2326
+ round += 1
2327
+ remaining = secs_to_timestr(maxtime - time.time(), compact=True)
2328
+ self.log(f"Repeating keyword, round {round}, {remaining} remaining.")
2305
2329
  yield name, args
2306
2330
 
2307
2331
  @run_keyword_variant(resolve=2, dry_run=True)
@@ -2354,11 +2378,11 @@ class _RunKeyword(_BuiltInBase):
2354
2378
  except ValueError:
2355
2379
  timeout = timestr_to_secs(retry)
2356
2380
  maxtime = time.time() + timeout
2357
- message = 'for %s' % secs_to_timestr(timeout)
2381
+ message = f'for {secs_to_timestr(timeout)}'
2358
2382
  else:
2359
2383
  if count <= 0:
2360
- raise ValueError('Retry count %d is not positive.' % count)
2361
- message = '%d time%s' % (count, s(count))
2384
+ raise ValueError(f'Retry count {count} is not positive.')
2385
+ message = f'{count} time{s(count)}'
2362
2386
  if is_string(retry_interval) and normalize(retry_interval).startswith('strict:'):
2363
2387
  retry_interval = retry_interval.split(':', 1)[1].strip()
2364
2388
  strict_interval = True
@@ -2374,16 +2398,18 @@ class _RunKeyword(_BuiltInBase):
2374
2398
  raise
2375
2399
  count -= 1
2376
2400
  if time.time() > maxtime > 0 or count == 0:
2377
- raise AssertionError("Keyword '%s' failed after retrying %s. "
2378
- "The last error was: %s" % (name, message, err))
2401
+ raise AssertionError(f"Keyword '{name}' failed after retrying "
2402
+ f"{message}. The last error was: {err}")
2379
2403
  finally:
2380
2404
  if strict_interval:
2381
- keyword_runtime = time.time() - start_time
2382
- sleep_time = retry_interval - keyword_runtime
2405
+ execution_time = time.time() - start_time
2406
+ sleep_time = retry_interval - execution_time
2383
2407
  if sleep_time < 0:
2384
- logger.warn("Keyword execution time %s is longer than retry "
2385
- "interval %s." % (secs_to_timestr(keyword_runtime),
2386
- secs_to_timestr(retry_interval)))
2408
+ logger.warn(
2409
+ f"Keyword execution time {secs_to_timestr(execution_time)} "
2410
+ f"is longer than retry interval "
2411
+ f"{secs_to_timestr(retry_interval)}."
2412
+ )
2387
2413
  self._sleep_in_parts(sleep_time)
2388
2414
 
2389
2415
  @run_keyword_variant(resolve=1)
@@ -2426,19 +2452,21 @@ class _RunKeyword(_BuiltInBase):
2426
2452
  Use `Get Variable Value` if you need to set variables
2427
2453
  dynamically based on whether a variable exist or not.
2428
2454
  """
2429
- values = self._verify_values_for_set_variable_if(list(values))
2430
- if self._is_true(condition):
2431
- return self._variables.replace_scalar(values[0])
2432
- values = self._verify_values_for_set_variable_if(values[1:], True)
2433
- if len(values) == 1:
2434
- return self._variables.replace_scalar(values[0])
2435
- return self.run_keyword('BuiltIn.Set Variable If', *values[0:])
2436
-
2437
- def _verify_values_for_set_variable_if(self, values, default=False):
2455
+ values = list(values)
2456
+ while True:
2457
+ values = self._verify_values_for_set_variable_if(values)
2458
+ if self._is_true(condition):
2459
+ return self._variables.replace_scalar(values[0])
2460
+ if len(values) == 1:
2461
+ return None
2462
+ if len(values) == 2:
2463
+ return self._variables.replace_scalar(values[1])
2464
+ condition, *values = values[1:]
2465
+ condition = self._variables.replace_scalar(condition)
2466
+
2467
+ def _verify_values_for_set_variable_if(self, values):
2438
2468
  if not values:
2439
- if default:
2440
- return [None]
2441
- raise RuntimeError('At least one value is required')
2469
+ raise RuntimeError('At least one value is required.')
2442
2470
  if is_list_variable(values[0]):
2443
2471
  values[:1] = [escape(item) for item in self._variables[values[0]]]
2444
2472
  return self._verify_values_for_set_variable_if(values)
@@ -2520,10 +2548,9 @@ class _RunKeyword(_BuiltInBase):
2520
2548
  if suite.statistics.failed > 0:
2521
2549
  return self.run_keyword(name, *args)
2522
2550
 
2523
- def _get_suite_in_teardown(self, kwname):
2551
+ def _get_suite_in_teardown(self, kw):
2524
2552
  if not self._context.in_suite_teardown:
2525
- raise RuntimeError("Keyword '%s' can only be used in suite teardown."
2526
- % kwname)
2553
+ raise RuntimeError(f"Keyword '{kw}' can only be used in suite teardown.")
2527
2554
  return self._context.suite
2528
2555
 
2529
2556
 
@@ -2872,7 +2899,7 @@ class _Control(_BuiltInBase):
2872
2899
  Passing execution in the middle of a test, setup or teardown should be
2873
2900
  used with care. In the worst case it leads to tests that skip all the
2874
2901
  parts that could actually uncover problems in the tested application.
2875
- In cases where execution cannot continue do to external factors,
2902
+ In cases where execution cannot continue due to external factors,
2876
2903
  it is often safer to fail the test case and make it non-critical.
2877
2904
  """
2878
2905
  message = message.strip()
@@ -2880,7 +2907,7 @@ class _Control(_BuiltInBase):
2880
2907
  raise RuntimeError('Message cannot be empty.')
2881
2908
  self._set_and_remove_tags(tags)
2882
2909
  log_message, level = self._get_logged_test_message_and_level(message)
2883
- self.log('Execution passed with message:\n%s' % log_message, level)
2910
+ self.log(f'Execution passed with message:\n{log_message}', level)
2884
2911
  raise PassExecution(message)
2885
2912
 
2886
2913
  @run_keyword_variant(resolve=1)
@@ -2931,7 +2958,7 @@ class _Misc(_BuiltInBase):
2931
2958
  if seconds < 0:
2932
2959
  seconds = 0
2933
2960
  self._sleep_in_parts(seconds)
2934
- self.log('Slept %s' % secs_to_timestr(seconds))
2961
+ self.log(f'Slept {secs_to_timestr(seconds)}.')
2935
2962
  if reason:
2936
2963
  self.log(reason)
2937
2964
 
@@ -3050,8 +3077,8 @@ class _Misc(_BuiltInBase):
3050
3077
  'len': len,
3051
3078
  'type': lambda x: type(x).__name__}[formatter.lower()]
3052
3079
  except KeyError:
3053
- raise ValueError("Invalid formatter '%s'. Available "
3054
- "'str', 'repr', 'ascii', 'len', and 'type'." % formatter)
3080
+ raise ValueError(f"Invalid formatter '{formatter}'. Available "
3081
+ f"'str', 'repr', 'ascii', 'len', and 'type'.")
3055
3082
 
3056
3083
  @run_keyword_variant(resolve=0)
3057
3084
  def log_many(self, *messages):
@@ -3078,7 +3105,7 @@ class _Misc(_BuiltInBase):
3078
3105
  yield item
3079
3106
  elif match.is_dict_variable():
3080
3107
  for name, value in value.items():
3081
- yield '%s=%s' % (name, value)
3108
+ yield f'{name}={value}'
3082
3109
  else:
3083
3110
  yield value
3084
3111
 
@@ -3131,18 +3158,14 @@ class _Misc(_BuiltInBase):
3131
3158
  """Sets the log threshold to the specified level and returns the old level.
3132
3159
 
3133
3160
  Messages below the level will not logged. The default logging level is
3134
- INFO, but it can be overridden with the command line option
3135
- ``--loglevel``.
3161
+ INFO, but it can be overridden with the command line option ``--loglevel``.
3136
3162
 
3137
- The available levels: TRACE, DEBUG, INFO (default), WARN, ERROR and NONE (no
3138
- logging).
3163
+ The available levels: TRACE, DEBUG, INFO (default), WARN, ERROR and NONE
3164
+ (no logging).
3139
3165
  """
3140
- try:
3141
- old = self._context.output.set_log_level(level)
3142
- except DataError as err:
3143
- raise RuntimeError(str(err))
3166
+ old = self._context.output.set_log_level(level)
3144
3167
  self._namespace.variables.set_global('${LOG_LEVEL}', level.upper())
3145
- self.log('Log level changed from %s to %s.' % (old, level.upper()))
3168
+ self.log(f'Log level changed from {old} to {level.upper()}.', level='DEBUG')
3146
3169
  return old
3147
3170
 
3148
3171
  def reload_library(self, name_or_instance):
@@ -3156,8 +3179,7 @@ class _Misc(_BuiltInBase):
3156
3179
  calls this keyword as a method.
3157
3180
  """
3158
3181
  library = self._namespace.reload_library(name_or_instance)
3159
- self.log('Reloaded library %s with %s keywords.' % (library.name,
3160
- len(library)))
3182
+ self.log(f'Reloaded library {library.name} with {len(library)} keywords.')
3161
3183
 
3162
3184
  @run_keyword_variant(resolve=0)
3163
3185
  def import_library(self, name, *args):
@@ -3523,7 +3545,7 @@ class _Misc(_BuiltInBase):
3523
3545
  if self._context.in_test_teardown:
3524
3546
  self._variables.set_test("${TEST_MESSAGE}", test.message)
3525
3547
  message, level = self._get_logged_test_message_and_level(test.message)
3526
- self.log('Set test message to:\n%s' % message, level)
3548
+ self.log(f'Set test message to:\n{message}', level)
3527
3549
 
3528
3550
  def _get_new_text(self, old, new, append, handle_html=False):
3529
3551
  if not is_string(new):
@@ -3534,10 +3556,10 @@ class _Misc(_BuiltInBase):
3534
3556
  if new.startswith('*HTML*'):
3535
3557
  new = new[6:].lstrip()
3536
3558
  if not old.startswith('*HTML*'):
3537
- old = '*HTML* %s' % html_escape(old)
3559
+ old = f'*HTML* {html_escape(old)}'
3538
3560
  elif old.startswith('*HTML*'):
3539
3561
  new = html_escape(new)
3540
- return '%s %s' % (old, new)
3562
+ return f'{old} {new}'
3541
3563
 
3542
3564
  def _get_logged_test_message_and_level(self, message):
3543
3565
  if message.startswith('*HTML*'):
@@ -3561,12 +3583,12 @@ class _Misc(_BuiltInBase):
3561
3583
  "used in suite setup or teardown.")
3562
3584
  test.doc = self._get_new_text(test.doc, doc, append)
3563
3585
  self._variables.set_test('${TEST_DOCUMENTATION}', test.doc)
3564
- self.log('Set test documentation to:\n%s' % test.doc)
3586
+ self.log(f'Set test documentation to:\n{test.doc}')
3565
3587
 
3566
3588
  def set_suite_documentation(self, doc, append=False, top=False):
3567
3589
  """Sets documentation for the current test suite.
3568
3590
 
3569
- By default the possible existing documentation is overwritten, but
3591
+ By default, the possible existing documentation is overwritten, but
3570
3592
  this can be changed using the optional ``append`` argument similarly
3571
3593
  as with `Set Test Message` keyword.
3572
3594
 
@@ -3581,12 +3603,12 @@ class _Misc(_BuiltInBase):
3581
3603
  suite = self._get_context(top).suite
3582
3604
  suite.doc = self._get_new_text(suite.doc, doc, append)
3583
3605
  self._variables.set_suite('${SUITE_DOCUMENTATION}', suite.doc, top)
3584
- self.log('Set suite documentation to:\n%s' % suite.doc)
3606
+ self.log(f'Set suite documentation to:\n{suite.doc}')
3585
3607
 
3586
3608
  def set_suite_metadata(self, name, value, append=False, top=False):
3587
3609
  """Sets metadata for the current test suite.
3588
3610
 
3589
- By default possible existing metadata values are overwritten, but
3611
+ By default, possible existing metadata values are overwritten, but
3590
3612
  this can be changed using the optional ``append`` argument similarly
3591
3613
  as with `Set Test Message` keyword.
3592
3614
 
@@ -3604,7 +3626,7 @@ class _Misc(_BuiltInBase):
3604
3626
  original = metadata.get(name, '')
3605
3627
  metadata[name] = self._get_new_text(original, value, append)
3606
3628
  self._variables.set_suite('${SUITE_METADATA}', metadata.copy(), top)
3607
- self.log("Set suite metadata '%s' to value '%s'." % (name, metadata[name]))
3629
+ self.log(f"Set suite metadata '{name}' to value '{metadata[name]}'.")
3608
3630
 
3609
3631
  def set_tags(self, *tags):
3610
3632
  """Adds given ``tags`` for the current test or all tests in a suite.
@@ -3629,7 +3651,7 @@ class _Misc(_BuiltInBase):
3629
3651
  ctx.suite.set_tags(tags, persist=True)
3630
3652
  else:
3631
3653
  raise RuntimeError("'Set Tags' cannot be used in suite teardown.")
3632
- self.log('Set tag%s %s.' % (s(tags), seq2str(tags)))
3654
+ self.log(f'Set tag{s(tags)} {seq2str((tags))}.')
3633
3655
 
3634
3656
  def remove_tags(self, *tags):
3635
3657
  """Removes given ``tags`` from the current test or all tests in a suite.
@@ -3657,7 +3679,7 @@ class _Misc(_BuiltInBase):
3657
3679
  ctx.suite.set_tags(remove=tags, persist=True)
3658
3680
  else:
3659
3681
  raise RuntimeError("'Remove Tags' cannot be used in suite teardown.")
3660
- self.log('Removed tag%s %s.' % (s(tags), seq2str(tags)))
3682
+ self.log(f'Removed tag{s(tags)} {seq2str((tags))}.')
3661
3683
 
3662
3684
  def get_library_instance(self, name=None, all=False):
3663
3685
  """Returns the currently active instance of the specified library.
@@ -3672,8 +3694,7 @@ class _Misc(_BuiltInBase):
3672
3694
  | seleniumlib = BuiltIn().get_library_instance('SeleniumLibrary')
3673
3695
  | title = seleniumlib.get_title()
3674
3696
  | if not title.startswith(expected):
3675
- | raise AssertionError("Title '%s' did not start with '%s'"
3676
- | % (title, expected))
3697
+ | raise AssertionError(f"Title '{title}' did not start with '{expected}'.")
3677
3698
 
3678
3699
  It is also possible to use this keyword in the test data and
3679
3700
  pass the returned library instance to another keyword. If a
@@ -3716,40 +3737,6 @@ class BuiltIn(_Verify, _Converter, _Variables, _RunKeyword, _Control, _Misc):
3716
3737
  HTML in messages is not limited to BuiltIn library but works with any
3717
3738
  error message.
3718
3739
 
3719
- = Using variables with keywords creating or accessing variables =
3720
-
3721
- This library has special keywords `Set Global Variable`, `Set Suite Variable`,
3722
- `Set Test Variable` and `Set Local Variable` for creating variables in
3723
- different scopes. These keywords take the variable name and its value as
3724
- arguments. The name can be given using the normal ``${variable}`` syntax or
3725
- in escaped format either like ``$variable`` or ``\${variable}``. For example,
3726
- these are typically equivalent and create new suite level variable
3727
- ``${name}`` with value ``value``:
3728
-
3729
- | Set Suite Variable ${name} value
3730
- | Set Suite Variable $name value
3731
- | Set Suite Variable \${name} value
3732
-
3733
- A problem with using the normal ``${variable}`` syntax is that these
3734
- keywords cannot easily know is the idea to create a variable with exactly
3735
- that name or does that variable actually contain the name of the variable
3736
- to create. If the variable does not initially exist, it will always be
3737
- created. If it exists and its value is a variable name either in the normal
3738
- or in the escaped syntax, variable with _that_ name is created instead.
3739
- For example, if ``${name}`` variable would exist and contain value
3740
- ``$example``, these examples would create different variables:
3741
-
3742
- | Set Suite Variable ${name} value # Creates ${example}.
3743
- | Set Suite Variable $name value # Creates ${name}.
3744
- | Set Suite Variable \${name} value # Creates ${name}.
3745
-
3746
- Because the behavior when using the normal ``${variable}`` syntax depends
3747
- on the possible existing value of the variable, it is *highly recommended
3748
- to use the escaped ``$variable`` or ``\${variable}`` format instead*.
3749
-
3750
- This same problem occurs also with special keywords for accessing variables
3751
- `Get Variable Value`, `Variable Should Exist` and `Variable Should Not Exist`.
3752
-
3753
3740
  = Evaluating expressions =
3754
3741
 
3755
3742
  Many keywords, such as `Evaluate`, `Run Keyword If` and `Should Be True`,
@@ -3814,6 +3801,45 @@ class BuiltIn(_Verify, _Converter, _Variables, _RunKeyword, _Control, _Misc):
3814
3801
  to move the logic into a library. That eases maintenance and can also
3815
3802
  enhance execution speed.
3816
3803
 
3804
+ = Using variables with keywords creating or accessing variables =
3805
+
3806
+ This library has special keywords `Set Global Variable`, `Set Suite Variable`,
3807
+ `Set Test Variable` and `Set Local Variable` for creating variables in
3808
+ different scopes. These keywords take the variable name and its value as
3809
+ arguments. The name can be given using the normal ``${variable}`` syntax or
3810
+ in escaped format either like ``$variable`` or ``\${variable}``. For example,
3811
+ these are typically equivalent and create new suite level variable
3812
+ ``${name}`` with value ``value``:
3813
+
3814
+ | Set Suite Variable ${name} value
3815
+ | Set Suite Variable $name value
3816
+ | Set Suite Variable \${name} value
3817
+
3818
+ A problem with using the normal ``${variable}`` syntax is that these
3819
+ keywords cannot easily know is the idea to create a variable with exactly
3820
+ that name or does that variable actually contain the name of the variable
3821
+ to create. If the variable does not initially exist, it will always be
3822
+ created. If it exists and its value is a variable name either in the normal
3823
+ or in the escaped syntax, variable with _that_ name is created instead.
3824
+ For example, if ``${name}`` variable would exist and contain value
3825
+ ``$example``, these examples would create different variables:
3826
+
3827
+ | Set Suite Variable ${name} value # Creates ${example}.
3828
+ | Set Suite Variable $name value # Creates ${name}.
3829
+ | Set Suite Variable \${name} value # Creates ${name}.
3830
+
3831
+ Because the behavior when using the normal ``${variable}`` syntax depends
3832
+ on the possible existing value of the variable, it is *highly recommended
3833
+ to use the escaped ``$variable`` or ``\${variable}`` format instead*.
3834
+
3835
+ This same problem occurs also with special keywords for accessing variables
3836
+ `Get Variable Value`, `Variable Should Exist` and `Variable Should Not Exist`.
3837
+
3838
+ *NOTE:* It is recommended to use the ``VAR`` syntax introduced in Robot
3839
+ Framework 7.0 for creating variables in different scopes instead of the
3840
+ `Set Global/Suite/Test/Local Variable` keywords. It makes creating variables
3841
+ uniform and avoids all the problems discussed above.
3842
+
3817
3843
  = Boolean arguments =
3818
3844
 
3819
3845
  Some keywords accept arguments that are handled as Boolean values true or