robotframework 6.1.1__zip → 7.0__zip
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {robotframework-6.1.1 → robotframework-7.0}/INSTALL.rst +25 -25
- {robotframework-6.1.1 → robotframework-7.0}/PKG-INFO +6 -8
- {robotframework-6.1.1 → robotframework-7.0}/README.rst +3 -2
- {robotframework-6.1.1 → robotframework-7.0}/setup.py +3 -6
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/api/__init__.py +4 -1
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/api/deco.py +60 -14
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/api/exceptions.py +6 -6
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/api/interfaces.py +402 -67
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/api/logger.py +27 -20
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/api/parsing.py +4 -2
- robotframework-7.0/src/robot/api/py.typed +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/conf/gatherfailed.py +2 -2
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/conf/languages.py +0 -9
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/conf/settings.py +21 -14
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/common/storage.js +11 -6
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/htmlfilewriter.py +1 -1
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/libdoc/libdoc.css +10 -2
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/libdoc/libdoc.html +10 -0
- robotframework-7.0/src/robot/htmldata/rebot/common.css +362 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/doc_formatting.css +13 -7
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/log.css +51 -10
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/log.html +14 -23
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/model.js +2 -4
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/report.css +83 -19
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/report.html +22 -7
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/testdata.js +10 -3
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/view.js +84 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/template.py +3 -3
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/builder.py +0 -8
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/datatypes.py +9 -10
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/htmlutils.py +4 -7
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/jsonbuilder.py +38 -20
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/model.py +21 -28
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/robotbuilder.py +50 -31
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/standardtypes.py +9 -1
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/xmlbuilder.py +35 -20
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/xmlwriter.py +18 -38
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/BuiltIn.py +255 -205
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/Collections.py +384 -240
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/DateTime.py +73 -60
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/OperatingSystem.py +6 -5
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/Process.py +26 -27
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/Remote.py +40 -36
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/String.py +66 -76
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/XML.py +66 -59
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/__init__.py +2 -2
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/__init__.py +5 -5
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/body.py +44 -13
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/configurer.py +15 -11
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/control.py +226 -84
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/filter.py +31 -25
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/itemlist.py +9 -8
- robotframework-7.0/src/robot/model/keyword.py +77 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/message.py +19 -10
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/modelobject.py +25 -7
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/namepatterns.py +3 -25
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/stats.py +9 -15
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/tags.py +1 -1
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/testcase.py +15 -27
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/testsuite.py +17 -26
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/visitor.py +35 -8
- robotframework-7.0/src/robot/output/console/dotted.py +90 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/output/console/quiet.py +3 -2
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/output/console/verbose.py +61 -61
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/output/debugfile.py +39 -24
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/output/filelogger.py +18 -15
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/output/librarylogger.py +3 -2
- robotframework-7.0/src/robot/output/listeners.py +753 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/output/logger.py +216 -80
- robotframework-7.0/src/robot/output/loggerapi.py +215 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/output/loggerhelper.py +23 -56
- robotframework-7.0/src/robot/output/output.py +185 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/output/stdoutlogsplitter.py +8 -5
- robotframework-7.0/src/robot/output/xmllogger.py +459 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/lexer/blocklexers.py +17 -13
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/lexer/context.py +12 -2
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/lexer/lexer.py +1 -1
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/lexer/settings.py +6 -3
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/lexer/statementlexers.py +39 -10
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/lexer/tokens.py +27 -29
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/model/blocks.py +19 -6
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/model/statements.py +193 -94
- robotframework-7.0/src/robot/parsing/model/visitor.py +100 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/rebot.py +2 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/reporting/expandkeywordmatcher.py +1 -1
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/reporting/jsbuildingcontext.py +8 -6
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/reporting/jsmodelbuilders.py +88 -61
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/reporting/logreportwriters.py +16 -10
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/reporting/outputwriter.py +18 -2
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/reporting/resultwriter.py +4 -4
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/reporting/stringcache.py +3 -3
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/reporting/xunitwriter.py +15 -21
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/result/__init__.py +3 -2
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/result/configurer.py +12 -9
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/result/executionresult.py +56 -8
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/result/flattenkeywordmatcher.py +48 -9
- robotframework-7.0/src/robot/result/keywordremover.py +207 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/result/merger.py +1 -1
- robotframework-7.0/src/robot/result/model.py +1185 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/result/modeldeprecation.py +9 -3
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/result/resultbuilder.py +46 -36
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/result/xmlelementhandlers.py +83 -43
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/run.py +2 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/__init__.py +14 -4
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/arguments/__init__.py +2 -1
- robotframework-7.0/src/robot/running/arguments/argumentconverter.py +100 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/arguments/argumentmapper.py +26 -24
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/arguments/argumentparser.py +82 -60
- robotframework-7.0/src/robot/running/arguments/argumentresolver.py +158 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/arguments/argumentspec.py +83 -116
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/arguments/argumentvalidator.py +33 -27
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/arguments/customconverters.py +15 -12
- robotframework-7.0/src/robot/running/arguments/embedded.py +145 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/arguments/typeconverters.py +233 -213
- robotframework-7.0/src/robot/running/arguments/typeinfo.py +317 -0
- robotframework-7.0/src/robot/running/arguments/typeinfoparser.py +219 -0
- robotframework-7.0/src/robot/running/arguments/typevalidator.py +60 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/bodyrunner.py +147 -129
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/builder/builders.py +2 -1
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/builder/parsers.py +10 -11
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/builder/settings.py +9 -17
- robotframework-7.0/src/robot/running/builder/transformers.py +535 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/context.py +113 -31
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/dynamicmethods.py +62 -34
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/importer.py +27 -49
- robotframework-7.0/src/robot/running/invalidkeyword.py +67 -0
- robotframework-7.0/src/robot/running/keywordfinder.py +91 -0
- robotframework-7.0/src/robot/running/keywordimplementation.py +164 -0
- robotframework-7.0/src/robot/running/librarykeyword.py +392 -0
- robotframework-7.0/src/robot/running/librarykeywordrunner.py +250 -0
- robotframework-7.0/src/robot/running/libraryscopes.py +115 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/model.py +195 -377
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/namespace.py +124 -137
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/outputcapture.py +20 -12
- robotframework-7.0/src/robot/running/resourcemodel.py +448 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/statusreporter.py +16 -13
- robotframework-7.0/src/robot/running/suiterunner.py +265 -0
- robotframework-7.0/src/robot/running/testlibraries.py +500 -0
- robotframework-7.0/src/robot/running/userkeywordrunner.py +260 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/testdoc.py +18 -13
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/__init__.py +53 -35
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/connectioncache.py +64 -59
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/dotdict.py +3 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/encodingsniffer.py +1 -1
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/escaping.py +19 -19
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/importer.py +2 -2
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/markupwriters.py +23 -15
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/misc.py +1 -2
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/normalizing.py +9 -24
- robotframework-7.0/src/robot/utils/notset.py +33 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/platform.py +15 -5
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/robotio.py +9 -9
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/robotpath.py +1 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/robottime.py +122 -90
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/robottypes.py +21 -31
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/setter.py +0 -5
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/text.py +7 -4
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/unic.py +2 -2
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/variables/__init__.py +2 -2
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/variables/assigner.py +17 -19
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/variables/evaluation.py +20 -17
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/variables/filesetter.py +80 -80
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/variables/replacer.py +33 -36
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/variables/scopes.py +17 -12
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/variables/search.py +66 -41
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/variables/store.py +14 -16
- robotframework-7.0/src/robot/variables/tablesetter.py +164 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/variables/variables.py +1 -1
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/version.py +1 -1
- {robotframework-6.1.1 → robotframework-7.0}/src/robotframework.egg-info/PKG-INFO +6 -8
- {robotframework-6.1.1 → robotframework-7.0}/src/robotframework.egg-info/SOURCES.txt +10 -8
- {robotframework-6.1.1 → robotframework-7.0}/tasks.py +6 -6
- robotframework-6.1.1/src/robot/htmldata/rebot/common.css +0 -239
- robotframework-6.1.1/src/robot/libraries/Reserved.py +0 -48
- robotframework-6.1.1/src/robot/model/keyword.py +0 -173
- robotframework-6.1.1/src/robot/output/console/dotted.py +0 -90
- robotframework-6.1.1/src/robot/output/listenerarguments.py +0 -165
- robotframework-6.1.1/src/robot/output/listenermethods.py +0 -113
- robotframework-6.1.1/src/robot/output/listeners.py +0 -174
- robotframework-6.1.1/src/robot/output/output.py +0 -95
- robotframework-6.1.1/src/robot/output/xmllogger.py +0 -354
- robotframework-6.1.1/src/robot/parsing/model/visitor.py +0 -67
- robotframework-6.1.1/src/robot/result/keywordremover.py +0 -183
- robotframework-6.1.1/src/robot/result/model.py +0 -957
- robotframework-6.1.1/src/robot/running/arguments/argumentconverter.py +0 -79
- robotframework-6.1.1/src/robot/running/arguments/argumentresolver.py +0 -131
- robotframework-6.1.1/src/robot/running/arguments/embedded.py +0 -146
- robotframework-6.1.1/src/robot/running/arguments/typevalidator.py +0 -56
- robotframework-6.1.1/src/robot/running/builder/transformers.py +0 -642
- robotframework-6.1.1/src/robot/running/handlers.py +0 -321
- robotframework-6.1.1/src/robot/running/handlerstore.py +0 -66
- robotframework-6.1.1/src/robot/running/librarykeywordrunner.py +0 -238
- robotframework-6.1.1/src/robot/running/libraryscopes.py +0 -97
- robotframework-6.1.1/src/robot/running/modelcombiner.py +0 -32
- robotframework-6.1.1/src/robot/running/suiterunner.py +0 -248
- robotframework-6.1.1/src/robot/running/testlibraries.py +0 -423
- robotframework-6.1.1/src/robot/running/usererrorhandler.py +0 -75
- robotframework-6.1.1/src/robot/running/userkeyword.py +0 -111
- robotframework-6.1.1/src/robot/running/userkeywordrunner.py +0 -274
- robotframework-6.1.1/src/robot/variables/tablesetter.py +0 -156
- {robotframework-6.1.1 → robotframework-7.0}/AUTHORS.rst +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/BUILD.rst +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/CONTRIBUTING.rst +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/COPYRIGHT.txt +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/LICENSE.txt +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/MANIFEST.in +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/setup.cfg +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/__init__.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/__main__.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/conf/__init__.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/errors.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/__init__.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/common/__init__.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/common/js_disabled.css +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/jsonwriter.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/lib/__init__.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/lib/jquery.highlight.min.js +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/lib/jquery.min.js +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/lib/jquery.tablesorter.min.js +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/lib/jquery.tmpl.min.js +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/lib/jsxcompressor.min.js +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/libdoc/__init__.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/libdoc/doc_formatting.css +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/libdoc/print.css +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/libdoc/pygments.css +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/__init__.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/fileloading.js +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/log.js +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/print.css +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/rebot/util.js +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/testdoc/__init__.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/testdoc/testdoc.css +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/htmldata/testdoc/testdoc.html +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdoc.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/__init__.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/consoleviewer.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/htmlwriter.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/jsonwriter.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/output.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libdocpkg/writer.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/Dialogs.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/Easter.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/Screenshot.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/Telnet.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/libraries/dialogs_py.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/fixture.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/metadata.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/modifier.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/statistics.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/suitestatistics.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/tagsetter.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/tagstatistics.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/model/totalstatistics.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/output/__init__.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/output/console/__init__.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/output/console/highlighting.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/output/pyloggingconf.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/__init__.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/lexer/__init__.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/lexer/tokenizer.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/model/__init__.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/parser/__init__.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/parser/blockparsers.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/parser/fileparser.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/parser/parser.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/parsing/suitestructure.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/pythonpathsetter.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/reporting/__init__.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/reporting/jsexecutionresult.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/reporting/jswriter.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/result/executionerrors.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/result/messagefilter.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/result/suiteteardownfailed.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/result/visitor.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/builder/__init__.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/randomizer.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/runkwregister.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/signalhandler.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/status.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/timeouts/__init__.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/timeouts/posix.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/running/timeouts/windows.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/application.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/argumentparser.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/asserts.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/charwidth.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/compress.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/encoding.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/error.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/etreewrapper.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/filereader.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/frange.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/htmlformatters.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/markuputils.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/match.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/recommendations.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/restreader.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/robotenv.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/robotinspect.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/sortable.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/utils/typehints.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/variables/finders.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/variables/notfound.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robot/variables/resolvable.py +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robotframework.egg-info/dependency_links.txt +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robotframework.egg-info/entry_points.txt +0 -0
- {robotframework-6.1.1 → robotframework-7.0}/src/robotframework.egg-info/top_level.txt +0 -0
|
@@ -0,0 +1,260 @@
|
|
|
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 itertools import chain
|
|
17
|
+
from typing import TYPE_CHECKING
|
|
18
|
+
|
|
19
|
+
from robot.errors import (DataError, ExecutionFailed, ExecutionPassed, ExecutionStatus,
|
|
20
|
+
PassExecution, ReturnFromKeyword, UserKeywordExecutionFailed,
|
|
21
|
+
VariableError)
|
|
22
|
+
from robot.result import Keyword as KeywordResult
|
|
23
|
+
from robot.utils import DotDict, getshortdoc, prepr, split_tags_from_doc
|
|
24
|
+
from robot.variables import is_list_variable, VariableAssignment
|
|
25
|
+
|
|
26
|
+
from .arguments import ArgumentSpec, DefaultValue
|
|
27
|
+
from .bodyrunner import BodyRunner, KeywordRunner
|
|
28
|
+
from .model import Keyword as KeywordData
|
|
29
|
+
from .statusreporter import StatusReporter
|
|
30
|
+
from .timeouts import KeywordTimeout
|
|
31
|
+
|
|
32
|
+
if TYPE_CHECKING:
|
|
33
|
+
from .resourcemodel import UserKeyword
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class UserKeywordRunner:
|
|
37
|
+
|
|
38
|
+
def __init__(self, keyword: 'UserKeyword', name: 'str|None' = None):
|
|
39
|
+
self.keyword = keyword
|
|
40
|
+
self.name = name or keyword.name
|
|
41
|
+
self.pre_run_messages = ()
|
|
42
|
+
|
|
43
|
+
def run(self, data: KeywordData, result: KeywordResult, context, run=True):
|
|
44
|
+
kw = self.keyword.bind(data)
|
|
45
|
+
assignment = VariableAssignment(data.assign)
|
|
46
|
+
self._config_result(result, data, kw, assignment, context.variables)
|
|
47
|
+
with StatusReporter(data, result, context, run, implementation=kw):
|
|
48
|
+
if kw.private:
|
|
49
|
+
context.warn_on_invalid_private_call(kw)
|
|
50
|
+
with assignment.assigner(context) as assigner:
|
|
51
|
+
if run:
|
|
52
|
+
return_value = self._run(data, kw, result, context)
|
|
53
|
+
assigner.assign(return_value)
|
|
54
|
+
return return_value
|
|
55
|
+
|
|
56
|
+
def _config_result(self, result: KeywordResult, data: KeywordData,
|
|
57
|
+
kw: 'UserKeyword', assignment, variables):
|
|
58
|
+
doc = variables.replace_string(kw.doc, ignore_errors=True)
|
|
59
|
+
doc, tags = split_tags_from_doc(doc)
|
|
60
|
+
tags = variables.replace_list(kw.tags, ignore_errors=True) + tags
|
|
61
|
+
result.config(name=self.name,
|
|
62
|
+
owner=kw.owner.name,
|
|
63
|
+
doc=getshortdoc(doc),
|
|
64
|
+
args=data.args,
|
|
65
|
+
assign=tuple(assignment),
|
|
66
|
+
tags=tags,
|
|
67
|
+
type=data.type)
|
|
68
|
+
|
|
69
|
+
def _run(self, data: KeywordData, kw: 'UserKeyword', result: KeywordResult, context):
|
|
70
|
+
if self.pre_run_messages:
|
|
71
|
+
for message in self.pre_run_messages:
|
|
72
|
+
context.output.message(message)
|
|
73
|
+
variables = context.variables
|
|
74
|
+
positional, named = self._resolve_arguments(kw, data.args, variables)
|
|
75
|
+
with context.user_keyword(kw):
|
|
76
|
+
self._set_arguments(kw, positional, named, context)
|
|
77
|
+
if kw.timeout:
|
|
78
|
+
timeout = KeywordTimeout(kw.timeout, variables)
|
|
79
|
+
result.timeout = str(timeout)
|
|
80
|
+
else:
|
|
81
|
+
timeout = None
|
|
82
|
+
with context.timeout(timeout):
|
|
83
|
+
exception, return_value = self._execute(kw, result, context)
|
|
84
|
+
if exception and not exception.can_continue(context):
|
|
85
|
+
raise exception
|
|
86
|
+
return_value = self._handle_return_value(return_value, variables)
|
|
87
|
+
if exception:
|
|
88
|
+
exception.return_value = return_value
|
|
89
|
+
raise exception
|
|
90
|
+
return return_value
|
|
91
|
+
|
|
92
|
+
def _resolve_arguments(self, kw: 'UserKeyword', args, variables=None):
|
|
93
|
+
return kw.resolve_arguments(args, variables)
|
|
94
|
+
|
|
95
|
+
def _set_arguments(self, kw: 'UserKeyword', positional, named, context):
|
|
96
|
+
variables = context.variables
|
|
97
|
+
positional, named = kw.args.map(positional, named, replace_defaults=False)
|
|
98
|
+
self._set_variables(kw.args, positional, named, variables)
|
|
99
|
+
context.output.trace(lambda: self._trace_log_args_message(kw, variables),
|
|
100
|
+
write_if_flat=False)
|
|
101
|
+
|
|
102
|
+
def _set_variables(self, spec: ArgumentSpec, positional, named, variables):
|
|
103
|
+
positional, var_positional = self._separate_positional(spec, positional)
|
|
104
|
+
named_only, var_named = self._separate_named(spec, named)
|
|
105
|
+
for name, value in chain(zip(spec.positional, positional), named_only):
|
|
106
|
+
if isinstance(value, DefaultValue):
|
|
107
|
+
value = value.resolve(variables)
|
|
108
|
+
variables[f'${{{name}}}'] = value
|
|
109
|
+
if spec.var_positional:
|
|
110
|
+
variables[f'@{{{spec.var_positional}}}'] = var_positional
|
|
111
|
+
if spec.var_named:
|
|
112
|
+
variables[f'&{{{spec.var_named}}}'] = DotDict(var_named)
|
|
113
|
+
|
|
114
|
+
def _separate_positional(self, spec: ArgumentSpec, positional):
|
|
115
|
+
if not spec.var_positional:
|
|
116
|
+
return positional, []
|
|
117
|
+
count = len(spec.positional)
|
|
118
|
+
return positional[:count], positional[count:]
|
|
119
|
+
|
|
120
|
+
def _separate_named(self, spec: ArgumentSpec, named):
|
|
121
|
+
named_only = []
|
|
122
|
+
var_named = []
|
|
123
|
+
for name, value in named:
|
|
124
|
+
target = named_only if name in spec.named_only else var_named
|
|
125
|
+
target.append((name, value))
|
|
126
|
+
return named_only, var_named
|
|
127
|
+
|
|
128
|
+
def _trace_log_args_message(self, kw: 'UserKeyword', variables):
|
|
129
|
+
return self._format_trace_log_args_message(
|
|
130
|
+
self._format_args_for_trace_logging(kw.args), variables
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
def _format_args_for_trace_logging(self, spec: ArgumentSpec):
|
|
134
|
+
args = [f'${{{arg}}}' for arg in spec.positional]
|
|
135
|
+
if spec.var_positional:
|
|
136
|
+
args.append(f'@{{{spec.var_positional}}}')
|
|
137
|
+
if spec.var_named:
|
|
138
|
+
args.append(f'&{{{spec.var_named}}}')
|
|
139
|
+
return args
|
|
140
|
+
|
|
141
|
+
def _format_trace_log_args_message(self, args, variables):
|
|
142
|
+
args = ' | '.join(f'{name}={prepr(variables[name])}' for name in args)
|
|
143
|
+
return f'Arguments: [ {args} ]'
|
|
144
|
+
|
|
145
|
+
def _execute(self, kw: 'UserKeyword', result: KeywordResult, context):
|
|
146
|
+
if kw.error:
|
|
147
|
+
raise DataError(kw.error)
|
|
148
|
+
if not kw.body:
|
|
149
|
+
raise DataError('User keyword cannot be empty.')
|
|
150
|
+
if not kw.name:
|
|
151
|
+
raise DataError('User keyword name cannot be empty.')
|
|
152
|
+
if context.dry_run and kw.tags.robot('no-dry-run'):
|
|
153
|
+
return None, None
|
|
154
|
+
error = success = return_value = None
|
|
155
|
+
if kw.setup:
|
|
156
|
+
error = self._run_setup_or_teardown(kw.setup, result.setup, context)
|
|
157
|
+
try:
|
|
158
|
+
BodyRunner(context, run=not error).run(kw, result)
|
|
159
|
+
except ReturnFromKeyword as exception:
|
|
160
|
+
return_value = exception.return_value
|
|
161
|
+
error = exception.earlier_failures
|
|
162
|
+
except ExecutionPassed as exception:
|
|
163
|
+
success = exception
|
|
164
|
+
error = exception.earlier_failures
|
|
165
|
+
if error:
|
|
166
|
+
error.continue_on_failure = False
|
|
167
|
+
except ExecutionFailed as exception:
|
|
168
|
+
error = exception
|
|
169
|
+
if kw.teardown:
|
|
170
|
+
with context.keyword_teardown(error):
|
|
171
|
+
td_error = self._run_setup_or_teardown(kw.teardown, result.teardown,
|
|
172
|
+
context)
|
|
173
|
+
else:
|
|
174
|
+
td_error = None
|
|
175
|
+
if error or td_error:
|
|
176
|
+
error = UserKeywordExecutionFailed(error, td_error)
|
|
177
|
+
return error or success, return_value
|
|
178
|
+
|
|
179
|
+
def _handle_return_value(self, return_value, variables):
|
|
180
|
+
if not return_value:
|
|
181
|
+
return None
|
|
182
|
+
contains_list_var = any(is_list_variable(item) for item in return_value)
|
|
183
|
+
try:
|
|
184
|
+
return_value = variables.replace_list(return_value)
|
|
185
|
+
except DataError as err:
|
|
186
|
+
raise VariableError(f'Replacing variables from keyword return '
|
|
187
|
+
f'value failed: {err}')
|
|
188
|
+
if len(return_value) != 1 or contains_list_var:
|
|
189
|
+
return return_value
|
|
190
|
+
return return_value[0]
|
|
191
|
+
|
|
192
|
+
def _run_setup_or_teardown(self, data: KeywordData, result: KeywordResult,
|
|
193
|
+
context):
|
|
194
|
+
try:
|
|
195
|
+
name = context.variables.replace_string(data.name)
|
|
196
|
+
except DataError as err:
|
|
197
|
+
if context.dry_run:
|
|
198
|
+
return None
|
|
199
|
+
return ExecutionFailed(err.message, syntax=True)
|
|
200
|
+
if name.upper() in ('', 'NONE'):
|
|
201
|
+
return None
|
|
202
|
+
try:
|
|
203
|
+
KeywordRunner(context).run(data, result, name)
|
|
204
|
+
except PassExecution:
|
|
205
|
+
return None
|
|
206
|
+
except ExecutionStatus as err:
|
|
207
|
+
return err
|
|
208
|
+
return None
|
|
209
|
+
|
|
210
|
+
def dry_run(self, data: KeywordData, result: KeywordResult, context):
|
|
211
|
+
kw = self.keyword.bind(data)
|
|
212
|
+
assignment = VariableAssignment(data.assign)
|
|
213
|
+
self._config_result(result, data, kw, assignment, context.variables)
|
|
214
|
+
with StatusReporter(data, result, context, implementation=kw):
|
|
215
|
+
assignment.validate_assignment()
|
|
216
|
+
self._dry_run(data, kw, result, context)
|
|
217
|
+
|
|
218
|
+
def _dry_run(self, data: KeywordData, kw: 'UserKeyword', result: KeywordResult,
|
|
219
|
+
context):
|
|
220
|
+
if self.pre_run_messages:
|
|
221
|
+
for message in self.pre_run_messages:
|
|
222
|
+
context.output.message(message)
|
|
223
|
+
self._resolve_arguments(kw, data.args)
|
|
224
|
+
with context.user_keyword(kw):
|
|
225
|
+
if kw.timeout:
|
|
226
|
+
timeout = KeywordTimeout(kw.timeout, context.variables)
|
|
227
|
+
result.timeout = str(timeout)
|
|
228
|
+
error, _ = self._execute(kw, result, context)
|
|
229
|
+
if error:
|
|
230
|
+
raise error
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
class EmbeddedArgumentsRunner(UserKeywordRunner):
|
|
234
|
+
|
|
235
|
+
def __init__(self, keyword: 'UserKeyword', name: str):
|
|
236
|
+
super().__init__(keyword, name)
|
|
237
|
+
self.embedded_args = keyword.embedded.match(name).groups()
|
|
238
|
+
|
|
239
|
+
def _resolve_arguments(self, kw: 'UserKeyword', args, variables=None):
|
|
240
|
+
result = super()._resolve_arguments(kw, args, variables)
|
|
241
|
+
if variables:
|
|
242
|
+
embedded = [variables.replace_scalar(e) for e in self.embedded_args]
|
|
243
|
+
self.embedded_args = kw.embedded.map(embedded)
|
|
244
|
+
return result
|
|
245
|
+
|
|
246
|
+
def _set_arguments(self, kw: 'UserKeyword', positional, named, context):
|
|
247
|
+
variables = context.variables
|
|
248
|
+
for name, value in self.embedded_args:
|
|
249
|
+
variables[f'${{{name}}}'] = value
|
|
250
|
+
super()._set_arguments(kw, positional, named, context)
|
|
251
|
+
|
|
252
|
+
def _trace_log_args_message(self, kw: 'UserKeyword', variables):
|
|
253
|
+
args = [f'${{{arg}}}' for arg in kw.embedded.args]
|
|
254
|
+
args += self._format_args_for_trace_logging(kw.args)
|
|
255
|
+
return self._format_trace_log_args_message(args, variables)
|
|
256
|
+
|
|
257
|
+
def _config_result(self, result: KeywordResult, data: KeywordData,
|
|
258
|
+
kw: 'UserKeyword', assignment, variables):
|
|
259
|
+
super()._config_result(result, data, kw, assignment, variables)
|
|
260
|
+
result.source_name = kw.name
|
|
@@ -171,11 +171,11 @@ class JsonConverter:
|
|
|
171
171
|
'relativeSource': self._get_relative_source(suite.source),
|
|
172
172
|
'id': suite.id,
|
|
173
173
|
'name': self._escape(suite.name),
|
|
174
|
-
'fullName': self._escape(suite.
|
|
174
|
+
'fullName': self._escape(suite.full_name),
|
|
175
175
|
'doc': self._html(suite.doc),
|
|
176
176
|
'metadata': [(self._escape(name), self._html(value))
|
|
177
177
|
for name, value in suite.metadata.items()],
|
|
178
|
-
'numberOfTests': suite.test_count
|
|
178
|
+
'numberOfTests': suite.test_count,
|
|
179
179
|
'suites': self._convert_suites(suite),
|
|
180
180
|
'tests': self._convert_tests(suite),
|
|
181
181
|
'keywords': list(self._convert_keywords((suite.setup, suite.teardown)))
|
|
@@ -205,7 +205,7 @@ class JsonConverter:
|
|
|
205
205
|
test.body.append(test.teardown)
|
|
206
206
|
return {
|
|
207
207
|
'name': self._escape(test.name),
|
|
208
|
-
'fullName': self._escape(test.
|
|
208
|
+
'fullName': self._escape(test.full_name),
|
|
209
209
|
'id': test.id,
|
|
210
210
|
'doc': self._html(test.doc),
|
|
211
211
|
'tags': [self._escape(t) for t in test.tags],
|
|
@@ -217,10 +217,8 @@ class JsonConverter:
|
|
|
217
217
|
for kw in keywords:
|
|
218
218
|
if not kw:
|
|
219
219
|
continue
|
|
220
|
-
if kw.type
|
|
221
|
-
yield self._convert_keyword(kw
|
|
222
|
-
elif kw.type == kw.TEARDOWN:
|
|
223
|
-
yield self._convert_keyword(kw, 'TEARDOWN')
|
|
220
|
+
if kw.type in kw.KEYWORD_TYPES:
|
|
221
|
+
yield self._convert_keyword(kw)
|
|
224
222
|
elif kw.type == kw.FOR:
|
|
225
223
|
yield self._convert_for(kw)
|
|
226
224
|
elif kw.type == kw.WHILE:
|
|
@@ -229,11 +227,11 @@ class JsonConverter:
|
|
|
229
227
|
yield from self._convert_if(kw)
|
|
230
228
|
elif kw.type == kw.TRY_EXCEPT_ROOT:
|
|
231
229
|
yield from self._convert_try(kw)
|
|
232
|
-
|
|
233
|
-
yield self.
|
|
230
|
+
elif kw.type == kw.VAR:
|
|
231
|
+
yield self._convert_var(kw)
|
|
234
232
|
|
|
235
233
|
def _convert_for(self, data):
|
|
236
|
-
name = '%s %s %s' % (', '.join(data.
|
|
234
|
+
name = '%s %s %s' % (', '.join(data.assign), data.flavor,
|
|
237
235
|
seq2str2(data.values))
|
|
238
236
|
return {'type': 'FOR', 'name': self._escape(name), 'arguments': ''}
|
|
239
237
|
|
|
@@ -250,15 +248,22 @@ class JsonConverter:
|
|
|
250
248
|
for branch in data.body:
|
|
251
249
|
if branch.type == branch.EXCEPT:
|
|
252
250
|
patterns = ', '.join(branch.patterns)
|
|
253
|
-
as_var = f'AS {branch.
|
|
251
|
+
as_var = f'AS {branch.assign}' if branch.assign else ''
|
|
254
252
|
name = f'{patterns} {as_var}'.strip()
|
|
255
253
|
else:
|
|
256
254
|
name = ''
|
|
257
255
|
yield {'type': branch.type, 'name': name, 'arguments': ''}
|
|
258
256
|
|
|
259
|
-
def
|
|
257
|
+
def _convert_var(self, data):
|
|
258
|
+
if data.name[0] == '$' and len(data.value) == 1:
|
|
259
|
+
value = data.value[0]
|
|
260
|
+
else:
|
|
261
|
+
value = '[' + ', '.join(data.value) + ']'
|
|
262
|
+
return {'type': 'VAR', 'name': f'{data.name} = {value}'}
|
|
263
|
+
|
|
264
|
+
def _convert_keyword(self, kw):
|
|
260
265
|
return {
|
|
261
|
-
'type':
|
|
266
|
+
'type': kw.type,
|
|
262
267
|
'name': self._escape(self._get_kw_name(kw)),
|
|
263
268
|
'arguments': self._escape(', '.join(kw.args))
|
|
264
269
|
}
|
|
@@ -33,6 +33,8 @@ or::
|
|
|
33
33
|
assert Matcher('H?llo').match('Hillo')
|
|
34
34
|
"""
|
|
35
35
|
|
|
36
|
+
import warnings
|
|
37
|
+
|
|
36
38
|
from .argumentparser import ArgumentParser, cmdline2list
|
|
37
39
|
from .application import Application
|
|
38
40
|
from .compress import compress_text
|
|
@@ -52,6 +54,7 @@ from .match import eq, Matcher, MultiMatcher
|
|
|
52
54
|
from .misc import (classproperty, isatty, parse_re_flags, plural_or_not,
|
|
53
55
|
printable_name, seq2str, seq2str2, test_or_task)
|
|
54
56
|
from .normalizing import normalize, normalize_whitespace, NormalizedDict
|
|
57
|
+
from .notset import NOT_SET
|
|
55
58
|
from .platform import PY_VERSION, PYPY, UNIXY, WINDOWS, RERAISED_EXCEPTIONS
|
|
56
59
|
from .recommendations import RecommendationFinder
|
|
57
60
|
from .robotenv import get_env_var, set_env_var, del_env_var, get_env_vars
|
|
@@ -61,7 +64,7 @@ from .robotpath import abspath, find_file, get_link_path, normpath
|
|
|
61
64
|
from .robottime import (elapsed_time_to_string, format_time, get_elapsed_time,
|
|
62
65
|
get_time, get_timestamp, secs_to_timestamp,
|
|
63
66
|
secs_to_timestr, timestamp_to_secs, timestr_to_secs,
|
|
64
|
-
parse_time)
|
|
67
|
+
parse_time, parse_timestamp)
|
|
65
68
|
from .robottypes import (has_args, is_bytes, is_dict_like, is_falsy, is_integer,
|
|
66
69
|
is_list_like, is_number, is_pathlike, is_string, is_truthy,
|
|
67
70
|
is_union, type_name, type_repr, typeddict_types)
|
|
@@ -79,37 +82,52 @@ def read_rest_data(rstfile):
|
|
|
79
82
|
return read_rest_data(rstfile)
|
|
80
83
|
|
|
81
84
|
|
|
82
|
-
|
|
83
|
-
#
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
#
|
|
91
|
-
#
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
def
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
85
|
+
def unic(item):
|
|
86
|
+
# Cannot be deprecated using '__getattr__' because a module with same name exists.
|
|
87
|
+
warnings.warn("'robot.utils.unic' is deprecated and will be removed in "
|
|
88
|
+
"Robot Framework 9.0.", DeprecationWarning)
|
|
89
|
+
return safe_str(item)
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def __getattr__(name):
|
|
93
|
+
# Deprecated utils mostly related to the old Python 2/3 compatibility layer.
|
|
94
|
+
# See also 'unic' above and 'PY2' in 'platform.py'.
|
|
95
|
+
# https://github.com/robotframework/robotframework/issues/4501
|
|
96
|
+
|
|
97
|
+
from io import StringIO
|
|
98
|
+
from .robottypes import FALSE_STRINGS, TRUE_STRINGS
|
|
99
|
+
|
|
100
|
+
def py2to3(cls):
|
|
101
|
+
if hasattr(cls, '__unicode__'):
|
|
102
|
+
cls.__str__ = lambda self: self.__unicode__()
|
|
103
|
+
if hasattr(cls, '__nonzero__'):
|
|
104
|
+
cls.__bool__ = lambda self: self.__nonzero__()
|
|
105
|
+
return cls
|
|
106
|
+
|
|
107
|
+
def py3to2(cls):
|
|
108
|
+
return cls
|
|
109
|
+
|
|
110
|
+
deprecated = {
|
|
111
|
+
'FALSE_STRINGS': FALSE_STRINGS,
|
|
112
|
+
'TRUE_STRINGS': TRUE_STRINGS,
|
|
113
|
+
'StringIO': StringIO,
|
|
114
|
+
'PY3': True,
|
|
115
|
+
'PY2': False,
|
|
116
|
+
'JYTHON': False,
|
|
117
|
+
'IRONPYTHON': False,
|
|
118
|
+
'is_unicode': is_string,
|
|
119
|
+
'unicode': str,
|
|
120
|
+
'roundup': round,
|
|
121
|
+
'py2to3': py2to3,
|
|
122
|
+
'py3to2': py3to2,
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if name in deprecated:
|
|
126
|
+
# TODO: Change DeprecationWarning to more visible UserWarning in RF 8.0.
|
|
127
|
+
# https://github.com/robotframework/robotframework/issues/4501
|
|
128
|
+
# Remember also 'unic' above '__getattr__' and 'PY2' in 'platform.py'.
|
|
129
|
+
warnings.warn(f"'robot.utils.{name}' is deprecated and will be removed in "
|
|
130
|
+
f"Robot Framework 9.0.", DeprecationWarning)
|
|
131
|
+
return deprecated[name]
|
|
132
|
+
|
|
133
|
+
raise AttributeError(f"'robot.utils' has no attribute '{name}'.")
|
|
@@ -13,17 +13,21 @@
|
|
|
13
13
|
# See the License for the specific language governing permissions and
|
|
14
14
|
# limitations under the License.
|
|
15
15
|
|
|
16
|
+
from typing import Any
|
|
17
|
+
|
|
16
18
|
from .normalizing import NormalizedDict
|
|
17
|
-
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
Connection = Any
|
|
18
22
|
|
|
19
23
|
|
|
20
24
|
class ConnectionCache:
|
|
21
25
|
"""Cache for libraries to use with concurrent connections, processes, etc.
|
|
22
26
|
|
|
23
27
|
The cache stores the registered connections (or other objects) and allows
|
|
24
|
-
switching between them using generated indices
|
|
25
|
-
This is useful with any library
|
|
26
|
-
connections, processes, etc.
|
|
28
|
+
switching between them using generated indices, user given aliases or
|
|
29
|
+
connection objects themselves. This is useful with any library having a need
|
|
30
|
+
for multiple concurrent connections, processes, etc.
|
|
27
31
|
|
|
28
32
|
This class is used also outside the core framework by SeleniumLibrary,
|
|
29
33
|
SSHLibrary, etc. Backwards compatibility is thus important when doing changes.
|
|
@@ -33,10 +37,10 @@ class ConnectionCache:
|
|
|
33
37
|
self._no_current = NoConnection(no_current_msg)
|
|
34
38
|
self.current = self._no_current #: Current active connection.
|
|
35
39
|
self._connections = []
|
|
36
|
-
self._aliases = NormalizedDict()
|
|
40
|
+
self._aliases = NormalizedDict[int]()
|
|
37
41
|
|
|
38
42
|
@property
|
|
39
|
-
def current_index(self):
|
|
43
|
+
def current_index(self) -> 'int|None':
|
|
40
44
|
if not self:
|
|
41
45
|
return None
|
|
42
46
|
for index, conn in enumerate(self):
|
|
@@ -44,11 +48,13 @@ class ConnectionCache:
|
|
|
44
48
|
return index + 1
|
|
45
49
|
|
|
46
50
|
@current_index.setter
|
|
47
|
-
def current_index(self, index):
|
|
48
|
-
|
|
49
|
-
|
|
51
|
+
def current_index(self, index: 'int|None'):
|
|
52
|
+
if index is None:
|
|
53
|
+
self.current = self._no_current
|
|
54
|
+
else:
|
|
55
|
+
self.current = self._connections[index - 1]
|
|
50
56
|
|
|
51
|
-
def register(self, connection, alias=None):
|
|
57
|
+
def register(self, connection: Connection, alias: 'str|None' = None):
|
|
52
58
|
"""Registers given connection with optional alias and returns its index.
|
|
53
59
|
|
|
54
60
|
Given connection is set to be the :attr:`current` connection.
|
|
@@ -62,52 +68,74 @@ class ConnectionCache:
|
|
|
62
68
|
self.current = connection
|
|
63
69
|
self._connections.append(connection)
|
|
64
70
|
index = len(self._connections)
|
|
65
|
-
if
|
|
71
|
+
if alias:
|
|
66
72
|
self._aliases[alias] = index
|
|
67
73
|
return index
|
|
68
74
|
|
|
69
|
-
def switch(self,
|
|
70
|
-
"""Switches to the connection specified
|
|
75
|
+
def switch(self, identifier: 'int|str|Connection') -> Connection:
|
|
76
|
+
"""Switches to the connection specified using the ``identifier``.
|
|
71
77
|
|
|
72
|
-
|
|
78
|
+
Identifier can be an index, an alias, or a registered connection.
|
|
79
|
+
Raises an error if no matching connection is found.
|
|
73
80
|
|
|
74
|
-
|
|
75
|
-
are returned by it. Index can be given either as an integer or
|
|
76
|
-
as a string that can be converted to an integer. Raises an error
|
|
77
|
-
if no connection with the given index or alias found.
|
|
81
|
+
Updates :attr:`current` and also returns its new value.
|
|
78
82
|
"""
|
|
79
|
-
self.current = self.get_connection(
|
|
83
|
+
self.current = self.get_connection(identifier)
|
|
80
84
|
return self.current
|
|
81
85
|
|
|
82
|
-
def get_connection(self,
|
|
83
|
-
"""
|
|
86
|
+
def get_connection(self, identifier: 'int|str|Connection|None' = None) -> Connection:
|
|
87
|
+
"""Returns the connection specified using the ``identifier``.
|
|
84
88
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
are returned by it. Index can be given either as an integer or
|
|
90
|
-
as a string that can be converted to an integer. Raises an error
|
|
91
|
-
if no connection with the given index or alias found.
|
|
89
|
+
Identifier can be an index (integer or string), an alias, a registered
|
|
90
|
+
connection or ``None``. If the identifier is ``None``, returns the
|
|
91
|
+
current connection if it is active and raises an error if it is not.
|
|
92
|
+
Raises an error also if no matching connection is found.
|
|
92
93
|
"""
|
|
93
|
-
if
|
|
94
|
+
if identifier is None:
|
|
94
95
|
if not self:
|
|
95
96
|
self.current.raise_error()
|
|
96
97
|
return self.current
|
|
97
98
|
try:
|
|
98
|
-
index = self.
|
|
99
|
+
index = self.get_connection_index(identifier)
|
|
99
100
|
except ValueError as err:
|
|
100
101
|
raise RuntimeError(err.args[0])
|
|
101
102
|
return self._connections[index-1]
|
|
102
103
|
|
|
103
|
-
|
|
104
|
+
def get_connection_index(self, identifier: 'int|str|Connection') -> int:
|
|
105
|
+
"""Returns the index of the connection specified using the ``identifier``.
|
|
106
|
+
|
|
107
|
+
Identifier can be an index (integer or string), an alias, or a registered
|
|
108
|
+
connection.
|
|
104
109
|
|
|
105
|
-
|
|
106
|
-
|
|
110
|
+
New in Robot Framework 7.0. :meth:`resolve_alias_or_index` can be used
|
|
111
|
+
with earlier versions.
|
|
112
|
+
"""
|
|
113
|
+
if isinstance(identifier, str) and identifier in self._aliases:
|
|
114
|
+
return self._aliases[identifier]
|
|
115
|
+
if identifier in self._connections:
|
|
116
|
+
return self._connections.index(identifier) + 1
|
|
117
|
+
try:
|
|
118
|
+
index = int(identifier)
|
|
119
|
+
except (ValueError, TypeError):
|
|
120
|
+
index = -1
|
|
121
|
+
if 0 < index <= len(self._connections):
|
|
122
|
+
return index
|
|
123
|
+
raise ValueError(f"Non-existing index or alias '{identifier}'.")
|
|
124
|
+
|
|
125
|
+
def resolve_alias_or_index(self, alias_or_index):
|
|
126
|
+
"""Deprecated in RF 7.0. Use :meth:`get_connection_index` instead."""
|
|
127
|
+
# This was initially added for SeleniumLibrary in RF 3.1.2.
|
|
128
|
+
# https://github.com/robotframework/robotframework/issues/3125
|
|
129
|
+
# The new method was added in RF 7.0. We can loudly deprecate this
|
|
130
|
+
# earliest in RF 8.0.
|
|
131
|
+
return self.get_connection_index(alias_or_index)
|
|
132
|
+
|
|
133
|
+
def close_all(self, closer_method: str = 'close'):
|
|
134
|
+
"""Closes connections using the specified closer method and empties cache.
|
|
107
135
|
|
|
108
136
|
If simply calling the closer method is not adequate for closing
|
|
109
137
|
connections, clients should close connections themselves and use
|
|
110
|
-
:meth:`empty_cache`
|
|
138
|
+
:meth:`empty_cache` afterward.
|
|
111
139
|
"""
|
|
112
140
|
for conn in self._connections:
|
|
113
141
|
getattr(conn, closer_method)()
|
|
@@ -123,6 +151,8 @@ class ConnectionCache:
|
|
|
123
151
|
self._connections = []
|
|
124
152
|
self._aliases = NormalizedDict()
|
|
125
153
|
|
|
154
|
+
__getitem__ = get_connection
|
|
155
|
+
|
|
126
156
|
def __iter__(self):
|
|
127
157
|
return iter(self._connections)
|
|
128
158
|
|
|
@@ -132,31 +162,6 @@ class ConnectionCache:
|
|
|
132
162
|
def __bool__(self):
|
|
133
163
|
return self.current is not self._no_current
|
|
134
164
|
|
|
135
|
-
def resolve_alias_or_index(self, alias_or_index):
|
|
136
|
-
for resolver in self._resolve_alias, self._resolve_index, self._is_connection:
|
|
137
|
-
try:
|
|
138
|
-
return resolver(alias_or_index)
|
|
139
|
-
except ValueError:
|
|
140
|
-
pass
|
|
141
|
-
raise ValueError(f"Non-existing index or alias '{alias_or_index}'.")
|
|
142
|
-
|
|
143
|
-
def _resolve_alias(self, alias):
|
|
144
|
-
if is_string(alias) and alias in self._aliases:
|
|
145
|
-
return self._aliases[alias]
|
|
146
|
-
raise ValueError
|
|
147
|
-
|
|
148
|
-
def _resolve_index(self, index):
|
|
149
|
-
try:
|
|
150
|
-
index = int(index)
|
|
151
|
-
except TypeError:
|
|
152
|
-
raise ValueError
|
|
153
|
-
if not 0 < index <= len(self._connections):
|
|
154
|
-
raise ValueError
|
|
155
|
-
return index
|
|
156
|
-
|
|
157
|
-
def _is_connection(self, conn):
|
|
158
|
-
return self._connections.index(conn) + 1
|
|
159
|
-
|
|
160
165
|
|
|
161
166
|
class NoConnection:
|
|
162
167
|
|
|
@@ -75,7 +75,7 @@ def _get_unixy_encoding():
|
|
|
75
75
|
|
|
76
76
|
|
|
77
77
|
def _get_stream_output_encoding():
|
|
78
|
-
# Python
|
|
78
|
+
# Python uses UTF-8 as encoding with output streams.
|
|
79
79
|
# We want the real console encoding regardless the platform.
|
|
80
80
|
if WINDOWS:
|
|
81
81
|
return None
|