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,317 @@
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 collections.abc import Mapping, Sequence, Set
17
+ from datetime import date, datetime, timedelta
18
+ from decimal import Decimal
19
+ from enum import Enum
20
+ from pathlib import Path
21
+ from typing import Any, ForwardRef, get_type_hints, Literal, Union
22
+
23
+ from robot.conf import Languages, LanguagesLike
24
+ from robot.errors import DataError
25
+ from robot.utils import (has_args, is_union, NOT_SET, plural_or_not as s, setter,
26
+ SetterAwareType, type_name, type_repr, typeddict_types)
27
+
28
+ from ..context import EXECUTION_CONTEXTS
29
+ from .customconverters import CustomArgumentConverters
30
+ from .typeconverters import TypeConverter
31
+
32
+
33
+ TYPE_NAMES = {
34
+ '...': Ellipsis,
35
+ 'ellipsis': Ellipsis,
36
+ 'any': Any,
37
+ 'str': str,
38
+ 'string': str,
39
+ 'unicode': str,
40
+ 'bool': bool,
41
+ 'boolean': bool,
42
+ 'int': int,
43
+ 'integer': int,
44
+ 'long': int,
45
+ 'float': float,
46
+ 'double': float,
47
+ 'decimal': Decimal,
48
+ 'bytes': bytes,
49
+ 'bytearray': bytearray,
50
+ 'datetime': datetime,
51
+ 'date': date,
52
+ 'timedelta': timedelta,
53
+ 'path': Path,
54
+ 'none': type(None),
55
+ 'list': list,
56
+ 'sequence': list,
57
+ 'tuple': tuple,
58
+ 'dictionary': dict,
59
+ 'dict': dict,
60
+ 'mapping': dict,
61
+ 'map': dict,
62
+ 'set': set,
63
+ 'frozenset': frozenset,
64
+ 'union': Union,
65
+ 'literal': Literal
66
+ }
67
+ LITERAL_TYPES = (int, str, bytes, bool, Enum, type(None))
68
+
69
+
70
+ class TypeInfo(metaclass=SetterAwareType):
71
+ """Represents an argument type.
72
+
73
+ Normally created using the :meth:`from_type_hint` classmethod.
74
+ With unions and parametrized types, :attr:`nested` contains nested types.
75
+
76
+ Values can be converted according to this type info by using the
77
+ :meth:`convert` method.
78
+
79
+ Part of the public API starting from Robot Framework 7.0. In such usage
80
+ should be imported via the :mod:`robot.api` package.
81
+ """
82
+ is_typed_dict = False
83
+ __slots__ = ('name', 'type')
84
+
85
+ def __init__(self, name: 'str|None' = None,
86
+ type: Any = NOT_SET,
87
+ nested: 'Sequence[TypeInfo]|None' = None):
88
+ if type is NOT_SET:
89
+ type = TYPE_NAMES.get(name.lower()) if name else None
90
+ self.name = name
91
+ self.type = type
92
+ self.nested = nested
93
+
94
+ @setter
95
+ def nested(self, nested: 'Sequence[TypeInfo]') -> 'tuple[TypeInfo, ...]|None':
96
+ """Nested types as a tuple of ``TypeInfo`` objects.
97
+
98
+ Used with parameterized types and unions.
99
+ """
100
+ typ = self.type
101
+ if self.is_union:
102
+ self._validate_union(nested)
103
+ elif nested is None:
104
+ return None
105
+ elif typ is None:
106
+ return tuple(nested)
107
+ elif typ is Literal:
108
+ self._validate_literal(nested)
109
+ elif not isinstance(typ, type):
110
+ self._report_nested_error(nested)
111
+ elif issubclass(typ, tuple):
112
+ if nested[-1].type is Ellipsis:
113
+ self._validate_nested_count(nested, 2, 'Homogenous tuple', offset=-1)
114
+ elif issubclass(typ, Sequence) and not issubclass(typ, (str, bytes, bytearray)):
115
+ self._validate_nested_count(nested, 1)
116
+ elif issubclass(typ, Set):
117
+ self._validate_nested_count(nested, 1)
118
+ elif issubclass(typ, Mapping):
119
+ self._validate_nested_count(nested, 2)
120
+ elif typ in TYPE_NAMES.values():
121
+ self._report_nested_error(nested)
122
+ return tuple(nested)
123
+
124
+ def _validate_union(self, nested):
125
+ if not nested:
126
+ raise DataError('Union cannot be empty.')
127
+
128
+ def _validate_literal(self, nested):
129
+ if not nested:
130
+ raise DataError('Literal cannot be empty.')
131
+ for info in nested:
132
+ if not isinstance(info.type, LITERAL_TYPES):
133
+ raise DataError(f'Literal supports only integers, strings, bytes, '
134
+ f'Booleans, enums and None, value {info.name} is '
135
+ f'{type_name(info.type)}.')
136
+
137
+ def _validate_nested_count(self, nested, expected, kind=None, offset=0):
138
+ if len(nested) != expected:
139
+ self._report_nested_error(nested, expected, kind, offset)
140
+
141
+ def _report_nested_error(self, nested, expected=0, kind=None, offset=0):
142
+ expected += offset
143
+ actual = len(nested) + offset
144
+ args = ', '.join(str(n) for n in nested)
145
+ kind = kind or f"'{self.name}{'[]' if expected > 0 else ''}'"
146
+ if expected == 0:
147
+ raise DataError(f"{kind} does not accept parameters, "
148
+ f"'{self.name}[{args}]' has {actual}.")
149
+ raise DataError(f"{kind} requires exactly {expected} parameter{s(expected)}, "
150
+ f"'{self.name}[{args}]' has {actual}.")
151
+
152
+ @property
153
+ def is_union(self):
154
+ return self.name == 'Union'
155
+
156
+ @classmethod
157
+ def from_type_hint(cls, hint: Any) -> 'TypeInfo':
158
+ """Construct a ``TypeInfo`` based on a type hint.
159
+
160
+ The type hint can be in various different formats:
161
+
162
+ - an actual type such as ``int``
163
+ - a parameterized type such as ``list[int]``
164
+ - a union such as ``int | float``
165
+ - a string such as ``'int'``, ``'list[int]'`` or ``'int | float'``
166
+ - a ``TypedDict`` (represented as a :class:`TypedDictInfo`)
167
+ - a sequence of supported type hints to create a union from such as
168
+ ``[int, float]`` or ``('int', 'list[int]')``
169
+
170
+ In special cases, for example with dictionaries or sequences, using the
171
+ more specialized methods like :meth:`from_dict` or :meth:`from_sequence`
172
+ may be more appropriate than using this generic method.
173
+ """
174
+ if hint is NOT_SET:
175
+ return cls()
176
+ if isinstance(hint, ForwardRef):
177
+ hint = hint.__forward_arg__
178
+ if isinstance(hint, typeddict_types):
179
+ return TypedDictInfo(hint.__name__, hint)
180
+ if is_union(hint):
181
+ nested = [cls.from_type_hint(a) for a in hint.__args__]
182
+ return cls('Union', nested=nested)
183
+ if hasattr(hint, '__origin__'):
184
+ if hint.__origin__ is Literal:
185
+ nested = [cls(repr(a) if not isinstance(a, Enum) else a.name, a)
186
+ for a in hint.__args__]
187
+ elif has_args(hint):
188
+ nested = [cls.from_type_hint(a) for a in hint.__args__]
189
+ else:
190
+ nested = None
191
+ return cls(type_repr(hint, nested=False), hint.__origin__, nested)
192
+ if isinstance(hint, str):
193
+ return cls.from_string(hint)
194
+ if isinstance(hint, (tuple, list)):
195
+ return cls.from_sequence(hint)
196
+ if isinstance(hint, type):
197
+ return cls(type_repr(hint), hint)
198
+ if hint is None:
199
+ return cls('None', type(None))
200
+ if hint is Union: # Plain `Union` without params.
201
+ return cls('Union')
202
+ if hint is Any:
203
+ return cls('Any', hint)
204
+ if hint is Ellipsis:
205
+ return cls('...', hint)
206
+ return cls(str(hint))
207
+
208
+ @classmethod
209
+ def from_type(cls, hint: type) -> 'TypeInfo':
210
+ """Construct a ``TypeInfo`` based on an actual type.
211
+
212
+ Use :meth:`from_type_hint` if the type hint can also be something else
213
+ than a concrete type such as a string.
214
+ """
215
+ return cls(type_repr(hint), hint)
216
+
217
+ @classmethod
218
+ def from_string(cls, hint: str) -> 'TypeInfo':
219
+ """Construct a ``TypeInfo`` based on a string.
220
+
221
+ In addition to just types names or their aliases like ``int`` or ``integer``,
222
+ supports also parameterized types like ``list[int]`` as well as unions like
223
+ ``int | float``.
224
+
225
+ Use :meth:`from_type_hint` if the type hint can also be something else
226
+ than a string such as an actual type.
227
+ """
228
+ # Needs to be imported here due to cyclic dependency.
229
+ from .typeinfoparser import TypeInfoParser
230
+ try:
231
+ return TypeInfoParser(hint).parse()
232
+ except ValueError as err:
233
+ raise DataError(str(err))
234
+
235
+ @classmethod
236
+ def from_sequence(cls, sequence: 'tuple|list') -> 'TypeInfo':
237
+ """Construct a ``TypeInfo`` based on a sequence of types.
238
+
239
+ Types can be actual types, strings, or anything else accepted by
240
+ :meth:`from_type_hint`. If the sequence contains just one type,
241
+ a ``TypeInfo`` created based on it is returned. If there are more
242
+ types, the returned ``TypeInfo`` represents a union. Using an empty
243
+ sequence is an error.
244
+
245
+ Use :meth:`from_type_hint` if other types than sequences need to
246
+ supported.
247
+ """
248
+ infos = []
249
+ for typ in sequence:
250
+ info = cls.from_type_hint(typ)
251
+ if info.is_union:
252
+ infos.extend(info.nested)
253
+ else:
254
+ infos.append(info)
255
+ if len(infos) == 1:
256
+ return infos[0]
257
+ return cls('Union', nested=infos)
258
+
259
+ def convert(self, value: Any,
260
+ name: 'str|None' = None,
261
+ custom_converters: 'CustomArgumentConverters|dict|None' = None,
262
+ languages: 'LanguagesLike' = None,
263
+ kind: str = 'Argument'):
264
+ """Convert ``value`` based on type information this ``TypeInfo`` contains.
265
+
266
+ :param value: Value to convert.
267
+ :param name: Name of the argument or other thing to convert.
268
+ Used only for error reporting.
269
+ :param custom_converters: Custom argument converters.
270
+ :param languages: Language configuration. During execution, uses the
271
+ current language configuration by default.
272
+ :param kind: Type of the thing to be converted.
273
+ Used only for error reporting.
274
+ :raises: ``TypeError`` if there is no converter for this type or
275
+ ``ValueError`` is conversion fails.
276
+ :return: Converted value.
277
+ """
278
+ if isinstance(custom_converters, dict):
279
+ custom_converters = CustomArgumentConverters.from_dict(custom_converters)
280
+ if not languages and EXECUTION_CONTEXTS.current:
281
+ languages = EXECUTION_CONTEXTS.current.languages
282
+ elif not isinstance(languages, Languages):
283
+ languages = Languages(languages)
284
+ converter = TypeConverter.converter_for(self, custom_converters, languages)
285
+ if not converter:
286
+ raise TypeError(f"No converter found for '{self}'.")
287
+ return converter.convert(value, name, kind)
288
+
289
+ def __str__(self):
290
+ if self.is_union:
291
+ return ' | '.join(str(n) for n in self.nested)
292
+ name = self.name or ''
293
+ if self.nested is None:
294
+ return name
295
+ nested = ', '.join(str(n) for n in self.nested)
296
+ return f'{name}[{nested}]'
297
+
298
+ def __bool__(self):
299
+ return self.name is not None
300
+
301
+
302
+ class TypedDictInfo(TypeInfo):
303
+ """Represents ``TypedDict`` used as an argument."""
304
+
305
+ is_typed_dict = True
306
+ __slots__ = ('annotations', 'required')
307
+
308
+ def __init__(self, name: str, type: type):
309
+ super().__init__(name, type)
310
+ try:
311
+ type_hints = get_type_hints(type)
312
+ except Exception:
313
+ type_hints = type.__annotations__
314
+ self.annotations = {name: TypeInfo.from_type_hint(hint)
315
+ for name, hint in type_hints.items()}
316
+ # __required_keys__ is new in Python 3.9.
317
+ self.required = getattr(type, '__required_keys__', frozenset())
@@ -0,0 +1,219 @@
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 ast import literal_eval
17
+ from enum import auto, Enum
18
+ from dataclasses import dataclass
19
+ from typing import Literal
20
+
21
+ from .typeinfo import LITERAL_TYPES, TypeInfo
22
+
23
+
24
+ class TokenType(Enum):
25
+ NAME = auto()
26
+ LEFT_SQUARE = auto()
27
+ RIGHT_SQUARE = auto()
28
+ PIPE = auto()
29
+ COMMA = auto()
30
+
31
+ def __repr__(self):
32
+ return str(self)
33
+
34
+
35
+ @dataclass
36
+ class Token:
37
+ type: TokenType
38
+ value: str
39
+ position: int = -1
40
+
41
+
42
+ class TypeInfoTokenizer:
43
+ markers = {
44
+ '[': TokenType.LEFT_SQUARE,
45
+ ']': TokenType.RIGHT_SQUARE,
46
+ '|': TokenType.PIPE,
47
+ ',': TokenType.COMMA,
48
+ }
49
+
50
+ def __init__(self, source: str):
51
+ self.source = source
52
+ self.tokens: 'list[Token]' = []
53
+ self.start = 0
54
+ self.current = 0
55
+
56
+ @property
57
+ def at_end(self) -> bool:
58
+ return self.current >= len(self.source)
59
+
60
+ def tokenize(self) -> 'list[Token]':
61
+ while not self.at_end:
62
+ self.start = self.current
63
+ char = self.advance()
64
+ if char in self.markers:
65
+ self.add_token(self.markers[char])
66
+ elif char.strip():
67
+ self.name()
68
+ return self.tokens
69
+
70
+ def advance(self) -> str:
71
+ char = self.source[self.current]
72
+ self.current += 1
73
+ return char
74
+
75
+ def peek(self) -> 'str|None':
76
+ try:
77
+ return self.source[self.current]
78
+ except IndexError:
79
+ return None
80
+
81
+ def name(self):
82
+ end_at = set(self.markers) | {None}
83
+ closing_quote = None
84
+ char = self.source[self.current-1]
85
+ if char in ('"', "'"):
86
+ end_at = {None}
87
+ closing_quote = char
88
+ elif char == 'b' and self.peek() in ('"', "'"):
89
+ end_at = {None}
90
+ closing_quote = self.advance()
91
+ while True:
92
+ char = self.peek()
93
+ if char in end_at:
94
+ break
95
+ self.current += 1
96
+ if char == closing_quote:
97
+ break
98
+ self.add_token(TokenType.NAME)
99
+
100
+ def add_token(self, type: TokenType):
101
+ value = self.source[self.start:self.current].strip()
102
+ self.tokens.append(Token(type, value, self.start))
103
+
104
+
105
+ class TypeInfoParser:
106
+
107
+ def __init__(self, source: str):
108
+ self.source = source
109
+ self.tokens: 'list[Token]' = []
110
+ self.current = 0
111
+
112
+ @property
113
+ def at_end(self) -> bool:
114
+ return self.peek() is None
115
+
116
+ def parse(self) -> TypeInfo:
117
+ self.tokens = TypeInfoTokenizer(self.source).tokenize()
118
+ info = self.type()
119
+ if not self.at_end:
120
+ self.error(f"Extra content after '{info}'.")
121
+ return info
122
+
123
+ def type(self) -> TypeInfo:
124
+ if not self.check(TokenType.NAME):
125
+ self.error('Type name missing.')
126
+ info = TypeInfo(self.advance().value)
127
+ if self.match(TokenType.LEFT_SQUARE):
128
+ info.nested = self.params(literal=info.type is Literal)
129
+ if self.match(TokenType.PIPE):
130
+ nested = [info] + self.union()
131
+ info = TypeInfo('Union', nested=nested)
132
+ return info
133
+
134
+ def params(self, literal: bool = False) -> 'list[TypeInfo]':
135
+ params = []
136
+ prev = None
137
+ while True:
138
+ token = self.peek()
139
+ if not token:
140
+ self.error("Closing ']' missing.")
141
+ if token.type is TokenType.RIGHT_SQUARE:
142
+ self.advance()
143
+ break
144
+ if token.type is TokenType.COMMA:
145
+ if not prev or prev.type is TokenType.COMMA:
146
+ self.error("Type missing before ','.")
147
+ self.advance()
148
+ prev = token
149
+ continue
150
+ if token.type is TokenType.NAME:
151
+ param = self.type()
152
+ elif token.type is TokenType.LEFT_SQUARE:
153
+ self.advance()
154
+ param = TypeInfo()
155
+ param.nested = self.params()
156
+ if literal:
157
+ param = self._literal_param(param)
158
+ params.append(param)
159
+ prev = token
160
+ if literal and not params:
161
+ self.error('Literal cannot be empty.')
162
+ return params
163
+
164
+ def _literal_param(self, param: TypeInfo) -> TypeInfo:
165
+ try:
166
+ if param.name is None:
167
+ raise ValueError
168
+ try:
169
+ value = literal_eval(param.name)
170
+ except ValueError:
171
+ if param.name.isidentifier():
172
+ return TypeInfo(param.name, None)
173
+ raise
174
+ if not isinstance(value, LITERAL_TYPES):
175
+ raise ValueError
176
+ except (ValueError, SyntaxError):
177
+ self.error(f"Invalid literal value {str(param)!r}.")
178
+ else:
179
+ return TypeInfo(repr(value), value)
180
+
181
+ def union(self) -> 'list[TypeInfo]':
182
+ types = []
183
+ while not types or self.match(TokenType.PIPE):
184
+ info = self.type()
185
+ if info.is_union:
186
+ types.extend(info.nested)
187
+ else:
188
+ types.append(info)
189
+ return types
190
+
191
+ def match(self, *types: TokenType) -> bool:
192
+ for typ in types:
193
+ if self.check(typ):
194
+ self.advance()
195
+ return True
196
+ return False
197
+
198
+ def check(self, expected: TokenType) -> bool:
199
+ peeked = self.peek()
200
+ return peeked and peeked.type == expected
201
+
202
+ def advance(self) -> 'Token|None':
203
+ token = self.peek()
204
+ if token:
205
+ self.current += 1
206
+ return token
207
+
208
+ def peek(self) -> 'Token|None':
209
+ try:
210
+ return self.tokens[self.current]
211
+ except IndexError:
212
+ return None
213
+
214
+ def error(self, message: str, token: 'Token|None' = None):
215
+ if not token:
216
+ token = self.peek()
217
+ position = f'index {token.position}' if token else 'end'
218
+ raise ValueError(f"Parsing type {self.source!r} failed: "
219
+ f"Error at {position}: {message}")
@@ -0,0 +1,60 @@
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 collections.abc import Mapping, Sequence
17
+ from typing import TYPE_CHECKING
18
+
19
+ from robot.errors import DataError
20
+ from robot.utils import (is_dict_like, is_list_like, plural_or_not as s,
21
+ seq2str, type_name)
22
+
23
+ from .typeinfo import TypeInfo
24
+
25
+ if TYPE_CHECKING:
26
+ from .argumentspec import ArgumentSpec
27
+
28
+
29
+ class TypeValidator:
30
+
31
+ def __init__(self, spec: 'ArgumentSpec'):
32
+ self.spec = spec
33
+
34
+ def validate(self, types: 'Mapping|Sequence|None') -> 'dict[str, TypeInfo]|None':
35
+ if types is None:
36
+ return None
37
+ if not types:
38
+ return {}
39
+ if is_dict_like(types):
40
+ self._validate_type_dict(types)
41
+ elif is_list_like(types):
42
+ types = self._type_list_to_dict(types)
43
+ else:
44
+ raise DataError(f'Type information must be given as a dictionary or '
45
+ f'a list, got {type_name(types)}.')
46
+ return {k: TypeInfo.from_type_hint(types[k]) for k in types}
47
+
48
+ def _validate_type_dict(self, types: Mapping):
49
+ names = set(self.spec.argument_names)
50
+ extra = [t for t in types if t not in names]
51
+ if extra:
52
+ raise DataError(f'Type information given to non-existing '
53
+ f'argument{s(extra)} {seq2str(sorted(extra))}.')
54
+
55
+ def _type_list_to_dict(self, types: Sequence) -> dict:
56
+ names = self.spec.argument_names
57
+ if len(types) > len(names):
58
+ raise DataError(f'Type information given to {len(types)} argument{s(types)} '
59
+ f'but keyword has only {len(names)} argument{s(names)}.')
60
+ return {name: value for name, value in zip(names, types) if value}