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.
- {robotframework-6.1rc1 → robotframework-7.0}/INSTALL.rst +25 -25
- {robotframework-6.1rc1 → robotframework-7.0}/PKG-INFO +6 -8
- {robotframework-6.1rc1 → robotframework-7.0}/README.rst +3 -2
- {robotframework-6.1rc1 → robotframework-7.0}/setup.py +3 -6
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/api/__init__.py +4 -1
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/api/deco.py +60 -14
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/api/exceptions.py +6 -6
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/api/interfaces.py +403 -68
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/api/logger.py +27 -20
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/api/parsing.py +4 -2
- robotframework-7.0/src/robot/api/py.typed +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/conf/gatherfailed.py +2 -2
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/conf/languages.py +61 -25
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/conf/settings.py +21 -14
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/common/storage.js +11 -6
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/htmlfilewriter.py +1 -1
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/libdoc/libdoc.css +10 -2
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/libdoc/libdoc.html +10 -0
- robotframework-7.0/src/robot/htmldata/rebot/common.css +362 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/doc_formatting.css +13 -7
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/log.css +51 -10
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/log.html +14 -23
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/model.js +2 -4
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/report.css +83 -19
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/report.html +22 -7
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/testdata.js +10 -3
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/view.js +84 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/template.py +3 -3
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/builder.py +0 -8
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/datatypes.py +9 -10
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/htmlutils.py +4 -7
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/jsonbuilder.py +38 -20
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/model.py +21 -28
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/robotbuilder.py +50 -31
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/standardtypes.py +9 -1
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/xmlbuilder.py +35 -20
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/xmlwriter.py +18 -38
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/BuiltIn.py +255 -205
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/Collections.py +384 -240
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/DateTime.py +73 -60
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/OperatingSystem.py +6 -5
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/Process.py +26 -27
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/Remote.py +40 -36
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/String.py +66 -76
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/XML.py +66 -59
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/__init__.py +2 -2
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/dialogs_py.py +14 -2
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/__init__.py +5 -5
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/body.py +44 -13
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/configurer.py +19 -15
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/control.py +230 -88
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/filter.py +31 -25
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/itemlist.py +9 -8
- robotframework-7.0/src/robot/model/keyword.py +77 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/message.py +19 -10
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/modelobject.py +27 -15
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/modifier.py +1 -1
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/namepatterns.py +3 -25
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/stats.py +9 -15
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/tags.py +1 -1
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/testcase.py +15 -27
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/testsuite.py +44 -28
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/visitor.py +35 -8
- robotframework-7.0/src/robot/output/console/dotted.py +90 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/output/console/quiet.py +3 -2
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/output/console/verbose.py +61 -61
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/output/debugfile.py +39 -24
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/output/filelogger.py +18 -15
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/output/librarylogger.py +3 -2
- robotframework-7.0/src/robot/output/listeners.py +753 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/output/logger.py +216 -80
- robotframework-7.0/src/robot/output/loggerapi.py +215 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/output/loggerhelper.py +23 -56
- robotframework-7.0/src/robot/output/output.py +185 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/output/stdoutlogsplitter.py +8 -5
- robotframework-7.0/src/robot/output/xmllogger.py +459 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/lexer/blocklexers.py +17 -13
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/lexer/context.py +12 -2
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/lexer/lexer.py +1 -1
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/lexer/settings.py +6 -3
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/lexer/statementlexers.py +39 -10
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/lexer/tokens.py +27 -29
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/model/blocks.py +19 -6
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/model/statements.py +193 -94
- robotframework-7.0/src/robot/parsing/model/visitor.py +100 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/rebot.py +2 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/reporting/expandkeywordmatcher.py +1 -1
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/reporting/jsbuildingcontext.py +8 -6
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/reporting/jsmodelbuilders.py +88 -61
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/reporting/logreportwriters.py +16 -10
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/reporting/outputwriter.py +18 -2
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/reporting/resultwriter.py +4 -4
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/reporting/stringcache.py +3 -3
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/reporting/xunitwriter.py +15 -21
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/result/__init__.py +3 -2
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/result/configurer.py +12 -9
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/result/executionresult.py +56 -8
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/result/flattenkeywordmatcher.py +48 -9
- robotframework-7.0/src/robot/result/keywordremover.py +207 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/result/merger.py +1 -1
- robotframework-7.0/src/robot/result/model.py +1185 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/result/modeldeprecation.py +9 -3
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/result/resultbuilder.py +46 -36
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/result/xmlelementhandlers.py +83 -43
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/run.py +3 -1
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/__init__.py +14 -4
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/arguments/__init__.py +2 -1
- robotframework-7.0/src/robot/running/arguments/argumentconverter.py +100 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/arguments/argumentmapper.py +26 -24
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/arguments/argumentparser.py +85 -61
- robotframework-7.0/src/robot/running/arguments/argumentresolver.py +158 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/arguments/argumentspec.py +83 -116
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/arguments/argumentvalidator.py +33 -27
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/arguments/customconverters.py +15 -12
- robotframework-7.0/src/robot/running/arguments/embedded.py +145 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/arguments/typeconverters.py +268 -220
- robotframework-7.0/src/robot/running/arguments/typeinfo.py +317 -0
- robotframework-7.0/src/robot/running/arguments/typeinfoparser.py +219 -0
- robotframework-7.0/src/robot/running/arguments/typevalidator.py +60 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/bodyrunner.py +147 -129
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/builder/builders.py +17 -26
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/builder/parsers.py +17 -11
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/builder/settings.py +9 -17
- robotframework-7.0/src/robot/running/builder/transformers.py +535 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/context.py +113 -31
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/dynamicmethods.py +62 -34
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/importer.py +27 -49
- robotframework-7.0/src/robot/running/invalidkeyword.py +67 -0
- robotframework-7.0/src/robot/running/keywordfinder.py +91 -0
- robotframework-7.0/src/robot/running/keywordimplementation.py +164 -0
- robotframework-7.0/src/robot/running/librarykeyword.py +392 -0
- robotframework-7.0/src/robot/running/librarykeywordrunner.py +250 -0
- robotframework-7.0/src/robot/running/libraryscopes.py +115 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/model.py +198 -337
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/namespace.py +124 -137
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/outputcapture.py +20 -12
- robotframework-7.0/src/robot/running/resourcemodel.py +448 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/statusreporter.py +16 -13
- robotframework-7.0/src/robot/running/suiterunner.py +265 -0
- robotframework-7.0/src/robot/running/testlibraries.py +500 -0
- robotframework-7.0/src/robot/running/userkeywordrunner.py +260 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/testdoc.py +18 -13
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/__init__.py +53 -35
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/connectioncache.py +64 -59
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/dotdict.py +3 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/encodingsniffer.py +9 -4
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/escaping.py +19 -19
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/importer.py +2 -2
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/markupwriters.py +23 -15
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/misc.py +1 -2
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/normalizing.py +9 -24
- robotframework-7.0/src/robot/utils/notset.py +33 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/platform.py +15 -5
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/robotio.py +9 -9
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/robotpath.py +1 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/robottime.py +122 -90
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/robottypes.py +21 -31
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/setter.py +0 -5
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/text.py +7 -4
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/unic.py +2 -2
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/variables/__init__.py +2 -2
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/variables/assigner.py +17 -19
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/variables/evaluation.py +20 -17
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/variables/filesetter.py +80 -80
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/variables/replacer.py +33 -36
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/variables/scopes.py +17 -12
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/variables/search.py +66 -41
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/variables/store.py +14 -16
- robotframework-7.0/src/robot/variables/tablesetter.py +164 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/variables/variables.py +1 -1
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/version.py +1 -1
- {robotframework-6.1rc1 → robotframework-7.0}/src/robotframework.egg-info/PKG-INFO +6 -8
- {robotframework-6.1rc1 → robotframework-7.0}/src/robotframework.egg-info/SOURCES.txt +10 -8
- {robotframework-6.1rc1 → robotframework-7.0}/tasks.py +6 -6
- robotframework-6.1rc1/src/robot/htmldata/rebot/common.css +0 -239
- robotframework-6.1rc1/src/robot/libraries/Reserved.py +0 -48
- robotframework-6.1rc1/src/robot/model/keyword.py +0 -173
- robotframework-6.1rc1/src/robot/output/console/dotted.py +0 -90
- robotframework-6.1rc1/src/robot/output/listenerarguments.py +0 -165
- robotframework-6.1rc1/src/robot/output/listenermethods.py +0 -113
- robotframework-6.1rc1/src/robot/output/listeners.py +0 -174
- robotframework-6.1rc1/src/robot/output/output.py +0 -95
- robotframework-6.1rc1/src/robot/output/xmllogger.py +0 -354
- robotframework-6.1rc1/src/robot/parsing/model/visitor.py +0 -67
- robotframework-6.1rc1/src/robot/result/keywordremover.py +0 -183
- robotframework-6.1rc1/src/robot/result/model.py +0 -957
- robotframework-6.1rc1/src/robot/running/arguments/argumentconverter.py +0 -79
- robotframework-6.1rc1/src/robot/running/arguments/argumentresolver.py +0 -131
- robotframework-6.1rc1/src/robot/running/arguments/embedded.py +0 -146
- robotframework-6.1rc1/src/robot/running/arguments/typevalidator.py +0 -56
- robotframework-6.1rc1/src/robot/running/builder/transformers.py +0 -642
- robotframework-6.1rc1/src/robot/running/handlers.py +0 -321
- robotframework-6.1rc1/src/robot/running/handlerstore.py +0 -66
- robotframework-6.1rc1/src/robot/running/librarykeywordrunner.py +0 -238
- robotframework-6.1rc1/src/robot/running/libraryscopes.py +0 -97
- robotframework-6.1rc1/src/robot/running/modelcombiner.py +0 -32
- robotframework-6.1rc1/src/robot/running/suiterunner.py +0 -249
- robotframework-6.1rc1/src/robot/running/testlibraries.py +0 -420
- robotframework-6.1rc1/src/robot/running/usererrorhandler.py +0 -75
- robotframework-6.1rc1/src/robot/running/userkeyword.py +0 -111
- robotframework-6.1rc1/src/robot/running/userkeywordrunner.py +0 -274
- robotframework-6.1rc1/src/robot/variables/tablesetter.py +0 -156
- {robotframework-6.1rc1 → robotframework-7.0}/AUTHORS.rst +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/BUILD.rst +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/CONTRIBUTING.rst +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/COPYRIGHT.txt +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/LICENSE.txt +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/MANIFEST.in +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/setup.cfg +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/__main__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/conf/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/errors.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/common/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/common/js_disabled.css +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/jsonwriter.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/lib/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/lib/jquery.highlight.min.js +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/lib/jquery.min.js +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/lib/jquery.tablesorter.min.js +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/lib/jquery.tmpl.min.js +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/lib/jsxcompressor.min.js +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/libdoc/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/libdoc/doc_formatting.css +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/libdoc/print.css +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/libdoc/pygments.css +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/fileloading.js +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/log.js +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/print.css +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/rebot/util.js +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/testdoc/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/testdoc/testdoc.css +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/htmldata/testdoc/testdoc.html +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdoc.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/consoleviewer.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/htmlwriter.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/jsonwriter.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/output.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libdocpkg/writer.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/Dialogs.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/Easter.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/Screenshot.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/libraries/Telnet.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/fixture.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/metadata.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/statistics.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/suitestatistics.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/tagsetter.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/tagstatistics.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/model/totalstatistics.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/output/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/output/console/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/output/console/highlighting.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/output/pyloggingconf.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/lexer/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/lexer/tokenizer.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/model/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/parser/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/parser/blockparsers.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/parser/fileparser.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/parser/parser.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/parsing/suitestructure.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/pythonpathsetter.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/reporting/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/reporting/jsexecutionresult.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/reporting/jswriter.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/result/executionerrors.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/result/messagefilter.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/result/suiteteardownfailed.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/result/visitor.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/builder/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/randomizer.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/runkwregister.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/signalhandler.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/status.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/timeouts/__init__.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/timeouts/posix.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/timeouts/windows.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/application.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/argumentparser.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/asserts.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/charwidth.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/compress.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/encoding.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/error.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/etreewrapper.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/filereader.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/frange.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/htmlformatters.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/markuputils.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/match.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/recommendations.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/restreader.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/robotenv.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/robotinspect.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/sortable.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/utils/typehints.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/variables/finders.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/variables/notfound.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robot/variables/resolvable.py +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robotframework.egg-info/dependency_links.txt +0 -0
- {robotframework-6.1rc1 → robotframework-7.0}/src/robotframework.egg-info/entry_points.txt +0 -0
- {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
|
|
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,
|
|
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,
|
|
30
|
-
|
|
31
|
-
|
|
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,
|
|
48
|
-
|
|
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,
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
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(
|
|
68
|
+
info = custom_converters.get_converter_info(type_info.type)
|
|
76
69
|
if info:
|
|
77
|
-
return CustomConverter(
|
|
78
|
-
if
|
|
79
|
-
return cls._converters[
|
|
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(
|
|
82
|
-
return converter(
|
|
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,
|
|
79
|
+
def handles(cls, type_info: 'TypeInfo') -> bool:
|
|
87
80
|
handled = (cls.type, cls.abc) if cls.abc else cls.type
|
|
88
|
-
return isinstance(
|
|
81
|
+
return isinstance(type_info.type, type) and issubclass(type_info.type, handled)
|
|
89
82
|
|
|
90
|
-
def convert(self,
|
|
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(
|
|
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
|
|
98
|
-
return self._convert(value
|
|
92
|
+
return self._non_string_convert(value)
|
|
93
|
+
return self._convert(value)
|
|
99
94
|
except ValueError as error:
|
|
100
|
-
return self._handle_error(
|
|
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,
|
|
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.
|
|
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
|
|
116
|
-
return self._convert(value
|
|
109
|
+
def _non_string_convert(self, value):
|
|
110
|
+
return self._convert(value)
|
|
117
111
|
|
|
118
|
-
def _convert(self, value
|
|
112
|
+
def _convert(self, value):
|
|
119
113
|
raise NotImplementedError
|
|
120
114
|
|
|
121
|
-
def _handle_error(self,
|
|
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.
|
|
158
|
+
return self.type_info.name
|
|
180
159
|
|
|
181
160
|
@property
|
|
182
161
|
def value_types(self):
|
|
183
|
-
return (str, int) if issubclass(self.
|
|
162
|
+
return (str, int) if issubclass(self.type_info.type, int) else (str,)
|
|
184
163
|
|
|
185
|
-
def _convert(self, value
|
|
186
|
-
enum = self.
|
|
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.
|
|
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,
|
|
229
|
-
return
|
|
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
|
|
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
|
|
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
|
|
241
|
+
def _non_string_convert(self, value):
|
|
268
242
|
return value
|
|
269
243
|
|
|
270
|
-
def _convert(self, value
|
|
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
|
|
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
|
|
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
|
|
273
|
+
if base == 10:
|
|
301
274
|
try:
|
|
302
|
-
|
|
303
|
-
except ValueError:
|
|
275
|
+
value, denominator = Decimal(value).as_integer_ratio()
|
|
276
|
+
except (InvalidOperation, ValueError, OverflowError):
|
|
304
277
|
pass
|
|
305
|
-
|
|
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
|
|
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
|
|
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
|
|
330
|
+
def _non_string_convert(self, value):
|
|
356
331
|
return bytes(value)
|
|
357
332
|
|
|
358
|
-
def _convert(self, value
|
|
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
|
|
347
|
+
def _non_string_convert(self, value):
|
|
373
348
|
return bytearray(value)
|
|
374
349
|
|
|
375
|
-
def _convert(self, value
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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,
|
|
433
|
-
return
|
|
407
|
+
def handles(cls, type_info: 'TypeInfo') -> bool:
|
|
408
|
+
return type_info.type in (NoneType, None)
|
|
434
409
|
|
|
435
|
-
def _convert(self, value
|
|
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,
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
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 =
|
|
455
|
-
self.converter = self.converter_for(
|
|
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
|
|
435
|
+
if isinstance(value, str) or not super().no_conversion_needed(value):
|
|
464
436
|
return False
|
|
465
|
-
|
|
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
|
|
468
|
-
return self._convert_items(list(value)
|
|
441
|
+
def _non_string_convert(self, value):
|
|
442
|
+
return self._convert_items(list(value))
|
|
469
443
|
|
|
470
|
-
def _convert(self, value
|
|
471
|
-
return self._convert_items(self._literal_eval(value, list)
|
|
444
|
+
def _convert(self, value):
|
|
445
|
+
return self._convert_items(self._literal_eval(value, list))
|
|
472
446
|
|
|
473
|
-
def _convert_items(self, value
|
|
447
|
+
def _convert_items(self, value):
|
|
474
448
|
if not self.converter:
|
|
475
449
|
return value
|
|
476
|
-
return [self.converter.convert(
|
|
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,
|
|
487
|
-
|
|
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
|
-
|
|
491
|
-
if not
|
|
466
|
+
nested = type_info.nested
|
|
467
|
+
if not nested:
|
|
492
468
|
return
|
|
493
|
-
if
|
|
494
|
-
|
|
495
|
-
if len(
|
|
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(
|
|
473
|
+
f'exactly one nested type, got {len(nested)}.')
|
|
498
474
|
self.homogenous = True
|
|
499
|
-
self.type_name =
|
|
475
|
+
self.type_name = str(type_info)
|
|
500
476
|
self.converters = tuple(self.converter_for(t, custom_converters, languages)
|
|
501
|
-
for t in
|
|
477
|
+
or NullConverter() for t in nested)
|
|
502
478
|
|
|
503
479
|
def no_conversion_needed(self, value):
|
|
504
|
-
|
|
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
|
|
507
|
-
return self._convert_items(tuple(value)
|
|
490
|
+
def _non_string_convert(self, value):
|
|
491
|
+
return self._convert_items(tuple(value))
|
|
508
492
|
|
|
509
|
-
def _convert(self, value
|
|
510
|
-
return self._convert_items(self._literal_eval(value, tuple)
|
|
493
|
+
def _convert(self, value):
|
|
494
|
+
return self._convert_items(self._literal_eval(value, tuple))
|
|
511
495
|
|
|
512
|
-
def _convert_items(self, value
|
|
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),
|
|
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(
|
|
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,
|
|
532
|
-
|
|
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
|
|
535
|
-
self.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,
|
|
541
|
-
return
|
|
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
|
|
531
|
+
def _non_string_convert(self, value):
|
|
547
532
|
return self._convert_items(value)
|
|
548
533
|
|
|
549
|
-
def _convert(self, value
|
|
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(
|
|
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.
|
|
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,
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
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 =
|
|
575
|
+
self.type_name = str(type_info)
|
|
590
576
|
self.converters = tuple(self.converter_for(t, custom_converters, languages)
|
|
591
|
-
for t in
|
|
577
|
+
or NullConverter() for t in nested)
|
|
592
578
|
|
|
593
579
|
def no_conversion_needed(self, value):
|
|
594
|
-
|
|
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
|
|
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
|
|
592
|
+
return self._convert_items(value)
|
|
600
593
|
|
|
601
594
|
def _used_type_is_dict(self):
|
|
602
|
-
|
|
603
|
-
return issubclass(used_type, dict)
|
|
595
|
+
return issubclass(self.type_info.type, dict)
|
|
604
596
|
|
|
605
|
-
def _convert(self, value
|
|
606
|
-
return self._convert_items(self._literal_eval(value, dict)
|
|
597
|
+
def _convert(self, value):
|
|
598
|
+
return self._convert_items(self._literal_eval(value, dict))
|
|
607
599
|
|
|
608
|
-
def _convert_items(self, value
|
|
600
|
+
def _convert_items(self, value):
|
|
609
601
|
if not self.converters:
|
|
610
602
|
return value
|
|
611
|
-
convert_key = self.
|
|
612
|
-
convert_value = self.
|
|
613
|
-
return {convert_key(None, k): convert_value(
|
|
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
|
|
616
|
-
|
|
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,
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
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 =
|
|
636
|
-
self.converter = self.converter_for(
|
|
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
|
-
|
|
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
|
|
642
|
-
return self._convert_items(set(value)
|
|
636
|
+
def _non_string_convert(self, value):
|
|
637
|
+
return self._convert_items(set(value))
|
|
643
638
|
|
|
644
|
-
def _convert(self, value
|
|
645
|
-
return self._convert_items(self._literal_eval(value, set)
|
|
639
|
+
def _convert(self, value):
|
|
640
|
+
return self._convert_items(self._literal_eval(value, set))
|
|
646
641
|
|
|
647
|
-
def _convert_items(self, value
|
|
642
|
+
def _convert_items(self, value):
|
|
648
643
|
if not self.converter:
|
|
649
644
|
return value
|
|
650
|
-
return {self.converter.convert(
|
|
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
|
|
660
|
-
return frozenset(super()._non_string_convert(value
|
|
653
|
+
def _non_string_convert(self, value):
|
|
654
|
+
return frozenset(super()._non_string_convert(value))
|
|
661
655
|
|
|
662
|
-
def _convert(self, value
|
|
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
|
|
660
|
+
return frozenset(super()._convert(value))
|
|
667
661
|
|
|
668
662
|
|
|
669
663
|
@TypeConverter.register
|
|
670
|
-
class
|
|
664
|
+
class UnionConverter(TypeConverter):
|
|
671
665
|
type = Union
|
|
672
666
|
|
|
673
|
-
def __init__(self,
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
if not
|
|
680
|
-
|
|
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.
|
|
690
|
-
return '
|
|
691
|
-
return
|
|
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,
|
|
695
|
-
return is_union
|
|
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,
|
|
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,
|
|
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
|
|
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(
|
|
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,
|
|
733
|
-
|
|
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
|
|
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
|