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,101 +15,140 @@
|
|
|
15
15
|
|
|
16
16
|
import sys
|
|
17
17
|
from enum import Enum
|
|
18
|
-
from typing import
|
|
18
|
+
from typing import Any, Callable, Iterator, Mapping, Sequence
|
|
19
19
|
|
|
20
|
-
from robot.utils import
|
|
20
|
+
from robot.utils import NOT_SET, safe_str, setter, SetterAwareType
|
|
21
21
|
|
|
22
22
|
from .argumentconverter import ArgumentConverter
|
|
23
23
|
from .argumentmapper import ArgumentMapper
|
|
24
24
|
from .argumentresolver import ArgumentResolver
|
|
25
|
+
from .typeinfo import TypeInfo
|
|
25
26
|
from .typevalidator import TypeValidator
|
|
26
27
|
|
|
27
28
|
|
|
28
|
-
class ArgumentSpec:
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
29
|
+
class ArgumentSpec(metaclass=SetterAwareType):
|
|
30
|
+
__slots__ = ['_name', 'type', 'positional_only', 'positional_or_named',
|
|
31
|
+
'var_positional', 'named_only', 'var_named', 'embedded', 'defaults']
|
|
32
|
+
|
|
33
|
+
def __init__(self, name: 'str|Callable[[], str]|None' = None,
|
|
34
|
+
type: str = 'Keyword',
|
|
35
|
+
positional_only: Sequence[str] = (),
|
|
36
|
+
positional_or_named: Sequence[str] = (),
|
|
37
|
+
var_positional: 'str|None' = None,
|
|
38
|
+
named_only: Sequence[str] = (),
|
|
39
|
+
var_named: 'str|None' = None,
|
|
40
|
+
defaults: 'Mapping[str, Any]|None' = None,
|
|
41
|
+
embedded: Sequence[str] = (),
|
|
42
|
+
types: 'Mapping[str, TypeInfo]|None' = None,
|
|
43
|
+
return_type: 'TypeInfo|None' = None):
|
|
33
44
|
self.name = name
|
|
34
45
|
self.type = type
|
|
35
|
-
self.positional_only = positional_only
|
|
36
|
-
self.positional_or_named = positional_or_named
|
|
46
|
+
self.positional_only = tuple(positional_only)
|
|
47
|
+
self.positional_or_named = tuple(positional_or_named)
|
|
37
48
|
self.var_positional = var_positional
|
|
38
|
-
self.named_only = named_only
|
|
49
|
+
self.named_only = tuple(named_only)
|
|
39
50
|
self.var_named = var_named
|
|
51
|
+
self.embedded = tuple(embedded)
|
|
40
52
|
self.defaults = defaults or {}
|
|
41
53
|
self.types = types
|
|
54
|
+
self.return_type = return_type
|
|
55
|
+
|
|
56
|
+
@property
|
|
57
|
+
def name(self) -> 'str|None':
|
|
58
|
+
return self._name if not callable(self._name) else self._name()
|
|
59
|
+
|
|
60
|
+
@name.setter
|
|
61
|
+
def name(self, name: 'str|Callable[[], str]|None'):
|
|
62
|
+
self._name = name
|
|
42
63
|
|
|
43
64
|
@setter
|
|
44
|
-
def types(self, types):
|
|
65
|
+
def types(self, types) -> 'dict[str, TypeInfo]|None':
|
|
45
66
|
return TypeValidator(self).validate(types)
|
|
46
67
|
|
|
68
|
+
@setter
|
|
69
|
+
def return_type(self, hint) -> 'TypeInfo|None':
|
|
70
|
+
if hint in (None, type(None)):
|
|
71
|
+
return None
|
|
72
|
+
if isinstance(hint, TypeInfo):
|
|
73
|
+
return hint
|
|
74
|
+
return TypeInfo.from_type_hint(hint)
|
|
75
|
+
|
|
47
76
|
@property
|
|
48
|
-
def positional(self):
|
|
77
|
+
def positional(self) -> 'tuple[str, ...]':
|
|
49
78
|
return self.positional_only + self.positional_or_named
|
|
50
79
|
|
|
51
80
|
@property
|
|
52
|
-
def
|
|
81
|
+
def named(self) -> 'tuple[str, ...]':
|
|
82
|
+
return self.named_only + self.positional_or_named
|
|
83
|
+
|
|
84
|
+
@property
|
|
85
|
+
def minargs(self) -> int:
|
|
53
86
|
return len([arg for arg in self.positional if arg not in self.defaults])
|
|
54
87
|
|
|
55
88
|
@property
|
|
56
|
-
def maxargs(self):
|
|
89
|
+
def maxargs(self) -> int:
|
|
57
90
|
return len(self.positional) if not self.var_positional else sys.maxsize
|
|
58
91
|
|
|
59
92
|
@property
|
|
60
|
-
def argument_names(self):
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
self.named_only +
|
|
65
|
-
([self.var_named] if self.var_named else []))
|
|
93
|
+
def argument_names(self) -> 'tuple[str, ...]':
|
|
94
|
+
var_positional = (self.var_positional,) if self.var_positional else ()
|
|
95
|
+
var_named = (self.var_named,) if self.var_named else ()
|
|
96
|
+
return (self.positional_only + self.positional_or_named + var_positional +
|
|
97
|
+
self.named_only + var_named)
|
|
66
98
|
|
|
67
99
|
def resolve(self, arguments, variables=None, converters=None,
|
|
68
|
-
resolve_named=True,
|
|
69
|
-
dict_to_kwargs=False, languages=None):
|
|
70
|
-
resolver = ArgumentResolver(self, resolve_named,
|
|
71
|
-
|
|
100
|
+
resolve_named=True, resolve_args_until=None,
|
|
101
|
+
dict_to_kwargs=False, languages=None) -> 'tuple[list, list]':
|
|
102
|
+
resolver = ArgumentResolver(self, resolve_named, resolve_args_until,
|
|
103
|
+
dict_to_kwargs)
|
|
72
104
|
positional, named = resolver.resolve(arguments, variables)
|
|
73
105
|
return self.convert(positional, named, converters, dry_run=not variables,
|
|
74
106
|
languages=languages)
|
|
75
107
|
|
|
76
|
-
def convert(self, positional, named, converters=None, dry_run=False,
|
|
108
|
+
def convert(self, positional, named, converters=None, dry_run=False,
|
|
109
|
+
languages=None) -> 'tuple[list, list]':
|
|
77
110
|
if self.types or self.defaults:
|
|
78
111
|
converter = ArgumentConverter(self, converters, dry_run, languages)
|
|
79
112
|
positional, named = converter.convert(positional, named)
|
|
80
113
|
return positional, named
|
|
81
114
|
|
|
82
|
-
def map(self, positional, named, replace_defaults=True):
|
|
115
|
+
def map(self, positional, named, replace_defaults=True) -> 'tuple[list, list]':
|
|
83
116
|
mapper = ArgumentMapper(self)
|
|
84
117
|
return mapper.map(positional, named, replace_defaults)
|
|
85
118
|
|
|
86
|
-
def
|
|
87
|
-
|
|
119
|
+
def copy(self) -> 'ArgumentSpec':
|
|
120
|
+
types = dict(self.types) if self.types is not None else None
|
|
121
|
+
return type(self)(self.name, self.type, self.positional_only,
|
|
122
|
+
self.positional_or_named, self.var_positional,
|
|
123
|
+
self.named_only, self.var_named, dict(self.defaults),
|
|
124
|
+
self.embedded, types, self.return_type)
|
|
125
|
+
|
|
126
|
+
def __iter__(self) -> Iterator['ArgInfo']:
|
|
88
127
|
get_type = (self.types or {}).get
|
|
89
128
|
get_default = self.defaults.get
|
|
90
129
|
for arg in self.positional_only:
|
|
91
130
|
yield ArgInfo(ArgInfo.POSITIONAL_ONLY, arg,
|
|
92
|
-
get_type(arg
|
|
131
|
+
get_type(arg), get_default(arg, NOT_SET))
|
|
93
132
|
if self.positional_only:
|
|
94
133
|
yield ArgInfo(ArgInfo.POSITIONAL_ONLY_MARKER)
|
|
95
134
|
for arg in self.positional_or_named:
|
|
96
135
|
yield ArgInfo(ArgInfo.POSITIONAL_OR_NAMED, arg,
|
|
97
|
-
get_type(arg
|
|
136
|
+
get_type(arg), get_default(arg, NOT_SET))
|
|
98
137
|
if self.var_positional:
|
|
99
138
|
yield ArgInfo(ArgInfo.VAR_POSITIONAL, self.var_positional,
|
|
100
|
-
get_type(self.var_positional
|
|
139
|
+
get_type(self.var_positional))
|
|
101
140
|
elif self.named_only:
|
|
102
141
|
yield ArgInfo(ArgInfo.NAMED_ONLY_MARKER)
|
|
103
142
|
for arg in self.named_only:
|
|
104
143
|
yield ArgInfo(ArgInfo.NAMED_ONLY, arg,
|
|
105
|
-
get_type(arg
|
|
144
|
+
get_type(arg), get_default(arg, NOT_SET))
|
|
106
145
|
if self.var_named:
|
|
107
146
|
yield ArgInfo(ArgInfo.VAR_NAMED, self.var_named,
|
|
108
|
-
get_type(self.var_named
|
|
147
|
+
get_type(self.var_named))
|
|
109
148
|
|
|
110
149
|
def __bool__(self):
|
|
111
150
|
return any([self.positional_only, self.positional_or_named, self.var_positional,
|
|
112
|
-
self.named_only, self.var_named])
|
|
151
|
+
self.named_only, self.var_named, self.return_type])
|
|
113
152
|
|
|
114
153
|
def __str__(self):
|
|
115
154
|
return ', '.join(str(arg) for arg in self)
|
|
@@ -117,7 +156,6 @@ class ArgumentSpec:
|
|
|
117
156
|
|
|
118
157
|
class ArgInfo:
|
|
119
158
|
"""Contains argument information. Only used by Libdoc."""
|
|
120
|
-
NOTSET = object()
|
|
121
159
|
POSITIONAL_ONLY = 'POSITIONAL_ONLY'
|
|
122
160
|
POSITIONAL_ONLY_MARKER = 'POSITIONAL_ONLY_MARKER'
|
|
123
161
|
POSITIONAL_OR_NAMED = 'POSITIONAL_OR_NAMED'
|
|
@@ -126,32 +164,26 @@ class ArgInfo:
|
|
|
126
164
|
NAMED_ONLY = 'NAMED_ONLY'
|
|
127
165
|
VAR_NAMED = 'VAR_NAMED'
|
|
128
166
|
|
|
129
|
-
def __init__(self, kind
|
|
167
|
+
def __init__(self, kind: str,
|
|
168
|
+
name: str = '',
|
|
169
|
+
type: 'TypeInfo|None' = None,
|
|
170
|
+
default: Any = NOT_SET):
|
|
130
171
|
self.kind = kind
|
|
131
172
|
self.name = name
|
|
132
|
-
self.type = TypeInfo
|
|
173
|
+
self.type = type or TypeInfo()
|
|
133
174
|
self.default = default
|
|
134
175
|
|
|
135
176
|
@property
|
|
136
|
-
def required(self):
|
|
177
|
+
def required(self) -> bool:
|
|
137
178
|
if self.kind in (self.POSITIONAL_ONLY,
|
|
138
179
|
self.POSITIONAL_OR_NAMED,
|
|
139
180
|
self.NAMED_ONLY):
|
|
140
|
-
return self.default is
|
|
181
|
+
return self.default is NOT_SET
|
|
141
182
|
return False
|
|
142
183
|
|
|
143
184
|
@property
|
|
144
|
-
def
|
|
145
|
-
|
|
146
|
-
if not self.type:
|
|
147
|
-
return []
|
|
148
|
-
if self.type.is_union:
|
|
149
|
-
return [str(t) for t in self.type.nested]
|
|
150
|
-
return [str(self.type)]
|
|
151
|
-
|
|
152
|
-
@property
|
|
153
|
-
def default_repr(self):
|
|
154
|
-
if self.default is self.NOTSET:
|
|
185
|
+
def default_repr(self) -> 'str|None':
|
|
186
|
+
if self.default is NOT_SET:
|
|
155
187
|
return None
|
|
156
188
|
if isinstance(self.default, Enum):
|
|
157
189
|
return self.default.name
|
|
@@ -172,71 +204,6 @@ class ArgInfo:
|
|
|
172
204
|
default_sep = ' = '
|
|
173
205
|
else:
|
|
174
206
|
default_sep = '='
|
|
175
|
-
if self.default is not
|
|
207
|
+
if self.default is not NOT_SET:
|
|
176
208
|
ret = f'{ret}{default_sep}{self.default_repr}'
|
|
177
209
|
return ret
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
Type = Union[type, str, tuple, type(ArgInfo.NOTSET)]
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
class TypeInfo:
|
|
184
|
-
"""Represents argument type. Only used by Libdoc.
|
|
185
|
-
|
|
186
|
-
With unions and parametrized types, :attr:`nested` contains nested types.
|
|
187
|
-
"""
|
|
188
|
-
NOTSET = ArgInfo.NOTSET
|
|
189
|
-
|
|
190
|
-
def __init__(self, type: Type = NOTSET, nested: Tuple['TypeInfo'] = ()):
|
|
191
|
-
self.type = type
|
|
192
|
-
self.nested = nested
|
|
193
|
-
|
|
194
|
-
@property
|
|
195
|
-
def name(self) -> str:
|
|
196
|
-
if isinstance(self.type, str):
|
|
197
|
-
return self.type
|
|
198
|
-
return type_repr(self.type, nested=False)
|
|
199
|
-
|
|
200
|
-
@property
|
|
201
|
-
def is_union(self) -> bool:
|
|
202
|
-
if isinstance(self.type, str):
|
|
203
|
-
return self.type == 'Union'
|
|
204
|
-
return is_union(self.type, allow_tuple=True)
|
|
205
|
-
|
|
206
|
-
@classmethod
|
|
207
|
-
def from_type(cls, type: Type) -> 'TypeInfo':
|
|
208
|
-
if type is cls.NOTSET:
|
|
209
|
-
return cls()
|
|
210
|
-
if isinstance(type, dict):
|
|
211
|
-
return cls.from_dict(type)
|
|
212
|
-
if isinstance(type, (tuple, list)):
|
|
213
|
-
if not type:
|
|
214
|
-
return cls()
|
|
215
|
-
if len(type) == 1:
|
|
216
|
-
return cls(type[0])
|
|
217
|
-
nested = tuple(cls.from_type(t) for t in type)
|
|
218
|
-
return cls('Union', nested)
|
|
219
|
-
if has_args(type):
|
|
220
|
-
nested = tuple(cls.from_type(t) for t in type.__args__)
|
|
221
|
-
return cls(type, nested)
|
|
222
|
-
return cls(type)
|
|
223
|
-
|
|
224
|
-
@classmethod
|
|
225
|
-
def from_dict(cls, data: dict) -> 'TypeInfo':
|
|
226
|
-
if not data:
|
|
227
|
-
return cls()
|
|
228
|
-
nested = tuple(cls.from_dict(n) for n in data['nested'])
|
|
229
|
-
return cls(data['name'], nested)
|
|
230
|
-
|
|
231
|
-
def __str__(self):
|
|
232
|
-
if self.is_union:
|
|
233
|
-
return ' | '.join(str(n) for n in self.nested)
|
|
234
|
-
if isinstance(self.type, str):
|
|
235
|
-
if self.nested:
|
|
236
|
-
nested = ', '.join(str(n) for n in self.nested)
|
|
237
|
-
return f'{self.name}[{nested}]'
|
|
238
|
-
return self.name
|
|
239
|
-
return type_repr(self.type)
|
|
240
|
-
|
|
241
|
-
def __bool__(self):
|
|
242
|
-
return self.type is not self.NOTSET
|
{robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/arguments/argumentvalidator.py
RENAMED
|
@@ -13,44 +13,48 @@
|
|
|
13
13
|
# See the License for the specific language governing permissions and
|
|
14
14
|
# limitations under the License.
|
|
15
15
|
|
|
16
|
+
from typing import TYPE_CHECKING
|
|
17
|
+
|
|
16
18
|
from robot.errors import DataError
|
|
17
|
-
from robot.utils import plural_or_not, seq2str
|
|
19
|
+
from robot.utils import plural_or_not as s, seq2str
|
|
18
20
|
from robot.variables import is_dict_variable, is_list_variable
|
|
19
21
|
|
|
22
|
+
if TYPE_CHECKING:
|
|
23
|
+
from .argumentspec import ArgumentSpec
|
|
24
|
+
|
|
20
25
|
|
|
21
26
|
class ArgumentValidator:
|
|
22
27
|
|
|
23
|
-
def __init__(self,
|
|
24
|
-
|
|
25
|
-
self._argspec = argspec
|
|
28
|
+
def __init__(self, arg_spec: 'ArgumentSpec'):
|
|
29
|
+
self.spec = arg_spec
|
|
26
30
|
|
|
27
31
|
def validate(self, positional, named, dryrun=False):
|
|
28
32
|
named = set(name for name, value in named)
|
|
29
33
|
if dryrun and (any(is_list_variable(arg) for arg in positional) or
|
|
30
34
|
any(is_dict_variable(arg) for arg in named)):
|
|
31
35
|
return
|
|
32
|
-
self._validate_no_multiple_values(positional, named, self.
|
|
33
|
-
self._validate_no_positional_only_as_named(named, self.
|
|
34
|
-
self._validate_positional_limits(positional, named, self.
|
|
35
|
-
self._validate_no_mandatory_missing(positional, named, self.
|
|
36
|
-
self._validate_no_named_only_missing(named, self.
|
|
37
|
-
self._validate_no_extra_named(named, self.
|
|
36
|
+
self._validate_no_multiple_values(positional, named, self.spec)
|
|
37
|
+
self._validate_no_positional_only_as_named(named, self.spec)
|
|
38
|
+
self._validate_positional_limits(positional, named, self.spec)
|
|
39
|
+
self._validate_no_mandatory_missing(positional, named, self.spec)
|
|
40
|
+
self._validate_no_named_only_missing(named, self.spec)
|
|
41
|
+
self._validate_no_extra_named(named, self.spec)
|
|
38
42
|
|
|
39
43
|
def _validate_no_multiple_values(self, positional, named, spec):
|
|
40
|
-
for name in spec.positional[:len(positional)]:
|
|
44
|
+
for name in spec.positional[:len(positional)-len(spec.embedded)]:
|
|
41
45
|
if name in named and name not in spec.positional_only:
|
|
42
|
-
self._raise_error("got multiple values for argument '
|
|
46
|
+
self._raise_error(f"got multiple values for argument '{name}'")
|
|
43
47
|
|
|
44
48
|
def _raise_error(self, message):
|
|
45
|
-
|
|
46
|
-
|
|
49
|
+
name = f"'{self.spec.name}' " if self.spec.name else ''
|
|
50
|
+
raise DataError(f"{self.spec.type.capitalize()} {name}{message}.")
|
|
47
51
|
|
|
48
52
|
def _validate_no_positional_only_as_named(self, named, spec):
|
|
49
53
|
if not spec.var_named:
|
|
50
54
|
for name in named:
|
|
51
55
|
if name in spec.positional_only:
|
|
52
|
-
self._raise_error("does not accept argument '
|
|
53
|
-
"argument"
|
|
56
|
+
self._raise_error(f"does not accept argument '{name}' as named "
|
|
57
|
+
f"argument")
|
|
54
58
|
|
|
55
59
|
def _validate_positional_limits(self, positional, named, spec):
|
|
56
60
|
count = len(positional) + self._named_positionals(named, spec)
|
|
@@ -61,32 +65,34 @@ class ArgumentValidator:
|
|
|
61
65
|
return sum(1 for n in named if n in spec.positional_or_named)
|
|
62
66
|
|
|
63
67
|
def _raise_wrong_count(self, count, spec):
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
68
|
+
embedded = len(spec.embedded)
|
|
69
|
+
minargs = spec.minargs - embedded
|
|
70
|
+
maxargs = spec.maxargs - embedded
|
|
71
|
+
if minargs == maxargs:
|
|
72
|
+
expected = f'{minargs} argument{s(minargs)}'
|
|
67
73
|
elif not spec.var_positional:
|
|
68
|
-
expected = '
|
|
74
|
+
expected = f'{minargs} to {maxargs} arguments'
|
|
69
75
|
else:
|
|
70
|
-
expected = 'at least
|
|
76
|
+
expected = f'at least {minargs} argument{s(minargs)}'
|
|
71
77
|
if spec.var_named or spec.named_only:
|
|
72
78
|
expected = expected.replace('argument', 'non-named argument')
|
|
73
|
-
self._raise_error("expected
|
|
79
|
+
self._raise_error(f"expected {expected}, got {count - embedded}")
|
|
74
80
|
|
|
75
81
|
def _validate_no_mandatory_missing(self, positional, named, spec):
|
|
76
82
|
for name in spec.positional[len(positional):]:
|
|
77
83
|
if name not in spec.defaults and name not in named:
|
|
78
|
-
self._raise_error("missing value for argument '
|
|
84
|
+
self._raise_error(f"missing value for argument '{name}'")
|
|
79
85
|
|
|
80
86
|
def _validate_no_named_only_missing(self, named, spec):
|
|
81
87
|
defined = set(named) | set(spec.defaults)
|
|
82
88
|
missing = [arg for arg in spec.named_only if arg not in defined]
|
|
83
89
|
if missing:
|
|
84
|
-
self._raise_error("missing named-only argument
|
|
85
|
-
|
|
90
|
+
self._raise_error(f"missing named-only argument{s(missing)} "
|
|
91
|
+
f"{seq2str(sorted(missing))}")
|
|
86
92
|
|
|
87
93
|
def _validate_no_extra_named(self, named, spec):
|
|
88
94
|
if not spec.var_named:
|
|
89
95
|
extra = set(named) - set(spec.positional_or_named) - set(spec.named_only)
|
|
90
96
|
if extra:
|
|
91
|
-
self._raise_error("got unexpected named argument
|
|
92
|
-
|
|
97
|
+
self._raise_error(f"got unexpected named argument{s(extra)} "
|
|
98
|
+
f"{seq2str(sorted(extra))}")
|
{robotframework-6.1rc1 → robotframework-7.0}/src/robot/running/arguments/customconverters.py
RENAMED
|
@@ -13,9 +13,7 @@
|
|
|
13
13
|
# See the License for the specific language governing permissions and
|
|
14
14
|
# limitations under the License.
|
|
15
15
|
|
|
16
|
-
from robot.utils import getdoc,
|
|
17
|
-
|
|
18
|
-
from .argumentparser import PythonArgumentParser
|
|
16
|
+
from robot.utils import getdoc, seq2str, type_name
|
|
19
17
|
|
|
20
18
|
|
|
21
19
|
class CustomArgumentConverters:
|
|
@@ -24,12 +22,14 @@ class CustomArgumentConverters:
|
|
|
24
22
|
self.converters = converters
|
|
25
23
|
|
|
26
24
|
@classmethod
|
|
27
|
-
def from_dict(cls, converters, library):
|
|
25
|
+
def from_dict(cls, converters, library=None):
|
|
28
26
|
valid = []
|
|
29
27
|
for type_, conv in converters.items():
|
|
30
28
|
try:
|
|
31
29
|
info = ConverterInfo.for_converter(type_, conv, library)
|
|
32
30
|
except TypeError as err:
|
|
31
|
+
if library is None:
|
|
32
|
+
raise
|
|
33
33
|
library.report_error(str(err))
|
|
34
34
|
else:
|
|
35
35
|
valid.append(info)
|
|
@@ -78,20 +78,23 @@ class ConverterInfo:
|
|
|
78
78
|
raise TypeError(f'Custom converters must be callable, converter for '
|
|
79
79
|
f'{type_name(type_)} is {type_name(converter)}.')
|
|
80
80
|
spec = cls._get_arg_spec(converter)
|
|
81
|
-
|
|
82
|
-
|
|
81
|
+
type_info = spec.types.get(spec.positional[0] if spec.positional
|
|
82
|
+
else spec.var_positional)
|
|
83
|
+
if type_info is None:
|
|
83
84
|
accepts = ()
|
|
84
|
-
elif is_union
|
|
85
|
-
accepts =
|
|
86
|
-
elif hasattr(arg_type, '__origin__'):
|
|
87
|
-
accepts = (arg_type.__origin__,)
|
|
85
|
+
elif type_info.is_union:
|
|
86
|
+
accepts = type_info.nested
|
|
88
87
|
else:
|
|
89
|
-
accepts = (
|
|
88
|
+
accepts = (type_info,)
|
|
89
|
+
accepts = tuple(info.type for info in accepts)
|
|
90
90
|
pass_library = spec.minargs == 2 or spec.var_positional
|
|
91
91
|
return cls(type_, converter, accepts, library if pass_library else None)
|
|
92
92
|
|
|
93
93
|
@classmethod
|
|
94
94
|
def _get_arg_spec(cls, converter):
|
|
95
|
+
# Avoid cyclic import. Yuck.
|
|
96
|
+
from .argumentparser import PythonArgumentParser
|
|
97
|
+
|
|
95
98
|
spec = PythonArgumentParser(type='Converter').parse(converter)
|
|
96
99
|
if spec.minargs > 2:
|
|
97
100
|
required = seq2str([a for a in spec.positional if a not in spec.defaults])
|
|
@@ -109,5 +112,5 @@ class ConverterInfo:
|
|
|
109
112
|
def convert(self, value):
|
|
110
113
|
if not self.library:
|
|
111
114
|
return self.converter(value)
|
|
112
|
-
return self.converter(value, self.library.
|
|
115
|
+
return self.converter(value, self.library.instance)
|
|
113
116
|
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
# Copyright 2008-2015 Nokia Networks
|
|
2
|
+
# Copyright 2016- Robot Framework Foundation
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
|
|
16
|
+
import re
|
|
17
|
+
from typing import Any, Mapping, Sequence
|
|
18
|
+
|
|
19
|
+
from robot.errors import DataError
|
|
20
|
+
from robot.utils import get_error_message
|
|
21
|
+
from robot.variables import VariableMatches
|
|
22
|
+
|
|
23
|
+
from ..context import EXECUTION_CONTEXTS
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class EmbeddedArguments:
|
|
27
|
+
|
|
28
|
+
def __init__(self, name: re.Pattern,
|
|
29
|
+
args: Sequence[str] = (),
|
|
30
|
+
custom_patterns: 'Mapping[str, str]|None' = None):
|
|
31
|
+
self.name = name
|
|
32
|
+
self.args = tuple(args)
|
|
33
|
+
self.custom_patterns = custom_patterns or None
|
|
34
|
+
|
|
35
|
+
@classmethod
|
|
36
|
+
def from_name(cls, name: str) -> 'EmbeddedArguments|None':
|
|
37
|
+
return EmbeddedArgumentParser().parse(name) if '${' in name else None
|
|
38
|
+
|
|
39
|
+
def match(self, name: str) -> 're.Match|None':
|
|
40
|
+
return self.name.fullmatch(name)
|
|
41
|
+
|
|
42
|
+
def map(self, args: Sequence[Any]) -> 'list[tuple[str, Any]]':
|
|
43
|
+
self.validate(args)
|
|
44
|
+
return list(zip(self.args, args))
|
|
45
|
+
|
|
46
|
+
def validate(self, args: Sequence[Any]):
|
|
47
|
+
"""Validate that embedded args match custom regexps.
|
|
48
|
+
|
|
49
|
+
Initial validation is done already when matching keywords, but this
|
|
50
|
+
validation makes sure arguments match also if they are given as variables.
|
|
51
|
+
|
|
52
|
+
Currently, argument not matching only causes a deprecation warning, but
|
|
53
|
+
that will be changed to ``ValueError`` in RF 8.0:
|
|
54
|
+
https://github.com/robotframework/robotframework/issues/4069
|
|
55
|
+
"""
|
|
56
|
+
if not self.custom_patterns:
|
|
57
|
+
return
|
|
58
|
+
for name, value in zip(self.args, args):
|
|
59
|
+
if name in self.custom_patterns and isinstance(value, str):
|
|
60
|
+
pattern = self.custom_patterns[name]
|
|
61
|
+
if not re.fullmatch(pattern, value):
|
|
62
|
+
# TODO: Change to `raise ValueError(...)` in RF 8.0.
|
|
63
|
+
context = EXECUTION_CONTEXTS.current
|
|
64
|
+
context.warn(f"Embedded argument '{name}' got value {value!r} "
|
|
65
|
+
f"that does not match custom pattern {pattern!r}. "
|
|
66
|
+
f"The argument is still accepted, but this behavior "
|
|
67
|
+
f"will change in Robot Framework 8.0.")
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
class EmbeddedArgumentParser:
|
|
71
|
+
_regexp_extension = re.compile(r'(?<!\\)\(\?.+\)')
|
|
72
|
+
_regexp_group_start = re.compile(r'(?<!\\)\((.*?)\)')
|
|
73
|
+
_escaped_curly = re.compile(r'(\\+)([{}])')
|
|
74
|
+
_regexp_group_escape = r'(?:\1)'
|
|
75
|
+
_default_pattern = '.*?'
|
|
76
|
+
_variable_pattern = r'\$\{[^\}]+\}'
|
|
77
|
+
|
|
78
|
+
def parse(self, string: str) -> 'EmbeddedArguments|None':
|
|
79
|
+
name_parts = ['^']
|
|
80
|
+
args = []
|
|
81
|
+
custom_patterns = {}
|
|
82
|
+
after = string
|
|
83
|
+
for match in VariableMatches(string, identifiers='$'):
|
|
84
|
+
arg, pattern, is_custom = self._get_name_and_pattern(match.base)
|
|
85
|
+
args.append(arg)
|
|
86
|
+
if is_custom:
|
|
87
|
+
custom_patterns[arg] = pattern
|
|
88
|
+
pattern = self._format_custom_regexp(pattern)
|
|
89
|
+
name_parts.extend([re.escape(match.before), f'({pattern})'])
|
|
90
|
+
after = match.after
|
|
91
|
+
if not args:
|
|
92
|
+
return None
|
|
93
|
+
name_parts.extend([re.escape(after), '$'])
|
|
94
|
+
name = self._compile_regexp(''.join(name_parts))
|
|
95
|
+
return EmbeddedArguments(name, args, custom_patterns)
|
|
96
|
+
|
|
97
|
+
def _get_name_and_pattern(self, name: str) -> 'tuple[str, str, bool]':
|
|
98
|
+
if ':' in name:
|
|
99
|
+
name, pattern = name.split(':', 1)
|
|
100
|
+
custom = True
|
|
101
|
+
else:
|
|
102
|
+
pattern = self._default_pattern
|
|
103
|
+
custom = False
|
|
104
|
+
return name, pattern, custom
|
|
105
|
+
|
|
106
|
+
def _format_custom_regexp(self, pattern: str) -> str:
|
|
107
|
+
for formatter in (self._regexp_extensions_are_not_allowed,
|
|
108
|
+
self._make_groups_non_capturing,
|
|
109
|
+
self._unescape_curly_braces,
|
|
110
|
+
self._escape_escapes,
|
|
111
|
+
self._add_automatic_variable_pattern):
|
|
112
|
+
pattern = formatter(pattern)
|
|
113
|
+
return pattern
|
|
114
|
+
|
|
115
|
+
def _regexp_extensions_are_not_allowed(self, pattern: str) -> str:
|
|
116
|
+
if self._regexp_extension.search(pattern):
|
|
117
|
+
raise DataError('Regexp extensions are not allowed in embedded arguments.')
|
|
118
|
+
return pattern
|
|
119
|
+
|
|
120
|
+
def _make_groups_non_capturing(self, pattern: str) -> str:
|
|
121
|
+
return self._regexp_group_start.sub(self._regexp_group_escape, pattern)
|
|
122
|
+
|
|
123
|
+
def _unescape_curly_braces(self, pattern: str) -> str:
|
|
124
|
+
# Users must escape possible lone curly braces in patters (e.g. `${x:\{}`)
|
|
125
|
+
# or otherwise the variable syntax is invalid.
|
|
126
|
+
def unescape(match):
|
|
127
|
+
backslashes = len(match.group(1))
|
|
128
|
+
return '\\' * (backslashes // 2 * 2) + match.group(2)
|
|
129
|
+
return self._escaped_curly.sub(unescape, pattern)
|
|
130
|
+
|
|
131
|
+
def _escape_escapes(self, pattern: str) -> str:
|
|
132
|
+
# When keywords are matched, embedded arguments have not yet been
|
|
133
|
+
# resolved which means possible escapes are still doubled. We thus
|
|
134
|
+
# need to double them in the pattern as well.
|
|
135
|
+
return pattern.replace(r'\\', r'\\\\')
|
|
136
|
+
|
|
137
|
+
def _add_automatic_variable_pattern(self, pattern: str) -> str:
|
|
138
|
+
return f'{pattern}|{self._variable_pattern}'
|
|
139
|
+
|
|
140
|
+
def _compile_regexp(self, pattern: str) -> re.Pattern:
|
|
141
|
+
try:
|
|
142
|
+
return re.compile(''.join(pattern), re.IGNORECASE)
|
|
143
|
+
except Exception:
|
|
144
|
+
raise DataError(f"Compiling embedded arguments regexp failed: "
|
|
145
|
+
f"{get_error_message()}")
|