robotframework 6.1rc1__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.1rc1 → robotframework-7.0}/INSTALL.rst +25 -25
  2. {robotframework-6.1rc1 → robotframework-7.0}/PKG-INFO +6 -8
  3. {robotframework-6.1rc1 → robotframework-7.0}/README.rst +3 -2
  4. {robotframework-6.1rc1 → robotframework-7.0}/setup.py +3 -6
  5. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/api/__init__.py +4 -1
  6. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/api/deco.py +60 -14
  7. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/api/exceptions.py +6 -6
  8. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/api/interfaces.py +403 -68
  9. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/api/logger.py +27 -20
  10. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/api/parsing.py +4 -2
  11. robotframework-7.0/src/robot/api/py.typed +0 -0
  12. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/conf/gatherfailed.py +2 -2
  13. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/conf/languages.py +61 -25
  14. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/conf/settings.py +21 -14
  15. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/common/storage.js +11 -6
  16. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/htmlfilewriter.py +1 -1
  17. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/libdoc/libdoc.css +10 -2
  18. {robotframework-6.1rc1 → 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.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/doc_formatting.css +13 -7
  21. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/log.css +51 -10
  22. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/log.html +14 -23
  23. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/model.js +2 -4
  24. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/report.css +83 -19
  25. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/report.html +22 -7
  26. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/testdata.js +10 -3
  27. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/view.js +84 -0
  28. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/template.py +3 -3
  29. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/builder.py +0 -8
  30. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/datatypes.py +9 -10
  31. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/htmlutils.py +4 -7
  32. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/jsonbuilder.py +38 -20
  33. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/model.py +21 -28
  34. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/robotbuilder.py +50 -31
  35. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/standardtypes.py +9 -1
  36. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/xmlbuilder.py +35 -20
  37. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/xmlwriter.py +18 -38
  38. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/BuiltIn.py +255 -205
  39. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/Collections.py +384 -240
  40. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/DateTime.py +73 -60
  41. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/OperatingSystem.py +6 -5
  42. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/Process.py +26 -27
  43. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/Remote.py +40 -36
  44. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/String.py +66 -76
  45. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/XML.py +66 -59
  46. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/__init__.py +2 -2
  47. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/dialogs_py.py +14 -2
  48. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/__init__.py +5 -5
  49. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/body.py +44 -13
  50. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/configurer.py +19 -15
  51. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/control.py +230 -88
  52. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/filter.py +31 -25
  53. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/itemlist.py +9 -8
  54. robotframework-7.0/src/robot/model/keyword.py +77 -0
  55. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/message.py +19 -10
  56. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/modelobject.py +27 -15
  57. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/modifier.py +1 -1
  58. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/namepatterns.py +3 -25
  59. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/stats.py +9 -15
  60. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/tags.py +1 -1
  61. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/testcase.py +15 -27
  62. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/testsuite.py +44 -28
  63. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/visitor.py +35 -8
  64. robotframework-7.0/src/robot/output/console/dotted.py +90 -0
  65. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/output/console/quiet.py +3 -2
  66. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/output/console/verbose.py +61 -61
  67. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/output/debugfile.py +39 -24
  68. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/output/filelogger.py +18 -15
  69. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/output/librarylogger.py +3 -2
  70. robotframework-7.0/src/robot/output/listeners.py +753 -0
  71. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/output/logger.py +216 -80
  72. robotframework-7.0/src/robot/output/loggerapi.py +215 -0
  73. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/output/loggerhelper.py +23 -56
  74. robotframework-7.0/src/robot/output/output.py +185 -0
  75. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/output/stdoutlogsplitter.py +8 -5
  76. robotframework-7.0/src/robot/output/xmllogger.py +459 -0
  77. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/lexer/blocklexers.py +17 -13
  78. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/lexer/context.py +12 -2
  79. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/lexer/lexer.py +1 -1
  80. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/lexer/settings.py +6 -3
  81. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/lexer/statementlexers.py +39 -10
  82. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/lexer/tokens.py +27 -29
  83. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/model/blocks.py +19 -6
  84. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/model/statements.py +193 -94
  85. robotframework-7.0/src/robot/parsing/model/visitor.py +100 -0
  86. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/rebot.py +2 -0
  87. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/reporting/expandkeywordmatcher.py +1 -1
  88. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/reporting/jsbuildingcontext.py +8 -6
  89. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/reporting/jsmodelbuilders.py +88 -61
  90. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/reporting/logreportwriters.py +16 -10
  91. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/reporting/outputwriter.py +18 -2
  92. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/reporting/resultwriter.py +4 -4
  93. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/reporting/stringcache.py +3 -3
  94. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/reporting/xunitwriter.py +15 -21
  95. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/result/__init__.py +3 -2
  96. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/result/configurer.py +12 -9
  97. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/result/executionresult.py +56 -8
  98. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/result/flattenkeywordmatcher.py +48 -9
  99. robotframework-7.0/src/robot/result/keywordremover.py +207 -0
  100. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/result/merger.py +1 -1
  101. robotframework-7.0/src/robot/result/model.py +1185 -0
  102. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/result/modeldeprecation.py +9 -3
  103. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/result/resultbuilder.py +46 -36
  104. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/result/xmlelementhandlers.py +83 -43
  105. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/run.py +3 -1
  106. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/__init__.py +14 -4
  107. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/arguments/__init__.py +2 -1
  108. robotframework-7.0/src/robot/running/arguments/argumentconverter.py +100 -0
  109. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/arguments/argumentmapper.py +26 -24
  110. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/arguments/argumentparser.py +85 -61
  111. robotframework-7.0/src/robot/running/arguments/argumentresolver.py +158 -0
  112. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/arguments/argumentspec.py +83 -116
  113. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/arguments/argumentvalidator.py +33 -27
  114. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/arguments/customconverters.py +15 -12
  115. robotframework-7.0/src/robot/running/arguments/embedded.py +145 -0
  116. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/arguments/typeconverters.py +268 -220
  117. robotframework-7.0/src/robot/running/arguments/typeinfo.py +317 -0
  118. robotframework-7.0/src/robot/running/arguments/typeinfoparser.py +219 -0
  119. robotframework-7.0/src/robot/running/arguments/typevalidator.py +60 -0
  120. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/bodyrunner.py +147 -129
  121. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/builder/builders.py +17 -26
  122. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/builder/parsers.py +17 -11
  123. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/builder/settings.py +9 -17
  124. robotframework-7.0/src/robot/running/builder/transformers.py +535 -0
  125. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/context.py +113 -31
  126. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/dynamicmethods.py +62 -34
  127. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/importer.py +27 -49
  128. robotframework-7.0/src/robot/running/invalidkeyword.py +67 -0
  129. robotframework-7.0/src/robot/running/keywordfinder.py +91 -0
  130. robotframework-7.0/src/robot/running/keywordimplementation.py +164 -0
  131. robotframework-7.0/src/robot/running/librarykeyword.py +392 -0
  132. robotframework-7.0/src/robot/running/librarykeywordrunner.py +250 -0
  133. robotframework-7.0/src/robot/running/libraryscopes.py +115 -0
  134. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/model.py +198 -337
  135. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/namespace.py +124 -137
  136. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/outputcapture.py +20 -12
  137. robotframework-7.0/src/robot/running/resourcemodel.py +448 -0
  138. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/statusreporter.py +16 -13
  139. robotframework-7.0/src/robot/running/suiterunner.py +265 -0
  140. robotframework-7.0/src/robot/running/testlibraries.py +500 -0
  141. robotframework-7.0/src/robot/running/userkeywordrunner.py +260 -0
  142. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/testdoc.py +18 -13
  143. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/__init__.py +53 -35
  144. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/connectioncache.py +64 -59
  145. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/dotdict.py +3 -0
  146. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/encodingsniffer.py +9 -4
  147. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/escaping.py +19 -19
  148. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/importer.py +2 -2
  149. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/markupwriters.py +23 -15
  150. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/misc.py +1 -2
  151. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/normalizing.py +9 -24
  152. robotframework-7.0/src/robot/utils/notset.py +33 -0
  153. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/platform.py +15 -5
  154. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/robotio.py +9 -9
  155. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/robotpath.py +1 -0
  156. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/robottime.py +122 -90
  157. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/robottypes.py +21 -31
  158. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/setter.py +0 -5
  159. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/text.py +7 -4
  160. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/unic.py +2 -2
  161. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/variables/__init__.py +2 -2
  162. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/variables/assigner.py +17 -19
  163. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/variables/evaluation.py +20 -17
  164. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/variables/filesetter.py +80 -80
  165. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/variables/replacer.py +33 -36
  166. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/variables/scopes.py +17 -12
  167. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/variables/search.py +66 -41
  168. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/variables/store.py +14 -16
  169. robotframework-7.0/src/robot/variables/tablesetter.py +164 -0
  170. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/variables/variables.py +1 -1
  171. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/version.py +1 -1
  172. {robotframework-6.1rc1 → robotframework-7.0}/src/robotframework.egg-info/PKG-INFO +6 -8
  173. {robotframework-6.1rc1 → robotframework-7.0}/src/robotframework.egg-info/SOURCES.txt +10 -8
  174. {robotframework-6.1rc1 → robotframework-7.0}/tasks.py +6 -6
  175. robotframework-6.1rc1/src/robot/htmldata/rebot/common.css +0 -239
  176. robotframework-6.1rc1/src/robot/libraries/Reserved.py +0 -48
  177. robotframework-6.1rc1/src/robot/model/keyword.py +0 -173
  178. robotframework-6.1rc1/src/robot/output/console/dotted.py +0 -90
  179. robotframework-6.1rc1/src/robot/output/listenerarguments.py +0 -165
  180. robotframework-6.1rc1/src/robot/output/listenermethods.py +0 -113
  181. robotframework-6.1rc1/src/robot/output/listeners.py +0 -174
  182. robotframework-6.1rc1/src/robot/output/output.py +0 -95
  183. robotframework-6.1rc1/src/robot/output/xmllogger.py +0 -354
  184. robotframework-6.1rc1/src/robot/parsing/model/visitor.py +0 -67
  185. robotframework-6.1rc1/src/robot/result/keywordremover.py +0 -183
  186. robotframework-6.1rc1/src/robot/result/model.py +0 -957
  187. robotframework-6.1rc1/src/robot/running/arguments/argumentconverter.py +0 -79
  188. robotframework-6.1rc1/src/robot/running/arguments/argumentresolver.py +0 -131
  189. robotframework-6.1rc1/src/robot/running/arguments/embedded.py +0 -146
  190. robotframework-6.1rc1/src/robot/running/arguments/typevalidator.py +0 -56
  191. robotframework-6.1rc1/src/robot/running/builder/transformers.py +0 -642
  192. robotframework-6.1rc1/src/robot/running/handlers.py +0 -321
  193. robotframework-6.1rc1/src/robot/running/handlerstore.py +0 -66
  194. robotframework-6.1rc1/src/robot/running/librarykeywordrunner.py +0 -238
  195. robotframework-6.1rc1/src/robot/running/libraryscopes.py +0 -97
  196. robotframework-6.1rc1/src/robot/running/modelcombiner.py +0 -32
  197. robotframework-6.1rc1/src/robot/running/suiterunner.py +0 -249
  198. robotframework-6.1rc1/src/robot/running/testlibraries.py +0 -420
  199. robotframework-6.1rc1/src/robot/running/usererrorhandler.py +0 -75
  200. robotframework-6.1rc1/src/robot/running/userkeyword.py +0 -111
  201. robotframework-6.1rc1/src/robot/running/userkeywordrunner.py +0 -274
  202. robotframework-6.1rc1/src/robot/variables/tablesetter.py +0 -156
  203. {robotframework-6.1rc1 → robotframework-7.0}/AUTHORS.rst +0 -0
  204. {robotframework-6.1rc1 → robotframework-7.0}/BUILD.rst +0 -0
  205. {robotframework-6.1rc1 → robotframework-7.0}/CONTRIBUTING.rst +0 -0
  206. {robotframework-6.1rc1 → robotframework-7.0}/COPYRIGHT.txt +0 -0
  207. {robotframework-6.1rc1 → robotframework-7.0}/LICENSE.txt +0 -0
  208. {robotframework-6.1rc1 → robotframework-7.0}/MANIFEST.in +0 -0
  209. {robotframework-6.1rc1 → robotframework-7.0}/setup.cfg +0 -0
  210. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/__init__.py +0 -0
  211. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/__main__.py +0 -0
  212. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/conf/__init__.py +0 -0
  213. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/errors.py +0 -0
  214. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/__init__.py +0 -0
  215. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/common/__init__.py +0 -0
  216. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/common/js_disabled.css +0 -0
  217. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/jsonwriter.py +0 -0
  218. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/lib/__init__.py +0 -0
  219. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/lib/jquery.highlight.min.js +0 -0
  220. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/lib/jquery.min.js +0 -0
  221. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/lib/jquery.tablesorter.min.js +0 -0
  222. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/lib/jquery.tmpl.min.js +0 -0
  223. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/lib/jsxcompressor.min.js +0 -0
  224. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/libdoc/__init__.py +0 -0
  225. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/libdoc/doc_formatting.css +0 -0
  226. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/libdoc/print.css +0 -0
  227. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/libdoc/pygments.css +0 -0
  228. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/__init__.py +0 -0
  229. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/fileloading.js +0 -0
  230. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/log.js +0 -0
  231. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/print.css +0 -0
  232. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/util.js +0 -0
  233. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/testdoc/__init__.py +0 -0
  234. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/testdoc/testdoc.css +0 -0
  235. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/testdoc/testdoc.html +0 -0
  236. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdoc.py +0 -0
  237. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/__init__.py +0 -0
  238. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/consoleviewer.py +0 -0
  239. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/htmlwriter.py +0 -0
  240. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/jsonwriter.py +0 -0
  241. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/output.py +0 -0
  242. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/writer.py +0 -0
  243. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/Dialogs.py +0 -0
  244. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/Easter.py +0 -0
  245. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/Screenshot.py +0 -0
  246. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/Telnet.py +0 -0
  247. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/fixture.py +0 -0
  248. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/metadata.py +0 -0
  249. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/statistics.py +0 -0
  250. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/suitestatistics.py +0 -0
  251. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/tagsetter.py +0 -0
  252. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/tagstatistics.py +0 -0
  253. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/totalstatistics.py +0 -0
  254. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/output/__init__.py +0 -0
  255. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/output/console/__init__.py +0 -0
  256. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/output/console/highlighting.py +0 -0
  257. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/output/pyloggingconf.py +0 -0
  258. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/__init__.py +0 -0
  259. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/lexer/__init__.py +0 -0
  260. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/lexer/tokenizer.py +0 -0
  261. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/model/__init__.py +0 -0
  262. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/parser/__init__.py +0 -0
  263. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/parser/blockparsers.py +0 -0
  264. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/parser/fileparser.py +0 -0
  265. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/parser/parser.py +0 -0
  266. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/suitestructure.py +0 -0
  267. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/pythonpathsetter.py +0 -0
  268. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/reporting/__init__.py +0 -0
  269. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/reporting/jsexecutionresult.py +0 -0
  270. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/reporting/jswriter.py +0 -0
  271. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/result/executionerrors.py +0 -0
  272. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/result/messagefilter.py +0 -0
  273. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/result/suiteteardownfailed.py +0 -0
  274. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/result/visitor.py +0 -0
  275. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/builder/__init__.py +0 -0
  276. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/randomizer.py +0 -0
  277. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/runkwregister.py +0 -0
  278. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/signalhandler.py +0 -0
  279. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/status.py +0 -0
  280. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/timeouts/__init__.py +0 -0
  281. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/timeouts/posix.py +0 -0
  282. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/timeouts/windows.py +0 -0
  283. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/application.py +0 -0
  284. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/argumentparser.py +0 -0
  285. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/asserts.py +0 -0
  286. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/charwidth.py +0 -0
  287. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/compress.py +0 -0
  288. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/encoding.py +0 -0
  289. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/error.py +0 -0
  290. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/etreewrapper.py +0 -0
  291. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/filereader.py +0 -0
  292. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/frange.py +0 -0
  293. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/htmlformatters.py +0 -0
  294. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/markuputils.py +0 -0
  295. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/match.py +0 -0
  296. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/recommendations.py +0 -0
  297. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/restreader.py +0 -0
  298. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/robotenv.py +0 -0
  299. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/robotinspect.py +0 -0
  300. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/sortable.py +0 -0
  301. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/typehints.py +0 -0
  302. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/variables/finders.py +0 -0
  303. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/variables/notfound.py +0 -0
  304. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/variables/resolvable.py +0 -0
  305. {robotframework-6.1rc1 → robotframework-7.0}/src/robotframework.egg-info/dependency_links.txt +0 -0
  306. {robotframework-6.1rc1 → robotframework-7.0}/src/robotframework.egg-info/entry_points.txt +0 -0
  307. {robotframework-6.1rc1 → robotframework-7.0}/src/robotframework.egg-info/top_level.txt +0 -0
@@ -13,12 +13,11 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
 
16
- import sys
17
16
  import inspect
18
17
  import asyncio
19
18
  from contextlib import contextmanager
20
19
 
21
- from robot.errors import DataError
20
+ from robot.errors import DataError, ExecutionFailed
22
21
 
23
22
 
24
23
  class Asynchronous:
@@ -37,15 +36,20 @@ class Asynchronous:
37
36
  self._loop_ref.close()
38
37
 
39
38
  def run_until_complete(self, coroutine):
40
- return self.event_loop.run_until_complete(coroutine)
39
+ task = self.event_loop.create_task(coroutine)
40
+ try:
41
+ return self.event_loop.run_until_complete(task)
42
+ except ExecutionFailed as e:
43
+ if e.dont_continue:
44
+ task.cancel()
45
+ # wait for task and its children to cancel
46
+ self.event_loop.run_until_complete(asyncio.gather(task, return_exceptions=True))
47
+ raise e
41
48
 
42
49
  def is_loop_required(self, obj):
43
50
  return inspect.iscoroutine(obj) and not self._is_loop_running()
44
51
 
45
52
  def _is_loop_running(self):
46
- # ensure 3.6 compatibility
47
- if sys.version_info.minor == 6:
48
- return asyncio._get_running_loop() is not None
49
53
  try:
50
54
  asyncio.get_running_loop()
51
55
  except RuntimeError:
@@ -108,6 +112,10 @@ class _ExecutionContext:
108
112
  self.user_keywords = []
109
113
  self.asynchronous = asynchronous
110
114
 
115
+ @property
116
+ def languages(self):
117
+ return self.namespace.languages
118
+
111
119
  @contextmanager
112
120
  def suite_teardown(self):
113
121
  self.in_suite_teardown = True
@@ -150,7 +158,7 @@ class _ExecutionContext:
150
158
  def warn_on_invalid_private_call(self, handler):
151
159
  parent = self.user_keywords[-1] if self.user_keywords else None
152
160
  if not parent or parent.source != handler.source:
153
- self.warn(f"Keyword '{handler.longname}' is private and should only "
161
+ self.warn(f"Keyword '{handler.full_name}' is private and should only "
154
162
  f"be called by keywords in the same file.")
155
163
 
156
164
  @contextmanager
@@ -174,34 +182,37 @@ class _ExecutionContext:
174
182
  def continue_on_failure(self, default=False):
175
183
  parents = ([self.test] if self.test else []) + self.user_keywords
176
184
  for index, parent in enumerate(reversed(parents)):
177
- if (parent.tags.robot('recursive-stop-on-failure')
178
- or index == 0 and parent.tags.robot('stop-on-failure')):
185
+ robot = parent.tags.robot
186
+ if index == 0 and robot('stop-on-failure'):
187
+ return False
188
+ if index == 0 and robot('continue-on-failure'):
189
+ return True
190
+ if robot('recursive-stop-on-failure'):
179
191
  return False
180
- if (parent.tags.robot('recursive-continue-on-failure')
181
- or index == 0 and parent.tags.robot('continue-on-failure')):
192
+ if robot('recursive-continue-on-failure'):
182
193
  return True
183
194
  return default or self.in_teardown
184
195
 
185
196
  @property
186
197
  def allow_loop_control(self):
187
- for step in reversed(self.steps):
198
+ for _, step in reversed(self.steps):
188
199
  if step.type == 'ITERATION':
189
200
  return True
190
- if step.type == 'KEYWORD' and step.libname != 'BuiltIn':
201
+ if step.type == 'KEYWORD' and step.owner != 'BuiltIn':
191
202
  return False
192
203
  return False
193
204
 
194
- def end_suite(self, suite):
205
+ def end_suite(self, data, result):
195
206
  for name in ['${PREV_TEST_NAME}',
196
207
  '${PREV_TEST_STATUS}',
197
208
  '${PREV_TEST_MESSAGE}']:
198
209
  self.variables.set_global(name, self.variables[name])
199
- self.output.end_suite(suite)
200
- self.namespace.end_suite(suite)
210
+ self.output.end_suite(data, result)
211
+ self.namespace.end_suite(data)
201
212
  EXECUTION_CONTEXTS.end_suite()
202
213
 
203
214
  def set_suite_variables(self, suite):
204
- self.variables['${SUITE_NAME}'] = suite.longname
215
+ self.variables['${SUITE_NAME}'] = suite.full_name
205
216
  self.variables['${SUITE_SOURCE}'] = str(suite.source or '')
206
217
  self.variables['${SUITE_DOCUMENTATION}'] = suite.doc
207
218
  self.variables['${SUITE_METADATA}'] = suite.metadata.copy()
@@ -210,13 +221,14 @@ class _ExecutionContext:
210
221
  self.variables['${SUITE_STATUS}'] = status
211
222
  self.variables['${SUITE_MESSAGE}'] = message
212
223
 
213
- def start_test(self, test):
214
- self.test = test
215
- self._add_timeout(test.timeout)
224
+ def start_test(self, data, result):
225
+ self.test = result
226
+ self._add_timeout(result.timeout)
216
227
  self.namespace.start_test()
217
- self.variables.set_test('${TEST_NAME}', test.name)
218
- self.variables.set_test('${TEST_DOCUMENTATION}', test.doc)
219
- self.variables.set_test('@{TEST_TAGS}', list(test.tags))
228
+ self.variables.set_test('${TEST_NAME}', result.name)
229
+ self.variables.set_test('${TEST_DOCUMENTATION}', result.doc)
230
+ self.variables.set_test('@{TEST_TAGS}', list(result.tags))
231
+ self.output.start_test(data, result)
220
232
 
221
233
  def _add_timeout(self, timeout):
222
234
  if timeout:
@@ -236,19 +248,89 @@ class _ExecutionContext:
236
248
  self.variables.set_suite('${PREV_TEST_MESSAGE}', test.message)
237
249
  self.timeout_occurred = False
238
250
 
239
- def start_keyword(self, keyword):
240
- self.steps.append(keyword)
251
+ def start_body_item(self, data, result, implementation=None):
252
+ self.steps.append((data, result))
241
253
  if len(self.steps) > self._started_keywords_threshold:
242
254
  raise DataError('Maximum limit of started keywords and control '
243
255
  'structures exceeded.')
244
- self.output.start_keyword(keyword)
245
-
246
- def end_keyword(self, keyword):
247
- self.output.end_keyword(keyword)
256
+ output = self.output
257
+ args = (data, result)
258
+ if implementation:
259
+ if implementation.error:
260
+ method = output.start_invalid_keyword
261
+ elif implementation.type == implementation.LIBRARY_KEYWORD:
262
+ method = output.start_library_keyword
263
+ else:
264
+ method = output.start_user_keyword
265
+ args = (data, implementation, result)
266
+ elif result.type in (result.ELSE, result.ITERATION):
267
+ method = {
268
+ result.IF_ELSE_ROOT: output.start_if_branch,
269
+ result.TRY_EXCEPT_ROOT: output.start_try_branch,
270
+ result.FOR: output.start_for_iteration,
271
+ result.WHILE: output.start_while_iteration,
272
+ }[result.parent.type]
273
+ else:
274
+ method = {
275
+ result.FOR: output.start_for,
276
+ result.WHILE: output.start_while,
277
+ result.IF_ELSE_ROOT: output.start_if,
278
+ result.IF: output.start_if_branch,
279
+ result.ELSE: output.start_if_branch,
280
+ result.ELSE_IF: output.start_if_branch,
281
+ result.TRY_EXCEPT_ROOT: output.start_try,
282
+ result.TRY: output.start_try_branch,
283
+ result.EXCEPT: output.start_try_branch,
284
+ result.FINALLY: output.start_try_branch,
285
+ result.VAR: output.start_var,
286
+ result.BREAK: output.start_break,
287
+ result.CONTINUE: output.start_continue,
288
+ result.RETURN: output.start_return,
289
+ result.ERROR: output.start_error,
290
+ }[result.type]
291
+ method(*args)
292
+
293
+ def end_body_item(self, data, result, implementation=None):
294
+ output = self.output
295
+ args = (data, result)
296
+ if implementation:
297
+ if implementation.error:
298
+ method = output.end_invalid_keyword
299
+ elif implementation.type == implementation.LIBRARY_KEYWORD:
300
+ method = output.end_library_keyword
301
+ else:
302
+ method = output.end_user_keyword
303
+ args = (data, implementation, result)
304
+ elif result.type in (result.ELSE, result.ITERATION):
305
+ method = {
306
+ result.IF_ELSE_ROOT: output.end_if_branch,
307
+ result.TRY_EXCEPT_ROOT: output.end_try_branch,
308
+ result.FOR: output.end_for_iteration,
309
+ result.WHILE: output.end_while_iteration,
310
+ }[result.parent.type]
311
+ else:
312
+ method = {
313
+ result.FOR: output.end_for,
314
+ result.WHILE: output.end_while,
315
+ result.IF_ELSE_ROOT: output.end_if,
316
+ result.IF: output.end_if_branch,
317
+ result.ELSE: output.end_if_branch,
318
+ result.ELSE_IF: output.end_if_branch,
319
+ result.TRY_EXCEPT_ROOT: output.end_try,
320
+ result.TRY: output.end_try_branch,
321
+ result.EXCEPT: output.end_try_branch,
322
+ result.FINALLY: output.end_try_branch,
323
+ result.VAR: output.end_var,
324
+ result.BREAK: output.end_break,
325
+ result.CONTINUE: output.end_continue,
326
+ result.RETURN: output.end_return,
327
+ result.ERROR: output.end_error,
328
+ }[result.type]
329
+ method(*args)
248
330
  self.steps.pop()
249
331
 
250
- def get_runner(self, name):
251
- return self.namespace.get_runner(name)
332
+ def get_runner(self, name, recommend_on_failure=True):
333
+ return self.namespace.get_runner(name, recommend_on_failure)
252
334
 
253
335
  def trace(self, message):
254
336
  self.output.trace(message)
@@ -14,24 +14,26 @@
14
14
  # limitations under the License.
15
15
 
16
16
  from robot.errors import DataError
17
- from robot.utils import get_error_message, is_bytes, is_list_like, is_string, type_name
17
+ from robot.utils import get_error_message, is_list_like, type_name
18
18
 
19
19
  from .arguments import PythonArgumentParser
20
+ from .context import EXECUTION_CONTEXTS
20
21
 
21
22
 
22
23
  def no_dynamic_method(*args):
23
24
  return None
24
25
 
25
26
 
26
- class _DynamicMethod:
27
+ class DynamicMethod:
27
28
  _underscore_name = NotImplemented
28
29
 
29
- def __init__(self, lib):
30
- self.method = self._get_method(lib)
30
+ def __init__(self, instance):
31
+ self.instance = instance
32
+ self.method = self._get_method(instance)
31
33
 
32
- def _get_method(self, lib):
34
+ def _get_method(self, instance):
33
35
  for name in self._underscore_name, self._camelCaseName:
34
- method = getattr(lib, name, None)
36
+ method = getattr(instance, name, None)
35
37
  if callable(method):
36
38
  return method
37
39
  return no_dynamic_method
@@ -45,28 +47,31 @@ class _DynamicMethod:
45
47
  def name(self):
46
48
  return self.method.__name__
47
49
 
48
- def __call__(self, *args):
50
+ def __call__(self, *args, **kwargs):
49
51
  try:
50
- return self._handle_return_value(self.method(*args))
51
- except:
52
- raise DataError("Calling dynamic method '%s' failed: %s"
53
- % (self.name, get_error_message()))
52
+ ctx = EXECUTION_CONTEXTS.current
53
+ result = self.method(*args, **kwargs)
54
+ if ctx and ctx.asynchronous.is_loop_required(result):
55
+ result = ctx.asynchronous.run_until_complete(result)
56
+ return self._handle_return_value(result)
57
+ except Exception:
58
+ raise DataError(f"Calling dynamic method '{self.name}' failed: "
59
+ f"{get_error_message()}")
54
60
 
55
61
  def _handle_return_value(self, value):
56
62
  raise NotImplementedError
57
63
 
58
64
  def _to_string(self, value, allow_tuple=False, allow_none=False):
59
- if is_string(value):
65
+ if isinstance(value, str):
60
66
  return value
61
- if is_bytes(value):
67
+ if isinstance(value, bytes):
62
68
  return value.decode('UTF-8')
63
69
  if allow_tuple and is_list_like(value) and len(value) > 0:
64
70
  return tuple(value)
65
71
  if allow_none and value is None:
66
72
  return value
67
- or_tuple = ' or a non-empty tuple' if allow_tuple else ''
68
- raise DataError('Return value must be a string%s, got %s.'
69
- % (or_tuple, type_name(value)))
73
+ allowed = 'a string or a non-empty tuple' if allow_tuple else 'a string'
74
+ raise DataError(f'Return value must be {allowed}, got {type_name(value)}.')
70
75
 
71
76
  def _to_list(self, value):
72
77
  if value is None:
@@ -80,14 +85,15 @@ class _DynamicMethod:
80
85
  return [self._to_string(item, allow_tuples)
81
86
  for item in self._to_list(value)]
82
87
  except DataError:
83
- raise DataError('Return value must be a list of strings%s.'
84
- % (' or non-empty tuples' if allow_tuples else ''))
88
+ allowed = 'strings or non-empty tuples' if allow_tuples else 'strings'
89
+ raise DataError(f'Return value must be a list of {allowed}, '
90
+ f'got {type_name(value)}.')
85
91
 
86
92
  def __bool__(self):
87
93
  return self.method is not no_dynamic_method
88
94
 
89
95
 
90
- class GetKeywordNames(_DynamicMethod):
96
+ class GetKeywordNames(DynamicMethod):
91
97
  _underscore_name = 'get_keyword_names'
92
98
 
93
99
  def _handle_return_value(self, value):
@@ -102,52 +108,74 @@ class GetKeywordNames(_DynamicMethod):
102
108
  yield name
103
109
 
104
110
 
105
- class RunKeyword(_DynamicMethod):
111
+ class RunKeyword(DynamicMethod):
106
112
  _underscore_name = 'run_keyword'
107
113
 
108
- @property
109
- def supports_kwargs(self):
110
- spec = PythonArgumentParser().parse(self.method)
111
- return len(spec.positional) == 3
112
-
114
+ def __init__(self, instance, keyword_name: 'str|None' = None,
115
+ supports_named_args: 'bool|None' = None):
116
+ super().__init__(instance)
117
+ self.keyword_name = keyword_name
118
+ self._supports_named_args = supports_named_args
113
119
 
114
- class GetKeywordDocumentation(_DynamicMethod):
120
+ @property
121
+ def supports_named_args(self) -> bool:
122
+ if self._supports_named_args is None:
123
+ spec = PythonArgumentParser().parse(self.method)
124
+ self._supports_named_args = len(spec.positional) == 3
125
+ return self._supports_named_args
126
+
127
+ def __call__(self, *positional, **named):
128
+ if self.supports_named_args:
129
+ args = (self.keyword_name, positional, named)
130
+ elif named:
131
+ # This should never happen.
132
+ raise ValueError(f"'named' should not be used when named-argument "
133
+ f"support is not enabled, got {named}.")
134
+ else:
135
+ args = (self.keyword_name, positional)
136
+ return self.method(*args)
137
+
138
+
139
+ class GetKeywordDocumentation(DynamicMethod):
115
140
  _underscore_name = 'get_keyword_documentation'
116
141
 
117
142
  def _handle_return_value(self, value):
118
143
  return self._to_string(value or '')
119
144
 
120
145
 
121
- class GetKeywordArguments(_DynamicMethod):
146
+ class GetKeywordArguments(DynamicMethod):
122
147
  _underscore_name = 'get_keyword_arguments'
123
148
 
124
- def __init__(self, lib):
125
- _DynamicMethod.__init__(self, lib)
126
- self._supports_kwargs = RunKeyword(lib).supports_kwargs
149
+ def __init__(self, instance, supports_named_args: 'bool|None' = None):
150
+ super().__init__(instance)
151
+ if supports_named_args is None:
152
+ self.supports_named_args = RunKeyword(instance).supports_named_args
153
+ else:
154
+ self.supports_named_args = supports_named_args
127
155
 
128
156
  def _handle_return_value(self, value):
129
157
  if value is None:
130
- if self._supports_kwargs:
158
+ if self.supports_named_args:
131
159
  return ['*varargs', '**kwargs']
132
160
  return ['*varargs']
133
161
  return self._to_list_of_strings(value, allow_tuples=True)
134
162
 
135
163
 
136
- class GetKeywordTypes(_DynamicMethod):
164
+ class GetKeywordTypes(DynamicMethod):
137
165
  _underscore_name = 'get_keyword_types'
138
166
 
139
167
  def _handle_return_value(self, value):
140
168
  return value if self else {}
141
169
 
142
170
 
143
- class GetKeywordTags(_DynamicMethod):
171
+ class GetKeywordTags(DynamicMethod):
144
172
  _underscore_name = 'get_keyword_tags'
145
173
 
146
174
  def _handle_return_value(self, value):
147
175
  return self._to_list_of_strings(value)
148
176
 
149
177
 
150
- class GetKeywordSource(_DynamicMethod):
178
+ class GetKeywordSource(DynamicMethod):
151
179
  _underscore_name = 'get_keyword_source'
152
180
 
153
181
  def _handle_return_value(self, value):
@@ -13,16 +13,13 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
 
16
- import copy
17
- import os.path
18
16
  import os
19
17
 
20
18
  from robot.output import LOGGER
21
19
  from robot.errors import FrameworkError, DataError
22
- from robot.utils import normpath, seq2str, seq2str2, is_string
20
+ from robot.utils import normpath, seq2str, seq2str2
23
21
 
24
22
  from .builder import ResourceFileBuilder
25
- from .handlerstore import HandlerStore
26
23
  from .testlibraries import TestLibrary
27
24
 
28
25
 
@@ -41,15 +38,27 @@ class Importer:
41
38
 
42
39
  def close_global_library_listeners(self):
43
40
  for lib in self._library_cache.values():
44
- lib.close_global_listeners()
41
+ lib.scope_manager.close_global_listeners()
45
42
 
46
43
  def import_library(self, name, args, alias, variables):
47
- lib = TestLibrary(name, args, variables, create_handlers=False)
48
- positional, named = lib.positional_args, lib.named_args
49
- lib = self._import_library(name, positional, named, lib)
44
+ lib = TestLibrary.from_name(name, args=args, variables=variables,
45
+ create_keywords=False)
46
+ positional, named = lib.init.positional, lib.init.named
47
+ args_str = seq2str2(positional + [f'{n}={named[n]}' for n in named])
48
+ key = (name, positional, named)
49
+ if key in self._library_cache:
50
+ LOGGER.info(f"Found library '{name}' with arguments {args_str} "
51
+ f"from cache.")
52
+ lib = self._library_cache[key]
53
+ else:
54
+ lib.create_keywords()
55
+ if lib.scope is not lib.scope.GLOBAL:
56
+ lib.instance = None
57
+ self._library_cache[key] = lib
58
+ self._log_imported_library(name, args_str, lib)
50
59
  if alias:
51
60
  alias = variables.replace_scalar(alias)
52
- lib = self._copy_library(lib, alias)
61
+ lib = lib.copy(name=alias)
53
62
  LOGGER.info(f"Imported library '{name}' with name '{alias}'.")
54
63
  return lib
55
64
 
@@ -69,46 +78,15 @@ class Importer:
69
78
  raise DataError(f"Invalid resource file extension '{extension}'. "
70
79
  f"Supported extensions are {extensions}.")
71
80
 
72
- def _import_library(self, name, positional, named, lib):
73
- args = positional + [f'{name}={value}' for name, value in named]
74
- key = (name, positional, named)
75
- if key in self._library_cache:
76
- LOGGER.info(f"Found library '{name}' with arguments {seq2str2(args)} "
77
- f"from cache.")
78
- return self._library_cache[key]
79
- lib.create_handlers()
80
- self._library_cache[key] = lib
81
- self._log_imported_library(name, args, lib)
82
- return lib
83
-
84
- def _log_imported_library(self, name, args, lib):
85
- type = lib.__class__.__name__.replace('Library', '').lower()[1:]
86
- listener = ', with listener' if lib.has_listener else ''
87
- LOGGER.info(f"Imported library '{name}' with arguments {seq2str2(args)} "
88
- f"(version {lib.version or '<unknown>'}, {type} type, "
89
- f"{lib.scope} scope, {len(lib)} keywords{listener}).")
90
- if not lib:
81
+ def _log_imported_library(self, name, args_str, lib):
82
+ kind = type(lib).__name__.replace('Library', '').lower()
83
+ listener = ', with listener' if lib.listeners else ''
84
+ LOGGER.info(f"Imported library '{name}' with arguments {args_str} "
85
+ f"(version {lib.version or '<unknown>'}, {kind} type, "
86
+ f"{lib.scope.name} scope, {len(lib.keywords)} keywords{listener}).")
87
+ if not (lib.keywords or lib.listeners):
91
88
  LOGGER.warn(f"Imported library '{name}' contains no keywords.")
92
89
 
93
- def _copy_library(self, orig, name):
94
- # This is pretty ugly. Hopefully we can remove cache and copying
95
- # altogether in 3.0 and always just re-import libraries:
96
- # https://github.com/robotframework/robotframework/issues/2106
97
- lib = copy.copy(orig)
98
- lib.name = name
99
- lib.scope = type(lib.scope)(lib)
100
- lib.reset_instance()
101
- lib.handlers = HandlerStore()
102
- for handler in orig.handlers._normal.values():
103
- handler = copy.copy(handler)
104
- handler.library = lib
105
- lib.handlers.add(handler)
106
- for handler in orig.handlers._embedded:
107
- handler = copy.copy(handler)
108
- handler.library = lib
109
- lib.handlers.add(handler, embedded=True)
110
- return lib
111
-
112
90
 
113
91
  class ImportCache:
114
92
  """Keeps track on and optionally caches imported items.
@@ -122,7 +100,7 @@ class ImportCache:
122
100
  self._items = []
123
101
 
124
102
  def __setitem__(self, key, item):
125
- if not is_string(key) and not isinstance(key, tuple):
103
+ if not isinstance(key, (str, tuple)):
126
104
  raise FrameworkError('Invalid key for ImportCache')
127
105
  key = self._norm_path_key(key)
128
106
  if key not in self._keys:
@@ -154,4 +132,4 @@ class ImportCache:
154
132
  return key
155
133
 
156
134
  def _is_path(self, key):
157
- return is_string(key) and os.path.isabs(key) and os.path.exists(key)
135
+ return isinstance(key, str) and os.path.isabs(key) and os.path.exists(key)
@@ -0,0 +1,67 @@
1
+ # Copyright 2008-2015 Nokia Networks
2
+ # Copyright 2016- Robot Framework Foundation
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ from robot.errors import DataError
17
+ from robot.result import Keyword as KeywordResult
18
+ from robot.variables import VariableAssignment
19
+
20
+ from .arguments import EmbeddedArguments
21
+ from .model import Keyword as KeywordData
22
+ from .statusreporter import StatusReporter
23
+ from .keywordimplementation import KeywordImplementation
24
+
25
+
26
+ class InvalidKeyword(KeywordImplementation):
27
+ """Represents an invalid keyword call.
28
+
29
+ Keyword may not have been found, there could have been multiple matches,
30
+ or the keyword call itself could have been invalid.
31
+ """
32
+ type = KeywordImplementation.INVALID_KEYWORD
33
+
34
+ def _get_embedded(self, name) -> 'EmbeddedArguments|None':
35
+ try:
36
+ return super()._get_embedded(name)
37
+ except DataError:
38
+ return None
39
+
40
+ def create_runner(self, name, languages=None):
41
+ return InvalidKeywordRunner(self, name)
42
+
43
+ def bind(self, data: KeywordData) -> 'InvalidKeyword':
44
+ return self.copy(parent=data.parent)
45
+
46
+
47
+ class InvalidKeywordRunner:
48
+
49
+ def __init__(self, keyword: InvalidKeyword, name: 'str|None' = None):
50
+ self.keyword = keyword
51
+ self.name = name or keyword.name
52
+ if not keyword.error:
53
+ raise ValueError("Executed 'InvalidKeyword' instance requires 'error'.")
54
+
55
+ def run(self, data: KeywordData, result: KeywordResult, context, run=True):
56
+ kw = self.keyword.bind(data)
57
+ result.config(name=self.name,
58
+ owner=kw.owner.name if kw.owner else None,
59
+ args=data.args,
60
+ assign=tuple(VariableAssignment(data.assign)),
61
+ type=data.type)
62
+ with StatusReporter(data, result, context, run, implementation=kw):
63
+ # 'error' is can be set to 'None' by a listener that handles it.
64
+ if run and kw.error is not None:
65
+ raise DataError(kw.error)
66
+
67
+ dry_run = run