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
@@ -0,0 +1,500 @@
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
+ import inspect
17
+ from functools import cached_property, partial
18
+ from pathlib import Path
19
+ from typing import Any, Literal, overload, Sequence, TypeVar
20
+ from types import ModuleType
21
+
22
+ from robot.errors import DataError
23
+ from robot.libraries import STDLIBS
24
+ from robot.output import LOGGER
25
+ from robot.utils import (getdoc, get_error_details, Importer, is_dict_like,
26
+ is_list_like, normalize, NormalizedDict, seq2str2, setter, type_name)
27
+
28
+ from .arguments import CustomArgumentConverters
29
+ from .dynamicmethods import GetKeywordDocumentation, GetKeywordNames, RunKeyword
30
+ from .keywordfinder import KeywordFinder
31
+ from .librarykeyword import DynamicKeyword, LibraryInit, LibraryKeyword, StaticKeyword
32
+ from .libraryscopes import Scope, ScopeManager
33
+ from .outputcapture import OutputCapturer
34
+
35
+
36
+ Self = TypeVar('Self', bound='TestLibrary')
37
+
38
+
39
+ class TestLibrary:
40
+ """Represents imported test library."""
41
+
42
+ def __init__(self, code: 'type|ModuleType',
43
+ init: LibraryInit,
44
+ name: 'str|None' = None,
45
+ real_name: 'str|None' = None,
46
+ source: 'Path|None' = None,
47
+ logger=LOGGER):
48
+ self.code = code
49
+ self.init = init
50
+ self.init.owner = self
51
+ self.instance = None
52
+ self.name = name or code.__name__
53
+ self.real_name = real_name or self.name
54
+ self.source = source
55
+ self._logger = logger
56
+ self.keywords: list[LibraryKeyword] = []
57
+ self._has_listeners = None
58
+ self.scope_manager = ScopeManager.for_library(self)
59
+ self.keyword_finder = KeywordFinder[LibraryKeyword](self)
60
+
61
+ @property
62
+ def instance(self) -> Any:
63
+ """Current library instance.
64
+
65
+ With module based libraries this is the module itself.
66
+
67
+ With class based libraries this is an instance of the class. Instances are
68
+ cleared automatically during execution based on their scope. Accessing this
69
+ property creates a new instance if needed.
70
+
71
+ :attr:`code´ contains the original library code. With module based libraries
72
+ it is the same as :attr:`instance`. With class based libraries it is
73
+ the library class.
74
+ """
75
+ instance = self.code if self._instance is None else self._instance
76
+ if self._has_listeners is None:
77
+ self._has_listeners = self._instance_has_listeners(instance)
78
+ return instance
79
+
80
+ @instance.setter
81
+ def instance(self, instance: Any):
82
+ self._instance = instance
83
+
84
+ @property
85
+ def listeners(self) -> 'list[Any]':
86
+ if self._has_listeners is None:
87
+ self._has_listeners = self._instance_has_listeners(self.instance)
88
+ if self._has_listeners is False:
89
+ return []
90
+ listener = self.instance.ROBOT_LIBRARY_LISTENER
91
+ return list(listener) if is_list_like(listener) else [listener]
92
+
93
+ def _instance_has_listeners(self, instance) -> bool:
94
+ return getattr(instance, 'ROBOT_LIBRARY_LISTENER', None) is not None
95
+
96
+ @property
97
+ def converters(self) -> 'CustomArgumentConverters|None':
98
+ converters = getattr(self.code, 'ROBOT_LIBRARY_CONVERTERS', None)
99
+ if not converters:
100
+ return None
101
+ if not is_dict_like(converters):
102
+ self.report_error(f'Argument converters must be given as a dictionary, '
103
+ f'got {type_name(converters)}.')
104
+ return None
105
+ return CustomArgumentConverters.from_dict(converters, self)
106
+
107
+ @property
108
+ def doc(self) -> str:
109
+ return getdoc(self.instance)
110
+
111
+ @property
112
+ def doc_format(self) -> str:
113
+ return self._attr('ROBOT_LIBRARY_DOC_FORMAT', upper=True)
114
+
115
+ @property
116
+ def scope(self) -> Scope:
117
+ scope = self._attr('ROBOT_LIBRARY_SCOPE', 'TEST', upper=True)
118
+ if scope == 'GLOBAL':
119
+ return Scope.GLOBAL
120
+ if scope in ('SUITE', 'TESTSUITE'):
121
+ return Scope.SUITE
122
+ return Scope.TEST
123
+
124
+ @setter
125
+ def source(self, source: 'Path|str|None') -> 'Path|None':
126
+ return Path(source) if source else None
127
+
128
+ @property
129
+ def version(self) -> str:
130
+ return self._attr('ROBOT_LIBRARY_VERSION') or self._attr('__version__')
131
+
132
+ @property
133
+ def lineno(self) -> int:
134
+ return 1
135
+
136
+ def _attr(self, name, default='', upper=False) -> str:
137
+ value = str(getattr(self.code, name, default))
138
+ if upper:
139
+ value = normalize(value, ignore='_').upper()
140
+ return value
141
+
142
+ @classmethod
143
+ def from_name(cls, name: str,
144
+ real_name: 'str|None' = None,
145
+ args: 'Sequence[str]|None' = None,
146
+ variables=None,
147
+ create_keywords: bool = True,
148
+ logger=LOGGER) -> 'TestLibrary':
149
+ if name in STDLIBS:
150
+ import_name = 'robot.libraries.' + name
151
+ else:
152
+ import_name = name
153
+ if Path(name).exists():
154
+ name = Path(name).stem
155
+ with OutputCapturer(library_import=True):
156
+ importer = Importer('library', logger=logger)
157
+ code, source = importer.import_class_or_module(import_name,
158
+ return_source=True)
159
+ return cls.from_code(code, name, real_name, source, args, variables,
160
+ create_keywords, logger)
161
+
162
+ @classmethod
163
+ def from_code(cls, code: 'type|ModuleType',
164
+ name: 'str|None' = None,
165
+ real_name: 'str|None' = None,
166
+ source: 'Path|None' = None,
167
+ args: 'Sequence[str]|None' = None,
168
+ variables=None,
169
+ create_keywords: bool = True,
170
+ logger=LOGGER) -> 'TestLibrary':
171
+ if inspect.ismodule(code):
172
+ lib = cls.from_module(code, name, real_name, source, create_keywords, logger)
173
+ if args: # Resolving arguments reports an error.
174
+ lib.init.resolve_arguments(args, variables)
175
+ return lib
176
+ return cls.from_class(code, name, real_name, source, args or (), variables,
177
+ create_keywords, logger)
178
+
179
+ @classmethod
180
+ def from_module(cls, module: ModuleType,
181
+ name: 'str|None' = None,
182
+ real_name: 'str|None' = None,
183
+ source: 'Path|None' = None,
184
+ create_keywords: bool = True,
185
+ logger=LOGGER) -> 'TestLibrary':
186
+ return ModuleLibrary.from_module(module, name, real_name, source,
187
+ create_keywords, logger)
188
+
189
+ @classmethod
190
+ def from_class(cls, klass: type,
191
+ name: 'str|None' = None,
192
+ real_name: 'str|None' = None,
193
+ source: 'Path|None' = None,
194
+ args: Sequence[str] = (),
195
+ variables=None,
196
+ create_keywords: bool = True,
197
+ logger=LOGGER) -> 'TestLibrary':
198
+ if not GetKeywordNames(klass):
199
+ library = ClassLibrary
200
+ elif not RunKeyword(klass):
201
+ library = HybridLibrary
202
+ else:
203
+ library = DynamicLibrary
204
+ return library.from_class(klass, name, real_name, source, args, variables,
205
+ create_keywords, logger)
206
+
207
+ def create_keywords(self):
208
+ raise NotImplementedError
209
+
210
+ @overload
211
+ def find_keywords(self, name: str, count: Literal[1]) -> 'LibraryKeyword':
212
+ ...
213
+
214
+ @overload
215
+ def find_keywords(self, name: str, count: 'int|None' = None) \
216
+ -> 'list[LibraryKeyword]':
217
+ ...
218
+
219
+ def find_keywords(self, name: str, count: 'int|None' = None) \
220
+ -> 'list[LibraryKeyword]|LibraryKeyword':
221
+ return self.keyword_finder.find(name, count)
222
+
223
+ def copy(self: Self, name: str) -> Self:
224
+ lib = type(self)(self.code, self.init.copy(), name, self.real_name,
225
+ self.source, self._logger)
226
+ lib.instance = self.instance
227
+ lib.keywords = [kw.copy(owner=lib) for kw in self.keywords]
228
+ return lib
229
+
230
+ def report_error(self, message: str,
231
+ details: 'str|None' = None,
232
+ level: str = 'ERROR',
233
+ details_level: str = 'INFO'):
234
+ prefix = 'Error in' if level in ('ERROR', 'WARN') else 'In'
235
+ self._logger.write(f"{prefix} library '{self.name}': {message}", level)
236
+ if details:
237
+ self._logger.write(f'Details:\n{details}', details_level)
238
+
239
+
240
+ class ModuleLibrary(TestLibrary):
241
+
242
+ @property
243
+ def scope(self) -> Scope:
244
+ return Scope.GLOBAL
245
+
246
+ @classmethod
247
+ def from_module(cls, module: ModuleType,
248
+ name: 'str|None' = None,
249
+ real_name: 'str|None' = None,
250
+ source: 'Path|None' = None,
251
+ create_keywords: bool = True,
252
+ logger=LOGGER) -> 'ModuleLibrary':
253
+ library = cls(module, LibraryInit.null(), name, real_name, source, logger)
254
+ if create_keywords:
255
+ library.create_keywords()
256
+ return library
257
+
258
+ @classmethod
259
+ def from_class(cls, *args, **kws) -> 'TestLibrary':
260
+ raise TypeError(f"Cannot create '{cls.__name__}' from class.")
261
+
262
+ def create_keywords(self):
263
+ excludes = getattr(self.code, '__all__', None)
264
+ StaticKeywordCreator(self, excluded_names=excludes).create_keywords()
265
+
266
+
267
+ class ClassLibrary(TestLibrary):
268
+
269
+ @property
270
+ def instance(self) -> Any:
271
+ if self._instance is None:
272
+ positional, named = self.init.positional, self.init.named
273
+ try:
274
+ with OutputCapturer(library_import=True):
275
+ self._instance = self.code(*positional, **named)
276
+ except Exception:
277
+ message, details = get_error_details()
278
+ if positional or named:
279
+ args = seq2str2(positional + [f'{n}={named[n]}' for n in named])
280
+ args_text = f'arguments {args}'
281
+ else:
282
+ args_text = 'no arguments'
283
+ raise DataError(f"Initializing library '{self.name}' with {args_text} "
284
+ f"failed: {message}\n{details}")
285
+ if self._has_listeners is None:
286
+ self._has_listeners = self._instance_has_listeners(self._instance)
287
+ return self._instance
288
+
289
+ @instance.setter
290
+ def instance(self, instance):
291
+ self._instance = instance
292
+
293
+ @property
294
+ def lineno(self) -> int:
295
+ try:
296
+ lines, start_lineno = inspect.getsourcelines(self.code)
297
+ except (TypeError, OSError, IOError):
298
+ return 1
299
+ for increment, line in enumerate(lines):
300
+ if line.strip().startswith('class '):
301
+ return start_lineno + increment
302
+ return start_lineno
303
+
304
+ @classmethod
305
+ def from_module(cls, *args, **kws) -> 'TestLibrary':
306
+ raise TypeError(f"Cannot create '{cls.__name__}' from module.")
307
+
308
+ @classmethod
309
+ def from_class(cls, klass: type,
310
+ name: 'str|None' = None,
311
+ real_name: 'str|None' = None,
312
+ source: 'Path|None' = None,
313
+ args: Sequence[str] = (),
314
+ variables=None,
315
+ create_keywords: bool = True,
316
+ logger=LOGGER) -> 'ClassLibrary':
317
+ init = LibraryInit.from_class(klass)
318
+ library = cls(klass, init, name, real_name, source, logger)
319
+ positional, named = init.args.resolve(args, variables)
320
+ init.positional, init.named = list(positional), dict(named)
321
+ if create_keywords:
322
+ library.create_keywords()
323
+ return library
324
+
325
+ def create_keywords(self):
326
+ StaticKeywordCreator(self, avoid_properties=True).create_keywords()
327
+
328
+
329
+ class HybridLibrary(ClassLibrary):
330
+
331
+ def create_keywords(self):
332
+ names = DynamicKeywordCreator(self).get_keyword_names()
333
+ creator = StaticKeywordCreator(self, getting_method_failed_level='ERROR')
334
+ creator.create_keywords(names)
335
+
336
+
337
+ class DynamicLibrary(ClassLibrary):
338
+ _supports_named_args = None
339
+
340
+ @property
341
+ def supports_named_args(self) -> bool:
342
+ if self._supports_named_args is None:
343
+ self._supports_named_args = RunKeyword(self.instance).supports_named_args
344
+ return self._supports_named_args
345
+
346
+ @property
347
+ def doc(self) -> str:
348
+ return GetKeywordDocumentation(self.instance)('__intro__') or super().doc
349
+
350
+ def create_keywords(self):
351
+ DynamicKeywordCreator(self).create_keywords()
352
+
353
+
354
+ class KeywordCreator:
355
+
356
+ def __init__(self, library: TestLibrary, getting_method_failed_level='INFO'):
357
+ self.library = library
358
+ self.getting_method_failed_level = getting_method_failed_level
359
+
360
+ def get_keyword_names(self) -> 'list[str]':
361
+ raise NotImplementedError
362
+
363
+ def create_keywords(self, names: 'list[str]|None' = None):
364
+ library = self.library
365
+ library.keyword_finder.invalidate_cache()
366
+ instance = library.instance
367
+ keywords = library.keywords = []
368
+ if names is None:
369
+ names = self.get_keyword_names()
370
+ seen = NormalizedDict(ignore='_')
371
+ for name in names:
372
+ try:
373
+ kw = self._create_keyword(instance, name)
374
+ except DataError as err:
375
+ self._adding_keyword_failed(name, err, self.getting_method_failed_level)
376
+ else:
377
+ if not kw:
378
+ continue
379
+ try:
380
+ if kw.embedded:
381
+ self._validate_embedded(kw)
382
+ else:
383
+ self._handle_duplicates(kw, seen)
384
+ except DataError as err:
385
+ self._adding_keyword_failed(kw.name, err)
386
+ else:
387
+ keywords.append(kw)
388
+ library._logger.debug(f"Created keyword '{kw.name}'.")
389
+
390
+ def _create_keyword(self, instance, name) -> 'LibraryKeyword|None':
391
+ raise NotImplementedError
392
+
393
+ def _handle_duplicates(self, kw, seen: NormalizedDict):
394
+ if kw.name in seen:
395
+ error = 'Keyword with same name defined multiple times.'
396
+ seen[kw.name].error = error
397
+ raise DataError(error)
398
+ seen[kw.name] = kw
399
+
400
+ def _validate_embedded(self, kw):
401
+ if len(kw.embedded.args) > kw.args.maxargs:
402
+ raise DataError(f'Keyword must accept at least as many positional '
403
+ f'arguments as it has embedded arguments.')
404
+ kw.args.embedded = kw.embedded.args
405
+
406
+ def _adding_keyword_failed(self, name, error, level='ERROR'):
407
+ self.library.report_error(
408
+ f"Adding keyword '{name}' failed: {error}",
409
+ error.details,
410
+ level=level,
411
+ details_level='DEBUG'
412
+ )
413
+
414
+
415
+ class StaticKeywordCreator(KeywordCreator):
416
+
417
+ def __init__(self, library: TestLibrary, getting_method_failed_level='INFO',
418
+ excluded_names=None, avoid_properties=False):
419
+ super().__init__(library, getting_method_failed_level)
420
+ self.excluded_names = excluded_names
421
+ self.avoid_properties = avoid_properties
422
+
423
+ def get_keyword_names(self) -> 'list[str]':
424
+ instance = self.library.instance
425
+ try:
426
+ return self._get_names(instance)
427
+ except Exception:
428
+ message, details = get_error_details()
429
+ raise DataError(f"Getting keyword names from library '{self.library.name}' "
430
+ f"failed: {message}", details)
431
+
432
+ def _get_names(self, instance) -> 'list[str]':
433
+ def explicitly_included(name):
434
+ candidate = inspect.getattr_static(instance, name)
435
+ if isinstance(candidate, (classmethod, staticmethod)):
436
+ candidate = candidate.__func__
437
+ try:
438
+ return hasattr(candidate, 'robot_name')
439
+ except Exception:
440
+ return False
441
+
442
+ names = []
443
+ auto_keywords = getattr(instance, 'ROBOT_AUTO_KEYWORDS', True)
444
+ excluded_names = self.excluded_names
445
+ for name in dir(instance):
446
+ if not auto_keywords:
447
+ if not explicitly_included(name):
448
+ continue
449
+ elif name[:1] == '_':
450
+ if not explicitly_included(name):
451
+ continue
452
+ elif excluded_names is not None:
453
+ if name not in excluded_names:
454
+ continue
455
+ names.append(name)
456
+ return names
457
+
458
+ def _create_keyword(self, instance, name) -> 'StaticKeyword|None':
459
+ if self.avoid_properties:
460
+ candidate = inspect.getattr_static(instance, name)
461
+ self._pre_validate_method(candidate)
462
+ try:
463
+ method = getattr(instance, name)
464
+ except Exception:
465
+ message, details = get_error_details()
466
+ raise DataError(f'Getting handler method failed: {message}', details)
467
+ self._validate_method(method)
468
+ try:
469
+ return StaticKeyword.from_name(name, self.library)
470
+ except DataError as err:
471
+ self._adding_keyword_failed(name, err)
472
+
473
+ def _pre_validate_method(self, candidate):
474
+ if isinstance(candidate, classmethod):
475
+ candidate = candidate.__func__
476
+ if isinstance(candidate, cached_property) or not inspect.isroutine(candidate):
477
+ raise DataError('Not a method or function.')
478
+
479
+ def _validate_method(self, candidate):
480
+ if not (inspect.isroutine(candidate) or isinstance(candidate, partial)):
481
+ raise DataError('Not a method or function.')
482
+ if getattr(candidate, 'robot_not_keyword', False):
483
+ raise DataError('Not exposed as a keyword.')
484
+
485
+
486
+ class DynamicKeywordCreator(KeywordCreator):
487
+ library: DynamicLibrary
488
+
489
+ def __init__(self, library: 'DynamicLibrary|HybridLibrary'):
490
+ super().__init__(library, getting_method_failed_level='ERROR')
491
+
492
+ def get_keyword_names(self) -> 'list[str]':
493
+ try:
494
+ return GetKeywordNames(self.library.instance)()
495
+ except DataError as err:
496
+ raise DataError(f"Getting keyword names from library '{self.library.name}' "
497
+ f"failed: {err}")
498
+
499
+ def _create_keyword(self, instance, name) -> DynamicKeyword:
500
+ return DynamicKeyword.from_name(name, self.library)