robotframework 6.1.1__zip → 7.0__zip

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (307) hide show
  1. {robotframework-6.1.1 → robotframework-7.0}/INSTALL.rst +25 -25
  2. {robotframework-6.1.1 → robotframework-7.0}/PKG-INFO +6 -8
  3. {robotframework-6.1.1 → robotframework-7.0}/README.rst +3 -2
  4. {robotframework-6.1.1 → robotframework-7.0}/setup.py +3 -6
  5. {robotframework-6.1.1 → robotframework-7.0}/src/robot/api/__init__.py +4 -1
  6. {robotframework-6.1.1 → robotframework-7.0}/src/robot/api/deco.py +60 -14
  7. {robotframework-6.1.1 → robotframework-7.0}/src/robot/api/exceptions.py +6 -6
  8. {robotframework-6.1.1 → robotframework-7.0}/src/robot/api/interfaces.py +402 -67
  9. {robotframework-6.1.1 → robotframework-7.0}/src/robot/api/logger.py +27 -20
  10. {robotframework-6.1.1 → robotframework-7.0}/src/robot/api/parsing.py +4 -2
  11. robotframework-7.0/src/robot/api/py.typed +0 -0
  12. {robotframework-6.1.1 → robotframework-7.0}/src/robot/conf/gatherfailed.py +2 -2
  13. {robotframework-6.1.1 → robotframework-7.0}/src/robot/conf/languages.py +0 -9
  14. {robotframework-6.1.1 → robotframework-7.0}/src/robot/conf/settings.py +21 -14
  15. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/common/storage.js +11 -6
  16. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/htmlfilewriter.py +1 -1
  17. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/libdoc/libdoc.css +10 -2
  18. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/libdoc/libdoc.html +10 -0
  19. robotframework-7.0/src/robot/htmldata/rebot/common.css +362 -0
  20. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/doc_formatting.css +13 -7
  21. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/log.css +51 -10
  22. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/log.html +14 -23
  23. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/model.js +2 -4
  24. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/report.css +83 -19
  25. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/report.html +22 -7
  26. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/testdata.js +10 -3
  27. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/view.js +84 -0
  28. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/template.py +3 -3
  29. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/builder.py +0 -8
  30. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/datatypes.py +9 -10
  31. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/htmlutils.py +4 -7
  32. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/jsonbuilder.py +38 -20
  33. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/model.py +21 -28
  34. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/robotbuilder.py +50 -31
  35. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/standardtypes.py +9 -1
  36. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/xmlbuilder.py +35 -20
  37. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/xmlwriter.py +18 -38
  38. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/BuiltIn.py +255 -205
  39. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/Collections.py +384 -240
  40. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/DateTime.py +73 -60
  41. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/OperatingSystem.py +6 -5
  42. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/Process.py +26 -27
  43. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/Remote.py +40 -36
  44. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/String.py +66 -76
  45. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/XML.py +66 -59
  46. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/__init__.py +2 -2
  47. {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/__init__.py +5 -5
  48. {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/body.py +44 -13
  49. {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/configurer.py +15 -11
  50. {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/control.py +226 -84
  51. {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/filter.py +31 -25
  52. {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/itemlist.py +9 -8
  53. robotframework-7.0/src/robot/model/keyword.py +77 -0
  54. {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/message.py +19 -10
  55. {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/modelobject.py +25 -7
  56. {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/namepatterns.py +3 -25
  57. {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/stats.py +9 -15
  58. {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/tags.py +1 -1
  59. {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/testcase.py +15 -27
  60. {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/testsuite.py +17 -26
  61. {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/visitor.py +35 -8
  62. robotframework-7.0/src/robot/output/console/dotted.py +90 -0
  63. {robotframework-6.1.1 → robotframework-7.0}/src/robot/output/console/quiet.py +3 -2
  64. {robotframework-6.1.1 → robotframework-7.0}/src/robot/output/console/verbose.py +61 -61
  65. {robotframework-6.1.1 → robotframework-7.0}/src/robot/output/debugfile.py +39 -24
  66. {robotframework-6.1.1 → robotframework-7.0}/src/robot/output/filelogger.py +18 -15
  67. {robotframework-6.1.1 → robotframework-7.0}/src/robot/output/librarylogger.py +3 -2
  68. robotframework-7.0/src/robot/output/listeners.py +753 -0
  69. {robotframework-6.1.1 → robotframework-7.0}/src/robot/output/logger.py +216 -80
  70. robotframework-7.0/src/robot/output/loggerapi.py +215 -0
  71. {robotframework-6.1.1 → robotframework-7.0}/src/robot/output/loggerhelper.py +23 -56
  72. robotframework-7.0/src/robot/output/output.py +185 -0
  73. {robotframework-6.1.1 → robotframework-7.0}/src/robot/output/stdoutlogsplitter.py +8 -5
  74. robotframework-7.0/src/robot/output/xmllogger.py +459 -0
  75. {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/lexer/blocklexers.py +17 -13
  76. {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/lexer/context.py +12 -2
  77. {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/lexer/lexer.py +1 -1
  78. {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/lexer/settings.py +6 -3
  79. {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/lexer/statementlexers.py +39 -10
  80. {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/lexer/tokens.py +27 -29
  81. {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/model/blocks.py +19 -6
  82. {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/model/statements.py +193 -94
  83. robotframework-7.0/src/robot/parsing/model/visitor.py +100 -0
  84. {robotframework-6.1.1 → robotframework-7.0}/src/robot/rebot.py +2 -0
  85. {robotframework-6.1.1 → robotframework-7.0}/src/robot/reporting/expandkeywordmatcher.py +1 -1
  86. {robotframework-6.1.1 → robotframework-7.0}/src/robot/reporting/jsbuildingcontext.py +8 -6
  87. {robotframework-6.1.1 → robotframework-7.0}/src/robot/reporting/jsmodelbuilders.py +88 -61
  88. {robotframework-6.1.1 → robotframework-7.0}/src/robot/reporting/logreportwriters.py +16 -10
  89. {robotframework-6.1.1 → robotframework-7.0}/src/robot/reporting/outputwriter.py +18 -2
  90. {robotframework-6.1.1 → robotframework-7.0}/src/robot/reporting/resultwriter.py +4 -4
  91. {robotframework-6.1.1 → robotframework-7.0}/src/robot/reporting/stringcache.py +3 -3
  92. {robotframework-6.1.1 → robotframework-7.0}/src/robot/reporting/xunitwriter.py +15 -21
  93. {robotframework-6.1.1 → robotframework-7.0}/src/robot/result/__init__.py +3 -2
  94. {robotframework-6.1.1 → robotframework-7.0}/src/robot/result/configurer.py +12 -9
  95. {robotframework-6.1.1 → robotframework-7.0}/src/robot/result/executionresult.py +56 -8
  96. {robotframework-6.1.1 → robotframework-7.0}/src/robot/result/flattenkeywordmatcher.py +48 -9
  97. robotframework-7.0/src/robot/result/keywordremover.py +207 -0
  98. {robotframework-6.1.1 → robotframework-7.0}/src/robot/result/merger.py +1 -1
  99. robotframework-7.0/src/robot/result/model.py +1185 -0
  100. {robotframework-6.1.1 → robotframework-7.0}/src/robot/result/modeldeprecation.py +9 -3
  101. {robotframework-6.1.1 → robotframework-7.0}/src/robot/result/resultbuilder.py +46 -36
  102. {robotframework-6.1.1 → robotframework-7.0}/src/robot/result/xmlelementhandlers.py +83 -43
  103. {robotframework-6.1.1 → robotframework-7.0}/src/robot/run.py +2 -0
  104. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/__init__.py +14 -4
  105. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/arguments/__init__.py +2 -1
  106. robotframework-7.0/src/robot/running/arguments/argumentconverter.py +100 -0
  107. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/arguments/argumentmapper.py +26 -24
  108. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/arguments/argumentparser.py +82 -60
  109. robotframework-7.0/src/robot/running/arguments/argumentresolver.py +158 -0
  110. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/arguments/argumentspec.py +83 -116
  111. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/arguments/argumentvalidator.py +33 -27
  112. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/arguments/customconverters.py +15 -12
  113. robotframework-7.0/src/robot/running/arguments/embedded.py +145 -0
  114. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/arguments/typeconverters.py +233 -213
  115. robotframework-7.0/src/robot/running/arguments/typeinfo.py +317 -0
  116. robotframework-7.0/src/robot/running/arguments/typeinfoparser.py +219 -0
  117. robotframework-7.0/src/robot/running/arguments/typevalidator.py +60 -0
  118. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/bodyrunner.py +147 -129
  119. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/builder/builders.py +2 -1
  120. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/builder/parsers.py +10 -11
  121. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/builder/settings.py +9 -17
  122. robotframework-7.0/src/robot/running/builder/transformers.py +535 -0
  123. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/context.py +113 -31
  124. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/dynamicmethods.py +62 -34
  125. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/importer.py +27 -49
  126. robotframework-7.0/src/robot/running/invalidkeyword.py +67 -0
  127. robotframework-7.0/src/robot/running/keywordfinder.py +91 -0
  128. robotframework-7.0/src/robot/running/keywordimplementation.py +164 -0
  129. robotframework-7.0/src/robot/running/librarykeyword.py +392 -0
  130. robotframework-7.0/src/robot/running/librarykeywordrunner.py +250 -0
  131. robotframework-7.0/src/robot/running/libraryscopes.py +115 -0
  132. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/model.py +195 -377
  133. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/namespace.py +124 -137
  134. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/outputcapture.py +20 -12
  135. robotframework-7.0/src/robot/running/resourcemodel.py +448 -0
  136. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/statusreporter.py +16 -13
  137. robotframework-7.0/src/robot/running/suiterunner.py +265 -0
  138. robotframework-7.0/src/robot/running/testlibraries.py +500 -0
  139. robotframework-7.0/src/robot/running/userkeywordrunner.py +260 -0
  140. {robotframework-6.1.1 → robotframework-7.0}/src/robot/testdoc.py +18 -13
  141. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/__init__.py +53 -35
  142. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/connectioncache.py +64 -59
  143. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/dotdict.py +3 -0
  144. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/encodingsniffer.py +1 -1
  145. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/escaping.py +19 -19
  146. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/importer.py +2 -2
  147. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/markupwriters.py +23 -15
  148. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/misc.py +1 -2
  149. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/normalizing.py +9 -24
  150. robotframework-7.0/src/robot/utils/notset.py +33 -0
  151. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/platform.py +15 -5
  152. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/robotio.py +9 -9
  153. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/robotpath.py +1 -0
  154. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/robottime.py +122 -90
  155. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/robottypes.py +21 -31
  156. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/setter.py +0 -5
  157. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/text.py +7 -4
  158. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/unic.py +2 -2
  159. {robotframework-6.1.1 → robotframework-7.0}/src/robot/variables/__init__.py +2 -2
  160. {robotframework-6.1.1 → robotframework-7.0}/src/robot/variables/assigner.py +17 -19
  161. {robotframework-6.1.1 → robotframework-7.0}/src/robot/variables/evaluation.py +20 -17
  162. {robotframework-6.1.1 → robotframework-7.0}/src/robot/variables/filesetter.py +80 -80
  163. {robotframework-6.1.1 → robotframework-7.0}/src/robot/variables/replacer.py +33 -36
  164. {robotframework-6.1.1 → robotframework-7.0}/src/robot/variables/scopes.py +17 -12
  165. {robotframework-6.1.1 → robotframework-7.0}/src/robot/variables/search.py +66 -41
  166. {robotframework-6.1.1 → robotframework-7.0}/src/robot/variables/store.py +14 -16
  167. robotframework-7.0/src/robot/variables/tablesetter.py +164 -0
  168. {robotframework-6.1.1 → robotframework-7.0}/src/robot/variables/variables.py +1 -1
  169. {robotframework-6.1.1 → robotframework-7.0}/src/robot/version.py +1 -1
  170. {robotframework-6.1.1 → robotframework-7.0}/src/robotframework.egg-info/PKG-INFO +6 -8
  171. {robotframework-6.1.1 → robotframework-7.0}/src/robotframework.egg-info/SOURCES.txt +10 -8
  172. {robotframework-6.1.1 → robotframework-7.0}/tasks.py +6 -6
  173. robotframework-6.1.1/src/robot/htmldata/rebot/common.css +0 -239
  174. robotframework-6.1.1/src/robot/libraries/Reserved.py +0 -48
  175. robotframework-6.1.1/src/robot/model/keyword.py +0 -173
  176. robotframework-6.1.1/src/robot/output/console/dotted.py +0 -90
  177. robotframework-6.1.1/src/robot/output/listenerarguments.py +0 -165
  178. robotframework-6.1.1/src/robot/output/listenermethods.py +0 -113
  179. robotframework-6.1.1/src/robot/output/listeners.py +0 -174
  180. robotframework-6.1.1/src/robot/output/output.py +0 -95
  181. robotframework-6.1.1/src/robot/output/xmllogger.py +0 -354
  182. robotframework-6.1.1/src/robot/parsing/model/visitor.py +0 -67
  183. robotframework-6.1.1/src/robot/result/keywordremover.py +0 -183
  184. robotframework-6.1.1/src/robot/result/model.py +0 -957
  185. robotframework-6.1.1/src/robot/running/arguments/argumentconverter.py +0 -79
  186. robotframework-6.1.1/src/robot/running/arguments/argumentresolver.py +0 -131
  187. robotframework-6.1.1/src/robot/running/arguments/embedded.py +0 -146
  188. robotframework-6.1.1/src/robot/running/arguments/typevalidator.py +0 -56
  189. robotframework-6.1.1/src/robot/running/builder/transformers.py +0 -642
  190. robotframework-6.1.1/src/robot/running/handlers.py +0 -321
  191. robotframework-6.1.1/src/robot/running/handlerstore.py +0 -66
  192. robotframework-6.1.1/src/robot/running/librarykeywordrunner.py +0 -238
  193. robotframework-6.1.1/src/robot/running/libraryscopes.py +0 -97
  194. robotframework-6.1.1/src/robot/running/modelcombiner.py +0 -32
  195. robotframework-6.1.1/src/robot/running/suiterunner.py +0 -248
  196. robotframework-6.1.1/src/robot/running/testlibraries.py +0 -423
  197. robotframework-6.1.1/src/robot/running/usererrorhandler.py +0 -75
  198. robotframework-6.1.1/src/robot/running/userkeyword.py +0 -111
  199. robotframework-6.1.1/src/robot/running/userkeywordrunner.py +0 -274
  200. robotframework-6.1.1/src/robot/variables/tablesetter.py +0 -156
  201. {robotframework-6.1.1 → robotframework-7.0}/AUTHORS.rst +0 -0
  202. {robotframework-6.1.1 → robotframework-7.0}/BUILD.rst +0 -0
  203. {robotframework-6.1.1 → robotframework-7.0}/CONTRIBUTING.rst +0 -0
  204. {robotframework-6.1.1 → robotframework-7.0}/COPYRIGHT.txt +0 -0
  205. {robotframework-6.1.1 → robotframework-7.0}/LICENSE.txt +0 -0
  206. {robotframework-6.1.1 → robotframework-7.0}/MANIFEST.in +0 -0
  207. {robotframework-6.1.1 → robotframework-7.0}/setup.cfg +0 -0
  208. {robotframework-6.1.1 → robotframework-7.0}/src/robot/__init__.py +0 -0
  209. {robotframework-6.1.1 → robotframework-7.0}/src/robot/__main__.py +0 -0
  210. {robotframework-6.1.1 → robotframework-7.0}/src/robot/conf/__init__.py +0 -0
  211. {robotframework-6.1.1 → robotframework-7.0}/src/robot/errors.py +0 -0
  212. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/__init__.py +0 -0
  213. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/common/__init__.py +0 -0
  214. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/common/js_disabled.css +0 -0
  215. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/jsonwriter.py +0 -0
  216. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/lib/__init__.py +0 -0
  217. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/lib/jquery.highlight.min.js +0 -0
  218. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/lib/jquery.min.js +0 -0
  219. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/lib/jquery.tablesorter.min.js +0 -0
  220. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/lib/jquery.tmpl.min.js +0 -0
  221. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/lib/jsxcompressor.min.js +0 -0
  222. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/libdoc/__init__.py +0 -0
  223. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/libdoc/doc_formatting.css +0 -0
  224. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/libdoc/print.css +0 -0
  225. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/libdoc/pygments.css +0 -0
  226. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/__init__.py +0 -0
  227. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/fileloading.js +0 -0
  228. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/log.js +0 -0
  229. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/print.css +0 -0
  230. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/util.js +0 -0
  231. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/testdoc/__init__.py +0 -0
  232. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/testdoc/testdoc.css +0 -0
  233. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/testdoc/testdoc.html +0 -0
  234. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdoc.py +0 -0
  235. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/__init__.py +0 -0
  236. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/consoleviewer.py +0 -0
  237. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/htmlwriter.py +0 -0
  238. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/jsonwriter.py +0 -0
  239. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/output.py +0 -0
  240. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/writer.py +0 -0
  241. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/Dialogs.py +0 -0
  242. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/Easter.py +0 -0
  243. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/Screenshot.py +0 -0
  244. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/Telnet.py +0 -0
  245. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/dialogs_py.py +0 -0
  246. {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/fixture.py +0 -0
  247. {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/metadata.py +0 -0
  248. {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/modifier.py +0 -0
  249. {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/statistics.py +0 -0
  250. {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/suitestatistics.py +0 -0
  251. {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/tagsetter.py +0 -0
  252. {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/tagstatistics.py +0 -0
  253. {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/totalstatistics.py +0 -0
  254. {robotframework-6.1.1 → robotframework-7.0}/src/robot/output/__init__.py +0 -0
  255. {robotframework-6.1.1 → robotframework-7.0}/src/robot/output/console/__init__.py +0 -0
  256. {robotframework-6.1.1 → robotframework-7.0}/src/robot/output/console/highlighting.py +0 -0
  257. {robotframework-6.1.1 → robotframework-7.0}/src/robot/output/pyloggingconf.py +0 -0
  258. {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/__init__.py +0 -0
  259. {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/lexer/__init__.py +0 -0
  260. {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/lexer/tokenizer.py +0 -0
  261. {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/model/__init__.py +0 -0
  262. {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/parser/__init__.py +0 -0
  263. {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/parser/blockparsers.py +0 -0
  264. {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/parser/fileparser.py +0 -0
  265. {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/parser/parser.py +0 -0
  266. {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/suitestructure.py +0 -0
  267. {robotframework-6.1.1 → robotframework-7.0}/src/robot/pythonpathsetter.py +0 -0
  268. {robotframework-6.1.1 → robotframework-7.0}/src/robot/reporting/__init__.py +0 -0
  269. {robotframework-6.1.1 → robotframework-7.0}/src/robot/reporting/jsexecutionresult.py +0 -0
  270. {robotframework-6.1.1 → robotframework-7.0}/src/robot/reporting/jswriter.py +0 -0
  271. {robotframework-6.1.1 → robotframework-7.0}/src/robot/result/executionerrors.py +0 -0
  272. {robotframework-6.1.1 → robotframework-7.0}/src/robot/result/messagefilter.py +0 -0
  273. {robotframework-6.1.1 → robotframework-7.0}/src/robot/result/suiteteardownfailed.py +0 -0
  274. {robotframework-6.1.1 → robotframework-7.0}/src/robot/result/visitor.py +0 -0
  275. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/builder/__init__.py +0 -0
  276. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/randomizer.py +0 -0
  277. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/runkwregister.py +0 -0
  278. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/signalhandler.py +0 -0
  279. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/status.py +0 -0
  280. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/timeouts/__init__.py +0 -0
  281. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/timeouts/posix.py +0 -0
  282. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/timeouts/windows.py +0 -0
  283. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/application.py +0 -0
  284. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/argumentparser.py +0 -0
  285. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/asserts.py +0 -0
  286. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/charwidth.py +0 -0
  287. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/compress.py +0 -0
  288. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/encoding.py +0 -0
  289. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/error.py +0 -0
  290. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/etreewrapper.py +0 -0
  291. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/filereader.py +0 -0
  292. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/frange.py +0 -0
  293. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/htmlformatters.py +0 -0
  294. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/markuputils.py +0 -0
  295. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/match.py +0 -0
  296. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/recommendations.py +0 -0
  297. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/restreader.py +0 -0
  298. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/robotenv.py +0 -0
  299. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/robotinspect.py +0 -0
  300. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/sortable.py +0 -0
  301. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/typehints.py +0 -0
  302. {robotframework-6.1.1 → robotframework-7.0}/src/robot/variables/finders.py +0 -0
  303. {robotframework-6.1.1 → robotframework-7.0}/src/robot/variables/notfound.py +0 -0
  304. {robotframework-6.1.1 → robotframework-7.0}/src/robot/variables/resolvable.py +0 -0
  305. {robotframework-6.1.1 → robotframework-7.0}/src/robotframework.egg-info/dependency_links.txt +0 -0
  306. {robotframework-6.1.1 → robotframework-7.0}/src/robotframework.egg-info/entry_points.txt +0 -0
  307. {robotframework-6.1.1 → robotframework-7.0}/src/robotframework.egg-info/top_level.txt +0 -0
@@ -105,7 +105,7 @@ class VariableAssigner:
105
105
 
106
106
  def assign(self, return_value):
107
107
  context = self._context
108
- context.output.trace(lambda: 'Return: %s' % prepr(return_value),
108
+ context.output.trace(lambda: f'Return: {prepr(return_value)}',
109
109
  write_if_flat=False)
110
110
  resolver = ReturnValueResolver(self._assignment)
111
111
  for name, items, value in resolver.resolve(return_value):
@@ -120,7 +120,7 @@ class VariableAssigner:
120
120
  return False
121
121
  base, attr = [token.strip() for token in name[2:-1].rsplit('.', 1)]
122
122
  try:
123
- var = variables.replace_scalar('${%s}' % base)
123
+ var = variables.replace_scalar(f'${{{base}}}')
124
124
  except VariableError:
125
125
  return False
126
126
  if not (self._variable_supports_extended_assign(var) and
@@ -128,9 +128,9 @@ class VariableAssigner:
128
128
  return False
129
129
  try:
130
130
  setattr(var, attr, value)
131
- except:
132
- raise VariableError("Setting attribute '%s' to variable '${%s}' failed: %s"
133
- % (attr, base, get_error_message()))
131
+ except Exception:
132
+ raise VariableError(f"Setting attribute '{attr}' to variable '${{{base}}}' "
133
+ f"failed: {get_error_message()}")
134
134
  return True
135
135
 
136
136
  def _variable_supports_extended_assign(self, var):
@@ -172,14 +172,12 @@ class VariableAssigner:
172
172
  *nested, item = items
173
173
  decorated_nested_items = ''.join(f'[{item}]' for item in nested)
174
174
  var = variables.replace_scalar(f'${name[1:]}{decorated_nested_items}')
175
-
176
175
  if not self._variable_type_supports_item_assign(var):
177
176
  var_type = type_name(var)
178
177
  raise VariableError(
179
178
  f"Variable '{name}{decorated_nested_items}' is {var_type} "
180
179
  f"and does not support item assignment."
181
180
  )
182
-
183
181
  selector = variables.replace_scalar(item)
184
182
  if isinstance(var, MutableSequence):
185
183
  try:
@@ -199,7 +197,10 @@ class VariableAssigner:
199
197
  return value
200
198
 
201
199
  def _normal_assign(self, name, value, variables):
202
- variables[name] = value
200
+ try:
201
+ variables[name] = value
202
+ except DataError as err:
203
+ raise VariableError(f"Setting variable '{name}' failed: {err}")
203
204
  # Always return the actually assigned value.
204
205
  return value if name[0] == '$' else variables[name]
205
206
 
@@ -239,8 +240,8 @@ class _MultiReturnValueResolver:
239
240
  def __init__(self, assignments):
240
241
  self._names = []
241
242
  self._items = []
242
- for assigment in assignments:
243
- match: VariableMatch = search_variable(assigment)
243
+ for assign in assignments:
244
+ match: VariableMatch = search_variable(assign)
244
245
  self._names.append(match.name)
245
246
  self._items.append(match.items)
246
247
  self._min_count = len(assignments)
@@ -261,10 +262,10 @@ class _MultiReturnValueResolver:
261
262
  self._raise_expected_list(return_value)
262
263
 
263
264
  def _raise_expected_list(self, ret):
264
- self._raise('Expected list-like value, got %s.' % type_name(ret))
265
+ self._raise(f'Expected list-like value, got {type_name(ret)}.')
265
266
 
266
267
  def _raise(self, error):
267
- raise VariableError('Cannot set variables: %s' % error)
268
+ raise VariableError(f'Cannot set variables: {error}')
268
269
 
269
270
  def _validate(self, return_count):
270
271
  raise NotImplementedError
@@ -277,8 +278,7 @@ class ScalarsOnlyReturnValueResolver(_MultiReturnValueResolver):
277
278
 
278
279
  def _validate(self, return_count):
279
280
  if return_count != self._min_count:
280
- self._raise('Expected %d return values, got %d.'
281
- % (self._min_count, return_count))
281
+ self._raise(f'Expected {self._min_count} return values, got {return_count}.')
282
282
 
283
283
  def _resolve(self, return_value):
284
284
  return list(zip(self._names, self._items, return_value))
@@ -287,18 +287,17 @@ class ScalarsOnlyReturnValueResolver(_MultiReturnValueResolver):
287
287
  class ScalarsAndListReturnValueResolver(_MultiReturnValueResolver):
288
288
 
289
289
  def __init__(self, assignments):
290
- _MultiReturnValueResolver.__init__(self, assignments)
290
+ super().__init__(assignments)
291
291
  self._min_count -= 1
292
292
 
293
293
  def _validate(self, return_count):
294
294
  if return_count < self._min_count:
295
- self._raise('Expected %d or more return values, got %d.'
296
- % (self._min_count, return_count))
295
+ self._raise(f'Expected {self._min_count} or more return values, '
296
+ f'got {return_count}.')
297
297
 
298
298
  def _resolve(self, return_value):
299
299
  list_index = [a[0][0] for a in self._names].index('@')
300
300
  list_len = len(return_value) - len(self._names) + 1
301
-
302
301
  elements_before_list = list(zip(
303
302
  self._names[:list_index],
304
303
  self._items[:list_index],
@@ -314,5 +313,4 @@ class ScalarsAndListReturnValueResolver(_MultiReturnValueResolver):
314
313
  self._items[list_index],
315
314
  return_value[list_index:list_index+list_len],
316
315
  )]
317
-
318
316
  return elements_before_list + list_elements + elements_after_list
@@ -14,6 +14,7 @@
14
14
  # limitations under the License.
15
15
 
16
16
  import builtins
17
+ import re
17
18
  import token
18
19
  from collections.abc import MutableMapping
19
20
  from io import StringIO
@@ -22,7 +23,7 @@ from tokenize import generate_tokens, untokenize
22
23
  from robot.errors import DataError
23
24
  from robot.utils import get_error_message, type_name
24
25
 
25
- from .search import search_variable
26
+ from .search import VariableMatches
26
27
  from .notfound import variable_not_found
27
28
 
28
29
 
@@ -44,12 +45,18 @@ def evaluate_expression(expression, variables, modules=None, namespace=None,
44
45
  return _evaluate(expression, variables.store, modules, namespace)
45
46
  except DataError as err:
46
47
  error = str(err)
47
- recommendation = ''
48
- except Exception:
48
+ variable_recommendation = ''
49
+ except Exception as err:
49
50
  error = get_error_message()
50
- recommendation = _recommend_special_variables(original)
51
- raise DataError(f"Evaluating expression '{expression}' failed: {error}\n\n"
52
- f"{recommendation}".strip())
51
+ variable_recommendation = ''
52
+ if isinstance(err, NameError) and 'RF_VAR_' in error:
53
+ name = re.search(r'RF_VAR_([\w_]*)', error).group(1)
54
+ error = (f"Robot Framework variable '${name}' is used in a scope "
55
+ f"where it cannot be seen.")
56
+ else:
57
+ variable_recommendation = _recommend_special_variables(original)
58
+ raise DataError(f'Evaluating expression {expression!r} failed: {error}\n\n'
59
+ f'{variable_recommendation}'.strip())
53
60
 
54
61
 
55
62
  def _evaluate(expression, variable_store, modules=None, namespace=None):
@@ -106,19 +113,15 @@ def _import_modules(module_names):
106
113
 
107
114
 
108
115
  def _recommend_special_variables(expression):
109
- example = []
110
- remaining = expression
111
- while True:
112
- match = search_variable(remaining)
113
- if not match:
114
- break
115
- example[-1:] = [match.before, match.identifier, match.base, match.after]
116
- remaining = example[-1]
117
- if not example:
116
+ matches = VariableMatches(expression)
117
+ if not matches:
118
118
  return ''
119
+ example = []
120
+ for match in matches:
121
+ example[-1:] += [match.before, match.identifier, match.base, match.after]
119
122
  example = ''.join(example)
120
- return (f"Variables in the original expression '{expression}' were resolved "
121
- f"before the expression was evaluated. Try using '{example}' "
123
+ return (f"Variables in the original expression {expression!r} were resolved "
124
+ f"before the expression was evaluated. Try using {example!r} "
122
125
  f"syntax to avoid that. See Evaluating Expressions appendix in "
123
126
  f"Robot Framework User Guide for more details.")
124
127
 
@@ -23,14 +23,16 @@ except ImportError:
23
23
 
24
24
  from robot.errors import DataError
25
25
  from robot.output import LOGGER
26
- from robot.utils import (get_error_message, is_dict_like, is_list_like,
27
- is_string, seq2str2, type_name, DotDict, Importer)
26
+ from robot.utils import (DotDict, get_error_message, Importer, is_dict_like,
27
+ is_list_like, type_name)
28
+
29
+ from .store import VariableStore
28
30
 
29
31
 
30
32
  class VariableFileSetter:
31
33
 
32
- def __init__(self, store):
33
- self._store = store
34
+ def __init__(self, store: VariableStore):
35
+ self.store = store
34
36
 
35
37
  def set(self, path_or_variables, args=None, overwrite=False):
36
38
  variables = self._import_if_needed(path_or_variables, args)
@@ -38,10 +40,9 @@ class VariableFileSetter:
38
40
  return variables
39
41
 
40
42
  def _import_if_needed(self, path_or_variables, args=None):
41
- if not is_string(path_or_variables):
43
+ if not isinstance(path_or_variables, str):
42
44
  return path_or_variables
43
- LOGGER.info("Importing variable file '%s' with args %s"
44
- % (path_or_variables, args))
45
+ LOGGER.info(f"Importing variable file '{path_or_variables}' with args {args}.")
45
46
  if path_or_variables.lower().endswith(('.yaml', '.yml')):
46
47
  importer = YamlImporter()
47
48
  elif path_or_variables.lower().endswith('.json'):
@@ -50,48 +51,14 @@ class VariableFileSetter:
50
51
  importer = PythonImporter()
51
52
  try:
52
53
  return importer.import_variables(path_or_variables, args)
53
- except:
54
- args = 'with arguments %s ' % seq2str2(args) if args else ''
55
- raise DataError("Processing variable file '%s' %sfailed: %s"
56
- % (path_or_variables, args, get_error_message()))
54
+ except Exception:
55
+ args = f'with arguments {args} ' if args else ''
56
+ raise DataError(f"Processing variable file '{path_or_variables}' "
57
+ f"{args}failed: {get_error_message()}")
57
58
 
58
59
  def _set(self, variables, overwrite=False):
59
60
  for name, value in variables:
60
- self._store.add(name, value, overwrite)
61
-
62
-
63
- class YamlImporter:
64
-
65
- def import_variables(self, path, args=None):
66
- if args:
67
- raise DataError('YAML variable files do not accept arguments.')
68
- variables = self._import(path)
69
- return [('${%s}' % name, self._dot_dict(value))
70
- for name, value in variables]
71
-
72
- def _import(self, path):
73
- with io.open(path, encoding='UTF-8') as stream:
74
- variables = self._load_yaml(stream)
75
- if not is_dict_like(variables):
76
- raise DataError('YAML variable file must be a mapping, got %s.'
77
- % type_name(variables))
78
- return variables.items()
79
-
80
- def _load_yaml(self, stream):
81
- if not yaml:
82
- raise DataError('Using YAML variable files requires PyYAML module '
83
- 'to be installed. Typically you can install it '
84
- 'by running `pip install pyyaml`.')
85
- if yaml.__version__.split('.')[0] == '3':
86
- return yaml.load(stream)
87
- return yaml.full_load(stream)
88
-
89
- def _dot_dict(self, value):
90
- if is_dict_like(value):
91
- return DotDict((k, self._dot_dict(v)) for k, v in value.items())
92
- if is_list_like(value):
93
- return [self._dot_dict(v) for v in value]
94
- return value
61
+ self.store.add(name, value, overwrite, decorated=False)
95
62
 
96
63
 
97
64
  class PythonImporter:
@@ -102,24 +69,29 @@ class PythonImporter:
102
69
  return self._get_variables(var_file, args)
103
70
 
104
71
  def _get_variables(self, var_file, args):
105
- if self._is_dynamic(var_file):
106
- variables = self._get_dynamic(var_file, args)
107
- else:
72
+ get_variables = (getattr(var_file, 'get_variables', None) or
73
+ getattr(var_file, 'getVariables', None))
74
+ if get_variables:
75
+ variables = self._get_dynamic(get_variables, args)
76
+ elif not args:
108
77
  variables = self._get_static(var_file)
78
+ else:
79
+ raise DataError('Static variable files do not accept arguments.')
109
80
  return list(self._decorate_and_validate(variables))
110
81
 
111
- def _is_dynamic(self, var_file):
112
- return (hasattr(var_file, 'get_variables') or
113
- hasattr(var_file, 'getVariables'))
114
-
115
- def _get_dynamic(self, var_file, args):
116
- get_variables = (getattr(var_file, 'get_variables', None) or
117
- getattr(var_file, 'getVariables'))
118
- variables = get_variables(*args)
82
+ def _get_dynamic(self, get_variables, args):
83
+ positional, named = self._resolve_arguments(get_variables, args)
84
+ variables = get_variables(*positional, **dict(named))
119
85
  if is_dict_like(variables):
120
86
  return variables.items()
121
- raise DataError("Expected '%s' to return dict-like value, got %s."
122
- % (get_variables.__name__, type_name(variables)))
87
+ raise DataError(f"Expected '{get_variables.__name__}' to return "
88
+ f"a dictionary-like value, got {type_name(variables)}.")
89
+
90
+ def _resolve_arguments(self, get_variables, args):
91
+ # Avoid cyclic import. Yuck.
92
+ from robot.running.arguments import PythonArgumentParser
93
+ spec = PythonArgumentParser('variable file').parse(get_variables)
94
+ return spec.resolve(args)
123
95
 
124
96
  def _get_static(self, var_file):
125
97
  names = [attr for attr in dir(var_file) if not attr.startswith('_')]
@@ -132,40 +104,35 @@ class PythonImporter:
132
104
 
133
105
  def _decorate_and_validate(self, variables):
134
106
  for name, value in variables:
135
- name = self._decorate(name)
136
- self._validate(name, value)
107
+ if name.startswith('LIST__'):
108
+ if not is_list_like(value):
109
+ raise DataError(f"Invalid variable '{name}': Expected a "
110
+ f"list-like value, got {type_name(value)}.")
111
+ name = name[6:]
112
+ value = list(value)
113
+ elif name.startswith('DICT__'):
114
+ if not is_dict_like(value):
115
+ raise DataError(f"Invalid variable '{name}': Expected a "
116
+ f"dictionary-like value, got {type_name(value)}.")
117
+ name = name[6:]
118
+ value = DotDict(value)
137
119
  yield name, value
138
120
 
139
- def _decorate(self, name):
140
- if name.startswith('LIST__'):
141
- return '@{%s}' % name[6:]
142
- if name.startswith('DICT__'):
143
- return '&{%s}' % name[6:]
144
- return '${%s}' % name
145
-
146
- def _validate(self, name, value):
147
- if name[0] == '@' and not is_list_like(value):
148
- raise DataError("Invalid variable '%s': Expected list-like value, "
149
- "got %s." % (name, type_name(value)))
150
- if name[0] == '&' and not is_dict_like(value):
151
- raise DataError("Invalid variable '%s': Expected dict-like value, "
152
- "got %s." % (name, type_name(value)))
153
-
154
121
 
155
122
  class JsonImporter:
123
+
156
124
  def import_variables(self, path, args=None):
157
125
  if args:
158
126
  raise DataError('JSON variable files do not accept arguments.')
159
127
  variables = self._import(path)
160
- return [('${%s}' % name, self._dot_dict(value))
161
- for name, value in variables]
128
+ return [(name, self._dot_dict(value)) for name, value in variables]
162
129
 
163
130
  def _import(self, path):
164
131
  with io.open(path, encoding='UTF-8') as stream:
165
132
  variables = json.load(stream)
166
133
  if not is_dict_like(variables):
167
- raise DataError('JSON variable file must be a mapping, got %s.'
168
- % type_name(variables))
134
+ raise DataError(f'JSON variable file must be a mapping, '
135
+ f'got {type_name(variables)}.')
169
136
  return variables.items()
170
137
 
171
138
  def _dot_dict(self, value):
@@ -174,3 +141,36 @@ class JsonImporter:
174
141
  if is_list_like(value):
175
142
  return [self._dot_dict(v) for v in value]
176
143
  return value
144
+
145
+
146
+ class YamlImporter:
147
+
148
+ def import_variables(self, path, args=None):
149
+ if args:
150
+ raise DataError('YAML variable files do not accept arguments.')
151
+ variables = self._import(path)
152
+ return [(name, self._dot_dict(value)) for name, value in variables]
153
+
154
+ def _import(self, path):
155
+ with io.open(path, encoding='UTF-8') as stream:
156
+ variables = self._load_yaml(stream)
157
+ if not is_dict_like(variables):
158
+ raise DataError(f'YAML variable file must be a mapping, '
159
+ f'got {type_name(variables)}.')
160
+ return variables.items()
161
+
162
+ def _load_yaml(self, stream):
163
+ if not yaml:
164
+ raise DataError('Using YAML variable files requires PyYAML module '
165
+ 'to be installed. Typically you can install it '
166
+ 'by running `pip install pyyaml`.')
167
+ if yaml.__version__.split('.')[0] == '3':
168
+ return yaml.load(stream)
169
+ return yaml.full_load(stream)
170
+
171
+ def _dot_dict(self, value):
172
+ if is_dict_like(value):
173
+ return DotDict((k, self._dot_dict(v)) for k, v in value.items())
174
+ if is_list_like(value):
175
+ return [self._dot_dict(v) for v in value]
176
+ return value
@@ -42,33 +42,32 @@ class VariableReplacer:
42
42
  items = list(items or [])
43
43
  if replace_until is not None:
44
44
  return self._replace_list_until(items, replace_until, ignore_errors)
45
- return list(self._replace_list(items, ignore_errors))
45
+ return self._replace_list(items, ignore_errors)
46
46
 
47
- def _replace_list_until(self, items, replace_until, ignore_errors):
47
+ def _replace_list_until(self, items, limit, ignore_errors):
48
48
  # @{list} variables can contain more or less arguments than needed.
49
49
  # Therefore, we need to go through items one by one, and escape
50
50
  # possible extra items we got.
51
51
  replaced = []
52
- while len(replaced) < replace_until and items:
52
+ while len(replaced) < limit and items:
53
53
  replaced.extend(self._replace_list([items.pop(0)], ignore_errors))
54
- if len(replaced) > replace_until:
55
- replaced[replace_until:] = [escape(item)
56
- for item in replaced[replace_until:]]
54
+ if len(replaced) > limit:
55
+ replaced[limit:] = [escape(item) for item in replaced[limit:]]
57
56
  return replaced + items
58
57
 
59
58
  def _replace_list(self, items, ignore_errors):
59
+ result = []
60
60
  for item in items:
61
- for value in self._replace_list_item(item, ignore_errors):
62
- yield value
63
-
64
- def _replace_list_item(self, item, ignore_errors):
65
- match = search_variable(item, ignore_errors=ignore_errors)
66
- if not match:
67
- return [unescape(match.string)]
68
- value = self.replace_scalar(match, ignore_errors)
69
- if match.is_list_variable() and is_list_like(value):
70
- return value
71
- return [value]
61
+ match = search_variable(item, ignore_errors=ignore_errors)
62
+ if not match:
63
+ result.append(unescape(item))
64
+ else:
65
+ value = self._replace_scalar(match, ignore_errors)
66
+ if match.is_list_variable() and is_list_like(value):
67
+ result.extend(value)
68
+ else:
69
+ result.append(value)
70
+ return result
72
71
 
73
72
  def replace_scalar(self, item, ignore_errors=False):
74
73
  """Replaces variables from a scalar item.
@@ -77,20 +76,18 @@ class VariableReplacer:
77
76
  its value is returned. Otherwise, possible variables are replaced with
78
77
  'replace_string'. Result may be any object.
79
78
  """
80
- match = self._search_variable(item, ignore_errors=ignore_errors)
79
+ if isinstance(item, VariableMatch):
80
+ match = item
81
+ else:
82
+ match = search_variable(item, ignore_errors=ignore_errors)
81
83
  if not match:
82
84
  return unescape(match.string)
83
85
  return self._replace_scalar(match, ignore_errors)
84
86
 
85
- def _search_variable(self, item, ignore_errors):
86
- if isinstance(item, VariableMatch):
87
- return item
88
- return search_variable(item, ignore_errors=ignore_errors)
89
-
90
87
  def _replace_scalar(self, match, ignore_errors=False):
91
- if not match.is_variable():
92
- return self.replace_string(match, ignore_errors=ignore_errors)
93
- return self._get_variable_value(match, ignore_errors)
88
+ if match.is_variable():
89
+ return self._get_variable_value(match, ignore_errors)
90
+ return self._replace_string(match, unescape, ignore_errors)
94
91
 
95
92
  def replace_string(self, item, custom_unescaper=None, ignore_errors=False):
96
93
  """Replaces variables from a string. Result is always a string.
@@ -98,7 +95,10 @@ class VariableReplacer:
98
95
  Input can also be an already found VariableMatch.
99
96
  """
100
97
  unescaper = custom_unescaper or unescape
101
- match = self._search_variable(item, ignore_errors=ignore_errors)
98
+ if isinstance(item, VariableMatch):
99
+ match = item
100
+ else:
101
+ match = search_variable(item, ignore_errors=ignore_errors)
102
102
  if not match:
103
103
  return safe_str(unescaper(match.string))
104
104
  return self._replace_string(match, unescaper, ignore_errors)
@@ -106,10 +106,8 @@ class VariableReplacer:
106
106
  def _replace_string(self, match, unescaper, ignore_errors):
107
107
  parts = []
108
108
  while match:
109
- parts.extend([
110
- unescaper(match.before),
111
- safe_str(self._get_variable_value(match, ignore_errors))
112
- ])
109
+ parts.append(unescaper(match.before))
110
+ parts.append(safe_str(self._get_variable_value(match, ignore_errors)))
113
111
  match = search_variable(match.after, ignore_errors=ignore_errors)
114
112
  parts.append(unescaper(match.string))
115
113
  return ''.join(parts)
@@ -126,17 +124,16 @@ class VariableReplacer:
126
124
  if match.items:
127
125
  value = self._get_variable_item(match, value)
128
126
  try:
129
- value = self._validate_value(match, value)
127
+ return self._validate_value(match, value)
130
128
  except VariableError:
131
129
  raise
132
130
  except Exception:
133
131
  error = get_error_message()
134
132
  raise VariableError(f"Resolving variable '{match}' failed: {error}")
135
133
  except DataError:
136
- if not ignore_errors:
137
- raise
138
- value = unescape(match.match)
139
- return value
134
+ if ignore_errors:
135
+ return unescape(match.match)
136
+ raise
140
137
 
141
138
  def _get_variable_item(self, match, value):
142
139
  name = match.name
@@ -113,9 +113,9 @@ class VariableScopes:
113
113
  else:
114
114
  scope.set_from_file(variables, overwrite=overwrite)
115
115
 
116
- def set_from_variable_table(self, variables, overwrite=False):
116
+ def set_from_variable_section(self, variables, overwrite=False):
117
117
  for scope in self._scopes_until_suite:
118
- scope.set_from_variable_table(variables, overwrite)
118
+ scope.set_from_variable_section(variables, overwrite)
119
119
 
120
120
  def resolve_delayed(self):
121
121
  for scope in self._scopes_until_suite:
@@ -140,8 +140,7 @@ class VariableScopes:
140
140
  return
141
141
  for scope in self._scopes_until_suite:
142
142
  name, value = self._set_global_suite_or_test(scope, name, value)
143
- if children:
144
- self._variables_set.set_suite(name, value)
143
+ self._variables_set.set_suite(name, value, children)
145
144
 
146
145
  def set_test(self, name, value):
147
146
  if self._test is None:
@@ -154,7 +153,7 @@ class VariableScopes:
154
153
  self.current[name] = value
155
154
  self._variables_set.set_keyword(name, value)
156
155
 
157
- def set_local_variable(self, name, value):
156
+ def set_local(self, name, value):
158
157
  self.current[name] = value
159
158
 
160
159
  def as_dict(self, decoration=True):
@@ -203,11 +202,11 @@ class GlobalVariables(Variables):
203
202
  ('${False}', False),
204
203
  ('${None}', None),
205
204
  ('${null}', None),
206
- ('${OUTPUT_DIR}', settings.output_directory),
207
- ('${OUTPUT_FILE}', settings.output or 'NONE'),
208
- ('${REPORT_FILE}', settings.report or 'NONE'),
209
- ('${LOG_FILE}', settings.log or 'NONE'),
210
- ('${DEBUG_FILE}', settings.debug_file or 'NONE'),
205
+ ('${OUTPUT_DIR}', str(settings.output_directory)),
206
+ ('${OUTPUT_FILE}', str(settings.output or 'NONE')),
207
+ ('${REPORT_FILE}', str(settings.report or 'NONE')),
208
+ ('${LOG_FILE}', str(settings.log or 'NONE')),
209
+ ('${DEBUG_FILE}', str(settings.debug_file or 'NONE')),
211
210
  ('${LOG_LEVEL}', settings.log_level),
212
211
  ('${PREV_TEST_NAME}', ''),
213
212
  ('${PREV_TEST_STATUS}', ''),
@@ -252,8 +251,14 @@ class SetVariables:
252
251
  if name in scope:
253
252
  scope.pop(name)
254
253
 
255
- def set_suite(self, name, value):
256
- self._suite[name] = value
254
+ def set_suite(self, name, value, children=False):
255
+ for scope in reversed(self._scopes):
256
+ if children:
257
+ scope[name] = value
258
+ elif name in scope:
259
+ scope.pop(name)
260
+ if scope is self._suite:
261
+ break
257
262
 
258
263
  def set_test(self, name, value):
259
264
  for scope in reversed(self._scopes):