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,12 +13,11 @@
|
|
|
13
13
|
# See the License for the specific language governing permissions and
|
|
14
14
|
# limitations under the License.
|
|
15
15
|
|
|
16
|
-
import sys
|
|
17
16
|
import inspect
|
|
18
17
|
import asyncio
|
|
19
18
|
from contextlib import contextmanager
|
|
20
19
|
|
|
21
|
-
from robot.errors import DataError
|
|
20
|
+
from robot.errors import DataError, ExecutionFailed
|
|
22
21
|
|
|
23
22
|
|
|
24
23
|
class Asynchronous:
|
|
@@ -37,15 +36,20 @@ class Asynchronous:
|
|
|
37
36
|
self._loop_ref.close()
|
|
38
37
|
|
|
39
38
|
def run_until_complete(self, coroutine):
|
|
40
|
-
|
|
39
|
+
task = self.event_loop.create_task(coroutine)
|
|
40
|
+
try:
|
|
41
|
+
return self.event_loop.run_until_complete(task)
|
|
42
|
+
except ExecutionFailed as e:
|
|
43
|
+
if e.dont_continue:
|
|
44
|
+
task.cancel()
|
|
45
|
+
# wait for task and its children to cancel
|
|
46
|
+
self.event_loop.run_until_complete(asyncio.gather(task, return_exceptions=True))
|
|
47
|
+
raise e
|
|
41
48
|
|
|
42
49
|
def is_loop_required(self, obj):
|
|
43
50
|
return inspect.iscoroutine(obj) and not self._is_loop_running()
|
|
44
51
|
|
|
45
52
|
def _is_loop_running(self):
|
|
46
|
-
# ensure 3.6 compatibility
|
|
47
|
-
if sys.version_info.minor == 6:
|
|
48
|
-
return asyncio._get_running_loop() is not None
|
|
49
53
|
try:
|
|
50
54
|
asyncio.get_running_loop()
|
|
51
55
|
except RuntimeError:
|
|
@@ -108,6 +112,10 @@ class _ExecutionContext:
|
|
|
108
112
|
self.user_keywords = []
|
|
109
113
|
self.asynchronous = asynchronous
|
|
110
114
|
|
|
115
|
+
@property
|
|
116
|
+
def languages(self):
|
|
117
|
+
return self.namespace.languages
|
|
118
|
+
|
|
111
119
|
@contextmanager
|
|
112
120
|
def suite_teardown(self):
|
|
113
121
|
self.in_suite_teardown = True
|
|
@@ -150,7 +158,7 @@ class _ExecutionContext:
|
|
|
150
158
|
def warn_on_invalid_private_call(self, handler):
|
|
151
159
|
parent = self.user_keywords[-1] if self.user_keywords else None
|
|
152
160
|
if not parent or parent.source != handler.source:
|
|
153
|
-
self.warn(f"Keyword '{handler.
|
|
161
|
+
self.warn(f"Keyword '{handler.full_name}' is private and should only "
|
|
154
162
|
f"be called by keywords in the same file.")
|
|
155
163
|
|
|
156
164
|
@contextmanager
|
|
@@ -174,34 +182,37 @@ class _ExecutionContext:
|
|
|
174
182
|
def continue_on_failure(self, default=False):
|
|
175
183
|
parents = ([self.test] if self.test else []) + self.user_keywords
|
|
176
184
|
for index, parent in enumerate(reversed(parents)):
|
|
177
|
-
|
|
178
|
-
|
|
185
|
+
robot = parent.tags.robot
|
|
186
|
+
if index == 0 and robot('stop-on-failure'):
|
|
187
|
+
return False
|
|
188
|
+
if index == 0 and robot('continue-on-failure'):
|
|
189
|
+
return True
|
|
190
|
+
if robot('recursive-stop-on-failure'):
|
|
179
191
|
return False
|
|
180
|
-
if
|
|
181
|
-
or index == 0 and parent.tags.robot('continue-on-failure')):
|
|
192
|
+
if robot('recursive-continue-on-failure'):
|
|
182
193
|
return True
|
|
183
194
|
return default or self.in_teardown
|
|
184
195
|
|
|
185
196
|
@property
|
|
186
197
|
def allow_loop_control(self):
|
|
187
|
-
for step in reversed(self.steps):
|
|
198
|
+
for _, step in reversed(self.steps):
|
|
188
199
|
if step.type == 'ITERATION':
|
|
189
200
|
return True
|
|
190
|
-
if step.type == 'KEYWORD' and step.
|
|
201
|
+
if step.type == 'KEYWORD' and step.owner != 'BuiltIn':
|
|
191
202
|
return False
|
|
192
203
|
return False
|
|
193
204
|
|
|
194
|
-
def end_suite(self,
|
|
205
|
+
def end_suite(self, data, result):
|
|
195
206
|
for name in ['${PREV_TEST_NAME}',
|
|
196
207
|
'${PREV_TEST_STATUS}',
|
|
197
208
|
'${PREV_TEST_MESSAGE}']:
|
|
198
209
|
self.variables.set_global(name, self.variables[name])
|
|
199
|
-
self.output.end_suite(
|
|
200
|
-
self.namespace.end_suite(
|
|
210
|
+
self.output.end_suite(data, result)
|
|
211
|
+
self.namespace.end_suite(data)
|
|
201
212
|
EXECUTION_CONTEXTS.end_suite()
|
|
202
213
|
|
|
203
214
|
def set_suite_variables(self, suite):
|
|
204
|
-
self.variables['${SUITE_NAME}'] = suite.
|
|
215
|
+
self.variables['${SUITE_NAME}'] = suite.full_name
|
|
205
216
|
self.variables['${SUITE_SOURCE}'] = str(suite.source or '')
|
|
206
217
|
self.variables['${SUITE_DOCUMENTATION}'] = suite.doc
|
|
207
218
|
self.variables['${SUITE_METADATA}'] = suite.metadata.copy()
|
|
@@ -210,13 +221,14 @@ class _ExecutionContext:
|
|
|
210
221
|
self.variables['${SUITE_STATUS}'] = status
|
|
211
222
|
self.variables['${SUITE_MESSAGE}'] = message
|
|
212
223
|
|
|
213
|
-
def start_test(self,
|
|
214
|
-
self.test =
|
|
215
|
-
self._add_timeout(
|
|
224
|
+
def start_test(self, data, result):
|
|
225
|
+
self.test = result
|
|
226
|
+
self._add_timeout(result.timeout)
|
|
216
227
|
self.namespace.start_test()
|
|
217
|
-
self.variables.set_test('${TEST_NAME}',
|
|
218
|
-
self.variables.set_test('${TEST_DOCUMENTATION}',
|
|
219
|
-
self.variables.set_test('@{TEST_TAGS}', list(
|
|
228
|
+
self.variables.set_test('${TEST_NAME}', result.name)
|
|
229
|
+
self.variables.set_test('${TEST_DOCUMENTATION}', result.doc)
|
|
230
|
+
self.variables.set_test('@{TEST_TAGS}', list(result.tags))
|
|
231
|
+
self.output.start_test(data, result)
|
|
220
232
|
|
|
221
233
|
def _add_timeout(self, timeout):
|
|
222
234
|
if timeout:
|
|
@@ -236,19 +248,89 @@ class _ExecutionContext:
|
|
|
236
248
|
self.variables.set_suite('${PREV_TEST_MESSAGE}', test.message)
|
|
237
249
|
self.timeout_occurred = False
|
|
238
250
|
|
|
239
|
-
def
|
|
240
|
-
self.steps.append(
|
|
251
|
+
def start_body_item(self, data, result, implementation=None):
|
|
252
|
+
self.steps.append((data, result))
|
|
241
253
|
if len(self.steps) > self._started_keywords_threshold:
|
|
242
254
|
raise DataError('Maximum limit of started keywords and control '
|
|
243
255
|
'structures exceeded.')
|
|
244
|
-
self.output
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
256
|
+
output = self.output
|
|
257
|
+
args = (data, result)
|
|
258
|
+
if implementation:
|
|
259
|
+
if implementation.error:
|
|
260
|
+
method = output.start_invalid_keyword
|
|
261
|
+
elif implementation.type == implementation.LIBRARY_KEYWORD:
|
|
262
|
+
method = output.start_library_keyword
|
|
263
|
+
else:
|
|
264
|
+
method = output.start_user_keyword
|
|
265
|
+
args = (data, implementation, result)
|
|
266
|
+
elif result.type in (result.ELSE, result.ITERATION):
|
|
267
|
+
method = {
|
|
268
|
+
result.IF_ELSE_ROOT: output.start_if_branch,
|
|
269
|
+
result.TRY_EXCEPT_ROOT: output.start_try_branch,
|
|
270
|
+
result.FOR: output.start_for_iteration,
|
|
271
|
+
result.WHILE: output.start_while_iteration,
|
|
272
|
+
}[result.parent.type]
|
|
273
|
+
else:
|
|
274
|
+
method = {
|
|
275
|
+
result.FOR: output.start_for,
|
|
276
|
+
result.WHILE: output.start_while,
|
|
277
|
+
result.IF_ELSE_ROOT: output.start_if,
|
|
278
|
+
result.IF: output.start_if_branch,
|
|
279
|
+
result.ELSE: output.start_if_branch,
|
|
280
|
+
result.ELSE_IF: output.start_if_branch,
|
|
281
|
+
result.TRY_EXCEPT_ROOT: output.start_try,
|
|
282
|
+
result.TRY: output.start_try_branch,
|
|
283
|
+
result.EXCEPT: output.start_try_branch,
|
|
284
|
+
result.FINALLY: output.start_try_branch,
|
|
285
|
+
result.VAR: output.start_var,
|
|
286
|
+
result.BREAK: output.start_break,
|
|
287
|
+
result.CONTINUE: output.start_continue,
|
|
288
|
+
result.RETURN: output.start_return,
|
|
289
|
+
result.ERROR: output.start_error,
|
|
290
|
+
}[result.type]
|
|
291
|
+
method(*args)
|
|
292
|
+
|
|
293
|
+
def end_body_item(self, data, result, implementation=None):
|
|
294
|
+
output = self.output
|
|
295
|
+
args = (data, result)
|
|
296
|
+
if implementation:
|
|
297
|
+
if implementation.error:
|
|
298
|
+
method = output.end_invalid_keyword
|
|
299
|
+
elif implementation.type == implementation.LIBRARY_KEYWORD:
|
|
300
|
+
method = output.end_library_keyword
|
|
301
|
+
else:
|
|
302
|
+
method = output.end_user_keyword
|
|
303
|
+
args = (data, implementation, result)
|
|
304
|
+
elif result.type in (result.ELSE, result.ITERATION):
|
|
305
|
+
method = {
|
|
306
|
+
result.IF_ELSE_ROOT: output.end_if_branch,
|
|
307
|
+
result.TRY_EXCEPT_ROOT: output.end_try_branch,
|
|
308
|
+
result.FOR: output.end_for_iteration,
|
|
309
|
+
result.WHILE: output.end_while_iteration,
|
|
310
|
+
}[result.parent.type]
|
|
311
|
+
else:
|
|
312
|
+
method = {
|
|
313
|
+
result.FOR: output.end_for,
|
|
314
|
+
result.WHILE: output.end_while,
|
|
315
|
+
result.IF_ELSE_ROOT: output.end_if,
|
|
316
|
+
result.IF: output.end_if_branch,
|
|
317
|
+
result.ELSE: output.end_if_branch,
|
|
318
|
+
result.ELSE_IF: output.end_if_branch,
|
|
319
|
+
result.TRY_EXCEPT_ROOT: output.end_try,
|
|
320
|
+
result.TRY: output.end_try_branch,
|
|
321
|
+
result.EXCEPT: output.end_try_branch,
|
|
322
|
+
result.FINALLY: output.end_try_branch,
|
|
323
|
+
result.VAR: output.end_var,
|
|
324
|
+
result.BREAK: output.end_break,
|
|
325
|
+
result.CONTINUE: output.end_continue,
|
|
326
|
+
result.RETURN: output.end_return,
|
|
327
|
+
result.ERROR: output.end_error,
|
|
328
|
+
}[result.type]
|
|
329
|
+
method(*args)
|
|
248
330
|
self.steps.pop()
|
|
249
331
|
|
|
250
|
-
def get_runner(self, name):
|
|
251
|
-
return self.namespace.get_runner(name)
|
|
332
|
+
def get_runner(self, name, recommend_on_failure=True):
|
|
333
|
+
return self.namespace.get_runner(name, recommend_on_failure)
|
|
252
334
|
|
|
253
335
|
def trace(self, message):
|
|
254
336
|
self.output.trace(message)
|
|
@@ -14,24 +14,26 @@
|
|
|
14
14
|
# limitations under the License.
|
|
15
15
|
|
|
16
16
|
from robot.errors import DataError
|
|
17
|
-
from robot.utils import get_error_message,
|
|
17
|
+
from robot.utils import get_error_message, is_list_like, type_name
|
|
18
18
|
|
|
19
19
|
from .arguments import PythonArgumentParser
|
|
20
|
+
from .context import EXECUTION_CONTEXTS
|
|
20
21
|
|
|
21
22
|
|
|
22
23
|
def no_dynamic_method(*args):
|
|
23
24
|
return None
|
|
24
25
|
|
|
25
26
|
|
|
26
|
-
class
|
|
27
|
+
class DynamicMethod:
|
|
27
28
|
_underscore_name = NotImplemented
|
|
28
29
|
|
|
29
|
-
def __init__(self,
|
|
30
|
-
self.
|
|
30
|
+
def __init__(self, instance):
|
|
31
|
+
self.instance = instance
|
|
32
|
+
self.method = self._get_method(instance)
|
|
31
33
|
|
|
32
|
-
def _get_method(self,
|
|
34
|
+
def _get_method(self, instance):
|
|
33
35
|
for name in self._underscore_name, self._camelCaseName:
|
|
34
|
-
method = getattr(
|
|
36
|
+
method = getattr(instance, name, None)
|
|
35
37
|
if callable(method):
|
|
36
38
|
return method
|
|
37
39
|
return no_dynamic_method
|
|
@@ -45,28 +47,31 @@ class _DynamicMethod:
|
|
|
45
47
|
def name(self):
|
|
46
48
|
return self.method.__name__
|
|
47
49
|
|
|
48
|
-
def __call__(self, *args):
|
|
50
|
+
def __call__(self, *args, **kwargs):
|
|
49
51
|
try:
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
52
|
+
ctx = EXECUTION_CONTEXTS.current
|
|
53
|
+
result = self.method(*args, **kwargs)
|
|
54
|
+
if ctx and ctx.asynchronous.is_loop_required(result):
|
|
55
|
+
result = ctx.asynchronous.run_until_complete(result)
|
|
56
|
+
return self._handle_return_value(result)
|
|
57
|
+
except Exception:
|
|
58
|
+
raise DataError(f"Calling dynamic method '{self.name}' failed: "
|
|
59
|
+
f"{get_error_message()}")
|
|
54
60
|
|
|
55
61
|
def _handle_return_value(self, value):
|
|
56
62
|
raise NotImplementedError
|
|
57
63
|
|
|
58
64
|
def _to_string(self, value, allow_tuple=False, allow_none=False):
|
|
59
|
-
if
|
|
65
|
+
if isinstance(value, str):
|
|
60
66
|
return value
|
|
61
|
-
if
|
|
67
|
+
if isinstance(value, bytes):
|
|
62
68
|
return value.decode('UTF-8')
|
|
63
69
|
if allow_tuple and is_list_like(value) and len(value) > 0:
|
|
64
70
|
return tuple(value)
|
|
65
71
|
if allow_none and value is None:
|
|
66
72
|
return value
|
|
67
|
-
|
|
68
|
-
raise DataError('Return value must be
|
|
69
|
-
% (or_tuple, type_name(value)))
|
|
73
|
+
allowed = 'a string or a non-empty tuple' if allow_tuple else 'a string'
|
|
74
|
+
raise DataError(f'Return value must be {allowed}, got {type_name(value)}.')
|
|
70
75
|
|
|
71
76
|
def _to_list(self, value):
|
|
72
77
|
if value is None:
|
|
@@ -80,14 +85,15 @@ class _DynamicMethod:
|
|
|
80
85
|
return [self._to_string(item, allow_tuples)
|
|
81
86
|
for item in self._to_list(value)]
|
|
82
87
|
except DataError:
|
|
83
|
-
|
|
84
|
-
|
|
88
|
+
allowed = 'strings or non-empty tuples' if allow_tuples else 'strings'
|
|
89
|
+
raise DataError(f'Return value must be a list of {allowed}, '
|
|
90
|
+
f'got {type_name(value)}.')
|
|
85
91
|
|
|
86
92
|
def __bool__(self):
|
|
87
93
|
return self.method is not no_dynamic_method
|
|
88
94
|
|
|
89
95
|
|
|
90
|
-
class GetKeywordNames(
|
|
96
|
+
class GetKeywordNames(DynamicMethod):
|
|
91
97
|
_underscore_name = 'get_keyword_names'
|
|
92
98
|
|
|
93
99
|
def _handle_return_value(self, value):
|
|
@@ -102,52 +108,74 @@ class GetKeywordNames(_DynamicMethod):
|
|
|
102
108
|
yield name
|
|
103
109
|
|
|
104
110
|
|
|
105
|
-
class RunKeyword(
|
|
111
|
+
class RunKeyword(DynamicMethod):
|
|
106
112
|
_underscore_name = 'run_keyword'
|
|
107
113
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
114
|
+
def __init__(self, instance, keyword_name: 'str|None' = None,
|
|
115
|
+
supports_named_args: 'bool|None' = None):
|
|
116
|
+
super().__init__(instance)
|
|
117
|
+
self.keyword_name = keyword_name
|
|
118
|
+
self._supports_named_args = supports_named_args
|
|
113
119
|
|
|
114
|
-
|
|
120
|
+
@property
|
|
121
|
+
def supports_named_args(self) -> bool:
|
|
122
|
+
if self._supports_named_args is None:
|
|
123
|
+
spec = PythonArgumentParser().parse(self.method)
|
|
124
|
+
self._supports_named_args = len(spec.positional) == 3
|
|
125
|
+
return self._supports_named_args
|
|
126
|
+
|
|
127
|
+
def __call__(self, *positional, **named):
|
|
128
|
+
if self.supports_named_args:
|
|
129
|
+
args = (self.keyword_name, positional, named)
|
|
130
|
+
elif named:
|
|
131
|
+
# This should never happen.
|
|
132
|
+
raise ValueError(f"'named' should not be used when named-argument "
|
|
133
|
+
f"support is not enabled, got {named}.")
|
|
134
|
+
else:
|
|
135
|
+
args = (self.keyword_name, positional)
|
|
136
|
+
return self.method(*args)
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
class GetKeywordDocumentation(DynamicMethod):
|
|
115
140
|
_underscore_name = 'get_keyword_documentation'
|
|
116
141
|
|
|
117
142
|
def _handle_return_value(self, value):
|
|
118
143
|
return self._to_string(value or '')
|
|
119
144
|
|
|
120
145
|
|
|
121
|
-
class GetKeywordArguments(
|
|
146
|
+
class GetKeywordArguments(DynamicMethod):
|
|
122
147
|
_underscore_name = 'get_keyword_arguments'
|
|
123
148
|
|
|
124
|
-
def __init__(self,
|
|
125
|
-
|
|
126
|
-
|
|
149
|
+
def __init__(self, instance, supports_named_args: 'bool|None' = None):
|
|
150
|
+
super().__init__(instance)
|
|
151
|
+
if supports_named_args is None:
|
|
152
|
+
self.supports_named_args = RunKeyword(instance).supports_named_args
|
|
153
|
+
else:
|
|
154
|
+
self.supports_named_args = supports_named_args
|
|
127
155
|
|
|
128
156
|
def _handle_return_value(self, value):
|
|
129
157
|
if value is None:
|
|
130
|
-
if self.
|
|
158
|
+
if self.supports_named_args:
|
|
131
159
|
return ['*varargs', '**kwargs']
|
|
132
160
|
return ['*varargs']
|
|
133
161
|
return self._to_list_of_strings(value, allow_tuples=True)
|
|
134
162
|
|
|
135
163
|
|
|
136
|
-
class GetKeywordTypes(
|
|
164
|
+
class GetKeywordTypes(DynamicMethod):
|
|
137
165
|
_underscore_name = 'get_keyword_types'
|
|
138
166
|
|
|
139
167
|
def _handle_return_value(self, value):
|
|
140
168
|
return value if self else {}
|
|
141
169
|
|
|
142
170
|
|
|
143
|
-
class GetKeywordTags(
|
|
171
|
+
class GetKeywordTags(DynamicMethod):
|
|
144
172
|
_underscore_name = 'get_keyword_tags'
|
|
145
173
|
|
|
146
174
|
def _handle_return_value(self, value):
|
|
147
175
|
return self._to_list_of_strings(value)
|
|
148
176
|
|
|
149
177
|
|
|
150
|
-
class GetKeywordSource(
|
|
178
|
+
class GetKeywordSource(DynamicMethod):
|
|
151
179
|
_underscore_name = 'get_keyword_source'
|
|
152
180
|
|
|
153
181
|
def _handle_return_value(self, value):
|
|
@@ -13,16 +13,13 @@
|
|
|
13
13
|
# See the License for the specific language governing permissions and
|
|
14
14
|
# limitations under the License.
|
|
15
15
|
|
|
16
|
-
import copy
|
|
17
|
-
import os.path
|
|
18
16
|
import os
|
|
19
17
|
|
|
20
18
|
from robot.output import LOGGER
|
|
21
19
|
from robot.errors import FrameworkError, DataError
|
|
22
|
-
from robot.utils import normpath, seq2str, seq2str2
|
|
20
|
+
from robot.utils import normpath, seq2str, seq2str2
|
|
23
21
|
|
|
24
22
|
from .builder import ResourceFileBuilder
|
|
25
|
-
from .handlerstore import HandlerStore
|
|
26
23
|
from .testlibraries import TestLibrary
|
|
27
24
|
|
|
28
25
|
|
|
@@ -41,15 +38,27 @@ class Importer:
|
|
|
41
38
|
|
|
42
39
|
def close_global_library_listeners(self):
|
|
43
40
|
for lib in self._library_cache.values():
|
|
44
|
-
lib.close_global_listeners()
|
|
41
|
+
lib.scope_manager.close_global_listeners()
|
|
45
42
|
|
|
46
43
|
def import_library(self, name, args, alias, variables):
|
|
47
|
-
lib = TestLibrary(name, args, variables,
|
|
48
|
-
|
|
49
|
-
|
|
44
|
+
lib = TestLibrary.from_name(name, args=args, variables=variables,
|
|
45
|
+
create_keywords=False)
|
|
46
|
+
positional, named = lib.init.positional, lib.init.named
|
|
47
|
+
args_str = seq2str2(positional + [f'{n}={named[n]}' for n in named])
|
|
48
|
+
key = (name, positional, named)
|
|
49
|
+
if key in self._library_cache:
|
|
50
|
+
LOGGER.info(f"Found library '{name}' with arguments {args_str} "
|
|
51
|
+
f"from cache.")
|
|
52
|
+
lib = self._library_cache[key]
|
|
53
|
+
else:
|
|
54
|
+
lib.create_keywords()
|
|
55
|
+
if lib.scope is not lib.scope.GLOBAL:
|
|
56
|
+
lib.instance = None
|
|
57
|
+
self._library_cache[key] = lib
|
|
58
|
+
self._log_imported_library(name, args_str, lib)
|
|
50
59
|
if alias:
|
|
51
60
|
alias = variables.replace_scalar(alias)
|
|
52
|
-
lib =
|
|
61
|
+
lib = lib.copy(name=alias)
|
|
53
62
|
LOGGER.info(f"Imported library '{name}' with name '{alias}'.")
|
|
54
63
|
return lib
|
|
55
64
|
|
|
@@ -69,46 +78,15 @@ class Importer:
|
|
|
69
78
|
raise DataError(f"Invalid resource file extension '{extension}'. "
|
|
70
79
|
f"Supported extensions are {extensions}.")
|
|
71
80
|
|
|
72
|
-
def
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
lib.create_handlers()
|
|
80
|
-
self._library_cache[key] = lib
|
|
81
|
-
self._log_imported_library(name, args, lib)
|
|
82
|
-
return lib
|
|
83
|
-
|
|
84
|
-
def _log_imported_library(self, name, args, lib):
|
|
85
|
-
type = lib.__class__.__name__.replace('Library', '').lower()[1:]
|
|
86
|
-
listener = ', with listener' if lib.has_listener else ''
|
|
87
|
-
LOGGER.info(f"Imported library '{name}' with arguments {seq2str2(args)} "
|
|
88
|
-
f"(version {lib.version or '<unknown>'}, {type} type, "
|
|
89
|
-
f"{lib.scope} scope, {len(lib)} keywords{listener}).")
|
|
90
|
-
if not lib:
|
|
81
|
+
def _log_imported_library(self, name, args_str, lib):
|
|
82
|
+
kind = type(lib).__name__.replace('Library', '').lower()
|
|
83
|
+
listener = ', with listener' if lib.listeners else ''
|
|
84
|
+
LOGGER.info(f"Imported library '{name}' with arguments {args_str} "
|
|
85
|
+
f"(version {lib.version or '<unknown>'}, {kind} type, "
|
|
86
|
+
f"{lib.scope.name} scope, {len(lib.keywords)} keywords{listener}).")
|
|
87
|
+
if not (lib.keywords or lib.listeners):
|
|
91
88
|
LOGGER.warn(f"Imported library '{name}' contains no keywords.")
|
|
92
89
|
|
|
93
|
-
def _copy_library(self, orig, name):
|
|
94
|
-
# This is pretty ugly. Hopefully we can remove cache and copying
|
|
95
|
-
# altogether in 3.0 and always just re-import libraries:
|
|
96
|
-
# https://github.com/robotframework/robotframework/issues/2106
|
|
97
|
-
lib = copy.copy(orig)
|
|
98
|
-
lib.name = name
|
|
99
|
-
lib.scope = type(lib.scope)(lib)
|
|
100
|
-
lib.reset_instance()
|
|
101
|
-
lib.handlers = HandlerStore()
|
|
102
|
-
for handler in orig.handlers._normal.values():
|
|
103
|
-
handler = copy.copy(handler)
|
|
104
|
-
handler.library = lib
|
|
105
|
-
lib.handlers.add(handler)
|
|
106
|
-
for handler in orig.handlers._embedded:
|
|
107
|
-
handler = copy.copy(handler)
|
|
108
|
-
handler.library = lib
|
|
109
|
-
lib.handlers.add(handler, embedded=True)
|
|
110
|
-
return lib
|
|
111
|
-
|
|
112
90
|
|
|
113
91
|
class ImportCache:
|
|
114
92
|
"""Keeps track on and optionally caches imported items.
|
|
@@ -122,7 +100,7 @@ class ImportCache:
|
|
|
122
100
|
self._items = []
|
|
123
101
|
|
|
124
102
|
def __setitem__(self, key, item):
|
|
125
|
-
if not
|
|
103
|
+
if not isinstance(key, (str, tuple)):
|
|
126
104
|
raise FrameworkError('Invalid key for ImportCache')
|
|
127
105
|
key = self._norm_path_key(key)
|
|
128
106
|
if key not in self._keys:
|
|
@@ -154,4 +132,4 @@ class ImportCache:
|
|
|
154
132
|
return key
|
|
155
133
|
|
|
156
134
|
def _is_path(self, key):
|
|
157
|
-
return
|
|
135
|
+
return isinstance(key, str) and os.path.isabs(key) and os.path.exists(key)
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# Copyright 2008-2015 Nokia Networks
|
|
2
|
+
# Copyright 2016- Robot Framework Foundation
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
|
|
16
|
+
from robot.errors import DataError
|
|
17
|
+
from robot.result import Keyword as KeywordResult
|
|
18
|
+
from robot.variables import VariableAssignment
|
|
19
|
+
|
|
20
|
+
from .arguments import EmbeddedArguments
|
|
21
|
+
from .model import Keyword as KeywordData
|
|
22
|
+
from .statusreporter import StatusReporter
|
|
23
|
+
from .keywordimplementation import KeywordImplementation
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class InvalidKeyword(KeywordImplementation):
|
|
27
|
+
"""Represents an invalid keyword call.
|
|
28
|
+
|
|
29
|
+
Keyword may not have been found, there could have been multiple matches,
|
|
30
|
+
or the keyword call itself could have been invalid.
|
|
31
|
+
"""
|
|
32
|
+
type = KeywordImplementation.INVALID_KEYWORD
|
|
33
|
+
|
|
34
|
+
def _get_embedded(self, name) -> 'EmbeddedArguments|None':
|
|
35
|
+
try:
|
|
36
|
+
return super()._get_embedded(name)
|
|
37
|
+
except DataError:
|
|
38
|
+
return None
|
|
39
|
+
|
|
40
|
+
def create_runner(self, name, languages=None):
|
|
41
|
+
return InvalidKeywordRunner(self, name)
|
|
42
|
+
|
|
43
|
+
def bind(self, data: KeywordData) -> 'InvalidKeyword':
|
|
44
|
+
return self.copy(parent=data.parent)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class InvalidKeywordRunner:
|
|
48
|
+
|
|
49
|
+
def __init__(self, keyword: InvalidKeyword, name: 'str|None' = None):
|
|
50
|
+
self.keyword = keyword
|
|
51
|
+
self.name = name or keyword.name
|
|
52
|
+
if not keyword.error:
|
|
53
|
+
raise ValueError("Executed 'InvalidKeyword' instance requires 'error'.")
|
|
54
|
+
|
|
55
|
+
def run(self, data: KeywordData, result: KeywordResult, context, run=True):
|
|
56
|
+
kw = self.keyword.bind(data)
|
|
57
|
+
result.config(name=self.name,
|
|
58
|
+
owner=kw.owner.name if kw.owner else None,
|
|
59
|
+
args=data.args,
|
|
60
|
+
assign=tuple(VariableAssignment(data.assign)),
|
|
61
|
+
type=data.type)
|
|
62
|
+
with StatusReporter(data, result, context, run, implementation=kw):
|
|
63
|
+
# 'error' is can be set to 'None' by a listener that handles it.
|
|
64
|
+
if run and kw.error is not None:
|
|
65
|
+
raise DataError(kw.error)
|
|
66
|
+
|
|
67
|
+
dry_run = run
|