Skip to content

Commit 5e0fba3

Browse files
committed
Port source code back to Python 2
1 parent 76e2734 commit 5e0fba3

File tree

4 files changed

+51
-8
lines changed

4 files changed

+51
-8
lines changed

multiaddr/codec.py

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
import idna
77
from netaddr import IPAddress
8+
import six
89

910
from .protocols import code_to_varint
1011
from .protocols import P_DNS
@@ -24,6 +25,23 @@
2425
from .protocols import read_varint_code
2526

2627

28+
if hasattr(os, "fsencode") and hasattr(os, "fsdecode"):
29+
fsencode = os.fsencode
30+
fsdecode = os.fsdecode
31+
else: # PY2
32+
import sys
33+
34+
def fsencode(path):
35+
if not isinstance(path, six.binary_type):
36+
path = path.encode(sys.getfilesystemencoding())
37+
return path
38+
39+
def fsdecode(path):
40+
if not isinstance(path, six.text_type):
41+
path = path.decode(sys.getfilesystemencoding())
42+
return path
43+
44+
2745
def string_to_bytes(string):
2846
if not string:
2947
return b''
@@ -150,6 +168,8 @@ def address_string_to_bytes(proto, addr_string):
150168
elif proto.code == P_P2P: # ipfs
151169
# the address is a varint prefixed multihash string representation
152170
try:
171+
if six.PY2 and isinstance(addr_string, unicode):
172+
addr_string = addr_string.encode("ascii")
153173
mm = base58.b58decode(addr_string)
154174
except Exception as ex:
155175
raise ValueError("failed to parse p2p addr: %s %s"
@@ -161,7 +181,7 @@ def address_string_to_bytes(proto, addr_string):
161181
raise ValueError("invalid P2P multihash: %s" % mm)
162182
return b''.join([size, mm])
163183
elif proto.code == P_UNIX:
164-
addr_string_bytes = os.fsencode(addr_string)
184+
addr_string_bytes = fsencode(addr_string)
165185
size = code_to_varint(len(addr_string_bytes))
166186
return b''.join([size, binascii.hexlify(addr_string_bytes)])
167187
elif proto.code in (P_DNS, P_DNS4, P_DNS6):
@@ -201,7 +221,7 @@ def address_bytes_to_string(proto, buf):
201221
elif proto.code == P_UNIX:
202222
buf = binascii.unhexlify(buf)
203223
size, num_bytes_read = read_varint_code(buf)
204-
return os.fsdecode(buf[num_bytes_read:])
224+
return fsdecode(buf[num_bytes_read:])
205225
elif proto.code in (P_DNS, P_DNS4, P_DNS6):
206226
buf = binascii.unhexlify(buf)
207227
size, num_bytes_read = read_varint_code(buf)

multiaddr/multiaddr.py

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
import binascii
33
from copy import copy
44

5+
import six
6+
57
from .codec import size_for_addr
68
from .codec import string_to_bytes
79
from .codec import bytes_to_string
@@ -37,9 +39,16 @@ def __init__(self, addr):
3739
addr : A string-encoded or a byte-encoded Multiaddr
3840
3941
"""
40-
if isinstance(addr, str):
42+
# On Python 2 text string will often be binary anyways so detect the
43+
# obvious case of a “binary-encoded” multiaddr starting with a slash
44+
# and decode it into text
45+
if six.PY2 and isinstance(addr, str) and addr.startswith("/"):
46+
import locale
47+
addr = addr.decode(locale.getpreferredencoding())
48+
49+
if isinstance(addr, six.text_type):
4150
self._bytes = string_to_bytes(addr)
42-
elif isinstance(addr, bytes):
51+
elif isinstance(addr, six.binary_type):
4352
self._bytes = addr
4453
else:
4554
raise ValueError("Invalid address type, must be bytes or str")
@@ -62,6 +71,16 @@ def __str__(self):
6271
raise ValueError(
6372
"multiaddr failed to convert back to string. corrupted?")
6473

74+
# On Python 2 __str__ needs to return binary text, so expose the original
75+
# function as __unicode__ and transparently encode its returned text based
76+
# on the current locale
77+
if six.PY2:
78+
__unicode__ = __str__
79+
80+
def __str__(self):
81+
import locale
82+
return self.__unicode__().encode(locale.getpreferredencoding())
83+
6584
def __repr__(self):
6685
return "<Multiaddr %s>" % str(self)
6786

tests/test_codec.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
# -*- encoding: utf-8 -*-
12
import pytest
23

34
from multiaddr.codec import address_bytes_to_string
@@ -27,10 +28,10 @@
2728
# Additional test data
2829
(_names_to_protocols['dns4'],
2930
b'30786e2d2d34676272696d2e786e2d2d2d2d796d63626161616a6c6336646a3762786e6532632e786e2d2d776762683163',
30-
u'موقع.وزارة-الاتصالات.مصر'), # Explicietly mark as unicode to force it LTR
31+
u'موقع.وزارة-الاتصالات.مصر'), # Explicietly mark this as unicode to force the text to be LTR in editors
3132
(_names_to_protocols['dns4'],
3233
b'16786e2d2d667562616c6c2d6374612e6578616d706c65',
33-
'fußball.example'), # This will fail if IDNA-2003/NamePrep is used
34+
u'fußball.example'), # This will fail if IDNA-2003/NamePrep is used
3435
]
3536

3637
BYTES_MAP_STR_TEST_DATA = [

tests/test_multiaddr.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
#!/usr/bin/env python
22
# -*- coding: utf-8 -*-
3+
from __future__ import unicode_literals
4+
35
import pytest
6+
import six
47

58
from multiaddr.multiaddr import Multiaddr
69
from multiaddr.multiaddr import ProtocolNotFoundException
@@ -89,7 +92,7 @@ def test_invalid(addr_str):
8992
"/dns4/موقع.وزارة-الاتصالات.مصر"]) # nopep8
9093
def test_valid(addr_str):
9194
ma = Multiaddr(addr_str)
92-
assert str(ma) == addr_str.rstrip("/")
95+
assert six.text_type(ma) == addr_str.rstrip("/")
9396

9497

9598
def test_eq():
@@ -250,7 +253,7 @@ def test_get_value_too_many_fields_protocol(monkeypatch):
250253
that the constructor specifies is ignored by the test.
251254
"""
252255
monkeypatch.setattr("multiaddr.multiaddr.Multiaddr.__str__",
253-
lambda ignore: '/udp/1234/5678')
256+
lambda ignore: str('/udp/1234/5678'))
254257
a = Multiaddr("/ip4/127.0.0.1/udp/1234")
255258
with pytest.raises(ValueError):
256259
a.value_for_protocol(P_UDP)

0 commit comments

Comments
 (0)