diff options
author | Darragh Bailey <daragh.bailey@gmail.com> | 2016-10-21 13:57:32 +0100 |
---|---|---|
committer | Darragh Bailey <daragh.bailey@gmail.com> | 2016-11-16 15:10:18 +0000 |
commit | efb5126e67eec5e162bf39f2c828e88dfed25c4e (patch) | |
tree | 125664a71617b4b20abb19767592020160d1ef59 | |
parent | 67dbbc2e59b0b104c9de0a8ab1d39ca54e9845ca (diff) | |
download | git-review-efb5126e67eec5e162bf39f2c828e88dfed25c4e.tar.gz |
Switch to string format to avoid interpolation issues
Convert to using python format to align and interpolate values to
ensure the correct output on python 2 & 3 when dealing with unicode and
str.
Interpolating strings using encode into '%s' and subsequently
interpolating the results into a second string results in the output
printing embedded byte strings on python 3.
$ git-review -l
b'226894' b'master' b'Add pem key parameter (WIP)'
b'199225' b'master' b'support urls as change-id input
Which occurs because after converting a string to unicode bytes, it was
then interpolated using '%s'.
Switching to using '.format()' method takes care of converting the
output to the correct string format for python 2 & 3 automatically.
Change-Id: Ia962d18bda34e0244fb05636a7be263045ecb256
-rwxr-xr-x | git_review/cmd.py | 19 | ||||
-rw-r--r-- | git_review/tests/test_unit.py | 16 |
2 files changed, 23 insertions, 12 deletions
diff --git a/git_review/cmd.py b/git_review/cmd.py index 597ba22..fa852f5 100755 --- a/git_review/cmd.py +++ b/git_review/cmd.py @@ -1008,8 +1008,8 @@ def list_reviews(remote): else: review_field_color = ("", "", "") color_reset = "" - review_field_format = ["%*s", "%*s", "%*s"] - review_field_justify = [+1, +1, -1] # +1 is justify to right + # > is right justify, < is left, field indices for py26 + review_field_format = ["{0:>{1}}", "{2:>{3}}", "{4:<{5}}"] review_list = [[r[f] for f in REVIEW_FIELDS] for r in reviews] review_field_width = dict() @@ -1026,20 +1026,15 @@ def list_reviews(remote): color_reset for i in FIELDS]) - review_field_width = [ - review_field_width[i] * review_field_justify[i] - for i in FIELDS] + review_field_width = [review_field_width[i] for i in FIELDS] for review_value in review_list: # At this point we have review_field_format - # like "%*s %*s %*s" and we need to supply - # (width1, value1, width2, value2, ...) tuple to print - # It's easy to zip() widths with actual values, - # but we need to flatten the resulting - # ((width1, value1), (width2, value2), ...) map. + # like "{:>{}} {:>{}} {:<{}}" and we need to supply + # (value1, width1, value2, width2, ...) tuple to print formatted_fields = [] for (width, value) in zip(review_field_width, review_value): - formatted_fields.extend([width, value.encode('utf-8')]) - print(review_field_format % tuple(formatted_fields)) + formatted_fields.extend([value, width]) + print(review_field_format.format(*formatted_fields)) print("Found %d items for review" % len(reviews)) return 0 diff --git a/git_review/tests/test_unit.py b/git_review/tests/test_unit.py index 3ef378b..4a7570f 100644 --- a/git_review/tests/test_unit.py +++ b/git_review/tests/test_unit.py @@ -105,6 +105,22 @@ class GitReviewConsole(testtools.TestCase, fixtures.TestWithFixtures): @mock.patch('git_review.cmd.query_reviews') @mock.patch('git_review.cmd.get_remote_url', mock.MagicMock) @mock.patch('git_review.cmd._has_color', False) + def test_list_reviews_output(self, mock_query): + + mock_query.return_value = self.reviews + with mock.patch('sys.stdout', new_callable=io.StringIO) as output: + cmd.list_reviews(None) + console_output = output.getvalue().split('\n') + + self.assertEqual( + ['1010101 master A simple short subject', + ' 9877 stable/codeword A longer and slightly more wordy ' + 'subject'], + console_output[:2]) + + @mock.patch('git_review.cmd.query_reviews') + @mock.patch('git_review.cmd.get_remote_url', mock.MagicMock) + @mock.patch('git_review.cmd._has_color', False) def test_list_reviews_no_blanks(self, mock_query): mock_query.return_value = self.reviews |