Skip to content

Commit abb191f

Browse files
committed
Fix and add more tests of futurize with encoding comments (issues #97 and #10)
1 parent ea484c1 commit abb191f

File tree

2 files changed

+70
-15
lines changed

2 files changed

+70
-15
lines changed

src/libfuturize/fixer_util.py

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -196,13 +196,13 @@ def future_import(feature, node):
196196
if does_tree_import(u"__future__", feature, node):
197197
return
198198

199-
# Look for a shebang line
200-
shebang_idx = None
199+
# Look for a shebang or encoding line
200+
shebang_encoding_idx = None
201201

202202
for idx, node in enumerate(root.children):
203-
# If it's a shebang line, attach the prefix to
204-
if is_shebang_comment(node):
205-
shebang_idx = idx
203+
# If it's a shebang or encoding line, attach the prefix to
204+
if is_shebang_comment(node) or is_encoding_comment(node):
205+
shebang_encoding_idx = idx
206206
if node.type == syms.simple_stmt and \
207207
len(node.children) > 0 and node.children[0].type == token.STRING:
208208
# skip over docstring
@@ -216,9 +216,9 @@ def future_import(feature, node):
216216
return
217217

218218
import_ = FromImport(u'__future__', [Leaf(token.NAME, feature, prefix=" ")])
219-
if shebang_idx == 0 and idx == 0:
219+
if shebang_encoding_idx == 0 and idx == 0:
220220
# If this __future__ import would go on the first line,
221-
# detach the shebang prefix from the current first line
221+
# detach the shebang / encoding prefix from the current first line
222222
# and attach it to our new __future__ import node.
223223
import_.prefix = root.children[0].prefix
224224
root.children[0].prefix = u''
@@ -424,16 +424,34 @@ def check_future_import(node):
424424
assert False, "strange import: %s" % savenode
425425

426426

427-
SHEBANG_REGEX = r'^#!\s*.*python'
427+
SHEBANG_REGEX = r'^#!.*python'
428+
ENCODING_REGEX = r"^#.*coding[:=]\s*([-\w.]+)"
429+
428430

429431
def is_shebang_comment(node):
430432
"""
431433
Comments are prefixes for Leaf nodes. Returns whether the given node has a
432-
prefix that looks like a shebang line.
434+
prefix that looks like a shebang line or an encoding line:
435+
436+
#!/usr/bin/env python
437+
#!/usr/bin/python3
433438
"""
434439
return bool(re.match(SHEBANG_REGEX, node.prefix))
435440

436441

442+
def is_encoding_comment(node):
443+
"""
444+
Comments are prefixes for Leaf nodes. Returns whether the given node has a
445+
prefix that looks like an encoding line:
446+
447+
# coding: utf-8
448+
# encoding: utf-8
449+
# -*- coding: <encoding name> -*-
450+
# vim: set fileencoding=<encoding name> :
451+
"""
452+
return bool(re.match(ENCODING_REGEX, node.prefix))
453+
454+
437455
def wrap_in_fn_call(fn_name, args, prefix=None):
438456
"""
439457
Example:

tests/test_future/test_futurize.py

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from subprocess import Popen, PIPE
77
import os
88

9-
from libfuturize.fixer_util import is_shebang_comment
9+
from libfuturize.fixer_util import is_shebang_comment, is_encoding_comment
1010
from lib2to3.fixer_util import FromImport
1111
from lib2to3.pytree import Leaf, Node
1212
from lib2to3.pygram import token
@@ -19,11 +19,48 @@
1919
class TestLibFuturize(unittest.TestCase):
2020
def test_is_shebang_comment(self):
2121
"""
22-
Tests whether the libfuturize.fixer_util.is_shebang_comment() function is working
23-
"""
24-
node = FromImport(u'math', [Leaf(token.NAME, u'cos', prefix=" ")])
25-
node.prefix = u'#!/usr/bin/env python\n'
26-
self.assertTrue(is_shebang_comment(node))
22+
Tests whether the fixer_util.is_encoding_comment() function is working.
23+
"""
24+
shebang_comments = [u'#!/usr/bin/env python\n'
25+
u"#!/usr/bin/python2\n",
26+
u"#! /usr/bin/python3\n",
27+
]
28+
not_shebang_comments = [u"# I saw a giant python\n",
29+
u"# I have never seen a python2\n",
30+
]
31+
for comment in shebang_comments:
32+
node = FromImport(u'math', [Leaf(token.NAME, u'cos', prefix=" ")])
33+
node.prefix = comment
34+
self.assertTrue(is_shebang_comment(node))
35+
36+
for comment in not_shebang_comments:
37+
node = FromImport(u'math', [Leaf(token.NAME, u'cos', prefix=" ")])
38+
node.prefix = comment
39+
self.assertFalse(is_shebang_comment(node))
40+
41+
42+
def test_is_encoding_comment(self):
43+
"""
44+
Tests whether the fixer_util.is_encoding_comment() function is working.
45+
"""
46+
encoding_comments = [u"# coding: utf-8",
47+
u"# encoding: utf-8",
48+
u"# -*- coding: latin-1 -*-",
49+
u"# vim: set fileencoding=iso-8859-15 :",
50+
]
51+
not_encoding_comments = [u"# We use the file encoding utf-8",
52+
u"coding = 'utf-8'",
53+
u"encoding = 'utf-8'",
54+
]
55+
for comment in encoding_comments:
56+
node = FromImport(u'math', [Leaf(token.NAME, u'cos', prefix=" ")])
57+
node.prefix = comment
58+
self.assertTrue(is_encoding_comment(node))
59+
60+
for comment in not_encoding_comments:
61+
node = FromImport(u'math', [Leaf(token.NAME, u'cos', prefix=" ")])
62+
node.prefix = comment
63+
self.assertFalse(is_encoding_comment(node))
2764

2865

2966
class TestFuturizeSimple(CodeHandler):

0 commit comments

Comments
 (0)