Skip to content

Commit ab05ddd

Browse files
committed
python3 (only) support
rkern/grin#1 and rkern/grin#4
1 parent 286726b commit ab05ddd

File tree

8 files changed

+127
-128
lines changed

8 files changed

+127
-128
lines changed

examples/grin

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#!/usr/bin/env python
1+
#!/usr/bin/env python3
22
# NOTE: You may have to adjust the line above to specify the precise python
33
# executable that has the grin module installed.
44
import grin

examples/grind

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#!/usr/bin/env python
1+
#!/usr/bin/env python3
22
# NOTE: You may have to adjust the line above to specify the precise python
33
# executable that has the grin module installed.
44
import grin

examples/grinimports.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
#!/usr/bin/env python
2-
# -*- coding: UTF-8 -*-
3-
""" Transform Python files into normalized import statements for grepping.
1+
#!/usr/bin/env python3
2+
"""
3+
Transform Python files into normalized import statements for grepping.
44
"""
55

66
import compiler
77
from compiler.visitor import ASTVisitor, walk
8-
from cStringIO import StringIO
8+
from io import StringIO
99
import os
1010
import shlex
1111
import sys
@@ -70,7 +70,7 @@ def normalize_file(filename, *args):
7070
"""
7171
try:
7272
ast = compiler.parseFile(filename)
73-
except Exception, e:
73+
except:
7474
return StringIO('')
7575
ip = ImportPuller()
7676
walk(ast, ip)

examples/grinpython.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
#!/usr/bin/env python
2-
# -*- coding: UTF-8 -*-
3-
""" Transform Python code by omitting strings, comments, and/or code.
1+
#!/usr/bin/env python3
2+
"""
3+
Transform Python code by omitting strings, comments, and/or code.
44
"""
55

6-
from cStringIO import StringIO
6+
from io import BytesIO
77
import os
88
import shlex
99
import string
@@ -55,7 +55,7 @@ def __call__(self, filename, mode='rb'):
5555
""" Open a file and convert it to a filelike object with transformed
5656
contents.
5757
"""
58-
g = StringIO()
58+
g = BytesIO()
5959
f = open(filename, mode)
6060
try:
6161
gen = tokenize.generate_tokens(f.readline)

grin.py

Lines changed: 29 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
#!/usr/bin/env python
2-
""" grin searches text files.
1+
#!/usr/bin/env python3
2+
"""
3+
grin searches text files.
34
"""
45

56
import argparse
@@ -12,6 +13,7 @@
1213
import shlex
1314
import stat
1415
import sys
16+
from io import UnsupportedOperation
1517

1618
# Constants
1719
__version__ = '1.2.1'
@@ -22,17 +24,18 @@
2224
POST = 1
2325

2426
# Use file(1)'s choices for what's text and what's not.
25-
TEXTCHARS = ''.join(map(chr, [7, 8, 9, 10, 12, 13, 27] + range(0x20, 0x100)))
26-
ALLBYTES = ''.join(map(chr, range(256)))
27+
TEXTCHARS = bytes([7,8,9,10,12,13,27] + list(range(0x20, 0x100)))
28+
ALLBYTES = bytes(range(256))
2729

2830
COLOR_TABLE = ['black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white', 'default']
2931
COLOR_STYLE = {
3032
'filename': dict(fg="green", bold=True),
3133
'searchterm': dict(fg="black", bg="yellow"),
3234
}
35+
to_str = lambda s : s.decode('latin1')
3336

3437
# gzip magic header bytes.
35-
GZIP_MAGIC = '\037\213'
38+
GZIP_MAGIC = b'\037\213'
3639

3740
# Target amount of data to read into memory at a time.
3841
READ_BLOCKSIZE = 16 * 1024 * 1024
@@ -235,6 +238,10 @@ def read_block_with_context(self, prev, fp, fp_size):
235238
block_main = fp.read(target_io_size)
236239
is_last_block = target_io_size == remaining
237240

241+
if not isinstance(block_main, str):
242+
# python3: ensure string are returned
243+
block_main = block_main.decode("utf-8")
244+
238245
if prev is None:
239246
if is_last_block:
240247
# FAST PATH: the entire file fits into a single block, so we
@@ -279,7 +286,7 @@ def read_block_with_context(self, prev, fp, fp_size):
279286
after_lines = ''.join(after_lines_list)
280287

281288
result = DataBlock(
282-
data=before_lines + curr_block + after_lines,
289+
data=(before_lines + curr_block + after_lines).decode("utf-8"),
283290
start=len(before_lines),
284291
end=len(before_lines) + len(curr_block),
285292
before_count=before_count,
@@ -307,13 +314,15 @@ def do_grep(self, fp):
307314
fp_size = None # gzipped data is usually longer than the file
308315
else:
309316
try:
310-
status = os.fstat(fp.fileno())
317+
file_no = fp.fileno()
318+
except (AttributeError, UnsupportedOperation): # doesn't support fileno()
319+
fp_size = None
320+
else:
321+
status = os.fstat(file_no)
311322
if stat.S_ISREG(status.st_mode):
312323
fp_size = status.st_size
313324
else:
314325
fp_size = None
315-
except AttributeError: # doesn't support fileno()
316-
fp_size = None
317326

318327
block = self.read_block_with_context(None, fp, fp_size)
319328
while block.end > block.start:
@@ -494,8 +503,8 @@ def grep_a_file(self, filename, opener=open):
494503
f = sys.stdin
495504
filename = '<STDIN>'
496505
else:
497-
# 'r' does the right thing for both open ('rt') and gzip.open ('rb')
498-
f = opener(filename, 'r')
506+
# Always open in binary mode
507+
f = opener(filename, 'rb')
499508
try:
500509
unique_context = self.do_grep(f)
501510
finally:
@@ -568,10 +577,8 @@ def is_binary(self, filename):
568577
-------
569578
is_binary : bool
570579
"""
571-
f = open(filename, 'rb')
572-
is_binary = self._is_binary_file(f)
573-
f.close()
574-
return is_binary
580+
with open(filename, 'rb') as fp:
581+
return self._is_binary_file(fp)
575582

576583
def _is_binary_file(self, f):
577584
""" Determine if a given filelike object has binary data or not.
@@ -585,12 +592,12 @@ def _is_binary_file(self, f):
585592
is_binary : bool
586593
"""
587594
try:
588-
bytes = f.read(self.binary_bytes)
595+
data = f.read(self.binary_bytes)
589596
except Exception as e:
590597
# When trying to read from something that looks like a gzipped file,
591598
# it may be corrupt. If we do get an error, assume that the file is binary.
592599
return True
593-
return is_binary_string(bytes)
600+
return is_binary_string(data)
594601

595602
def is_gzipped_text(self, filename):
596603
""" Determine if a given file is a gzip-compressed text file or not.
@@ -607,20 +614,17 @@ def is_gzipped_text(self, filename):
607614
is_gzipped_text : bool
608615
"""
609616
is_gzipped_text = False
610-
f = open(filename, 'rb')
611-
marker = f.read(2)
612-
f.close()
617+
with open(filename, 'rb') as fp:
618+
marker = fp.read(2)
619+
613620
if marker == GZIP_MAGIC:
614-
fp = gzip.open(filename)
615-
try:
621+
with gzip.open(filename) as fp:
616622
try:
617623
is_gzipped_text = not self._is_binary_file(fp)
618624
except IOError:
619625
# We saw the GZIP_MAGIC marker, but it is not actually a gzip
620626
# file.
621627
is_gzipped_text = False
622-
finally:
623-
fp.close()
624628
return is_gzipped_text
625629

626630
def recognize(self, filename):
@@ -1209,10 +1213,6 @@ def grin_main(argv=None):
12091213
raise
12101214

12111215

1212-
def print_line(filename):
1213-
print(filename)
1214-
1215-
12161216
def print_null(filename):
12171217
# Note that the final filename will have a trailing NUL, just like
12181218
# "find -print0" does.
@@ -1233,7 +1233,7 @@ def grind_main(argv=None):
12331233
if args.null_separated:
12341234
output = print_null
12351235
else:
1236-
output = print_line
1236+
output = print
12371237

12381238
if args.sys_path:
12391239
args.dirs.extend(sys.path)

setup.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ with-doctest=1
99
doctest-tests=1
1010

1111
[bdist_wheel]
12-
universal = 1
12+
universal = 0
1313

1414
[metadata]
1515
description-file = README.rst

tests/test_file_recognizer.py

Lines changed: 29 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,22 @@
88
import sys
99

1010
import nose
11+
from grin import FileRecognizer, GZIP_MAGIC
1112

12-
from grin import FileRecognizer
1313

1414
def empty_file(filename, open=open):
1515
f = open(filename, 'wb')
1616
f.close()
1717

1818
def binary_file(filename, open=open):
1919
f = open(filename, 'wb')
20-
f.write(''.join(map(chr, range(256))))
20+
f.write(bytes(range(255)))
2121
f.close()
2222

2323
def text_file(filename, open=open):
24-
lines = ['foo\n', 'bar\n'] * 100
25-
lines.append('baz\n')
26-
lines.extend(['foo\n', 'bar\n'] * 100)
24+
lines = [b'foo\n', b'bar\n'] * 100
25+
lines.append(b'baz\n')
26+
lines.extend([b'foo\n', b'bar\n'] * 100)
2727
f = open(filename, 'wb')
2828
f.writelines(lines)
2929
f.close()
@@ -32,18 +32,17 @@ def fake_gzip_file(filename, open=open):
3232
""" Write out a binary file that has the gzip magic header bytes, but is not
3333
a gzip file.
3434
"""
35-
GZIP_MAGIC = '\037\213'
3635
f = open(filename, 'wb')
3736
f.write(GZIP_MAGIC)
38-
f.write(''.join(map(chr, range(256))))
37+
f.write(bytes(range(255)))
3938
f.close()
4039

4140
def binary_middle(filename, open=open):
4241
""" Write out a file that is text for the first 100 bytes, then 100 binary
4342
bytes, then 100 text bytes to test that the recognizer only reads some of
4443
the file.
4544
"""
46-
text = 'a'*100 + '\0'*100 + 'b'*100
45+
text = b'a'*100 + b'\0'*100 + b'b'*100
4746
f = open(filename, 'wb')
4847
f.write(text)
4948
f.close()
@@ -56,25 +55,25 @@ def unreadable_file(filename):
5655
""" Write a file that does not have read permissions.
5756
"""
5857
text_file(filename)
59-
os.chmod(filename, 0200)
58+
os.chmod(filename, 0o200)
6059

6160
def unreadable_dir(filename):
6261
""" Make a directory that does not have read permissions.
6362
"""
6463
os.mkdir(filename)
65-
os.chmod(filename, 0300)
64+
os.chmod(filename, 0o300)
6665

6766
def unexecutable_dir(filename):
6867
""" Make a directory that does not have execute permissions.
6968
"""
7069
os.mkdir(filename)
71-
os.chmod(filename, 0600)
70+
os.chmod(filename, 0o600)
7271

7372
def totally_unusable_dir(filename):
7473
""" Make a directory that has neither read nor execute permissions.
7574
"""
7675
os.mkdir(filename)
77-
os.chmod(filename, 0100)
76+
os.chmod(filename, 0o100)
7877

7978
def setup():
8079
# Make files to test individual recognizers.
@@ -135,22 +134,22 @@ def setup():
135134
text_file('tree/.skip_hidden_file')
136135
os.mkdir('tree/unreadable_dir')
137136
text_file('tree/unreadable_dir/text')
138-
os.chmod('tree/unreadable_dir', 0300)
137+
os.chmod('tree/unreadable_dir', 0o300)
139138
os.mkdir('tree/unexecutable_dir')
140139
text_file('tree/unexecutable_dir/text')
141-
os.chmod('tree/unexecutable_dir', 0600)
140+
os.chmod('tree/unexecutable_dir', 0o600)
142141
os.mkdir('tree/totally_unusable_dir')
143142
text_file('tree/totally_unusable_dir/text')
144-
os.chmod('tree/totally_unusable_dir', 0100)
143+
os.chmod('tree/totally_unusable_dir', 0o100)
145144

146-
def ensure_deletability(arg, dirname, fnames):
147-
""" os.path.walk() callback function which will make sure every directory is
148-
readable and executable so that it may be easily deleted.
149-
"""
150-
for fn in fnames:
151-
fn = os.path.join(dirname, fn)
152-
if os.path.isdir(fn):
153-
os.chmod(fn, 0700)
145+
#def ensure_deletability(arg, dirname, fnames):
146+
#""" os.path.walk() callback function which will make sure every directory is
147+
#readable and executable so that it may be easily deleted.
148+
#"""
149+
#for fn in fnames:
150+
#fn = os.path.join(dirname, fn)
151+
#if os.path.isdir(fn):
152+
#os.chmod(fn, 0700)
154153

155154
def teardown():
156155
files_to_delete = ['empty', 'binary', 'binary_middle', 'text', 'text~',
@@ -168,10 +167,14 @@ def teardown():
168167
os.unlink(filename)
169168
else:
170169
os.rmdir(filename)
171-
except Exception, e:
172-
print >>sys.stderr, 'Could not delete %s: %s' % (filename, e)
170+
except Exception as e:
171+
print('Could not delete %s: %s' % (filename, e), file=sys.stderr)
173172
os.unlink('socket_test')
174-
os.path.walk('tree', ensure_deletability, None)
173+
# os.path.walk('tree', ensure_deletability, None)
174+
for dirpath, dirnames, filenames in os.walk('tree'):
175+
# Make sure every directory can be deleted
176+
for dirname in dirnames:
177+
os.chmod(os.path.join(dirpath, dirname), 0o700)
175178
shutil.rmtree('tree')
176179

177180

@@ -409,5 +412,3 @@ def test_dot_dot():
409412
]
410413
result = sorted(fr.walk('..'))
411414
assert result == truth
412-
413-

0 commit comments

Comments
 (0)