robotframework 6.1.1__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.1.1 → robotframework-7.0}/INSTALL.rst +25 -25
  2. {robotframework-6.1.1 → robotframework-7.0}/PKG-INFO +6 -8
  3. {robotframework-6.1.1 → robotframework-7.0}/README.rst +3 -2
  4. {robotframework-6.1.1 → robotframework-7.0}/setup.py +3 -6
  5. {robotframework-6.1.1 → robotframework-7.0}/src/robot/api/__init__.py +4 -1
  6. {robotframework-6.1.1 → robotframework-7.0}/src/robot/api/deco.py +60 -14
  7. {robotframework-6.1.1 → robotframework-7.0}/src/robot/api/exceptions.py +6 -6
  8. {robotframework-6.1.1 → robotframework-7.0}/src/robot/api/interfaces.py +402 -67
  9. {robotframework-6.1.1 → robotframework-7.0}/src/robot/api/logger.py +27 -20
  10. {robotframework-6.1.1 → robotframework-7.0}/src/robot/api/parsing.py +4 -2
  11. robotframework-7.0/src/robot/api/py.typed +0 -0
  12. {robotframework-6.1.1 → robotframework-7.0}/src/robot/conf/gatherfailed.py +2 -2
  13. {robotframework-6.1.1 → robotframework-7.0}/src/robot/conf/languages.py +0 -9
  14. {robotframework-6.1.1 → robotframework-7.0}/src/robot/conf/settings.py +21 -14
  15. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/common/storage.js +11 -6
  16. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/htmlfilewriter.py +1 -1
  17. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/libdoc/libdoc.css +10 -2
  18. {robotframework-6.1.1 → 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.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/doc_formatting.css +13 -7
  21. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/log.css +51 -10
  22. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/log.html +14 -23
  23. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/model.js +2 -4
  24. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/report.css +83 -19
  25. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/report.html +22 -7
  26. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/testdata.js +10 -3
  27. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/view.js +84 -0
  28. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/template.py +3 -3
  29. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/builder.py +0 -8
  30. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/datatypes.py +9 -10
  31. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/htmlutils.py +4 -7
  32. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/jsonbuilder.py +38 -20
  33. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/model.py +21 -28
  34. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/robotbuilder.py +50 -31
  35. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/standardtypes.py +9 -1
  36. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/xmlbuilder.py +35 -20
  37. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/xmlwriter.py +18 -38
  38. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/BuiltIn.py +255 -205
  39. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/Collections.py +384 -240
  40. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/DateTime.py +73 -60
  41. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/OperatingSystem.py +6 -5
  42. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/Process.py +26 -27
  43. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/Remote.py +40 -36
  44. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/String.py +66 -76
  45. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/XML.py +66 -59
  46. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/__init__.py +2 -2
  47. {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/__init__.py +5 -5
  48. {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/body.py +44 -13
  49. {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/configurer.py +15 -11
  50. {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/control.py +226 -84
  51. {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/filter.py +31 -25
  52. {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/itemlist.py +9 -8
  53. robotframework-7.0/src/robot/model/keyword.py +77 -0
  54. {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/message.py +19 -10
  55. {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/modelobject.py +25 -7
  56. {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/namepatterns.py +3 -25
  57. {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/stats.py +9 -15
  58. {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/tags.py +1 -1
  59. {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/testcase.py +15 -27
  60. {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/testsuite.py +17 -26
  61. {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/visitor.py +35 -8
  62. robotframework-7.0/src/robot/output/console/dotted.py +90 -0
  63. {robotframework-6.1.1 → robotframework-7.0}/src/robot/output/console/quiet.py +3 -2
  64. {robotframework-6.1.1 → robotframework-7.0}/src/robot/output/console/verbose.py +61 -61
  65. {robotframework-6.1.1 → robotframework-7.0}/src/robot/output/debugfile.py +39 -24
  66. {robotframework-6.1.1 → robotframework-7.0}/src/robot/output/filelogger.py +18 -15
  67. {robotframework-6.1.1 → robotframework-7.0}/src/robot/output/librarylogger.py +3 -2
  68. robotframework-7.0/src/robot/output/listeners.py +753 -0
  69. {robotframework-6.1.1 → robotframework-7.0}/src/robot/output/logger.py +216 -80
  70. robotframework-7.0/src/robot/output/loggerapi.py +215 -0
  71. {robotframework-6.1.1 → robotframework-7.0}/src/robot/output/loggerhelper.py +23 -56
  72. robotframework-7.0/src/robot/output/output.py +185 -0
  73. {robotframework-6.1.1 → robotframework-7.0}/src/robot/output/stdoutlogsplitter.py +8 -5
  74. robotframework-7.0/src/robot/output/xmllogger.py +459 -0
  75. {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/lexer/blocklexers.py +17 -13
  76. {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/lexer/context.py +12 -2
  77. {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/lexer/lexer.py +1 -1
  78. {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/lexer/settings.py +6 -3
  79. {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/lexer/statementlexers.py +39 -10
  80. {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/lexer/tokens.py +27 -29
  81. {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/model/blocks.py +19 -6
  82. {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/model/statements.py +193 -94
  83. robotframework-7.0/src/robot/parsing/model/visitor.py +100 -0
  84. {robotframework-6.1.1 → robotframework-7.0}/src/robot/rebot.py +2 -0
  85. {robotframework-6.1.1 → robotframework-7.0}/src/robot/reporting/expandkeywordmatcher.py +1 -1
  86. {robotframework-6.1.1 → robotframework-7.0}/src/robot/reporting/jsbuildingcontext.py +8 -6
  87. {robotframework-6.1.1 → robotframework-7.0}/src/robot/reporting/jsmodelbuilders.py +88 -61
  88. {robotframework-6.1.1 → robotframework-7.0}/src/robot/reporting/logreportwriters.py +16 -10
  89. {robotframework-6.1.1 → robotframework-7.0}/src/robot/reporting/outputwriter.py +18 -2
  90. {robotframework-6.1.1 → robotframework-7.0}/src/robot/reporting/resultwriter.py +4 -4
  91. {robotframework-6.1.1 → robotframework-7.0}/src/robot/reporting/stringcache.py +3 -3
  92. {robotframework-6.1.1 → robotframework-7.0}/src/robot/reporting/xunitwriter.py +15 -21
  93. {robotframework-6.1.1 → robotframework-7.0}/src/robot/result/__init__.py +3 -2
  94. {robotframework-6.1.1 → robotframework-7.0}/src/robot/result/configurer.py +12 -9
  95. {robotframework-6.1.1 → robotframework-7.0}/src/robot/result/executionresult.py +56 -8
  96. {robotframework-6.1.1 → robotframework-7.0}/src/robot/result/flattenkeywordmatcher.py +48 -9
  97. robotframework-7.0/src/robot/result/keywordremover.py +207 -0
  98. {robotframework-6.1.1 → robotframework-7.0}/src/robot/result/merger.py +1 -1
  99. robotframework-7.0/src/robot/result/model.py +1185 -0
  100. {robotframework-6.1.1 → robotframework-7.0}/src/robot/result/modeldeprecation.py +9 -3
  101. {robotframework-6.1.1 → robotframework-7.0}/src/robot/result/resultbuilder.py +46 -36
  102. {robotframework-6.1.1 → robotframework-7.0}/src/robot/result/xmlelementhandlers.py +83 -43
  103. {robotframework-6.1.1 → robotframework-7.0}/src/robot/run.py +2 -0
  104. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/__init__.py +14 -4
  105. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/arguments/__init__.py +2 -1
  106. robotframework-7.0/src/robot/running/arguments/argumentconverter.py +100 -0
  107. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/arguments/argumentmapper.py +26 -24
  108. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/arguments/argumentparser.py +82 -60
  109. robotframework-7.0/src/robot/running/arguments/argumentresolver.py +158 -0
  110. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/arguments/argumentspec.py +83 -116
  111. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/arguments/argumentvalidator.py +33 -27
  112. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/arguments/customconverters.py +15 -12
  113. robotframework-7.0/src/robot/running/arguments/embedded.py +145 -0
  114. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/arguments/typeconverters.py +233 -213
  115. robotframework-7.0/src/robot/running/arguments/typeinfo.py +317 -0
  116. robotframework-7.0/src/robot/running/arguments/typeinfoparser.py +219 -0
  117. robotframework-7.0/src/robot/running/arguments/typevalidator.py +60 -0
  118. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/bodyrunner.py +147 -129
  119. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/builder/builders.py +2 -1
  120. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/builder/parsers.py +10 -11
  121. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/builder/settings.py +9 -17
  122. robotframework-7.0/src/robot/running/builder/transformers.py +535 -0
  123. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/context.py +113 -31
  124. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/dynamicmethods.py +62 -34
  125. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/importer.py +27 -49
  126. robotframework-7.0/src/robot/running/invalidkeyword.py +67 -0
  127. robotframework-7.0/src/robot/running/keywordfinder.py +91 -0
  128. robotframework-7.0/src/robot/running/keywordimplementation.py +164 -0
  129. robotframework-7.0/src/robot/running/librarykeyword.py +392 -0
  130. robotframework-7.0/src/robot/running/librarykeywordrunner.py +250 -0
  131. robotframework-7.0/src/robot/running/libraryscopes.py +115 -0
  132. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/model.py +195 -377
  133. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/namespace.py +124 -137
  134. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/outputcapture.py +20 -12
  135. robotframework-7.0/src/robot/running/resourcemodel.py +448 -0
  136. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/statusreporter.py +16 -13
  137. robotframework-7.0/src/robot/running/suiterunner.py +265 -0
  138. robotframework-7.0/src/robot/running/testlibraries.py +500 -0
  139. robotframework-7.0/src/robot/running/userkeywordrunner.py +260 -0
  140. {robotframework-6.1.1 → robotframework-7.0}/src/robot/testdoc.py +18 -13
  141. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/__init__.py +53 -35
  142. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/connectioncache.py +64 -59
  143. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/dotdict.py +3 -0
  144. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/encodingsniffer.py +1 -1
  145. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/escaping.py +19 -19
  146. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/importer.py +2 -2
  147. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/markupwriters.py +23 -15
  148. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/misc.py +1 -2
  149. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/normalizing.py +9 -24
  150. robotframework-7.0/src/robot/utils/notset.py +33 -0
  151. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/platform.py +15 -5
  152. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/robotio.py +9 -9
  153. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/robotpath.py +1 -0
  154. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/robottime.py +122 -90
  155. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/robottypes.py +21 -31
  156. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/setter.py +0 -5
  157. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/text.py +7 -4
  158. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/unic.py +2 -2
  159. {robotframework-6.1.1 → robotframework-7.0}/src/robot/variables/__init__.py +2 -2
  160. {robotframework-6.1.1 → robotframework-7.0}/src/robot/variables/assigner.py +17 -19
  161. {robotframework-6.1.1 → robotframework-7.0}/src/robot/variables/evaluation.py +20 -17
  162. {robotframework-6.1.1 → robotframework-7.0}/src/robot/variables/filesetter.py +80 -80
  163. {robotframework-6.1.1 → robotframework-7.0}/src/robot/variables/replacer.py +33 -36
  164. {robotframework-6.1.1 → robotframework-7.0}/src/robot/variables/scopes.py +17 -12
  165. {robotframework-6.1.1 → robotframework-7.0}/src/robot/variables/search.py +66 -41
  166. {robotframework-6.1.1 → robotframework-7.0}/src/robot/variables/store.py +14 -16
  167. robotframework-7.0/src/robot/variables/tablesetter.py +164 -0
  168. {robotframework-6.1.1 → robotframework-7.0}/src/robot/variables/variables.py +1 -1
  169. {robotframework-6.1.1 → robotframework-7.0}/src/robot/version.py +1 -1
  170. {robotframework-6.1.1 → robotframework-7.0}/src/robotframework.egg-info/PKG-INFO +6 -8
  171. {robotframework-6.1.1 → robotframework-7.0}/src/robotframework.egg-info/SOURCES.txt +10 -8
  172. {robotframework-6.1.1 → robotframework-7.0}/tasks.py +6 -6
  173. robotframework-6.1.1/src/robot/htmldata/rebot/common.css +0 -239
  174. robotframework-6.1.1/src/robot/libraries/Reserved.py +0 -48
  175. robotframework-6.1.1/src/robot/model/keyword.py +0 -173
  176. robotframework-6.1.1/src/robot/output/console/dotted.py +0 -90
  177. robotframework-6.1.1/src/robot/output/listenerarguments.py +0 -165
  178. robotframework-6.1.1/src/robot/output/listenermethods.py +0 -113
  179. robotframework-6.1.1/src/robot/output/listeners.py +0 -174
  180. robotframework-6.1.1/src/robot/output/output.py +0 -95
  181. robotframework-6.1.1/src/robot/output/xmllogger.py +0 -354
  182. robotframework-6.1.1/src/robot/parsing/model/visitor.py +0 -67
  183. robotframework-6.1.1/src/robot/result/keywordremover.py +0 -183
  184. robotframework-6.1.1/src/robot/result/model.py +0 -957
  185. robotframework-6.1.1/src/robot/running/arguments/argumentconverter.py +0 -79
  186. robotframework-6.1.1/src/robot/running/arguments/argumentresolver.py +0 -131
  187. robotframework-6.1.1/src/robot/running/arguments/embedded.py +0 -146
  188. robotframework-6.1.1/src/robot/running/arguments/typevalidator.py +0 -56
  189. robotframework-6.1.1/src/robot/running/builder/transformers.py +0 -642
  190. robotframework-6.1.1/src/robot/running/handlers.py +0 -321
  191. robotframework-6.1.1/src/robot/running/handlerstore.py +0 -66
  192. robotframework-6.1.1/src/robot/running/librarykeywordrunner.py +0 -238
  193. robotframework-6.1.1/src/robot/running/libraryscopes.py +0 -97
  194. robotframework-6.1.1/src/robot/running/modelcombiner.py +0 -32
  195. robotframework-6.1.1/src/robot/running/suiterunner.py +0 -248
  196. robotframework-6.1.1/src/robot/running/testlibraries.py +0 -423
  197. robotframework-6.1.1/src/robot/running/usererrorhandler.py +0 -75
  198. robotframework-6.1.1/src/robot/running/userkeyword.py +0 -111
  199. robotframework-6.1.1/src/robot/running/userkeywordrunner.py +0 -274
  200. robotframework-6.1.1/src/robot/variables/tablesetter.py +0 -156
  201. {robotframework-6.1.1 → robotframework-7.0}/AUTHORS.rst +0 -0
  202. {robotframework-6.1.1 → robotframework-7.0}/BUILD.rst +0 -0
  203. {robotframework-6.1.1 → robotframework-7.0}/CONTRIBUTING.rst +0 -0
  204. {robotframework-6.1.1 → robotframework-7.0}/COPYRIGHT.txt +0 -0
  205. {robotframework-6.1.1 → robotframework-7.0}/LICENSE.txt +0 -0
  206. {robotframework-6.1.1 → robotframework-7.0}/MANIFEST.in +0 -0
  207. {robotframework-6.1.1 → robotframework-7.0}/setup.cfg +0 -0
  208. {robotframework-6.1.1 → robotframework-7.0}/src/robot/__init__.py +0 -0
  209. {robotframework-6.1.1 → robotframework-7.0}/src/robot/__main__.py +0 -0
  210. {robotframework-6.1.1 → robotframework-7.0}/src/robot/conf/__init__.py +0 -0
  211. {robotframework-6.1.1 → robotframework-7.0}/src/robot/errors.py +0 -0
  212. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/__init__.py +0 -0
  213. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/common/__init__.py +0 -0
  214. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/common/js_disabled.css +0 -0
  215. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/jsonwriter.py +0 -0
  216. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/lib/__init__.py +0 -0
  217. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/lib/jquery.highlight.min.js +0 -0
  218. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/lib/jquery.min.js +0 -0
  219. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/lib/jquery.tablesorter.min.js +0 -0
  220. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/lib/jquery.tmpl.min.js +0 -0
  221. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/lib/jsxcompressor.min.js +0 -0
  222. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/libdoc/__init__.py +0 -0
  223. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/libdoc/doc_formatting.css +0 -0
  224. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/libdoc/print.css +0 -0
  225. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/libdoc/pygments.css +0 -0
  226. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/__init__.py +0 -0
  227. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/fileloading.js +0 -0
  228. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/log.js +0 -0
  229. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/print.css +0 -0
  230. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/util.js +0 -0
  231. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/testdoc/__init__.py +0 -0
  232. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/testdoc/testdoc.css +0 -0
  233. {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/testdoc/testdoc.html +0 -0
  234. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdoc.py +0 -0
  235. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/__init__.py +0 -0
  236. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/consoleviewer.py +0 -0
  237. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/htmlwriter.py +0 -0
  238. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/jsonwriter.py +0 -0
  239. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/output.py +0 -0
  240. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/writer.py +0 -0
  241. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/Dialogs.py +0 -0
  242. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/Easter.py +0 -0
  243. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/Screenshot.py +0 -0
  244. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/Telnet.py +0 -0
  245. {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/dialogs_py.py +0 -0
  246. {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/fixture.py +0 -0
  247. {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/metadata.py +0 -0
  248. {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/modifier.py +0 -0
  249. {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/statistics.py +0 -0
  250. {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/suitestatistics.py +0 -0
  251. {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/tagsetter.py +0 -0
  252. {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/tagstatistics.py +0 -0
  253. {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/totalstatistics.py +0 -0
  254. {robotframework-6.1.1 → robotframework-7.0}/src/robot/output/__init__.py +0 -0
  255. {robotframework-6.1.1 → robotframework-7.0}/src/robot/output/console/__init__.py +0 -0
  256. {robotframework-6.1.1 → robotframework-7.0}/src/robot/output/console/highlighting.py +0 -0
  257. {robotframework-6.1.1 → robotframework-7.0}/src/robot/output/pyloggingconf.py +0 -0
  258. {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/__init__.py +0 -0
  259. {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/lexer/__init__.py +0 -0
  260. {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/lexer/tokenizer.py +0 -0
  261. {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/model/__init__.py +0 -0
  262. {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/parser/__init__.py +0 -0
  263. {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/parser/blockparsers.py +0 -0
  264. {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/parser/fileparser.py +0 -0
  265. {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/parser/parser.py +0 -0
  266. {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/suitestructure.py +0 -0
  267. {robotframework-6.1.1 → robotframework-7.0}/src/robot/pythonpathsetter.py +0 -0
  268. {robotframework-6.1.1 → robotframework-7.0}/src/robot/reporting/__init__.py +0 -0
  269. {robotframework-6.1.1 → robotframework-7.0}/src/robot/reporting/jsexecutionresult.py +0 -0
  270. {robotframework-6.1.1 → robotframework-7.0}/src/robot/reporting/jswriter.py +0 -0
  271. {robotframework-6.1.1 → robotframework-7.0}/src/robot/result/executionerrors.py +0 -0
  272. {robotframework-6.1.1 → robotframework-7.0}/src/robot/result/messagefilter.py +0 -0
  273. {robotframework-6.1.1 → robotframework-7.0}/src/robot/result/suiteteardownfailed.py +0 -0
  274. {robotframework-6.1.1 → robotframework-7.0}/src/robot/result/visitor.py +0 -0
  275. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/builder/__init__.py +0 -0
  276. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/randomizer.py +0 -0
  277. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/runkwregister.py +0 -0
  278. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/signalhandler.py +0 -0
  279. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/status.py +0 -0
  280. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/timeouts/__init__.py +0 -0
  281. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/timeouts/posix.py +0 -0
  282. {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/timeouts/windows.py +0 -0
  283. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/application.py +0 -0
  284. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/argumentparser.py +0 -0
  285. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/asserts.py +0 -0
  286. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/charwidth.py +0 -0
  287. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/compress.py +0 -0
  288. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/encoding.py +0 -0
  289. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/error.py +0 -0
  290. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/etreewrapper.py +0 -0
  291. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/filereader.py +0 -0
  292. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/frange.py +0 -0
  293. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/htmlformatters.py +0 -0
  294. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/markuputils.py +0 -0
  295. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/match.py +0 -0
  296. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/recommendations.py +0 -0
  297. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/restreader.py +0 -0
  298. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/robotenv.py +0 -0
  299. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/robotinspect.py +0 -0
  300. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/sortable.py +0 -0
  301. {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/typehints.py +0 -0
  302. {robotframework-6.1.1 → robotframework-7.0}/src/robot/variables/finders.py +0 -0
  303. {robotframework-6.1.1 → robotframework-7.0}/src/robot/variables/notfound.py +0 -0
  304. {robotframework-6.1.1 → robotframework-7.0}/src/robot/variables/resolvable.py +0 -0
  305. {robotframework-6.1.1 → robotframework-7.0}/src/robotframework.egg-info/dependency_links.txt +0 -0
  306. {robotframework-6.1.1 → robotframework-7.0}/src/robotframework.egg-info/entry_points.txt +0 -0
  307. {robotframework-6.1.1 → 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,19 +420,16 @@ 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
435
  if isinstance(value, str) or not super().no_conversion_needed(value):
@@ -466,16 +438,16 @@ class ListConverter(TypeConverter):
466
438
  return True
467
439
  return all(self.converter.no_conversion_needed(v) for v in value)
468
440
 
469
- def _non_string_convert(self, value, explicit_type=True):
470
- return self._convert_items(list(value), explicit_type)
441
+ def _non_string_convert(self, value):
442
+ return self._convert_items(list(value))
471
443
 
472
- def _convert(self, value, explicit_type=True):
473
- 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))
474
446
 
475
- def _convert_items(self, value, explicit_type):
447
+ def _convert_items(self, value):
476
448
  if not self.converter:
477
449
  return value
478
- return [self.converter.convert(i, v, explicit_type, kind='Item')
450
+ return [self.converter.convert(v, name=i, kind='Item')
479
451
  for i, v in enumerate(value)]
480
452
 
481
453
 
@@ -485,22 +457,24 @@ class TupleConverter(TypeConverter):
485
457
  type_name = 'tuple'
486
458
  value_types = (str, Sequence)
487
459
 
488
- def __init__(self, used_type, custom_converters=None, languages=None):
489
- 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)
490
464
  self.converters = ()
491
465
  self.homogenous = False
492
- types = self._get_nested_types(used_type)
493
- if not types:
466
+ nested = type_info.nested
467
+ if not nested:
494
468
  return
495
- if types[-1] is Ellipsis:
496
- types = types[:-1]
497
- if len(types) != 1:
469
+ if nested[-1].type is Ellipsis:
470
+ nested = nested[:-1]
471
+ if len(nested) != 1:
498
472
  raise TypeError(f'Homogenous tuple used as a type hint requires '
499
- f'exactly one nested type, got {len(types)}.')
473
+ f'exactly one nested type, got {len(nested)}.')
500
474
  self.homogenous = True
501
- self.type_name = type_repr(used_type)
475
+ self.type_name = str(type_info)
502
476
  self.converters = tuple(self.converter_for(t, custom_converters, languages)
503
- or NullConverter() for t in types)
477
+ or NullConverter() for t in nested)
504
478
 
505
479
  def no_conversion_needed(self, value):
506
480
  if isinstance(value, str) or not super().no_conversion_needed(value):
@@ -513,23 +487,23 @@ class TupleConverter(TypeConverter):
513
487
  return False
514
488
  return all(c.no_conversion_needed(v) for c, v in zip(self.converters, value))
515
489
 
516
- def _non_string_convert(self, value, explicit_type=True):
517
- return self._convert_items(tuple(value), explicit_type)
490
+ def _non_string_convert(self, value):
491
+ return self._convert_items(tuple(value))
518
492
 
519
- def _convert(self, value, explicit_type=True):
520
- 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))
521
495
 
522
- def _convert_items(self, value, explicit_type):
496
+ def _convert_items(self, value):
523
497
  if not self.converters:
524
498
  return value
525
499
  if self.homogenous:
526
500
  conv = self.converters[0]
527
- return tuple(conv.convert(str(i), v, explicit_type, kind='Item')
501
+ return tuple(conv.convert(v, name=str(i), kind='Item')
528
502
  for i, v in enumerate(value))
529
503
  if len(self.converters) != len(value):
530
504
  raise ValueError(f'Expected {len(self.converters)} '
531
505
  f'item{s(self.converters)}, got {len(value)}.')
532
- return tuple(conv.convert(i, v, explicit_type, kind='Item')
506
+ return tuple(conv.convert(v, name=str(i), kind='Item')
533
507
  for i, (conv, v) in enumerate(zip(self.converters, value)))
534
508
 
535
509
 
@@ -537,26 +511,27 @@ class TupleConverter(TypeConverter):
537
511
  class TypedDictConverter(TypeConverter):
538
512
  type = 'TypedDict'
539
513
  value_types = (str, Mapping)
514
+ type_info: 'TypedDictInfo'
540
515
 
541
- def __init__(self, used_type, custom_converters, languages=None):
542
- 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)
543
520
  self.converters = {n: self.converter_for(t, custom_converters, languages)
544
- for n, t in used_type.__annotations__.items()}
545
- self.type_name = used_type.__name__
546
- # __required_keys__ is new in Python 3.9.
547
- 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
548
523
 
549
524
  @classmethod
550
- def handles(cls, type_):
551
- return isinstance(type_, typeddict_types)
525
+ def handles(cls, type_info: 'TypeInfo') -> bool:
526
+ return type_info.is_typed_dict
552
527
 
553
528
  def no_conversion_needed(self, value):
554
529
  return False
555
530
 
556
- def _non_string_convert(self, value, explicit_type=True):
531
+ def _non_string_convert(self, value):
557
532
  return self._convert_items(value)
558
533
 
559
- def _convert(self, value, explicit_type=True):
534
+ def _convert(self, value):
560
535
  return self._convert_items(self._literal_eval(value, dict))
561
536
 
562
537
  def _convert_items(self, value):
@@ -568,14 +543,14 @@ class TypedDictConverter(TypeConverter):
568
543
  not_allowed.append(key)
569
544
  else:
570
545
  if converter:
571
- value[key] = converter.convert(key, value[key], kind='Item')
546
+ value[key] = converter.convert(value[key], name=key, kind='Item')
572
547
  if not_allowed:
573
548
  error = f'Item{s(not_allowed)} {seq2str(sorted(not_allowed))} not allowed.'
574
549
  available = [key for key in self.converters if key not in value]
575
550
  if available:
576
551
  error += f' Available item{s(available)}: {seq2str(sorted(available))}'
577
552
  raise ValueError(error)
578
- 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]
579
554
  if missing:
580
555
  raise ValueError(f"Required item{s(missing)} "
581
556
  f"{seq2str(sorted(missing))} missing.")
@@ -587,18 +562,19 @@ class DictionaryConverter(TypeConverter):
587
562
  type = dict
588
563
  abc = Mapping
589
564
  type_name = 'dictionary'
590
- aliases = ('dict', 'map')
591
565
  value_types = (str, Mapping)
592
566
 
593
- def __init__(self, used_type, custom_converters=None, languages=None):
594
- super().__init__(used_type, custom_converters, languages)
595
- types = self._get_nested_types(used_type, expected_count=2)
596
- 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:
597
573
  self.converters = ()
598
574
  else:
599
- self.type_name = type_repr(used_type)
575
+ self.type_name = str(type_info)
600
576
  self.converters = tuple(self.converter_for(t, custom_converters, languages)
601
- or NullConverter() for t in types)
577
+ or NullConverter() for t in nested)
602
578
 
603
579
  def no_conversion_needed(self, value):
604
580
  if isinstance(value, str) or not super().no_conversion_needed(value):
@@ -610,28 +586,26 @@ class DictionaryConverter(TypeConverter):
610
586
  return all(no_key_conversion_needed(k) and no_value_conversion_needed(v)
611
587
  for k, v in value.items())
612
588
 
613
- def _non_string_convert(self, value, explicit_type=True):
589
+ def _non_string_convert(self, value):
614
590
  if self._used_type_is_dict() and not isinstance(value, dict):
615
591
  value = dict(value)
616
- return self._convert_items(value, explicit_type)
592
+ return self._convert_items(value)
617
593
 
618
594
  def _used_type_is_dict(self):
619
- used_type = getattr(self.used_type, '__origin__', self.used_type)
620
- return issubclass(used_type, dict)
595
+ return issubclass(self.type_info.type, dict)
621
596
 
622
- def _convert(self, value, explicit_type=True):
623
- 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))
624
599
 
625
- def _convert_items(self, value, explicit_type):
600
+ def _convert_items(self, value):
626
601
  if not self.converters:
627
602
  return value
628
- convert_key = self._get_converter(self.converters[0], explicit_type, 'Key')
629
- convert_value = self._get_converter(self.converters[1], explicit_type, 'Item')
603
+ convert_key = self._get_converter(self.converters[0], 'Key')
604
+ convert_value = self._get_converter(self.converters[1], 'Item')
630
605
  return {convert_key(None, k): convert_value(k, v) for k, v in value.items()}
631
606
 
632
- def _get_converter(self, converter, explicit_type, kind):
633
- return lambda name, value: converter.convert(name, value, explicit_type,
634
- kind=kind)
607
+ def _get_converter(self, converter, kind):
608
+ return lambda name, value: converter.convert(value, name, kind=kind)
635
609
 
636
610
 
637
611
  @TypeConverter.register
@@ -641,14 +615,16 @@ class SetConverter(TypeConverter):
641
615
  type_name = 'set'
642
616
  value_types = (str, Container)
643
617
 
644
- def __init__(self, used_type, custom_converters=None, languages=None):
645
- super().__init__(used_type, custom_converters, languages)
646
- types = self._get_nested_types(used_type, expected_count=1)
647
- 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:
648
624
  self.converter = None
649
625
  else:
650
- self.type_name = type_repr(used_type)
651
- 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)
652
628
 
653
629
  def no_conversion_needed(self, value):
654
630
  if isinstance(value, str) or not super().no_conversion_needed(value):
@@ -657,17 +633,16 @@ class SetConverter(TypeConverter):
657
633
  return True
658
634
  return all(self.converter.no_conversion_needed(v) for v in value)
659
635
 
660
- def _non_string_convert(self, value, explicit_type=True):
661
- return self._convert_items(set(value), explicit_type)
636
+ def _non_string_convert(self, value):
637
+ return self._convert_items(set(value))
662
638
 
663
- def _convert(self, value, explicit_type=True):
664
- 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))
665
641
 
666
- def _convert_items(self, value, explicit_type):
642
+ def _convert_items(self, value):
667
643
  if not self.converter:
668
644
  return value
669
- return {self.converter.convert(None, v, explicit_type, kind='Item')
670
- for v in value}
645
+ return {self.converter.convert(v, kind='Item') for v in value}
671
646
 
672
647
 
673
648
  @TypeConverter.register
@@ -675,68 +650,61 @@ class FrozenSetConverter(SetConverter):
675
650
  type = frozenset
676
651
  type_name = 'frozenset'
677
652
 
678
- def _non_string_convert(self, value, explicit_type=True):
679
- return frozenset(super()._non_string_convert(value, explicit_type))
653
+ def _non_string_convert(self, value):
654
+ return frozenset(super()._non_string_convert(value))
680
655
 
681
- def _convert(self, value, explicit_type=True):
656
+ def _convert(self, value):
682
657
  # There are issues w/ literal_eval. See self._literal_eval for details.
683
658
  if value == 'frozenset()':
684
659
  return frozenset()
685
- return frozenset(super()._convert(value, explicit_type))
660
+ return frozenset(super()._convert(value))
686
661
 
687
662
 
688
663
  @TypeConverter.register
689
- class CombinedConverter(TypeConverter):
664
+ class UnionConverter(TypeConverter):
690
665
  type = Union
691
666
 
692
- def __init__(self, union, custom_converters, languages=None):
693
- super().__init__(self._get_types(union))
694
- self.converters = tuple(self.converter_for(t, custom_converters, languages)
695
- for t in self.used_type)
696
-
697
- def _get_types(self, union):
698
- if not union:
699
- return ()
700
- if isinstance(union, tuple):
701
- return union
702
- if has_args(union):
703
- return union.__args__
704
- 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.')
705
675
 
706
676
  @property
707
677
  def type_name(self):
708
- if not self.used_type:
709
- return 'union'
710
- 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 ')
711
681
 
712
682
  @classmethod
713
- def handles(cls, type_):
714
- return is_union(type_, allow_tuple=True)
683
+ def handles(cls, type_info: 'TypeInfo') -> bool:
684
+ return type_info.is_union
715
685
 
716
686
  def _handles_value(self, value):
717
687
  return True
718
688
 
719
689
  def no_conversion_needed(self, value):
720
- for converter, type_ in zip(self.converters, self.used_type):
690
+ for converter, info in zip(self.converters, self.type_info.nested):
721
691
  if converter:
722
692
  if converter.no_conversion_needed(value):
723
693
  return True
724
694
  else:
725
695
  try:
726
- if isinstance(value, type_):
696
+ if isinstance(value, info.type):
727
697
  return True
728
698
  except TypeError:
729
699
  pass
730
700
  return False
731
701
 
732
- def _convert(self, value, explicit_type=True):
733
- if not self.used_type:
734
- raise ValueError('Cannot have union without types.')
702
+ def _convert(self, value):
735
703
  unrecognized_types = False
736
704
  for converter in self.converters:
737
705
  if converter:
738
706
  try:
739
- return converter.convert('', value, explicit_type)
707
+ return converter.convert(value)
740
708
  except ValueError:
741
709
  pass
742
710
  else:
@@ -746,10 +714,62 @@ class CombinedConverter(TypeConverter):
746
714
  raise ValueError
747
715
 
748
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
+
749
767
  class CustomConverter(TypeConverter):
750
768
 
751
- def __init__(self, used_type, converter_info, languages=None):
752
- 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)
753
773
  self.converter_info = converter_info
754
774
 
755
775
  @property
@@ -767,7 +787,7 @@ class CustomConverter(TypeConverter):
767
787
  def _handles_value(self, value):
768
788
  return not self.value_types or isinstance(value, self.value_types)
769
789
 
770
- def _convert(self, value, explicit_type=True):
790
+ def _convert(self, value):
771
791
  try:
772
792
  return self.converter_info.convert(value)
773
793
  except ValueError:
@@ -778,7 +798,7 @@ class CustomConverter(TypeConverter):
778
798
 
779
799
  class NullConverter:
780
800
 
781
- def convert(self, name, value, explicit_type=True, strict=True, kind='Argument'):
801
+ def convert(self, value, name, kind='Argument'):
782
802
  return value
783
803
 
784
804
  def no_conversion_needed(self, value):