robotframework 7.0.1rc1__zip → 7.1__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-7.0.1rc1 → robotframework-7.1}/PKG-INFO +3 -2
- {robotframework-7.0.1rc1 → robotframework-7.1}/setup.py +2 -1
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/api/interfaces.py +32 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/conf/languages.py +73 -18
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/conf/settings.py +8 -1
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/htmldata/rebot/model.js +22 -33
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/htmldata/template.py +0 -2
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/libdocpkg/jsonbuilder.py +1 -1
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/libraries/BuiltIn.py +16 -3
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/libraries/Collections.py +2 -3
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/libraries/DateTime.py +3 -2
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/libraries/Dialogs.py +12 -4
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/libraries/OperatingSystem.py +4 -4
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/libraries/Process.py +7 -3
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/libraries/String.py +4 -1
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/libraries/dialogs_py.py +17 -1
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/model/modelobject.py +1 -6
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/output/console/__init__.py +3 -3
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/output/console/dotted.py +4 -4
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/output/console/highlighting.py +90 -65
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/output/console/verbose.py +10 -10
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/output/listeners.py +61 -217
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/output/logger.py +32 -16
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/output/loggerapi.py +11 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/output/loggerhelper.py +6 -1
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/output/output.py +2 -1
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/parsing/model/statements.py +1 -1
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/rebot.py +3 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/result/executionresult.py +1 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/result/model.py +1 -1
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/result/resultbuilder.py +12 -11
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/result/xmlelementhandlers.py +12 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/run.py +3 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/__init__.py +1 -1
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/arguments/argumentresolver.py +18 -11
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/arguments/argumentspec.py +2 -2
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/arguments/argumentvalidator.py +0 -8
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/arguments/embedded.py +2 -2
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/bodyrunner.py +34 -19
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/invalidkeyword.py +4 -1
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/keywordimplementation.py +9 -5
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/librarykeyword.py +19 -9
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/librarykeywordrunner.py +25 -19
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/model.py +69 -27
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/namespace.py +20 -26
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/resourcemodel.py +9 -1
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/statusreporter.py +9 -4
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/testlibraries.py +2 -2
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/userkeywordrunner.py +10 -7
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/encodingsniffer.py +3 -1
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/robottime.py +5 -3
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/variables/evaluation.py +1 -4
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/variables/scopes.py +2 -1
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/variables/tablesetter.py +17 -20
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/version.py +1 -1
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robotframework.egg-info/PKG-INFO +3 -2
- {robotframework-7.0.1rc1 → robotframework-7.1}/AUTHORS.rst +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/BUILD.rst +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/CONTRIBUTING.rst +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/COPYRIGHT.txt +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/INSTALL.rst +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/LICENSE.txt +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/MANIFEST.in +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/README.rst +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/setup.cfg +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/__init__.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/__main__.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/api/__init__.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/api/deco.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/api/exceptions.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/api/logger.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/api/parsing.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/api/py.typed +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/conf/__init__.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/conf/gatherfailed.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/errors.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/htmldata/__init__.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/htmldata/common/__init__.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/htmldata/common/js_disabled.css +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/htmldata/common/storage.js +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/htmldata/htmlfilewriter.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/htmldata/jsonwriter.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/htmldata/lib/__init__.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/htmldata/lib/jquery.highlight.min.js +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/htmldata/lib/jquery.min.js +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/htmldata/lib/jquery.tablesorter.min.js +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/htmldata/lib/jquery.tmpl.min.js +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/htmldata/lib/jsxcompressor.min.js +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/htmldata/libdoc/__init__.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/htmldata/libdoc/doc_formatting.css +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/htmldata/libdoc/libdoc.css +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/htmldata/libdoc/libdoc.html +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/htmldata/libdoc/print.css +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/htmldata/libdoc/pygments.css +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/htmldata/rebot/__init__.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/htmldata/rebot/common.css +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/htmldata/rebot/doc_formatting.css +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/htmldata/rebot/fileloading.js +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/htmldata/rebot/log.css +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/htmldata/rebot/log.html +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/htmldata/rebot/log.js +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/htmldata/rebot/print.css +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/htmldata/rebot/report.css +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/htmldata/rebot/report.html +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/htmldata/rebot/testdata.js +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/htmldata/rebot/util.js +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/htmldata/rebot/view.js +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/htmldata/testdoc/__init__.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/htmldata/testdoc/testdoc.css +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/htmldata/testdoc/testdoc.html +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/libdoc.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/libdocpkg/__init__.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/libdocpkg/builder.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/libdocpkg/consoleviewer.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/libdocpkg/datatypes.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/libdocpkg/htmlutils.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/libdocpkg/htmlwriter.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/libdocpkg/jsonwriter.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/libdocpkg/model.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/libdocpkg/output.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/libdocpkg/robotbuilder.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/libdocpkg/standardtypes.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/libdocpkg/writer.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/libdocpkg/xmlbuilder.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/libdocpkg/xmlwriter.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/libraries/Easter.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/libraries/Remote.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/libraries/Screenshot.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/libraries/Telnet.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/libraries/XML.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/libraries/__init__.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/model/__init__.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/model/body.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/model/configurer.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/model/control.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/model/filter.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/model/fixture.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/model/itemlist.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/model/keyword.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/model/message.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/model/metadata.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/model/modifier.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/model/namepatterns.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/model/statistics.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/model/stats.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/model/suitestatistics.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/model/tags.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/model/tagsetter.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/model/tagstatistics.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/model/testcase.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/model/testsuite.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/model/totalstatistics.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/model/visitor.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/output/__init__.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/output/console/quiet.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/output/debugfile.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/output/filelogger.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/output/librarylogger.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/output/pyloggingconf.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/output/stdoutlogsplitter.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/output/xmllogger.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/parsing/__init__.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/parsing/lexer/__init__.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/parsing/lexer/blocklexers.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/parsing/lexer/context.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/parsing/lexer/lexer.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/parsing/lexer/settings.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/parsing/lexer/statementlexers.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/parsing/lexer/tokenizer.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/parsing/lexer/tokens.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/parsing/model/__init__.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/parsing/model/blocks.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/parsing/model/visitor.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/parsing/parser/__init__.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/parsing/parser/blockparsers.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/parsing/parser/fileparser.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/parsing/parser/parser.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/parsing/suitestructure.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/pythonpathsetter.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/reporting/__init__.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/reporting/expandkeywordmatcher.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/reporting/jsbuildingcontext.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/reporting/jsexecutionresult.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/reporting/jsmodelbuilders.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/reporting/jswriter.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/reporting/logreportwriters.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/reporting/outputwriter.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/reporting/resultwriter.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/reporting/stringcache.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/reporting/xunitwriter.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/result/__init__.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/result/configurer.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/result/executionerrors.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/result/flattenkeywordmatcher.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/result/keywordremover.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/result/merger.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/result/messagefilter.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/result/modeldeprecation.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/result/suiteteardownfailed.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/result/visitor.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/arguments/__init__.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/arguments/argumentconverter.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/arguments/argumentmapper.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/arguments/argumentparser.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/arguments/customconverters.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/arguments/typeconverters.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/arguments/typeinfo.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/arguments/typeinfoparser.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/arguments/typevalidator.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/builder/__init__.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/builder/builders.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/builder/parsers.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/builder/settings.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/builder/transformers.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/context.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/dynamicmethods.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/importer.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/keywordfinder.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/libraryscopes.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/outputcapture.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/randomizer.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/runkwregister.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/signalhandler.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/status.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/suiterunner.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/timeouts/__init__.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/timeouts/nosupport.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/timeouts/posix.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/running/timeouts/windows.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/testdoc.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/__init__.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/application.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/argumentparser.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/asserts.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/charwidth.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/compress.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/connectioncache.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/dotdict.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/encoding.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/error.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/escaping.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/etreewrapper.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/filereader.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/frange.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/htmlformatters.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/importer.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/markuputils.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/markupwriters.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/match.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/misc.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/normalizing.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/notset.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/platform.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/recommendations.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/restreader.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/robotenv.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/robotinspect.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/robotio.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/robotpath.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/robottypes.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/setter.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/sortable.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/text.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/typehints.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/utils/unic.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/variables/__init__.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/variables/assigner.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/variables/filesetter.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/variables/finders.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/variables/notfound.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/variables/replacer.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/variables/resolvable.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/variables/search.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/variables/store.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robot/variables/variables.py +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robotframework.egg-info/SOURCES.txt +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robotframework.egg-info/dependency_links.txt +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robotframework.egg-info/entry_points.txt +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/src/robotframework.egg-info/top_level.txt +0 -0
- {robotframework-7.0.1rc1 → robotframework-7.1}/tasks.py +0 -0
|
@@ -49,32 +49,38 @@ class LibraryKeywordRunner:
|
|
|
49
49
|
with StatusReporter(data, result, context, run, implementation=kw):
|
|
50
50
|
if run:
|
|
51
51
|
with assignment.assigner(context) as assigner:
|
|
52
|
-
return_value = self._run(
|
|
52
|
+
return_value = self._run(data, kw, context)
|
|
53
53
|
assigner.assign(return_value)
|
|
54
54
|
return return_value
|
|
55
55
|
|
|
56
56
|
def _config_result(self, result: KeywordResult, data: KeywordData,
|
|
57
57
|
kw: 'LibraryKeyword', assignment):
|
|
58
|
+
args = tuple(data.args)
|
|
59
|
+
if data.named_args:
|
|
60
|
+
args += tuple(f'{n}={v}' for n, v in data.named_args.items())
|
|
58
61
|
result.config(name=self.name,
|
|
59
62
|
owner=kw.owner.name,
|
|
60
63
|
doc=kw.short_doc,
|
|
61
|
-
args=
|
|
64
|
+
args=args,
|
|
62
65
|
assign=tuple(assignment),
|
|
63
66
|
tags=kw.tags,
|
|
64
67
|
type=data.type)
|
|
65
68
|
|
|
66
|
-
def _run(self, kw: 'LibraryKeyword',
|
|
69
|
+
def _run(self, data: KeywordData, kw: 'LibraryKeyword', context):
|
|
67
70
|
if self.pre_run_messages:
|
|
68
71
|
for message in self.pre_run_messages:
|
|
69
72
|
context.output.message(message)
|
|
70
73
|
variables = context.variables if not context.dry_run else None
|
|
71
|
-
positional, named =
|
|
74
|
+
positional, named = self._resolve_arguments(data, kw, variables)
|
|
72
75
|
context.output.trace(lambda: self._trace_log_args(positional, named),
|
|
73
76
|
write_if_flat=False)
|
|
74
77
|
if kw.error:
|
|
75
78
|
raise DataError(kw.error)
|
|
76
79
|
return self._execute(kw.method, positional, named, context)
|
|
77
80
|
|
|
81
|
+
def _resolve_arguments(self, data: KeywordData, kw: 'LibraryKeyword', variables=None):
|
|
82
|
+
return kw.resolve_arguments(data.args, data.named_args, variables, self.languages)
|
|
83
|
+
|
|
78
84
|
def _trace_log_args(self, positional, named):
|
|
79
85
|
args = [prepr(arg) for arg in positional]
|
|
80
86
|
args += ['%s=%s' % (safe_str(n), prepr(v)) for n, v in named]
|
|
@@ -127,18 +133,20 @@ class LibraryKeywordRunner:
|
|
|
127
133
|
self._config_result(result, data, kw, assignment)
|
|
128
134
|
with StatusReporter(data, result, context, run=False, implementation=kw):
|
|
129
135
|
assignment.validate_assignment()
|
|
130
|
-
self.
|
|
136
|
+
if self._executed_in_dry_run(kw):
|
|
137
|
+
self._run(data, kw, context)
|
|
138
|
+
else:
|
|
139
|
+
self._resolve_arguments(data, kw)
|
|
140
|
+
self._end_dry_run(data, kw, result, context)
|
|
131
141
|
|
|
132
|
-
def
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
else:
|
|
136
|
-
kw.resolve_arguments(args, languages=self.languages)
|
|
142
|
+
def _end_dry_run(self, data: KeywordData, kw: 'LibraryKeyword',
|
|
143
|
+
result: KeywordResult, context):
|
|
144
|
+
pass
|
|
137
145
|
|
|
138
146
|
def _executed_in_dry_run(self, kw: 'LibraryKeyword'):
|
|
139
147
|
return (kw.owner.name == 'BuiltIn'
|
|
140
148
|
and kw.name in ('Import Library', 'Set Library Search Order',
|
|
141
|
-
'Set Tags', 'Remove Tags'))
|
|
149
|
+
'Set Tags', 'Remove Tags', 'Import Resource'))
|
|
142
150
|
|
|
143
151
|
|
|
144
152
|
class EmbeddedArgumentsRunner(LibraryKeywordRunner):
|
|
@@ -147,11 +155,9 @@ class EmbeddedArgumentsRunner(LibraryKeywordRunner):
|
|
|
147
155
|
super().__init__(keyword, name)
|
|
148
156
|
self.embedded_args = keyword.embedded.match(name).groups()
|
|
149
157
|
|
|
150
|
-
def
|
|
151
|
-
return
|
|
152
|
-
|
|
153
|
-
def _dry_run(self, kw: 'LibraryKeyword', args, result: KeywordResult, context):
|
|
154
|
-
return super()._dry_run(kw, self.embedded_args + args, result, context)
|
|
158
|
+
def _resolve_arguments(self, data: KeywordData, kw: 'LibraryKeyword', variables=None):
|
|
159
|
+
return kw.resolve_arguments(self.embedded_args + data.args, data.named_args,
|
|
160
|
+
variables, self.languages)
|
|
155
161
|
|
|
156
162
|
def _config_result(self, result: KeywordResult, data: KeywordData,
|
|
157
163
|
kw: 'LibraryKeyword', assignment):
|
|
@@ -177,12 +183,12 @@ class RunKeywordRunner(LibraryKeywordRunner):
|
|
|
177
183
|
finally:
|
|
178
184
|
STOP_SIGNAL_MONITOR.stop_running_keyword()
|
|
179
185
|
|
|
180
|
-
def
|
|
181
|
-
|
|
186
|
+
def _end_dry_run(self, data: KeywordData, kw: 'LibraryKeyword',
|
|
187
|
+
result: KeywordResult, context):
|
|
182
188
|
wrapper = UserKeyword(name=kw.name,
|
|
183
189
|
doc="Wraps keywords executed by '{kw.name}' in dry-run.",
|
|
184
190
|
parent=kw.parent)
|
|
185
|
-
wrapper.body = [k for k in self._get_dry_run_keywords(kw, args)
|
|
191
|
+
wrapper.body = [k for k in self._get_dry_run_keywords(kw, data.args)
|
|
186
192
|
if not contains_variable(k.name)]
|
|
187
193
|
BodyRunner(context).run(wrapper, result)
|
|
188
194
|
|
|
@@ -36,14 +36,14 @@ __ http://robotframework.org/robotframework/latest/RobotFrameworkUserGuide.html#
|
|
|
36
36
|
|
|
37
37
|
import warnings
|
|
38
38
|
from pathlib import Path
|
|
39
|
-
from typing import Literal, Mapping, Sequence, TYPE_CHECKING, TypeVar, Union
|
|
39
|
+
from typing import Any, Literal, Mapping, Sequence, TYPE_CHECKING, TypeVar, Union
|
|
40
40
|
|
|
41
41
|
from robot import model
|
|
42
42
|
from robot.conf import RobotSettings
|
|
43
43
|
from robot.errors import BreakLoop, ContinueLoop, DataError, ReturnFromKeyword, VariableError
|
|
44
44
|
from robot.model import BodyItem, DataDict, TestSuites
|
|
45
45
|
from robot.output import LOGGER, Output, pyloggingconf
|
|
46
|
-
from robot.utils import setter
|
|
46
|
+
from robot.utils import format_assign_message, setter
|
|
47
47
|
from robot.variables import VariableResolver
|
|
48
48
|
|
|
49
49
|
from .bodyrunner import ForRunner, IfRunner, KeywordRunner, TryRunner, WhileRunner
|
|
@@ -80,6 +80,35 @@ class WithSource:
|
|
|
80
80
|
return self.parent.source if self.parent is not None else None
|
|
81
81
|
|
|
82
82
|
|
|
83
|
+
class Argument:
|
|
84
|
+
"""A temporary API for creating named arguments with non-string values.
|
|
85
|
+
|
|
86
|
+
This class was added in RF 7.0.1 (#5031) after a failed attempt to add a public
|
|
87
|
+
API for this purpose in RF 7.0 (#5000). A better public API that allows passing
|
|
88
|
+
named arguments separately was added in RF 7.1 (#5143).
|
|
89
|
+
|
|
90
|
+
If you need to support also RF 7.0, you can pass named arguments as two-item tuples
|
|
91
|
+
like `(name, value)` and positional arguments as one-item tuples like `(value,)`.
|
|
92
|
+
That approach does not work anymore in RF 7.0.1, though, so the code needs to be
|
|
93
|
+
conditional depending on Robot Framework version.
|
|
94
|
+
|
|
95
|
+
The main limitation of this class is that it is not compatible with the JSON model.
|
|
96
|
+
The current plan is to remove this in the future, possibly already in RF 8.0, but
|
|
97
|
+
we can consider preserving it if it turns out to be useful.
|
|
98
|
+
"""
|
|
99
|
+
|
|
100
|
+
def __init__(self, name: 'str|None', value: Any):
|
|
101
|
+
"""
|
|
102
|
+
:param name: Argument name. If ``None``, argument is considered positional.
|
|
103
|
+
:param value: Argument value.
|
|
104
|
+
"""
|
|
105
|
+
self.name = name
|
|
106
|
+
self.value = value
|
|
107
|
+
|
|
108
|
+
def __str__(self):
|
|
109
|
+
return str(self.value) if self.name is None else f'{self.name}={self.value}'
|
|
110
|
+
|
|
111
|
+
|
|
83
112
|
@Body.register
|
|
84
113
|
class Keyword(model.Keyword, WithSource):
|
|
85
114
|
"""Represents an executable keyword call.
|
|
@@ -93,24 +122,33 @@ class Keyword(model.Keyword, WithSource):
|
|
|
93
122
|
The actual keyword that is executed depends on the context where this model
|
|
94
123
|
is executed.
|
|
95
124
|
|
|
96
|
-
Arguments originating from normal Robot Framework data are stored
|
|
97
|
-
strings in the exact same format as in
|
|
98
|
-
have variables and escape characters,
|
|
99
|
-
using the ``name=value`` syntax.
|
|
125
|
+
Arguments originating from normal Robot Framework data are stored in the
|
|
126
|
+
:attr:`args` attribute as a tuple of strings in the exact same format as in
|
|
127
|
+
the data. This means that arguments can have variables and escape characters,
|
|
128
|
+
and that named arguments are specified using the ``name=value`` syntax.
|
|
129
|
+
|
|
130
|
+
When creating keywords programmatically, it is possible to set :attr:`named_args`
|
|
131
|
+
separately and use :attr:`args` only for positional arguments. Argument values
|
|
132
|
+
do not need to be strings, but also in this case strings can contain variables
|
|
133
|
+
and normal Robot Framework escaping rules must be taken into account.
|
|
100
134
|
"""
|
|
101
|
-
__slots__ = ['lineno']
|
|
135
|
+
__slots__ = ['named_args', 'lineno']
|
|
102
136
|
|
|
103
137
|
def __init__(self, name: str = '',
|
|
104
|
-
args: Sequence[str] = (),
|
|
138
|
+
args: 'Sequence[str|Argument|Any]' = (),
|
|
139
|
+
named_args: 'Mapping[str, Any]|None' = None,
|
|
105
140
|
assign: Sequence[str] = (),
|
|
106
141
|
type: str = BodyItem.KEYWORD,
|
|
107
142
|
parent: BodyItemParent = None,
|
|
108
143
|
lineno: 'int|None' = None):
|
|
109
144
|
super().__init__(name, args, assign, type, parent)
|
|
145
|
+
self.named_args = named_args
|
|
110
146
|
self.lineno = lineno
|
|
111
147
|
|
|
112
148
|
def to_dict(self) -> DataDict:
|
|
113
149
|
data = super().to_dict()
|
|
150
|
+
if self.named_args is not None:
|
|
151
|
+
data['named_args'] = self.named_args
|
|
114
152
|
if self.lineno:
|
|
115
153
|
data['lineno'] = self.lineno
|
|
116
154
|
return data
|
|
@@ -336,35 +374,39 @@ class Var(model.Var, WithSource):
|
|
|
336
374
|
def run(self, result, context, run=True, templated=False):
|
|
337
375
|
result = result.body.create_var(self.name, self.value, self.scope, self.separator)
|
|
338
376
|
with StatusReporter(self, result, context, run):
|
|
339
|
-
if run:
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
377
|
+
if self.error and run:
|
|
378
|
+
raise DataError(self.error, syntax=True)
|
|
379
|
+
if not run or context.dry_run:
|
|
380
|
+
return
|
|
381
|
+
scope, config = self._get_scope(context.variables)
|
|
382
|
+
set_variable = getattr(context.variables, f'set_{scope}')
|
|
383
|
+
try:
|
|
384
|
+
name, value = self._resolve_name_and_value(context.variables)
|
|
385
|
+
set_variable(name, value, **config)
|
|
386
|
+
context.info(format_assign_message(name, value))
|
|
387
|
+
except DataError as err:
|
|
388
|
+
raise VariableError(f"Setting variable '{self.name}' failed: {err}")
|
|
351
389
|
|
|
352
390
|
def _get_scope(self, variables):
|
|
353
391
|
if not self.scope:
|
|
354
|
-
return 'local'
|
|
392
|
+
return 'local', {}
|
|
355
393
|
try:
|
|
356
394
|
scope = variables.replace_string(self.scope)
|
|
357
395
|
if scope.upper() == 'TASK':
|
|
358
|
-
return 'test'
|
|
359
|
-
if scope.upper()
|
|
360
|
-
return
|
|
396
|
+
return 'test', {}
|
|
397
|
+
if scope.upper() == 'SUITES':
|
|
398
|
+
return 'suite', {'children': True}
|
|
399
|
+
if scope.upper() in ('LOCAL', 'TEST', 'SUITE', 'GLOBAL'):
|
|
400
|
+
return scope.lower(), {}
|
|
361
401
|
raise DataError(f"Value '{scope}' is not accepted. Valid values are "
|
|
362
|
-
f"'
|
|
402
|
+
f"'LOCAL', 'TEST', 'TASK', 'SUITE', 'SUITES' and 'GLOBAL'.")
|
|
363
403
|
except DataError as err:
|
|
364
404
|
raise DataError(f"Invalid VAR scope: {err}")
|
|
365
405
|
|
|
366
|
-
def
|
|
367
|
-
|
|
406
|
+
def _resolve_name_and_value(self, variables):
|
|
407
|
+
name = self.name[:2] + variables.replace_string(self.name[2:-1]) + '}'
|
|
408
|
+
value = VariableResolver.from_variable(self).resolve(variables)
|
|
409
|
+
return name, value
|
|
368
410
|
|
|
369
411
|
def to_dict(self) -> DataDict:
|
|
370
412
|
data = super().to_dict()
|
|
@@ -87,9 +87,7 @@ class Namespace:
|
|
|
87
87
|
self.variables.set_from_variable_section(resource.variables, overwrite)
|
|
88
88
|
self._kw_store.resources[path] = resource
|
|
89
89
|
self._handle_imports(resource.imports)
|
|
90
|
-
LOGGER.
|
|
91
|
-
importer=str(import_setting.source),
|
|
92
|
-
source=path)
|
|
90
|
+
LOGGER.resource_import(resource, import_setting)
|
|
93
91
|
else:
|
|
94
92
|
LOGGER.info(f"Resource file '{path}' already imported by "
|
|
95
93
|
f"suite '{self._suite_name}'.")
|
|
@@ -109,10 +107,10 @@ class Namespace:
|
|
|
109
107
|
if overwrite or (path, args) not in self._imported_variable_files:
|
|
110
108
|
self._imported_variable_files.add((path, args))
|
|
111
109
|
self.variables.set_from_file(path, args, overwrite)
|
|
112
|
-
LOGGER.
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
110
|
+
LOGGER.variables_import({'name': os.path.basename(path),
|
|
111
|
+
'args': args,
|
|
112
|
+
'source': path},
|
|
113
|
+
importer=import_setting)
|
|
116
114
|
else:
|
|
117
115
|
msg = f"Variable file '{path}'"
|
|
118
116
|
if args:
|
|
@@ -131,11 +129,7 @@ class Namespace:
|
|
|
131
129
|
f"'{self._suite_name}'.")
|
|
132
130
|
return
|
|
133
131
|
if notify:
|
|
134
|
-
LOGGER.
|
|
135
|
-
args=list(import_setting.args),
|
|
136
|
-
originalname=lib.real_name,
|
|
137
|
-
importer=str(import_setting.source),
|
|
138
|
-
source=str(lib.source or ''))
|
|
132
|
+
LOGGER.library_import(lib, import_setting)
|
|
139
133
|
self._kw_store.libraries[lib.name] = lib
|
|
140
134
|
lib.scope_manager.start_suite()
|
|
141
135
|
if self._running_test:
|
|
@@ -287,30 +281,30 @@ class KeywordStore:
|
|
|
287
281
|
else:
|
|
288
282
|
raise KeywordError(message)
|
|
289
283
|
|
|
290
|
-
def _get_runner(self, name):
|
|
284
|
+
def _get_runner(self, name, strip_bdd_prefix=True):
|
|
291
285
|
if not name:
|
|
292
286
|
raise DataError('Keyword name cannot be empty.')
|
|
293
287
|
if not is_string(name):
|
|
294
288
|
raise DataError('Keyword name must be a string.')
|
|
295
|
-
runner =
|
|
289
|
+
runner = None
|
|
290
|
+
if strip_bdd_prefix:
|
|
291
|
+
runner = self._get_bdd_style_runner(name)
|
|
292
|
+
if not runner:
|
|
293
|
+
runner = self._get_runner_from_suite_file(name)
|
|
296
294
|
if not runner and '.' in name:
|
|
297
295
|
runner = self._get_explicit_runner(name)
|
|
298
296
|
if not runner:
|
|
299
297
|
runner = self._get_implicit_runner(name)
|
|
300
|
-
if not runner:
|
|
301
|
-
runner = self._get_bdd_style_runner(name, self.languages.bdd_prefixes)
|
|
302
298
|
return runner
|
|
303
299
|
|
|
304
|
-
def _get_bdd_style_runner(self, name
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
if
|
|
309
|
-
runner =
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
runner.name = name
|
|
313
|
-
return runner
|
|
300
|
+
def _get_bdd_style_runner(self, name):
|
|
301
|
+
match = self.languages.bdd_prefix_regexp.match(name)
|
|
302
|
+
if match:
|
|
303
|
+
runner = self._get_runner(name[match.end():], strip_bdd_prefix=False)
|
|
304
|
+
if runner:
|
|
305
|
+
runner = copy.copy(runner)
|
|
306
|
+
runner.name = name
|
|
307
|
+
return runner
|
|
314
308
|
return None
|
|
315
309
|
|
|
316
310
|
def _get_implicit_runner(self, name):
|
|
@@ -28,10 +28,13 @@ from .model import Body, BodyItemParent, Keyword, TestSuite
|
|
|
28
28
|
from .userkeywordrunner import UserKeywordRunner, EmbeddedArgumentsRunner
|
|
29
29
|
|
|
30
30
|
if TYPE_CHECKING:
|
|
31
|
+
from robot.conf import LanguagesLike
|
|
31
32
|
from robot.parsing import File
|
|
32
33
|
|
|
33
34
|
|
|
34
35
|
class ResourceFile(ModelObject):
|
|
36
|
+
"""Represents a resource file."""
|
|
37
|
+
|
|
35
38
|
repr_args = ('source',)
|
|
36
39
|
__slots__ = ('_source', 'owner', 'doc', 'keyword_finder')
|
|
37
40
|
|
|
@@ -234,7 +237,8 @@ class UserKeyword(KeywordImplementation):
|
|
|
234
237
|
"""
|
|
235
238
|
return bool(self._teardown)
|
|
236
239
|
|
|
237
|
-
def create_runner(self, name: 'str|None',
|
|
240
|
+
def create_runner(self, name: 'str|None',
|
|
241
|
+
languages: 'LanguagesLike' = None) \
|
|
238
242
|
-> 'UserKeywordRunner|EmbeddedArgumentsRunner':
|
|
239
243
|
if self.embedded:
|
|
240
244
|
return EmbeddedArgumentsRunner(self, name)
|
|
@@ -317,8 +321,12 @@ class Variable(ModelObject):
|
|
|
317
321
|
data['error'] = self.error
|
|
318
322
|
return data
|
|
319
323
|
|
|
324
|
+
def _include_in_repr(self, name: str, value: Any) -> bool:
|
|
325
|
+
return not (name == 'separator' and value is None)
|
|
326
|
+
|
|
320
327
|
|
|
321
328
|
class Import(ModelObject):
|
|
329
|
+
"""Represents library, resource file or variable file import."""
|
|
322
330
|
repr_args = ('type', 'name', 'args', 'alias')
|
|
323
331
|
LIBRARY = 'LIBRARY'
|
|
324
332
|
RESOURCE = 'RESOURCE'
|
|
@@ -52,10 +52,10 @@ class StatusReporter:
|
|
|
52
52
|
message = ' ' + doc.split('*', 2)[-1].strip()
|
|
53
53
|
self.context.warn(f"Keyword '{name}' is deprecated.{message}")
|
|
54
54
|
|
|
55
|
-
def __exit__(self, exc_type,
|
|
55
|
+
def __exit__(self, exc_type, exc_value, exc_traceback):
|
|
56
56
|
context = self.context
|
|
57
57
|
result = self.result
|
|
58
|
-
failure = self._get_failure(
|
|
58
|
+
failure = self._get_failure(exc_value, context)
|
|
59
59
|
if failure is None:
|
|
60
60
|
result.status = self.pass_status
|
|
61
61
|
else:
|
|
@@ -65,12 +65,17 @@ class StatusReporter:
|
|
|
65
65
|
if self.initial_test_status == 'PASS':
|
|
66
66
|
context.test.status = result.status
|
|
67
67
|
result.elapsed_time = datetime.now() - result.start_time
|
|
68
|
+
orig_status = (result.status, result.message)
|
|
68
69
|
context.end_body_item(self.data, result, self.implementation)
|
|
69
|
-
if
|
|
70
|
+
if orig_status != (result.status, result.message):
|
|
71
|
+
if result.passed or result.not_run:
|
|
72
|
+
return True
|
|
73
|
+
raise ExecutionFailed(result.message, skip=result.skipped)
|
|
74
|
+
if failure is not exc_value and not self.suppress:
|
|
70
75
|
raise failure
|
|
71
76
|
return self.suppress
|
|
72
77
|
|
|
73
|
-
def _get_failure(self,
|
|
78
|
+
def _get_failure(self, exc_value, context):
|
|
74
79
|
if exc_value is None:
|
|
75
80
|
return None
|
|
76
81
|
if isinstance(exc_value, ExecutionStatus):
|
|
@@ -171,7 +171,7 @@ class TestLibrary:
|
|
|
171
171
|
if inspect.ismodule(code):
|
|
172
172
|
lib = cls.from_module(code, name, real_name, source, create_keywords, logger)
|
|
173
173
|
if args: # Resolving arguments reports an error.
|
|
174
|
-
lib.init.resolve_arguments(args, variables)
|
|
174
|
+
lib.init.resolve_arguments(args, variables=variables)
|
|
175
175
|
return lib
|
|
176
176
|
return cls.from_class(code, name, real_name, source, args or (), variables,
|
|
177
177
|
create_keywords, logger)
|
|
@@ -316,7 +316,7 @@ class ClassLibrary(TestLibrary):
|
|
|
316
316
|
logger=LOGGER) -> 'ClassLibrary':
|
|
317
317
|
init = LibraryInit.from_class(klass)
|
|
318
318
|
library = cls(klass, init, name, real_name, source, logger)
|
|
319
|
-
positional, named = init.args.resolve(args, variables)
|
|
319
|
+
positional, named = init.args.resolve(args, variables=variables)
|
|
320
320
|
init.positional, init.named = list(positional), dict(named)
|
|
321
321
|
if create_keywords:
|
|
322
322
|
library.create_keywords()
|
|
@@ -55,13 +55,16 @@ class UserKeywordRunner:
|
|
|
55
55
|
|
|
56
56
|
def _config_result(self, result: KeywordResult, data: KeywordData,
|
|
57
57
|
kw: 'UserKeyword', assignment, variables):
|
|
58
|
+
args = tuple(data.args)
|
|
59
|
+
if data.named_args:
|
|
60
|
+
args += tuple(f'{n}={v}' for n, v in data.named_args.items())
|
|
58
61
|
doc = variables.replace_string(kw.doc, ignore_errors=True)
|
|
59
62
|
doc, tags = split_tags_from_doc(doc)
|
|
60
63
|
tags = variables.replace_list(kw.tags, ignore_errors=True) + tags
|
|
61
64
|
result.config(name=self.name,
|
|
62
65
|
owner=kw.owner.name,
|
|
63
66
|
doc=getshortdoc(doc),
|
|
64
|
-
args=
|
|
67
|
+
args=args,
|
|
65
68
|
assign=tuple(assignment),
|
|
66
69
|
tags=tags,
|
|
67
70
|
type=data.type)
|
|
@@ -71,7 +74,7 @@ class UserKeywordRunner:
|
|
|
71
74
|
for message in self.pre_run_messages:
|
|
72
75
|
context.output.message(message)
|
|
73
76
|
variables = context.variables
|
|
74
|
-
positional, named = self._resolve_arguments(
|
|
77
|
+
positional, named = self._resolve_arguments(data, kw, variables)
|
|
75
78
|
with context.user_keyword(kw):
|
|
76
79
|
self._set_arguments(kw, positional, named, context)
|
|
77
80
|
if kw.timeout:
|
|
@@ -89,8 +92,8 @@ class UserKeywordRunner:
|
|
|
89
92
|
raise exception
|
|
90
93
|
return return_value
|
|
91
94
|
|
|
92
|
-
def _resolve_arguments(self, kw: 'UserKeyword',
|
|
93
|
-
return kw.resolve_arguments(args, variables)
|
|
95
|
+
def _resolve_arguments(self, data: KeywordData, kw: 'UserKeyword', variables=None):
|
|
96
|
+
return kw.resolve_arguments(data.args, data.named_args, variables)
|
|
94
97
|
|
|
95
98
|
def _set_arguments(self, kw: 'UserKeyword', positional, named, context):
|
|
96
99
|
variables = context.variables
|
|
@@ -222,7 +225,7 @@ class UserKeywordRunner:
|
|
|
222
225
|
if self.pre_run_messages:
|
|
223
226
|
for message in self.pre_run_messages:
|
|
224
227
|
context.output.message(message)
|
|
225
|
-
self._resolve_arguments(
|
|
228
|
+
self._resolve_arguments(data, kw)
|
|
226
229
|
with context.user_keyword(kw):
|
|
227
230
|
if kw.timeout:
|
|
228
231
|
timeout = KeywordTimeout(kw.timeout, context.variables)
|
|
@@ -238,8 +241,8 @@ class EmbeddedArgumentsRunner(UserKeywordRunner):
|
|
|
238
241
|
super().__init__(keyword, name)
|
|
239
242
|
self.embedded_args = keyword.embedded.match(name).groups()
|
|
240
243
|
|
|
241
|
-
def _resolve_arguments(self, kw: 'UserKeyword',
|
|
242
|
-
result = super()._resolve_arguments(
|
|
244
|
+
def _resolve_arguments(self, data: KeywordData, kw: 'UserKeyword', variables=None):
|
|
245
|
+
result = super()._resolve_arguments(data, kw, variables)
|
|
243
246
|
if variables:
|
|
244
247
|
embedded = [variables.replace_scalar(e) for e in self.embedded_args]
|
|
245
248
|
self.embedded_args = kw.embedded.map(embedded)
|
|
@@ -18,7 +18,7 @@ import sys
|
|
|
18
18
|
import locale
|
|
19
19
|
|
|
20
20
|
from .misc import isatty
|
|
21
|
-
from .platform import UNIXY, WINDOWS
|
|
21
|
+
from .platform import PY_VERSION, UNIXY, WINDOWS
|
|
22
22
|
|
|
23
23
|
|
|
24
24
|
if UNIXY:
|
|
@@ -53,6 +53,8 @@ def _get_encoding(platform_getters, default):
|
|
|
53
53
|
|
|
54
54
|
|
|
55
55
|
def _get_python_system_encoding():
|
|
56
|
+
if PY_VERSION >= (3, 11):
|
|
57
|
+
return locale.getencoding()
|
|
56
58
|
# ValueError occurs with PyPy 3.10 if language config is invalid.
|
|
57
59
|
# https://foss.heptapod.net/pypy/pypy/-/issues/3975
|
|
58
60
|
try:
|
|
@@ -86,7 +86,7 @@ def _time_string_to_secs(timestr):
|
|
|
86
86
|
timestr = _normalize_timestr(timestr)
|
|
87
87
|
if not timestr:
|
|
88
88
|
return None
|
|
89
|
-
nanos = micros = millis = secs = mins = hours = days = 0
|
|
89
|
+
nanos = micros = millis = secs = mins = hours = days = weeks = 0
|
|
90
90
|
if timestr[0] == '-':
|
|
91
91
|
sign = -1
|
|
92
92
|
timestr = timestr[1:]
|
|
@@ -102,13 +102,14 @@ def _time_string_to_secs(timestr):
|
|
|
102
102
|
elif c == 'm': mins = float(''.join(temp)); temp = []
|
|
103
103
|
elif c == 'h': hours = float(''.join(temp)); temp = []
|
|
104
104
|
elif c == 'd': days = float(''.join(temp)); temp = []
|
|
105
|
+
elif c == 'w': weeks = float(''.join(temp)); temp = []
|
|
105
106
|
else: temp.append(c)
|
|
106
107
|
except ValueError:
|
|
107
108
|
return None
|
|
108
109
|
if temp:
|
|
109
110
|
return None
|
|
110
111
|
return sign * (nanos/1E9 + micros/1E6 + millis/1000 + secs +
|
|
111
|
-
mins*60 + hours*60*60 + days*60*60*24)
|
|
112
|
+
mins*60 + hours*60*60 + days*60*60*24 + weeks*60*60*24*7)
|
|
112
113
|
|
|
113
114
|
|
|
114
115
|
def _normalize_timestr(timestr):
|
|
@@ -120,7 +121,8 @@ def _normalize_timestr(timestr):
|
|
|
120
121
|
('s', ['second', 'sec']),
|
|
121
122
|
('m', ['minute', 'min']),
|
|
122
123
|
('h', ['hour']),
|
|
123
|
-
('d', ['day'])
|
|
124
|
+
('d', ['day']),
|
|
125
|
+
('w', ['week'])]:
|
|
124
126
|
plural_aliases = [a+'s' for a in aliases if not a.endswith('s')]
|
|
125
127
|
for alias in plural_aliases + aliases:
|
|
126
128
|
if alias in timestr:
|
|
@@ -27,9 +27,6 @@ from .search import VariableMatches
|
|
|
27
27
|
from .notfound import variable_not_found
|
|
28
28
|
|
|
29
29
|
|
|
30
|
-
PYTHON_BUILTINS = set(builtins.__dict__)
|
|
31
|
-
|
|
32
|
-
|
|
33
30
|
def evaluate_expression(expression, variables, modules=None, namespace=None,
|
|
34
31
|
resolve_variables=False):
|
|
35
32
|
original = expression
|
|
@@ -146,7 +143,7 @@ class EvaluationNamespace(MutableMapping):
|
|
|
146
143
|
self.namespace.pop(key)
|
|
147
144
|
|
|
148
145
|
def _import_module(self, name):
|
|
149
|
-
if name
|
|
146
|
+
if hasattr(builtins, name):
|
|
150
147
|
raise KeyError
|
|
151
148
|
try:
|
|
152
149
|
return __import__(name)
|
|
@@ -192,7 +192,8 @@ class GlobalVariables(Variables):
|
|
|
192
192
|
'include': Tags(settings.include),
|
|
193
193
|
'exclude': Tags(settings.exclude),
|
|
194
194
|
'skip': Tags(settings.skip),
|
|
195
|
-
'skip_on_failure': Tags(settings.skip_on_failure)
|
|
195
|
+
'skip_on_failure': Tags(settings.skip_on_failure),
|
|
196
|
+
'console_width': settings.console_width
|
|
196
197
|
})),
|
|
197
198
|
('${/}', os.sep),
|
|
198
199
|
('${:}', os.pathsep),
|
|
@@ -13,8 +13,7 @@
|
|
|
13
13
|
# See the License for the specific language governing permissions and
|
|
14
14
|
# limitations under the License.
|
|
15
15
|
|
|
16
|
-
from
|
|
17
|
-
from typing import Sequence, TYPE_CHECKING
|
|
16
|
+
from typing import Any, Sequence, TYPE_CHECKING
|
|
18
17
|
|
|
19
18
|
from robot.errors import DataError
|
|
20
19
|
from robot.utils import DotDict, split_from_equals
|
|
@@ -23,7 +22,7 @@ from .resolvable import Resolvable
|
|
|
23
22
|
from .search import is_assign, is_list_variable, is_dict_variable
|
|
24
23
|
|
|
25
24
|
if TYPE_CHECKING:
|
|
26
|
-
from robot.running
|
|
25
|
+
from robot.running import Var, Variable
|
|
27
26
|
from .store import VariableStore
|
|
28
27
|
|
|
29
28
|
|
|
@@ -35,8 +34,8 @@ class VariableTableSetter:
|
|
|
35
34
|
def set(self, variables: 'Sequence[Variable]', overwrite: bool = False):
|
|
36
35
|
for var in variables:
|
|
37
36
|
try:
|
|
38
|
-
|
|
39
|
-
self.store.add(var.name,
|
|
37
|
+
resolver = VariableResolver.from_variable(var)
|
|
38
|
+
self.store.add(var.name, resolver, overwrite)
|
|
40
39
|
except DataError as err:
|
|
41
40
|
var.report_error(str(err))
|
|
42
41
|
|
|
@@ -46,7 +45,8 @@ class VariableResolver(Resolvable):
|
|
|
46
45
|
def __init__(self, value: Sequence[str], error_reporter=None):
|
|
47
46
|
self.value = tuple(value)
|
|
48
47
|
self.error_reporter = error_reporter
|
|
49
|
-
self.
|
|
48
|
+
self.resolving = False
|
|
49
|
+
self.resolved = False
|
|
50
50
|
|
|
51
51
|
@classmethod
|
|
52
52
|
def from_name_and_value(cls, name: str, value: 'str|Sequence[str]',
|
|
@@ -69,22 +69,19 @@ class VariableResolver(Resolvable):
|
|
|
69
69
|
return cls.from_name_and_value(var.name, var.value, var.separator,
|
|
70
70
|
getattr(var, 'report_error', None))
|
|
71
71
|
|
|
72
|
-
def resolve(self, variables):
|
|
73
|
-
|
|
74
|
-
return self._replace_variables(variables)
|
|
75
|
-
|
|
76
|
-
@property
|
|
77
|
-
@contextmanager
|
|
78
|
-
def _avoid_recursion(self):
|
|
79
|
-
if self._resolving:
|
|
72
|
+
def resolve(self, variables) -> Any:
|
|
73
|
+
if self.resolving:
|
|
80
74
|
raise DataError('Recursive variable definition.')
|
|
81
|
-
self.
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
75
|
+
if not self.resolved:
|
|
76
|
+
self.resolving = True
|
|
77
|
+
try:
|
|
78
|
+
self.value = self._replace_variables(variables)
|
|
79
|
+
finally:
|
|
80
|
+
self.resolving = False
|
|
81
|
+
self.resolved = True
|
|
82
|
+
return self.value
|
|
86
83
|
|
|
87
|
-
def _replace_variables(self, variables):
|
|
84
|
+
def _replace_variables(self, variables) -> Any:
|
|
88
85
|
raise NotImplementedError
|
|
89
86
|
|
|
90
87
|
def report_error(self, error):
|