Skip to content

Commit c196302

Browse files
committed
py3 compat
1 parent 340c39c commit c196302

18 files changed

Lines changed: 133 additions & 138 deletions

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ clean_sdist:
6969

7070
.PHONY: test
7171
test: _check_venv
72-
$(python) setup.py test --pytest-args "-vv --assert=plain $(tests)"
72+
$(python) setup.py test --addopts "-vv --assert=plain --continue-on-collection-errors $(tests)"
7373

7474

7575
.PHONY: pypi

pytest.ini

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
[pytest]
2+
# Look for any python file, the default of test_*.py wouldn't work for us
3+
python_files=*.py
4+
# Run doctests and start test collection in the src dir
5+
addopts = --doctest-modules

setup.cfg

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,2 @@
1-
[pytest]
2-
# Look for any python file, the default of test_*.py wouldn't work for us
3-
python_files=*.py
4-
# Run doctests and start test collection in the src dir
5-
addopts = --doctest-modules
1+
[aliases]
2+
test=pytest

setup.py

Lines changed: 2 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -16,36 +16,12 @@
1616
package_dir={ '': 'src' },
1717
packages=find_packages( 'src' ),
1818
install_requires=[ 'future' ],
19+
setup_requires=['pytest-runner'],
1920
tests_require=[
20-
'pytest==2.7.2',
21+
'pytest==3.5.0',
2122
'mock==1.0.1',
2223
'lockfile==0.11.0',
2324
'boto==2.38.0'],
2425
namespace_packages=[ 'bd2k' ] )
2526

26-
from setuptools.command.test import test as TestCommand
27-
28-
29-
class PyTest( TestCommand ):
30-
user_options = [ ('pytest-args=', 'a', "Arguments to pass to py.test") ]
31-
32-
def initialize_options( self ):
33-
TestCommand.initialize_options( self )
34-
self.pytest_args = [ ]
35-
36-
def finalize_options( self ):
37-
TestCommand.finalize_options( self )
38-
self.test_args = [ ]
39-
self.test_suite = True
40-
41-
def run_tests( self ):
42-
import pytest
43-
# Sanitize command line arguments to avoid confusing Toil code attempting to parse them
44-
sys.argv[ 1: ] = [ ]
45-
errno = pytest.main( self.pytest_args )
46-
sys.exit( errno )
47-
48-
49-
kwargs[ 'cmdclass' ] = { 'test': PyTest }
50-
5127
setup( **kwargs )

src/bd2k/util/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,8 @@ def ilen( it ):
109109
"""
110110
Return the number of elements in an iterable
111111
112-
>>> ilen(xrange(0,100))
112+
>>> from builtins import range
113+
>>> ilen(range(0,100))
113114
100
114115
"""
115116
return sum( 1 for _ in it )

src/bd2k/util/collections.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,8 @@ def rindex( l, v ):
152152
2
153153
>>> rindex( (0,1,0,1), 0 )
154154
2
155-
>>> rindex( xrange(3), 2 )
155+
>>> from builtins import range
156+
>>> rindex( range(3), 2 )
156157
2
157158
"""
158159
try:

src/bd2k/util/d32.py

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@
1717
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1818

1919
# Inspired by Dominic Tarr's JavaScript at https://github.com/dominictarr/d64
20-
20+
import codecs
21+
import sys
2122
from builtins import range
2223
from builtins import object
2324
from past.utils import old_div
@@ -28,23 +29,23 @@ class D32( object ):
2829

2930
def __init__( self, alphabet ):
3031
super( D32, self ).__init__( )
31-
self.alphabet = bytearray( alphabet )
32+
self.alphabet = bytearray( alphabet.encode('utf-8') )
3233
self.lookup = bytearray( 255 )
3334
for i in range( 32 ):
3435
self.lookup[ self.alphabet[ i ] ] = i
3536

3637
def encode( self, d ):
3738
"""
3839
>>> encode = standard.encode
39-
>>> encode('')
40+
>>> encode(b'') # doctest: +ALLOW_UNICODE
4041
''
41-
>>> encode('\\0')
42+
>>> encode(b'\\0') # doctest: +ALLOW_UNICODE
4243
'22'
43-
>>> encode('\\xff')
44+
>>> encode(b'\\xff') # doctest: +ALLOW_UNICODE
4445
'zw'
45-
>>> encode('\\0\\1\\2\\3\\4')
46+
>>> encode(b'\\0\\1\\2\\3\\4') # doctest: +ALLOW_UNICODE
4647
'222k62s6'
47-
>>> encode('\\0\\1\\2\\3\\4\\5')
48+
>>> encode(b'\\0\\1\\2\\3\\4\\5') # doctest: +ALLOW_UNICODE
4849
'222k62s62o'
4950
"""
5051
m = len( d )
@@ -56,7 +57,7 @@ def encode( self, d ):
5657

5758
while i < m:
5859
if m - i < 5:
59-
g = bytearray( d[ i: ] + '\0' * (5 - (m - i)) )
60+
g = bytearray( d[ i: ] + b'\0' * (5 - (m - i)))
6061
else:
6162
g = bytearray( d[ i:i + 5 ] )
6263
# bit 1 2 3
@@ -73,17 +74,18 @@ def encode( self, d ):
7374
e[ j + 7 ] = a[ g[ 4 ] & 31 ]
7475
j += 8
7576
i += 5
76-
return str( e[ :-padding ] )
77+
return codecs.decode( e[ :-padding ], 'ASCII' )
7778

7879
def decode( self, e ):
7980
"""
81+
>>> import codecs
8082
>>> decode = standard.decode
8183
8284
# >>> decode('222k62s62o')
8385
# '\\x00\\x01\\x02\\x03\\x04\\x05'
8486
# >>> decode('222k62s6')
8587
# '\\x00\\x01\\x02\\x03\\x04'
86-
>>> decode('zw')
88+
>>> codecs.decode(decode('zw'), 'unicode-escape') # # doctest: +ALLOW_UNICODE
8789
'\\xff'
8890
"""
8991
n = len( e )
@@ -108,7 +110,8 @@ def decode( self, e ):
108110
d[ i + 4 ] = g[ 6 ] << 5 & 255 | g[ 7 ]
109111
j += 8
110112
i += 5
111-
return str( d[ :-padding ] )
113+
114+
return bytes(d[ :-padding ])
112115

113116

114117
# A variant of Base64 that maintains the lexicographical ordering such that for any given list of

src/bd2k/util/d64.py

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,17 @@
1919

2020
# Ported from JS found at https://github.com/dominictarr/d64
2121

22-
23-
22+
import codecs
23+
from builtins import bytes
2424
from builtins import range
2525
from builtins import object
2626
from past.utils import old_div
27+
2728
class D64( object ):
2829
def __init__( self, special_chars ):
2930
super( D64, self ).__init__( )
3031
alphabet = 'PYFGCRLAOEUIDHTNSQJKXBMWVZpyfgcrlaoeuidhtnsqjkxbmwvz1234567890'
31-
self.alphabet = bytearray( sorted( alphabet + special_chars ) )
32+
self.alphabet = bytearray( str(''.join(sorted( alphabet + special_chars))).encode( 'utf-8' ))
3233
self.lookup = bytearray( 255 )
3334
for i in range( 64 ):
3435
code = self.alphabet[ i ]
@@ -37,24 +38,25 @@ def __init__( self, special_chars ):
3738
def encode( self, data ):
3839
"""
3940
>>> encode = standard.encode
40-
>>> encode('')
41+
>>> encode(b'') # doctest: +ALLOW_UNICODE
4142
''
42-
>>> encode('\\x00')
43+
>>> encode(b'\\x00') # doctest: +ALLOW_UNICODE
4344
'..'
44-
>>> encode('\\x00\\x01')
45+
>>> encode(b'\\x00\\x01') # doctest: +ALLOW_UNICODE
4546
'..3'
46-
>>> encode('\\x00\\x01\\x02')
47+
>>> encode(b'\\x00\\x01\\x02') # doctest: +ALLOW_UNICODE
4748
'..31'
48-
>>> encode('\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07')
49+
>>> encode(b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07') # doctest: +ALLOW_UNICODE
4950
'..31.kF40VR'
5051
"""
52+
data = bytes( data )
5153
l = len( data )
5254
s = bytearray( old_div((l * 4 + 2), 3) )
5355
hang = 0
5456
j = 0
5557
a = self.alphabet
5658
for i in range( l ):
57-
v = ord( data[ i ] )
59+
v = data[ i ]
5860
r = i % 3
5961
if r == 0:
6062
s[ j ] = a[ v >> 2 ]
@@ -75,20 +77,21 @@ def encode( self, data ):
7577
if l % 3:
7678
s[ j ] = a[ hang ]
7779

78-
return str( s )
80+
return codecs.decode( s )
7981

8082
def decode( self, e ):
8183
"""
84+
>>> import codecs
8285
>>> decode = standard.decode
83-
>>> decode('')
86+
>>> codecs.decode(decode(''), 'unicode-escape') # doctest: +ALLOW_UNICODE
8487
''
85-
>>> decode('..')
88+
>>> codecs.decode(decode('..'), 'unicode-escape') # doctest: +ALLOW_UNICODE
8689
'\\x00'
87-
>>> decode('..3')
90+
>>> codecs.decode(decode('..3'), 'unicode-escape') # doctest: +ALLOW_UNICODE
8891
'\\x00\\x01'
89-
>>> decode('..31')
92+
>>> codecs.decode(decode('..31'), 'unicode-escape') # doctest: +ALLOW_UNICODE
9093
'\\x00\\x01\\x02'
91-
>>> decode('..31.kF40VR')
94+
>>> codecs.decode(decode('..31.kF40VR'), 'unicode-escape') # doctest: +ALLOW_UNICODE
9295
'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07'
9396
"""
9497
n = len( e )
@@ -115,7 +118,7 @@ def decode( self, e ):
115118
j += 1
116119
else:
117120
assert False
118-
return str( b )
121+
return bytes(b)
119122

120123

121124
standard = D64( '._' )

src/bd2k/util/exceptions.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from future.utils import raise_
12
from builtins import object
23
from contextlib import contextmanager
34
import sys
@@ -35,7 +36,7 @@ def __exit__( self, *exc_info ):
3536
if self.log is not None and exc_info and exc_info[ 0 ]:
3637
self.log.warn( "Exception during panic", exc_info=exc_info )
3738
exc_type, exc_value, traceback = self.exc_info
38-
raise exc_type, exc_value, traceback
39+
raise_(exc_type, exc_value, traceback)
3940

4041

4142
class RequirementError( Exception ):
@@ -61,17 +62,17 @@ def require( value, message, *message_args ):
6162
6263
>>> require(1 + 1 == 2, 'You made a terrible mistake')
6364
64-
>>> require(1 + 1 == 3, 'You made a terrible mistake')
65+
>>> require(1 + 1 == 3, 'You made a terrible mistake') # doctest: +IGNORE_EXCEPTION_DETAIL
6566
Traceback (most recent call last):
6667
...
6768
RequirementError: You made a terrible mistake
6869
69-
>>> require(1 + 1 == 3, 'You made a terrible mistake, %s', 'you fool')
70+
>>> require(1 + 1 == 3, 'You made a terrible mistake, %s', 'you fool') # doctest: +IGNORE_EXCEPTION_DETAIL
7071
Traceback (most recent call last):
7172
...
7273
RequirementError: You made a terrible mistake, you fool
7374
74-
>>> require(1 + 1 == 3, 'You made a terrible mistake, %s %s', 'your', 'majesty')
75+
>>> require(1 + 1 == 3, 'You made a terrible mistake, %s %s', 'your', 'majesty') # doctest: +IGNORE_EXCEPTION_DETAIL
7576
Traceback (most recent call last):
7677
...
7778
RequirementError: You made a terrible mistake, your majesty

src/bd2k/util/expando.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,11 @@ class Expando(dict):
2424
>>> import json
2525
>>> s='{"foo":42}'
2626
>>> o = json.loads(s,object_hook=Expando)
27-
>>> o
28-
{u'foo': 42}
2927
>>> o.foo
3028
42
3129
>>> o.bar = 'hi'
32-
>>> o
33-
{u'foo': 42, 'bar': 'hi'}
30+
>>> o.bar
31+
'hi'
3432
3533
And since Expando is a dict, it serializes back to JSON just fine:
3634

0 commit comments

Comments
 (0)