{"action":"created","issue":{"url":"https://api.github.com/repos/robotframework/robotframework/issues/2190","repository_url":"https://api.github.com/repos/robotframework/robotframework","labels_url":"https://api.github.com/repos/robotframework/robotframework/issues/2190/labels{/name}","comments_url":"https://api.github.com/repos/robotframework/robotframework/issues/2190/comments","events_url":"https://api.github.com/repos/robotframework/robotframework/issues/2190/events","html_url":"https://github.com/robotframework/robotframework/issues/2190","id":114558284,"number":2190,"title":"Clean-up semi-public API to register \"run keyword variants\" and to disable variable resolving in arguments","user":{"login":"pekkaklarck","id":114985,"avatar_url":"https://avatars.githubusercontent.com/u/114985?v=3","gravatar_id":"","url":"https://api.github.com/users/pekkaklarck","html_url":"https://github.com/pekkaklarck","followers_url":"https://api.github.com/users/pekkaklarck/followers","following_url":"https://api.github.com/users/pekkaklarck/following{/other_user}","gists_url":"https://api.github.com/users/pekkaklarck/gists{/gist_id}","starred_url":"https://api.github.com/users/pekkaklarck/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pekkaklarck/subscriptions","organizations_url":"https://api.github.com/users/pekkaklarck/orgs","repos_url":"https://api.github.com/users/pekkaklarck/repos","events_url":"https://api.github.com/users/pekkaklarck/events{/privacy}","received_events_url":"https://api.github.com/users/pekkaklarck/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/robotframework/robotframework/labels/bwic","name":"bwic","color":"fbca04"},{"url":"https://api.github.com/repos/robotframework/robotframework/labels/enhancement","name":"enhancement","color":"84b6eb"},{"url":"https://api.github.com/repos/robotframework/robotframework/labels/prio-medium","name":"prio-medium","color":"ededed"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":2,"created_at":"2015-11-02T09:32:51Z","updated_at":"2016-03-17T19:08:44Z","closed_at":null,"body":"Robot has a mechanism to disable resolving variables in arguments using `robot.libraries.BuiltIn.register_run_keyword` method. This also makes the method so called \"run keyword variant\" which slightly changes the logic how the keyword is executed. This whole system is a mess that needs to be cleaned up. At least the following things need to be considered:\r\n\r\n1. Separate mechanism to disable resolving variables from arguments. Could possibly be part of `robot.api.deco.keyword`. Should then also have an API to resolve arguments if needed.\r\n\r\n2. Investigate could the whole \"run keyword variant\" system be removed from the public API or, preferably, altogether.\r\n\r\n3. If we cannot remove \"run keyword variant\" system, we need to deprecate/remove the functionality to register keywords by using function/method. That system doesn't work in Python 3 currently and trying to fix it is not worth the effort.\r\n\r\n"},"comment":{"url":"https://api.github.com/repos/robotframework/robotframework/issues/comments/198037432","html_url":"https://github.com/robotframework/robotframework/issues/2190#issuecomment-198037432","issue_url":"https://api.github.com/repos/robotframework/robotframework/issues/2190","id":198037432,"user":{"login":"fkberthold","id":4960532,"avatar_url":"https://avatars.githubusercontent.com/u/4960532?v=3","gravatar_id":"","url":"https://api.github.com/users/fkberthold","html_url":"https://github.com/fkberthold","followers_url":"https://api.github.com/users/fkberthold/followers","following_url":"https://api.github.com/users/fkberthold/following{/other_user}","gists_url":"https://api.github.com/users/fkberthold/gists{/gist_id}","starred_url":"https://api.github.com/users/fkberthold/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/fkberthold/subscriptions","organizations_url":"https://api.github.com/users/fkberthold/orgs","repos_url":"https://api.github.com/users/fkberthold/repos","events_url":"https://api.github.com/users/fkberthold/events{/privacy}","received_events_url":"https://api.github.com/users/fkberthold/received_events","type":"User","site_admin":false},"created_at":"2016-03-17T19:08:44Z","updated_at":"2016-03-17T19:08:44Z","body":"In our own code base we have numerous situations where we've created custom control structures. This feature's pretty important to keeping our logs clean looking and making complex behaviors simple to use.  One example is a custom if statement that evaluates a javascript expression against the given page instead of a python expression:\r\n\r\n```\r\n    def js_run_keyword_if(self, *args):\r\n        \"\"\"If the first value in *args* evaluates to true in javascript, execute's the second value as a keyword\r\n        *keyword*, with the following values up to the first instance of \"ELSE\" or \"ELSE IF.\" If *js_test* returns\r\n        false and there is an \"ELSE\" or \"ELSE IF\" in *args*, it verifies the js_test.\r\n\r\n        @param args: A list of values in a RobotFramework style ELSE/IF format, where the conditionals are javascript booleans\r\n        @type args: ListType\r\n\r\n        @return: The result of executing one of the keywords, or nothing if none of the keywords is executed.\r\n        \"\"\"\r\n        (else_ifs, elses) = self._split_else_ifs(list(args))\r\n        for else_if in else_ifs:\r\n            assert len(else_if) > 1, \"Each else if statement must have a condition and result, %s does not.\" % str(else_if)\r\n            conditional = else_if[0]\r\n            action = else_if[1:]\r\n            js = \"return %s;\" % conditional\r\n            conditional_result = self._current_browser().execute_script(js)\r\n            if conditional_result:\r\n                return robot.libraries.BuiltIn.BuiltIn().run_keyword(*action)\r\n        if elses:\r\n            return robot.libraries.BuiltIn.BuiltIn().run_keyword(*elses)\r\n```\r\n\r\nWithout `register_run_keyword` it would be pretty hard to make this at all clean. It would either involve doing it wholly in RF, or writing a separate python keyword for each case I needed it in."}}