internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: python-telegram-bot/python-telegram-bot

Issue:
support socks5 proxy.
First of all, everthing works well. Very thanks for your working on this awesome lib.

But in China, telegram is been blocked by gov. When deploying the bot in China, it's unable to reply message to the api server, can receive message from telegram.

I tried to set up a sock5 proxy, but failed. Is there any plan for supporting the sock5 proxy?

![image](https://cloud.githubusercontent.com/assets/2503423/22633710/d62f7b6e-ec5e-11e6-870f-ace293672f04.png)



Discussion:

Resolving patch:
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -36,6 +36,7 @@ def requirements():
           install_requires=requirements(),
           extras_require={
               'json': 'ujson',
+              'socks': 'PySocks'
           },
           include_package_data=True,
           classifiers=[
diff --git a/telegram/utils/request.py b/telegram/utils/request.py
--- a/telegram/utils/request.py
+++ b/telegram/utils/request.py
@@ -30,6 +30,10 @@
 import urllib3
 from urllib3.connection import HTTPConnection
 from urllib3.util.timeout import Timeout
+try:
+    from urllib3.contrib.socks import SOCKSProxyManager
+except ImportError:
+    SOCKSProxyManager = None
 
 from telegram import (InputFile, TelegramError)
 from telegram.error import (Unauthorized, NetworkError, TimedOut, BadRequest, ChatMigrated,
@@ -92,11 +96,16 @@ def __init__(self,
             mgr = urllib3.PoolManager(**kwargs)
         else:
             kwargs.update(urllib3_proxy_kwargs)
-            mgr = urllib3.proxy_from_url(proxy_url, **kwargs)
-            if mgr.proxy.auth:
-                # TODO: what about other auth types?
-                auth_hdrs = urllib3.make_headers(proxy_basic_auth=mgr.proxy.auth)
-                mgr.proxy_headers.update(auth_hdrs)
+            if proxy_url.startswith('socks'):
+                if not SOCKSProxyManager:
+                    raise RuntimeError('PySocks is missing')
+                mgr = SOCKSProxyManager(proxy_url, **kwargs)
+            else:
+                mgr = urllib3.proxy_from_url(proxy_url, **kwargs)
+                if mgr.proxy.auth:
+                    # TODO: what about other auth types?
+                    auth_hdrs = urllib3.make_headers(proxy_basic_auth=mgr.proxy.auth)
+                    mgr.proxy_headers.update(auth_hdrs)
 
         self._con_pool = mgr
 


Test patch:
Repository: python-telegram-bot/python-telegram-bot

Issue:
add reasons description when an Unauthorized exceptions occurs
Add possibility to know the description of an Unauthorized exceptions.

Botogram (https://botogram.pietroalbini.org/) has the feature and it returns a description of the error well documented here: https://botogram.pietroalbini.org/docs/dev/unavailable-chats/

thanks


Discussion:
@91DarioDev For reference: https://github.com/pietroalbini/botogram/blob/master/botogram/api.py#L112-L153
It seems to me it's enough to pass the error-message so you can handle it in your own code. Working on this
I agree

Resolving patch:
diff --git a/telegram/error.py b/telegram/error.py
--- a/telegram/error.py
+++ b/telegram/error.py
@@ -62,9 +62,7 @@ def __str__(self):
 
 
 class Unauthorized(TelegramError):
-
-    def __init__(self):
-        super(Unauthorized, self).__init__('Unauthorized')
+    pass
 
 
 class InvalidToken(TelegramError):
diff --git a/telegram/utils/request.py b/telegram/utils/request.py
--- a/telegram/utils/request.py
+++ b/telegram/utils/request.py
@@ -183,7 +183,7 @@ def _request_wrapper(self, *args, **kwargs):
             raise NetworkError('Unknown HTTPError {0}'.format(resp.status))
 
         if resp.status in (401, 403):
-            raise Unauthorized()
+            raise Unauthorized(message)
         elif resp.status == 400:
             raise BadRequest(message)
         elif resp.status == 404:


Test patch:
diff --git a/tests/test_updater.py b/tests/test_updater.py
--- a/tests/test_updater.py
+++ b/tests/test_updater.py
@@ -693,7 +693,7 @@ def test_bootstrap_retries_success(self):
     def test_bootstrap_retries_unauth(self):
         retries = 3
         self._setup_updater(
-            '', messages=0, bootstrap_retries=retries, bootstrap_err=Unauthorized())
+            '', messages=0, bootstrap_retries=retries, bootstrap_err=Unauthorized("Unauthorized"))
 
         self.assertRaises(Unauthorized, self.updater._bootstrap, retries, False, 'path', None)
         self.assertEqual(self.updater.bot.bootstrap_attempts, 1)
Repository: python-telegram-bot/python-telegram-bot

Issue:
@message decorator in Bot
In bot.py we have some methods decorated with @message which in turn calles self._message_wrapper.

Is this still needed? Or could we do with just one decorator?



Discussion:
The code in `Bot._message_wrapper` should be moved to the `@message` decorator.
@bomjacob it's not that easy. In that cas @message should be located within the Bot class because _message_wrapper needs a reference to self
It doesn't need to be no, the decorator gets attributes as if they were passed to the decorated method, therefore the first arguement that the decorator (or the wrapper inside it to be more precise) will indeed be the bots `self` AFAIK

Resolving patch:
diff --git a/telegram/bot.py b/telegram/bot.py
--- a/telegram/bot.py
+++ b/telegram/bot.py
@@ -66,7 +66,25 @@ def message(func):
     @functools.wraps(func)
     def decorator(self, *args, **kwargs):
         url, data = func(self, *args, **kwargs)
-        return self._message_wrapper(url, data, *args, **kwargs)
+        if kwargs.get('reply_to_message_id'):
+            data['reply_to_message_id'] = kwargs.get('reply_to_message_id')
+
+        if kwargs.get('disable_notification'):
+            data['disable_notification'] = kwargs.get('disable_notification')
+
+        if kwargs.get('reply_markup'):
+            reply_markup = kwargs.get('reply_markup')
+            if isinstance(reply_markup, ReplyMarkup):
+                data['reply_markup'] = reply_markup.to_json()
+            else:
+                data['reply_markup'] = reply_markup
+
+        result = self._request.post(url, data, timeout=kwargs.get('timeout'))
+
+        if result is True:
+            return result
+
+        return Message.de_json(result, self)
 
     return decorator
 
@@ -148,27 +166,6 @@ def name(self):
 
         return '@{0}'.format(self.username)
 
-    def _message_wrapper(self, url, data, *args, **kwargs):
-        if kwargs.get('reply_to_message_id'):
-            data['reply_to_message_id'] = kwargs.get('reply_to_message_id')
-
-        if kwargs.get('disable_notification'):
-            data['disable_notification'] = kwargs.get('disable_notification')
-
-        if kwargs.get('reply_markup'):
-            reply_markup = kwargs.get('reply_markup')
-            if isinstance(reply_markup, ReplyMarkup):
-                data['reply_markup'] = reply_markup.to_json()
-            else:
-                data['reply_markup'] = reply_markup
-
-        result = self._request.post(url, data, timeout=kwargs.get('timeout'))
-
-        if result is True:
-            return result
-
-        return Message.de_json(result, self)
-
     @log
     def get_me(self, timeout=None, **kwargs):
         """A simple method for testing your bot's auth token. Requires no parameters.


Test patch:
Repository: python-telegram-bot/python-telegram-bot

Issue:
[Feature] Add global timeout argument for all network methods
I think it will be useful to add one timeout argument for all network methods

For example, I have slow internet connection and I know that timeout for me should be 20 sec. I put `timeout=20` keyword argument in all send_* calls. But I have big code, so it will take me some minutes to do it. But when I have global timeout argument, I can change one line of code and everything will work as I wanted

**Version of Python, python-telegram-bot & dependencies:**

python-telegram-bot 6.1.0, Python 3.6.1



Discussion:
@evgfilim1 
I believe that creating a `Request` object and passing it to the `Bot` (or `Updater`) when initializing it should meet you needs. 
What do you think?
@tsnoam I think this will help, but it should be documented.

Resolving patch:
diff --git a/telegram/bot.py b/telegram/bot.py
--- a/telegram/bot.py
+++ b/telegram/bot.py
@@ -97,7 +97,7 @@ class Bot(TelegramObject):
         base_url (:obj:`str`, optional): Telegram Bot API service URL.
         base_file_url (:obj:`str`, optional): Telegram Bot API file URL.
         request (:obj:`telegram.utils.request.Request`, optional): Pre initialized
-            :obj:`telegram.utils.Request`.
+            :obj:`telegram.utils.request.Request`.
 
     """
 
diff --git a/telegram/ext/updater.py b/telegram/ext/updater.py
--- a/telegram/ext/updater.py
+++ b/telegram/ext/updater.py
@@ -69,8 +69,10 @@ class Updater(object):
         user_sig_handler (:obj:`function`, optional): Takes ``signum, frame`` as positional
             arguments. This will be called when a signal is received, defaults are (SIGINT,
             SIGTERM, SIGABRT) setable with :attr:`idle`.
-        request_kwargs (:obj:`dict`, optional): Keyword args to control the creation of a request
-            object (ignored if `bot` argument is used).
+        request_kwargs (:obj:`dict`, optional): Keyword args to control the creation of a
+            `telegram.utils.request.Request` object (ignored if `bot` argument is used). The
+            request_kwargs are very useful for the advanced users who would like to control the
+            default timeouts and/or control the proxy used for http communication.
 
     Note:
         You must supply either a :attr:`bot` or a :attr:`token` argument.


Test patch:
Repository: python-telegram-bot/python-telegram-bot

Issue:
pre_checkout_query does not store bot.

### Steps to reproduce
- On a PreChecoutQueryHandler, get the PreCheckoutQuery object update.pre_checkout_query

- Try to answer it, bot has not been set:

  File "/home/folarte/sexychat/nor  File "/home/folarte/sexychat/normalstate.py", line 998, in on_pcoq
    pcoq.answer(ok=True)
  File "/home/folarte/venv-sxc/local/lib/python3.6/site-packages/telegram/payment/precheckoutquery.py", line 115, in answer
    return self.bot.answer_pre_checkout_query(self.id, *args, **kwargs)
AttributeError: 'NoneType' object has no attribute 'answer_pre_checkout_query'
malstate.py", line 998, in on_pcoq
    pcoq.answer(ok=True)
  File "/home/folarte/venv-sxc/local/lib/python3.6/site-packages/telegram/payment/precheckoutquery.py", line 115, in answer
    return self.bot.answer_pre_checkout_query(self.id, *args, **kwargs)
AttributeError: 'NoneType' object has no attribute 'answer_pre_checkout_query'

### Expected behaviour

pcoq.bot should contain the bot object.

### Actual behaviour

bot object is not set. Thi is due to the de_json function being:

    @classmethod
    def de_json(cls, data, bot):
        if not data:
            return None

        data = super(PreCheckoutQuery, cls).de_json(data, bot)

        data['from_user'] = User.de_json(data.pop('from'), bot)
	data['order_info'] = OrderInfo.de_json(data.get('order_info'), bot)

        return cls(**data)

When the last call should pass the bot to the constructor, as done in the callbackquery object:

        return cls(bot=bot, **data)

When editing the line to these, it works fine.

Do not know GIT, can try to do it, but it is a trivial fix, probably a typo.

### Configuration

Amazon Linux, aws instance.

$ python -m telegram
python-telegram-bot 9.0.0
certifi 2017.11.05
future 0.16.0
Python 3.6.2 (default, Nov  2 2017, 19:34:31)  [GCC 4.8.5 20150623 (Red Hat 4.8.5-11)]



Discussion:

Resolving patch:
diff --git a/telegram/payment/precheckoutquery.py b/telegram/payment/precheckoutquery.py
--- a/telegram/payment/precheckoutquery.py
+++ b/telegram/payment/precheckoutquery.py
@@ -87,7 +87,7 @@ def de_json(cls, data, bot):
         data['from_user'] = User.de_json(data.pop('from'), bot)
         data['order_info'] = OrderInfo.de_json(data.get('order_info'), bot)
 
-        return cls(**data)
+        return cls(bot=bot, **data)
 
     def to_dict(self):
         data = super(PreCheckoutQuery, self).to_dict()


Test patch:
diff --git a/tests/test_precheckoutquery.py b/tests/test_precheckoutquery.py
--- a/tests/test_precheckoutquery.py
+++ b/tests/test_precheckoutquery.py
@@ -55,6 +55,7 @@ def test_de_json(self, bot):
         }
         pre_checkout_query = PreCheckoutQuery.de_json(json_dict, bot)
 
+        assert pre_checkout_query.bot is bot
         assert pre_checkout_query.id == self.id
         assert pre_checkout_query.invoice_payload == self.invoice_payload
         assert pre_checkout_query.shipping_option_id == self.shipping_option_id
Repository: python-telegram-bot/python-telegram-bot

Issue:
Message.reply_media_group
Hello, 

The Message class has helpers for `reply_text`, `reply_photo`, `reply_sticker` etc. Only `reply_media_group` is missing. Would be cool if you would add this little helper, so all type of sent messages are supported.

Best regards, 

Jannik (t.me/bergfreak)




Discussion:

Resolving patch:
diff --git a/telegram/message.py b/telegram/message.py
--- a/telegram/message.py
+++ b/telegram/message.py
@@ -468,6 +468,26 @@ def reply_html(self, *args, **kwargs):
 
         return self.bot.send_message(self.chat_id, *args, **kwargs)
 
+    def reply_media_group(self, *args, **kwargs):
+        """Shortcut for::
+
+            bot.reply_media_group(update.message.chat_id, *args, **kwargs)
+
+        Keyword Args:
+            quote (:obj:`bool`, optional): If set to ``True``, the media group is sent as an
+                actual reply to this message. If ``reply_to_message_id`` is passed in ``kwargs``,
+                this parameter will be ignored. Default: ``True`` in group chats and ``False`` in
+                private chats.
+
+        Returns:
+            List[:class:`telegram.Message`]: An array of the sent Messages.
+
+        Raises:
+            :class:`telegram.TelegramError`
+        """
+        self._quote(kwargs)
+        return self.bot.send_media_group(self.chat_id, *args, **kwargs)
+
     def reply_photo(self, *args, **kwargs):
         """Shortcut for::
 


Test patch:
diff --git a/tests/test_message.py b/tests/test_message.py
--- a/tests/test_message.py
+++ b/tests/test_message.py
@@ -291,6 +291,20 @@ def test(*args, **kwargs):
                                   reply_to_message_id=message.message_id,
                                   quote=True)
 
+    def test_reply_media_group(self, monkeypatch, message):
+        def test(*args, **kwargs):
+            id = args[1] == message.chat_id
+            media = kwargs['media'] == 'reply_media_group'
+            if kwargs.get('reply_to_message_id'):
+                reply = kwargs['reply_to_message_id'] == message.message_id
+            else:
+                reply = True
+            return id and media and reply
+
+        monkeypatch.setattr('telegram.Bot.send_media_group', test)
+        assert message.reply_media_group(media='reply_media_group')
+        assert message.reply_media_group(media='reply_media_group', quote=True)
+
     def test_reply_photo(self, monkeypatch, message):
         def test(*args, **kwargs):
             id = args[1] == message.chat_id
Repository: python-telegram-bot/python-telegram-bot

Issue:
ConversationHandler and run_async racing condition
In conversation handler we may face racing condition in check_update method:
1) `res = new_state.result(timeout=self.run_async_timeout)` may return None since the result is not ready
2) ` if not error and new_state.done.is_set():` may return **True** since the result may be calculated by this time

After that we have a state (old_state, Promise_object) since `self.update_state(None, key)` will leave previous state and may go by the fallback scenario since state dictionary does not contain this state.

Code lines with bug: https://github.com/python-telegram-bot/python-telegram-bot/blob/master/telegram/ext/conversationhandler.py#L229 - https://github.com/python-telegram-bot/python-telegram-bot/blob/master/telegram/ext/conversationhandler.py#L255

**Actually problem may be even bigger because res may be calculated and may actually be None.**

This bug was originally noticed by Николай during a conversation in official telegram chat.


Discussion:
The underlying issue seems to be that it's impossible to distinguish between PTB's `Promise.result` timing out and successfully returning None. `Promise.result` [uses](https://github.com/python-telegram-bot/python-telegram-bot/blob/d4b5bd40a5545a238ebd63f7ffcc1811691526b0/telegram/utils/promise.py#L83) `threading.Event.wait` which signals timeout by its return value.

Resolving patch:
diff --git a/telegram/ext/conversationhandler.py b/telegram/ext/conversationhandler.py
--- a/telegram/ext/conversationhandler.py
+++ b/telegram/ext/conversationhandler.py
@@ -230,18 +230,17 @@ def check_update(self, update):
             self.logger.debug('waiting for promise...')
 
             old_state, new_state = state
-            error = False
-            try:
-                res = new_state.result(timeout=self.run_async_timeout)
-            except Exception as exc:
-                self.logger.exception("Promise function raised exception")
-                self.logger.exception("{}".format(exc))
-                error = True
-
-            if not error and new_state.done.is_set():
-                self.update_state(res, key)
-                state = self.conversations.get(key)
-
+            if new_state.done.wait(timeout=self.run_async_timeout):
+                try:
+                    res = new_state.result(timeout=0)
+                    res = res if res is not None else old_state
+                except Exception as exc:
+                    self.logger.exception("Promise function raised exception")
+                    self.logger.exception("{}".format(exc))
+                    res = old_state
+                finally:
+                    self.update_state(res, key)
+                    state = self.conversations.get(key)
             else:
                 for candidate in (self.timed_out_behavior or []):
                     if candidate.check_update(update):


Test patch:
Repository: python-telegram-bot/python-telegram-bot

Issue:
Typo in comment in conversationbot2.py
<!--
Thanks for reporting issues of python-telegram-bot!

Use this template to notify us if you found a bug, or if you want to request a new feature.
If you're looking for help with programming your bot using our library, feel free to ask your
questions in out telegram group at: https://t.me/pythontelegrambotgroup

To make it easier for us to help you please enter detailed information below.

Please note, we only support the latest version of python-telegram-bot and
master branch. Please make sure to upgrade & recreate the issue on the latest
version prior to opening an issue.
-->
### Steps to reproduce
1. Not really a bug... wrong comment line in conversationbot2.py :)

### Expected behaviour
Should be: # Add conversation handler with the states CHOOSING, TYPING_CHOICE and TYPING_REPLY

### Actual behaviour
Actual comment in conversationbot2.py (leftover from conversationbot.py I guess :))
# Add conversation handler with the states GENDER, PHOTO, LOCATION and BIO

### Configuration
**Operating System:**
Windows

**Version of Python, python-telegram-bot & dependencies:**
3.6

``$ python -m telegram``

### Logs
Insert logs here (if necessary)



Discussion:
I will work on this just to start contributing to the project. 
Great! :D Nice to have you :)

Just write on the telegram group if you need help setting up the development environment :D

Resolving patch:
diff --git a/examples/conversationbot2.py b/examples/conversationbot2.py
--- a/examples/conversationbot2.py
+++ b/examples/conversationbot2.py
@@ -109,7 +109,7 @@ def main():
     # Get the dispatcher to register handlers
     dp = updater.dispatcher
 
-    # Add conversation handler with the states GENDER, PHOTO, LOCATION and BIO
+    # Add conversation handler with the states CHOOSING, TYPING_CHOICE and TYPING_REPLY
     conv_handler = ConversationHandler(
         entry_points=[CommandHandler('start', start)],
 


Test patch:
Repository: python-telegram-bot/python-telegram-bot

Issue:
webhook listen parameter is ignored
The webhook `listen` parameter is ignored.

### Steps to reproduce
1. Call `updater.start_webhook(listen='127.0.0.1')

2. See that python is listening and accepting connections on everything (`0.0.0.0`).

3. Look in the code and see that the `listen` parameter isn't passed into the actual http listener.

### Expected behaviour
The webhook should listen only on the `listen` IP address, as documented.

### Actual behaviour
The webhook is listening on all IP addresses.


Discussion:

Resolving patch:
diff --git a/telegram/ext/updater.py b/telegram/ext/updater.py
--- a/telegram/ext/updater.py
+++ b/telegram/ext/updater.py
@@ -383,7 +383,7 @@ def _start_webhook(self, listen, port, url_path, cert, key, bootstrap_retries, c
             ssl_ctx = None
 
         # Create and start server
-        self.httpd = WebhookServer(port, app, ssl_ctx)
+        self.httpd = WebhookServer(listen, port, app, ssl_ctx)
 
         if use_ssl:
             # DO NOT CHANGE: Only set webhook if SSL is handled by library
diff --git a/telegram/utils/webhookhandler.py b/telegram/utils/webhookhandler.py
--- a/telegram/utils/webhookhandler.py
+++ b/telegram/utils/webhookhandler.py
@@ -34,8 +34,9 @@
 
 class WebhookServer(object):
 
-    def __init__(self, port, webhook_app, ssl_ctx):
+    def __init__(self, listen, port, webhook_app, ssl_ctx):
         self.http_server = HTTPServer(webhook_app, ssl_options=ssl_ctx)
+        self.listen = listen
         self.port = port
         self.loop = None
         self.logger = logging.getLogger(__name__)
@@ -48,7 +49,7 @@ def serve_forever(self):
             IOLoop().make_current()
             self.is_running = True
             self.logger.debug('Webhook Server started.')
-            self.http_server.listen(self.port)
+            self.http_server.listen(self.port, address=self.listen)
             self.loop = IOLoop.current()
             self.loop.start()
             self.logger.debug('Webhook Server stopped.')


Test patch: