{"action":"created","issue":{"url":"https://api.github.com/repos/micheles/decorator/issues/33","repository_url":"https://api.github.com/repos/micheles/decorator","labels_url":"https://api.github.com/repos/micheles/decorator/issues/33/labels{/name}","comments_url":"https://api.github.com/repos/micheles/decorator/issues/33/comments","events_url":"https://api.github.com/repos/micheles/decorator/issues/33/events","html_url":"https://github.com/micheles/decorator/issues/33","id":170385663,"number":33,"title":"Include \"argument-resolving decorator\" into decorator package ?","user":{"login":"pakal","id":330629,"avatar_url":"https://avatars.githubusercontent.com/u/330629?v=3","gravatar_id":"","url":"https://api.github.com/users/pakal","html_url":"https://github.com/pakal","followers_url":"https://api.github.com/users/pakal/followers","following_url":"https://api.github.com/users/pakal/following{/other_user}","gists_url":"https://api.github.com/users/pakal/gists{/gist_id}","starred_url":"https://api.github.com/users/pakal/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pakal/subscriptions","organizations_url":"https://api.github.com/users/pakal/orgs","repos_url":"https://api.github.com/users/pakal/repos","events_url":"https://api.github.com/users/pakal/events{/privacy}","received_events_url":"https://api.github.com/users/pakal/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":2,"created_at":"2016-08-10T10:35:59Z","updated_at":"2016-08-11T16:24:08Z","closed_at":null,"body":"I've developed a handy utility which looks like @decorator, but pre-resolves arguments before passing them to the wrapper function (using https://docs.python.org/2/library/inspect.html#inspect.getcallargs).\r\n\r\nIt's very useful when you need to decorate many functions, without knowing it advanced if they'll be passed arguments by position (<*args>) or by keywords (<**kwargs>). Since incoming arguments are normalized in a simple dict, you can inspect and modify them freely. \r\n\r\nI used it to automatically inject or commit/rollback SQL sessions which travelled through program, for example.\r\n\r\nBelow is an example of use.\r\n\r\nWould you be OK for me to prepare a pull request including that utility next to the standard \"decorator\".\r\n\r\n```\r\n        @resolving_decorator\r\n        def inject_session(func, **all_kwargs):\r\n            if not all_kwargs[\"session\"]:\r\n                all_kwargs[\"session\"] = \"<SESSION>\"\r\n            return func(**all_kwargs)\r\n        \r\n        @inject_session\r\n        def myfunc(session):\r\n            return session\r\n        \r\n        assert myfunc(None) == myfunc(session=None) == \"<SESSION>\"\r\n        assert myfunc(\"<stuff>\") == myfunc(session=\"<stuff>\") == \"<stuff>\"\r\n```"},"comment":{"url":"https://api.github.com/repos/micheles/decorator/issues/comments/239213320","html_url":"https://github.com/micheles/decorator/issues/33#issuecomment-239213320","issue_url":"https://api.github.com/repos/micheles/decorator/issues/33","id":239213320,"user":{"login":"pakal","id":330629,"avatar_url":"https://avatars.githubusercontent.com/u/330629?v=3","gravatar_id":"","url":"https://api.github.com/users/pakal","html_url":"https://github.com/pakal","followers_url":"https://api.github.com/users/pakal/followers","following_url":"https://api.github.com/users/pakal/following{/other_user}","gists_url":"https://api.github.com/users/pakal/gists{/gist_id}","starred_url":"https://api.github.com/users/pakal/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pakal/subscriptions","organizations_url":"https://api.github.com/users/pakal/orgs","repos_url":"https://api.github.com/users/pakal/repos","events_url":"https://api.github.com/users/pakal/events{/privacy}","received_events_url":"https://api.github.com/users/pakal/received_events","type":"User","site_admin":false},"created_at":"2016-08-11T16:24:08Z","updated_at":"2016-08-11T16:24:08Z","body":"Actually if I see well the \"resolving_decorator\" included in that package, it's because imho it's just a variant of the \"decorator.decorator\" utility. \r\n\r\nBelow is an excerpt from the decorator documentation. \r\n\r\n```\r\n>>> @decorator\r\n... def trace(f, *args, **kw):\r\n... kwstr = ', '.join('%r: %r' % (k, kw[k]) for k in sorted(kw))\r\n... print(\"calling %s with args %s, {%s}\" % (f.__name__, args, kwstr))\r\n... return f(*args, **kw)\r\n```\r\n\r\nAs you see, when the decorated function get called at runtime, all arguments are passed as standard \"*args, **kw\" pair. So inside this \"trace\" decorator, it's complicated to extract, for example, an argument which would be an SQL session, because one doesn't know if it's in \"args\" (passed by position) or \"kwargs\" (passed by keyword).\r\n\r\nThe \"resolving_decorator\" would allow \"trace\" to receive a single \"**all_kwargs\" data set, with all arguments already bound to their final \"local variable\" name. Thus \"trace\" could simply do all_kwargs.get(\"sql_session\"), and fiddle with this pre-resolved parameter. The only constraint would be, of course, that all decorated functions which want to have sql session handling, expose a \"sql_session\" argument in their signature.\r\n\r\n\r\n\r\n"}}
{"actor":{"display_login":"pakal"}}