Changeset 57907 in webkit
- Timestamp:
- Apr 20, 2010 12:54:46 PM (14 years ago)
- Location:
- trunk/WebKitTools
- Files:
-
- 32 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebKitTools/ChangeLog
r57905 r57907 1 2010-04-20 Eric Seidel <eric@webkit.org> 2 3 Reviewed by Adam Barth. 4 5 REGRESSION(57531): the commit-queue still hates Tor Arne Vestbø 6 https://bugs.webkit.org/show_bug.cgi?id=37765 7 8 I fixed the queue to not ignore Tor as a reviwer in r57531, 9 but instead it throws an exception every time his name is in a patch. 10 11 This fixes our Executive.run_command code to work around a Popen 12 bug http://bugs.python.org/issue5290 whereby python versions before 2.6 13 do not correctly handle unicode objects as input or output to 14 Popen.communicate. 15 16 Following the advice of: 17 http://farmdev.com/talks/unicode/ 18 I'm attempting to take the python unicode plunge and use unicode() 19 objects as strings instead of str() objects everywhere in webkitpy. 20 21 We do not have to use u"" instead of "" because u"a" == "a" as expected 22 in Python. Python will generate a warning to the console in cases where 23 a unicode() == str() operation cannot be performed. 24 25 I also cleaned up the input handling in run_command a little by adding 26 a new _compute_input() method which can return early instead of having 27 such a long/cluttered if-block. 28 29 Executive.run* now correctly accept and return unicode() objects. 30 I attempted to fix all the places that we call .write() to make sure we 31 encode any unicode() objects into utf-8. 32 33 All places which use StringIO need to be sure to pass StringIO a 34 pre-encoded byte-array (str object) instead of unicode so that 35 clients which read from the StringIO don't have encoding exceptions. 36 To make this easier, I removed the patch_file_object support from 37 add_patch_to_bug, and changed the 4 places which previously used 38 StringIO to create a fake patch file. 39 40 I attempted to document any places where we are not correctly converting 41 to/from bytes (str() objects) to strings (unicode() objects). 42 43 * Scripts/webkitpy/common/checkout/api_unittest.py: 44 - Read/write utf-8 files instead of ascii. 45 - Update the tests to use test for proper unicode() handling. 46 * Scripts/webkitpy/common/checkout/changelog_unittest.py: 47 - Use unicode() strings instead of str() byte arrays. 48 * Scripts/webkitpy/common/checkout/scm.py: 49 - Remove use of str(). 50 * Scripts/webkitpy/common/checkout/scm_unittest.py: 51 - Read/write utf-8 files and use unicode() strings in testing. 52 * Scripts/webkitpy/common/config/committers.py: 53 - Use \u instead of \x to make slightly clearer what we're doing. 54 * Scripts/webkitpy/common/net/bugzilla.py: 55 - Add a new _string_contents() method and explain why 56 we have to call unicode() on the result of soup.string 57 and why it's safe to do so w/o needing to pass a codec name. 58 - Remove the (unused) support for passing a file object to add_patch_to_bug(). 59 * Scripts/webkitpy/common/net/buildbot.py: 60 - Use unicode() instead of str() when needing to coax a 61 NavigableString object into a unicode() object. 62 * Scripts/webkitpy/common/net/statusserver.py: 63 - Remove use of str() 64 * Scripts/webkitpy/common/prettypatch.py: 65 - Write out the patch file as utf-8. 66 * Scripts/webkitpy/common/system/autoinstall.py: 67 - Add a FIXME about encoding. 68 * Scripts/webkitpy/common/system/deprecated_logging.py: 69 - Document that tee() works on bytes, not strings. 70 * Scripts/webkitpy/common/system/executive.py: 71 - Make run* properly take and return unicode() objects. 72 * Scripts/webkitpy/common/system/executive_unittest.py: 73 - Added a unit test to make sure we don't break Tor again! 74 * Scripts/webkitpy/layout_tests/layout_package/dump_render_tree_thread.py: 75 - Write out the test list as utf-8. 76 * Scripts/webkitpy/layout_tests/layout_package/json_results_generator.py: 77 - Write out json files as utf-8. 78 * Scripts/webkitpy/layout_tests/layout_package/metered_stream.py: 79 - Add FIXME about encoding handling. 80 * Scripts/webkitpy/tool/commands/upload.py: 81 - Pass the diff directly to add_patch_to_bug instead of creating a StringIO file wrapper. 82 * Scripts/webkitpy/tool/mocktool.py: 83 - Rename add_patch_to_bug argument to match bugzilla.py 84 * Scripts/webkitpy/tool/steps/postdiff.py: 85 - Pass the diff directly to add_patch_to_bug instead of creating a StringIO file wrapper. 86 * Scripts/webkitpy/tool/steps/postdiffforcommit.py: ditto. 87 * Scripts/webkitpy/tool/steps/postdiffforrevert.py: ditto. 88 * Scripts/webkitpy/tool/steps/steps_unittest.py: 89 - Fixed spurious logging seen when running test-webkitpy 90 1 91 2010-04-20 Chris Jerdonek <cjerdonek@webkit.org> 2 92 -
trunk/WebKitTools/Scripts/webkitpy/common/checkout/api.py
r57572 r57907 51 51 def _latest_entry_for_changelog_at_revision(self, changelog_path, revision): 52 52 changelog_contents = self._scm.contents_at_revision(changelog_path, revision) 53 return ChangeLog.parse_latest_entry_from_file(StringIO.StringIO(changelog_contents)) 53 fake_file = StringIO.StringIO(changelog_contents.encode("utf-8")) 54 return ChangeLog.parse_latest_entry_from_file(fake_file) 54 55 55 56 def changelog_entries_for_revision(self, revision): -
trunk/WebKitTools/Scripts/webkitpy/common/checkout/api_unittest.py
r57572 r57907 27 27 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 28 29 import codecs 29 30 import os 30 31 import shutil … … 40 41 # FIXME: Copied from scm_unittest.py 41 42 def write_into_file_at_path(file_path, contents): 42 new_file = open(file_path, 'w')43 new_file = codecs.open(file_path, "w", "utf-8") 43 44 new_file.write(contents) 44 45 new_file.close() 45 46 46 47 47 _changelog1entry1 = """2010-03-25 Eric Seidel <eric@webkit.org>48 _changelog1entry1 = u"""2010-03-25 Tor Arne Vestb\u00f8 <vestbo@webkit.org> 48 49 49 50 Unreviewed build fix to un-break webkit-patch land. … … 54 55 * Scripts/webkitpy/common/checkout/api.py: import scm.CommitMessage 55 56 """ 56 _changelog1entry2 = """2010-03-25 Adam Barth <abarth@webkit.org>57 _changelog1entry2 = u"""2010-03-25 Adam Barth <abarth@webkit.org> 57 58 58 59 Reviewed by Eric Seidel. … … 63 64 * Scripts/webkitpy/common/checkout/api.py: 64 65 """ 65 _changelog1 = "\n".join([_changelog1entry1, _changelog1entry2])66 _changelog2 = """2010-03-25 Eric Seidel <eric@webkit.org>66 _changelog1 = u"\n".join([_changelog1entry1, _changelog1entry2]) 67 _changelog2 = u"""2010-03-25 Tor Arne Vestb\u00f8 <vestbo@webkit.org> 67 68 68 69 Unreviewed build fix to un-break webkit-patch land. … … 80 81 81 82 class CommitMessageForThisCommitTest(unittest.TestCase): 82 expected_commit_message = """2010-03-25 Eric Seidel <eric@webkit.org>83 expected_commit_message = u"""2010-03-25 Tor Arne Vestb\u00f8 <vestbo@webkit.org> 83 84 84 85 Unreviewed build fix to un-break webkit-patch land. … … 88 89 89 90 * Scripts/webkitpy/common/checkout/api.py: import scm.CommitMessage 90 2010-03-25 Eric Seidel <eric@webkit.org>91 2010-03-25 Tor Arne Vestb\u00f8 <vestbo@webkit.org> 91 92 92 93 Unreviewed build fix to un-break webkit-patch land. … … 138 139 commitinfo = checkout.commit_info_for_revision(4) 139 140 self.assertEqual(commitinfo.bug_id(), 36629) 140 self.assertEqual(commitinfo.author_name(), "Eric Seidel")141 self.assertEqual(commitinfo.author_email(), " eric@webkit.org")141 self.assertEqual(commitinfo.author_name(), u"Tor Arne Vestb\u00f8") 142 self.assertEqual(commitinfo.author_email(), "vestbo@webkit.org") 142 143 self.assertEqual(commitinfo.reviewer_text(), None) 143 144 self.assertEqual(commitinfo.reviewer(), None) -
trunk/WebKitTools/Scripts/webkitpy/common/checkout/changelog.py
r57531 r57907 103 103 entry_lines = [] 104 104 # The first line should be a date line. 105 first_line = changelog_file.readline()105 first_line = unicode(changelog_file.readline(), "utf-8") 106 106 if not date_line_regexp.match(first_line): 107 107 return None … … 109 109 110 110 for line in changelog_file: 111 line = unicode(line, "utf-8") 111 112 # If we've hit the next entry, return. 112 113 if date_line_regexp.match(line): … … 118 119 def latest_entry(self): 119 120 # ChangeLog files are always UTF-8, we read them in as such to support Reviewers with unicode in their names. 120 changelog_file = codecs.open(self.path, "r", "utf-8") 121 # We don't use codecs.open here to make the api for parse_latest_entry_from_file clearer. 122 # If we did, then it would be unclear as to whos reponsibility decoding of the file should be. 123 changelog_file = open(self.path, "r") 121 124 try: 122 125 return self.parse_latest_entry_from_file(changelog_file) -
trunk/WebKitTools/Scripts/webkitpy/common/checkout/changelog_unittest.py
r57531 r57907 88 88 89 89 def test_latest_entry_parse(self): 90 changelog_contents = "%s\n%s" % (self._example_entry, self._example_changelog)91 changelog_file = StringIO(changelog_contents )90 changelog_contents = u"%s\n%s" % (self._example_entry, self._example_changelog) 91 changelog_file = StringIO(changelog_contents.encode("utf-8")) 92 92 latest_entry = ChangeLog.parse_latest_entry_from_file(changelog_file) 93 93 self.assertEquals(latest_entry.contents(), self._example_entry) … … 122 122 123 123 def test_set_reviewer(self): 124 changelog_contents = "%s\n%s" % (self._new_entry_boilerplate, self._example_changelog)124 changelog_contents = u"%s\n%s" % (self._new_entry_boilerplate, self._example_changelog) 125 125 changelog_path = self._write_tmp_file_with_contents(changelog_contents) 126 126 reviewer_name = 'Test Reviewer' … … 170 170 171 171 def _assert_update_for_revert_output(self, args, expected_entry): 172 changelog_contents = "%s\n%s" % (self._new_entry_boilerplate, self._example_changelog)172 changelog_contents = u"%s\n%s" % (self._new_entry_boilerplate, self._example_changelog) 173 173 changelog_path = self._write_tmp_file_with_contents(changelog_contents) 174 174 changelog = ChangeLog(changelog_path) -
trunk/WebKitTools/Scripts/webkitpy/common/checkout/commitinfo.py
r57195 r57907 28 28 # 29 29 # WebKit's python module for holding information on a commit 30 31 import StringIO32 30 33 31 from webkitpy.common.checkout.changelog import view_source_url -
trunk/WebKitTools/Scripts/webkitpy/common/checkout/scm.py
r57439 r57907 146 146 147 147 def strip_r_from_svn_revision(self, svn_revision): 148 match = re.match("^r(?P<svn_revision>\d+)", svn_revision)148 match = re.match("^r(?P<svn_revision>\d+)", unicode(svn_revision)) 149 149 if (match): 150 150 return match.group('svn_revision') … … 345 345 def changed_files_for_revision(self, revision): 346 346 # As far as I can tell svn diff --summarize output looks just like svn status output. 347 status_command = ["svn", "diff", "--summarize", "-c", str(revision)]347 status_command = ["svn", "diff", "--summarize", "-c", revision] 348 348 return self.run_status_and_extract_filenames(status_command, self._status_regexp("ACDMR")) 349 349 … … 365 365 366 366 def committer_email_for_revision(self, revision): 367 return run_command(["svn", "propget", "svn:author", "--revprop", "-r", str(revision)]).rstrip()367 return run_command(["svn", "propget", "svn:author", "--revprop", "-r", revision]).rstrip() 368 368 369 369 def contents_at_revision(self, path, revision): 370 370 remote_path = "%s/%s" % (self._repository_url(), path) 371 return run_command(["svn", "cat", "-r", str(revision), remote_path])371 return run_command(["svn", "cat", "-r", revision, remote_path]) 372 372 373 373 def diff_for_revision(self, revision): 374 374 # FIXME: This should probably use cwd=self.checkout_root 375 return run_command(['svn', 'diff', '-c', str(revision)])375 return run_command(['svn', 'diff', '-c', revision]) 376 376 377 377 def _repository_url(self): … … 406 406 407 407 def svn_commit_log(self, svn_revision): 408 svn_revision = self.strip_r_from_svn_revision(s tr(svn_revision))408 svn_revision = self.strip_r_from_svn_revision(svn_revision) 409 409 return run_command(['svn', 'log', '--non-interactive', '--revision', svn_revision]); 410 410 -
trunk/WebKitTools/Scripts/webkitpy/common/checkout/scm_unittest.py
r57439 r57907 29 29 30 30 import base64 31 import codecs 31 32 import getpass 32 33 import os … … 58 59 59 60 def write_into_file_at_path(file_path, contents): 60 file = open(file_path, 'w')61 file = codecs.open(file_path, "w", "utf-8") 61 62 file.write(contents) 62 63 file.close() 63 64 64 65 def read_from_path(file_path): 65 file = open(file_path, 'r')66 file = codecs.open(file_path, "r", "utf-8") 66 67 contents = file.read() 67 68 file.close() -
trunk/WebKitTools/Scripts/webkitpy/common/config/committers.py
r57898 r57907 240 240 Reviewer("Tim Omernick", "timo@apple.com"), 241 241 Reviewer("Timothy Hatcher", ["timothy@hatcher.name", "timothy@apple.com"], "xenon"), 242 Reviewer(u 'Tor Arne Vestb\xf8', "vestbo@webkit.org", "torarne"),242 Reviewer(u"Tor Arne Vestb\u00f8", "vestbo@webkit.org", "torarne"), 243 243 Reviewer("Vicki Murley", "vicki@apple.com"), 244 244 Reviewer("Xan Lopez", ["xan.lopez@gmail.com", "xan@gnome.org", "xan@webkit.org"], "xan"), -
trunk/WebKitTools/Scripts/webkitpy/common/net/bugzilla.py
r57869 r57907 33 33 import os.path 34 34 import re 35 import StringIO 35 36 import subprocess 36 37 … … 412 413 attachment[result_key] = flag['setter'] 413 414 415 def _string_contents(self, soup): 416 # WebKit's bugzilla instance uses UTF-8. 417 # BeautifulSoup always returns Unicode strings, however 418 # the .string method returns a (unicode) NavigableString. 419 # NavigableString can confuse other parts of the code, so we 420 # convert from NavigableString to a real unicode() object using unicode(). 421 return unicode(soup.string) 422 414 423 def _parse_attachment_element(self, element, bug_id): 424 415 425 attachment = {} 416 426 attachment['bug_id'] = bug_id … … 420 430 # FIXME: No need to parse out the url here. 421 431 attachment['url'] = self.attachment_url_for_id(attachment['id']) 422 attachment['name'] = unicode(element.find('desc').string)423 attachment['attacher_email'] = s tr(element.find('attacher').string)424 attachment['type'] = s tr(element.find('type').string)432 attachment['name'] = self._string_contents(element.find('desc')) 433 attachment['attacher_email'] = self._string_contents(element.find('attacher')) 434 attachment['type'] = self._string_contents(element.find('type')) 425 435 self._parse_attachment_flag( 426 436 element, 'review', attachment, 'reviewer_email') … … 433 443 bug = {} 434 444 bug["id"] = int(soup.find("bug_id").string) 435 bug["title"] = unicode(soup.find("short_desc").string)436 bug["reporter_email"] = s tr(soup.find("reporter").string)437 bug["assigned_to_email"] = s tr(soup.find("assigned_to").string)438 bug["cc_emails"] = [s tr(element.string)445 bug["title"] = self._string_contents(soup.find("short_desc")) 446 bug["reporter_email"] = self._string_contents(soup.find("reporter")) 447 bug["assigned_to_email"] = self._string_contents(soup.find("assigned_to")) 448 bug["cc_emails"] = [self._string_contents(element) 439 449 for element in soup.findAll('cc')] 440 450 bug["attachments"] = [self._parse_attachment_element(element, bug["id"]) for element in soup.findAll('attachment')] … … 533 543 def _fill_attachment_form(self, 534 544 description, 535 patch_file_object,545 diff, 536 546 comment_text=None, 537 547 mark_for_review=False, … … 553 563 else: 554 564 patch_name ="%s.patch" % timestamp() 565 566 # ClientForm expects a file-like object 567 patch_file_object = StringIO.StringIO(diff.encode("utf-8")) 555 568 self.browser.add_file(patch_file_object, 556 569 "text/plain", … … 560 573 def add_patch_to_bug(self, 561 574 bug_id, 562 patch_file_object,575 diff, 563 576 description, 564 577 comment_text=None, … … 579 592 self.bug_server_url, bug_id)) 580 593 self.browser.select_form(name="entryform") 594 581 595 self._fill_attachment_form(description, 582 patch_file_object,596 diff, 583 597 mark_for_review=mark_for_review, 584 598 mark_for_commit_queue=mark_for_commit_queue, … … 613 627 bug_description, 614 628 component=None, 615 patch_file_object=None,629 diff=None, 616 630 patch_description=None, 617 631 cc=None, … … 638 652 self.browser["cc"] = cc 639 653 if blocked: 640 self.browser["blocked"] = str(blocked)654 self.browser["blocked"] = unicode(blocked) 641 655 self.browser["short_desc"] = bug_title 642 656 self.browser["comment"] = bug_description 643 657 644 if patch_file_object:658 if diff: 645 659 self._fill_attachment_form( 646 660 patch_description, 647 patch_file_object,661 diff, 648 662 mark_for_review=mark_for_review, 649 663 mark_for_commit_queue=mark_for_commit_queue) -
trunk/WebKitTools/Scripts/webkitpy/common/net/buildbot.py
r57805 r57907 45 45 class Builder(object): 46 46 def __init__(self, name, buildbot): 47 self._name = unicode(name)47 self._name = name 48 48 self._buildbot = buildbot 49 49 self._builds_cache = {} … … 224 224 tables = BeautifulSoup(page).findAll("table") 225 225 for table in tables: 226 table_title = table.findPreviousSibling("p").string226 table_title = unicode(table.findPreviousSibling("p").string) 227 227 if table_title not in cls.expected_keys: 228 228 # This Exception should only ever be hit if run-webkit-tests changes its results.html format. 229 raise Exception("Unhandled title: %s" % str(table_title))229 raise Exception("Unhandled title: %s" % table_title) 230 230 # We might want to translate table titles into identifiers before storing. 231 parsed_results[table_title] = [ row.find("a").stringfor row in table.findAll("tr")]231 parsed_results[table_title] = [unicode(row.find("a").string) for row in table.findAll("tr")] 232 232 233 233 return parsed_results … … 362 362 # First cell is the name 363 363 name_link = status_cells[0].find('a') 364 builder["name"] = name_link.string364 builder["name"] = unicode(name_link.string) 365 365 366 366 self._parse_last_build_cell(builder, status_cells[1]) … … 411 411 412 412 def _parse_twisted_file_row(self, file_row): 413 string_or_empty = lambda s tring: str(string) if string else""413 string_or_empty = lambda soup: unicode(soup.string) if soup.string else u"" 414 414 file_cells = file_row.findAll('td') 415 415 return { 416 "filename" : string_or_empty(file_cells[0].find("a").string),417 "size" : string_or_empty(file_cells[1].string),418 "type" : string_or_empty(file_cells[2].string),419 "encoding" : string_or_empty(file_cells[3].string),416 "filename": string_or_empty(file_cells[0].find("a")), 417 "size": string_or_empty(file_cells[1]), 418 "type": string_or_empty(file_cells[2]), 419 "encoding": string_or_empty(file_cells[3]), 420 420 } 421 421 -
trunk/WebKitTools/Scripts/webkitpy/common/net/buildbot_unittest.py
r57795 r57907 52 52 def setUp(self): 53 53 self.buildbot = BuildBot() 54 self.builder = Builder( "Test Builder", self.buildbot)54 self.builder = Builder(u"Test Builder \u2661", self.buildbot) 55 55 self._install_fetch_build(lambda build_number: ["test1", "test2"]) 56 56 -
trunk/WebKitTools/Scripts/webkitpy/common/net/statusserver.py
r57195 r57907 53 53 return 54 54 if patch.bug_id(): 55 self.browser["bug_id"] = str(patch.bug_id())55 self.browser["bug_id"] = unicode(patch.bug_id()) 56 56 if patch.id(): 57 self.browser["patch_id"] = str(patch.id())57 self.browser["patch_id"] = unicode(patch.id()) 58 58 59 59 def _add_results_file(self, results_file): … … 80 80 self.browser.open(update_svn_revision_url) 81 81 self.browser.select_form(name="update_svn_revision") 82 self.browser["number"] = str(svn_revision_number)82 self.browser["number"] = unicode(svn_revision_number) 83 83 self.browser["broken_bot"] = broken_bot 84 84 return self.browser.submit().read() -
trunk/WebKitTools/Scripts/webkitpy/common/prettypatch.py
r57587 r57907 39 39 pretty_diff = self.pretty_diff(diff) 40 40 diff_file = tempfile.NamedTemporaryFile(suffix=".html") 41 diff_file.write(pretty_diff )41 diff_file.write(pretty_diff.encode("utf-8")) 42 42 diff_file.flush() 43 43 return diff_file -
trunk/WebKitTools/Scripts/webkitpy/common/system/autoinstall.py
r56897 r57907 125 125 file = open(path, "w") 126 126 try: 127 file.write(text) 127 file.write(text) # FIXME: What's the encoding of this file? 128 128 finally: 129 129 file.close() -
trunk/WebKitTools/Scripts/webkitpy/common/system/deprecated_logging.py
r56544 r57907 46 46 self.files = files 47 47 48 def write(self, string): 48 # Callers should pass an already encoded string for writing. 49 def write(self, bytes): 49 50 for file in self.files: 50 file.write( string)51 file.write(bytes) 51 52 52 53 class OutputTee: -
trunk/WebKitTools/Scripts/webkitpy/common/system/executive.py
r57550 r57907 89 89 90 90 def _run_command_with_teed_output(self, args, teed_output): 91 args = map(unicode, args) # Popen will throw an exception if args are non-strings (like int()) 91 92 child_process = subprocess.Popen(args, 92 93 stdout=subprocess.PIPE, … … 100 101 if output_line == "" and child_process.poll() != None: 101 102 return child_process.poll() 103 # We assume that the child process wrote to us in utf-8, 104 # so no re-encoding is necessary before writing here. 102 105 teed_output.write(output_line) 103 106 104 def run_and_throw_if_fail(self, args, quiet=False): 107 # FIXME: Remove this deprecated method and move callers to run_command. 108 # FIXME: This method is a hack to allow running command which both 109 # capture their output and print out to stdin. Useful for things 110 # like "build-webkit" where we want to display to the user that we're building 111 # but still have the output to stuff into a log file. 112 def run_and_throw_if_fail(self, args, quiet=False, decode_output=True): 105 113 # Cache the child's output locally so it can be used for error reports. 106 114 child_out_file = StringIO.StringIO() … … 116 124 child_output = child_out_file.getvalue() 117 125 child_out_file.close() 126 127 # We assume the child process output utf-8 128 if decode_output: 129 child_output = child_output.decode("utf-8") 118 130 119 131 if exit_code: … … 146 158 # using Cygwin, it worked fine. We should investigate whether 147 159 # we need this platform specific code here. 148 subprocess.call(('taskkill.exe', '/f', '/pid', str(pid)),160 subprocess.call(('taskkill.exe', '/f', '/pid', unicode(pid)), 149 161 stdin=open(os.devnull, 'r'), 150 162 stdout=subprocess.PIPE, … … 164 176 pass 165 177 166 # FIXME: This should be merged with run_and_throw_if_fail 167 178 def _compute_stdin(self, input): 179 """Returns (stdin, string_to_communicate)""" 180 if not input: 181 return (None, None) 182 if hasattr(input, "read"): # Check if the input is a file. 183 return (input, None) # Assume the file is in the right encoding. 184 185 # Popen in Python 2.5 and before does not automatically encode unicode objects. 186 # http://bugs.python.org/issue5290 187 # See https://bugs.webkit.org/show_bug.cgi?id=37528 188 # for an example of a regresion caused by passing a unicode string directly. 189 # FIXME: We may need to encode differently on different platforms. 190 if isinstance(input, unicode): 191 input = input.encode("utf-8") 192 return (subprocess.PIPE, input) 193 194 # FIXME: run_and_throw_if_fail should be merged into this method. 168 195 def run_command(self, 169 196 args, … … 172 199 error_handler=None, 173 200 return_exit_code=False, 174 return_stderr=True): 175 if hasattr(input, 'read'): # Check if the input is a file. 176 stdin = input 177 string_to_communicate = None 178 else: 179 stdin = None 180 if input: 181 stdin = subprocess.PIPE 182 # string_to_communicate seems to need to be a str for proper 183 # communication with shell commands. 184 # See https://bugs.webkit.org/show_bug.cgi?id=37528 185 # For an example of a regresion caused by passing a unicode string through. 186 string_to_communicate = str(input) 187 if return_stderr: 188 stderr = subprocess.STDOUT 189 else: 190 stderr = None 201 return_stderr=True, 202 decode_output=True): 203 args = map(unicode, args) # Popen will throw an exception if args are non-strings (like int()) 204 stdin, string_to_communicate = self._compute_stdin(input) 205 stderr = subprocess.STDOUT if return_stderr else None 191 206 192 207 process = subprocess.Popen(args, … … 196 211 cwd=cwd) 197 212 output = process.communicate(string_to_communicate)[0] 213 # run_command automatically decodes to unicode() unless explicitly told not to. 214 if decode_output: 215 output = output.decode("utf-8") 198 216 exit_code = process.wait() 199 217 -
trunk/WebKitTools/Scripts/webkitpy/common/system/executive_unittest.py
r56517 r57907 1 # Copyright (C) 20 09Google Inc. All rights reserved.1 # Copyright (C) 2010 Google Inc. All rights reserved. 2 2 # Copyright (C) 2009 Daniel Bates (dbates@intudata.com). All rights reserved. 3 3 # … … 32 32 from webkitpy.common.system.executive import Executive, run_command 33 33 34 34 35 class ExecutiveTest(unittest.TestCase): 35 36 … … 39 40 self.failUnlessRaises(OSError, run_bad_command) 40 41 41 if __name__ == '__main__': 42 unittest.main() 42 def test_run_command_with_unicode(self): 43 """Validate that it is safe to pass unicode() objects 44 to Executive.run* methods, and they will return unicode() 45 objects by default unless decode_output=False""" 46 executive = Executive() 47 unicode_tor = u"WebKit \u2661 Tor Arne Vestb\u00F8!" 48 utf8_tor = unicode_tor.encode("utf-8") 49 50 output = executive.run_command(["cat"], input=unicode_tor) 51 self.assertEquals(output, unicode_tor) 52 53 output = executive.run_command(["echo", "-n", unicode_tor]) 54 self.assertEquals(output, unicode_tor) 55 56 output = executive.run_command(["echo", "-n", unicode_tor], decode_output=False) 57 self.assertEquals(output, utf8_tor) 58 59 # FIXME: We should only have one run* method to test 60 output = executive.run_and_throw_if_fail(["echo", "-n", unicode_tor], quiet=True) 61 self.assertEquals(output, unicode_tor) 62 63 output = executive.run_and_throw_if_fail(["echo", "-n", unicode_tor], quiet=True, decode_output=False) 64 self.assertEquals(output, utf8_tor) -
trunk/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/dump_render_tree_thread.py
r57446 r57907 36 36 """ 37 37 38 import codecs 38 39 import copy 39 40 import logging … … 287 288 tests_run_filename = os.path.join(self._options.results_directory, 288 289 "tests_run.txt") 289 tests_run_file = open(tests_run_filename, "a")290 tests_run_file = codecs.open(tests_run_filename, "a", "utf-8") 290 291 291 292 while True: -
trunk/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/json_results_generator.py
r57800 r57907 28 28 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 29 30 import codecs 30 31 import logging 31 32 import os … … 119 120 json = self._get_json() 120 121 if json: 121 results_file = open(self._results_file_path, "w")122 results_file = codecs.open(self._results_file_path, "w", "utf-8") 122 123 results_file.write(json) 123 124 results_file.close() -
trunk/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/metered_stream.py
r57841 r57907 61 61 self._last_update = "" 62 62 63 # FIXME: Does this take a string (unicode) or an array of bytes (str)? 64 # If it takes a string, it needs to call txt.encode("utf-8") 63 65 def write(self, txt): 64 66 """Write to the stream, overwriting and resetting the meter.""" … … 87 89 self._write(str) 88 90 91 # FIXME: Does this take a string (unicode) or an array of bytes (str)? 92 # If it takes a string, it needs to call txt.encode("utf-8") 89 93 def update(self, str): 90 94 """ -
trunk/WebKitTools/Scripts/webkitpy/layout_tests/port/mac_unittest.py
r54830 r57907 41 41 self.assertEqual(relative_paths, ['LayoutTests/platform/mac-leopard/Skipped', 'LayoutTests/platform/mac/Skipped']) 42 42 43 example_skipped_file = """43 example_skipped_file = u""" 44 44 # <rdar://problem/5647952> fast/events/mouseout-on-window.html needs mac DRT to issue mouse out events 45 45 fast/events/mouseout-on-window.html … … 59 59 def test_skipped_file_paths(self): 60 60 port = mac.MacPort() 61 skipped_file = StringIO.StringIO(self.example_skipped_file )61 skipped_file = StringIO.StringIO(self.example_skipped_file.encode("utf-8")) 62 62 self.assertEqual(port._tests_from_skipped_file(skipped_file), self.example_skipped_tests) 63 63 -
trunk/WebKitTools/Scripts/webkitpy/tool/commands/earlywarningsystem.py
r57778 r57907 26 26 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 27 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 29 from StringIO import StringIO30 28 31 29 from webkitpy.tool.commands.queues import AbstractReviewQueue -
trunk/WebKitTools/Scripts/webkitpy/tool/commands/queues.py
r57451 r57907 72 72 webkit_patch_args = [self.tool.path()] 73 73 # FIXME: This is a hack, we should have a more general way to pass global options. 74 webkit_patch_args += ["--status-host=%s" % self.tool.status_server.host] 75 webkit_patch_args += map(str, args) 74 webkit_patch_args.append("--status-host") 75 webkit_patch_args.append(self.tool.status_server.host) 76 webkit_patch_args.extend(args) 76 77 return self.tool.executive.run_and_throw_if_fail(webkit_patch_args) 77 78 … … 124 125 message = "Error: %s" % message 125 126 output = script_error.message_with_output(output_limit=1024*1024) # 1MB 126 return tool.status_server.update_status(cls.name, message, state["patch"], StringIO(output ))127 return tool.status_server.update_status(cls.name, message, state["patch"], StringIO(output.encode("utf-8"))) 127 128 128 129 -
trunk/WebKitTools/Scripts/webkitpy/tool/commands/queues_unittest.py
r57788 r57907 76 76 77 77 queue.run_webkit_patch(run_args) 78 expected_run_args = ["echo", "--status-host =example.com"] + map(str, run_args)78 expected_run_args = ["echo", "--status-host", "example.com"] + run_args 79 79 tool.executive.run_and_throw_if_fail.assert_called_with(expected_run_args) 80 80 … … 151 151 1 patch in commit-queue [106] 152 152 """, 153 "process_work_item": "MOCK run_and_throw_if_fail: ['echo', '--status-host =example.com', 'land-attachment', '--force-clean', '--build', '--test', '--non-interactive', '--ignore-builders', '--build-style=both', '--quiet', '76543']\n",153 "process_work_item": "MOCK run_and_throw_if_fail: ['echo', '--status-host', 'example.com', 'land-attachment', '--force-clean', '--build', '--test', '--non-interactive', '--ignore-builders', '--build-style=both', '--quiet', 76543]\n", 154 154 } 155 155 self.assert_queue_outputs(CommitQueue(), tool=tool, work_item=rollout_patch, expected_stderr=expected_stderr) -
trunk/WebKitTools/Scripts/webkitpy/tool/commands/upload.py
r57788 r57907 31 31 import os 32 32 import re 33 import StringIO34 33 import sys 35 34 … … 261 260 return comment_text 262 261 263 def _diff_file_for_commit(self, tool, commit_id):264 diff = tool.scm().create_patch_from_local_commit(commit_id)265 return StringIO.StringIO(diff) # add_patch_to_bug expects a file-like object266 267 262 def execute(self, options, args, tool): 268 263 commit_ids = tool.scm().commit_ids_from_commitish_arguments(args) … … 285 280 have_obsoleted_patches.add(bug_id) 286 281 287 diff _file = self._diff_file_for_commit(tool,commit_id)282 diff = tool.scm().create_patch_from_local_commit(commit_id) 288 283 description = options.description or commit_message.description(lstrip=True, strip_url=True) 289 284 comment_text = self._comment_text_for_commit(options, commit_message, tool, commit_id) 290 tool.bugs.add_patch_to_bug(bug_id, diff _file, description, comment_text, mark_for_review=options.review, mark_for_commit_queue=options.request_commit)285 tool.bugs.add_patch_to_bug(bug_id, diff, description, comment_text, mark_for_review=options.review, mark_for_commit_queue=options.request_commit) 291 286 292 287 … … 405 400 406 401 diff = tool.scm().create_patch_from_local_commit(commit_id) 407 diff_file = StringIO.StringIO(diff) # create_bug expects a file-like object 408 bug_id = tool.bugs.create_bug(bug_title, comment_text, options.component, diff_file, "Patch", cc=options.cc, mark_for_review=options.review, mark_for_commit_queue=options.request_commit) 402 bug_id = tool.bugs.create_bug(bug_title, comment_text, options.component, diff, "Patch", cc=options.cc, mark_for_review=options.review, mark_for_commit_queue=options.request_commit) 409 403 410 404 if bug_id and len(commit_ids) > 1: … … 425 419 426 420 diff = tool.scm().create_patch() 427 diff_file = StringIO.StringIO(diff) # create_bug expects a file-like object 428 bug_id = tool.bugs.create_bug(bug_title, comment_text, options.component, diff_file, "Patch", cc=options.cc, mark_for_review=options.review, mark_for_commit_queue=options.request_commit) 421 bug_id = tool.bugs.create_bug(bug_title, comment_text, options.component, diff, "Patch", cc=options.cc, mark_for_review=options.review, mark_for_commit_queue=options.request_commit) 429 422 430 423 def prompt_for_bug_title_and_comment(self): -
trunk/WebKitTools/Scripts/webkitpy/tool/mocktool.py
r57869 r57907 261 261 bug_description, 262 262 component=None, 263 patch_file_object=None,263 diff=None, 264 264 patch_description=None, 265 265 cc=None, … … 300 300 def add_patch_to_bug(self, 301 301 bug_id, 302 patch_file_object,302 diff, 303 303 description, 304 304 comment_text=None, -
trunk/WebKitTools/Scripts/webkitpy/tool/steps/abstractstep.py
r56601 r57907 40 40 log("Running %s" % script_name) 41 41 # FIXME: This should use self.port() 42 self._tool.executive.run_and_throw_if_fail( port.script_path(script_name), quiet)42 self._tool.executive.run_and_throw_if_fail([port.script_path(script_name)], quiet) 43 43 44 44 # FIXME: The port should live on the tool. -
trunk/WebKitTools/Scripts/webkitpy/tool/steps/postdiff.py
r57679 r57907 27 27 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 28 29 import StringIO30 31 29 from webkitpy.tool.steps.abstractstep import AbstractStep 32 30 from webkitpy.tool.steps.options import Options … … 45 43 def run(self, state): 46 44 diff = self.cached_lookup(state, "diff") 47 diff_file = StringIO.StringIO(diff) # add_patch_to_bug expects a file-like object48 45 description = self._options.description or "Patch" 49 46 comment_text = None … … 53 50 if codereview_issue: 54 51 description += "-%s" % state["codereview_issue"] 55 self._tool.bugs.add_patch_to_bug(state["bug_id"], diff _file, description, comment_text=comment_text, mark_for_review=self._options.review, mark_for_commit_queue=self._options.request_commit)52 self._tool.bugs.add_patch_to_bug(state["bug_id"], diff, description, comment_text=comment_text, mark_for_review=self._options.review, mark_for_commit_queue=self._options.request_commit) 56 53 if self._options.open_bug: 57 54 self._tool.user.open_url(self._tool.bugs.bug_url_for_bug_id(state["bug_id"])) -
trunk/WebKitTools/Scripts/webkitpy/tool/steps/postdiffforcommit.py
r56497 r57907 27 27 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 28 29 import StringIO30 31 29 from webkitpy.tool.steps.abstractstep import AbstractStep 32 30 … … 36 34 self._tool.bugs.add_patch_to_bug( 37 35 state["bug_id"], 38 StringIO.StringIO(self.cached_lookup(state, "diff")),36 self.cached_lookup(state, "diff"), 39 37 "Patch for landing", 40 38 mark_for_review=False, -
trunk/WebKitTools/Scripts/webkitpy/tool/steps/postdiffforrevert.py
r57462 r57907 27 27 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 28 29 import StringIO30 31 29 from webkitpy.common.net.bugzilla import Attachment 32 30 from webkitpy.tool.steps.abstractstep import AbstractStep … … 45 43 self._tool.bugs.add_patch_to_bug( 46 44 state["bug_id"], 47 StringIO.StringIO(self.cached_lookup(state, "diff")),45 self.cached_lookup(state, "diff"), 48 46 "%s%s" % (Attachment.rollout_preamble, state["revision"]), 49 47 comment_text=comment_text, -
trunk/WebKitTools/Scripts/webkitpy/tool/steps/steps_unittest.py
r57788 r57907 49 49 options = Mock() 50 50 options.update = True 51 self._run_step(Update, options) 51 expected_stderr = "Updating working directory\n" 52 OutputCapture().assert_outputs(self, self._run_step, [Update, options], expected_stderr=expected_stderr) 52 53 53 54 def test_prompt_for_bug_or_title_step(self):
Note: See TracChangeset
for help on using the changeset viewer.