{"action":"created","issue":{"url":"https://api.github.com/repos/google/python-fire/issues/149","repository_url":"https://api.github.com/repos/google/python-fire","labels_url":"https://api.github.com/repos/google/python-fire/issues/149/labels{/name}","comments_url":"https://api.github.com/repos/google/python-fire/issues/149/comments","events_url":"https://api.github.com/repos/google/python-fire/issues/149/events","html_url":"https://github.com/google/python-fire/issues/149","id":375028999,"node_id":"MDU6SXNzdWUzNzUwMjg5OTk=","number":149,"title":"Using __getattr__ breaks python-fire","user":{"login":"borislopezaraoz","id":2962801,"node_id":"MDQ6VXNlcjI5NjI4MDE=","avatar_url":"https://avatars0.githubusercontent.com/u/2962801?v=4","gravatar_id":"","url":"https://api.github.com/users/borislopezaraoz","html_url":"https://github.com/borislopezaraoz","followers_url":"https://api.github.com/users/borislopezaraoz/followers","following_url":"https://api.github.com/users/borislopezaraoz/following{/other_user}","gists_url":"https://api.github.com/users/borislopezaraoz/gists{/gist_id}","starred_url":"https://api.github.com/users/borislopezaraoz/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/borislopezaraoz/subscriptions","organizations_url":"https://api.github.com/users/borislopezaraoz/orgs","repos_url":"https://api.github.com/users/borislopezaraoz/repos","events_url":"https://api.github.com/users/borislopezaraoz/events{/privacy}","received_events_url":"https://api.github.com/users/borislopezaraoz/received_events","type":"User","site_admin":false},"labels":[{"id":544836571,"node_id":"MDU6TGFiZWw1NDQ4MzY1NzE=","url":"https://api.github.com/repos/google/python-fire/labels/bug","name":"bug","color":"ee0701","default":true}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":5,"created_at":"2018-10-29T13:58:52Z","updated_at":"2018-11-05T12:48:03Z","closed_at":null,"author_association":"NONE","body":"This (admittedly hacky) metaprogramming way of implementing missing methods on the fly breaks python-fire.\r\n\r\nRef: https://stackoverflow.com/a/6955825/1096370\r\n\r\n\r\n    import fire\r\n\r\n    class Calculator(object):\r\n        \"\"\"A simple calculator class.\"\"\"\r\n\r\n        def double(self, number):\r\n            return 2 * number\r\n\r\n        def __getattr__(self, name):\r\n            def _missing(*args, **kwargs):\r\n                print(\"A missing method was called.\")\r\n                print(\"The object was %r, the method was %r. \" % (self, name))\r\n                print(\"It was called with %r and %r as arguments\" % (args, kwargs))\r\n            return _missing\r\n\r\n    if __name__ == '__main__':\r\n        fire.Fire(Calculator)\r\n\r\n\r\nThis \"ghost methods\" works normally when called from other python module.\r\nWhen trying to call it with fire I get this:\r\n\r\n\r\n    python -m calculator double 10\r\n\r\n    Traceback (most recent call last):\r\n      File \"/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/runpy.py\", line 193, in _run_module_as_main\r\n        \"__main__\", mod_spec)\r\n      File \"/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/runpy.py\", line 85, in _run_code\r\n        exec(code, run_globals)\r\n      File \"/users/dev/project/calculator.py\", line 19, in <module>\r\n        fire.Fire(Calculator)\r\n      File \"/users/dev/project/venv/lib/python3.7/site-packages/fire/core.py\", line 127, in Fire\r\n        component_trace = _Fire(component, args, context, name)\r\n      File \"/users/dev/project/venv/lib/python3.7/site-packages/fire/core.py\", line 437, in _Fire\r\n        component, remaining_args)\r\n      File \"/users/dev/project/venv/lib/python3.7/site-packages/fire/core.py\", line 513, in _GetMember\r\n        members = dict(inspect.getmembers(component))\r\n      File \"/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/inspect.py\", line 330, in getmembers\r\n        for base in object.__bases__:\r\n    TypeError: 'function' object is not iterable\r\n"},"comment":{"url":"https://api.github.com/repos/google/python-fire/issues/comments/435861874","html_url":"https://github.com/google/python-fire/issues/149#issuecomment-435861874","issue_url":"https://api.github.com/repos/google/python-fire/issues/149","id":435861874,"node_id":"MDEyOklzc3VlQ29tbWVudDQzNTg2MTg3NA==","user":{"login":"borislopezaraoz","id":2962801,"node_id":"MDQ6VXNlcjI5NjI4MDE=","avatar_url":"https://avatars0.githubusercontent.com/u/2962801?v=4","gravatar_id":"","url":"https://api.github.com/users/borislopezaraoz","html_url":"https://github.com/borislopezaraoz","followers_url":"https://api.github.com/users/borislopezaraoz/followers","following_url":"https://api.github.com/users/borislopezaraoz/following{/other_user}","gists_url":"https://api.github.com/users/borislopezaraoz/gists{/gist_id}","starred_url":"https://api.github.com/users/borislopezaraoz/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/borislopezaraoz/subscriptions","organizations_url":"https://api.github.com/users/borislopezaraoz/orgs","repos_url":"https://api.github.com/users/borislopezaraoz/repos","events_url":"https://api.github.com/users/borislopezaraoz/events{/privacy}","received_events_url":"https://api.github.com/users/borislopezaraoz/received_events","type":"User","site_admin":false},"created_at":"2018-11-05T12:48:03Z","updated_at":"2018-11-05T12:48:03Z","author_association":"NONE","body":"Thanks @meshde, I can confirm that your second solution works on python 3.\r\n\r\nIn the end I went with a different approach: https://stackoverflow.com/a/534597/1096370\r\nUsing setattr to define the methods I need (which I know in advance) instead of catching all missing methods.\r\nIt seems cleaner and it doesn't break python-fire.\r\n"}}
{"actor":{"display_login":"borislopezaraoz"}}