Change:
Updated the toolstate repository at https://rust-lang- currently does not seem to work, see e.g. To "tool failed to build"-issues are being created, either. remarked that the error . Cc

Discussion:
import textwrap try: import urllib2 <ins> from urllib2 import HTTPError </ins> except ImportError: import urllib.request as urllib2 <ins> from urllib.error import HTTPError try: import typing except ImportError: pass </ins> # List of people to ping when the status of a tool or a book changed. # These should be collaborators of the rust-lang/rust repository (with at least

} def load_json_from_response(resp): <ins> # type: (typing.Any) -> typing.Any </ins> content = resp.read() if isinstance(content, bytes): <del> content = content.decode('utf-8') </del> <ins> content_str = content.decode('utf-8') </ins> else: print("Refusing to decode " + str(type(content)) + " to str") <del> return json.loads(content) </del> <ins> return json.loads(content_str) </ins> def validate_maintainers(repo, github_token): <ins> # type: (str, str) -> None </ins> '''Ensure all maintainers are assignable on a GitHub repo''' next_link_re = re.compile(r'<([^>]+)>; rel="next"') # Load the list of assignable people in the GitHub repo <del> assignable = [] url = 'https://api.github.com/repos/%s/collaborators?per_page=100' % repo </del> <ins> assignable = [] # type: typing.List[str] url = 'https://api.github.com/repos/'  + '%s/collaborators?per_page=100' % repo # type: typing.Optional[str] </ins> while url is not None: response = urllib2.urlopen(urllib2.Request(url, headers={ 'Authorization': 'token ' + github_token,

def read_current_status(current_commit, path): <ins> # type: (str, str) -> typing.Mapping[str, typing.Any] </ins> '''Reads build status of `current_commit` from content of `history/*.tsv` ''' <del> with open(path, 'rU') as f: </del> <ins> with open(path, 'r') as f: </ins> for line in f: (commit, status) = line.split('t', 1) if commit == current_commit:

def gh_url(): <ins> # type: () -> str </ins> return os.environ['TOOLSTATE_ISSUES_API_URL'] def maybe_delink(message): <ins> # type: (str) -> str </ins> if os.environ.get('TOOLSTATE_SKIP_MENTIONS') is not None: return message.replace("@", "") return message

relevant_pr_number, relevant_pr_user, labels, <ins> github_token, </ins> ): <del> # Open an issue about the toolstate failure. </del> <ins> # type: (str, str, typing.Iterable[str], str, str, typing.List[str], str) -> None '''Open an issue about the toolstate failure.''' </ins> if status == 'test-fail': status_description = 'has failing tests' else:

print("Creating issue:n{}".format(request)) response = urllib2.urlopen(urllib2.Request( gh_url(), <del> request, </del> <ins> request.encode(), </ins> { 'Authorization': 'token ' + github_token, 'Content-Type': 'application/json',

relevant_pr_url, relevant_pr_user, pr_reviewer, <del> current_datetime </del> <ins> current_datetime, github_token, </ins> ): <ins> # type: (str, str, str, str, str, str, str) -> str </ins> '''Updates `_data/latest.json` to match build result of the given commit. ''' with open('_data/latest.json', 'r+') as f:

if create_issue_for_status is not None: try: issue( <del> tool, create_issue_for_status, MAINTAINERS.get(tool, ''), relevant_pr_number, relevant_pr_user, LABELS.get(tool, ''), </del> <ins> tool, create_issue_for_status, MAINTAINERS.get(tool, ()), relevant_pr_number, relevant_pr_user, LABELS.get(tool, []), github_token, </ins> ) <del> except urllib2.HTTPError as e: </del> <ins> except HTTPError as e: </ins> # network errors will simply end up not creating an issue, but that's better # than failing the entire build job <del> print("HTTPError when creating issue for status regression: {0}n{1}" </del> <ins> print("HTTPError when creating issue for status regression: {0}n{1!r}" </ins> .format(e, e.read())) except IOError as e: print("I/O error when creating issue for status regression: {0}".format(e))

relevant_pr_url, relevant_pr_user, pr_reviewer, <del> cur_datetime </del> <ins> cur_datetime, github_token, </ins> ) if not message: print('<Nothing changed>')

issue_url = gh_url() + '/{}/comments'.format(number) response = urllib2.urlopen(urllib2.Request( issue_url, <del> json.dumps({'body': maybe_delink(message)}), </del> <ins> json.dumps({'body': maybe_delink(message)}).encode(), </ins> { 'Authorization': 'token ' + github_token, 'Content-Type': 'application/json', } )) response.read() <del> except urllib2.HTTPError as e: print("HTTPError: %sn%s" % (e, e.read())) </del> <ins> except HTTPError as e: print("HTTPError: %sn%r" % (e, e.read())) </ins> raise