Repository: python-telegram-bot/python-telegram-bot

Issue:
[BUG] Upate.to_dict includes Update._effective_message
### Steps to reproduce
1. Send a message to the bot.

2.
```python
import json
from telegram import Bot

update = Bot('TOKEN').get_updates()[-1]
update.effective_chat
update.effective_user
update.effective_message
print(json.dumps(update.to_dict(), indent=2))
```
### Expected behaviour
```
{
  "update_id": 601206924,
  "message": {
    "message_id": 3030,
    "date": 1591742976,
    "chat": {
      "id": 447493381,
      "type": "private",
      "first_name": "\u041d\u0438\u043a\u043e\u043b\u0430\u0439"
    },
    "text": "1",
    "entities": [],
    "caption_entities": [],
    "photo": [],
    "new_chat_members": [],
    "new_chat_photo": [],
    "delete_chat_photo": false,
    "group_chat_created": false,
    "supergroup_chat_created": false,
    "channel_chat_created": false,
    "from": {
      "id": 447493381,
      "first_name": "\u041d\u0438\u043a\u043e\u043b\u0430\u0439",
      "is_bot": false,
      "language_code": "en"
    }
  }
}
```

### Actual behaviour
```
{
  "update_id": 601206924,
  "message": {
    "message_id": 3030,
    "date": 1591742976,
    "chat": {
      "id": 447493381,
      "type": "private",
      "first_name": "\u041d\u0438\u043a\u043e\u043b\u0430\u0439"
    },
    "text": "1",
    "entities": [],
    "caption_entities": [],
    "photo": [],
    "new_chat_members": [],
    "new_chat_photo": [],
    "delete_chat_photo": false,
    "group_chat_created": false,
    "supergroup_chat_created": false,
    "channel_chat_created": false,
    "from": {
      "id": 447493381,
      "first_name": "\u041d\u0438\u043a\u043e\u043b\u0430\u0439",
      "is_bot": false,
      "language_code": "en"
    }
  },
  "_effective_user": {
    "id": 447493381,
    "first_name": "\u041d\u0438\u043a\u043e\u043b\u0430\u0439",
    "is_bot": false,
    "language_code": "en"
  },
  "_effective_chat": {
    "id": 447493381,
    "type": "private",
    "first_name": "\u041d\u0438\u043a\u043e\u043b\u0430\u0439"
  },
  "_effective_message": {
    "message_id": 3030,
    "date": 1591742976,
    "chat": {
      "id": 447493381,
      "type": "private",
      "first_name": "\u041d\u0438\u043a\u043e\u043b\u0430\u0439"
    },
    "text": "1",
    "entities": [],
    "caption_entities": [],
    "photo": [],
    "new_chat_members": [],
    "new_chat_photo": [],
    "delete_chat_photo": false,
    "group_chat_created": false,
    "supergroup_chat_created": false,
    "channel_chat_created": false,
    "from": {
      "id": 447493381,
      "first_name": "\u041d\u0438\u043a\u043e\u043b\u0430\u0439",
      "is_bot": false,
      "language_code": "en"
    }
  }
}
```

This also applies to effective_* attributes of other classes, e.g. `Message.effective_attachment`

### Configuration
**Operating System:** windows 10


**Version of Python, python-telegram-bot & dependencies:**
```
python-telegram-bot 12.7
certifi 2020.04.05.1
future 0.18.2
Python 3.8.3 (tags/v3.8.3:6f8c832, May 13 2020, 22:37:02) [MSC v.1924 64 bit (AMD64)]
```

### Proposed solution
Make `TelegramObject.to_dict` ignore all attributes starting with an underscore rather than a fixed list.
https://github.com/python-telegram-bot/python-telegram-bot/blob/a42b68933c3628b9b98c83927661eddb61d1571a/telegram/base.py#L56-L67


Discussion:
Git blame tells me that `TGO.to_dict()` was last updated for API 4.0 and before that only `bot` and `_id_attrs` were ignored. If the tests don't complain, I see no reason not to ignore all private attributes. Would you like to PR?

Resolving patch:
diff --git a/telegram/base.py b/telegram/base.py
--- a/telegram/base.py
+++ b/telegram/base.py
@@ -57,12 +57,7 @@ def to_dict(self):
         data = dict()
 
         for key in iter(self.__dict__):
-            if key in ('bot',
-                       '_id_attrs',
-                       '_credentials',
-                       '_decrypted_credentials',
-                       '_decrypted_data',
-                       '_decrypted_secret'):
+            if key == 'bot' or key.startswith('_'):
                 continue
 
             value = self.__dict__[key]


Test patch:
diff --git a/tests/test_telegramobject.py b/tests/test_telegramobject.py
--- a/tests/test_telegramobject.py
+++ b/tests/test_telegramobject.py
@@ -74,3 +74,12 @@ def test_to_json_ujson(self, monkeypatch):
 
         monkeypatch.setattr('telegram.TelegramObject.to_dict', lambda _: d)
         telegram_object.to_json()
+
+    def test_to_dict_private_attribute(self):
+        class TelegramObjectSubclass(TelegramObject):
+            def __init__(self):
+                self.a = 1
+                self._b = 2
+
+        subclass_instance = TelegramObjectSubclass()
+        assert subclass_instance.to_dict() == {'a': 1}