{"action":"created","issue":{"url":"https://api.github.com/repos/nickoala/telepot/issues/166","repository_url":"https://api.github.com/repos/nickoala/telepot","labels_url":"https://api.github.com/repos/nickoala/telepot/issues/166/labels{/name}","comments_url":"https://api.github.com/repos/nickoala/telepot/issues/166/comments","events_url":"https://api.github.com/repos/nickoala/telepot/issues/166/events","html_url":"https://github.com/nickoala/telepot/issues/166","id":180386582,"number":166,"title":"Keyerror when creating a Message","user":{"login":"pymaldebaran","id":2659210,"avatar_url":"https://avatars.githubusercontent.com/u/2659210?v=3","gravatar_id":"","url":"https://api.github.com/users/pymaldebaran","html_url":"https://github.com/pymaldebaran","followers_url":"https://api.github.com/users/pymaldebaran/followers","following_url":"https://api.github.com/users/pymaldebaran/following{/other_user}","gists_url":"https://api.github.com/users/pymaldebaran/gists{/gist_id}","starred_url":"https://api.github.com/users/pymaldebaran/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pymaldebaran/subscriptions","organizations_url":"https://api.github.com/users/pymaldebaran/orgs","repos_url":"https://api.github.com/users/pymaldebaran/repos","events_url":"https://api.github.com/users/pymaldebaran/events{/privacy}","received_events_url":"https://api.github.com/users/pymaldebaran/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":5,"created_at":"2016-09-30T19:43:01Z","updated_at":"2016-10-02T13:31:59Z","closed_at":null,"body":"I wanted to use the very convenient telepot.namedtuple to have more readable code. It worked perfectly with InlineKeyboardMarkup and InlineKeyboardButton but when trying to use Message I always got a KeyError regarding the 'from' field.\r\nTe simplest way to reproduce the error is simply to try to create an empty Message tuple:\r\n```python\r\n>>> from telepot.namedtuple import Message\r\n>>> msg = Message()\r\nTraceback (most recent call last):\r\n  File \"<stdin>\", line 1, in <module>\r\n  File \"/usr/lib/python3.5/site-packages/telepot/namedtuple.py\", line 28, in __new__\r\n    kwargs[newkey] = kwargs[oldkey]\r\nKeyError: 'from'\r\n>>> msg = Message(from_='aaa')\r\nTraceback (most recent call last):\r\n  File \"<stdin>\", line 1, in <module>\r\n  File \"/usr/lib/python3.5/site-packages/telepot/namedtuple.py\", line 28, in __new__\r\n    kwargs[newkey] = kwargs[oldkey]\r\nKeyError: 'from'\r\n```\r\nIt must have something to do with the 'from_' to 'from' conversion somewhat but I can't figure out how to circumvent the problem... I can't decide if this is a bug or that I'm not using the namedtuple correctly."},"comment":{"url":"https://api.github.com/repos/nickoala/telepot/issues/comments/250971420","html_url":"https://github.com/nickoala/telepot/issues/166#issuecomment-250971420","issue_url":"https://api.github.com/repos/nickoala/telepot/issues/166","id":250971420,"user":{"login":"pymaldebaran","id":2659210,"avatar_url":"https://avatars.githubusercontent.com/u/2659210?v=3","gravatar_id":"","url":"https://api.github.com/users/pymaldebaran","html_url":"https://github.com/pymaldebaran","followers_url":"https://api.github.com/users/pymaldebaran/followers","following_url":"https://api.github.com/users/pymaldebaran/following{/other_user}","gists_url":"https://api.github.com/users/pymaldebaran/gists{/gist_id}","starred_url":"https://api.github.com/users/pymaldebaran/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pymaldebaran/subscriptions","organizations_url":"https://api.github.com/users/pymaldebaran/orgs","repos_url":"https://api.github.com/users/pymaldebaran/repos","events_url":"https://api.github.com/users/pymaldebaran/events{/privacy}","received_events_url":"https://api.github.com/users/pymaldebaran/received_events","type":"User","site_admin":false},"created_at":"2016-10-02T13:31:59Z","updated_at":"2016-10-02T13:31:59Z","body":"Thanks a lot, I now understand what was the exact problem (I tried by myself but I couldn't sort out a solution without breaking everything). You're right some of the fields have to be dictionaries... so creating \"fake messages\" can be quite cumbersome: I would have to build my messages with explicit instanciation of each sub structure (User, Chat...) just to be sure... overkill for a unittest helper. What I really needed was a convenient way to simply create Teleport like data structure using keyword arg syntax and automatic checking of the existence of the provided keys in the reference Teleport structure... telepot.namedtuple provide me the structure... so I need a workaround...\r\n\r\nSo with this brand new understanding of the situation I managed to find a solution that fits my problem well (without altering telepot's code) :\r\n```python\r\ndef FakeMessage(**kwargs):\r\n    \"\"\"\r\n    Helper pseudo type to create fake Telegram messages.\r\n\r\n    Returns:\r\n        A dict compatible with Telegram definition of a message.\r\n    \"\"\"\r\n    # Preconditions\r\n    assert all([key in Message._fields for key in kwargs])\r\n    assert 'from_' in kwargs\r\n\r\n    # Work around the fact from is a reserved word and can't be used as\r\n    # parameter name\r\n    kwargs['from'] = kwargs['from_']\r\n    del kwargs['from_']\r\n\r\n    return kwargs\r\n\r\ndef FakeChat(**kwargs):\r\n    \"\"\"\r\n    Helper pseudo type to create fake Telegram chat.\r\n\r\n    Returns:\r\n        A dict compatible with Telegram definition of a message.\r\n    \"\"\"\r\n    # Preconditions\r\n    assert all([key in Chat._fields for key in kwargs])\r\n    assert 'id' not in kwargs\r\n\r\n    # KISS way to have a unique id for each chat\r\n    kwargs['id'] = hash(time.time())\r\n\r\n    return kwargs\r\n\r\ndef FakeUser(**kwargs):\r\n    \"\"\"\r\n    Helper pseudo type to create fake Telegram user.\r\n\r\n    Returns:\r\n        A dict compatible with Telegram definition of a message.\r\n    \"\"\"\r\n    # Preconditions\r\n    assert all([key in User._fields for key in kwargs])\r\n    assert 'first_name' in kwargs\r\n    assert 'id' not in kwargs\r\n\r\n    kwargs['id'] = hash(kwargs['first_name'])\r\n\r\n    return kwargs\r\n\r\nmsg = FakeMessage(\r\n    chat=FakeChat(type='text'),\r\n    from_=FakeUser(\r\n        first_name='Joey',\r\n        last_name='Tribbiani',\r\n        username='@friendsjoey'),\r\n    text=txt)\r\n```\r\nThis doesn't really use the namedtuple but they provide the \"reference\" I need to be sure not to create awful Frankenstein monsters by mistake while testing my bot. And this even gives me a good place to put my \"dummy id\" generation code.\r\n\r\nIndependently from this very specific problem of mine (now solved) I think the change you proposed to enable the creation of Message the same way the other namedtuple could be created would really be a real improvement to telepot."}}
{"actor":{"display_login":"pymaldebaran"}}