Repository: pyca/cryptography

Issue:
UnicodeEncodeError in x509 name (Python 2.7)
I recently updated cryptography from 2.1.4 to 2.5 (Python 2.7) and now I am getting UnicodeEncodeError errors. Here is shortened traceback:

```
.....
  File "/usr/lib/python2.7/vendor-packages/cryptography/x509/name.py", line 258, in __repr__
    return "<Name({0})>".format(self.rfc4514_string())
UnicodeEncodeError: 'ascii' codec can't encode character u'\xf3' in position 38: ordinal not in range(128)
```

The actual line it's trying to encode is here:
```C=CO,O=Sociedad Cameral de Certificación Digital - .....```.

I checked the previous version and there is a change from `list(self)` to `self.rfc4514_string()` and the string is automatically escaped to `Sociedad Cameral de Certificaci\xf3n Digital`. I tried to add `.encode('utf-8')` and it looked like it fixed the problem, but I don't understand this library and exactly how this string is used, and so I don't know if it's a correct fix.



Discussion:
We clearly shouldn't error generating a repr. We could just do `{0!r}` to have it insert the unicode repr. Thanks for the report, we'll get this fixed.
Thank you - change you proposed works.

Resolving patch:
diff --git a/src/cryptography/x509/name.py b/src/cryptography/x509/name.py
--- a/src/cryptography/x509/name.py
+++ b/src/cryptography/x509/name.py
@@ -253,4 +253,7 @@ def __len__(self):
         return sum(len(rdn) for rdn in self._attributes)
 
     def __repr__(self):
-        return "<Name({})>".format(self.rfc4514_string())
+        if six.PY2:
+            return "<Name({})>".format(self.rfc4514_string().encode('utf8'))
+        else:
+            return "<Name({})>".format(self.rfc4514_string())


Test patch:
diff --git a/tests/x509/test_x509.py b/tests/x509/test_x509.py
--- a/tests/x509/test_x509.py
+++ b/tests/x509/test_x509.py
@@ -1,3 +1,4 @@
+# -*- coding: utf-8 -*-
 # This file is dual licensed under the terms of the Apache License, Version
 # 2.0, and the BSD License. See the LICENSE file in the root of this repository
 # for complete details.
@@ -4120,13 +4121,27 @@ def test_rdns(self):
         name2 = x509.Name([x509.RelativeDistinguishedName([rdn1, rdn2])])
         assert name2.rdns == [x509.RelativeDistinguishedName([rdn1, rdn2])]
 
-    def test_repr(self):
+    @pytest.mark.parametrize(
+        ("common_name", "org_name", "expected_repr"),
+        [
+            (
+                u'cryptography.io',
+                u'PyCA',
+                "<Name(CN=cryptography.io,O=PyCA)>",
+            ),
+            (
+                u'Certificación',
+                u'Certificación',
+                "<Name(CN=Certificación,O=Certificación)>",
+            ),
+        ])
+    def test_repr(self, common_name, org_name, expected_repr):
         name = x509.Name([
-            x509.NameAttribute(NameOID.COMMON_NAME, u'cryptography.io'),
-            x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA'),
+            x509.NameAttribute(NameOID.COMMON_NAME, common_name),
+            x509.NameAttribute(NameOID.ORGANIZATION_NAME, org_name),
         ])
 
-        assert repr(name) == "<Name(CN=cryptography.io,O=PyCA)>"
+        assert repr(name) == expected_repr
 
     def test_rfc4514_string(self):
         n = x509.Name([