[tor-commits] [stem/master] Using byte string for base64.b64decode in python 3

atagar at torproject.org atagar at torproject.org
Sat Feb 2 18:20:49 UTC 2013


commit 2e7913aa6c59d147ef5ae926d456c54ec459dd52
Author: Damian Johnson <atagar at torproject.org>
Date:   Sun Jan 27 12:17:43 2013 -0800

    Using byte string for base64.b64decode in python 3
    
    First correction for the ASCII -> Unicode switch over in python 3.
    
    ======================================================================
    ERROR: test_get_network_status
    ----------------------------------------------------------------------
    Traceback:
      File "/home/atagar/Desktop/stem/test/data/python3/stem/descriptor/router_status_entry.py", line 702, in _decode_fingerprint
        identity_decoded = base64.b64decode(identity)
      File "/usr/lib/python3.2/base64.py", line 83, in b64decode
        raise TypeError("expected bytes, not %s" % s.__class__.__name__)
    TypeError: expected bytes, not str
    
    During handling of the above exception, another exception occurred:
    
    Traceback:
      File "/home/atagar/Desktop/stem/test/data/python3/test/unit/control/controller.py", line 247, in test_get_network_status
        router = stem.descriptor.router_status_entry.RouterStatusEntryV2(desc)
      File "/home/atagar/Desktop/stem/test/data/python3/stem/descriptor/router_status_entry.py", line 254, in __init__
        super(RouterStatusEntryV2, self).__init__(content, validate, document)
      File "/home/atagar/Desktop/stem/test/data/python3/stem/descriptor/router_status_entry.py", line 149, in __init__
        self._parse(entries, validate)
      File "/home/atagar/Desktop/stem/test/data/python3/stem/descriptor/router_status_entry.py", line 261, in _parse
        _parse_r_line(self, value, validate, True)
      File "/home/atagar/Desktop/stem/test/data/python3/stem/descriptor/router_status_entry.py", line 495, in _parse_r_line
        desc.fingerprint = _decode_fingerprint(r_comp[1], validate)
      File "/home/atagar/Desktop/stem/test/data/python3/stem/descriptor/router_status_entry.py", line 707, in _decode_fingerprint
        raise ValueError("Unable to decode identity string '%s'" % identity)
    ValueError: Unable to decode identity string '/96bKo4soysolMgKn5Hex2nyFSY='
    
    ----------------------------------------------------------------------
    Ran 9 tests in 0.063s
---
 stem/descriptor/router_status_entry.py |    6 ++++--
 stem/descriptor/server_descriptor.py   |    3 ++-
 stem/prereq.py                         |    4 ++--
 stem/util/str_tools.py                 |   28 ++++++++++++++++++++++++++++
 test/settings.cfg                      |    1 +
 5 files changed, 37 insertions(+), 5 deletions(-)

diff --git a/stem/descriptor/router_status_entry.py b/stem/descriptor/router_status_entry.py
index 9af2f44..7f9875b 100644
--- a/stem/descriptor/router_status_entry.py
+++ b/stem/descriptor/router_status_entry.py
@@ -21,6 +21,7 @@ import datetime
 
 import stem.descriptor
 import stem.exit_policy
+import stem.util.str_tools
 
 
 def _parse_file(document_file, validate, entry_class, entry_keyword = "r", start_position = None, end_position = None, section_end_keywords = (), extra_args = ()):
@@ -699,7 +700,7 @@ def _decode_fingerprint(identity, validate):
   fingerprint = ""
 
   try:
-    identity_decoded = base64.b64decode(identity)
+    identity_decoded = base64.b64decode(stem.util.str_tools.to_bytes(identity))
   except TypeError:
     if not validate:
       return None
@@ -717,7 +718,8 @@ def _decode_fingerprint(identity, validate):
     # >>> '0xa'[2:].zfill(2).upper()
     # '0A'
 
-    fingerprint += hex(ord(char))[2:].zfill(2).upper()
+    char_int = char if isinstance(char, int) else ord(char)
+    fingerprint += hex(char_int)[2:].zfill(2).upper()
 
   if not stem.util.tor_tools.is_valid_fingerprint(fingerprint):
     if not validate:
diff --git a/stem/descriptor/server_descriptor.py b/stem/descriptor/server_descriptor.py
index 38781bd..1cf4d31 100644
--- a/stem/descriptor/server_descriptor.py
+++ b/stem/descriptor/server_descriptor.py
@@ -36,6 +36,7 @@ import stem.descriptor.extrainfo_descriptor
 import stem.exit_policy
 import stem.prereq
 import stem.util.connection
+import stem.util.str_tools
 import stem.util.tor_tools
 import stem.version
 
@@ -818,7 +819,7 @@ class RelayDescriptor(ServerDescriptor):
 
     # get the key representation in bytes
 
-    key_bytes = base64.b64decode(key_as_string)
+    key_bytes = base64.b64decode(stem.util.str_tools.to_bytes(key_as_string))
 
     return key_bytes
 
diff --git a/stem/prereq.py b/stem/prereq.py
index b0a508e..46913e4 100644
--- a/stem/prereq.py
+++ b/stem/prereq.py
@@ -23,8 +23,6 @@ series). Other requirements for complete functionality are...
 
 import sys
 
-from stem.util import log
-
 IS_CRYPTO_AVAILABLE = None
 
 
@@ -76,6 +74,8 @@ def is_crypto_available():
   global IS_CRYPTO_AVAILABLE
 
   if IS_CRYPTO_AVAILABLE is None:
+    from stem.util import log
+
     try:
       from Crypto.PublicKey import RSA
       from Crypto.Util import asn1
diff --git a/stem/util/str_tools.py b/stem/util/str_tools.py
index 25512b6..022874e 100644
--- a/stem/util/str_tools.py
+++ b/stem/util/str_tools.py
@@ -5,6 +5,7 @@ Toolkit for various string activity.
 
 ::
 
+  to_bytes - normalizes string ASCII bytes
   to_camel_case - converts a string to camel case
   get_size_label - human readable label for a number of bytes
   get_time_label - human readable label for a number of seconds
@@ -17,6 +18,8 @@ Toolkit for various string activity.
 
 import datetime
 
+import stem.prereq
+
 # label conversion tuples of the form...
 # (bits / bytes / seconds, short label, long label)
 SIZE_UNITS_BITS = (
@@ -44,6 +47,31 @@ TIME_UNITS = (
   (1.0, "s", " second"),
 )
 
+if stem.prereq.is_python_3():
+  import codecs
+
+  def _to_bytes(msg):
+    return codecs.latin_1_encode(msg)[0]
+else:
+  def _to_bytes(msg):
+    return msg
+
+
+def to_bytes(msg):
+  """
+  Provides the ASCII bytes for the given string. This is purely to provide
+  python 3 compatability, normalizing the unicode/ASCII change in the version
+  bump. For an explanation of this see...
+
+  http://python3porting.com/problems.html#nicer-solutions
+
+  :param msg label: string to be converted
+
+  :returns: ASCII bytes for string
+  """
+
+  return _to_bytes(msg)
+
 
 def to_camel_case(label, divider = "_", joiner = " "):
   """
diff --git a/test/settings.cfg b/test/settings.cfg
index 66475ee..4d99bfe 100644
--- a/test/settings.cfg
+++ b/test/settings.cfg
@@ -157,6 +157,7 @@ pyflakes.ignore stem/prereq.py => 'RSA' imported but unused
 pyflakes.ignore stem/prereq.py => 'asn1' imported but unused
 pyflakes.ignore stem/prereq.py => 'long_to_bytes' imported but unused
 pyflakes.ignore stem/descriptor/__init__.py => redefinition of unused 'OrderedDict' from line 32
+pyflakes.ignore stem/util/str_tools.py => redefinition of function '_to_bytes' from line 53
 pyflakes.ignore test/mocking.py => undefined name 'builtins'
 pyflakes.ignore test/unit/response/events.py => 'from stem import *' used; unable to detect undefined names
 





More information about the tor-commits mailing list