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.
- {robotframework-6.1.1 → robotframework-7.0}/INSTALL.rst +25 -25
- {robotframework-6.1.1 → robotframework-7.0}/PKG-INFO +6 -8
- {robotframework-6.1.1 → robotframework-7.0}/README.rst +3 -2
- {robotframework-6.1.1 → robotframework-7.0}/setup.py +3 -6
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/api/__init__.py +4 -1
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/api/deco.py +60 -14
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/api/exceptions.py +6 -6
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/api/interfaces.py +402 -67
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/api/logger.py +27 -20
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/api/parsing.py +4 -2
- robotframework-7.0/src/robot/api/py.typed +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/conf/gatherfailed.py +2 -2
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/conf/languages.py +0 -9
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/conf/settings.py +21 -14
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/common/storage.js +11 -6
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/htmlfilewriter.py +1 -1
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/libdoc/libdoc.css +10 -2
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/libdoc/libdoc.html +10 -0
- robotframework-7.0/src/robot/htmldata/rebot/common.css +362 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/doc_formatting.css +13 -7
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/log.css +51 -10
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/log.html +14 -23
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/model.js +2 -4
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/report.css +83 -19
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/report.html +22 -7
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/testdata.js +10 -3
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/view.js +84 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/template.py +3 -3
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/builder.py +0 -8
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/datatypes.py +9 -10
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/htmlutils.py +4 -7
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/jsonbuilder.py +38 -20
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/model.py +21 -28
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/robotbuilder.py +50 -31
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/standardtypes.py +9 -1
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/xmlbuilder.py +35 -20
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/xmlwriter.py +18 -38
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/BuiltIn.py +255 -205
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/Collections.py +384 -240
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/DateTime.py +73 -60
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/OperatingSystem.py +6 -5
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/Process.py +26 -27
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/Remote.py +40 -36
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/String.py +66 -76
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/XML.py +66 -59
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/__init__.py +2 -2
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/__init__.py +5 -5
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/body.py +44 -13
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/configurer.py +15 -11
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/control.py +226 -84
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/filter.py +31 -25
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/itemlist.py +9 -8
- robotframework-7.0/src/robot/model/keyword.py +77 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/message.py +19 -10
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/modelobject.py +25 -7
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/namepatterns.py +3 -25
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/stats.py +9 -15
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/tags.py +1 -1
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/testcase.py +15 -27
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/testsuite.py +17 -26
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/visitor.py +35 -8
- robotframework-7.0/src/robot/output/console/dotted.py +90 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/output/console/quiet.py +3 -2
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/output/console/verbose.py +61 -61
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/output/debugfile.py +39 -24
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/output/filelogger.py +18 -15
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/output/librarylogger.py +3 -2
- robotframework-7.0/src/robot/output/listeners.py +753 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/output/logger.py +216 -80
- robotframework-7.0/src/robot/output/loggerapi.py +215 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/output/loggerhelper.py +23 -56
- robotframework-7.0/src/robot/output/output.py +185 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/output/stdoutlogsplitter.py +8 -5
- robotframework-7.0/src/robot/output/xmllogger.py +459 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/lexer/blocklexers.py +17 -13
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/lexer/context.py +12 -2
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/lexer/lexer.py +1 -1
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/lexer/settings.py +6 -3
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/lexer/statementlexers.py +39 -10
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/lexer/tokens.py +27 -29
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/model/blocks.py +19 -6
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/model/statements.py +193 -94
- robotframework-7.0/src/robot/parsing/model/visitor.py +100 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/rebot.py +2 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/reporting/expandkeywordmatcher.py +1 -1
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/reporting/jsbuildingcontext.py +8 -6
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/reporting/jsmodelbuilders.py +88 -61
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/reporting/logreportwriters.py +16 -10
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/reporting/outputwriter.py +18 -2
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/reporting/resultwriter.py +4 -4
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/reporting/stringcache.py +3 -3
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/reporting/xunitwriter.py +15 -21
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/result/__init__.py +3 -2
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/result/configurer.py +12 -9
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/result/executionresult.py +56 -8
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/result/flattenkeywordmatcher.py +48 -9
- robotframework-7.0/src/robot/result/keywordremover.py +207 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/result/merger.py +1 -1
- robotframework-7.0/src/robot/result/model.py +1185 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/result/modeldeprecation.py +9 -3
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/result/resultbuilder.py +46 -36
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/result/xmlelementhandlers.py +83 -43
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/run.py +2 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/__init__.py +14 -4
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/arguments/__init__.py +2 -1
- robotframework-7.0/src/robot/running/arguments/argumentconverter.py +100 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/arguments/argumentmapper.py +26 -24
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/arguments/argumentparser.py +82 -60
- robotframework-7.0/src/robot/running/arguments/argumentresolver.py +158 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/arguments/argumentspec.py +83 -116
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/arguments/argumentvalidator.py +33 -27
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/arguments/customconverters.py +15 -12
- robotframework-7.0/src/robot/running/arguments/embedded.py +145 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/arguments/typeconverters.py +233 -213
- 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.1.1 → robotframework-7.0}/src/robot/running/bodyrunner.py +147 -129
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/builder/builders.py +2 -1
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/builder/parsers.py +10 -11
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/builder/settings.py +9 -17
- robotframework-7.0/src/robot/running/builder/transformers.py +535 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/context.py +113 -31
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/dynamicmethods.py +62 -34
- {robotframework-6.1.1 → 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.1.1 → robotframework-7.0}/src/robot/running/model.py +195 -377
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/namespace.py +124 -137
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/outputcapture.py +20 -12
- robotframework-7.0/src/robot/running/resourcemodel.py +448 -0
- {robotframework-6.1.1 → 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.1.1 → robotframework-7.0}/src/robot/testdoc.py +18 -13
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/__init__.py +53 -35
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/connectioncache.py +64 -59
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/dotdict.py +3 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/encodingsniffer.py +1 -1
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/escaping.py +19 -19
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/importer.py +2 -2
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/markupwriters.py +23 -15
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/misc.py +1 -2
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/normalizing.py +9 -24
- robotframework-7.0/src/robot/utils/notset.py +33 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/platform.py +15 -5
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/robotio.py +9 -9
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/robotpath.py +1 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/robottime.py +122 -90
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/robottypes.py +21 -31
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/setter.py +0 -5
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/text.py +7 -4
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/unic.py +2 -2
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/variables/__init__.py +2 -2
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/variables/assigner.py +17 -19
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/variables/evaluation.py +20 -17
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/variables/filesetter.py +80 -80
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/variables/replacer.py +33 -36
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/variables/scopes.py +17 -12
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/variables/search.py +66 -41
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/variables/store.py +14 -16
- robotframework-7.0/src/robot/variables/tablesetter.py +164 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/variables/variables.py +1 -1
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/version.py +1 -1
- {robotframework-6.1.1 → robotframework-7.0}/src/robotframework.egg-info/PKG-INFO +6 -8
- {robotframework-6.1.1 → robotframework-7.0}/src/robotframework.egg-info/SOURCES.txt +10 -8
- {robotframework-6.1.1 → robotframework-7.0}/tasks.py +6 -6
- robotframework-6.1.1/src/robot/htmldata/rebot/common.css +0 -239
- robotframework-6.1.1/src/robot/libraries/Reserved.py +0 -48
- robotframework-6.1.1/src/robot/model/keyword.py +0 -173
- robotframework-6.1.1/src/robot/output/console/dotted.py +0 -90
- robotframework-6.1.1/src/robot/output/listenerarguments.py +0 -165
- robotframework-6.1.1/src/robot/output/listenermethods.py +0 -113
- robotframework-6.1.1/src/robot/output/listeners.py +0 -174
- robotframework-6.1.1/src/robot/output/output.py +0 -95
- robotframework-6.1.1/src/robot/output/xmllogger.py +0 -354
- robotframework-6.1.1/src/robot/parsing/model/visitor.py +0 -67
- robotframework-6.1.1/src/robot/result/keywordremover.py +0 -183
- robotframework-6.1.1/src/robot/result/model.py +0 -957
- robotframework-6.1.1/src/robot/running/arguments/argumentconverter.py +0 -79
- robotframework-6.1.1/src/robot/running/arguments/argumentresolver.py +0 -131
- robotframework-6.1.1/src/robot/running/arguments/embedded.py +0 -146
- robotframework-6.1.1/src/robot/running/arguments/typevalidator.py +0 -56
- robotframework-6.1.1/src/robot/running/builder/transformers.py +0 -642
- robotframework-6.1.1/src/robot/running/handlers.py +0 -321
- robotframework-6.1.1/src/robot/running/handlerstore.py +0 -66
- robotframework-6.1.1/src/robot/running/librarykeywordrunner.py +0 -238
- robotframework-6.1.1/src/robot/running/libraryscopes.py +0 -97
- robotframework-6.1.1/src/robot/running/modelcombiner.py +0 -32
- robotframework-6.1.1/src/robot/running/suiterunner.py +0 -248
- robotframework-6.1.1/src/robot/running/testlibraries.py +0 -423
- robotframework-6.1.1/src/robot/running/usererrorhandler.py +0 -75
- robotframework-6.1.1/src/robot/running/userkeyword.py +0 -111
- robotframework-6.1.1/src/robot/running/userkeywordrunner.py +0 -274
- robotframework-6.1.1/src/robot/variables/tablesetter.py +0 -156
- {robotframework-6.1.1 → robotframework-7.0}/AUTHORS.rst +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/BUILD.rst +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/CONTRIBUTING.rst +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/COPYRIGHT.txt +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/LICENSE.txt +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/MANIFEST.in +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/setup.cfg +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/__init__.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/__main__.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/conf/__init__.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/errors.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/__init__.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/common/__init__.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/common/js_disabled.css +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/jsonwriter.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/lib/__init__.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/lib/jquery.highlight.min.js +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/lib/jquery.min.js +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/lib/jquery.tablesorter.min.js +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/lib/jquery.tmpl.min.js +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/lib/jsxcompressor.min.js +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/libdoc/__init__.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/libdoc/doc_formatting.css +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/libdoc/print.css +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/libdoc/pygments.css +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/__init__.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/fileloading.js +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/log.js +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/print.css +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/util.js +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/testdoc/__init__.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/testdoc/testdoc.css +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/testdoc/testdoc.html +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdoc.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/__init__.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/consoleviewer.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/htmlwriter.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/jsonwriter.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/output.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/writer.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/Dialogs.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/Easter.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/Screenshot.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/Telnet.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/dialogs_py.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/fixture.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/metadata.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/modifier.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/statistics.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/suitestatistics.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/tagsetter.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/tagstatistics.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/totalstatistics.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/output/__init__.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/output/console/__init__.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/output/console/highlighting.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/output/pyloggingconf.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/__init__.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/lexer/__init__.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/lexer/tokenizer.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/model/__init__.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/parser/__init__.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/parser/blockparsers.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/parser/fileparser.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/parser/parser.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/suitestructure.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/pythonpathsetter.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/reporting/__init__.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/reporting/jsexecutionresult.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/reporting/jswriter.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/result/executionerrors.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/result/messagefilter.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/result/suiteteardownfailed.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/result/visitor.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/builder/__init__.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/randomizer.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/runkwregister.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/signalhandler.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/status.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/timeouts/__init__.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/timeouts/posix.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/timeouts/windows.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/application.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/argumentparser.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/asserts.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/charwidth.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/compress.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/encoding.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/error.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/etreewrapper.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/filereader.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/frange.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/htmlformatters.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/markuputils.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/match.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/recommendations.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/restreader.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/robotenv.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/robotinspect.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/sortable.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/typehints.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/variables/finders.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/variables/notfound.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/variables/resolvable.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robotframework.egg-info/dependency_links.txt +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robotframework.egg-info/entry_points.txt +0 -0
- {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
|
|
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,19 +420,16 @@ 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
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
|
|
470
|
-
return self._convert_items(list(value)
|
|
441
|
+
def _non_string_convert(self, value):
|
|
442
|
+
return self._convert_items(list(value))
|
|
471
443
|
|
|
472
|
-
def _convert(self, value
|
|
473
|
-
return self._convert_items(self._literal_eval(value, list)
|
|
444
|
+
def _convert(self, value):
|
|
445
|
+
return self._convert_items(self._literal_eval(value, list))
|
|
474
446
|
|
|
475
|
-
def _convert_items(self, value
|
|
447
|
+
def _convert_items(self, value):
|
|
476
448
|
if not self.converter:
|
|
477
449
|
return value
|
|
478
|
-
return [self.converter.convert(
|
|
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,
|
|
489
|
-
|
|
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
|
-
|
|
493
|
-
if not
|
|
466
|
+
nested = type_info.nested
|
|
467
|
+
if not nested:
|
|
494
468
|
return
|
|
495
|
-
if
|
|
496
|
-
|
|
497
|
-
if len(
|
|
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(
|
|
473
|
+
f'exactly one nested type, got {len(nested)}.')
|
|
500
474
|
self.homogenous = True
|
|
501
|
-
self.type_name =
|
|
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
|
|
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
|
|
517
|
-
return self._convert_items(tuple(value)
|
|
490
|
+
def _non_string_convert(self, value):
|
|
491
|
+
return self._convert_items(tuple(value))
|
|
518
492
|
|
|
519
|
-
def _convert(self, value
|
|
520
|
-
return self._convert_items(self._literal_eval(value, tuple)
|
|
493
|
+
def _convert(self, value):
|
|
494
|
+
return self._convert_items(self._literal_eval(value, tuple))
|
|
521
495
|
|
|
522
|
-
def _convert_items(self, value
|
|
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),
|
|
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(
|
|
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,
|
|
542
|
-
|
|
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
|
|
545
|
-
self.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,
|
|
551
|
-
return
|
|
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
|
|
531
|
+
def _non_string_convert(self, value):
|
|
557
532
|
return self._convert_items(value)
|
|
558
533
|
|
|
559
|
-
def _convert(self, value
|
|
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(
|
|
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.
|
|
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,
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
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 =
|
|
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
|
|
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
|
|
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
|
|
592
|
+
return self._convert_items(value)
|
|
617
593
|
|
|
618
594
|
def _used_type_is_dict(self):
|
|
619
|
-
|
|
620
|
-
return issubclass(used_type, dict)
|
|
595
|
+
return issubclass(self.type_info.type, dict)
|
|
621
596
|
|
|
622
|
-
def _convert(self, value
|
|
623
|
-
return self._convert_items(self._literal_eval(value, dict)
|
|
597
|
+
def _convert(self, value):
|
|
598
|
+
return self._convert_items(self._literal_eval(value, dict))
|
|
624
599
|
|
|
625
|
-
def _convert_items(self, value
|
|
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],
|
|
629
|
-
convert_value = self._get_converter(self.converters[1],
|
|
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,
|
|
633
|
-
return lambda name, value: converter.convert(
|
|
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,
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
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 =
|
|
651
|
-
self.converter = self.converter_for(
|
|
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
|
|
661
|
-
return self._convert_items(set(value)
|
|
636
|
+
def _non_string_convert(self, value):
|
|
637
|
+
return self._convert_items(set(value))
|
|
662
638
|
|
|
663
|
-
def _convert(self, value
|
|
664
|
-
return self._convert_items(self._literal_eval(value, set)
|
|
639
|
+
def _convert(self, value):
|
|
640
|
+
return self._convert_items(self._literal_eval(value, set))
|
|
665
641
|
|
|
666
|
-
def _convert_items(self, value
|
|
642
|
+
def _convert_items(self, value):
|
|
667
643
|
if not self.converter:
|
|
668
644
|
return value
|
|
669
|
-
return {self.converter.convert(
|
|
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
|
|
679
|
-
return frozenset(super()._non_string_convert(value
|
|
653
|
+
def _non_string_convert(self, value):
|
|
654
|
+
return frozenset(super()._non_string_convert(value))
|
|
680
655
|
|
|
681
|
-
def _convert(self, value
|
|
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
|
|
660
|
+
return frozenset(super()._convert(value))
|
|
686
661
|
|
|
687
662
|
|
|
688
663
|
@TypeConverter.register
|
|
689
|
-
class
|
|
664
|
+
class UnionConverter(TypeConverter):
|
|
690
665
|
type = Union
|
|
691
666
|
|
|
692
|
-
def __init__(self,
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
if not
|
|
699
|
-
|
|
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.
|
|
709
|
-
return '
|
|
710
|
-
return
|
|
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,
|
|
714
|
-
return is_union
|
|
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,
|
|
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,
|
|
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
|
|
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(
|
|
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,
|
|
752
|
-
|
|
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
|
|
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,
|
|
801
|
+
def convert(self, value, name, kind='Argument'):
|
|
782
802
|
return value
|
|
783
803
|
|
|
784
804
|
def no_conversion_needed(self, value):
|