Skip to content

Commit ef14688

Browse files
committed
Auto merge of #82340 - kennytm:fix-82254, r=Mark-Simulacrum
Fix some Python2→3 error in publish_toolstate.py Fix #82254. The error is primarily due to `data = json.dumps(…)` producing a `str` instead of a `bytes`, which are different types on Python 3. But then `urllib.request.urlopen(…, data)` cannot accept `data` as a `str`, thus the error. This PR added `.encode()` call after `json.dumps()` to ensure we are sending `bytes`. Additionally, we added type annotation to ensure things can statically type-check with `mypy` on both Python 2 and 3.
2 parents ed58a2b + 45da227 commit ef14688

File tree

1 file changed

+34
-16
lines changed

1 file changed

+34
-16
lines changed

src/tools/publish_toolstate.py

+34-16
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,14 @@
1717
import textwrap
1818
try:
1919
import urllib2
20+
from urllib2 import HTTPError
2021
except ImportError:
2122
import urllib.request as urllib2
23+
from urllib.error import HTTPError
24+
try:
25+
import typing
26+
except ImportError:
27+
pass
2228

2329
# List of people to ping when the status of a tool or a book changed.
2430
# These should be collaborators of the rust-lang/rust repository (with at least
@@ -63,20 +69,23 @@
6369
}
6470

6571
def load_json_from_response(resp):
72+
# type: (typing.Any) -> typing.Any
6673
content = resp.read()
6774
if isinstance(content, bytes):
68-
content = content.decode('utf-8')
75+
content_str = content.decode('utf-8')
6976
else:
7077
print("Refusing to decode " + str(type(content)) + " to str")
71-
return json.loads(content)
78+
return json.loads(content_str)
7279

7380
def validate_maintainers(repo, github_token):
81+
# type: (str, str) -> None
7482
'''Ensure all maintainers are assignable on a GitHub repo'''
7583
next_link_re = re.compile(r'<([^>]+)>; rel="next"')
7684

7785
# Load the list of assignable people in the GitHub repo
78-
assignable = []
79-
url = 'https://api.github.com/repos/%s/collaborators?per_page=100' % repo
86+
assignable = [] # type: typing.List[str]
87+
url = 'https://api.github.com/repos/' \
88+
+ '%s/collaborators?per_page=100' % repo # type: typing.Optional[str]
8089
while url is not None:
8190
response = urllib2.urlopen(urllib2.Request(url, headers={
8291
'Authorization': 'token ' + github_token,
@@ -116,9 +125,10 @@ def validate_maintainers(repo, github_token):
116125

117126

118127
def read_current_status(current_commit, path):
128+
# type: (str, str) -> typing.Mapping[str, typing.Any]
119129
'''Reads build status of `current_commit` from content of `history/*.tsv`
120130
'''
121-
with open(path, 'rU') as f:
131+
with open(path, 'r') as f:
122132
for line in f:
123133
(commit, status) = line.split('\t', 1)
124134
if commit == current_commit:
@@ -127,10 +137,12 @@ def read_current_status(current_commit, path):
127137

128138

129139
def gh_url():
140+
# type: () -> str
130141
return os.environ['TOOLSTATE_ISSUES_API_URL']
131142

132143

133144
def maybe_delink(message):
145+
# type: (str) -> str
134146
if os.environ.get('TOOLSTATE_SKIP_MENTIONS') is not None:
135147
return message.replace("@", "")
136148
return message
@@ -143,8 +155,10 @@ def issue(
143155
relevant_pr_number,
144156
relevant_pr_user,
145157
labels,
158+
github_token,
146159
):
147-
# Open an issue about the toolstate failure.
160+
# type: (str, str, typing.Iterable[str], str, str, typing.List[str], str) -> None
161+
'''Open an issue about the toolstate failure.'''
148162
if status == 'test-fail':
149163
status_description = 'has failing tests'
150164
else:
@@ -168,7 +182,7 @@ def issue(
168182
print("Creating issue:\n{}".format(request))
169183
response = urllib2.urlopen(urllib2.Request(
170184
gh_url(),
171-
request,
185+
request.encode(),
172186
{
173187
'Authorization': 'token ' + github_token,
174188
'Content-Type': 'application/json',
@@ -183,8 +197,10 @@ def update_latest(
183197
relevant_pr_url,
184198
relevant_pr_user,
185199
pr_reviewer,
186-
current_datetime
200+
current_datetime,
201+
github_token,
187202
):
203+
# type: (str, str, str, str, str, str, str) -> str
188204
'''Updates `_data/latest.json` to match build result of the given commit.
189205
'''
190206
with open('_data/latest.json', 'r+') as f:
@@ -243,13 +259,14 @@ def update_latest(
243259
if create_issue_for_status is not None:
244260
try:
245261
issue(
246-
tool, create_issue_for_status, MAINTAINERS.get(tool, ''),
247-
relevant_pr_number, relevant_pr_user, LABELS.get(tool, ''),
262+
tool, create_issue_for_status, MAINTAINERS.get(tool, ()),
263+
relevant_pr_number, relevant_pr_user, LABELS.get(tool, []),
264+
github_token,
248265
)
249-
except urllib2.HTTPError as e:
266+
except HTTPError as e:
250267
# network errors will simply end up not creating an issue, but that's better
251268
# than failing the entire build job
252-
print("HTTPError when creating issue for status regression: {0}\n{1}"
269+
print("HTTPError when creating issue for status regression: {0}\n{1!r}"
253270
.format(e, e.read()))
254271
except IOError as e:
255272
print("I/O error when creating issue for status regression: {0}".format(e))
@@ -318,7 +335,8 @@ def update_latest(
318335
relevant_pr_url,
319336
relevant_pr_user,
320337
pr_reviewer,
321-
cur_datetime
338+
cur_datetime,
339+
github_token,
322340
)
323341
if not message:
324342
print('<Nothing changed>')
@@ -337,13 +355,13 @@ def update_latest(
337355
issue_url = gh_url() + '/{}/comments'.format(number)
338356
response = urllib2.urlopen(urllib2.Request(
339357
issue_url,
340-
json.dumps({'body': maybe_delink(message)}),
358+
json.dumps({'body': maybe_delink(message)}).encode(),
341359
{
342360
'Authorization': 'token ' + github_token,
343361
'Content-Type': 'application/json',
344362
}
345363
))
346364
response.read()
347-
except urllib2.HTTPError as e:
348-
print("HTTPError: %s\n%s" % (e, e.read()))
365+
except HTTPError as e:
366+
print("HTTPError: %s\n%r" % (e, e.read()))
349367
raise

0 commit comments

Comments
 (0)