Commit 6c728fb8 by Ned Batchelder

Make it work on Python 3

parent c5745631
"""Check that getattr and setattr aren't being used with literal attribute names.""" """Check that getattr and setattr aren't being used with literal attribute names."""
import six
import astroid import astroid
from pylint.checkers import BaseChecker, utils from pylint.checkers import BaseChecker, utils
...@@ -49,7 +51,7 @@ class GetSetAttrLiteralChecker(BaseChecker): ...@@ -49,7 +51,7 @@ class GetSetAttrLiteralChecker(BaseChecker):
second = node.args[1] second = node.args[1]
if isinstance(second, astroid.Const): if isinstance(second, astroid.Const):
if isinstance(second.value, basestring): if isinstance(second.value, six.string_types):
# The first argument is a constant string! Bad! # The first argument is a constant string! Bad!
self.add_message(self.MESSAGE_ID, args=node.func.name, node=node) self.add_message(self.MESSAGE_ID, args=node.func.name, node=node)
......
import six
import astroid import astroid
from pylint.checkers import BaseChecker, utils from pylint.checkers import BaseChecker, utils
...@@ -51,7 +53,7 @@ class TranslationStringConstantsChecker(BaseChecker): ...@@ -51,7 +53,7 @@ class TranslationStringConstantsChecker(BaseChecker):
first = node.args[0] first = node.args[0]
if isinstance(first, astroid.Const): if isinstance(first, astroid.Const):
if isinstance(first.value, basestring): if isinstance(first.value, six.string_types):
# The first argument is a constant string! All is well! # The first argument is a constant string! All is well!
return return
......
...@@ -15,7 +15,7 @@ class TamperEvidentFile(object): ...@@ -15,7 +15,7 @@ class TamperEvidentFile(object):
def __init__(self, filename): def __init__(self, filename):
self.filename = filename self.filename = filename
def write(self, text, hashline="# {}"): def write(self, text, hashline=b"# {}"):
""" """
Write `text` to the file. Write `text` to the file.
...@@ -25,16 +25,22 @@ class TamperEvidentFile(object): ...@@ -25,16 +25,22 @@ class TamperEvidentFile(object):
The last line is written with the `hashline` format string, which can The last line is written with the `hashline` format string, which can
be changed to accommodate different file syntaxes. be changed to accommodate different file syntaxes.
Arguments:
text (byte string): the contents of the file to write.
hashline (byte string): the format of the last line to append to
the file, with "{}" replaced with the hash.
""" """
if not text.endswith("\n"): if not text.endswith(b"\n"):
text += "\n" text += b"\n"
hash = hashlib.sha1(text).hexdigest() hash = hashlib.sha1(text).hexdigest()
with open(self.filename, "w") as f: with open(self.filename, "wb") as f:
f.write(text) f.write(text)
f.write(hashline.format(hash)) f.write(hashline.decode("ascii").format(hash).encode("ascii"))
f.write("\n") f.write(b"\n")
def validate(self): def validate(self):
""" """
...@@ -44,18 +50,18 @@ class TamperEvidentFile(object): ...@@ -44,18 +50,18 @@ class TamperEvidentFile(object):
with. with.
""" """
with open(self.filename, "r") as f: with open(self.filename, "rb") as f:
text = f.read() text = f.read()
start_last_line = text.rfind("\n", 0, -1) start_last_line = text.rfind(b"\n", 0, -1)
if start_last_line == -1: if start_last_line == -1:
return False return False
original_text = text[:start_last_line+1] original_text = text[:start_last_line+1]
last_line = text[start_last_line+1:] last_line = text[start_last_line+1:]
expected_hash = hashlib.sha1(original_text).hexdigest() expected_hash = hashlib.sha1(original_text).hexdigest().encode("ascii")
match = re.search(r"[0-9a-f]{40}", last_line) match = re.search(br"[0-9a-f]{40}", last_line)
if not match: if not match:
return False return False
actual_hash = match.group(0) actual_hash = match.group(0)
......
...@@ -2,7 +2,11 @@ ...@@ -2,7 +2,11 @@
# pylint: disable=missing-docstring # pylint: disable=missing-docstring
from string import lower as _, upper as gettext def _(text):
return text
def gettext(text):
return text
def welcome(name): def welcome(name):
_("Hello"+"There") _("Hello"+"There")
......
"""No-op file to see a test run."""
print "Hello, world!"
"""These are all good uses of _()""" """These are all good uses of _()"""
from string import lower as _ def _(text):
"""A dummy _() to use."""
return text
_("Hello") _("Hello")
......
"""Good uses of range.""" """Good uses of range."""
import six
if six.PY3:
def xrange(*args_unused): # pylint: disable=unused-argument, redefined-builtin
"""Just to keep PY3 happy."""
i = 2 i = 2
range(10) range(10)
......
"""Bad uses of range().""" """Bad uses of range()."""
import six
if six.PY3:
def xrange(*args_unused): # pylint: disable=unused-argument, redefined-builtin
"""Just to keep PY3 happy."""
i = 12 i = 12
range(0, 10) range(0, 10)
......
E: 8:welcome: i18n function _() must be called with a literal string E: 12:welcome: i18n function _() must be called with a literal string
E: 9:welcome: i18n function _() must be called with a literal string E: 13:welcome: i18n function _() must be called with a literal string
E: 10:welcome: i18n function _() must be called with a literal string E: 14:welcome: i18n function _() must be called with a literal string
E: 14:welcome: i18n function gettext() must be called with a literal string E: 18:welcome: i18n function gettext() must be called with a literal string
C: 5: range() call could be single-argument C: 11: range() call could be single-argument
C: 6: range() call could be single-argument C: 12: range() call could be single-argument
C: 7: range() call could be single-argument
C: 8: xrange() call could be single-argument
C: 13: range() call could be single-argument C: 13: range() call could be single-argument
C: 14: xrange() call could be single-argument
C: 19: range() call could be single-argument
...@@ -23,60 +23,60 @@ class TamperEvidentFileTest(unittest.TestCase): ...@@ -23,60 +23,60 @@ class TamperEvidentFileTest(unittest.TestCase):
def test_writing(self): def test_writing(self):
# The contents are written, with a hash. # The contents are written, with a hash.
# Different contents produce different hashes. # Different contents produce different hashes.
filename1 = self.write_tamper_evident("Hello!") filename1 = self.write_tamper_evident(b"Hello!")
with open(filename1) as f: with open(filename1, "rb") as f:
self.assertEqual( self.assertEqual(
f.read(), f.read(),
"Hello!\n# a8d191538209e335154750d2df575b9ddfb16fc7\n" b"Hello!\n# a8d191538209e335154750d2df575b9ddfb16fc7\n"
) )
filename2 = self.write_tamper_evident("Hello?") filename2 = self.write_tamper_evident(b"Hello?")
with open(filename2) as f: with open(filename2, "rb") as f:
self.assertEqual( self.assertEqual(
f.read(), f.read(),
"Hello?\n# 4820175d44ef1a2c92e52bd1b3b7f05020d66e1c\n" b"Hello?\n# 4820175d44ef1a2c92e52bd1b3b7f05020d66e1c\n"
) )
def test_hashline_formatting(self): def test_hashline_formatting(self):
filename1 = self.write_tamper_evident("Hello!", hashline="XXX {} YYY") filename1 = self.write_tamper_evident(b"Hello!", hashline=b"XXX {} YYY")
with open(filename1) as f: with open(filename1, "rb") as f:
self.assertEqual( self.assertEqual(
f.read(), f.read(),
"Hello!\nXXX a8d191538209e335154750d2df575b9ddfb16fc7 YYY\n" b"Hello!\nXXX a8d191538209e335154750d2df575b9ddfb16fc7 YYY\n"
) )
def test_validating_a_good_file(self): def test_validating_a_good_file(self):
filename = self.write_tamper_evident("Am I OK?") filename = self.write_tamper_evident(b"Am I OK?")
tef = TamperEvidentFile(filename) tef = TamperEvidentFile(filename)
self.assertTrue(tef.validate()) self.assertTrue(tef.validate())
def test_appending_is_detected(self): def test_appending_is_detected(self):
filename = self.write_tamper_evident("Am I OK?") filename = self.write_tamper_evident(b"Am I OK?")
with open(filename, "a") as f: with open(filename, "ab") as f:
f.write("tamper\n") f.write(b"tamper\n")
tef = TamperEvidentFile(filename) tef = TamperEvidentFile(filename)
self.assertFalse(tef.validate()) self.assertFalse(tef.validate())
def test_editing_is_detected(self): def test_editing_is_detected(self):
filename = self.write_tamper_evident("Line 1\nLine 2\nLine 3\n") filename = self.write_tamper_evident(b"Line 1\nLine 2\nLine 3\n")
with open(filename, "r") as f: with open(filename, "rb") as f:
text = f.read() text = f.read()
with open(filename, "w") as f: with open(filename, "wb") as f:
f.write("X") f.write(b"X")
f.write(text[1:]) f.write(text[1:])
tef = TamperEvidentFile(filename) tef = TamperEvidentFile(filename)
self.assertFalse(tef.validate()) self.assertFalse(tef.validate())
def test_oneline_file_is_detected(self): def test_oneline_file_is_detected(self):
filename = self.write_tamper_evident("Am I OK?") filename = self.write_tamper_evident(b"Am I OK?")
with open(filename, "w") as f: with open(filename, "wb") as f:
f.write("tamper") f.write(b"tamper")
tef = TamperEvidentFile(filename) tef = TamperEvidentFile(filename)
self.assertFalse(tef.validate()) self.assertFalse(tef.validate())
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment