We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
send_photo file from disk doesn't seem to work on python2
### Steps to reproduce
1.  https://github.com/python-telegram-bot/python-telegram-bot/wiki/Code-snippets#post-an-image-file-from-disk

2. I'm using the API and I'm getting this error:
```
'ascii' codec can't decode byte 0x89 in position 0: ordinal not in range(128)
2018-04-24 09:49:59,039 - telegram.ext.dispatcher - ERROR - An uncaught error was raised while processing the update
Traceback (most recent call last):
  File "C:\Python27\lib\site-packages\telegram\ext\dispatcher.py", line 279, in process_update
    handler.handle_update(update, self)
  File "C:\Python27\lib\site-packages\telegram\ext\commandhandler.py", line 173, in handle_update
    return self.callback(dispatcher.bot, update, **optional_args)
  File "bot_status.py", line 101, in graph_progress
    bot.send_photo(chat_id, open(photo, 'rb'))
  File "C:\Python27\lib\site-packages\telegram\bot.py", line 60, in decorator
    result = func(self, *args, **kwargs)
  File "C:\Python27\lib\site-packages\telegram\bot.py", line 85, in decorator
    result = self._request.post(url, data, timeout=kwargs.get('timeout'))
  File "C:\Python27\lib\site-packages\telegram\utils\request.py", line 270, in post
    'POST', url, body=data.to_form(), headers=data.headers, **urlopen_kwargs)
  File "C:\Python27\lib\site-packages\telegram\files\inputfile.py", line 127, in to_form
    return self._parse(form)
  File "C:\Python27\lib\site-packages\telegram\files\inputfile.py", line 141, in _parse
    return '\r\n'.join(form)
UnicodeDecodeError: 'ascii' codec can't decode byte 0x89 in position 0: ordinal not in range(128)
```

3.

### Expected behaviour
I was supposed to get an image

### Actual behaviour
The bot raised an exception

I've tested the same code on python3 and it works correctly, it seems to be a python2 only issue.
In the _parse function it seems that element form[5] is unicode which forces python to treat everything as unicode and PNG is not a valid utf8 data.

### Configuration
Windows 10 x64 1803


**Version of Python, python-telegram-bot & dependencies:**

``$ python -m telegram``
```
python-telegram-bot 10.0.2
certifi 2018.04.16
future 0.16.0
Python 2.7.14 (v2.7.14:84471935ed, Sep 16 2017, 20:25:58) [MSC v.1500 64 bit (AMD64)]
```


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `telegram/files/inputfile.py`
Content:
```
1 #!/usr/bin/env python
2 # pylint: disable=W0622,E0611
3 #
4 # A library that provides a Python interface to the Telegram Bot API
5 # Copyright (C) 2015-2018
6 # Leandro Toledo de Souza <devs@python-telegram-bot.org>
7 #
8 # This program is free software: you can redistribute it and/or modify
9 # it under the terms of the GNU Lesser Public License as published by
10 # the Free Software Foundation, either version 3 of the License, or
11 # (at your option) any later version.
12 #
13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 # GNU Lesser Public License for more details.
17 #
18 # You should have received a copy of the GNU Lesser Public License
19 # along with this program.  If not, see [http://www.gnu.org/licenses/].
20 """This module contains an object that represents a Telegram InputFile."""
21 
22 try:
23     # python 3
24     from email.generator import _make_boundary as choose_boundary
25 except ImportError:
26     # python 2
27     from mimetools import choose_boundary
28 
29 import imghdr
30 import mimetypes
31 import os
32 import sys
33 
34 from telegram import TelegramError
35 
36 DEFAULT_MIME_TYPE = 'application/octet-stream'
37 USER_AGENT = 'Python Telegram Bot (https://github.com/python-telegram-bot/python-telegram-bot)'
38 FILE_TYPES = ('audio', 'document', 'photo', 'sticker', 'video', 'voice', 'certificate',
39               'video_note', 'png_sticker')
40 
41 
42 class InputFile(object):
43     """This object represents a Telegram InputFile.
44 
45     Attributes:
46         data (:obj:`dict`): Data containing an inputfile.
47 
48     Args:
49         data (:obj:`dict`): Data containing an inputfile.
50 
51     Raises:
52         TelegramError
53 
54     """
55 
56     def __init__(self, data):
57         self.data = data
58         self.boundary = choose_boundary()
59 
60         for t in FILE_TYPES:
61             if t in data:
62                 self.input_name = t
63                 self.input_file = data.pop(t)
64                 break
65         else:
66             raise TelegramError('Unknown inputfile type')
67 
68         if hasattr(self.input_file, 'read'):
69             self.filename = None
70             self.input_file_content = self.input_file.read()
71             if 'filename' in data:
72                 self.filename = self.data.pop('filename')
73             elif hasattr(self.input_file, 'name'):
74                 # on py2.7, pylint fails to understand this properly
75                 # pylint: disable=E1101
76                 self.filename = os.path.basename(self.input_file.name)
77 
78             try:
79                 self.mimetype = self.is_image(self.input_file_content)
80                 if not self.filename or '.' not in self.filename:
81                     self.filename = self.mimetype.replace('/', '.')
82             except TelegramError:
83                 if self.filename:
84                     self.mimetype = mimetypes.guess_type(
85                         self.filename)[0] or DEFAULT_MIME_TYPE
86                 else:
87                     self.mimetype = DEFAULT_MIME_TYPE
88 
89     @property
90     def headers(self):
91         """:obj:`dict`: Headers."""
92 
93         return {'User-agent': USER_AGENT, 'Content-type': self.content_type}
94 
95     @property
96     def content_type(self):
97         """:obj:`str`: Content type"""
98         return 'multipart/form-data; boundary=%s' % self.boundary
99 
100     def to_form(self):
101         """Transform the inputfile to multipart/form data.
102 
103         Returns:
104             :obj:`str`
105 
106         """
107         form = []
108         form_boundary = '--' + self.boundary
109 
110         # Add data fields
111         for name in iter(self.data):
112             value = self.data[name]
113             form.extend([
114                 form_boundary, 'Content-Disposition: form-data; name="%s"' % name, '', str(value)
115             ])
116 
117         # Add input_file to upload
118         form.extend([
119             form_boundary, 'Content-Disposition: form-data; name="%s"; filename="%s"' %
120             (self.input_name,
121              self.filename), 'Content-Type: %s' % self.mimetype, '', self.input_file_content
122         ])
123 
124         form.append('--' + self.boundary + '--')
125         form.append('')
126 
127         return self._parse(form)
128 
129     @staticmethod
130     def _parse(form):
131         if sys.version_info > (3,):
132             # on Python 3 form needs to be byte encoded
133             encoded_form = []
134             for item in form:
135                 try:
136                     encoded_form.append(item.encode())
137                 except AttributeError:
138                     encoded_form.append(item)
139 
140             return b'\r\n'.join(encoded_form)
141         return '\r\n'.join(form)
142 
143     @staticmethod
144     def is_image(stream):
145         """Check if the content file is an image by analyzing its headers.
146 
147         Args:
148             stream (:obj:`str`): A str representing the content of a file.
149 
150         Returns:
151             :obj:`str`: The str mime-type of an image.
152 
153         """
154         image = imghdr.what(None, stream)
155         if image:
156             return 'image/%s' % image
157 
158         raise TelegramError('Could not parse file content')
159 
160     @staticmethod
161     def is_inputfile(data):
162         """Check if the request is a file request.
163 
164         Args:
165             data (Dict[:obj:`str`, :obj:`str`]): A dict of (str, str) key/value pairs.
166 
167         Returns:
168             :obj:`bool`
169 
170         """
171         if data:
172             file_type = [i for i in iter(data) if i in FILE_TYPES]
173 
174             if file_type:
175                 file_content = data[file_type[0]]
176 
177                 return hasattr(file_content, 'read')
178 
179         return False
180
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/telegram/files/inputfile.py b/telegram/files/inputfile.py
--- a/telegram/files/inputfile.py
+++ b/telegram/files/inputfile.py
@@ -86,6 +86,10 @@
                 else:
                     self.mimetype = DEFAULT_MIME_TYPE
 
+        if sys.version_info < (3,):
+            if isinstance(self.filename, unicode):  # flake8: noqa  pylint: disable=E0602
+                self.filename = self.filename.encode('utf-8', 'replace')
+
     @property
     def headers(self):
         """:obj:`dict`: Headers."""

{"golden_diff": "diff --git a/telegram/files/inputfile.py b/telegram/files/inputfile.py\n--- a/telegram/files/inputfile.py\n+++ b/telegram/files/inputfile.py\n@@ -86,6 +86,10 @@\n                 else:\n                     self.mimetype = DEFAULT_MIME_TYPE\n \n+        if sys.version_info < (3,):\n+            if isinstance(self.filename, unicode):  # flake8: noqa  pylint: disable=E0602\n+                self.filename = self.filename.encode('utf-8', 'replace')\n+\n     @property\n     def headers(self):\n         \"\"\":obj:`dict`: Headers.\"\"\"\n", "issue": "send_photo file from disk doesn't seem to work on python2\n### Steps to reproduce\r\n1.  https://github.com/python-telegram-bot/python-telegram-bot/wiki/Code-snippets#post-an-image-file-from-disk\r\n\r\n2. I'm using the API and I'm getting this error:\r\n```\r\n'ascii' codec can't decode byte 0x89 in position 0: ordinal not in range(128)\r\n2018-04-24 09:49:59,039 - telegram.ext.dispatcher - ERROR - An uncaught error was raised while processing the update\r\nTraceback (most recent call last):\r\n  File \"C:\\Python27\\lib\\site-packages\\telegram\\ext\\dispatcher.py\", line 279, in process_update\r\n    handler.handle_update(update, self)\r\n  File \"C:\\Python27\\lib\\site-packages\\telegram\\ext\\commandhandler.py\", line 173, in handle_update\r\n    return self.callback(dispatcher.bot, update, **optional_args)\r\n  File \"bot_status.py\", line 101, in graph_progress\r\n    bot.send_photo(chat_id, open(photo, 'rb'))\r\n  File \"C:\\Python27\\lib\\site-packages\\telegram\\bot.py\", line 60, in decorator\r\n    result = func(self, *args, **kwargs)\r\n  File \"C:\\Python27\\lib\\site-packages\\telegram\\bot.py\", line 85, in decorator\r\n    result = self._request.post(url, data, timeout=kwargs.get('timeout'))\r\n  File \"C:\\Python27\\lib\\site-packages\\telegram\\utils\\request.py\", line 270, in post\r\n    'POST', url, body=data.to_form(), headers=data.headers, **urlopen_kwargs)\r\n  File \"C:\\Python27\\lib\\site-packages\\telegram\\files\\inputfile.py\", line 127, in to_form\r\n    return self._parse(form)\r\n  File \"C:\\Python27\\lib\\site-packages\\telegram\\files\\inputfile.py\", line 141, in _parse\r\n    return '\\r\\n'.join(form)\r\nUnicodeDecodeError: 'ascii' codec can't decode byte 0x89 in position 0: ordinal not in range(128)\r\n```\r\n\r\n3.\r\n\r\n### Expected behaviour\r\nI was supposed to get an image\r\n\r\n### Actual behaviour\r\nThe bot raised an exception\r\n\r\nI've tested the same code on python3 and it works correctly, it seems to be a python2 only issue.\r\nIn the _parse function it seems that element form[5] is unicode which forces python to treat everything as unicode and PNG is not a valid utf8 data.\r\n\r\n### Configuration\r\nWindows 10 x64 1803\r\n\r\n\r\n**Version of Python, python-telegram-bot & dependencies:**\r\n\r\n``$ python -m telegram``\r\n```\r\npython-telegram-bot 10.0.2\r\ncertifi 2018.04.16\r\nfuture 0.16.0\r\nPython 2.7.14 (v2.7.14:84471935ed, Sep 16 2017, 20:25:58) [MSC v.1500 64 bit (AMD64)]\r\n```\r\n\n", "before_files": [{"content": "#!/usr/bin/env python\n# pylint: disable=W0622,E0611\n#\n# A library that provides a Python interface to the Telegram Bot API\n# Copyright (C) 2015-2018\n# Leandro Toledo de Souza <devs@python-telegram-bot.org>\n#\n# This program is free software: you can redistribute it and/or modify\n# it under the terms of the GNU Lesser Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU Lesser Public License for more details.\n#\n# You should have received a copy of the GNU Lesser Public License\n# along with this program.  If not, see [http://www.gnu.org/licenses/].\n\"\"\"This module contains an object that represents a Telegram InputFile.\"\"\"\n\ntry:\n    # python 3\n    from email.generator import _make_boundary as choose_boundary\nexcept ImportError:\n    # python 2\n    from mimetools import choose_boundary\n\nimport imghdr\nimport mimetypes\nimport os\nimport sys\n\nfrom telegram import TelegramError\n\nDEFAULT_MIME_TYPE = 'application/octet-stream'\nUSER_AGENT = 'Python Telegram Bot (https://github.com/python-telegram-bot/python-telegram-bot)'\nFILE_TYPES = ('audio', 'document', 'photo', 'sticker', 'video', 'voice', 'certificate',\n              'video_note', 'png_sticker')\n\n\nclass InputFile(object):\n    \"\"\"This object represents a Telegram InputFile.\n\n    Attributes:\n        data (:obj:`dict`): Data containing an inputfile.\n\n    Args:\n        data (:obj:`dict`): Data containing an inputfile.\n\n    Raises:\n        TelegramError\n\n    \"\"\"\n\n    def __init__(self, data):\n        self.data = data\n        self.boundary = choose_boundary()\n\n        for t in FILE_TYPES:\n            if t in data:\n                self.input_name = t\n                self.input_file = data.pop(t)\n                break\n        else:\n            raise TelegramError('Unknown inputfile type')\n\n        if hasattr(self.input_file, 'read'):\n            self.filename = None\n            self.input_file_content = self.input_file.read()\n            if 'filename' in data:\n                self.filename = self.data.pop('filename')\n            elif hasattr(self.input_file, 'name'):\n                # on py2.7, pylint fails to understand this properly\n                # pylint: disable=E1101\n                self.filename = os.path.basename(self.input_file.name)\n\n            try:\n                self.mimetype = self.is_image(self.input_file_content)\n                if not self.filename or '.' not in self.filename:\n                    self.filename = self.mimetype.replace('/', '.')\n            except TelegramError:\n                if self.filename:\n                    self.mimetype = mimetypes.guess_type(\n                        self.filename)[0] or DEFAULT_MIME_TYPE\n                else:\n                    self.mimetype = DEFAULT_MIME_TYPE\n\n    @property\n    def headers(self):\n        \"\"\":obj:`dict`: Headers.\"\"\"\n\n        return {'User-agent': USER_AGENT, 'Content-type': self.content_type}\n\n    @property\n    def content_type(self):\n        \"\"\":obj:`str`: Content type\"\"\"\n        return 'multipart/form-data; boundary=%s' % self.boundary\n\n    def to_form(self):\n        \"\"\"Transform the inputfile to multipart/form data.\n\n        Returns:\n            :obj:`str`\n\n        \"\"\"\n        form = []\n        form_boundary = '--' + self.boundary\n\n        # Add data fields\n        for name in iter(self.data):\n            value = self.data[name]\n            form.extend([\n                form_boundary, 'Content-Disposition: form-data; name=\"%s\"' % name, '', str(value)\n            ])\n\n        # Add input_file to upload\n        form.extend([\n            form_boundary, 'Content-Disposition: form-data; name=\"%s\"; filename=\"%s\"' %\n            (self.input_name,\n             self.filename), 'Content-Type: %s' % self.mimetype, '', self.input_file_content\n        ])\n\n        form.append('--' + self.boundary + '--')\n        form.append('')\n\n        return self._parse(form)\n\n    @staticmethod\n    def _parse(form):\n        if sys.version_info > (3,):\n            # on Python 3 form needs to be byte encoded\n            encoded_form = []\n            for item in form:\n                try:\n                    encoded_form.append(item.encode())\n                except AttributeError:\n                    encoded_form.append(item)\n\n            return b'\\r\\n'.join(encoded_form)\n        return '\\r\\n'.join(form)\n\n    @staticmethod\n    def is_image(stream):\n        \"\"\"Check if the content file is an image by analyzing its headers.\n\n        Args:\n            stream (:obj:`str`): A str representing the content of a file.\n\n        Returns:\n            :obj:`str`: The str mime-type of an image.\n\n        \"\"\"\n        image = imghdr.what(None, stream)\n        if image:\n            return 'image/%s' % image\n\n        raise TelegramError('Could not parse file content')\n\n    @staticmethod\n    def is_inputfile(data):\n        \"\"\"Check if the request is a file request.\n\n        Args:\n            data (Dict[:obj:`str`, :obj:`str`]): A dict of (str, str) key/value pairs.\n\n        Returns:\n            :obj:`bool`\n\n        \"\"\"\n        if data:\n            file_type = [i for i in iter(data) if i in FILE_TYPES]\n\n            if file_type:\n                file_content = data[file_type[0]]\n\n                return hasattr(file_content, 'read')\n\n        return False\n", "path": "telegram/files/inputfile.py"}], "after_files": [{"content": "#!/usr/bin/env python\n# pylint: disable=W0622,E0611\n#\n# A library that provides a Python interface to the Telegram Bot API\n# Copyright (C) 2015-2018\n# Leandro Toledo de Souza <devs@python-telegram-bot.org>\n#\n# This program is free software: you can redistribute it and/or modify\n# it under the terms of the GNU Lesser Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU Lesser Public License for more details.\n#\n# You should have received a copy of the GNU Lesser Public License\n# along with this program.  If not, see [http://www.gnu.org/licenses/].\n\"\"\"This module contains an object that represents a Telegram InputFile.\"\"\"\n\ntry:\n    # python 3\n    from email.generator import _make_boundary as choose_boundary\nexcept ImportError:\n    # python 2\n    from mimetools import choose_boundary\n\nimport imghdr\nimport mimetypes\nimport os\nimport sys\n\nfrom telegram import TelegramError\n\nDEFAULT_MIME_TYPE = 'application/octet-stream'\nUSER_AGENT = 'Python Telegram Bot (https://github.com/python-telegram-bot/python-telegram-bot)'\nFILE_TYPES = ('audio', 'document', 'photo', 'sticker', 'video', 'voice', 'certificate',\n              'video_note', 'png_sticker')\n\n\nclass InputFile(object):\n    \"\"\"This object represents a Telegram InputFile.\n\n    Attributes:\n        data (:obj:`dict`): Data containing an inputfile.\n\n    Args:\n        data (:obj:`dict`): Data containing an inputfile.\n\n    Raises:\n        TelegramError\n\n    \"\"\"\n\n    def __init__(self, data):\n        self.data = data\n        self.boundary = choose_boundary()\n\n        for t in FILE_TYPES:\n            if t in data:\n                self.input_name = t\n                self.input_file = data.pop(t)\n                break\n        else:\n            raise TelegramError('Unknown inputfile type')\n\n        if hasattr(self.input_file, 'read'):\n            self.filename = None\n            self.input_file_content = self.input_file.read()\n            if 'filename' in data:\n                self.filename = self.data.pop('filename')\n            elif hasattr(self.input_file, 'name'):\n                # on py2.7, pylint fails to understand this properly\n                # pylint: disable=E1101\n                self.filename = os.path.basename(self.input_file.name)\n\n            try:\n                self.mimetype = self.is_image(self.input_file_content)\n                if not self.filename or '.' not in self.filename:\n                    self.filename = self.mimetype.replace('/', '.')\n            except TelegramError:\n                if self.filename:\n                    self.mimetype = mimetypes.guess_type(\n                        self.filename)[0] or DEFAULT_MIME_TYPE\n                else:\n                    self.mimetype = DEFAULT_MIME_TYPE\n\n        if sys.version_info < (3,):\n            if isinstance(self.filename, unicode):  # flake8: noqa  pylint: disable=E0602\n                self.filename = self.filename.encode('utf-8', 'replace')\n\n    @property\n    def headers(self):\n        \"\"\":obj:`dict`: Headers.\"\"\"\n\n        return {'User-agent': USER_AGENT, 'Content-type': self.content_type}\n\n    @property\n    def content_type(self):\n        \"\"\":obj:`str`: Content type\"\"\"\n        return 'multipart/form-data; boundary=%s' % self.boundary\n\n    def to_form(self):\n        \"\"\"Transform the inputfile to multipart/form data.\n\n        Returns:\n            :obj:`str`\n\n        \"\"\"\n        form = []\n        form_boundary = '--' + self.boundary\n\n        # Add data fields\n        for name in iter(self.data):\n            value = self.data[name]\n            form.extend([\n                form_boundary, 'Content-Disposition: form-data; name=\"%s\"' % name, '', str(value)\n            ])\n\n        # Add input_file to upload\n        form.extend([\n            form_boundary, 'Content-Disposition: form-data; name=\"%s\"; filename=\"%s\"' %\n            (self.input_name,\n             self.filename), 'Content-Type: %s' % self.mimetype, '', self.input_file_content\n        ])\n\n        form.append('--' + self.boundary + '--')\n        form.append('')\n\n        return self._parse(form)\n\n    @staticmethod\n    def _parse(form):\n        if sys.version_info > (3,):\n            # on Python 3 form needs to be byte encoded\n            encoded_form = []\n            for item in form:\n                try:\n                    encoded_form.append(item.encode())\n                except AttributeError:\n                    encoded_form.append(item)\n\n            return b'\\r\\n'.join(encoded_form)\n        return '\\r\\n'.join(form)\n\n    @staticmethod\n    def is_image(stream):\n        \"\"\"Check if the content file is an image by analyzing its headers.\n\n        Args:\n            stream (:obj:`str`): A str representing the content of a file.\n\n        Returns:\n            :obj:`str`: The str mime-type of an image.\n\n        \"\"\"\n        image = imghdr.what(None, stream)\n        if image:\n            return 'image/%s' % image\n\n        raise TelegramError('Could not parse file content')\n\n    @staticmethod\n    def is_inputfile(data):\n        \"\"\"Check if the request is a file request.\n\n        Args:\n            data (Dict[:obj:`str`, :obj:`str`]): A dict of (str, str) key/value pairs.\n\n        Returns:\n            :obj:`bool`\n\n        \"\"\"\n        if data:\n            file_type = [i for i in iter(data) if i in FILE_TYPES]\n\n            if file_type:\n                file_content = data[file_type[0]]\n\n                return hasattr(file_content, 'read')\n\n        return False\n", "path": "telegram/files/inputfile.py"}]}