robotframework 7.0rc2__zip → 7.0.1__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 (280) hide show
  1. {robotframework-7.0rc2 → robotframework-7.0.1}/INSTALL.rst +35 -35
  2. {robotframework-7.0rc2/src/robotframework.egg-info → robotframework-7.0.1}/PKG-INFO +5 -3
  3. {robotframework-7.0rc2 → robotframework-7.0.1}/README.rst +3 -1
  4. {robotframework-7.0rc2 → robotframework-7.0.1}/setup.py +1 -1
  5. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/api/interfaces.py +14 -10
  6. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/conf/languages.py +45 -0
  7. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/htmldata/rebot/common.css +17 -0
  8. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/htmldata/rebot/log.html +0 -26
  9. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/libdocpkg/jsonbuilder.py +1 -1
  10. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/libdocpkg/model.py +1 -1
  11. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/libdocpkg/robotbuilder.py +1 -1
  12. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/libdocpkg/xmlbuilder.py +1 -1
  13. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/libraries/BuiltIn.py +8 -4
  14. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/libraries/Collections.py +5 -3
  15. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/libraries/String.py +2 -2
  16. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/libraries/XML.py +2 -7
  17. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/libraries/dialogs_py.py +3 -4
  18. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/model/__init__.py +1 -1
  19. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/model/configurer.py +1 -1
  20. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/model/filter.py +9 -9
  21. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/model/keyword.py +2 -9
  22. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/output/xmllogger.py +3 -1
  23. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/reporting/logreportwriters.py +1 -1
  24. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/result/model.py +2 -27
  25. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/running/__init__.py +7 -0
  26. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/running/arguments/argumentresolver.py +7 -15
  27. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/running/arguments/typeconverters.py +11 -1
  28. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/running/arguments/typeinfo.py +48 -16
  29. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/running/arguments/typeinfoparser.py +48 -28
  30. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/running/bodyrunner.py +1 -1
  31. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/running/builder/transformers.py +3 -3
  32. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/running/invalidkeyword.py +5 -0
  33. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/running/librarykeyword.py +3 -3
  34. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/running/model.py +32 -28
  35. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/running/namespace.py +4 -0
  36. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/running/resourcemodel.py +1 -1
  37. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/running/timeouts/__init__.py +6 -2
  38. robotframework-7.0.1/src/robot/running/timeouts/nosupport.py +25 -0
  39. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/running/userkeywordrunner.py +2 -0
  40. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/utils/__init__.py +1 -1
  41. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/utils/misc.py +1 -2
  42. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/utils/notset.py +2 -3
  43. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/version.py +1 -1
  44. {robotframework-7.0rc2 → robotframework-7.0.1/src/robotframework.egg-info}/PKG-INFO +5 -3
  45. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robotframework.egg-info/SOURCES.txt +1 -0
  46. {robotframework-7.0rc2 → robotframework-7.0.1}/AUTHORS.rst +0 -0
  47. {robotframework-7.0rc2 → robotframework-7.0.1}/BUILD.rst +0 -0
  48. {robotframework-7.0rc2 → robotframework-7.0.1}/CONTRIBUTING.rst +0 -0
  49. {robotframework-7.0rc2 → robotframework-7.0.1}/COPYRIGHT.txt +0 -0
  50. {robotframework-7.0rc2 → robotframework-7.0.1}/LICENSE.txt +0 -0
  51. {robotframework-7.0rc2 → robotframework-7.0.1}/MANIFEST.in +0 -0
  52. {robotframework-7.0rc2 → robotframework-7.0.1}/setup.cfg +0 -0
  53. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/__init__.py +0 -0
  54. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/__main__.py +0 -0
  55. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/api/__init__.py +0 -0
  56. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/api/deco.py +0 -0
  57. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/api/exceptions.py +0 -0
  58. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/api/logger.py +0 -0
  59. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/api/parsing.py +0 -0
  60. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/api/py.typed +0 -0
  61. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/conf/__init__.py +0 -0
  62. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/conf/gatherfailed.py +0 -0
  63. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/conf/settings.py +0 -0
  64. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/errors.py +0 -0
  65. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/htmldata/__init__.py +0 -0
  66. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/htmldata/common/__init__.py +0 -0
  67. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/htmldata/common/js_disabled.css +0 -0
  68. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/htmldata/common/storage.js +0 -0
  69. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/htmldata/htmlfilewriter.py +0 -0
  70. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/htmldata/jsonwriter.py +0 -0
  71. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/htmldata/lib/__init__.py +0 -0
  72. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/htmldata/lib/jquery.highlight.min.js +0 -0
  73. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/htmldata/lib/jquery.min.js +0 -0
  74. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/htmldata/lib/jquery.tablesorter.min.js +0 -0
  75. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/htmldata/lib/jquery.tmpl.min.js +0 -0
  76. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/htmldata/lib/jsxcompressor.min.js +0 -0
  77. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/htmldata/libdoc/__init__.py +0 -0
  78. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/htmldata/libdoc/doc_formatting.css +0 -0
  79. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/htmldata/libdoc/libdoc.css +0 -0
  80. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/htmldata/libdoc/libdoc.html +0 -0
  81. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/htmldata/libdoc/print.css +0 -0
  82. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/htmldata/libdoc/pygments.css +0 -0
  83. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/htmldata/rebot/__init__.py +0 -0
  84. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/htmldata/rebot/doc_formatting.css +0 -0
  85. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/htmldata/rebot/fileloading.js +0 -0
  86. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/htmldata/rebot/log.css +0 -0
  87. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/htmldata/rebot/log.js +0 -0
  88. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/htmldata/rebot/model.js +0 -0
  89. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/htmldata/rebot/print.css +0 -0
  90. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/htmldata/rebot/report.css +0 -0
  91. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/htmldata/rebot/report.html +0 -0
  92. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/htmldata/rebot/testdata.js +0 -0
  93. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/htmldata/rebot/util.js +0 -0
  94. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/htmldata/rebot/view.js +0 -0
  95. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/htmldata/template.py +0 -0
  96. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/htmldata/testdoc/__init__.py +0 -0
  97. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/htmldata/testdoc/testdoc.css +0 -0
  98. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/htmldata/testdoc/testdoc.html +0 -0
  99. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/libdoc.py +0 -0
  100. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/libdocpkg/__init__.py +0 -0
  101. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/libdocpkg/builder.py +0 -0
  102. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/libdocpkg/consoleviewer.py +0 -0
  103. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/libdocpkg/datatypes.py +0 -0
  104. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/libdocpkg/htmlutils.py +0 -0
  105. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/libdocpkg/htmlwriter.py +0 -0
  106. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/libdocpkg/jsonwriter.py +0 -0
  107. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/libdocpkg/output.py +0 -0
  108. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/libdocpkg/standardtypes.py +0 -0
  109. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/libdocpkg/writer.py +0 -0
  110. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/libdocpkg/xmlwriter.py +0 -0
  111. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/libraries/DateTime.py +0 -0
  112. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/libraries/Dialogs.py +0 -0
  113. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/libraries/Easter.py +0 -0
  114. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/libraries/OperatingSystem.py +0 -0
  115. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/libraries/Process.py +0 -0
  116. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/libraries/Remote.py +0 -0
  117. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/libraries/Screenshot.py +0 -0
  118. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/libraries/Telnet.py +0 -0
  119. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/libraries/__init__.py +0 -0
  120. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/model/body.py +0 -0
  121. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/model/control.py +0 -0
  122. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/model/fixture.py +0 -0
  123. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/model/itemlist.py +0 -0
  124. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/model/message.py +0 -0
  125. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/model/metadata.py +0 -0
  126. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/model/modelobject.py +0 -0
  127. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/model/modifier.py +0 -0
  128. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/model/namepatterns.py +0 -0
  129. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/model/statistics.py +0 -0
  130. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/model/stats.py +0 -0
  131. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/model/suitestatistics.py +0 -0
  132. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/model/tags.py +0 -0
  133. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/model/tagsetter.py +0 -0
  134. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/model/tagstatistics.py +0 -0
  135. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/model/testcase.py +0 -0
  136. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/model/testsuite.py +0 -0
  137. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/model/totalstatistics.py +0 -0
  138. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/model/visitor.py +0 -0
  139. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/output/__init__.py +0 -0
  140. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/output/console/__init__.py +0 -0
  141. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/output/console/dotted.py +0 -0
  142. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/output/console/highlighting.py +0 -0
  143. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/output/console/quiet.py +0 -0
  144. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/output/console/verbose.py +0 -0
  145. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/output/debugfile.py +0 -0
  146. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/output/filelogger.py +0 -0
  147. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/output/librarylogger.py +0 -0
  148. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/output/listeners.py +0 -0
  149. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/output/logger.py +0 -0
  150. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/output/loggerapi.py +0 -0
  151. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/output/loggerhelper.py +0 -0
  152. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/output/output.py +0 -0
  153. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/output/pyloggingconf.py +0 -0
  154. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/output/stdoutlogsplitter.py +0 -0
  155. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/parsing/__init__.py +0 -0
  156. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/parsing/lexer/__init__.py +0 -0
  157. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/parsing/lexer/blocklexers.py +0 -0
  158. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/parsing/lexer/context.py +0 -0
  159. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/parsing/lexer/lexer.py +0 -0
  160. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/parsing/lexer/settings.py +0 -0
  161. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/parsing/lexer/statementlexers.py +0 -0
  162. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/parsing/lexer/tokenizer.py +0 -0
  163. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/parsing/lexer/tokens.py +0 -0
  164. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/parsing/model/__init__.py +0 -0
  165. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/parsing/model/blocks.py +0 -0
  166. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/parsing/model/statements.py +0 -0
  167. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/parsing/model/visitor.py +0 -0
  168. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/parsing/parser/__init__.py +0 -0
  169. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/parsing/parser/blockparsers.py +0 -0
  170. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/parsing/parser/fileparser.py +0 -0
  171. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/parsing/parser/parser.py +0 -0
  172. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/parsing/suitestructure.py +0 -0
  173. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/pythonpathsetter.py +0 -0
  174. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/rebot.py +0 -0
  175. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/reporting/__init__.py +0 -0
  176. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/reporting/expandkeywordmatcher.py +0 -0
  177. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/reporting/jsbuildingcontext.py +0 -0
  178. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/reporting/jsexecutionresult.py +0 -0
  179. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/reporting/jsmodelbuilders.py +0 -0
  180. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/reporting/jswriter.py +0 -0
  181. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/reporting/outputwriter.py +0 -0
  182. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/reporting/resultwriter.py +0 -0
  183. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/reporting/stringcache.py +0 -0
  184. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/reporting/xunitwriter.py +0 -0
  185. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/result/__init__.py +0 -0
  186. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/result/configurer.py +0 -0
  187. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/result/executionerrors.py +0 -0
  188. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/result/executionresult.py +0 -0
  189. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/result/flattenkeywordmatcher.py +0 -0
  190. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/result/keywordremover.py +0 -0
  191. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/result/merger.py +0 -0
  192. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/result/messagefilter.py +0 -0
  193. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/result/modeldeprecation.py +0 -0
  194. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/result/resultbuilder.py +0 -0
  195. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/result/suiteteardownfailed.py +0 -0
  196. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/result/visitor.py +0 -0
  197. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/result/xmlelementhandlers.py +0 -0
  198. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/run.py +0 -0
  199. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/running/arguments/__init__.py +0 -0
  200. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/running/arguments/argumentconverter.py +0 -0
  201. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/running/arguments/argumentmapper.py +0 -0
  202. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/running/arguments/argumentparser.py +0 -0
  203. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/running/arguments/argumentspec.py +0 -0
  204. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/running/arguments/argumentvalidator.py +0 -0
  205. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/running/arguments/customconverters.py +0 -0
  206. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/running/arguments/embedded.py +0 -0
  207. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/running/arguments/typevalidator.py +0 -0
  208. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/running/builder/__init__.py +0 -0
  209. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/running/builder/builders.py +0 -0
  210. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/running/builder/parsers.py +0 -0
  211. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/running/builder/settings.py +0 -0
  212. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/running/context.py +0 -0
  213. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/running/dynamicmethods.py +0 -0
  214. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/running/importer.py +0 -0
  215. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/running/keywordfinder.py +0 -0
  216. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/running/keywordimplementation.py +0 -0
  217. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/running/librarykeywordrunner.py +0 -0
  218. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/running/libraryscopes.py +0 -0
  219. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/running/outputcapture.py +0 -0
  220. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/running/randomizer.py +0 -0
  221. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/running/runkwregister.py +0 -0
  222. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/running/signalhandler.py +0 -0
  223. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/running/status.py +0 -0
  224. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/running/statusreporter.py +0 -0
  225. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/running/suiterunner.py +0 -0
  226. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/running/testlibraries.py +0 -0
  227. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/running/timeouts/posix.py +0 -0
  228. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/running/timeouts/windows.py +0 -0
  229. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/testdoc.py +0 -0
  230. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/utils/application.py +0 -0
  231. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/utils/argumentparser.py +0 -0
  232. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/utils/asserts.py +0 -0
  233. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/utils/charwidth.py +0 -0
  234. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/utils/compress.py +0 -0
  235. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/utils/connectioncache.py +0 -0
  236. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/utils/dotdict.py +0 -0
  237. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/utils/encoding.py +0 -0
  238. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/utils/encodingsniffer.py +0 -0
  239. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/utils/error.py +0 -0
  240. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/utils/escaping.py +0 -0
  241. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/utils/etreewrapper.py +0 -0
  242. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/utils/filereader.py +0 -0
  243. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/utils/frange.py +0 -0
  244. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/utils/htmlformatters.py +0 -0
  245. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/utils/importer.py +0 -0
  246. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/utils/markuputils.py +0 -0
  247. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/utils/markupwriters.py +0 -0
  248. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/utils/match.py +0 -0
  249. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/utils/normalizing.py +0 -0
  250. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/utils/platform.py +0 -0
  251. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/utils/recommendations.py +0 -0
  252. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/utils/restreader.py +0 -0
  253. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/utils/robotenv.py +0 -0
  254. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/utils/robotinspect.py +0 -0
  255. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/utils/robotio.py +0 -0
  256. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/utils/robotpath.py +0 -0
  257. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/utils/robottime.py +0 -0
  258. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/utils/robottypes.py +0 -0
  259. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/utils/setter.py +0 -0
  260. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/utils/sortable.py +0 -0
  261. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/utils/text.py +0 -0
  262. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/utils/typehints.py +0 -0
  263. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/utils/unic.py +0 -0
  264. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/variables/__init__.py +0 -0
  265. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/variables/assigner.py +0 -0
  266. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/variables/evaluation.py +0 -0
  267. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/variables/filesetter.py +0 -0
  268. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/variables/finders.py +0 -0
  269. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/variables/notfound.py +0 -0
  270. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/variables/replacer.py +0 -0
  271. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/variables/resolvable.py +0 -0
  272. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/variables/scopes.py +0 -0
  273. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/variables/search.py +0 -0
  274. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/variables/store.py +0 -0
  275. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/variables/tablesetter.py +0 -0
  276. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robot/variables/variables.py +0 -0
  277. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robotframework.egg-info/dependency_links.txt +0 -0
  278. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robotframework.egg-info/entry_points.txt +0 -0
  279. {robotframework-7.0rc2 → robotframework-7.0.1}/src/robotframework.egg-info/top_level.txt +0 -0
  280. {robotframework-7.0rc2 → robotframework-7.0.1}/tasks.py +0 -0
@@ -13,7 +13,7 @@
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, Dict, List, Sequence, Tuple, TYPE_CHECKING, Union
16
+ from typing import Sequence, TYPE_CHECKING
17
17
 
18
18
  from .body import Body, BodyItem, BodyItemParent
19
19
  from .modelobject import DataDict
@@ -22,25 +22,18 @@ if TYPE_CHECKING:
22
22
  from .visitor import SuiteVisitor
23
23
 
24
24
 
25
- Arguments = Union[Sequence[Union[Any, Tuple[Any], Tuple[str, Any]]],
26
- Tuple[List[Any], Dict[str, Any]]]
27
-
28
-
29
25
  @Body.register
30
26
  class Keyword(BodyItem):
31
27
  """Base model for a single keyword.
32
28
 
33
29
  Extended by :class:`robot.running.model.Keyword` and
34
30
  :class:`robot.result.model.Keyword`.
35
-
36
- Arguments from normal data are always strings, but other types are possible in
37
- programmatic usage. See the docstrings of the extending classes for more details.
38
31
  """
39
32
  repr_args = ('name', 'args', 'assign')
40
33
  __slots__ = ['name', 'args', 'assign', 'type']
41
34
 
42
35
  def __init__(self, name: 'str|None' = '',
43
- args: Arguments = (),
36
+ args: Sequence[str] = (),
44
37
  assign: Sequence[str] = (),
45
38
  type: str = BodyItem.KEYWORD,
46
39
  parent: BodyItemParent = None):
@@ -217,7 +217,7 @@ class XmlLogger(ResultVisitor):
217
217
  if self.flatten_level == 0:
218
218
  self._writer = self._xml_writer
219
219
  self._write_list('var', kw.assign)
220
- self._write_list('arg', kw.args)
220
+ self._write_list('arg', [str(a) for a in kw.args])
221
221
  self._write_list('tag', kw.tags)
222
222
  self._writer.element('doc', kw.doc)
223
223
  if kw.timeout:
@@ -429,6 +429,8 @@ class LegacyXmlLogger(XmlLogger):
429
429
  'schemaversion': '4'}
430
430
 
431
431
  def _datetime_to_timestamp(self, dt):
432
+ if dt is None:
433
+ return None
432
434
  return dt.isoformat(' ', timespec='milliseconds').replace('-', '')
433
435
 
434
436
  def _get_start_keyword_attrs(self, kw):
@@ -56,7 +56,7 @@ class LogWriter(_LogReportWriter):
56
56
  def _write_split_log(self, index, keywords, strings, path: Path):
57
57
  with file_writer(path, usage=self.usage) as outfile:
58
58
  writer = SplitLogWriter(outfile)
59
- writer.write(keywords, strings, index, path.stem)
59
+ writer.write(keywords, strings, index, path.name)
60
60
 
61
61
 
62
62
  class ReportWriter(_LogReportWriter):
@@ -43,7 +43,7 @@ from typing import Literal, Mapping, overload, Sequence, Union, TextIO, TypeVar
43
43
  from robot import model
44
44
  from robot.model import (BodyItem, create_fixture, DataDict, Tags, TestSuites,
45
45
  TotalStatistics, TotalStatisticsBuilder)
46
- from robot.utils import is_dict_like, is_list_like, setter
46
+ from robot.utils import setter
47
47
 
48
48
  from .configurer import SuiteConfigurer
49
49
  from .messagefilter import MessageFilter
@@ -91,7 +91,6 @@ class Message(model.Message):
91
91
  return data
92
92
 
93
93
 
94
-
95
94
  class StatusMixin:
96
95
  PASS = 'PASS'
97
96
  FAIL = 'FAIL'
@@ -711,7 +710,7 @@ class Keyword(model.Keyword, StatusMixin):
711
710
  owner: 'str|None' = None,
712
711
  source_name: 'str|None' = None,
713
712
  doc: str = '',
714
- args: model.Arguments = (),
713
+ args: Sequence[str] = (),
715
714
  assign: Sequence[str] = (),
716
715
  tags: Sequence[str] = (),
717
716
  timeout: 'str|None' = None,
@@ -739,30 +738,6 @@ class Keyword(model.Keyword, StatusMixin):
739
738
  self._teardown = None
740
739
  self.body = ()
741
740
 
742
- @setter
743
- def args(self, args: model.Arguments) -> 'tuple[str, ...]':
744
- """Keyword arguments.
745
-
746
- Arguments originating from normal data are given as a list of strings.
747
- Programmatically it is possible to use also other types and named arguments
748
- can be specified using name-value tuples. Additionally, it is possible
749
- o give arguments directly as a list of positional arguments and a dictionary
750
- of named arguments. In all these cases arguments are stored as strings.
751
- """
752
- if len(args) == 2 and is_list_like(args[0]) and is_dict_like(args[1]):
753
- positional = [str(a) for a in args[0]]
754
- named = [f'{n}={v}' for n, v in args[1].items()]
755
- return tuple(positional + named)
756
- return tuple([a if isinstance(a, str) else self._arg_to_str(a) for a in args])
757
-
758
- def _arg_to_str(self, arg):
759
- if isinstance(arg, tuple):
760
- if len(arg) == 2:
761
- return f'{arg[0]}={arg[1]}'
762
- if len(arg) == 1:
763
- return str(arg[0])
764
- return str(arg)
765
-
766
741
  @setter
767
742
  def body(self, body: 'Sequence[BodyItem|DataDict]') -> Body:
768
743
  """Possible keyword body as a :class:`~.Body` object.
@@ -32,6 +32,12 @@ The public API of this module consists of the following objects:
32
32
  :mod:`robot.running.model` module. These classes are typically only needed
33
33
  in type hints.
34
34
 
35
+ * Keyword implementation related classes :class:`~robot.running.resourcemodel.UserKeyword`,
36
+ :class:`~robot.running.librarykeyword.LibraryKeyword`,
37
+ :class:`~robot.running.invalidkeyword.InvalidKeyword` and their common base class
38
+ :class:`~robot.running.keywordimplementation.KeywordImplementation`. Also these
39
+ classes are mainly needed in type hints.
40
+
35
41
  * :class:`~robot.running.builder.settings.TestDefaults` that is part of the
36
42
  `external parsing API`__ and also typically needed only in type hints.
37
43
 
@@ -43,6 +49,7 @@ the :mod:`robot.api` package.
43
49
 
44
50
  .. note:: Prior to Robot Framework 6.1, only some classes in
45
51
  :mod:`robot.running.model` were exposed via :mod:`robot.running`.
52
+ Keyword implementation related classes are new in Robot Framework 7.0.
46
53
 
47
54
  Examples
48
55
  --------
@@ -16,10 +16,11 @@
16
16
  from typing import TYPE_CHECKING
17
17
 
18
18
  from robot.errors import DataError
19
- from robot.utils import is_dict_like, is_list_like, split_from_equals
19
+ from robot.utils import is_dict_like, split_from_equals
20
20
  from robot.variables import is_dict_variable
21
21
 
22
22
  from .argumentvalidator import ArgumentValidator
23
+ from ..model import Argument
23
24
 
24
25
  if TYPE_CHECKING:
25
26
  from .argumentspec import ArgumentSpec
@@ -38,13 +39,9 @@ class ArgumentResolver:
38
39
  self.argument_validator = ArgumentValidator(spec)
39
40
 
40
41
  def resolve(self, arguments, variables=None):
41
- if len(arguments) == 2 and is_list_like(arguments[0]) and is_dict_like(arguments[1]):
42
- positional = list(arguments[0])
43
- named = list(arguments[1].items())
44
- else:
45
- positional, named = self.named_resolver.resolve(arguments, variables)
46
- positional, named = self.variable_replacer.replace(positional, named, variables)
47
- positional, named = self.dict_to_kwargs.handle(positional, named)
42
+ positional, named = self.named_resolver.resolve(arguments, variables)
43
+ positional, named = self.variable_replacer.replace(positional, named, variables)
44
+ positional, named = self.dict_to_kwargs.handle(positional, named)
48
45
  self.argument_validator.validate(positional, named, dryrun=variables is None)
49
46
  return positional, named
50
47
 
@@ -72,13 +69,8 @@ class NamedArgumentResolver:
72
69
  return positional, named
73
70
 
74
71
  def _split_named(self, arg, previous_named, variables, spec):
75
- if isinstance(arg, tuple):
76
- if len(arg) == 2 and isinstance(arg[0], str):
77
- return arg
78
- elif len(arg) == 1:
79
- return None, arg[0]
80
- else:
81
- return None, arg
72
+ if isinstance(arg, Argument):
73
+ return arg.name, arg.value
82
74
  name, value = split_from_equals(arg)
83
75
  if value is None or not self._is_named(name, previous_named, variables, spec):
84
76
  return None, arg
@@ -526,7 +526,17 @@ class TypedDictConverter(TypeConverter):
526
526
  return type_info.is_typed_dict
527
527
 
528
528
  def no_conversion_needed(self, value):
529
- return False
529
+ if not isinstance(value, Mapping):
530
+ return False
531
+ for key in value:
532
+ try:
533
+ converter = self.converters[key]
534
+ except KeyError:
535
+ return False
536
+ else:
537
+ if not converter.no_conversion_needed(value[key]):
538
+ return False
539
+ return set(value).issuperset(self.type_info.required)
530
540
 
531
541
  def _non_string_convert(self, value):
532
542
  return self._convert_items(value)
@@ -13,12 +13,20 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
 
16
+ import sys
16
17
  from collections.abc import Mapping, Sequence, Set
17
18
  from datetime import date, datetime, timedelta
18
19
  from decimal import Decimal
19
20
  from enum import Enum
20
21
  from pathlib import Path
21
- from typing import Any, ForwardRef, get_type_hints, Literal, Union
22
+ from typing import Any, ForwardRef, get_type_hints, get_origin, Literal, Union
23
+ if sys.version_info >= (3, 11):
24
+ from typing import NotRequired, Required
25
+ else:
26
+ try:
27
+ from typing_extensions import NotRequired, Required
28
+ except ImportError:
29
+ NotRequired = Required = object()
22
30
 
23
31
  from robot.conf import Languages, LanguagesLike
24
32
  from robot.errors import DataError
@@ -84,7 +92,7 @@ class TypeInfo(metaclass=SetterAwareType):
84
92
 
85
93
  def __init__(self, name: 'str|None' = None,
86
94
  type: Any = NOT_SET,
87
- nested: 'Sequence[TypeInfo]' = ()):
95
+ nested: 'Sequence[TypeInfo]|None' = None):
88
96
  if type is NOT_SET:
89
97
  type = TYPE_NAMES.get(name.lower()) if name else None
90
98
  self.name = name
@@ -92,7 +100,7 @@ class TypeInfo(metaclass=SetterAwareType):
92
100
  self.nested = nested
93
101
 
94
102
  @setter
95
- def nested(self, nested: 'Sequence[TypeInfo]') -> 'tuple[TypeInfo, ...]':
103
+ def nested(self, nested: 'Sequence[TypeInfo]') -> 'tuple[TypeInfo, ...]|None':
96
104
  """Nested types as a tuple of ``TypeInfo`` objects.
97
105
 
98
106
  Used with parameterized types and unions.
@@ -100,8 +108,10 @@ class TypeInfo(metaclass=SetterAwareType):
100
108
  typ = self.type
101
109
  if self.is_union:
102
110
  self._validate_union(nested)
103
- elif typ is None or not nested:
104
- pass
111
+ elif nested is None:
112
+ return None
113
+ elif typ is None:
114
+ return tuple(nested)
105
115
  elif typ is Literal:
106
116
  self._validate_literal(nested)
107
117
  elif not isinstance(typ, type):
@@ -124,6 +134,8 @@ class TypeInfo(metaclass=SetterAwareType):
124
134
  raise DataError('Union cannot be empty.')
125
135
 
126
136
  def _validate_literal(self, nested):
137
+ if not nested:
138
+ raise DataError('Literal cannot be empty.')
127
139
  for info in nested:
128
140
  if not isinstance(info.type, LITERAL_TYPES):
129
141
  raise DataError(f'Literal supports only integers, strings, bytes, '
@@ -183,7 +195,7 @@ class TypeInfo(metaclass=SetterAwareType):
183
195
  elif has_args(hint):
184
196
  nested = [cls.from_type_hint(a) for a in hint.__args__]
185
197
  else:
186
- nested = []
198
+ nested = None
187
199
  return cls(type_repr(hint, nested=False), hint.__origin__, nested)
188
200
  if isinstance(hint, str):
189
201
  return cls.from_string(hint)
@@ -285,10 +297,11 @@ class TypeInfo(metaclass=SetterAwareType):
285
297
  def __str__(self):
286
298
  if self.is_union:
287
299
  return ' | '.join(str(n) for n in self.nested)
288
- if self.nested:
289
- nested = ', '.join(str(n) for n in self.nested)
290
- return f'{self.name}[{nested}]'
291
- return self.name or ''
300
+ name = self.name or ''
301
+ if self.nested is None:
302
+ return name
303
+ nested = ', '.join(str(n) for n in self.nested)
304
+ return f'{name}[{nested}]'
292
305
 
293
306
  def __bool__(self):
294
307
  return self.name is not None
@@ -302,11 +315,30 @@ class TypedDictInfo(TypeInfo):
302
315
 
303
316
  def __init__(self, name: str, type: type):
304
317
  super().__init__(name, type)
305
- try:
306
- type_hints = get_type_hints(type)
307
- except Exception:
308
- type_hints = type.__annotations__
309
- self.annotations = {name: TypeInfo.from_type_hint(hint)
310
- for name, hint in type_hints.items()}
318
+ type_hints = self._get_type_hints(type)
311
319
  # __required_keys__ is new in Python 3.9.
312
320
  self.required = getattr(type, '__required_keys__', frozenset())
321
+ if sys.version_info < (3, 11):
322
+ self._handle_typing_extensions_required_and_not_required(type_hints)
323
+ self.annotations = {name: TypeInfo.from_type_hint(hint)
324
+ for name, hint in type_hints.items()}
325
+
326
+ def _get_type_hints(self, type) -> 'dict[str, Any]':
327
+ try:
328
+ return get_type_hints(type)
329
+ except Exception:
330
+ return type.__annotations__
331
+
332
+ def _handle_typing_extensions_required_and_not_required(self, type_hints):
333
+ # NotRequired and Required are handled automatically by Python 3.11 and newer,
334
+ # but with older they appear in type hints and need to be handled separately.
335
+ required = set(self.required)
336
+ for key, hint in type_hints.items():
337
+ origin = get_origin(hint)
338
+ if origin is Required:
339
+ required.add(key)
340
+ type_hints[key] = hint.__args__[0]
341
+ elif origin is NotRequired:
342
+ required.discard(key)
343
+ type_hints[key] = hint.__args__[0]
344
+ self.required = frozenset(required)
@@ -21,7 +21,7 @@ from typing import Literal
21
21
  from .typeinfo import LITERAL_TYPES, TypeInfo
22
22
 
23
23
 
24
- class TypeInfoTokenType(Enum):
24
+ class TokenType(Enum):
25
25
  NAME = auto()
26
26
  LEFT_SQUARE = auto()
27
27
  RIGHT_SQUARE = auto()
@@ -33,23 +33,23 @@ class TypeInfoTokenType(Enum):
33
33
 
34
34
 
35
35
  @dataclass
36
- class TypeInfoToken:
37
- type: TypeInfoTokenType
36
+ class Token:
37
+ type: TokenType
38
38
  value: str
39
39
  position: int = -1
40
40
 
41
41
 
42
42
  class TypeInfoTokenizer:
43
43
  markers = {
44
- '[': TypeInfoTokenType.LEFT_SQUARE,
45
- ']': TypeInfoTokenType.RIGHT_SQUARE,
46
- '|': TypeInfoTokenType.PIPE,
47
- ',': TypeInfoTokenType.COMMA,
44
+ '[': TokenType.LEFT_SQUARE,
45
+ ']': TokenType.RIGHT_SQUARE,
46
+ '|': TokenType.PIPE,
47
+ ',': TokenType.COMMA,
48
48
  }
49
49
 
50
50
  def __init__(self, source: str):
51
51
  self.source = source
52
- self.tokens: 'list[TypeInfoToken]' = []
52
+ self.tokens: 'list[Token]' = []
53
53
  self.start = 0
54
54
  self.current = 0
55
55
 
@@ -57,7 +57,7 @@ class TypeInfoTokenizer:
57
57
  def at_end(self) -> bool:
58
58
  return self.current >= len(self.source)
59
59
 
60
- def tokenize(self) -> 'list[TypeInfoToken]':
60
+ def tokenize(self) -> 'list[Token]':
61
61
  while not self.at_end:
62
62
  self.start = self.current
63
63
  char = self.advance()
@@ -95,18 +95,18 @@ class TypeInfoTokenizer:
95
95
  self.current += 1
96
96
  if char == closing_quote:
97
97
  break
98
- self.add_token(TypeInfoTokenType.NAME)
98
+ self.add_token(TokenType.NAME)
99
99
 
100
- def add_token(self, type: TypeInfoTokenType):
100
+ def add_token(self, type: TokenType):
101
101
  value = self.source[self.start:self.current].strip()
102
- self.tokens.append(TypeInfoToken(type, value, self.start))
102
+ self.tokens.append(Token(type, value, self.start))
103
103
 
104
104
 
105
105
  class TypeInfoParser:
106
106
 
107
107
  def __init__(self, source: str):
108
108
  self.source = source
109
- self.tokens: 'list[TypeInfoToken]' = []
109
+ self.tokens: 'list[Token]' = []
110
110
  self.current = 0
111
111
 
112
112
  @property
@@ -121,29 +121,50 @@ class TypeInfoParser:
121
121
  return info
122
122
 
123
123
  def type(self) -> TypeInfo:
124
- if not self.check(TypeInfoTokenType.NAME):
124
+ if not self.check(TokenType.NAME):
125
125
  self.error('Type name missing.')
126
126
  info = TypeInfo(self.advance().value)
127
- if self.match(TypeInfoTokenType.LEFT_SQUARE):
127
+ if self.match(TokenType.LEFT_SQUARE):
128
128
  info.nested = self.params(literal=info.type is Literal)
129
- if self.match(TypeInfoTokenType.PIPE):
129
+ if self.match(TokenType.PIPE):
130
130
  nested = [info] + self.union()
131
131
  info = TypeInfo('Union', nested=nested)
132
132
  return info
133
133
 
134
134
  def params(self, literal: bool = False) -> 'list[TypeInfo]':
135
135
  params = []
136
- while not params or self.match(TypeInfoTokenType.COMMA):
137
- param = self.type()
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()
138
156
  if literal:
139
157
  param = self._literal_param(param)
140
158
  params.append(param)
141
- if not self.match(TypeInfoTokenType.RIGHT_SQUARE):
142
- self.error("Closing ']' missing.")
159
+ prev = token
160
+ if literal and not params:
161
+ self.error('Literal cannot be empty.')
143
162
  return params
144
163
 
145
164
  def _literal_param(self, param: TypeInfo) -> TypeInfo:
146
165
  try:
166
+ if param.name is None:
167
+ raise ValueError
147
168
  try:
148
169
  value = literal_eval(param.name)
149
170
  except ValueError:
@@ -153,14 +174,13 @@ class TypeInfoParser:
153
174
  if not isinstance(value, LITERAL_TYPES):
154
175
  raise ValueError
155
176
  except (ValueError, SyntaxError):
156
- token = self.tokens[self.current-1]
157
- self.error(f"Invalid literal value {param.name!r}.", token)
177
+ self.error(f"Invalid literal value {str(param)!r}.")
158
178
  else:
159
179
  return TypeInfo(repr(value), value)
160
180
 
161
181
  def union(self) -> 'list[TypeInfo]':
162
182
  types = []
163
- while not types or self.match(TypeInfoTokenType.PIPE):
183
+ while not types or self.match(TokenType.PIPE):
164
184
  info = self.type()
165
185
  if info.is_union:
166
186
  types.extend(info.nested)
@@ -168,30 +188,30 @@ class TypeInfoParser:
168
188
  types.append(info)
169
189
  return types
170
190
 
171
- def match(self, *types: TypeInfoTokenType) -> bool:
191
+ def match(self, *types: TokenType) -> bool:
172
192
  for typ in types:
173
193
  if self.check(typ):
174
194
  self.advance()
175
195
  return True
176
196
  return False
177
197
 
178
- def check(self, expected: TypeInfoTokenType) -> bool:
198
+ def check(self, expected: TokenType) -> bool:
179
199
  peeked = self.peek()
180
200
  return peeked and peeked.type == expected
181
201
 
182
- def advance(self) -> 'TypeInfoToken|None':
202
+ def advance(self) -> 'Token|None':
183
203
  token = self.peek()
184
204
  if token:
185
205
  self.current += 1
186
206
  return token
187
207
 
188
- def peek(self) -> 'TypeInfoToken|None':
208
+ def peek(self) -> 'Token|None':
189
209
  try:
190
210
  return self.tokens[self.current]
191
211
  except IndexError:
192
212
  return None
193
213
 
194
- def error(self, message: str, token: 'TypeInfoToken|None' = None):
214
+ def error(self, message: str, token: 'Token|None' = None):
195
215
  if not token:
196
216
  token = self.peek()
197
217
  position = f'index {token.position}' if token else 'end'
@@ -68,7 +68,7 @@ class KeywordRunner:
68
68
 
69
69
  def run(self, data, result, name=None):
70
70
  context = self._context
71
- runner = context.get_runner(name or data.name)
71
+ runner = context.get_runner(name or data.name, recommend_on_failure=self._run)
72
72
  if context.dry_run:
73
73
  return runner.dry_run(data, result, context)
74
74
  return runner.run(data, result, context, self._run)
@@ -370,9 +370,9 @@ class ForBuilder(BodyBuilder):
370
370
 
371
371
  def build(self, node):
372
372
  error = format_error(self._get_errors(node))
373
- self.model.config(assign=node.assign, flavor=node.flavor, values=node.values,
374
- start=node.start, mode=node.mode, fill=node.fill,
375
- lineno=node.lineno, error=error)
373
+ self.model.config(assign=node.assign, flavor=node.flavor or 'IN',
374
+ values=node.values, start=node.start, mode=node.mode,
375
+ fill=node.fill, lineno=node.lineno, error=error)
376
376
  for step in node.body:
377
377
  self.visit(step)
378
378
  return self.model
@@ -24,6 +24,11 @@ from .keywordimplementation import KeywordImplementation
24
24
 
25
25
 
26
26
  class InvalidKeyword(KeywordImplementation):
27
+ """Represents an invalid keyword call.
28
+
29
+ Keyword may not have been found, there could have been multiple matches,
30
+ or the keyword call itself could have been invalid.
31
+ """
27
32
  type = KeywordImplementation.INVALID_KEYWORD
28
33
 
29
34
  def _get_embedded(self, name) -> 'EmbeddedArguments|None':
@@ -100,7 +100,7 @@ class LibraryKeyword(KeywordImplementation):
100
100
 
101
101
 
102
102
  class StaticKeyword(LibraryKeyword):
103
- """Represents keywords in static libraries."""
103
+ """Represents a keyword in a static library."""
104
104
  __slots__ = ['method_name']
105
105
 
106
106
  def __init__(self, method_name: str,
@@ -142,7 +142,7 @@ class StaticKeyword(LibraryKeyword):
142
142
 
143
143
 
144
144
  class DynamicKeyword(LibraryKeyword):
145
- """Represents keywords in dynamic libraries."""
145
+ """Represents a keyword in a dynamic library."""
146
146
  owner: 'DynamicLibrary'
147
147
  __slots__ = ['run_keyword', '_orig_name', '__source_info']
148
148
 
@@ -212,7 +212,7 @@ class DynamicKeyword(LibraryKeyword):
212
212
 
213
213
 
214
214
  class LibraryInit(LibraryKeyword):
215
- """Represents library initializer.
215
+ """Represents a library initializer.
216
216
 
217
217
  :attr:`positional` and :attr:`named` contain arguments used for initializing
218
218
  the library.