robotframework 6.1rc1__zip → 7.0__zip

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (307) hide show
  1. {robotframework-6.1rc1 → robotframework-7.0}/INSTALL.rst +25 -25
  2. {robotframework-6.1rc1 → robotframework-7.0}/PKG-INFO +6 -8
  3. {robotframework-6.1rc1 → robotframework-7.0}/README.rst +3 -2
  4. {robotframework-6.1rc1 → robotframework-7.0}/setup.py +3 -6
  5. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/api/__init__.py +4 -1
  6. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/api/deco.py +60 -14
  7. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/api/exceptions.py +6 -6
  8. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/api/interfaces.py +403 -68
  9. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/api/logger.py +27 -20
  10. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/api/parsing.py +4 -2
  11. robotframework-7.0/src/robot/api/py.typed +0 -0
  12. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/conf/gatherfailed.py +2 -2
  13. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/conf/languages.py +61 -25
  14. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/conf/settings.py +21 -14
  15. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/common/storage.js +11 -6
  16. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/htmlfilewriter.py +1 -1
  17. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/libdoc/libdoc.css +10 -2
  18. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/libdoc/libdoc.html +10 -0
  19. robotframework-7.0/src/robot/htmldata/rebot/common.css +362 -0
  20. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/doc_formatting.css +13 -7
  21. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/log.css +51 -10
  22. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/log.html +14 -23
  23. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/model.js +2 -4
  24. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/report.css +83 -19
  25. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/report.html +22 -7
  26. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/testdata.js +10 -3
  27. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/view.js +84 -0
  28. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/template.py +3 -3
  29. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/builder.py +0 -8
  30. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/datatypes.py +9 -10
  31. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/htmlutils.py +4 -7
  32. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/jsonbuilder.py +38 -20
  33. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/model.py +21 -28
  34. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/robotbuilder.py +50 -31
  35. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/standardtypes.py +9 -1
  36. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/xmlbuilder.py +35 -20
  37. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/xmlwriter.py +18 -38
  38. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/BuiltIn.py +255 -205
  39. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/Collections.py +384 -240
  40. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/DateTime.py +73 -60
  41. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/OperatingSystem.py +6 -5
  42. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/Process.py +26 -27
  43. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/Remote.py +40 -36
  44. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/String.py +66 -76
  45. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/XML.py +66 -59
  46. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/__init__.py +2 -2
  47. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/dialogs_py.py +14 -2
  48. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/__init__.py +5 -5
  49. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/body.py +44 -13
  50. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/configurer.py +19 -15
  51. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/control.py +230 -88
  52. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/filter.py +31 -25
  53. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/itemlist.py +9 -8
  54. robotframework-7.0/src/robot/model/keyword.py +77 -0
  55. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/message.py +19 -10
  56. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/modelobject.py +27 -15
  57. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/modifier.py +1 -1
  58. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/namepatterns.py +3 -25
  59. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/stats.py +9 -15
  60. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/tags.py +1 -1
  61. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/testcase.py +15 -27
  62. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/testsuite.py +44 -28
  63. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/visitor.py +35 -8
  64. robotframework-7.0/src/robot/output/console/dotted.py +90 -0
  65. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/output/console/quiet.py +3 -2
  66. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/output/console/verbose.py +61 -61
  67. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/output/debugfile.py +39 -24
  68. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/output/filelogger.py +18 -15
  69. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/output/librarylogger.py +3 -2
  70. robotframework-7.0/src/robot/output/listeners.py +753 -0
  71. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/output/logger.py +216 -80
  72. robotframework-7.0/src/robot/output/loggerapi.py +215 -0
  73. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/output/loggerhelper.py +23 -56
  74. robotframework-7.0/src/robot/output/output.py +185 -0
  75. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/output/stdoutlogsplitter.py +8 -5
  76. robotframework-7.0/src/robot/output/xmllogger.py +459 -0
  77. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/lexer/blocklexers.py +17 -13
  78. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/lexer/context.py +12 -2
  79. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/lexer/lexer.py +1 -1
  80. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/lexer/settings.py +6 -3
  81. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/lexer/statementlexers.py +39 -10
  82. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/lexer/tokens.py +27 -29
  83. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/model/blocks.py +19 -6
  84. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/model/statements.py +193 -94
  85. robotframework-7.0/src/robot/parsing/model/visitor.py +100 -0
  86. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/rebot.py +2 -0
  87. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/reporting/expandkeywordmatcher.py +1 -1
  88. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/reporting/jsbuildingcontext.py +8 -6
  89. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/reporting/jsmodelbuilders.py +88 -61
  90. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/reporting/logreportwriters.py +16 -10
  91. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/reporting/outputwriter.py +18 -2
  92. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/reporting/resultwriter.py +4 -4
  93. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/reporting/stringcache.py +3 -3
  94. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/reporting/xunitwriter.py +15 -21
  95. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/result/__init__.py +3 -2
  96. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/result/configurer.py +12 -9
  97. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/result/executionresult.py +56 -8
  98. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/result/flattenkeywordmatcher.py +48 -9
  99. robotframework-7.0/src/robot/result/keywordremover.py +207 -0
  100. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/result/merger.py +1 -1
  101. robotframework-7.0/src/robot/result/model.py +1185 -0
  102. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/result/modeldeprecation.py +9 -3
  103. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/result/resultbuilder.py +46 -36
  104. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/result/xmlelementhandlers.py +83 -43
  105. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/run.py +3 -1
  106. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/__init__.py +14 -4
  107. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/arguments/__init__.py +2 -1
  108. robotframework-7.0/src/robot/running/arguments/argumentconverter.py +100 -0
  109. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/arguments/argumentmapper.py +26 -24
  110. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/arguments/argumentparser.py +85 -61
  111. robotframework-7.0/src/robot/running/arguments/argumentresolver.py +158 -0
  112. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/arguments/argumentspec.py +83 -116
  113. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/arguments/argumentvalidator.py +33 -27
  114. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/arguments/customconverters.py +15 -12
  115. robotframework-7.0/src/robot/running/arguments/embedded.py +145 -0
  116. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/arguments/typeconverters.py +268 -220
  117. robotframework-7.0/src/robot/running/arguments/typeinfo.py +317 -0
  118. robotframework-7.0/src/robot/running/arguments/typeinfoparser.py +219 -0
  119. robotframework-7.0/src/robot/running/arguments/typevalidator.py +60 -0
  120. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/bodyrunner.py +147 -129
  121. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/builder/builders.py +17 -26
  122. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/builder/parsers.py +17 -11
  123. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/builder/settings.py +9 -17
  124. robotframework-7.0/src/robot/running/builder/transformers.py +535 -0
  125. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/context.py +113 -31
  126. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/dynamicmethods.py +62 -34
  127. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/importer.py +27 -49
  128. robotframework-7.0/src/robot/running/invalidkeyword.py +67 -0
  129. robotframework-7.0/src/robot/running/keywordfinder.py +91 -0
  130. robotframework-7.0/src/robot/running/keywordimplementation.py +164 -0
  131. robotframework-7.0/src/robot/running/librarykeyword.py +392 -0
  132. robotframework-7.0/src/robot/running/librarykeywordrunner.py +250 -0
  133. robotframework-7.0/src/robot/running/libraryscopes.py +115 -0
  134. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/model.py +198 -337
  135. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/namespace.py +124 -137
  136. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/outputcapture.py +20 -12
  137. robotframework-7.0/src/robot/running/resourcemodel.py +448 -0
  138. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/statusreporter.py +16 -13
  139. robotframework-7.0/src/robot/running/suiterunner.py +265 -0
  140. robotframework-7.0/src/robot/running/testlibraries.py +500 -0
  141. robotframework-7.0/src/robot/running/userkeywordrunner.py +260 -0
  142. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/testdoc.py +18 -13
  143. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/__init__.py +53 -35
  144. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/connectioncache.py +64 -59
  145. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/dotdict.py +3 -0
  146. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/encodingsniffer.py +9 -4
  147. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/escaping.py +19 -19
  148. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/importer.py +2 -2
  149. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/markupwriters.py +23 -15
  150. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/misc.py +1 -2
  151. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/normalizing.py +9 -24
  152. robotframework-7.0/src/robot/utils/notset.py +33 -0
  153. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/platform.py +15 -5
  154. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/robotio.py +9 -9
  155. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/robotpath.py +1 -0
  156. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/robottime.py +122 -90
  157. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/robottypes.py +21 -31
  158. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/setter.py +0 -5
  159. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/text.py +7 -4
  160. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/unic.py +2 -2
  161. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/variables/__init__.py +2 -2
  162. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/variables/assigner.py +17 -19
  163. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/variables/evaluation.py +20 -17
  164. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/variables/filesetter.py +80 -80
  165. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/variables/replacer.py +33 -36
  166. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/variables/scopes.py +17 -12
  167. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/variables/search.py +66 -41
  168. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/variables/store.py +14 -16
  169. robotframework-7.0/src/robot/variables/tablesetter.py +164 -0
  170. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/variables/variables.py +1 -1
  171. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/version.py +1 -1
  172. {robotframework-6.1rc1 → robotframework-7.0}/src/robotframework.egg-info/PKG-INFO +6 -8
  173. {robotframework-6.1rc1 → robotframework-7.0}/src/robotframework.egg-info/SOURCES.txt +10 -8
  174. {robotframework-6.1rc1 → robotframework-7.0}/tasks.py +6 -6
  175. robotframework-6.1rc1/src/robot/htmldata/rebot/common.css +0 -239
  176. robotframework-6.1rc1/src/robot/libraries/Reserved.py +0 -48
  177. robotframework-6.1rc1/src/robot/model/keyword.py +0 -173
  178. robotframework-6.1rc1/src/robot/output/console/dotted.py +0 -90
  179. robotframework-6.1rc1/src/robot/output/listenerarguments.py +0 -165
  180. robotframework-6.1rc1/src/robot/output/listenermethods.py +0 -113
  181. robotframework-6.1rc1/src/robot/output/listeners.py +0 -174
  182. robotframework-6.1rc1/src/robot/output/output.py +0 -95
  183. robotframework-6.1rc1/src/robot/output/xmllogger.py +0 -354
  184. robotframework-6.1rc1/src/robot/parsing/model/visitor.py +0 -67
  185. robotframework-6.1rc1/src/robot/result/keywordremover.py +0 -183
  186. robotframework-6.1rc1/src/robot/result/model.py +0 -957
  187. robotframework-6.1rc1/src/robot/running/arguments/argumentconverter.py +0 -79
  188. robotframework-6.1rc1/src/robot/running/arguments/argumentresolver.py +0 -131
  189. robotframework-6.1rc1/src/robot/running/arguments/embedded.py +0 -146
  190. robotframework-6.1rc1/src/robot/running/arguments/typevalidator.py +0 -56
  191. robotframework-6.1rc1/src/robot/running/builder/transformers.py +0 -642
  192. robotframework-6.1rc1/src/robot/running/handlers.py +0 -321
  193. robotframework-6.1rc1/src/robot/running/handlerstore.py +0 -66
  194. robotframework-6.1rc1/src/robot/running/librarykeywordrunner.py +0 -238
  195. robotframework-6.1rc1/src/robot/running/libraryscopes.py +0 -97
  196. robotframework-6.1rc1/src/robot/running/modelcombiner.py +0 -32
  197. robotframework-6.1rc1/src/robot/running/suiterunner.py +0 -249
  198. robotframework-6.1rc1/src/robot/running/testlibraries.py +0 -420
  199. robotframework-6.1rc1/src/robot/running/usererrorhandler.py +0 -75
  200. robotframework-6.1rc1/src/robot/running/userkeyword.py +0 -111
  201. robotframework-6.1rc1/src/robot/running/userkeywordrunner.py +0 -274
  202. robotframework-6.1rc1/src/robot/variables/tablesetter.py +0 -156
  203. {robotframework-6.1rc1 → robotframework-7.0}/AUTHORS.rst +0 -0
  204. {robotframework-6.1rc1 → robotframework-7.0}/BUILD.rst +0 -0
  205. {robotframework-6.1rc1 → robotframework-7.0}/CONTRIBUTING.rst +0 -0
  206. {robotframework-6.1rc1 → robotframework-7.0}/COPYRIGHT.txt +0 -0
  207. {robotframework-6.1rc1 → robotframework-7.0}/LICENSE.txt +0 -0
  208. {robotframework-6.1rc1 → robotframework-7.0}/MANIFEST.in +0 -0
  209. {robotframework-6.1rc1 → robotframework-7.0}/setup.cfg +0 -0
  210. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/__init__.py +0 -0
  211. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/__main__.py +0 -0
  212. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/conf/__init__.py +0 -0
  213. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/errors.py +0 -0
  214. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/__init__.py +0 -0
  215. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/common/__init__.py +0 -0
  216. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/common/js_disabled.css +0 -0
  217. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/jsonwriter.py +0 -0
  218. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/lib/__init__.py +0 -0
  219. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/lib/jquery.highlight.min.js +0 -0
  220. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/lib/jquery.min.js +0 -0
  221. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/lib/jquery.tablesorter.min.js +0 -0
  222. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/lib/jquery.tmpl.min.js +0 -0
  223. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/lib/jsxcompressor.min.js +0 -0
  224. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/libdoc/__init__.py +0 -0
  225. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/libdoc/doc_formatting.css +0 -0
  226. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/libdoc/print.css +0 -0
  227. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/libdoc/pygments.css +0 -0
  228. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/__init__.py +0 -0
  229. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/fileloading.js +0 -0
  230. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/log.js +0 -0
  231. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/print.css +0 -0
  232. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/util.js +0 -0
  233. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/testdoc/__init__.py +0 -0
  234. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/testdoc/testdoc.css +0 -0
  235. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/testdoc/testdoc.html +0 -0
  236. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdoc.py +0 -0
  237. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/__init__.py +0 -0
  238. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/consoleviewer.py +0 -0
  239. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/htmlwriter.py +0 -0
  240. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/jsonwriter.py +0 -0
  241. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/output.py +0 -0
  242. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/writer.py +0 -0
  243. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/Dialogs.py +0 -0
  244. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/Easter.py +0 -0
  245. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/Screenshot.py +0 -0
  246. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/Telnet.py +0 -0
  247. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/fixture.py +0 -0
  248. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/metadata.py +0 -0
  249. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/statistics.py +0 -0
  250. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/suitestatistics.py +0 -0
  251. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/tagsetter.py +0 -0
  252. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/tagstatistics.py +0 -0
  253. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/totalstatistics.py +0 -0
  254. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/output/__init__.py +0 -0
  255. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/output/console/__init__.py +0 -0
  256. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/output/console/highlighting.py +0 -0
  257. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/output/pyloggingconf.py +0 -0
  258. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/__init__.py +0 -0
  259. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/lexer/__init__.py +0 -0
  260. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/lexer/tokenizer.py +0 -0
  261. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/model/__init__.py +0 -0
  262. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/parser/__init__.py +0 -0
  263. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/parser/blockparsers.py +0 -0
  264. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/parser/fileparser.py +0 -0
  265. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/parser/parser.py +0 -0
  266. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/suitestructure.py +0 -0
  267. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/pythonpathsetter.py +0 -0
  268. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/reporting/__init__.py +0 -0
  269. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/reporting/jsexecutionresult.py +0 -0
  270. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/reporting/jswriter.py +0 -0
  271. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/result/executionerrors.py +0 -0
  272. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/result/messagefilter.py +0 -0
  273. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/result/suiteteardownfailed.py +0 -0
  274. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/result/visitor.py +0 -0
  275. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/builder/__init__.py +0 -0
  276. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/randomizer.py +0 -0
  277. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/runkwregister.py +0 -0
  278. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/signalhandler.py +0 -0
  279. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/status.py +0 -0
  280. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/timeouts/__init__.py +0 -0
  281. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/timeouts/posix.py +0 -0
  282. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/timeouts/windows.py +0 -0
  283. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/application.py +0 -0
  284. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/argumentparser.py +0 -0
  285. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/asserts.py +0 -0
  286. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/charwidth.py +0 -0
  287. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/compress.py +0 -0
  288. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/encoding.py +0 -0
  289. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/error.py +0 -0
  290. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/etreewrapper.py +0 -0
  291. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/filereader.py +0 -0
  292. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/frange.py +0 -0
  293. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/htmlformatters.py +0 -0
  294. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/markuputils.py +0 -0
  295. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/match.py +0 -0
  296. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/recommendations.py +0 -0
  297. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/restreader.py +0 -0
  298. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/robotenv.py +0 -0
  299. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/robotinspect.py +0 -0
  300. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/sortable.py +0 -0
  301. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/typehints.py +0 -0
  302. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/variables/finders.py +0 -0
  303. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/variables/notfound.py +0 -0
  304. {robotframework-6.1rc1 → robotframework-7.0}/src/robot/variables/resolvable.py +0 -0
  305. {robotframework-6.1rc1 → robotframework-7.0}/src/robotframework.egg-info/dependency_links.txt +0 -0
  306. {robotframework-6.1rc1 → robotframework-7.0}/src/robotframework.egg-info/entry_points.txt +0 -0
  307. {robotframework-6.1rc1 → robotframework-7.0}/src/robotframework.egg-info/top_level.txt +0 -0
@@ -15,20 +15,24 @@
15
15
 
16
16
  from ast import literal_eval
17
17
  from collections import OrderedDict
18
- from collections.abc import ByteString, Container, Mapping, Sequence, Set
18
+ from collections.abc import Container, Mapping, Sequence, Set
19
19
  from datetime import datetime, date, timedelta
20
20
  from decimal import InvalidOperation, Decimal
21
21
  from enum import Enum
22
22
  from numbers import Integral, Real
23
23
  from os import PathLike
24
24
  from pathlib import Path, PurePath
25
- from typing import Any, Tuple, TypeVar, Union
25
+ from typing import Any, Literal, TYPE_CHECKING, Union
26
26
 
27
27
  from robot.conf import Languages
28
28
  from robot.libraries.DateTime import convert_date, convert_time
29
- from robot.utils import (eq, get_error_message, has_args, is_string, is_union,
30
- plural_or_not as s, safe_str, seq2str, type_name, type_repr,
31
- typeddict_types)
29
+ from robot.utils import (eq, get_error_message, is_string, plural_or_not as s,
30
+ safe_str, seq2str, type_name)
31
+
32
+
33
+ if TYPE_CHECKING:
34
+ from .customconverters import ConverterInfo, CustomArgumentConverters
35
+ from .typeinfo import TypeInfo, TypedDictInfo
32
36
 
33
37
 
34
38
  NoneType = type(None)
@@ -38,99 +42,87 @@ class TypeConverter:
38
42
  type = None
39
43
  type_name = None
40
44
  abc = None
41
- aliases = ()
42
45
  value_types = (str,)
43
46
  doc = None
44
47
  _converters = OrderedDict()
45
- _type_aliases = {}
46
48
 
47
- def __init__(self, used_type, custom_converters=None, languages=None):
48
- self.used_type = used_type
49
+ def __init__(self, type_info: 'TypeInfo',
50
+ custom_converters: 'CustomArgumentConverters|None' = None,
51
+ languages: 'Languages|None' = None):
52
+ self.type_info = type_info
49
53
  self.custom_converters = custom_converters
50
54
  self.languages = languages or Languages()
51
55
 
52
56
  @classmethod
53
- def register(cls, converter):
57
+ def register(cls, converter: 'type[TypeConverter]') -> 'type[TypeConverter]':
54
58
  cls._converters[converter.type] = converter
55
- for name in (converter.type_name,) + converter.aliases:
56
- if name is not None and not isinstance(name, property):
57
- cls._type_aliases[name.lower()] = converter.type
58
59
  return converter
59
60
 
60
61
  @classmethod
61
- def converter_for(cls, type_, custom_converters=None, languages=None):
62
- try:
63
- hash(type_)
64
- except TypeError:
62
+ def converter_for(cls, type_info: 'TypeInfo',
63
+ custom_converters: 'CustomArgumentConverters|None' = None,
64
+ languages: 'Languages|None' = None) -> 'TypeConverter|None':
65
+ if type_info.type is None:
65
66
  return None
66
- if isinstance(type_, str):
67
- try:
68
- type_ = cls._type_aliases[type_.lower()]
69
- except KeyError:
70
- return None
71
- used_type = type_
72
- if getattr(type_, '__origin__', None) and type_.__origin__ is not Union:
73
- type_ = type_.__origin__
74
67
  if custom_converters:
75
- info = custom_converters.get_converter_info(type_)
68
+ info = custom_converters.get_converter_info(type_info.type)
76
69
  if info:
77
- return CustomConverter(used_type, info)
78
- if type_ in cls._converters:
79
- return cls._converters[type_](used_type, custom_converters, languages)
70
+ return CustomConverter(type_info, info, languages)
71
+ if type_info.type in cls._converters:
72
+ return cls._converters[type_info.type](type_info, custom_converters, languages)
80
73
  for converter in cls._converters.values():
81
- if converter.handles(type_):
82
- return converter(used_type, custom_converters, languages)
74
+ if converter.handles(type_info):
75
+ return converter(type_info, custom_converters, languages)
83
76
  return None
84
77
 
85
78
  @classmethod
86
- def handles(cls, type_):
79
+ def handles(cls, type_info: 'TypeInfo') -> bool:
87
80
  handled = (cls.type, cls.abc) if cls.abc else cls.type
88
- return isinstance(type_, type) and issubclass(type_, handled)
81
+ return isinstance(type_info.type, type) and issubclass(type_info.type, handled)
89
82
 
90
- def convert(self, name, value, explicit_type=True, strict=True, kind='Argument'):
83
+ def convert(self, value: Any,
84
+ name: 'str|None' = None,
85
+ kind: str = 'Argument') -> Any:
91
86
  if self.no_conversion_needed(value):
92
87
  return value
93
88
  if not self._handles_value(value):
94
- return self._handle_error(name, value, kind, strict=strict)
89
+ return self._handle_error(value, name, kind)
95
90
  try:
96
91
  if not isinstance(value, str):
97
- return self._non_string_convert(value, explicit_type)
98
- return self._convert(value, explicit_type)
92
+ return self._non_string_convert(value)
93
+ return self._convert(value)
99
94
  except ValueError as error:
100
- return self._handle_error(name, value, kind, error, strict)
95
+ return self._handle_error(value, name, kind, error)
101
96
 
102
- def no_conversion_needed(self, value):
103
- used_type = getattr(self.used_type, '__origin__', self.used_type)
97
+ def no_conversion_needed(self, value: Any) -> bool:
104
98
  try:
105
- return isinstance(value, used_type)
99
+ return isinstance(value, self.type_info.type)
106
100
  except TypeError:
107
101
  # Used type wasn't a class. Compare to generic type instead.
108
- if self.type and self.type is not self.used_type:
102
+ if self.type and self.type is not self.type_info.type:
109
103
  return isinstance(value, self.type)
110
104
  raise
111
105
 
112
106
  def _handles_value(self, value):
113
107
  return isinstance(value, self.value_types)
114
108
 
115
- def _non_string_convert(self, value, explicit_type=True):
116
- return self._convert(value, explicit_type)
109
+ def _non_string_convert(self, value):
110
+ return self._convert(value)
117
111
 
118
- def _convert(self, value, explicit_type=True):
112
+ def _convert(self, value):
119
113
  raise NotImplementedError
120
114
 
121
- def _handle_error(self, name, value, kind, error=None, strict=True):
122
- if not strict:
123
- return value
115
+ def _handle_error(self, value, name, kind, error=None):
124
116
  value_type = '' if isinstance(value, str) else f' ({type_name(value)})'
125
117
  value = safe_str(value)
126
118
  ending = f': {error}' if (error and error.args) else '.'
127
119
  if name is None:
128
120
  raise ValueError(
129
- f"{kind} '{value}'{value_type} "
121
+ f"{kind.capitalize()} '{value}'{value_type} "
130
122
  f"cannot be converted to {self.type_name}{ending}"
131
123
  )
132
124
  raise ValueError(
133
- f"{kind} '{name}' got value '{value}'{value_type} that "
125
+ f"{kind.capitalize()} '{name}' got value '{value}'{value_type} that "
134
126
  f"cannot be converted to {self.type_name}{ending}"
135
127
  )
136
128
 
@@ -149,19 +141,6 @@ class TypeConverter:
149
141
  raise ValueError(f'Value is {type_name(value)}, not {expected.__name__}.')
150
142
  return value
151
143
 
152
- def _get_nested_types(self, type_hint, expected_count=None):
153
- types = getattr(type_hint, '__args__', ())
154
- # With generics from typing like Dict, __args__ is None with Python 3.6 and
155
- # contains TypeVars with 3.7-3.8. Newer versions don't have __args__ at all.
156
- # Subscripted usages like Dict[x, y].__args__ work fine with all.
157
- if not types or all(isinstance(a, TypeVar) for a in types):
158
- return ()
159
- if expected_count and len(types) != expected_count:
160
- raise TypeError(f'{type_hint.__name__}[] construct used as a type hint '
161
- f'requires exactly {expected_count} nested '
162
- f'type{s(expected_count)}, got {len(types)}.')
163
- return types
164
-
165
144
  def _remove_number_separators(self, value):
166
145
  if is_string(value):
167
146
  for sep in ' ', '_':
@@ -176,14 +155,14 @@ class EnumConverter(TypeConverter):
176
155
 
177
156
  @property
178
157
  def type_name(self):
179
- return self.used_type.__name__
158
+ return self.type_info.name
180
159
 
181
160
  @property
182
161
  def value_types(self):
183
- return (str, int) if issubclass(self.used_type, int) else (str,)
162
+ return (str, int) if issubclass(self.type_info.type, int) else (str,)
184
163
 
185
- def _convert(self, value, explicit_type=True):
186
- enum = self.used_type
164
+ def _convert(self, value):
165
+ enum = self.type_info.type
187
166
  if isinstance(value, int):
188
167
  return self._find_by_int_value(enum, value)
189
168
  try:
@@ -193,14 +172,14 @@ class EnumConverter(TypeConverter):
193
172
 
194
173
  def _find_by_normalized_name_or_int_value(self, enum, value):
195
174
  members = sorted(enum.__members__)
196
- matches = [m for m in members if eq(m, value, ignore='_')]
175
+ matches = [m for m in members if eq(m, value, ignore='_-')]
197
176
  if len(matches) == 1:
198
177
  return getattr(enum, matches[0])
199
178
  if len(matches) > 1:
200
179
  raise ValueError(f"{self.type_name} has multiple members matching "
201
180
  f"'{value}'. Available: {seq2str(matches)}")
202
181
  try:
203
- if issubclass(self.used_type, int):
182
+ if issubclass(self.type_info.type, int):
204
183
  return self._find_by_int_value(enum, value)
205
184
  except ValueError:
206
185
  members = [f'{m} ({getattr(enum, m)})' for m in members]
@@ -221,17 +200,16 @@ class EnumConverter(TypeConverter):
221
200
  class AnyConverter(TypeConverter):
222
201
  type = Any
223
202
  type_name = 'Any'
224
- aliases = ('any',)
225
203
  value_types = (Any,)
226
204
 
227
205
  @classmethod
228
- def handles(cls, type_):
229
- return type_ is Any
206
+ def handles(cls, type_info: 'TypeInfo'):
207
+ return type_info.type is Any
230
208
 
231
209
  def no_conversion_needed(self, value):
232
210
  return True
233
211
 
234
- def _convert(self, value, explicit_type=True):
212
+ def _convert(self, value):
235
213
  return value
236
214
 
237
215
  def _handles_value(self, value):
@@ -242,15 +220,12 @@ class AnyConverter(TypeConverter):
242
220
  class StringConverter(TypeConverter):
243
221
  type = str
244
222
  type_name = 'string'
245
- aliases = ('string', 'str', 'unicode')
246
223
  value_types = (Any,)
247
224
 
248
225
  def _handles_value(self, value):
249
226
  return True
250
227
 
251
- def _convert(self, value, explicit_type=True):
252
- if not explicit_type:
253
- return value
228
+ def _convert(self, value):
254
229
  try:
255
230
  return str(value)
256
231
  except Exception:
@@ -261,13 +236,12 @@ class StringConverter(TypeConverter):
261
236
  class BooleanConverter(TypeConverter):
262
237
  type = bool
263
238
  type_name = 'boolean'
264
- aliases = ('bool',)
265
239
  value_types = (str, int, float, NoneType)
266
240
 
267
- def _non_string_convert(self, value, explicit_type=True):
241
+ def _non_string_convert(self, value):
268
242
  return value
269
243
 
270
- def _convert(self, value, explicit_type=True):
244
+ def _convert(self, value):
271
245
  normalized = value.title()
272
246
  if normalized == 'None':
273
247
  return None
@@ -283,26 +257,29 @@ class IntegerConverter(TypeConverter):
283
257
  type = int
284
258
  abc = Integral
285
259
  type_name = 'integer'
286
- aliases = ('int', 'long')
287
260
  value_types = (str, float)
288
261
 
289
- def _non_string_convert(self, value, explicit_type=True):
262
+ def _non_string_convert(self, value):
290
263
  if value.is_integer():
291
264
  return int(value)
292
265
  raise ValueError('Conversion would lose precision.')
293
266
 
294
- def _convert(self, value, explicit_type=True):
267
+ def _convert(self, value):
295
268
  value = self._remove_number_separators(value)
296
269
  value, base = self._get_base(value)
297
270
  try:
298
271
  return int(value, base)
299
272
  except ValueError:
300
- if base == 10 and not explicit_type:
273
+ if base == 10:
301
274
  try:
302
- return float(value)
303
- except ValueError:
275
+ value, denominator = Decimal(value).as_integer_ratio()
276
+ except (InvalidOperation, ValueError, OverflowError):
304
277
  pass
305
- raise ValueError
278
+ else:
279
+ if denominator != 1:
280
+ raise ValueError('Conversion would lose precision.')
281
+ return value
282
+ raise ValueError
306
283
 
307
284
  def _get_base(self, value):
308
285
  value = value.lower()
@@ -319,10 +296,9 @@ class FloatConverter(TypeConverter):
319
296
  type = float
320
297
  abc = Real
321
298
  type_name = 'float'
322
- aliases = ('double',)
323
299
  value_types = (str, Real)
324
300
 
325
- def _convert(self, value, explicit_type=True):
301
+ def _convert(self, value):
326
302
  try:
327
303
  return float(self._remove_number_separators(value))
328
304
  except ValueError:
@@ -335,7 +311,7 @@ class DecimalConverter(TypeConverter):
335
311
  type_name = 'decimal'
336
312
  value_types = (str, int, float)
337
313
 
338
- def _convert(self, value, explicit_type=True):
314
+ def _convert(self, value):
339
315
  try:
340
316
  return Decimal(self._remove_number_separators(value))
341
317
  except InvalidOperation:
@@ -348,14 +324,13 @@ class DecimalConverter(TypeConverter):
348
324
  @TypeConverter.register
349
325
  class BytesConverter(TypeConverter):
350
326
  type = bytes
351
- abc = ByteString
352
327
  type_name = 'bytes'
353
328
  value_types = (str, bytearray)
354
329
 
355
- def _non_string_convert(self, value, explicit_type=True):
330
+ def _non_string_convert(self, value):
356
331
  return bytes(value)
357
332
 
358
- def _convert(self, value, explicit_type=True):
333
+ def _convert(self, value):
359
334
  try:
360
335
  return value.encode('latin-1')
361
336
  except UnicodeEncodeError as err:
@@ -369,10 +344,10 @@ class ByteArrayConverter(TypeConverter):
369
344
  type_name = 'bytearray'
370
345
  value_types = (str, bytes)
371
346
 
372
- def _non_string_convert(self, value, explicit_type=True):
347
+ def _non_string_convert(self, value):
373
348
  return bytearray(value)
374
349
 
375
- def _convert(self, value, explicit_type=True):
350
+ def _convert(self, value):
376
351
  try:
377
352
  return bytearray(value, 'latin-1')
378
353
  except UnicodeEncodeError as err:
@@ -386,7 +361,7 @@ class DateTimeConverter(TypeConverter):
386
361
  type_name = 'datetime'
387
362
  value_types = (str, int, float)
388
363
 
389
- def _convert(self, value, explicit_type=True):
364
+ def _convert(self, value):
390
365
  return convert_date(value, result_format='datetime')
391
366
 
392
367
 
@@ -395,7 +370,7 @@ class DateConverter(TypeConverter):
395
370
  type = date
396
371
  type_name = 'date'
397
372
 
398
- def _convert(self, value, explicit_type=True):
373
+ def _convert(self, value):
399
374
  dt = convert_date(value, result_format='datetime')
400
375
  if dt.hour or dt.minute or dt.second or dt.microsecond:
401
376
  raise ValueError("Value is datetime, not date.")
@@ -408,7 +383,7 @@ class TimeDeltaConverter(TypeConverter):
408
383
  type_name = 'timedelta'
409
384
  value_types = (str, int, float)
410
385
 
411
- def _convert(self, value, explicit_type=True):
386
+ def _convert(self, value):
412
387
  return convert_time(value, result_format='timedelta')
413
388
 
414
389
 
@@ -419,7 +394,7 @@ class PathConverter(TypeConverter):
419
394
  type_name = 'Path'
420
395
  value_types = (str, PurePath)
421
396
 
422
- def _convert(self, value, explicit_type=True):
397
+ def _convert(self, value):
423
398
  return Path(value)
424
399
 
425
400
 
@@ -429,10 +404,10 @@ class NoneConverter(TypeConverter):
429
404
  type_name = 'None'
430
405
 
431
406
  @classmethod
432
- def handles(cls, type_):
433
- return type_ in (NoneType, None)
407
+ def handles(cls, type_info: 'TypeInfo') -> bool:
408
+ return type_info.type in (NoneType, None)
434
409
 
435
- def _convert(self, value, explicit_type=True):
410
+ def _convert(self, value):
436
411
  if value.upper() == 'NONE':
437
412
  return None
438
413
  raise ValueError
@@ -445,35 +420,34 @@ class ListConverter(TypeConverter):
445
420
  abc = Sequence
446
421
  value_types = (str, Sequence)
447
422
 
448
- def __init__(self, used_type, custom_converters=None, languages=None):
449
- super().__init__(used_type, custom_converters, languages)
450
- types = self._get_nested_types(used_type, expected_count=1)
451
- if not types:
423
+ def __init__(self, type_info: 'TypeInfo',
424
+ custom_converters: 'CustomArgumentConverters|None' = None,
425
+ languages: 'Languages|None' = None):
426
+ super().__init__(type_info, custom_converters, languages)
427
+ nested = type_info.nested
428
+ if not nested:
452
429
  self.converter = None
453
430
  else:
454
- self.type_name = type_repr(used_type)
455
- self.converter = self.converter_for(types[0], custom_converters, languages)
456
-
457
- @classmethod
458
- def handles(cls, type_):
459
- # `type_ is not Tuple` is needed with Python 3.6.
460
- return super().handles(type_) and type_ is not Tuple
431
+ self.type_name = str(type_info)
432
+ self.converter = self.converter_for(nested[0], custom_converters, languages)
461
433
 
462
434
  def no_conversion_needed(self, value):
463
- if isinstance(value, str) or self.converter:
435
+ if isinstance(value, str) or not super().no_conversion_needed(value):
464
436
  return False
465
- return super().no_conversion_needed(value)
437
+ if not self.converter:
438
+ return True
439
+ return all(self.converter.no_conversion_needed(v) for v in value)
466
440
 
467
- def _non_string_convert(self, value, explicit_type=True):
468
- return self._convert_items(list(value), explicit_type)
441
+ def _non_string_convert(self, value):
442
+ return self._convert_items(list(value))
469
443
 
470
- def _convert(self, value, explicit_type=True):
471
- return self._convert_items(self._literal_eval(value, list), explicit_type)
444
+ def _convert(self, value):
445
+ return self._convert_items(self._literal_eval(value, list))
472
446
 
473
- def _convert_items(self, value, explicit_type):
447
+ def _convert_items(self, value):
474
448
  if not self.converter:
475
449
  return value
476
- return [self.converter.convert(i, v, explicit_type, kind='Item')
450
+ return [self.converter.convert(v, name=i, kind='Item')
477
451
  for i, v in enumerate(value)]
478
452
 
479
453
 
@@ -483,43 +457,53 @@ class TupleConverter(TypeConverter):
483
457
  type_name = 'tuple'
484
458
  value_types = (str, Sequence)
485
459
 
486
- def __init__(self, used_type, custom_converters=None, languages=None):
487
- super().__init__(used_type, custom_converters, languages)
460
+ def __init__(self, type_info: 'TypeInfo',
461
+ custom_converters: 'CustomArgumentConverters|None' = None,
462
+ languages: 'Languages|None' = None):
463
+ super().__init__(type_info, custom_converters, languages)
488
464
  self.converters = ()
489
465
  self.homogenous = False
490
- types = self._get_nested_types(used_type)
491
- if not types:
466
+ nested = type_info.nested
467
+ if not nested:
492
468
  return
493
- if types[-1] is Ellipsis:
494
- types = types[:-1]
495
- if len(types) != 1:
469
+ if nested[-1].type is Ellipsis:
470
+ nested = nested[:-1]
471
+ if len(nested) != 1:
496
472
  raise TypeError(f'Homogenous tuple used as a type hint requires '
497
- f'exactly one nested type, got {len(types)}.')
473
+ f'exactly one nested type, got {len(nested)}.')
498
474
  self.homogenous = True
499
- self.type_name = type_repr(used_type)
475
+ self.type_name = str(type_info)
500
476
  self.converters = tuple(self.converter_for(t, custom_converters, languages)
501
- for t in types)
477
+ or NullConverter() for t in nested)
502
478
 
503
479
  def no_conversion_needed(self, value):
504
- return super().no_conversion_needed(value) and not self.converters
480
+ if isinstance(value, str) or not super().no_conversion_needed(value):
481
+ return False
482
+ if not self.converters:
483
+ return True
484
+ if self.homogenous:
485
+ return all(self.converters[0].no_conversion_needed(v) for v in value)
486
+ if len(value) != len(self.converters):
487
+ return False
488
+ return all(c.no_conversion_needed(v) for c, v in zip(self.converters, value))
505
489
 
506
- def _non_string_convert(self, value, explicit_type=True):
507
- return self._convert_items(tuple(value), explicit_type)
490
+ def _non_string_convert(self, value):
491
+ return self._convert_items(tuple(value))
508
492
 
509
- def _convert(self, value, explicit_type=True):
510
- return self._convert_items(self._literal_eval(value, tuple), explicit_type)
493
+ def _convert(self, value):
494
+ return self._convert_items(self._literal_eval(value, tuple))
511
495
 
512
- def _convert_items(self, value, explicit_type):
496
+ def _convert_items(self, value):
513
497
  if not self.converters:
514
498
  return value
515
499
  if self.homogenous:
516
500
  conv = self.converters[0]
517
- return tuple(conv.convert(str(i), v, explicit_type, kind='Item')
501
+ return tuple(conv.convert(v, name=str(i), kind='Item')
518
502
  for i, v in enumerate(value))
519
503
  if len(self.converters) != len(value):
520
504
  raise ValueError(f'Expected {len(self.converters)} '
521
505
  f'item{s(self.converters)}, got {len(value)}.')
522
- return tuple(conv.convert(i, v, explicit_type, kind='Item')
506
+ return tuple(conv.convert(v, name=str(i), kind='Item')
523
507
  for i, (conv, v) in enumerate(zip(self.converters, value)))
524
508
 
525
509
 
@@ -527,26 +511,27 @@ class TupleConverter(TypeConverter):
527
511
  class TypedDictConverter(TypeConverter):
528
512
  type = 'TypedDict'
529
513
  value_types = (str, Mapping)
514
+ type_info: 'TypedDictInfo'
530
515
 
531
- def __init__(self, used_type, custom_converters, languages=None):
532
- super().__init__(used_type, custom_converters, languages)
516
+ def __init__(self, type_info: 'TypedDictInfo',
517
+ custom_converters: 'CustomArgumentConverters|None' = None,
518
+ languages: 'Languages|None' = None):
519
+ super().__init__(type_info, custom_converters, languages)
533
520
  self.converters = {n: self.converter_for(t, custom_converters, languages)
534
- for n, t in used_type.__annotations__.items()}
535
- self.type_name = used_type.__name__
536
- # __required_keys__ is new in Python 3.9.
537
- self.required_keys = getattr(used_type, '__required_keys__', frozenset())
521
+ for n, t in type_info.annotations.items()}
522
+ self.type_name = type_info.name
538
523
 
539
524
  @classmethod
540
- def handles(cls, type_):
541
- return isinstance(type_, typeddict_types)
525
+ def handles(cls, type_info: 'TypeInfo') -> bool:
526
+ return type_info.is_typed_dict
542
527
 
543
528
  def no_conversion_needed(self, value):
544
529
  return False
545
530
 
546
- def _non_string_convert(self, value, explicit_type=True):
531
+ def _non_string_convert(self, value):
547
532
  return self._convert_items(value)
548
533
 
549
- def _convert(self, value, explicit_type=True):
534
+ def _convert(self, value):
550
535
  return self._convert_items(self._literal_eval(value, dict))
551
536
 
552
537
  def _convert_items(self, value):
@@ -558,14 +543,14 @@ class TypedDictConverter(TypeConverter):
558
543
  not_allowed.append(key)
559
544
  else:
560
545
  if converter:
561
- value[key] = converter.convert(key, value[key], kind='Item')
546
+ value[key] = converter.convert(value[key], name=key, kind='Item')
562
547
  if not_allowed:
563
548
  error = f'Item{s(not_allowed)} {seq2str(sorted(not_allowed))} not allowed.'
564
549
  available = [key for key in self.converters if key not in value]
565
550
  if available:
566
551
  error += f' Available item{s(available)}: {seq2str(sorted(available))}'
567
552
  raise ValueError(error)
568
- missing = [key for key in self.required_keys if key not in value]
553
+ missing = [key for key in self.type_info.required if key not in value]
569
554
  if missing:
570
555
  raise ValueError(f"Required item{s(missing)} "
571
556
  f"{seq2str(sorted(missing))} missing.")
@@ -577,46 +562,50 @@ class DictionaryConverter(TypeConverter):
577
562
  type = dict
578
563
  abc = Mapping
579
564
  type_name = 'dictionary'
580
- aliases = ('dict', 'map')
581
565
  value_types = (str, Mapping)
582
566
 
583
- def __init__(self, used_type, custom_converters=None, languages=None):
584
- super().__init__(used_type, custom_converters, languages)
585
- types = self._get_nested_types(used_type, expected_count=2)
586
- if not types:
567
+ def __init__(self, type_info: 'TypeInfo',
568
+ custom_converters: 'CustomArgumentConverters|None' = None,
569
+ languages: 'Languages|None' = None):
570
+ super().__init__(type_info, custom_converters, languages)
571
+ nested = type_info.nested
572
+ if not nested:
587
573
  self.converters = ()
588
574
  else:
589
- self.type_name = type_repr(used_type)
575
+ self.type_name = str(type_info)
590
576
  self.converters = tuple(self.converter_for(t, custom_converters, languages)
591
- for t in types)
577
+ or NullConverter() for t in nested)
592
578
 
593
579
  def no_conversion_needed(self, value):
594
- return super().no_conversion_needed(value) and not self.converters
580
+ if isinstance(value, str) or not super().no_conversion_needed(value):
581
+ return False
582
+ if not self.converters:
583
+ return True
584
+ no_key_conversion_needed = self.converters[0].no_conversion_needed
585
+ no_value_conversion_needed = self.converters[1].no_conversion_needed
586
+ return all(no_key_conversion_needed(k) and no_value_conversion_needed(v)
587
+ for k, v in value.items())
595
588
 
596
- def _non_string_convert(self, value, explicit_type=True):
589
+ def _non_string_convert(self, value):
597
590
  if self._used_type_is_dict() and not isinstance(value, dict):
598
591
  value = dict(value)
599
- return self._convert_items(value, explicit_type)
592
+ return self._convert_items(value)
600
593
 
601
594
  def _used_type_is_dict(self):
602
- used_type = getattr(self.used_type, '__origin__', self.used_type)
603
- return issubclass(used_type, dict)
595
+ return issubclass(self.type_info.type, dict)
604
596
 
605
- def _convert(self, value, explicit_type=True):
606
- return self._convert_items(self._literal_eval(value, dict), explicit_type)
597
+ def _convert(self, value):
598
+ return self._convert_items(self._literal_eval(value, dict))
607
599
 
608
- def _convert_items(self, value, explicit_type):
600
+ def _convert_items(self, value):
609
601
  if not self.converters:
610
602
  return value
611
- convert_key = self.__get_converter(self.converters[0], explicit_type, 'Key')
612
- convert_value = self.__get_converter(self.converters[1], explicit_type, 'Item')
613
- return {convert_key(None, k): convert_value(str(k), v) for k, v in value.items()}
603
+ convert_key = self._get_converter(self.converters[0], 'Key')
604
+ convert_value = self._get_converter(self.converters[1], 'Item')
605
+ return {convert_key(None, k): convert_value(k, v) for k, v in value.items()}
614
606
 
615
- def __get_converter(self, converter, explicit_type, kind):
616
- if not converter:
617
- return lambda name, value: value
618
- return lambda name, value: converter.convert(name, value, explicit_type,
619
- kind=kind)
607
+ def _get_converter(self, converter, kind):
608
+ return lambda name, value: converter.convert(value, name, kind=kind)
620
609
 
621
610
 
622
611
  @TypeConverter.register
@@ -626,29 +615,34 @@ class SetConverter(TypeConverter):
626
615
  type_name = 'set'
627
616
  value_types = (str, Container)
628
617
 
629
- def __init__(self, used_type, custom_converters=None, languages=None):
630
- super().__init__(used_type, custom_converters, languages)
631
- types = self._get_nested_types(used_type, expected_count=1)
632
- if not types:
618
+ def __init__(self, type_info: 'TypeInfo',
619
+ custom_converters: 'CustomArgumentConverters|None' = None,
620
+ languages: 'Languages|None' = None):
621
+ super().__init__(type_info, custom_converters, languages)
622
+ nested = type_info.nested
623
+ if not nested:
633
624
  self.converter = None
634
625
  else:
635
- self.type_name = type_repr(used_type)
636
- self.converter = self.converter_for(types[0], custom_converters, languages)
626
+ self.type_name = str(type_info)
627
+ self.converter = self.converter_for(nested[0], custom_converters, languages)
637
628
 
638
629
  def no_conversion_needed(self, value):
639
- return super().no_conversion_needed(value) and not self.converter
630
+ if isinstance(value, str) or not super().no_conversion_needed(value):
631
+ return False
632
+ if not self.converter:
633
+ return True
634
+ return all(self.converter.no_conversion_needed(v) for v in value)
640
635
 
641
- def _non_string_convert(self, value, explicit_type=True):
642
- return self._convert_items(set(value), explicit_type)
636
+ def _non_string_convert(self, value):
637
+ return self._convert_items(set(value))
643
638
 
644
- def _convert(self, value, explicit_type=True):
645
- return self._convert_items(self._literal_eval(value, set), explicit_type)
639
+ def _convert(self, value):
640
+ return self._convert_items(self._literal_eval(value, set))
646
641
 
647
- def _convert_items(self, value, explicit_type):
642
+ def _convert_items(self, value):
648
643
  if not self.converter:
649
644
  return value
650
- return {self.converter.convert(None, v, explicit_type, kind='Item')
651
- for v in value}
645
+ return {self.converter.convert(v, kind='Item') for v in value}
652
646
 
653
647
 
654
648
  @TypeConverter.register
@@ -656,68 +650,61 @@ class FrozenSetConverter(SetConverter):
656
650
  type = frozenset
657
651
  type_name = 'frozenset'
658
652
 
659
- def _non_string_convert(self, value, explicit_type=True):
660
- return frozenset(super()._non_string_convert(value, explicit_type))
653
+ def _non_string_convert(self, value):
654
+ return frozenset(super()._non_string_convert(value))
661
655
 
662
- def _convert(self, value, explicit_type=True):
656
+ def _convert(self, value):
663
657
  # There are issues w/ literal_eval. See self._literal_eval for details.
664
658
  if value == 'frozenset()':
665
659
  return frozenset()
666
- return frozenset(super()._convert(value, explicit_type))
660
+ return frozenset(super()._convert(value))
667
661
 
668
662
 
669
663
  @TypeConverter.register
670
- class CombinedConverter(TypeConverter):
664
+ class UnionConverter(TypeConverter):
671
665
  type = Union
672
666
 
673
- def __init__(self, union, custom_converters, languages=None):
674
- super().__init__(self._get_types(union))
675
- self.converters = tuple(self.converter_for(t, custom_converters, languages)
676
- for t in self.used_type)
677
-
678
- def _get_types(self, union):
679
- if not union:
680
- return ()
681
- if isinstance(union, tuple):
682
- return union
683
- if has_args(union):
684
- return union.__args__
685
- return ()
667
+ def __init__(self, type_info: 'TypeInfo',
668
+ custom_converters: 'CustomArgumentConverters|None' = None,
669
+ languages: 'Languages|None' = None):
670
+ super().__init__(type_info, custom_converters, languages)
671
+ self.converters = tuple(self.converter_for(info, custom_converters, languages)
672
+ for info in type_info.nested)
673
+ if not self.converters:
674
+ raise TypeError('Union used as a type hint cannot be empty.')
686
675
 
687
676
  @property
688
677
  def type_name(self):
689
- if not self.used_type:
690
- return 'union'
691
- return ' or '.join(type_name(t) for t in self.used_type)
678
+ if not self.converters:
679
+ return 'Union'
680
+ return seq2str([c.type_name for c in self.converters], quote='', lastsep=' or ')
692
681
 
693
682
  @classmethod
694
- def handles(cls, type_):
695
- return is_union(type_, allow_tuple=True)
683
+ def handles(cls, type_info: 'TypeInfo') -> bool:
684
+ return type_info.is_union
696
685
 
697
686
  def _handles_value(self, value):
698
687
  return True
699
688
 
700
689
  def no_conversion_needed(self, value):
701
- for converter, type_ in zip(self.converters, self.used_type):
690
+ for converter, info in zip(self.converters, self.type_info.nested):
702
691
  if converter:
703
692
  if converter.no_conversion_needed(value):
704
693
  return True
705
694
  else:
706
695
  try:
707
- if isinstance(value, type_):
696
+ if isinstance(value, info.type):
708
697
  return True
709
698
  except TypeError:
710
699
  pass
711
700
  return False
712
701
 
713
- def _convert(self, value, explicit_type=True):
714
- if not self.used_type:
715
- raise ValueError('Cannot have union without types.')
702
+ def _convert(self, value):
716
703
  unrecognized_types = False
717
704
  for converter in self.converters:
718
705
  if converter:
719
706
  try:
720
- return converter.convert('', value, explicit_type)
707
+ return converter.convert(value)
721
708
  except ValueError:
722
709
  pass
723
710
  else:
@@ -727,10 +714,62 @@ class CombinedConverter(TypeConverter):
727
714
  raise ValueError
728
715
 
729
716
 
717
+ @TypeConverter.register
718
+ class LiteralConverter(TypeConverter):
719
+ type = Literal
720
+ type_name = 'Literal'
721
+ value_types = (Any,)
722
+
723
+ def __init__(self, type_info: 'TypeInfo',
724
+ custom_converters: 'CustomArgumentConverters|None' = None,
725
+ languages: 'Languages|None' = None):
726
+ super().__init__(type_info, custom_converters, languages)
727
+ self.converters = [(info.type, self.literal_converter_for(info, languages))
728
+ for info in type_info.nested]
729
+ self.type_name = seq2str([info.name for info in type_info.nested],
730
+ quote='', lastsep=' or ')
731
+
732
+ def literal_converter_for(self, type_info: 'TypeInfo',
733
+ languages: 'Languages|None' = None) -> TypeConverter:
734
+ type_info = type(type_info)(type_info.name, type(type_info.type))
735
+ return self.converter_for(type_info, languages=languages)
736
+
737
+ @classmethod
738
+ def handles(cls, type_info: 'TypeInfo') -> bool:
739
+ return type_info.type is Literal
740
+
741
+ def no_conversion_needed(self, value: Any) -> bool:
742
+ return False
743
+
744
+ def _handles_value(self, value):
745
+ return True
746
+
747
+ def _convert(self, value):
748
+ matches = []
749
+ for expected, converter in self.converters:
750
+ if value == expected and type(value) is type(expected):
751
+ return expected
752
+ try:
753
+ converted = converter.convert(value)
754
+ except ValueError:
755
+ pass
756
+ else:
757
+ if (isinstance(expected, str) and eq(converted, expected, ignore='_-')
758
+ or converted == expected):
759
+ matches.append(expected)
760
+ if len(matches) == 1:
761
+ return matches[0]
762
+ if matches:
763
+ raise ValueError('No unique match found.')
764
+ raise ValueError
765
+
766
+
730
767
  class CustomConverter(TypeConverter):
731
768
 
732
- def __init__(self, used_type, converter_info, languages=None):
733
- super().__init__(used_type, languages=languages)
769
+ def __init__(self, type_info: 'TypeInfo',
770
+ converter_info: 'ConverterInfo',
771
+ languages: 'Languages|None' = None):
772
+ super().__init__(type_info, languages=languages)
734
773
  self.converter_info = converter_info
735
774
 
736
775
  @property
@@ -748,10 +787,19 @@ class CustomConverter(TypeConverter):
748
787
  def _handles_value(self, value):
749
788
  return not self.value_types or isinstance(value, self.value_types)
750
789
 
751
- def _convert(self, value, explicit_type=True):
790
+ def _convert(self, value):
752
791
  try:
753
792
  return self.converter_info.convert(value)
754
793
  except ValueError:
755
794
  raise
756
795
  except Exception:
757
796
  raise ValueError(get_error_message())
797
+
798
+
799
+ class NullConverter:
800
+
801
+ def convert(self, value, name, kind='Argument'):
802
+ return value
803
+
804
+ def no_conversion_needed(self, value):
805
+ return True