robotframework 6.1rc1__zip → 7.0a1__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 (288) hide show
  1. {robotframework-6.1rc1/src/robotframework.egg-info → robotframework-7.0a1}/PKG-INFO +3 -6
  2. {robotframework-6.1rc1 → robotframework-7.0a1}/setup.py +2 -5
  3. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/api/interfaces.py +36 -49
  4. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/api/parsing.py +4 -2
  5. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/conf/gatherfailed.py +2 -2
  6. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/conf/languages.py +61 -25
  7. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/conf/settings.py +8 -5
  8. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/rebot/log.css +4 -0
  9. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/rebot/log.html +9 -1
  10. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/rebot/model.js +2 -4
  11. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/rebot/testdata.js +10 -3
  12. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/template.py +3 -3
  13. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libdocpkg/builder.py +0 -8
  14. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libdocpkg/datatypes.py +9 -10
  15. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libdocpkg/htmlutils.py +4 -7
  16. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libdocpkg/jsonbuilder.py +14 -10
  17. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libdocpkg/model.py +13 -25
  18. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libdocpkg/robotbuilder.py +14 -4
  19. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libdocpkg/xmlbuilder.py +8 -8
  20. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libdocpkg/xmlwriter.py +12 -38
  21. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libraries/BuiltIn.py +215 -189
  22. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libraries/Collections.py +2 -9
  23. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libraries/DateTime.py +1 -1
  24. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libraries/OperatingSystem.py +4 -3
  25. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libraries/Process.py +26 -27
  26. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libraries/Remote.py +40 -36
  27. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libraries/String.py +4 -4
  28. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libraries/XML.py +7 -8
  29. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libraries/__init__.py +2 -2
  30. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libraries/dialogs_py.py +14 -2
  31. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/__init__.py +4 -4
  32. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/body.py +14 -6
  33. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/configurer.py +19 -15
  34. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/control.py +155 -85
  35. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/filter.py +31 -25
  36. robotframework-7.0a1/src/robot/model/keyword.py +70 -0
  37. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/message.py +19 -10
  38. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/modelobject.py +2 -8
  39. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/modifier.py +1 -1
  40. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/namepatterns.py +3 -25
  41. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/stats.py +9 -15
  42. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/tags.py +1 -1
  43. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/testcase.py +12 -21
  44. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/testsuite.py +43 -24
  45. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/visitor.py +35 -8
  46. robotframework-7.0a1/src/robot/output/console/dotted.py +90 -0
  47. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/output/console/quiet.py +3 -2
  48. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/output/console/verbose.py +60 -60
  49. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/output/debugfile.py +36 -23
  50. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/output/filelogger.py +16 -13
  51. robotframework-7.0a1/src/robot/output/listeners.py +586 -0
  52. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/output/logger.py +164 -77
  53. robotframework-7.0a1/src/robot/output/loggerapi.py +152 -0
  54. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/output/loggerhelper.py +23 -56
  55. robotframework-7.0a1/src/robot/output/output.py +158 -0
  56. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/output/stdoutlogsplitter.py +8 -5
  57. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/output/xmllogger.py +163 -109
  58. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/parsing/lexer/blocklexers.py +17 -13
  59. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/parsing/lexer/context.py +12 -2
  60. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/parsing/lexer/lexer.py +1 -1
  61. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/parsing/lexer/settings.py +6 -3
  62. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/parsing/lexer/statementlexers.py +39 -10
  63. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/parsing/lexer/tokens.py +27 -29
  64. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/parsing/model/blocks.py +19 -6
  65. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/parsing/model/statements.py +184 -84
  66. robotframework-7.0a1/src/robot/parsing/model/visitor.py +102 -0
  67. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/reporting/expandkeywordmatcher.py +1 -1
  68. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/reporting/jsbuildingcontext.py +8 -6
  69. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/reporting/jsmodelbuilders.py +88 -61
  70. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/reporting/stringcache.py +4 -3
  71. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/reporting/xunitwriter.py +15 -21
  72. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/result/__init__.py +3 -2
  73. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/result/configurer.py +12 -9
  74. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/result/flattenkeywordmatcher.py +8 -8
  75. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/result/keywordremover.py +71 -54
  76. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/result/merger.py +1 -1
  77. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/result/model.py +400 -316
  78. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/result/modeldeprecation.py +9 -3
  79. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/result/resultbuilder.py +21 -23
  80. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/result/xmlelementhandlers.py +76 -40
  81. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/run.py +1 -1
  82. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/__init__.py +1 -1
  83. robotframework-7.0a1/src/robot/running/arguments/argumentconverter.py +101 -0
  84. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/arguments/argumentmapper.py +16 -14
  85. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/arguments/argumentparser.py +3 -1
  86. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/arguments/argumentresolver.py +41 -33
  87. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/arguments/argumentspec.py +24 -90
  88. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/arguments/argumentvalidator.py +34 -27
  89. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/arguments/customconverters.py +14 -11
  90. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/arguments/embedded.py +23 -26
  91. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/arguments/typeconverters.py +210 -220
  92. robotframework-7.0a1/src/robot/running/arguments/typeinfo.py +367 -0
  93. robotframework-7.0a1/src/robot/running/arguments/typevalidator.py +62 -0
  94. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/bodyrunner.py +83 -68
  95. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/builder/builders.py +15 -25
  96. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/builder/parsers.py +15 -10
  97. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/builder/settings.py +9 -17
  98. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/builder/transformers.py +166 -308
  99. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/context.py +80 -25
  100. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/handlers.py +11 -16
  101. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/handlerstore.py +1 -1
  102. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/librarykeywordrunner.py +9 -17
  103. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/model.py +156 -36
  104. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/namespace.py +18 -19
  105. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/statusreporter.py +13 -12
  106. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/suiterunner.py +18 -21
  107. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/testlibraries.py +35 -39
  108. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/usererrorhandler.py +8 -8
  109. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/userkeyword.py +13 -8
  110. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/userkeywordrunner.py +18 -21
  111. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/testdoc.py +18 -13
  112. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/__init__.py +50 -35
  113. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/connectioncache.py +64 -59
  114. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/encodingsniffer.py +9 -4
  115. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/escaping.py +11 -9
  116. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/markupwriters.py +20 -13
  117. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/normalizing.py +9 -24
  118. robotframework-7.0a1/src/robot/utils/notset.py +33 -0
  119. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/platform.py +15 -5
  120. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/robotpath.py +1 -0
  121. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/robottime.py +120 -88
  122. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/robottypes.py +16 -31
  123. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/setter.py +0 -5
  124. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/text.py +7 -4
  125. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/unic.py +2 -2
  126. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/variables/__init__.py +2 -2
  127. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/variables/assigner.py +17 -19
  128. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/variables/evaluation.py +20 -17
  129. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/variables/filesetter.py +80 -80
  130. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/variables/replacer.py +33 -36
  131. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/variables/scopes.py +3 -3
  132. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/variables/search.py +66 -41
  133. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/variables/store.py +14 -16
  134. robotframework-7.0a1/src/robot/variables/tablesetter.py +164 -0
  135. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/variables/variables.py +1 -1
  136. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/version.py +1 -1
  137. {robotframework-6.1rc1 → robotframework-7.0a1/src/robotframework.egg-info}/PKG-INFO +3 -6
  138. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robotframework.egg-info/SOURCES.txt +3 -4
  139. {robotframework-6.1rc1 → robotframework-7.0a1}/tasks.py +6 -6
  140. robotframework-6.1rc1/src/robot/libraries/Reserved.py +0 -48
  141. robotframework-6.1rc1/src/robot/model/keyword.py +0 -173
  142. robotframework-6.1rc1/src/robot/output/console/dotted.py +0 -90
  143. robotframework-6.1rc1/src/robot/output/listenerarguments.py +0 -165
  144. robotframework-6.1rc1/src/robot/output/listenermethods.py +0 -113
  145. robotframework-6.1rc1/src/robot/output/listeners.py +0 -174
  146. robotframework-6.1rc1/src/robot/output/output.py +0 -95
  147. robotframework-6.1rc1/src/robot/parsing/model/visitor.py +0 -67
  148. robotframework-6.1rc1/src/robot/running/arguments/argumentconverter.py +0 -79
  149. robotframework-6.1rc1/src/robot/running/arguments/typevalidator.py +0 -56
  150. robotframework-6.1rc1/src/robot/running/modelcombiner.py +0 -32
  151. robotframework-6.1rc1/src/robot/variables/tablesetter.py +0 -156
  152. {robotframework-6.1rc1 → robotframework-7.0a1}/AUTHORS.rst +0 -0
  153. {robotframework-6.1rc1 → robotframework-7.0a1}/BUILD.rst +0 -0
  154. {robotframework-6.1rc1 → robotframework-7.0a1}/CONTRIBUTING.rst +0 -0
  155. {robotframework-6.1rc1 → robotframework-7.0a1}/COPYRIGHT.txt +0 -0
  156. {robotframework-6.1rc1 → robotframework-7.0a1}/INSTALL.rst +0 -0
  157. {robotframework-6.1rc1 → robotframework-7.0a1}/LICENSE.txt +0 -0
  158. {robotframework-6.1rc1 → robotframework-7.0a1}/MANIFEST.in +0 -0
  159. {robotframework-6.1rc1 → robotframework-7.0a1}/README.rst +0 -0
  160. {robotframework-6.1rc1 → robotframework-7.0a1}/setup.cfg +0 -0
  161. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/__init__.py +0 -0
  162. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/__main__.py +0 -0
  163. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/api/__init__.py +0 -0
  164. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/api/deco.py +0 -0
  165. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/api/exceptions.py +0 -0
  166. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/api/logger.py +0 -0
  167. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/conf/__init__.py +0 -0
  168. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/errors.py +0 -0
  169. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/__init__.py +0 -0
  170. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/common/__init__.py +0 -0
  171. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/common/js_disabled.css +0 -0
  172. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/common/storage.js +0 -0
  173. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/htmlfilewriter.py +0 -0
  174. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/jsonwriter.py +0 -0
  175. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/lib/__init__.py +0 -0
  176. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/lib/jquery.highlight.min.js +0 -0
  177. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/lib/jquery.min.js +0 -0
  178. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/lib/jquery.tablesorter.min.js +0 -0
  179. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/lib/jquery.tmpl.min.js +0 -0
  180. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/lib/jsxcompressor.min.js +0 -0
  181. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/libdoc/__init__.py +0 -0
  182. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/libdoc/doc_formatting.css +0 -0
  183. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/libdoc/libdoc.css +0 -0
  184. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/libdoc/libdoc.html +0 -0
  185. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/libdoc/print.css +0 -0
  186. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/libdoc/pygments.css +0 -0
  187. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/rebot/__init__.py +0 -0
  188. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/rebot/common.css +0 -0
  189. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/rebot/doc_formatting.css +0 -0
  190. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/rebot/fileloading.js +0 -0
  191. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/rebot/log.js +0 -0
  192. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/rebot/print.css +0 -0
  193. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/rebot/report.css +0 -0
  194. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/rebot/report.html +0 -0
  195. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/rebot/util.js +0 -0
  196. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/rebot/view.js +0 -0
  197. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/testdoc/__init__.py +0 -0
  198. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/testdoc/testdoc.css +0 -0
  199. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/htmldata/testdoc/testdoc.html +0 -0
  200. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libdoc.py +0 -0
  201. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libdocpkg/__init__.py +0 -0
  202. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libdocpkg/consoleviewer.py +0 -0
  203. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libdocpkg/htmlwriter.py +0 -0
  204. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libdocpkg/jsonwriter.py +0 -0
  205. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libdocpkg/output.py +0 -0
  206. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libdocpkg/standardtypes.py +0 -0
  207. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libdocpkg/writer.py +0 -0
  208. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libraries/Dialogs.py +0 -0
  209. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libraries/Easter.py +0 -0
  210. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libraries/Screenshot.py +0 -0
  211. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/libraries/Telnet.py +0 -0
  212. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/fixture.py +0 -0
  213. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/itemlist.py +0 -0
  214. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/metadata.py +0 -0
  215. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/statistics.py +0 -0
  216. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/suitestatistics.py +0 -0
  217. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/tagsetter.py +0 -0
  218. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/tagstatistics.py +0 -0
  219. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/model/totalstatistics.py +0 -0
  220. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/output/__init__.py +0 -0
  221. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/output/console/__init__.py +0 -0
  222. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/output/console/highlighting.py +0 -0
  223. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/output/librarylogger.py +0 -0
  224. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/output/pyloggingconf.py +0 -0
  225. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/parsing/__init__.py +0 -0
  226. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/parsing/lexer/__init__.py +0 -0
  227. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/parsing/lexer/tokenizer.py +0 -0
  228. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/parsing/model/__init__.py +0 -0
  229. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/parsing/parser/__init__.py +0 -0
  230. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/parsing/parser/blockparsers.py +0 -0
  231. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/parsing/parser/fileparser.py +0 -0
  232. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/parsing/parser/parser.py +0 -0
  233. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/parsing/suitestructure.py +0 -0
  234. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/pythonpathsetter.py +0 -0
  235. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/rebot.py +0 -0
  236. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/reporting/__init__.py +0 -0
  237. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/reporting/jsexecutionresult.py +0 -0
  238. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/reporting/jswriter.py +0 -0
  239. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/reporting/logreportwriters.py +0 -0
  240. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/reporting/outputwriter.py +0 -0
  241. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/reporting/resultwriter.py +0 -0
  242. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/result/executionerrors.py +0 -0
  243. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/result/executionresult.py +0 -0
  244. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/result/messagefilter.py +0 -0
  245. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/result/suiteteardownfailed.py +0 -0
  246. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/result/visitor.py +0 -0
  247. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/arguments/__init__.py +0 -0
  248. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/builder/__init__.py +0 -0
  249. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/dynamicmethods.py +0 -0
  250. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/importer.py +0 -0
  251. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/libraryscopes.py +0 -0
  252. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/outputcapture.py +0 -0
  253. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/randomizer.py +0 -0
  254. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/runkwregister.py +0 -0
  255. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/signalhandler.py +0 -0
  256. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/status.py +0 -0
  257. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/timeouts/__init__.py +0 -0
  258. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/timeouts/posix.py +0 -0
  259. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/running/timeouts/windows.py +0 -0
  260. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/application.py +0 -0
  261. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/argumentparser.py +0 -0
  262. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/asserts.py +0 -0
  263. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/charwidth.py +0 -0
  264. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/compress.py +0 -0
  265. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/dotdict.py +0 -0
  266. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/encoding.py +0 -0
  267. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/error.py +0 -0
  268. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/etreewrapper.py +0 -0
  269. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/filereader.py +0 -0
  270. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/frange.py +0 -0
  271. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/htmlformatters.py +0 -0
  272. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/importer.py +0 -0
  273. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/markuputils.py +0 -0
  274. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/match.py +0 -0
  275. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/misc.py +0 -0
  276. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/recommendations.py +0 -0
  277. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/restreader.py +0 -0
  278. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/robotenv.py +0 -0
  279. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/robotinspect.py +0 -0
  280. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/robotio.py +0 -0
  281. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/sortable.py +0 -0
  282. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/utils/typehints.py +0 -0
  283. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/variables/finders.py +0 -0
  284. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/variables/notfound.py +0 -0
  285. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robot/variables/resolvable.py +0 -0
  286. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robotframework.egg-info/dependency_links.txt +0 -0
  287. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robotframework.egg-info/entry_points.txt +0 -0
  288. {robotframework-6.1rc1 → robotframework-7.0a1}/src/robotframework.egg-info/top_level.txt +0 -0
@@ -13,50 +13,53 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
 
16
+ from typing import TYPE_CHECKING
17
+
16
18
  from robot.errors import DataError
17
19
  from robot.utils import is_string, is_dict_like, split_from_equals
18
20
  from robot.variables import is_dict_variable
19
21
 
20
22
  from .argumentvalidator import ArgumentValidator
21
23
 
24
+ if TYPE_CHECKING:
25
+ from .argumentspec import ArgumentSpec
26
+
22
27
 
23
28
  class ArgumentResolver:
24
29
 
25
- def __init__(self, argspec, resolve_named=True,
26
- resolve_variables_until=None, dict_to_kwargs=False):
27
- self._named_resolver = NamedArgumentResolver(argspec) \
28
- if resolve_named else NullNamedArgumentResolver()
29
- self._variable_replacer = VariableReplacer(resolve_variables_until)
30
- self._dict_to_kwargs = DictToKwargs(argspec, dict_to_kwargs)
31
- self._argument_validator = ArgumentValidator(argspec)
30
+ def __init__(self, spec: 'ArgumentSpec',
31
+ resolve_named: bool = True,
32
+ resolve_variables_until: 'int|None' = None,
33
+ dict_to_kwargs: bool = False):
34
+ self.named_resolver = NamedArgumentResolver(spec) \
35
+ if resolve_named else NullNamedArgumentResolver()
36
+ self.variable_replacer = VariableReplacer(spec, resolve_variables_until)
37
+ self.dict_to_kwargs = DictToKwargs(spec, dict_to_kwargs)
38
+ self.argument_validator = ArgumentValidator(spec)
32
39
 
33
40
  def resolve(self, arguments, variables=None):
34
- positional, named = self._named_resolver.resolve(arguments, variables)
35
- positional, named = self._variable_replacer.replace(positional, named, variables)
36
- positional, named = self._dict_to_kwargs.handle(positional, named)
37
- self._argument_validator.validate(positional, named,
38
- dryrun=variables is None)
41
+ positional, named = self.named_resolver.resolve(arguments, variables)
42
+ positional, named = self.variable_replacer.replace(positional, named, variables)
43
+ positional, named = self.dict_to_kwargs.handle(positional, named)
44
+ self.argument_validator.validate(positional, named, dryrun=variables is None)
39
45
  return positional, named
40
46
 
41
47
 
42
48
  class NamedArgumentResolver:
43
49
 
44
- def __init__(self, argspec):
45
- """:type argspec: :py:class:`robot.running.arguments.ArgumentSpec`"""
46
- self._argspec = argspec
50
+ def __init__(self, spec: 'ArgumentSpec'):
51
+ self.spec = spec
47
52
 
48
53
  def resolve(self, arguments, variables=None):
49
- positional = []
50
54
  named = []
51
- for arg in arguments:
55
+ for arg in arguments[len(self.spec.embedded):]:
52
56
  if is_dict_variable(arg):
53
57
  named.append(arg)
54
58
  elif self._is_named(arg, named, variables):
55
59
  named.append(split_from_equals(arg))
56
60
  elif named:
57
61
  self._raise_positional_after_named()
58
- else:
59
- positional.append(arg)
62
+ positional = arguments[:-len(named)] if named else arguments
60
63
  return positional, named
61
64
 
62
65
  def _is_named(self, arg, previous_named, variables=None):
@@ -68,15 +71,13 @@ class NamedArgumentResolver:
68
71
  name = variables.replace_scalar(name)
69
72
  except DataError:
70
73
  return False
71
- spec = self._argspec
72
74
  return bool(previous_named or
73
- spec.var_named or
74
- name in spec.positional_or_named or
75
- name in spec.named_only)
75
+ self.spec.var_named or
76
+ name in self.spec.named)
76
77
 
77
78
  def _raise_positional_after_named(self):
78
- raise DataError("%s '%s' got positional argument after named arguments."
79
- % (self._argspec.type.capitalize(), self._argspec.name))
79
+ raise DataError(f"{self.spec.type.capitalize()} '{self.spec.name}' "
80
+ f"got positional argument after named arguments.")
80
81
 
81
82
 
82
83
  class NullNamedArgumentResolver:
@@ -87,30 +88,37 @@ class NullNamedArgumentResolver:
87
88
 
88
89
  class DictToKwargs:
89
90
 
90
- def __init__(self, argspec, enabled=False):
91
- self._maxargs = argspec.maxargs
92
- self._enabled = enabled and bool(argspec.var_named)
91
+ def __init__(self, spec: 'ArgumentSpec', enabled: bool = False):
92
+ self.maxargs = spec.maxargs
93
+ self.enabled = enabled and bool(spec.var_named)
93
94
 
94
95
  def handle(self, positional, named):
95
- if self._enabled and self._extra_arg_has_kwargs(positional, named):
96
+ if self.enabled and self._extra_arg_has_kwargs(positional, named):
96
97
  named = positional.pop().items()
97
98
  return positional, named
98
99
 
99
100
  def _extra_arg_has_kwargs(self, positional, named):
100
- if named or len(positional) != self._maxargs + 1:
101
+ if named or len(positional) != self.maxargs + 1:
101
102
  return False
102
103
  return is_dict_like(positional[-1])
103
104
 
104
105
 
105
106
  class VariableReplacer:
106
107
 
107
- def __init__(self, resolve_until=None):
108
- self._resolve_until = resolve_until
108
+ def __init__(self, spec: 'ArgumentSpec', resolve_until: 'int|None' = None):
109
+ self.spec = spec
110
+ self.resolve_until = resolve_until
109
111
 
110
112
  def replace(self, positional, named, variables=None):
111
113
  # `variables` is None in dry-run mode and when using Libdoc.
112
114
  if variables:
113
- positional = variables.replace_list(positional, self._resolve_until)
115
+ if self.spec.embedded:
116
+ embedded = len(self.spec.embedded)
117
+ positional = [
118
+ variables.replace_scalar(emb) for emb in positional[:embedded]
119
+ ] + variables.replace_list(positional[embedded:])
120
+ else:
121
+ positional = variables.replace_list(positional, self.resolve_until)
114
122
  named = list(self._replace_named(named, variables.replace_scalar))
115
123
  else:
116
124
  # If `var` isn't a tuple, it's a &{dict} variables.
@@ -15,13 +15,14 @@
15
15
 
16
16
  import sys
17
17
  from enum import Enum
18
- from typing import Union, Tuple
18
+ from typing import Any
19
19
 
20
- from robot.utils import has_args, is_union, safe_str, setter, type_repr
20
+ from robot.utils import NOT_SET, safe_str, setter
21
21
 
22
22
  from .argumentconverter import ArgumentConverter
23
23
  from .argumentmapper import ArgumentMapper
24
24
  from .argumentresolver import ArgumentResolver
25
+ from .typeinfo import TypeInfo
25
26
  from .typevalidator import TypeValidator
26
27
 
27
28
 
@@ -29,25 +30,31 @@ class ArgumentSpec:
29
30
 
30
31
  def __init__(self, name=None, type='Keyword', positional_only=None,
31
32
  positional_or_named=None, var_positional=None, named_only=None,
32
- var_named=None, defaults=None, types=None):
33
+ var_named=None, embedded=None, defaults=None, types=None):
33
34
  self.name = name
34
35
  self.type = type
36
+ # FIXME: Use tuples, not lists. Consider using __slots__.
35
37
  self.positional_only = positional_only or []
36
38
  self.positional_or_named = positional_or_named or []
37
39
  self.var_positional = var_positional
38
40
  self.named_only = named_only or []
39
41
  self.var_named = var_named
42
+ self.embedded = embedded or ()
40
43
  self.defaults = defaults or {}
41
44
  self.types = types
42
45
 
43
46
  @setter
44
- def types(self, types):
47
+ def types(self, types) -> 'dict[str, TypeInfo]':
45
48
  return TypeValidator(self).validate(types)
46
49
 
47
50
  @property
48
51
  def positional(self):
49
52
  return self.positional_only + self.positional_or_named
50
53
 
54
+ @property
55
+ def named(self):
56
+ return self.named_only + self.positional_or_named
57
+
51
58
  @property
52
59
  def minargs(self):
53
60
  return len([arg for arg in self.positional if arg not in self.defaults])
@@ -84,28 +91,27 @@ class ArgumentSpec:
84
91
  return mapper.map(positional, named, replace_defaults)
85
92
 
86
93
  def __iter__(self):
87
- notset = ArgInfo.NOTSET
88
94
  get_type = (self.types or {}).get
89
95
  get_default = self.defaults.get
90
96
  for arg in self.positional_only:
91
97
  yield ArgInfo(ArgInfo.POSITIONAL_ONLY, arg,
92
- get_type(arg, notset), get_default(arg, notset))
98
+ get_type(arg), get_default(arg, NOT_SET))
93
99
  if self.positional_only:
94
100
  yield ArgInfo(ArgInfo.POSITIONAL_ONLY_MARKER)
95
101
  for arg in self.positional_or_named:
96
102
  yield ArgInfo(ArgInfo.POSITIONAL_OR_NAMED, arg,
97
- get_type(arg, notset), get_default(arg, notset))
103
+ get_type(arg), get_default(arg, NOT_SET))
98
104
  if self.var_positional:
99
105
  yield ArgInfo(ArgInfo.VAR_POSITIONAL, self.var_positional,
100
- get_type(self.var_positional, notset))
106
+ get_type(self.var_positional))
101
107
  elif self.named_only:
102
108
  yield ArgInfo(ArgInfo.NAMED_ONLY_MARKER)
103
109
  for arg in self.named_only:
104
110
  yield ArgInfo(ArgInfo.NAMED_ONLY, arg,
105
- get_type(arg, notset), get_default(arg, notset))
111
+ get_type(arg), get_default(arg, NOT_SET))
106
112
  if self.var_named:
107
113
  yield ArgInfo(ArgInfo.VAR_NAMED, self.var_named,
108
- get_type(self.var_named, notset))
114
+ get_type(self.var_named))
109
115
 
110
116
  def __bool__(self):
111
117
  return any([self.positional_only, self.positional_or_named, self.var_positional,
@@ -117,7 +123,6 @@ class ArgumentSpec:
117
123
 
118
124
  class ArgInfo:
119
125
  """Contains argument information. Only used by Libdoc."""
120
- NOTSET = object()
121
126
  POSITIONAL_ONLY = 'POSITIONAL_ONLY'
122
127
  POSITIONAL_ONLY_MARKER = 'POSITIONAL_ONLY_MARKER'
123
128
  POSITIONAL_OR_NAMED = 'POSITIONAL_OR_NAMED'
@@ -126,10 +131,13 @@ class ArgInfo:
126
131
  NAMED_ONLY = 'NAMED_ONLY'
127
132
  VAR_NAMED = 'VAR_NAMED'
128
133
 
129
- def __init__(self, kind, name='', type=NOTSET, default=NOTSET):
134
+ def __init__(self, kind: str,
135
+ name: str = '',
136
+ type: 'TypeInfo|None' = None,
137
+ default: Any = NOT_SET):
130
138
  self.kind = kind
131
139
  self.name = name
132
- self.type = TypeInfo.from_type(type)
140
+ self.type = type or TypeInfo()
133
141
  self.default = default
134
142
 
135
143
  @property
@@ -137,21 +145,12 @@ class ArgInfo:
137
145
  if self.kind in (self.POSITIONAL_ONLY,
138
146
  self.POSITIONAL_OR_NAMED,
139
147
  self.NAMED_ONLY):
140
- return self.default is self.NOTSET
148
+ return self.default is NOT_SET
141
149
  return False
142
150
 
143
- @property
144
- def types_reprs(self):
145
- """Deprecated. Use :attr:`type` instead."""
146
- if not self.type:
147
- return []
148
- if self.type.is_union:
149
- return [str(t) for t in self.type.nested]
150
- return [str(self.type)]
151
-
152
151
  @property
153
152
  def default_repr(self):
154
- if self.default is self.NOTSET:
153
+ if self.default is NOT_SET:
155
154
  return None
156
155
  if isinstance(self.default, Enum):
157
156
  return self.default.name
@@ -172,71 +171,6 @@ class ArgInfo:
172
171
  default_sep = ' = '
173
172
  else:
174
173
  default_sep = '='
175
- if self.default is not self.NOTSET:
174
+ if self.default is not NOT_SET:
176
175
  ret = f'{ret}{default_sep}{self.default_repr}'
177
176
  return ret
178
-
179
-
180
- Type = Union[type, str, tuple, type(ArgInfo.NOTSET)]
181
-
182
-
183
- class TypeInfo:
184
- """Represents argument type. Only used by Libdoc.
185
-
186
- With unions and parametrized types, :attr:`nested` contains nested types.
187
- """
188
- NOTSET = ArgInfo.NOTSET
189
-
190
- def __init__(self, type: Type = NOTSET, nested: Tuple['TypeInfo'] = ()):
191
- self.type = type
192
- self.nested = nested
193
-
194
- @property
195
- def name(self) -> str:
196
- if isinstance(self.type, str):
197
- return self.type
198
- return type_repr(self.type, nested=False)
199
-
200
- @property
201
- def is_union(self) -> bool:
202
- if isinstance(self.type, str):
203
- return self.type == 'Union'
204
- return is_union(self.type, allow_tuple=True)
205
-
206
- @classmethod
207
- def from_type(cls, type: Type) -> 'TypeInfo':
208
- if type is cls.NOTSET:
209
- return cls()
210
- if isinstance(type, dict):
211
- return cls.from_dict(type)
212
- if isinstance(type, (tuple, list)):
213
- if not type:
214
- return cls()
215
- if len(type) == 1:
216
- return cls(type[0])
217
- nested = tuple(cls.from_type(t) for t in type)
218
- return cls('Union', nested)
219
- if has_args(type):
220
- nested = tuple(cls.from_type(t) for t in type.__args__)
221
- return cls(type, nested)
222
- return cls(type)
223
-
224
- @classmethod
225
- def from_dict(cls, data: dict) -> 'TypeInfo':
226
- if not data:
227
- return cls()
228
- nested = tuple(cls.from_dict(n) for n in data['nested'])
229
- return cls(data['name'], nested)
230
-
231
- def __str__(self):
232
- if self.is_union:
233
- return ' | '.join(str(n) for n in self.nested)
234
- if isinstance(self.type, str):
235
- if self.nested:
236
- nested = ', '.join(str(n) for n in self.nested)
237
- return f'{self.name}[{nested}]'
238
- return self.name
239
- return type_repr(self.type)
240
-
241
- def __bool__(self):
242
- return self.type is not self.NOTSET
@@ -13,44 +13,49 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
 
16
+ from typing import TYPE_CHECKING
17
+
16
18
  from robot.errors import DataError
17
- from robot.utils import plural_or_not, seq2str
19
+ from robot.utils import plural_or_not as s, seq2str
18
20
  from robot.variables import is_dict_variable, is_list_variable
19
21
 
22
+ if TYPE_CHECKING:
23
+ from .argumentspec import ArgumentSpec
24
+
20
25
 
21
26
  class ArgumentValidator:
22
27
 
23
- def __init__(self, argspec):
24
- """:type argspec: :py:class:`robot.running.arguments.ArgumentSpec`"""
25
- self._argspec = argspec
28
+ def __init__(self, arg_spec: 'ArgumentSpec'):
29
+ self.arg_spec = arg_spec
26
30
 
27
31
  def validate(self, positional, named, dryrun=False):
28
32
  named = set(name for name, value in named)
29
33
  if dryrun and (any(is_list_variable(arg) for arg in positional) or
30
34
  any(is_dict_variable(arg) for arg in named)):
31
35
  return
32
- self._validate_no_multiple_values(positional, named, self._argspec)
33
- self._validate_no_positional_only_as_named(named, self._argspec)
34
- self._validate_positional_limits(positional, named, self._argspec)
35
- self._validate_no_mandatory_missing(positional, named, self._argspec)
36
- self._validate_no_named_only_missing(named, self._argspec)
37
- self._validate_no_extra_named(named, self._argspec)
36
+ self._validate_no_multiple_values(positional, named, self.arg_spec)
37
+ self._validate_no_positional_only_as_named(named, self.arg_spec)
38
+ self._validate_positional_limits(positional, named, self.arg_spec)
39
+ self._validate_no_mandatory_missing(positional, named, self.arg_spec)
40
+ self._validate_no_named_only_missing(named, self.arg_spec)
41
+ self._validate_no_extra_named(named, self.arg_spec)
38
42
 
39
43
  def _validate_no_multiple_values(self, positional, named, spec):
40
- for name in spec.positional[:len(positional)]:
44
+ for name in spec.positional[:len(positional)-len(spec.embedded)]:
41
45
  if name in named and name not in spec.positional_only:
42
- self._raise_error("got multiple values for argument '%s'" % name)
46
+ self._raise_error(f"got multiple values for argument '{name}'")
43
47
 
44
48
  def _raise_error(self, message):
45
- raise DataError("%s '%s' %s." % (self._argspec.type.capitalize(),
46
- self._argspec.name, message))
49
+ spec = self.arg_spec
50
+ name = f"'{spec.name}' " if spec.name else ''
51
+ raise DataError(f"{spec.type.capitalize()} {name}{message}.")
47
52
 
48
53
  def _validate_no_positional_only_as_named(self, named, spec):
49
54
  if not spec.var_named:
50
55
  for name in named:
51
56
  if name in spec.positional_only:
52
- self._raise_error("does not accept argument '%s' as named "
53
- "argument" % name)
57
+ self._raise_error(f"does not accept argument '{name}' as named "
58
+ f"argument")
54
59
 
55
60
  def _validate_positional_limits(self, positional, named, spec):
56
61
  count = len(positional) + self._named_positionals(named, spec)
@@ -61,32 +66,34 @@ class ArgumentValidator:
61
66
  return sum(1 for n in named if n in spec.positional_or_named)
62
67
 
63
68
  def _raise_wrong_count(self, count, spec):
64
- minend = plural_or_not(spec.minargs)
65
- if spec.minargs == spec.maxargs:
66
- expected = '%d argument%s' % (spec.minargs, minend)
69
+ embedded = len(spec.embedded)
70
+ minargs = spec.minargs - embedded
71
+ maxargs = spec.maxargs - embedded
72
+ if minargs == maxargs:
73
+ expected = f'{minargs} argument{s(minargs)}'
67
74
  elif not spec.var_positional:
68
- expected = '%d to %d arguments' % (spec.minargs, spec.maxargs)
75
+ expected = f'{minargs} to {maxargs} arguments'
69
76
  else:
70
- expected = 'at least %d argument%s' % (spec.minargs, minend)
77
+ expected = f'at least {minargs} argument{s(minargs)}'
71
78
  if spec.var_named or spec.named_only:
72
79
  expected = expected.replace('argument', 'non-named argument')
73
- self._raise_error("expected %s, got %d" % (expected, count))
80
+ self._raise_error(f"expected {expected}, got {count - embedded}")
74
81
 
75
82
  def _validate_no_mandatory_missing(self, positional, named, spec):
76
83
  for name in spec.positional[len(positional):]:
77
84
  if name not in spec.defaults and name not in named:
78
- self._raise_error("missing value for argument '%s'" % name)
85
+ self._raise_error(f"missing value for argument '{name}'")
79
86
 
80
87
  def _validate_no_named_only_missing(self, named, spec):
81
88
  defined = set(named) | set(spec.defaults)
82
89
  missing = [arg for arg in spec.named_only if arg not in defined]
83
90
  if missing:
84
- self._raise_error("missing named-only argument%s %s"
85
- % (plural_or_not(missing), seq2str(sorted(missing))))
91
+ self._raise_error(f"missing named-only argument{s(missing)} "
92
+ f"{seq2str(sorted(missing))}")
86
93
 
87
94
  def _validate_no_extra_named(self, named, spec):
88
95
  if not spec.var_named:
89
96
  extra = set(named) - set(spec.positional_or_named) - set(spec.named_only)
90
97
  if extra:
91
- self._raise_error("got unexpected named argument%s %s"
92
- % (plural_or_not(extra), seq2str(sorted(extra))))
98
+ self._raise_error(f"got unexpected named argument{s(extra)} "
99
+ f"{seq2str(sorted(extra))}")
@@ -13,9 +13,7 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
 
16
- from robot.utils import getdoc, is_union, seq2str, type_name
17
-
18
- from .argumentparser import PythonArgumentParser
16
+ from robot.utils import getdoc, seq2str, type_name
19
17
 
20
18
 
21
19
  class CustomArgumentConverters:
@@ -24,12 +22,14 @@ class CustomArgumentConverters:
24
22
  self.converters = converters
25
23
 
26
24
  @classmethod
27
- def from_dict(cls, converters, library):
25
+ def from_dict(cls, converters, library=None):
28
26
  valid = []
29
27
  for type_, conv in converters.items():
30
28
  try:
31
29
  info = ConverterInfo.for_converter(type_, conv, library)
32
30
  except TypeError as err:
31
+ if library is None:
32
+ raise
33
33
  library.report_error(str(err))
34
34
  else:
35
35
  valid.append(info)
@@ -78,20 +78,23 @@ class ConverterInfo:
78
78
  raise TypeError(f'Custom converters must be callable, converter for '
79
79
  f'{type_name(type_)} is {type_name(converter)}.')
80
80
  spec = cls._get_arg_spec(converter)
81
- arg_type = spec.types.get(spec.positional and spec.positional[0] or spec.var_positional)
82
- if arg_type is None:
81
+ type_info = spec.types.get(spec.positional[0] if spec.positional
82
+ else spec.var_positional)
83
+ if type_info is None:
83
84
  accepts = ()
84
- elif is_union(arg_type):
85
- accepts = arg_type.__args__
86
- elif hasattr(arg_type, '__origin__'):
87
- accepts = (arg_type.__origin__,)
85
+ elif type_info.is_union:
86
+ accepts = type_info.nested
88
87
  else:
89
- accepts = (arg_type,)
88
+ accepts = (type_info,)
89
+ accepts = tuple(info.type for info in accepts)
90
90
  pass_library = spec.minargs == 2 or spec.var_positional
91
91
  return cls(type_, converter, accepts, library if pass_library else None)
92
92
 
93
93
  @classmethod
94
94
  def _get_arg_spec(cls, converter):
95
+ # Avoid cyclic import. Yuck.
96
+ from .argumentparser import PythonArgumentParser
97
+
95
98
  spec = PythonArgumentParser(type='Converter').parse(converter)
96
99
  if spec.minargs > 2:
97
100
  required = seq2str([a for a in spec.positional if a not in spec.defaults])
@@ -17,10 +17,9 @@ import re
17
17
 
18
18
  from robot.errors import DataError
19
19
  from robot.utils import get_error_message, is_string
20
- from robot.variables import VariableIterator
20
+ from robot.variables import VariableMatches
21
21
 
22
-
23
- ENABLE_STRICT_ARGUMENT_VALIDATION = False
22
+ from ..context import EXECUTION_CONTEXTS
24
23
 
25
24
 
26
25
  class EmbeddedArguments:
@@ -42,31 +41,27 @@ class EmbeddedArguments:
42
41
  return list(zip(self.args, values))
43
42
 
44
43
  def validate(self, values):
45
- # Validating that embedded args match custom regexps also if args are
46
- # given as variables was initially implemented in RF 6.0. It needed
47
- # to be reverted due to backwards incompatibility reasons but the plan
48
- # is to enable it again in RF 7.0:
49
- # https://github.com/robotframework/robotframework/issues/4069
50
- #
51
- # TODO: Emit deprecation warnings if patterns don't match in RF 6.1:
52
- # https://github.com/robotframework/robotframework/issues/4524
53
- #
54
- # Because the plan is to add validation back, the code was not removed
55
- # but the `ENABLE_STRICT_ARGUMENT_VALIDATION` guard was added instead.
56
- # Enabling validation requires only removing the following two lines
57
- # (along with this comment). If someone wants to enable strict validation
58
- # already now, they set `ENABLE_STRICT_ARGUMENT_VALIDATION` to True
59
- # before running tests.
60
- if not ENABLE_STRICT_ARGUMENT_VALIDATION:
61
- return
44
+ """Validate that embedded args match custom regexps.
45
+
46
+ Initial validation is done already when matching keywords, but this
47
+ validation makes sure arguments match also if they are given as variables.
48
+
49
+ Currently, argument not matching only causes a deprecation warning, but
50
+ that will be changed to an actual failure in RF 8.0:
51
+ https://github.com/robotframework/robotframework/issues/4069
52
+ """
62
53
  if not self.custom_patterns:
63
54
  return
64
55
  for arg, value in zip(self.args, values):
65
56
  if arg in self.custom_patterns and is_string(value):
66
57
  pattern = self.custom_patterns[arg]
67
58
  if not re.fullmatch(pattern, value):
68
- raise ValueError(f"Embedded argument '{arg}' got value '{value}' "
69
- f"that does not match custom pattern '{pattern}'.")
59
+ # TODO: Change to `raise ValueError(...)` in RF 8.0.
60
+ context = EXECUTION_CONTEXTS.current
61
+ context.warn(f"Embedded argument '{arg}' got value {value!r} "
62
+ f"that does not match custom pattern {pattern!r}. "
63
+ f"The argument is still accepted, but this behavior "
64
+ f"will change in Robot Framework 8.0.")
70
65
 
71
66
  def __bool__(self):
72
67
  return self.name is not None
@@ -84,14 +79,16 @@ class EmbeddedArgumentParser:
84
79
  args = []
85
80
  custom_patterns = {}
86
81
  name_regexp = ['^']
87
- for before, variable, string in VariableIterator(string, identifiers='$'):
88
- name, pattern, custom = self._get_name_and_pattern(variable[2:-1])
82
+ after = string
83
+ for match in VariableMatches(string, identifiers='$'):
84
+ name, pattern, custom = self._get_name_and_pattern(match.base)
89
85
  args.append(name)
90
86
  if custom:
91
87
  custom_patterns[name] = pattern
92
88
  pattern = self._format_custom_regexp(pattern)
93
- name_regexp.extend([re.escape(before), f'({pattern})'])
94
- name_regexp.extend([re.escape(string), '$'])
89
+ name_regexp.extend([re.escape(match.before), f'({pattern})'])
90
+ after = match.after
91
+ name_regexp.extend([re.escape(after), '$'])
95
92
  name = self._compile_regexp(name_regexp) if args else None
96
93
  return EmbeddedArguments(name, args, custom_patterns or None)
97
94