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
|
@@ -13,21 +13,19 @@
|
|
|
13
13
|
# See the License for the specific language governing permissions and
|
|
14
14
|
# limitations under the License.
|
|
15
15
|
|
|
16
|
+
import re
|
|
17
|
+
import time
|
|
16
18
|
from collections import OrderedDict
|
|
17
19
|
from contextlib import contextmanager
|
|
20
|
+
from datetime import datetime
|
|
18
21
|
from itertools import zip_longest
|
|
19
|
-
import re
|
|
20
|
-
import time
|
|
21
22
|
|
|
22
23
|
from robot.errors import (BreakLoop, ContinueLoop, DataError, ExecutionFailed,
|
|
23
24
|
ExecutionFailures, ExecutionPassed, ExecutionStatus)
|
|
24
|
-
from robot.result import (For as ForResult, While as WhileResult, If as IfResult,
|
|
25
|
-
IfBranch as IfBranchResult, Try as TryResult,
|
|
26
|
-
TryBranch as TryBranchResult)
|
|
27
25
|
from robot.output import librarylogger as logger
|
|
28
|
-
from robot.utils import (cut_assign_value, frange, get_error_message,
|
|
29
|
-
|
|
30
|
-
|
|
26
|
+
from robot.utils import (cut_assign_value, frange, get_error_message, is_list_like,
|
|
27
|
+
is_number, normalize, plural_or_not as s, secs_to_timestr, seq2str,
|
|
28
|
+
split_from_equals, type_name, Matcher, timestr_to_secs)
|
|
31
29
|
from robot.variables import is_dict_variable, evaluate_expression
|
|
32
30
|
|
|
33
31
|
from .statusreporter import StatusReporter
|
|
@@ -43,12 +41,12 @@ class BodyRunner:
|
|
|
43
41
|
self._run = run
|
|
44
42
|
self._templated = templated
|
|
45
43
|
|
|
46
|
-
def run(self,
|
|
44
|
+
def run(self, data, result):
|
|
47
45
|
errors = []
|
|
48
46
|
passed = None
|
|
49
|
-
for
|
|
47
|
+
for item in data.body:
|
|
50
48
|
try:
|
|
51
|
-
|
|
49
|
+
item.run(result, self._context, self._run, self._templated)
|
|
52
50
|
except ExecutionPassed as exception:
|
|
53
51
|
exception.set_earlier_failures(errors)
|
|
54
52
|
passed = exception
|
|
@@ -68,12 +66,12 @@ class KeywordRunner:
|
|
|
68
66
|
self._context = context
|
|
69
67
|
self._run = run
|
|
70
68
|
|
|
71
|
-
def run(self,
|
|
69
|
+
def run(self, data, result, name=None):
|
|
72
70
|
context = self._context
|
|
73
|
-
runner = context.get_runner(name or
|
|
71
|
+
runner = context.get_runner(name or data.name)
|
|
74
72
|
if context.dry_run:
|
|
75
|
-
return runner.dry_run(
|
|
76
|
-
return runner.run(
|
|
73
|
+
return runner.dry_run(data, result, context)
|
|
74
|
+
return runner.run(data, result, context, self._run)
|
|
77
75
|
|
|
78
76
|
|
|
79
77
|
def ForRunner(context, flavor='IN', run=True, templated=False):
|
|
@@ -93,7 +91,7 @@ class ForInRunner:
|
|
|
93
91
|
self._run = run
|
|
94
92
|
self._templated = templated
|
|
95
93
|
|
|
96
|
-
def run(self, data):
|
|
94
|
+
def run(self, data, result):
|
|
97
95
|
error = None
|
|
98
96
|
run = False
|
|
99
97
|
if self._run:
|
|
@@ -101,8 +99,6 @@ class ForInRunner:
|
|
|
101
99
|
error = DataError(data.error, syntax=True)
|
|
102
100
|
else:
|
|
103
101
|
run = True
|
|
104
|
-
result = ForResult(data.variables, data.flavor, data.values, data.start,
|
|
105
|
-
data.mode, data.fill)
|
|
106
102
|
with StatusReporter(data, result, self._context, run) as status:
|
|
107
103
|
if run:
|
|
108
104
|
try:
|
|
@@ -143,7 +139,7 @@ class ForInRunner:
|
|
|
143
139
|
def _get_values_for_rounds(self, data):
|
|
144
140
|
if self._context.dry_run:
|
|
145
141
|
return [None]
|
|
146
|
-
values_per_round = len(data.
|
|
142
|
+
values_per_round = len(data.assign)
|
|
147
143
|
if self._is_dict_iteration(data.values):
|
|
148
144
|
values = self._resolve_dict_values(data.values)
|
|
149
145
|
values = self._map_dict_values_to_rounds(values, values_per_round)
|
|
@@ -213,18 +209,20 @@ class ForInRunner:
|
|
|
213
209
|
f'value{s(values)}.')
|
|
214
210
|
|
|
215
211
|
def _run_one_round(self, data, result, values=None, run=True):
|
|
216
|
-
|
|
212
|
+
iter_data = data.get_iteration()
|
|
213
|
+
iter_result = result.body.create_iteration()
|
|
217
214
|
if values is not None:
|
|
218
215
|
variables = self._context.variables
|
|
219
|
-
else: # Not really run (earlier failure,
|
|
216
|
+
else: # Not really run (earlier failure, un-executed IF branch, dry-run)
|
|
220
217
|
variables = {}
|
|
221
|
-
values = [''] * len(data.
|
|
222
|
-
for name, value in self._map_variables_and_values(data.
|
|
218
|
+
values = [''] * len(data.assign)
|
|
219
|
+
for name, value in self._map_variables_and_values(data.assign, values):
|
|
223
220
|
variables[name] = value
|
|
224
|
-
|
|
221
|
+
iter_data.assign[name] = value
|
|
222
|
+
iter_result.assign[name] = cut_assign_value(value)
|
|
225
223
|
runner = BodyRunner(self._context, run, self._templated)
|
|
226
|
-
with StatusReporter(
|
|
227
|
-
runner.run(
|
|
224
|
+
with StatusReporter(iter_data, iter_result, self._context, run):
|
|
225
|
+
runner.run(iter_data, iter_result)
|
|
228
226
|
|
|
229
227
|
def _map_variables_and_values(self, variables, values):
|
|
230
228
|
if len(variables) == 1 and len(values) != 1:
|
|
@@ -274,13 +272,13 @@ class ForInZipRunner(ForInRunner):
|
|
|
274
272
|
if not mode or self._context.dry_run:
|
|
275
273
|
return None
|
|
276
274
|
try:
|
|
277
|
-
mode = self._context.variables.replace_string(mode)
|
|
278
|
-
if mode in ('STRICT', 'SHORTEST', 'LONGEST'):
|
|
279
|
-
return mode
|
|
280
|
-
raise DataError(f"
|
|
281
|
-
f"
|
|
275
|
+
mode = self._context.variables.replace_string(mode)
|
|
276
|
+
if mode.upper() in ('STRICT', 'SHORTEST', 'LONGEST'):
|
|
277
|
+
return mode.upper()
|
|
278
|
+
raise DataError(f"Value '{mode}' is not accepted. Valid values "
|
|
279
|
+
f"are 'STRICT', 'SHORTEST' and 'LONGEST'.")
|
|
282
280
|
except DataError as err:
|
|
283
|
-
raise DataError(f'Invalid mode: {err}')
|
|
281
|
+
raise DataError(f'Invalid FOR IN ZIP mode: {err}')
|
|
284
282
|
|
|
285
283
|
def _resolve_fill(self, fill):
|
|
286
284
|
if not fill or self._context.dry_run:
|
|
@@ -288,7 +286,7 @@ class ForInZipRunner(ForInRunner):
|
|
|
288
286
|
try:
|
|
289
287
|
return self._context.variables.replace_scalar(fill)
|
|
290
288
|
except DataError as err:
|
|
291
|
-
raise DataError(f'Invalid fill value: {err}')
|
|
289
|
+
raise DataError(f'Invalid FOR IN ZIP fill value: {err}')
|
|
292
290
|
|
|
293
291
|
def _resolve_dict_values(self, values):
|
|
294
292
|
raise DataError('FOR IN ZIP loops do not support iterating over dictionaries.',
|
|
@@ -302,6 +300,8 @@ class ForInZipRunner(ForInRunner):
|
|
|
302
300
|
return zip_longest(*values, fillvalue=self._fill)
|
|
303
301
|
if self._mode == 'STRICT':
|
|
304
302
|
self._validate_strict_lengths(values)
|
|
303
|
+
if self._mode is None:
|
|
304
|
+
self._deprecate_different_lengths(values)
|
|
305
305
|
return zip(*values)
|
|
306
306
|
|
|
307
307
|
def _validate_types(self, values):
|
|
@@ -316,12 +316,21 @@ class ForInZipRunner(ForInRunner):
|
|
|
316
316
|
try:
|
|
317
317
|
lengths.append(len(item))
|
|
318
318
|
except TypeError:
|
|
319
|
-
raise DataError(f"FOR IN ZIP items
|
|
320
|
-
f"but item {index} does not.")
|
|
319
|
+
raise DataError(f"FOR IN ZIP items must have length in the STRICT "
|
|
320
|
+
f"mode, but item {index} does not.")
|
|
321
321
|
if len(set(lengths)) > 1:
|
|
322
|
-
raise DataError(f"FOR IN ZIP items
|
|
322
|
+
raise DataError(f"FOR IN ZIP items must have equal lengths in the STRICT "
|
|
323
323
|
f"mode, but lengths are {seq2str(lengths, quote='')}.")
|
|
324
324
|
|
|
325
|
+
def _deprecate_different_lengths(self, values):
|
|
326
|
+
try:
|
|
327
|
+
self._validate_strict_lengths(values)
|
|
328
|
+
except DataError as err:
|
|
329
|
+
logger.warn(f"FOR IN ZIP default mode will be changed from SHORTEST to "
|
|
330
|
+
f"STRICT in Robot Framework 8.0. Use 'mode=SHORTEST' to keep "
|
|
331
|
+
f"using the SHORTEST mode. If the mode is not changed, "
|
|
332
|
+
f"execution will fail like this in the future: {err}")
|
|
333
|
+
|
|
325
334
|
|
|
326
335
|
class ForInEnumerateRunner(ForInRunner):
|
|
327
336
|
flavor = 'IN ENUMERATE'
|
|
@@ -339,9 +348,9 @@ class ForInEnumerateRunner(ForInRunner):
|
|
|
339
348
|
try:
|
|
340
349
|
return int(start)
|
|
341
350
|
except ValueError:
|
|
342
|
-
raise DataError(f"
|
|
351
|
+
raise DataError(f"Value must be an integer, got '{start}'.")
|
|
343
352
|
except DataError as err:
|
|
344
|
-
raise DataError(f'Invalid start value: {err}')
|
|
353
|
+
raise DataError(f'Invalid FOR IN ENUMERATE start value: {err}')
|
|
345
354
|
|
|
346
355
|
def _map_dict_values_to_rounds(self, values, per_round):
|
|
347
356
|
if per_round > 3:
|
|
@@ -370,15 +379,13 @@ class WhileRunner:
|
|
|
370
379
|
self._run = run
|
|
371
380
|
self._templated = templated
|
|
372
381
|
|
|
373
|
-
def run(self, data):
|
|
382
|
+
def run(self, data, result):
|
|
374
383
|
ctx = self._context
|
|
375
384
|
error = None
|
|
376
385
|
run = False
|
|
377
386
|
limit = None
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
starttime=get_timestamp())
|
|
381
|
-
iter_result = loop_result.body.create_iteration(starttime=get_timestamp())
|
|
387
|
+
result.start_time = datetime.now()
|
|
388
|
+
iter_result = result.body.create_iteration(start_time=datetime.now())
|
|
382
389
|
if self._run:
|
|
383
390
|
if data.error:
|
|
384
391
|
error = DataError(data.error, syntax=True)
|
|
@@ -391,9 +398,10 @@ class WhileRunner:
|
|
|
391
398
|
run = self._should_run(data.condition, ctx.variables)
|
|
392
399
|
except DataError as err:
|
|
393
400
|
error = err
|
|
394
|
-
with StatusReporter(data,
|
|
401
|
+
with StatusReporter(data, result, self._context, run):
|
|
402
|
+
iter_data = data.get_iteration()
|
|
395
403
|
if ctx.dry_run or not run:
|
|
396
|
-
self._run_iteration(
|
|
404
|
+
self._run_iteration(iter_data, iter_result, run)
|
|
397
405
|
if error:
|
|
398
406
|
raise error
|
|
399
407
|
return
|
|
@@ -401,7 +409,7 @@ class WhileRunner:
|
|
|
401
409
|
while True:
|
|
402
410
|
try:
|
|
403
411
|
with limit:
|
|
404
|
-
self._run_iteration(
|
|
412
|
+
self._run_iteration(iter_data, iter_result)
|
|
405
413
|
except (BreakLoop, ContinueLoop) as ctrl:
|
|
406
414
|
if ctrl.earlier_failures:
|
|
407
415
|
errors.extend(ctrl.earlier_failures.get_errors())
|
|
@@ -420,7 +428,8 @@ class WhileRunner:
|
|
|
420
428
|
errors.extend(failed.get_errors())
|
|
421
429
|
if not failed.can_continue(ctx, self._templated):
|
|
422
430
|
break
|
|
423
|
-
iter_result =
|
|
431
|
+
iter_result = result.body.create_iteration(start_time=datetime.now())
|
|
432
|
+
iter_data = data.get_iteration()
|
|
424
433
|
if not self._should_run(data.condition, ctx.variables):
|
|
425
434
|
break
|
|
426
435
|
if errors:
|
|
@@ -429,7 +438,7 @@ class WhileRunner:
|
|
|
429
438
|
def _run_iteration(self, data, result, run=True):
|
|
430
439
|
runner = BodyRunner(self._context, run, self._templated)
|
|
431
440
|
with StatusReporter(data, result, self._context, run):
|
|
432
|
-
runner.run(data
|
|
441
|
+
runner.run(data, result)
|
|
433
442
|
|
|
434
443
|
def _should_run(self, condition, variables):
|
|
435
444
|
if not condition:
|
|
@@ -450,13 +459,13 @@ class IfRunner:
|
|
|
450
459
|
self._run = run
|
|
451
460
|
self._templated = templated
|
|
452
461
|
|
|
453
|
-
def run(self, data):
|
|
462
|
+
def run(self, data, result):
|
|
454
463
|
with self._dry_run_recursion_detection(data) as recursive_dry_run:
|
|
455
464
|
error = None
|
|
456
|
-
with StatusReporter(data,
|
|
465
|
+
with StatusReporter(data, result, self._context, self._run):
|
|
457
466
|
for branch in data.body:
|
|
458
467
|
try:
|
|
459
|
-
if self._run_if_branch(branch, recursive_dry_run, data.error):
|
|
468
|
+
if self._run_if_branch(branch, result, recursive_dry_run, data.error):
|
|
460
469
|
self._run = False
|
|
461
470
|
except ExecutionStatus as err:
|
|
462
471
|
error = err
|
|
@@ -466,54 +475,52 @@ class IfRunner:
|
|
|
466
475
|
|
|
467
476
|
@contextmanager
|
|
468
477
|
def _dry_run_recursion_detection(self, data):
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
recursive_dry_run = data in self._dry_run_stack
|
|
472
|
-
self._dry_run_stack.append(data)
|
|
478
|
+
if not self._context.dry_run:
|
|
479
|
+
yield False
|
|
473
480
|
else:
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
481
|
+
data = data.to_dict()
|
|
482
|
+
recursive = data in self._dry_run_stack
|
|
483
|
+
self._dry_run_stack.append(data)
|
|
484
|
+
try:
|
|
485
|
+
yield recursive
|
|
486
|
+
finally:
|
|
479
487
|
self._dry_run_stack.pop()
|
|
480
488
|
|
|
481
|
-
def _run_if_branch(self,
|
|
489
|
+
def _run_if_branch(self, data, result, recursive_dry_run=False, syntax_error=None):
|
|
482
490
|
context = self._context
|
|
483
|
-
result =
|
|
491
|
+
result = result.body.create_branch(data.type, data.condition,
|
|
492
|
+
start_time=datetime.now())
|
|
484
493
|
error = None
|
|
485
494
|
if syntax_error:
|
|
486
495
|
run_branch = False
|
|
487
496
|
error = DataError(syntax_error, syntax=True)
|
|
488
497
|
else:
|
|
489
498
|
try:
|
|
490
|
-
run_branch = self._should_run_branch(
|
|
499
|
+
run_branch = self._should_run_branch(data, context, recursive_dry_run)
|
|
491
500
|
except DataError as err:
|
|
492
501
|
error = err
|
|
493
502
|
run_branch = False
|
|
494
|
-
with StatusReporter(
|
|
503
|
+
with StatusReporter(data, result, context, run_branch):
|
|
495
504
|
runner = BodyRunner(context, run_branch, self._templated)
|
|
496
505
|
if not recursive_dry_run:
|
|
497
|
-
runner.run(
|
|
506
|
+
runner.run(data, result)
|
|
498
507
|
if error and self._run:
|
|
499
508
|
raise error
|
|
500
509
|
return run_branch
|
|
501
510
|
|
|
502
|
-
def _should_run_branch(self,
|
|
503
|
-
condition = branch.condition
|
|
504
|
-
variables = context.variables
|
|
511
|
+
def _should_run_branch(self, data, context, recursive_dry_run=False):
|
|
505
512
|
if context.dry_run:
|
|
506
513
|
return not recursive_dry_run
|
|
507
514
|
if not self._run:
|
|
508
515
|
return False
|
|
509
|
-
if condition is None:
|
|
516
|
+
if data.condition is None:
|
|
510
517
|
return True
|
|
511
518
|
try:
|
|
512
|
-
return evaluate_expression(condition, variables.current,
|
|
519
|
+
return evaluate_expression(data.condition, context.variables.current,
|
|
513
520
|
resolve_variables=True)
|
|
514
521
|
except Exception:
|
|
515
522
|
msg = get_error_message()
|
|
516
|
-
raise DataError(f'Invalid {
|
|
523
|
+
raise DataError(f'Invalid {data.type} condition: {msg}')
|
|
517
524
|
|
|
518
525
|
|
|
519
526
|
class TryRunner:
|
|
@@ -523,39 +530,39 @@ class TryRunner:
|
|
|
523
530
|
self._run = run
|
|
524
531
|
self._templated = templated
|
|
525
532
|
|
|
526
|
-
def run(self, data):
|
|
533
|
+
def run(self, data, result):
|
|
527
534
|
run = self._run
|
|
528
|
-
with StatusReporter(data,
|
|
535
|
+
with StatusReporter(data, result, self._context, run):
|
|
529
536
|
if data.error:
|
|
530
|
-
self._run_invalid(data)
|
|
537
|
+
self._run_invalid(data, result)
|
|
531
538
|
return
|
|
532
|
-
error = self._run_try(data, run)
|
|
539
|
+
error = self._run_try(data, result, run)
|
|
533
540
|
run_excepts_or_else = self._should_run_excepts_or_else(error, run)
|
|
534
541
|
if error:
|
|
535
|
-
error = self._run_excepts(data, error, run=run_excepts_or_else)
|
|
536
|
-
self._run_else(data, run=False)
|
|
542
|
+
error = self._run_excepts(data, result, error, run=run_excepts_or_else)
|
|
543
|
+
self._run_else(data, result, run=False)
|
|
537
544
|
else:
|
|
538
|
-
self._run_excepts(data, error, run=False)
|
|
539
|
-
error = self._run_else(data, run=run_excepts_or_else)
|
|
540
|
-
error = self._run_finally(data, run) or error
|
|
545
|
+
self._run_excepts(data, result, error, run=False)
|
|
546
|
+
error = self._run_else(data, result, run=run_excepts_or_else)
|
|
547
|
+
error = self._run_finally(data, result, run) or error
|
|
541
548
|
if error:
|
|
542
549
|
raise error
|
|
543
550
|
|
|
544
|
-
def _run_invalid(self, data):
|
|
551
|
+
def _run_invalid(self, data, result):
|
|
545
552
|
error_reported = False
|
|
546
553
|
for branch in data.body:
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
with StatusReporter(branch,
|
|
554
|
+
branch_result = result.body.create_branch(branch.type, branch.patterns,
|
|
555
|
+
branch.pattern_type, branch.assign)
|
|
556
|
+
with StatusReporter(branch, branch_result, self._context, run=False, suppress=True):
|
|
550
557
|
runner = BodyRunner(self._context, run=False, templated=self._templated)
|
|
551
|
-
runner.run(branch
|
|
558
|
+
runner.run(branch, branch_result)
|
|
552
559
|
if not error_reported:
|
|
553
560
|
error_reported = True
|
|
554
561
|
raise DataError(data.error, syntax=True)
|
|
555
562
|
raise ExecutionFailed(data.error, syntax=True)
|
|
556
563
|
|
|
557
|
-
def _run_try(self, data, run):
|
|
558
|
-
result =
|
|
564
|
+
def _run_try(self, data, result, run):
|
|
565
|
+
result = result.body.create_branch(data.TRY)
|
|
559
566
|
return self._run_branch(data.try_branch, result, run)
|
|
560
567
|
|
|
561
568
|
def _should_run_excepts_or_else(self, error, run):
|
|
@@ -565,19 +572,19 @@ class TryRunner:
|
|
|
565
572
|
return True
|
|
566
573
|
return not (error.skip or error.syntax or isinstance(error, ExecutionPassed))
|
|
567
574
|
|
|
568
|
-
def _run_branch(self,
|
|
575
|
+
def _run_branch(self, data, result, run=True, error=None):
|
|
569
576
|
try:
|
|
570
|
-
with StatusReporter(
|
|
577
|
+
with StatusReporter(data, result, self._context, run):
|
|
571
578
|
if error:
|
|
572
579
|
raise error
|
|
573
580
|
runner = BodyRunner(self._context, run, self._templated)
|
|
574
|
-
runner.run(
|
|
581
|
+
runner.run(data, result)
|
|
575
582
|
except ExecutionStatus as err:
|
|
576
583
|
return err
|
|
577
584
|
else:
|
|
578
585
|
return None
|
|
579
586
|
|
|
580
|
-
def _run_excepts(self, data, error, run):
|
|
587
|
+
def _run_excepts(self, data, result, error, run):
|
|
581
588
|
for branch in data.except_branches:
|
|
582
589
|
try:
|
|
583
590
|
run_branch = run and self._should_run_except(branch, error)
|
|
@@ -586,15 +593,15 @@ class TryRunner:
|
|
|
586
593
|
pattern_error = err
|
|
587
594
|
else:
|
|
588
595
|
pattern_error = None
|
|
589
|
-
|
|
590
|
-
|
|
596
|
+
branch_result = result.body.create_branch(branch.type, branch.patterns,
|
|
597
|
+
branch.pattern_type, branch.assign)
|
|
591
598
|
if run_branch:
|
|
592
|
-
if branch.
|
|
593
|
-
self._context.variables[branch.
|
|
594
|
-
error = self._run_branch(branch,
|
|
599
|
+
if branch.assign:
|
|
600
|
+
self._context.variables[branch.assign] = str(error)
|
|
601
|
+
error = self._run_branch(branch, branch_result, error=pattern_error)
|
|
595
602
|
run = False
|
|
596
603
|
else:
|
|
597
|
-
self._run_branch(branch,
|
|
604
|
+
self._run_branch(branch, branch_result, run=False)
|
|
598
605
|
return error
|
|
599
606
|
|
|
600
607
|
def _should_run_except(self, branch, error):
|
|
@@ -602,9 +609,9 @@ class TryRunner:
|
|
|
602
609
|
return True
|
|
603
610
|
matchers = {
|
|
604
611
|
'GLOB': lambda m, p: Matcher(p, spaceless=False, caseless=False).match(m),
|
|
612
|
+
'REGEXP': lambda m, p: re.fullmatch(p, m) is not None,
|
|
613
|
+
'START': lambda m, p: m.startswith(p),
|
|
605
614
|
'LITERAL': lambda m, p: m == p,
|
|
606
|
-
'REGEXP': lambda m, p: re.match(rf'{p}\Z', m) is not None,
|
|
607
|
-
'START': lambda m, p: m.startswith(p)
|
|
608
615
|
}
|
|
609
616
|
if branch.pattern_type:
|
|
610
617
|
pattern_type = self._context.variables.replace_string(branch.pattern_type)
|
|
@@ -612,25 +619,25 @@ class TryRunner:
|
|
|
612
619
|
pattern_type = 'LITERAL'
|
|
613
620
|
matcher = matchers.get(pattern_type.upper())
|
|
614
621
|
if not matcher:
|
|
615
|
-
raise DataError(f"Invalid EXCEPT pattern type '{pattern_type}'
|
|
616
|
-
f"
|
|
622
|
+
raise DataError(f"Invalid EXCEPT pattern type '{pattern_type}'. "
|
|
623
|
+
f"Valid values are {seq2str(matchers)}.")
|
|
617
624
|
for pattern in branch.patterns:
|
|
618
625
|
if matcher(error.message, self._context.variables.replace_string(pattern)):
|
|
619
626
|
return True
|
|
620
627
|
return False
|
|
621
628
|
|
|
622
|
-
def _run_else(self, data, run):
|
|
629
|
+
def _run_else(self, data, result, run):
|
|
623
630
|
if data.else_branch:
|
|
624
|
-
result =
|
|
631
|
+
result = result.body.create_branch(data.ELSE)
|
|
625
632
|
return self._run_branch(data.else_branch, result, run)
|
|
626
633
|
|
|
627
|
-
def _run_finally(self, data, run):
|
|
634
|
+
def _run_finally(self, data, result, run):
|
|
628
635
|
if data.finally_branch:
|
|
629
|
-
result =
|
|
636
|
+
result = result.body.create_branch(data.FINALLY)
|
|
630
637
|
try:
|
|
631
638
|
with StatusReporter(data.finally_branch, result, self._context, run):
|
|
632
639
|
runner = BodyRunner(self._context, run, self._templated)
|
|
633
|
-
runner.run(data.finally_branch
|
|
640
|
+
runner.run(data.finally_branch, result)
|
|
634
641
|
except ExecutionStatus as err:
|
|
635
642
|
return err
|
|
636
643
|
else:
|
|
@@ -650,44 +657,55 @@ class WhileLimit:
|
|
|
650
657
|
on_limit_message = variables.replace_string(on_limit_message)
|
|
651
658
|
except DataError as err:
|
|
652
659
|
raise DataError(f"Invalid WHILE loop 'on_limit_message': '{err}")
|
|
653
|
-
on_limit = cls.
|
|
660
|
+
on_limit = cls._parse_on_limit(variables, on_limit)
|
|
654
661
|
if not limit:
|
|
655
|
-
return IterationCountLimit(DEFAULT_WHILE_LIMIT,
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
if value.upper() == 'NONE':
|
|
662
|
+
return IterationCountLimit(DEFAULT_WHILE_LIMIT, on_limit, on_limit_message)
|
|
663
|
+
limit = variables.replace_string(limit)
|
|
664
|
+
if limit.upper() == 'NONE':
|
|
659
665
|
return NoLimit()
|
|
660
666
|
try:
|
|
661
|
-
count =
|
|
667
|
+
count = cls._parse_limit_as_count(limit)
|
|
662
668
|
except ValueError:
|
|
663
|
-
|
|
669
|
+
seconds = cls._parse_limit_as_timestr(limit)
|
|
670
|
+
return DurationLimit(seconds, on_limit, on_limit_message)
|
|
664
671
|
else:
|
|
665
|
-
if count <= 0:
|
|
666
|
-
raise DataError(f"Invalid WHILE loop limit: Iteration count must be "
|
|
667
|
-
f"a positive integer, got '{count}'.")
|
|
668
672
|
return IterationCountLimit(count, on_limit, on_limit_message)
|
|
669
|
-
try:
|
|
670
|
-
secs = timestr_to_secs(value)
|
|
671
|
-
except ValueError as err:
|
|
672
|
-
raise DataError(f'Invalid WHILE loop limit: {err.args[0]}')
|
|
673
|
-
else:
|
|
674
|
-
return DurationLimit(secs, on_limit, on_limit_message)
|
|
675
673
|
|
|
676
674
|
@classmethod
|
|
677
|
-
def
|
|
675
|
+
def _parse_on_limit(cls, variables, on_limit):
|
|
678
676
|
if on_limit is None:
|
|
679
677
|
return None
|
|
680
678
|
try:
|
|
681
679
|
on_limit = variables.replace_string(on_limit)
|
|
682
|
-
if on_limit.upper()
|
|
683
|
-
|
|
680
|
+
if on_limit.upper() in ('PASS', 'FAIL'):
|
|
681
|
+
return on_limit.upper()
|
|
682
|
+
raise DataError(f"Value '{on_limit}' is not accepted. Valid values "
|
|
683
|
+
f"are 'PASS' and 'FAIL'.")
|
|
684
684
|
except DataError as err:
|
|
685
|
-
raise DataError(f"Invalid WHILE loop 'on_limit' value
|
|
686
|
-
|
|
687
|
-
|
|
685
|
+
raise DataError(f"Invalid WHILE loop 'on_limit' value: {err}")
|
|
686
|
+
|
|
687
|
+
@classmethod
|
|
688
|
+
def _parse_limit_as_count(cls, limit):
|
|
689
|
+
limit = normalize(limit)
|
|
690
|
+
if limit.endswith('times'):
|
|
691
|
+
limit = limit[:-5]
|
|
692
|
+
elif limit.endswith('x'):
|
|
693
|
+
limit = limit[:-1]
|
|
694
|
+
count = int(limit)
|
|
695
|
+
if count <= 0:
|
|
696
|
+
raise DataError(f"Invalid WHILE loop limit: Iteration count must be "
|
|
697
|
+
f"a positive integer, got '{count}'.")
|
|
698
|
+
return count
|
|
699
|
+
|
|
700
|
+
@classmethod
|
|
701
|
+
def _parse_limit_as_timestr(cls, limit):
|
|
702
|
+
try:
|
|
703
|
+
return timestr_to_secs(limit)
|
|
704
|
+
except ValueError as err:
|
|
705
|
+
raise DataError(f'Invalid WHILE loop limit: {err.args[0]}')
|
|
688
706
|
|
|
689
707
|
def limit_exceeded(self):
|
|
690
|
-
on_limit_pass = self.on_limit == '
|
|
708
|
+
on_limit_pass = self.on_limit == 'PASS'
|
|
691
709
|
if self.on_limit_message:
|
|
692
710
|
raise LimitExceeded(on_limit_pass, self.on_limit_message)
|
|
693
711
|
else:
|
|
@@ -26,7 +26,8 @@ from robot.parsing import (SuiteFile, SuiteDirectory, SuiteStructure,
|
|
|
26
26
|
SuiteStructureBuilder, SuiteStructureVisitor)
|
|
27
27
|
from robot.utils import Importer, seq2str, split_args_from_name_or_path, type_name
|
|
28
28
|
|
|
29
|
-
from ..model import
|
|
29
|
+
from ..model import TestSuite
|
|
30
|
+
from ..resourcemodel import ResourceFile
|
|
30
31
|
from .parsers import (CustomParser, JsonParser, NoInitFileDirectoryParser, Parser,
|
|
31
32
|
RestParser, RobotParser)
|
|
32
33
|
from .settings import TestDefaults
|
|
@@ -84,8 +85,8 @@ class TestSuiteBuilder:
|
|
|
84
85
|
New in RF 6.1.
|
|
85
86
|
:param rpa:
|
|
86
87
|
Explicit execution mode. ``True`` for RPA and ``False`` for test
|
|
87
|
-
automation. By default, mode is got from data file headers
|
|
88
|
-
|
|
88
|
+
automation. By default, mode is got from data file headers.
|
|
89
|
+
Same as ``--rpa`` or ``--norpa``.
|
|
89
90
|
:param lang:
|
|
90
91
|
Additional languages to be supported during parsing.
|
|
91
92
|
Can be a string matching any of the supported language codes or names,
|
|
@@ -111,7 +112,7 @@ class TestSuiteBuilder:
|
|
|
111
112
|
if included_suites != 'DEPRECATED':
|
|
112
113
|
warnings.warn("'TestSuiteBuilder' argument 'included_suites' is deprecated "
|
|
113
114
|
"and has no effect. Use the new 'included_files' argument "
|
|
114
|
-
"or filter the
|
|
115
|
+
"or filter the created suite instead.")
|
|
115
116
|
|
|
116
117
|
def _get_standard_parsers(self, lang: LanguagesLike,
|
|
117
118
|
process_curdir: bool) -> 'dict[str, Parser]':
|
|
@@ -201,11 +202,11 @@ class TestSuiteBuilder:
|
|
|
201
202
|
class SuiteStructureParser(SuiteStructureVisitor):
|
|
202
203
|
|
|
203
204
|
def __init__(self, parsers: 'dict[str|None, Parser]',
|
|
204
|
-
defaults: 'TestDefaults|None' = None,
|
|
205
|
+
defaults: 'TestDefaults|None' = None,
|
|
206
|
+
rpa: 'bool|None' = None):
|
|
205
207
|
self.parsers = parsers
|
|
206
208
|
self.rpa = rpa
|
|
207
209
|
self.defaults = defaults
|
|
208
|
-
self._rpa_given = rpa is not None
|
|
209
210
|
self.suite: 'TestSuite|None' = None
|
|
210
211
|
self._stack: 'list[tuple[TestSuite, TestDefaults]]' = []
|
|
211
212
|
|
|
@@ -215,13 +216,13 @@ class SuiteStructureParser(SuiteStructureVisitor):
|
|
|
215
216
|
|
|
216
217
|
def parse(self, structure: SuiteStructure) -> TestSuite:
|
|
217
218
|
structure.visit(self)
|
|
218
|
-
|
|
219
|
-
suite.rpa = self.rpa
|
|
220
|
-
return suite
|
|
219
|
+
return cast(TestSuite, self.suite)
|
|
221
220
|
|
|
222
221
|
def visit_file(self, structure: SuiteFile):
|
|
223
222
|
LOGGER.info(f"Parsing file '{structure.source}'.")
|
|
224
223
|
suite = self._build_suite_file(structure)
|
|
224
|
+
if self.rpa is not None:
|
|
225
|
+
suite.rpa = self.rpa
|
|
225
226
|
if self.suite is None:
|
|
226
227
|
self.suite = suite
|
|
227
228
|
else:
|
|
@@ -239,8 +240,13 @@ class SuiteStructureParser(SuiteStructureVisitor):
|
|
|
239
240
|
|
|
240
241
|
def end_directory(self, structure: SuiteDirectory):
|
|
241
242
|
suite, _ = self._stack.pop()
|
|
242
|
-
if
|
|
243
|
-
suite.rpa =
|
|
243
|
+
if self.rpa is not None:
|
|
244
|
+
suite.rpa = self.rpa
|
|
245
|
+
elif suite.rpa is None and suite.suites:
|
|
246
|
+
if all(s.rpa is False for s in suite.suites):
|
|
247
|
+
suite.rpa = False
|
|
248
|
+
elif all(s.rpa is True for s in suite.suites):
|
|
249
|
+
suite.rpa = True
|
|
244
250
|
|
|
245
251
|
def _build_suite_file(self, structure: SuiteFile):
|
|
246
252
|
source = cast(Path, structure.source)
|
|
@@ -250,7 +256,6 @@ class SuiteStructureParser(SuiteStructureVisitor):
|
|
|
250
256
|
suite = parser.parse_suite_file(source, defaults)
|
|
251
257
|
if not suite.tests:
|
|
252
258
|
LOGGER.info(f"Data source '{source}' has no tests or tasks.")
|
|
253
|
-
self._validate_execution_mode(suite)
|
|
254
259
|
except DataError as err:
|
|
255
260
|
raise DataError(f"Parsing '{source}' failed: {err.message}")
|
|
256
261
|
return suite
|
|
@@ -267,20 +272,6 @@ class SuiteStructureParser(SuiteStructureVisitor):
|
|
|
267
272
|
raise DataError(f"Parsing '{source}' failed: {err.message}")
|
|
268
273
|
return suite, defaults
|
|
269
274
|
|
|
270
|
-
def _validate_execution_mode(self, suite: TestSuite):
|
|
271
|
-
if self._rpa_given:
|
|
272
|
-
suite.rpa = self.rpa
|
|
273
|
-
elif suite.rpa is None:
|
|
274
|
-
pass
|
|
275
|
-
elif self.rpa is None:
|
|
276
|
-
self.rpa = suite.rpa
|
|
277
|
-
elif self.rpa is not suite.rpa:
|
|
278
|
-
this, that = ('tasks', 'tests') if suite.rpa else ('tests', 'tasks')
|
|
279
|
-
raise DataError(f"Conflicting execution modes. File has {this} "
|
|
280
|
-
f"but files parsed earlier have {that}. Fix headers "
|
|
281
|
-
f"or use '--rpa' or '--norpa' options to set the "
|
|
282
|
-
f"execution mode explicitly.")
|
|
283
|
-
|
|
284
275
|
|
|
285
276
|
class ResourceFileBuilder:
|
|
286
277
|
|