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

Issue:
User.full_name doesn't handle non-ASCII (in Python 2?)
### Steps to reproduce
```python
updater = ext.Updater(token=settings.telegram_token())
def F(bot, update):
  user = update.effective_user
  print repr(user.first_name), repr(user.last_name)
  print '%s %s' % (user.first_name, user.last_name)
  print user.full_name

updater.dispatcher.add_handler(ext.MessageHandler(0, F))
updater.start_polling()
updater.idle()
```

### Expected behaviour
```
u'Dan\u2022iel' u'Reed'
Dan•iel Reed
Dan•iel Reed
```

### Actual behaviour
```
u'Dan\u2022iel' u'Reed'
Dan•iel Reed
ERROR dispatcher.py:301] An uncaught error was raised while processing the update
Traceback (most recent call last):
  File "local/lib/python2.7/site-packages/telegram/ext/dispatcher.py", line 279, in process_update
    handler.handle_update(update, self)
  File "local/lib/python2.7/site-packages/telegram/ext/messagehandler.py", line 169, in handle_update
    return self.callback(dispatcher.bot, update, **optional_args)
  File "<stdin>", line 5, in F
  File "local/lib/python2.7/site-packages/telegram/user.py", line 91, in full_name
    return '{} {}'.format(self.first_name, self.last_name)
UnicodeEncodeError: 'ascii' codec can't encode character u'\u2022' in position 3: ordinal not in range(128)
```

### Configuration
**Operating System:**


**Version of Python, python-telegram-bot & dependencies:**

```
python-telegram-bot 10.0.1
certifi 2018.01.18
future 0.16.0
Python 2.7.14 (default, Sep 23 2017, 22:06:14)  [GCC 7.2.0]
```

I'm a little rushed, but this is works for me:

```python
    @property
    def full_name(self):
        """
        :obj:`str`: Convenience property. The user's :attr:`first_name`, followed by (if available)
            :attr:`last_name`.

        """
        if self.last_name:
!           return u'{} {}'.format(self.first_name, self.last_name)
        return self.first_name
```


Discussion:
Hi Daniel.

I'm having a fit with this one.
I'm using your sample code, but with logging and an error_handler added. When run from pycharm:
```
2.7.13 (v2.7.13:a06454b1afa1, Dec 17 2016, 20:42:59) [MSC v.1500 32 bit (Intel)]
u'Pieter (@Eldin) \U0001f1f3\U0001f1f1' None
Pieter (@Eldin) 🇳🇱 None
Pieter (@Eldin) 🇳🇱
```
When run from cmd (windows 10):
```
2.7.13 (v2.7.13:a06454b1afa1, Dec 17 2016, 20:42:59) [MSC v.1500 32 bit (Intel)]
u'Pieter (@Eldin) \U0001f1f3\U0001f1f1' None
2018-03-14 08:42:44,555 - 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\messagehandler.py", line 169, in handle_update
    return self.callback(dispatcher.bot, update, **optional_args)
  File "test.py", line 17, in F
    print '%s %s' % (user.first_name, user.last_name)
  File "c:\Python27\lib\encodings\cp850.py", line 12, in encode
    return codecs.charmap_encode(input,errors,encoding_map)
UnicodeEncodeError: 'charmap' codec can't encode characters in position 16-19: character maps to <undefined>
```


Oops, I should have noted it's only when the user has both a first and last name set, triggering the catenation. Apparently a decision was made somewhere that, while `'%s' % u'...'` returns a unicode object, `'{}'.format(u'...')` will return a str object.

The Windows issue looks like the terminal is set to codepage 850 (~Latin 1), which wouldn't have your flag emoji :)
@nmlorg You're right about the windows console :D . Could you PR a fix?
I'm not super fluent in Python 3, would it be appropriate to just change that to explicitly be a unicode string like I did locally (`u'{} {}'.format(...)`), or something like adding a `from __future__ import unicode_literals` to the top?

Resolving patch:
diff --git a/telegram/user.py b/telegram/user.py
--- a/telegram/user.py
+++ b/telegram/user.py
@@ -88,7 +88,7 @@ def full_name(self):
 
         """
         if self.last_name:
-            return '{} {}'.format(self.first_name, self.last_name)
+            return u'{} {}'.format(self.first_name, self.last_name)
         return self.first_name
 
     @classmethod


Test patch:
diff --git a/tests/test_user.py b/tests/test_user.py
--- a/tests/test_user.py
+++ b/tests/test_user.py
@@ -42,8 +42,8 @@ def user(bot):
 class TestUser(object):
     id = 1
     is_bot = True
-    first_name = 'first_name'
-    last_name = 'last_name'
+    first_name = u'first\u2022name'
+    last_name = u'last\u2022name'
     username = 'username'
     language_code = 'en_us'
 
@@ -85,16 +85,16 @@ def test_de_json_without_username_and_last_name(self, json_dict, bot):
     def test_name(self, user):
         assert user.name == '@username'
         user.username = None
-        assert user.name == 'first_name last_name'
+        assert user.name == u'first\u2022name last\u2022name'
         user.last_name = None
-        assert user.name == 'first_name'
+        assert user.name == u'first\u2022name'
         user.username = self.username
         assert user.name == '@username'
 
     def test_full_name(self, user):
-        assert user.full_name == 'first_name last_name'
+        assert user.full_name == u'first\u2022name last\u2022name'
         user.last_name = None
-        assert user.full_name == 'first_name'
+        assert user.full_name == u'first\u2022name'
 
     def test_get_profile_photos(self, monkeypatch, user):
         def test(_, *args, **kwargs):