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
@@ -0,0 +1,260 @@
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 itertools import chain
17
+ from typing import TYPE_CHECKING
18
+
19
+ from robot.errors import (DataError, ExecutionFailed, ExecutionPassed, ExecutionStatus,
20
+ PassExecution, ReturnFromKeyword, UserKeywordExecutionFailed,
21
+ VariableError)
22
+ from robot.result import Keyword as KeywordResult
23
+ from robot.utils import DotDict, getshortdoc, prepr, split_tags_from_doc
24
+ from robot.variables import is_list_variable, VariableAssignment
25
+
26
+ from .arguments import ArgumentSpec, DefaultValue
27
+ from .bodyrunner import BodyRunner, KeywordRunner
28
+ from .model import Keyword as KeywordData
29
+ from .statusreporter import StatusReporter
30
+ from .timeouts import KeywordTimeout
31
+
32
+ if TYPE_CHECKING:
33
+ from .resourcemodel import UserKeyword
34
+
35
+
36
+ class UserKeywordRunner:
37
+
38
+ def __init__(self, keyword: 'UserKeyword', name: 'str|None' = None):
39
+ self.keyword = keyword
40
+ self.name = name or keyword.name
41
+ self.pre_run_messages = ()
42
+
43
+ def run(self, data: KeywordData, result: KeywordResult, context, run=True):
44
+ kw = self.keyword.bind(data)
45
+ assignment = VariableAssignment(data.assign)
46
+ self._config_result(result, data, kw, assignment, context.variables)
47
+ with StatusReporter(data, result, context, run, implementation=kw):
48
+ if kw.private:
49
+ context.warn_on_invalid_private_call(kw)
50
+ with assignment.assigner(context) as assigner:
51
+ if run:
52
+ return_value = self._run(data, kw, result, context)
53
+ assigner.assign(return_value)
54
+ return return_value
55
+
56
+ def _config_result(self, result: KeywordResult, data: KeywordData,
57
+ kw: 'UserKeyword', assignment, variables):
58
+ doc = variables.replace_string(kw.doc, ignore_errors=True)
59
+ doc, tags = split_tags_from_doc(doc)
60
+ tags = variables.replace_list(kw.tags, ignore_errors=True) + tags
61
+ result.config(name=self.name,
62
+ owner=kw.owner.name,
63
+ doc=getshortdoc(doc),
64
+ args=data.args,
65
+ assign=tuple(assignment),
66
+ tags=tags,
67
+ type=data.type)
68
+
69
+ def _run(self, data: KeywordData, kw: 'UserKeyword', result: KeywordResult, context):
70
+ if self.pre_run_messages:
71
+ for message in self.pre_run_messages:
72
+ context.output.message(message)
73
+ variables = context.variables
74
+ positional, named = self._resolve_arguments(kw, data.args, variables)
75
+ with context.user_keyword(kw):
76
+ self._set_arguments(kw, positional, named, context)
77
+ if kw.timeout:
78
+ timeout = KeywordTimeout(kw.timeout, variables)
79
+ result.timeout = str(timeout)
80
+ else:
81
+ timeout = None
82
+ with context.timeout(timeout):
83
+ exception, return_value = self._execute(kw, result, context)
84
+ if exception and not exception.can_continue(context):
85
+ raise exception
86
+ return_value = self._handle_return_value(return_value, variables)
87
+ if exception:
88
+ exception.return_value = return_value
89
+ raise exception
90
+ return return_value
91
+
92
+ def _resolve_arguments(self, kw: 'UserKeyword', args, variables=None):
93
+ return kw.resolve_arguments(args, variables)
94
+
95
+ def _set_arguments(self, kw: 'UserKeyword', positional, named, context):
96
+ variables = context.variables
97
+ positional, named = kw.args.map(positional, named, replace_defaults=False)
98
+ self._set_variables(kw.args, positional, named, variables)
99
+ context.output.trace(lambda: self._trace_log_args_message(kw, variables),
100
+ write_if_flat=False)
101
+
102
+ def _set_variables(self, spec: ArgumentSpec, positional, named, variables):
103
+ positional, var_positional = self._separate_positional(spec, positional)
104
+ named_only, var_named = self._separate_named(spec, named)
105
+ for name, value in chain(zip(spec.positional, positional), named_only):
106
+ if isinstance(value, DefaultValue):
107
+ value = value.resolve(variables)
108
+ variables[f'${{{name}}}'] = value
109
+ if spec.var_positional:
110
+ variables[f'@{{{spec.var_positional}}}'] = var_positional
111
+ if spec.var_named:
112
+ variables[f'&{{{spec.var_named}}}'] = DotDict(var_named)
113
+
114
+ def _separate_positional(self, spec: ArgumentSpec, positional):
115
+ if not spec.var_positional:
116
+ return positional, []
117
+ count = len(spec.positional)
118
+ return positional[:count], positional[count:]
119
+
120
+ def _separate_named(self, spec: ArgumentSpec, named):
121
+ named_only = []
122
+ var_named = []
123
+ for name, value in named:
124
+ target = named_only if name in spec.named_only else var_named
125
+ target.append((name, value))
126
+ return named_only, var_named
127
+
128
+ def _trace_log_args_message(self, kw: 'UserKeyword', variables):
129
+ return self._format_trace_log_args_message(
130
+ self._format_args_for_trace_logging(kw.args), variables
131
+ )
132
+
133
+ def _format_args_for_trace_logging(self, spec: ArgumentSpec):
134
+ args = [f'${{{arg}}}' for arg in spec.positional]
135
+ if spec.var_positional:
136
+ args.append(f'@{{{spec.var_positional}}}')
137
+ if spec.var_named:
138
+ args.append(f'&{{{spec.var_named}}}')
139
+ return args
140
+
141
+ def _format_trace_log_args_message(self, args, variables):
142
+ args = ' | '.join(f'{name}={prepr(variables[name])}' for name in args)
143
+ return f'Arguments: [ {args} ]'
144
+
145
+ def _execute(self, kw: 'UserKeyword', result: KeywordResult, context):
146
+ if kw.error:
147
+ raise DataError(kw.error)
148
+ if not kw.body:
149
+ raise DataError('User keyword cannot be empty.')
150
+ if not kw.name:
151
+ raise DataError('User keyword name cannot be empty.')
152
+ if context.dry_run and kw.tags.robot('no-dry-run'):
153
+ return None, None
154
+ error = success = return_value = None
155
+ if kw.setup:
156
+ error = self._run_setup_or_teardown(kw.setup, result.setup, context)
157
+ try:
158
+ BodyRunner(context, run=not error).run(kw, result)
159
+ except ReturnFromKeyword as exception:
160
+ return_value = exception.return_value
161
+ error = exception.earlier_failures
162
+ except ExecutionPassed as exception:
163
+ success = exception
164
+ error = exception.earlier_failures
165
+ if error:
166
+ error.continue_on_failure = False
167
+ except ExecutionFailed as exception:
168
+ error = exception
169
+ if kw.teardown:
170
+ with context.keyword_teardown(error):
171
+ td_error = self._run_setup_or_teardown(kw.teardown, result.teardown,
172
+ context)
173
+ else:
174
+ td_error = None
175
+ if error or td_error:
176
+ error = UserKeywordExecutionFailed(error, td_error)
177
+ return error or success, return_value
178
+
179
+ def _handle_return_value(self, return_value, variables):
180
+ if not return_value:
181
+ return None
182
+ contains_list_var = any(is_list_variable(item) for item in return_value)
183
+ try:
184
+ return_value = variables.replace_list(return_value)
185
+ except DataError as err:
186
+ raise VariableError(f'Replacing variables from keyword return '
187
+ f'value failed: {err}')
188
+ if len(return_value) != 1 or contains_list_var:
189
+ return return_value
190
+ return return_value[0]
191
+
192
+ def _run_setup_or_teardown(self, data: KeywordData, result: KeywordResult,
193
+ context):
194
+ try:
195
+ name = context.variables.replace_string(data.name)
196
+ except DataError as err:
197
+ if context.dry_run:
198
+ return None
199
+ return ExecutionFailed(err.message, syntax=True)
200
+ if name.upper() in ('', 'NONE'):
201
+ return None
202
+ try:
203
+ KeywordRunner(context).run(data, result, name)
204
+ except PassExecution:
205
+ return None
206
+ except ExecutionStatus as err:
207
+ return err
208
+ return None
209
+
210
+ def dry_run(self, data: KeywordData, result: KeywordResult, context):
211
+ kw = self.keyword.bind(data)
212
+ assignment = VariableAssignment(data.assign)
213
+ self._config_result(result, data, kw, assignment, context.variables)
214
+ with StatusReporter(data, result, context, implementation=kw):
215
+ assignment.validate_assignment()
216
+ self._dry_run(data, kw, result, context)
217
+
218
+ def _dry_run(self, data: KeywordData, kw: 'UserKeyword', result: KeywordResult,
219
+ context):
220
+ if self.pre_run_messages:
221
+ for message in self.pre_run_messages:
222
+ context.output.message(message)
223
+ self._resolve_arguments(kw, data.args)
224
+ with context.user_keyword(kw):
225
+ if kw.timeout:
226
+ timeout = KeywordTimeout(kw.timeout, context.variables)
227
+ result.timeout = str(timeout)
228
+ error, _ = self._execute(kw, result, context)
229
+ if error:
230
+ raise error
231
+
232
+
233
+ class EmbeddedArgumentsRunner(UserKeywordRunner):
234
+
235
+ def __init__(self, keyword: 'UserKeyword', name: str):
236
+ super().__init__(keyword, name)
237
+ self.embedded_args = keyword.embedded.match(name).groups()
238
+
239
+ def _resolve_arguments(self, kw: 'UserKeyword', args, variables=None):
240
+ result = super()._resolve_arguments(kw, args, variables)
241
+ if variables:
242
+ embedded = [variables.replace_scalar(e) for e in self.embedded_args]
243
+ self.embedded_args = kw.embedded.map(embedded)
244
+ return result
245
+
246
+ def _set_arguments(self, kw: 'UserKeyword', positional, named, context):
247
+ variables = context.variables
248
+ for name, value in self.embedded_args:
249
+ variables[f'${{{name}}}'] = value
250
+ super()._set_arguments(kw, positional, named, context)
251
+
252
+ def _trace_log_args_message(self, kw: 'UserKeyword', variables):
253
+ args = [f'${{{arg}}}' for arg in kw.embedded.args]
254
+ args += self._format_args_for_trace_logging(kw.args)
255
+ return self._format_trace_log_args_message(args, variables)
256
+
257
+ def _config_result(self, result: KeywordResult, data: KeywordData,
258
+ kw: 'UserKeyword', assignment, variables):
259
+ super()._config_result(result, data, kw, assignment, variables)
260
+ result.source_name = kw.name
@@ -171,11 +171,11 @@ class JsonConverter:
171
171
  'relativeSource': self._get_relative_source(suite.source),
172
172
  'id': suite.id,
173
173
  'name': self._escape(suite.name),
174
- 'fullName': self._escape(suite.longname),
174
+ 'fullName': self._escape(suite.full_name),
175
175
  'doc': self._html(suite.doc),
176
176
  'metadata': [(self._escape(name), self._html(value))
177
177
  for name, value in suite.metadata.items()],
178
- 'numberOfTests': suite.test_count ,
178
+ 'numberOfTests': suite.test_count,
179
179
  'suites': self._convert_suites(suite),
180
180
  'tests': self._convert_tests(suite),
181
181
  'keywords': list(self._convert_keywords((suite.setup, suite.teardown)))
@@ -205,7 +205,7 @@ class JsonConverter:
205
205
  test.body.append(test.teardown)
206
206
  return {
207
207
  'name': self._escape(test.name),
208
- 'fullName': self._escape(test.longname),
208
+ 'fullName': self._escape(test.full_name),
209
209
  'id': test.id,
210
210
  'doc': self._html(test.doc),
211
211
  'tags': [self._escape(t) for t in test.tags],
@@ -217,10 +217,8 @@ class JsonConverter:
217
217
  for kw in keywords:
218
218
  if not kw:
219
219
  continue
220
- if kw.type == kw.SETUP:
221
- yield self._convert_keyword(kw, 'SETUP')
222
- elif kw.type == kw.TEARDOWN:
223
- yield self._convert_keyword(kw, 'TEARDOWN')
220
+ if kw.type in kw.KEYWORD_TYPES:
221
+ yield self._convert_keyword(kw)
224
222
  elif kw.type == kw.FOR:
225
223
  yield self._convert_for(kw)
226
224
  elif kw.type == kw.WHILE:
@@ -229,11 +227,11 @@ class JsonConverter:
229
227
  yield from self._convert_if(kw)
230
228
  elif kw.type == kw.TRY_EXCEPT_ROOT:
231
229
  yield from self._convert_try(kw)
232
- else:
233
- yield self._convert_keyword(kw, 'KEYWORD')
230
+ elif kw.type == kw.VAR:
231
+ yield self._convert_var(kw)
234
232
 
235
233
  def _convert_for(self, data):
236
- name = '%s %s %s' % (', '.join(data.variables), data.flavor,
234
+ name = '%s %s %s' % (', '.join(data.assign), data.flavor,
237
235
  seq2str2(data.values))
238
236
  return {'type': 'FOR', 'name': self._escape(name), 'arguments': ''}
239
237
 
@@ -250,15 +248,22 @@ class JsonConverter:
250
248
  for branch in data.body:
251
249
  if branch.type == branch.EXCEPT:
252
250
  patterns = ', '.join(branch.patterns)
253
- as_var = f'AS {branch.variable}' if branch.variable else ''
251
+ as_var = f'AS {branch.assign}' if branch.assign else ''
254
252
  name = f'{patterns} {as_var}'.strip()
255
253
  else:
256
254
  name = ''
257
255
  yield {'type': branch.type, 'name': name, 'arguments': ''}
258
256
 
259
- def _convert_keyword(self, kw, kw_type):
257
+ def _convert_var(self, data):
258
+ if data.name[0] == '$' and len(data.value) == 1:
259
+ value = data.value[0]
260
+ else:
261
+ value = '[' + ', '.join(data.value) + ']'
262
+ return {'type': 'VAR', 'name': f'{data.name} = {value}'}
263
+
264
+ def _convert_keyword(self, kw):
260
265
  return {
261
- 'type': kw_type,
266
+ 'type': kw.type,
262
267
  'name': self._escape(self._get_kw_name(kw)),
263
268
  'arguments': self._escape(', '.join(kw.args))
264
269
  }
@@ -33,6 +33,8 @@ or::
33
33
  assert Matcher('H?llo').match('Hillo')
34
34
  """
35
35
 
36
+ import warnings
37
+
36
38
  from .argumentparser import ArgumentParser, cmdline2list
37
39
  from .application import Application
38
40
  from .compress import compress_text
@@ -52,6 +54,7 @@ from .match import eq, Matcher, MultiMatcher
52
54
  from .misc import (classproperty, isatty, parse_re_flags, plural_or_not,
53
55
  printable_name, seq2str, seq2str2, test_or_task)
54
56
  from .normalizing import normalize, normalize_whitespace, NormalizedDict
57
+ from .notset import NOT_SET
55
58
  from .platform import PY_VERSION, PYPY, UNIXY, WINDOWS, RERAISED_EXCEPTIONS
56
59
  from .recommendations import RecommendationFinder
57
60
  from .robotenv import get_env_var, set_env_var, del_env_var, get_env_vars
@@ -61,7 +64,7 @@ from .robotpath import abspath, find_file, get_link_path, normpath
61
64
  from .robottime import (elapsed_time_to_string, format_time, get_elapsed_time,
62
65
  get_time, get_timestamp, secs_to_timestamp,
63
66
  secs_to_timestr, timestamp_to_secs, timestr_to_secs,
64
- parse_time)
67
+ parse_time, parse_timestamp)
65
68
  from .robottypes import (has_args, is_bytes, is_dict_like, is_falsy, is_integer,
66
69
  is_list_like, is_number, is_pathlike, is_string, is_truthy,
67
70
  is_union, type_name, type_repr, typeddict_types)
@@ -79,37 +82,52 @@ def read_rest_data(rstfile):
79
82
  return read_rest_data(rstfile)
80
83
 
81
84
 
82
- # Quietly deprecated utils. Should be deprecated loudly in RF 7.0.
83
- # https://github.com/robotframework/robotframework/issues/4501
84
-
85
- from .robottypes import FALSE_STRINGS, TRUE_STRINGS
86
-
87
-
88
- # Deprecated Python 2/3 compatibility layer. Not needed by Robot Framework itself
89
- # after RF 5.0 when Python 2 support was dropped. Should be deprecated loudly in
90
- # RF 7.0. Notice that there's also `PY2` in the `platform` submodule.
91
- # https://github.com/robotframework/robotframework/issues/4501
92
-
93
- from io import StringIO
94
-
95
-
96
- PY3 = True
97
- PY2 = JYTHON = IRONPYTHON = False
98
- is_unicode = is_string
99
- unicode = str
100
- unic = safe_str
101
- roundup = round
102
-
103
-
104
- def py2to3(cls):
105
- """Deprecated since RF 5.0. Use Python 3 features directly instead."""
106
- if hasattr(cls, '__unicode__'):
107
- cls.__str__ = lambda self: self.__unicode__()
108
- if hasattr(cls, '__nonzero__'):
109
- cls.__bool__ = lambda self: self.__nonzero__()
110
- return cls
111
-
112
-
113
- def py3to2(cls):
114
- """Deprecated since RF 5.0. Never done anything when used on Python 3."""
115
- return cls
85
+ def unic(item):
86
+ # Cannot be deprecated using '__getattr__' because a module with same name exists.
87
+ warnings.warn("'robot.utils.unic' is deprecated and will be removed in "
88
+ "Robot Framework 9.0.", DeprecationWarning)
89
+ return safe_str(item)
90
+
91
+
92
+ def __getattr__(name):
93
+ # Deprecated utils mostly related to the old Python 2/3 compatibility layer.
94
+ # See also 'unic' above and 'PY2' in 'platform.py'.
95
+ # https://github.com/robotframework/robotframework/issues/4501
96
+
97
+ from io import StringIO
98
+ from .robottypes import FALSE_STRINGS, TRUE_STRINGS
99
+
100
+ def py2to3(cls):
101
+ if hasattr(cls, '__unicode__'):
102
+ cls.__str__ = lambda self: self.__unicode__()
103
+ if hasattr(cls, '__nonzero__'):
104
+ cls.__bool__ = lambda self: self.__nonzero__()
105
+ return cls
106
+
107
+ def py3to2(cls):
108
+ return cls
109
+
110
+ deprecated = {
111
+ 'FALSE_STRINGS': FALSE_STRINGS,
112
+ 'TRUE_STRINGS': TRUE_STRINGS,
113
+ 'StringIO': StringIO,
114
+ 'PY3': True,
115
+ 'PY2': False,
116
+ 'JYTHON': False,
117
+ 'IRONPYTHON': False,
118
+ 'is_unicode': is_string,
119
+ 'unicode': str,
120
+ 'roundup': round,
121
+ 'py2to3': py2to3,
122
+ 'py3to2': py3to2,
123
+ }
124
+
125
+ if name in deprecated:
126
+ # TODO: Change DeprecationWarning to more visible UserWarning in RF 8.0.
127
+ # https://github.com/robotframework/robotframework/issues/4501
128
+ # Remember also 'unic' above '__getattr__' and 'PY2' in 'platform.py'.
129
+ warnings.warn(f"'robot.utils.{name}' is deprecated and will be removed in "
130
+ f"Robot Framework 9.0.", DeprecationWarning)
131
+ return deprecated[name]
132
+
133
+ raise AttributeError(f"'robot.utils' has no attribute '{name}'.")
@@ -13,17 +13,21 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
 
16
+ from typing import Any
17
+
16
18
  from .normalizing import NormalizedDict
17
- from .robottypes import is_string
19
+
20
+
21
+ Connection = Any
18
22
 
19
23
 
20
24
  class ConnectionCache:
21
25
  """Cache for libraries to use with concurrent connections, processes, etc.
22
26
 
23
27
  The cache stores the registered connections (or other objects) and allows
24
- switching between them using generated indices or user given aliases.
25
- This is useful with any library where there's need for multiple concurrent
26
- connections, processes, etc.
28
+ switching between them using generated indices, user given aliases or
29
+ connection objects themselves. This is useful with any library having a need
30
+ for multiple concurrent connections, processes, etc.
27
31
 
28
32
  This class is used also outside the core framework by SeleniumLibrary,
29
33
  SSHLibrary, etc. Backwards compatibility is thus important when doing changes.
@@ -33,10 +37,10 @@ class ConnectionCache:
33
37
  self._no_current = NoConnection(no_current_msg)
34
38
  self.current = self._no_current #: Current active connection.
35
39
  self._connections = []
36
- self._aliases = NormalizedDict()
40
+ self._aliases = NormalizedDict[int]()
37
41
 
38
42
  @property
39
- def current_index(self):
43
+ def current_index(self) -> 'int|None':
40
44
  if not self:
41
45
  return None
42
46
  for index, conn in enumerate(self):
@@ -44,11 +48,13 @@ class ConnectionCache:
44
48
  return index + 1
45
49
 
46
50
  @current_index.setter
47
- def current_index(self, index):
48
- self.current = self._connections[index - 1] \
49
- if index is not None else self._no_current
51
+ def current_index(self, index: 'int|None'):
52
+ if index is None:
53
+ self.current = self._no_current
54
+ else:
55
+ self.current = self._connections[index - 1]
50
56
 
51
- def register(self, connection, alias=None):
57
+ def register(self, connection: Connection, alias: 'str|None' = None):
52
58
  """Registers given connection with optional alias and returns its index.
53
59
 
54
60
  Given connection is set to be the :attr:`current` connection.
@@ -62,52 +68,74 @@ class ConnectionCache:
62
68
  self.current = connection
63
69
  self._connections.append(connection)
64
70
  index = len(self._connections)
65
- if is_string(alias):
71
+ if alias:
66
72
  self._aliases[alias] = index
67
73
  return index
68
74
 
69
- def switch(self, alias_or_index):
70
- """Switches to the connection specified by the given alias or index.
75
+ def switch(self, identifier: 'int|str|Connection') -> Connection:
76
+ """Switches to the connection specified using the ``identifier``.
71
77
 
72
- Updates :attr:`current` and also returns its new value.
78
+ Identifier can be an index, an alias, or a registered connection.
79
+ Raises an error if no matching connection is found.
73
80
 
74
- Alias is whatever was given to :meth:`register` method and indices
75
- are returned by it. Index can be given either as an integer or
76
- as a string that can be converted to an integer. Raises an error
77
- if no connection with the given index or alias found.
81
+ Updates :attr:`current` and also returns its new value.
78
82
  """
79
- self.current = self.get_connection(alias_or_index)
83
+ self.current = self.get_connection(identifier)
80
84
  return self.current
81
85
 
82
- def get_connection(self, alias_or_index=None):
83
- """Get the connection specified by the given alias or index..
86
+ def get_connection(self, identifier: 'int|str|Connection|None' = None) -> Connection:
87
+ """Returns the connection specified using the ``identifier``.
84
88
 
85
- If ``alias_or_index`` is ``None``, returns the current connection
86
- if it is active, or raises an error if it is not.
87
-
88
- Alias is whatever was given to :meth:`register` method and indices
89
- are returned by it. Index can be given either as an integer or
90
- as a string that can be converted to an integer. Raises an error
91
- if no connection with the given index or alias found.
89
+ Identifier can be an index (integer or string), an alias, a registered
90
+ connection or ``None``. If the identifier is ``None``, returns the
91
+ current connection if it is active and raises an error if it is not.
92
+ Raises an error also if no matching connection is found.
92
93
  """
93
- if alias_or_index is None:
94
+ if identifier is None:
94
95
  if not self:
95
96
  self.current.raise_error()
96
97
  return self.current
97
98
  try:
98
- index = self.resolve_alias_or_index(alias_or_index)
99
+ index = self.get_connection_index(identifier)
99
100
  except ValueError as err:
100
101
  raise RuntimeError(err.args[0])
101
102
  return self._connections[index-1]
102
103
 
103
- __getitem__ = get_connection
104
+ def get_connection_index(self, identifier: 'int|str|Connection') -> int:
105
+ """Returns the index of the connection specified using the ``identifier``.
106
+
107
+ Identifier can be an index (integer or string), an alias, or a registered
108
+ connection.
104
109
 
105
- def close_all(self, closer_method='close'):
106
- """Closes connections using given closer method and empties cache.
110
+ New in Robot Framework 7.0. :meth:`resolve_alias_or_index` can be used
111
+ with earlier versions.
112
+ """
113
+ if isinstance(identifier, str) and identifier in self._aliases:
114
+ return self._aliases[identifier]
115
+ if identifier in self._connections:
116
+ return self._connections.index(identifier) + 1
117
+ try:
118
+ index = int(identifier)
119
+ except (ValueError, TypeError):
120
+ index = -1
121
+ if 0 < index <= len(self._connections):
122
+ return index
123
+ raise ValueError(f"Non-existing index or alias '{identifier}'.")
124
+
125
+ def resolve_alias_or_index(self, alias_or_index):
126
+ """Deprecated in RF 7.0. Use :meth:`get_connection_index` instead."""
127
+ # This was initially added for SeleniumLibrary in RF 3.1.2.
128
+ # https://github.com/robotframework/robotframework/issues/3125
129
+ # The new method was added in RF 7.0. We can loudly deprecate this
130
+ # earliest in RF 8.0.
131
+ return self.get_connection_index(alias_or_index)
132
+
133
+ def close_all(self, closer_method: str = 'close'):
134
+ """Closes connections using the specified closer method and empties cache.
107
135
 
108
136
  If simply calling the closer method is not adequate for closing
109
137
  connections, clients should close connections themselves and use
110
- :meth:`empty_cache` afterwards.
138
+ :meth:`empty_cache` afterward.
111
139
  """
112
140
  for conn in self._connections:
113
141
  getattr(conn, closer_method)()
@@ -123,6 +151,8 @@ class ConnectionCache:
123
151
  self._connections = []
124
152
  self._aliases = NormalizedDict()
125
153
 
154
+ __getitem__ = get_connection
155
+
126
156
  def __iter__(self):
127
157
  return iter(self._connections)
128
158
 
@@ -132,31 +162,6 @@ class ConnectionCache:
132
162
  def __bool__(self):
133
163
  return self.current is not self._no_current
134
164
 
135
- def resolve_alias_or_index(self, alias_or_index):
136
- for resolver in self._resolve_alias, self._resolve_index, self._is_connection:
137
- try:
138
- return resolver(alias_or_index)
139
- except ValueError:
140
- pass
141
- raise ValueError(f"Non-existing index or alias '{alias_or_index}'.")
142
-
143
- def _resolve_alias(self, alias):
144
- if is_string(alias) and alias in self._aliases:
145
- return self._aliases[alias]
146
- raise ValueError
147
-
148
- def _resolve_index(self, index):
149
- try:
150
- index = int(index)
151
- except TypeError:
152
- raise ValueError
153
- if not 0 < index <= len(self._connections):
154
- raise ValueError
155
- return index
156
-
157
- def _is_connection(self, conn):
158
- return self._connections.index(conn) + 1
159
-
160
165
 
161
166
  class NoConnection:
162
167
 
@@ -60,6 +60,9 @@ class DotDict(OrderedDict):
60
60
  def __eq__(self, other):
61
61
  return dict.__eq__(self, other)
62
62
 
63
+ def __ne__(self, other):
64
+ return not self == other
65
+
63
66
  def __str__(self):
64
67
  return '{%s}' % ', '.join('%r: %r' % (key, self[key]) for key in self)
65
68
 
@@ -75,7 +75,7 @@ def _get_unixy_encoding():
75
75
 
76
76
 
77
77
  def _get_stream_output_encoding():
78
- # Python 3.6+ uses UTF-8 as encoding with output streams.
78
+ # Python uses UTF-8 as encoding with output streams.
79
79
  # We want the real console encoding regardless the platform.
80
80
  if WINDOWS:
81
81
  return None