Status: | Merged |
---|---|
Approved by: | Jelmer Vernooij |
Approved revision: | no longer in the source branch. |
Merge reported by: | The Breezy Bot |
Merged at revision: | not available |
Proposed branch: | lp:~jelmer/brz/merge-3.2 |
Merge into: | lp:brz |
Diff against target: |
297 lines (+38/-28) 8 files modified
.github/workflows/pythonpackage.yml (+1/-1) breezy/controldir.py (+2/-2) breezy/errors.py (+4/-3) breezy/git/__init__.py (+2/-1) breezy/plugins/github/hoster.py (+18/-14) breezy/plugins/gitlab/hoster.py (+2/-1) breezy/transport/http/response.py (+2/-1) breezy/transport/http/urllib.py (+7/-5) |
To merge this branch: | bzr merge lp:~jelmer/brz/merge-3.2 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Jelmer Vernooij | Approve | ||
Review via email: mp+409076@code.launchpad.net |
Commit message
Merge lp:brz/3.2.
Description of the change
Merge lp:brz/3.2.
To post a comment you must log in.
Revision history for this message
Jelmer Vernooij (jelmer) : | # |
review:
Approve
Revision history for this message
The Breezy Bot (the-breezy-bot) wrote : | # |
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file '.github/workflows/pythonpackage.yml' | |||
2 | --- .github/workflows/pythonpackage.yml 2020-11-19 01:58:47 +0000 | |||
3 | +++ .github/workflows/pythonpackage.yml 2021-09-23 15:16:28 +0000 | |||
4 | @@ -33,7 +33,7 @@ | |||
5 | 33 | run: | | 33 | run: | |
6 | 34 | python -m pip install --upgrade pip | 34 | python -m pip install --upgrade pip |
7 | 35 | pip install -U pip setuptools | 35 | pip install -U pip setuptools |
9 | 36 | pip install -U pip coverage codecov flake8 testtools paramiko fastimport configobj cython testscenarios six docutils $TEST_REQUIRE sphinx sphinx_epytext launchpadlib patiencediff pyinotify git+https://github.com/dulwich/dulwich | 36 | pip install -U pip coverage codecov flake8 testtools paramiko fastbencode fastimport configobj cython testscenarios six docutils $TEST_REQUIRE sphinx sphinx_epytext launchpadlib patiencediff pyinotify git+https://github.com/dulwich/dulwich |
10 | 37 | - name: Build docs | 37 | - name: Build docs |
11 | 38 | run: | | 38 | run: | |
12 | 39 | make docs PYTHON=python | 39 | make docs PYTHON=python |
13 | 40 | 40 | ||
14 | === removed file 'README_BDIST_RPM' | |||
15 | === modified file 'breezy/controldir.py' | |||
16 | --- breezy/controldir.py 2021-08-29 20:05:31 +0000 | |||
17 | +++ breezy/controldir.py 2021-09-23 15:16:28 +0000 | |||
18 | @@ -773,7 +773,7 @@ | |||
19 | 773 | return klass.open_containing_from_transport(transport) | 773 | return klass.open_containing_from_transport(transport) |
20 | 774 | 774 | ||
21 | 775 | @classmethod | 775 | @classmethod |
23 | 776 | def open_containing_from_transport(klass, a_transport): | 776 | def open_containing_from_transport(klass, a_transport, probers=None): |
24 | 777 | """Open an existing branch which contains a_transport.base. | 777 | """Open an existing branch which contains a_transport.base. |
25 | 778 | 778 | ||
26 | 779 | This probes for a branch at a_transport, and searches upwards from there. | 779 | This probes for a branch at a_transport, and searches upwards from there. |
27 | @@ -791,7 +791,7 @@ | |||
28 | 791 | url = a_transport.base | 791 | url = a_transport.base |
29 | 792 | while True: | 792 | while True: |
30 | 793 | try: | 793 | try: |
32 | 794 | result = klass.open_from_transport(a_transport) | 794 | result = klass.open_from_transport(a_transport, probers=probers) |
33 | 795 | return result, urlutils.unescape(a_transport.relpath(url)) | 795 | return result, urlutils.unescape(a_transport.relpath(url)) |
34 | 796 | except errors.NotBranchError: | 796 | except errors.NotBranchError: |
35 | 797 | pass | 797 | pass |
36 | 798 | 798 | ||
37 | === modified file 'breezy/errors.py' | |||
38 | --- breezy/errors.py 2020-08-10 15:00:17 +0000 | |||
39 | +++ breezy/errors.py 2021-09-23 15:16:28 +0000 | |||
40 | @@ -1269,7 +1269,7 @@ | |||
41 | 1269 | 1269 | ||
42 | 1270 | _fmt = "Invalid http response for %(path)s: %(msg)s%(orig_error)s" | 1270 | _fmt = "Invalid http response for %(path)s: %(msg)s%(orig_error)s" |
43 | 1271 | 1271 | ||
45 | 1272 | def __init__(self, path, msg, orig_error=None): | 1272 | def __init__(self, path, msg, orig_error=None, headers=None): |
46 | 1273 | self.path = path | 1273 | self.path = path |
47 | 1274 | if orig_error is None: | 1274 | if orig_error is None: |
48 | 1275 | orig_error = '' | 1275 | orig_error = '' |
49 | @@ -1277,6 +1277,7 @@ | |||
50 | 1277 | # This is reached for obscure and unusual errors so we want to | 1277 | # This is reached for obscure and unusual errors so we want to |
51 | 1278 | # preserve as much info as possible to ease debug. | 1278 | # preserve as much info as possible to ease debug. |
52 | 1279 | orig_error = ': %r' % (orig_error,) | 1279 | orig_error = ': %r' % (orig_error,) |
53 | 1280 | self.headers = headers | ||
54 | 1280 | TransportError.__init__(self, msg, orig_error=orig_error) | 1281 | TransportError.__init__(self, msg, orig_error=orig_error) |
55 | 1281 | 1282 | ||
56 | 1282 | 1283 | ||
57 | @@ -1284,7 +1285,7 @@ | |||
58 | 1284 | 1285 | ||
59 | 1285 | _fmt = "Unexpected HTTP status %(code)d for %(path)s: %(extra)s" | 1286 | _fmt = "Unexpected HTTP status %(code)d for %(path)s: %(extra)s" |
60 | 1286 | 1287 | ||
62 | 1287 | def __init__(self, path, code, extra=None): | 1288 | def __init__(self, path, code, extra=None, headers=None): |
63 | 1288 | self.path = path | 1289 | self.path = path |
64 | 1289 | self.code = code | 1290 | self.code = code |
65 | 1290 | self.extra = extra or '' | 1291 | self.extra = extra or '' |
66 | @@ -1292,7 +1293,7 @@ | |||
67 | 1292 | if extra is not None: | 1293 | if extra is not None: |
68 | 1293 | full_msg += ': ' + extra | 1294 | full_msg += ': ' + extra |
69 | 1294 | InvalidHttpResponse.__init__( | 1295 | InvalidHttpResponse.__init__( |
71 | 1295 | self, path, full_msg) | 1296 | self, path, full_msg, headers=headers) |
72 | 1296 | 1297 | ||
73 | 1297 | 1298 | ||
74 | 1298 | class BadHttpRequest(UnexpectedHttpStatus): | 1299 | class BadHttpRequest(UnexpectedHttpStatus): |
75 | 1299 | 1300 | ||
76 | === modified file 'breezy/git/__init__.py' | |||
77 | --- breezy/git/__init__.py 2020-11-16 22:17:09 +0000 | |||
78 | +++ breezy/git/__init__.py 2021-09-23 15:16:28 +0000 | |||
79 | @@ -185,7 +185,8 @@ | |||
80 | 185 | # hgweb :( | 185 | # hgweb :( |
81 | 186 | raise brz_errors.NotBranchError(transport.base) | 186 | raise brz_errors.NotBranchError(transport.base) |
82 | 187 | elif resp.status != 200: | 187 | elif resp.status != 200: |
84 | 188 | raise brz_errors.UnexpectedHttpStatus(url, resp.status) | 188 | raise brz_errors.UnexpectedHttpStatus( |
85 | 189 | url, resp.status, headers=resp.getheaders()) | ||
86 | 189 | 190 | ||
87 | 190 | ct = resp.getheader("Content-Type") | 191 | ct = resp.getheader("Content-Type") |
88 | 191 | if ct and ct.startswith("application/x-git"): | 192 | if ct and ct.startswith("application/x-git"): |
89 | 192 | 193 | ||
90 | === modified file 'breezy/plugins/github/hoster.py' | |||
91 | --- breezy/plugins/github/hoster.py 2021-05-02 15:07:21 +0000 | |||
92 | +++ breezy/plugins/github/hoster.py 2021-09-23 15:16:28 +0000 | |||
93 | @@ -168,7 +168,8 @@ | |||
94 | 168 | if response.status == 422: | 168 | if response.status == 422: |
95 | 169 | raise ValidationFailed(json.loads(response.text)) | 169 | raise ValidationFailed(json.loads(response.text)) |
96 | 170 | if response.status != 200: | 170 | if response.status != 200: |
98 | 171 | raise UnexpectedHttpStatus(self._pr['url'], response.status) | 171 | raise UnexpectedHttpStatus( |
99 | 172 | self._pr['url'], response.status, headers=response.getheaders()) | ||
100 | 172 | self._pr = json.loads(response.text) | 173 | self._pr = json.loads(response.text) |
101 | 173 | 174 | ||
102 | 174 | def set_description(self, description): | 175 | def set_description(self, description): |
103 | @@ -205,7 +206,8 @@ | |||
104 | 205 | if response.status == 422: | 206 | if response.status == 422: |
105 | 206 | raise ValidationFailed(json.loads(response.text)) | 207 | raise ValidationFailed(json.loads(response.text)) |
106 | 207 | if response.status != 200: | 208 | if response.status != 200: |
108 | 208 | raise UnexpectedHttpStatus(self._pr['url'], response.status) | 209 | raise UnexpectedHttpStatus( |
109 | 210 | self._pr['url'], response.status, headers=response.getheaders()) | ||
110 | 209 | 211 | ||
111 | 210 | def get_merged_by(self): | 212 | def get_merged_by(self): |
112 | 211 | merged_by = self._pr.get('merged_by') | 213 | merged_by = self._pr.get('merged_by') |
113 | @@ -228,7 +230,7 @@ | |||
114 | 228 | raise ValidationFailed(json.loads(response.text)) | 230 | raise ValidationFailed(json.loads(response.text)) |
115 | 229 | if response.status != 201: | 231 | if response.status != 201: |
116 | 230 | raise UnexpectedHttpStatus( | 232 | raise UnexpectedHttpStatus( |
118 | 231 | self._pr['comments_url'], response.status) | 233 | self._pr['comments_url'], response.status, headers=response.getheaders()) |
119 | 232 | json.loads(response.text) | 234 | json.loads(response.text) |
120 | 233 | 235 | ||
121 | 234 | 236 | ||
122 | @@ -295,7 +297,8 @@ | |||
123 | 295 | raise NoSuchProject(path) | 297 | raise NoSuchProject(path) |
124 | 296 | if response.status == 200: | 298 | if response.status == 200: |
125 | 297 | return json.loads(response.text) | 299 | return json.loads(response.text) |
127 | 298 | raise UnexpectedHttpStatus(path, response.status) | 300 | raise UnexpectedHttpStatus( |
128 | 301 | path, response.status, headers=response.getheaders()) | ||
129 | 299 | 302 | ||
130 | 300 | def _get_repo_pulls(self, path, head=None, state=None): | 303 | def _get_repo_pulls(self, path, head=None, state=None): |
131 | 301 | path = path + '?' | 304 | path = path + '?' |
132 | @@ -311,7 +314,7 @@ | |||
133 | 311 | raise NoSuchProject(path) | 314 | raise NoSuchProject(path) |
134 | 312 | if response.status == 200: | 315 | if response.status == 200: |
135 | 313 | return json.loads(response.text) | 316 | return json.loads(response.text) |
137 | 314 | raise UnexpectedHttpStatus(path, response.status) | 317 | raise UnexpectedHttpStatus(path, response.status, headers=response.getheaders()) |
138 | 315 | 318 | ||
139 | 316 | def _create_pull(self, path, title, head, base, body=None, labels=None, | 319 | def _create_pull(self, path, title, head, base, body=None, labels=None, |
140 | 317 | assignee=None, draft=False, maintainer_can_modify=False): | 320 | assignee=None, draft=False, maintainer_can_modify=False): |
141 | @@ -336,14 +339,14 @@ | |||
142 | 336 | if response.status == 422: | 339 | if response.status == 422: |
143 | 337 | raise ValidationFailed(json.loads(response.text)) | 340 | raise ValidationFailed(json.loads(response.text)) |
144 | 338 | if response.status != 201: | 341 | if response.status != 201: |
146 | 339 | raise UnexpectedHttpStatus(path, response.status) | 342 | raise UnexpectedHttpStatus(path, response.status, headers=response.getheaders()) |
147 | 340 | return json.loads(response.text) | 343 | return json.loads(response.text) |
148 | 341 | 344 | ||
149 | 342 | def _get_user_by_email(self, email): | 345 | def _get_user_by_email(self, email): |
150 | 343 | path = 'search/users?q=%s+in:email' % email | 346 | path = 'search/users?q=%s+in:email' % email |
151 | 344 | response = self._api_request('GET', path) | 347 | response = self._api_request('GET', path) |
152 | 345 | if response.status != 200: | 348 | if response.status != 200: |
154 | 346 | raise UnexpectedHttpStatus(path, response.status) | 349 | raise UnexpectedHttpStatus(path, response.status, headers=response.getheaders()) |
155 | 347 | ret = json.loads(response.text) | 350 | ret = json.loads(response.text) |
156 | 348 | if ret['total_count'] == 0: | 351 | if ret['total_count'] == 0: |
157 | 349 | raise KeyError('no user with email %s' % email) | 352 | raise KeyError('no user with email %s' % email) |
158 | @@ -358,14 +361,14 @@ | |||
159 | 358 | path = 'user' | 361 | path = 'user' |
160 | 359 | response = self._api_request('GET', path) | 362 | response = self._api_request('GET', path) |
161 | 360 | if response.status != 200: | 363 | if response.status != 200: |
163 | 361 | raise UnexpectedHttpStatus(path, response.status) | 364 | raise UnexpectedHttpStatus(path, response.status, headers=response.getheaders()) |
164 | 362 | return json.loads(response.text) | 365 | return json.loads(response.text) |
165 | 363 | 366 | ||
166 | 364 | def _get_organization(self, name): | 367 | def _get_organization(self, name): |
167 | 365 | path = 'orgs/%s' % name | 368 | path = 'orgs/%s' % name |
168 | 366 | response = self._api_request('GET', path) | 369 | response = self._api_request('GET', path) |
169 | 367 | if response.status != 200: | 370 | if response.status != 200: |
171 | 368 | raise UnexpectedHttpStatus(path, response.status) | 371 | raise UnexpectedHttpStatus(path, response.status, headers=response.getheaders()) |
172 | 369 | return json.loads(response.text) | 372 | return json.loads(response.text) |
173 | 370 | 373 | ||
174 | 371 | def _list_paged(self, path, parameters=None, per_page=None): | 374 | def _list_paged(self, path, parameters=None, per_page=None): |
175 | @@ -384,7 +387,7 @@ | |||
176 | 384 | ';'.join(['%s=%s' % (k, urlutils.quote(v)) | 387 | ';'.join(['%s=%s' % (k, urlutils.quote(v)) |
177 | 385 | for (k, v) in parameters.items()])) | 388 | for (k, v) in parameters.items()])) |
178 | 386 | if response.status != 200: | 389 | if response.status != 200: |
180 | 387 | raise UnexpectedHttpStatus(path, response.status) | 390 | raise UnexpectedHttpStatus(path, response.status, headers=response.getheaders()) |
181 | 388 | data = json.loads(response.text) | 391 | data = json.loads(response.text) |
182 | 389 | for entry in data['items']: | 392 | for entry in data['items']: |
183 | 390 | i += 1 | 393 | i += 1 |
184 | @@ -402,7 +405,7 @@ | |||
185 | 402 | path += '?organization=%s' % owner | 405 | path += '?organization=%s' % owner |
186 | 403 | response = self._api_request('POST', path) | 406 | response = self._api_request('POST', path) |
187 | 404 | if response.status != 202: | 407 | if response.status != 202: |
189 | 405 | raise UnexpectedHttpStatus(path, response.status) | 408 | raise UnexpectedHttpStatus(path, response.status, headers=response.getheaders()) |
190 | 406 | return json.loads(response.text) | 409 | return json.loads(response.text) |
191 | 407 | 410 | ||
192 | 408 | @property | 411 | @property |
193 | @@ -558,7 +561,7 @@ | |||
194 | 558 | url = issue['pull_request']['url'] | 561 | url = issue['pull_request']['url'] |
195 | 559 | response = self._api_request('GET', url) | 562 | response = self._api_request('GET', url) |
196 | 560 | if response.status != 200: | 563 | if response.status != 200: |
198 | 561 | raise UnexpectedHttpStatus(url, response.status) | 564 | raise UnexpectedHttpStatus(url, response.status, headers=response.getheaders()) |
199 | 562 | yield GitHubMergeProposal(self, json.loads(response.text)) | 565 | yield GitHubMergeProposal(self, json.loads(response.text)) |
200 | 563 | 566 | ||
201 | 564 | def get_proposal_by_url(self, url): | 567 | def get_proposal_by_url(self, url): |
202 | @@ -571,7 +574,8 @@ | |||
203 | 571 | path = '/user/repos' | 574 | path = '/user/repos' |
204 | 572 | response = self._api_request('GET', path) | 575 | response = self._api_request('GET', path) |
205 | 573 | if response.status != 200: | 576 | if response.status != 200: |
207 | 574 | raise UnexpectedHttpStatus(self.transport.user_url, response.status) | 577 | raise UnexpectedHttpStatus( |
208 | 578 | self.transport.user_url, response.status, headers=response.getheaders()) | ||
209 | 575 | for project in json.loads(response.text): | 579 | for project in json.loads(response.text): |
210 | 576 | if not project['fork']: | 580 | if not project['fork']: |
211 | 577 | continue | 581 | continue |
212 | @@ -586,7 +590,7 @@ | |||
213 | 586 | return | 590 | return |
214 | 587 | if response.status == 200: | 591 | if response.status == 200: |
215 | 588 | return json.loads(response.text) | 592 | return json.loads(response.text) |
217 | 589 | raise UnexpectedHttpStatus(path, response.status) | 593 | raise UnexpectedHttpStatus(path, response.status, headers=response.getheaders()) |
218 | 590 | 594 | ||
219 | 591 | def get_current_user(self): | 595 | def get_current_user(self): |
220 | 592 | if self._token is not None: | 596 | if self._token is not None: |
221 | 593 | 597 | ||
222 | === modified file 'breezy/plugins/gitlab/hoster.py' | |||
223 | --- breezy/plugins/gitlab/hoster.py 2021-05-02 15:07:21 +0000 | |||
224 | +++ breezy/plugins/gitlab/hoster.py 2021-09-23 15:16:28 +0000 | |||
225 | @@ -232,7 +232,8 @@ | |||
226 | 232 | 232 | ||
227 | 233 | def _unexpected_status(path, response): | 233 | def _unexpected_status(path, response): |
228 | 234 | raise errors.UnexpectedHttpStatus( | 234 | raise errors.UnexpectedHttpStatus( |
230 | 235 | path, response.status, response.data.decode('utf-8', 'replace')) | 235 | path, response.status, response.data.decode('utf-8', 'replace'), |
231 | 236 | headers=response.getheaders()) | ||
232 | 236 | 237 | ||
233 | 237 | 238 | ||
234 | 238 | class GitLabMergeProposal(MergeProposal): | 239 | class GitLabMergeProposal(MergeProposal): |
235 | 239 | 240 | ||
236 | === modified file 'breezy/transport/http/response.py' | |||
237 | --- breezy/transport/http/response.py 2020-07-18 23:14:00 +0000 | |||
238 | +++ breezy/transport/http/response.py 2021-09-23 15:16:28 +0000 | |||
239 | @@ -218,7 +218,8 @@ | |||
240 | 218 | if content_range is None: | 218 | if content_range is None: |
241 | 219 | raise errors.InvalidHttpResponse( | 219 | raise errors.InvalidHttpResponse( |
242 | 220 | self._path, | 220 | self._path, |
244 | 221 | 'Content-Range header missing in a multi-part response') | 221 | 'Content-Range header missing in a multi-part response', |
245 | 222 | headers=self._headers) | ||
246 | 222 | self.set_range_from_header(content_range) | 223 | self.set_range_from_header(content_range) |
247 | 223 | 224 | ||
248 | 224 | def set_range_from_header(self, content_range): | 225 | def set_range_from_header(self, content_range): |
249 | 225 | 226 | ||
250 | === modified file 'breezy/transport/http/urllib.py' | |||
251 | --- breezy/transport/http/urllib.py 2021-05-02 15:07:21 +0000 | |||
252 | +++ breezy/transport/http/urllib.py 2021-09-23 15:16:28 +0000 | |||
253 | @@ -1732,7 +1732,8 @@ | |||
254 | 1732 | else: | 1732 | else: |
255 | 1733 | raise errors.UnexpectedHttpStatus( | 1733 | raise errors.UnexpectedHttpStatus( |
256 | 1734 | req.get_full_url(), code, | 1734 | req.get_full_url(), code, |
258 | 1735 | 'Unable to handle http code: %s' % msg) | 1735 | 'Unable to handle http code: %s' % msg, |
259 | 1736 | headers=hdrs) | ||
260 | 1736 | 1737 | ||
261 | 1737 | 1738 | ||
262 | 1738 | class Opener(object): | 1739 | class Opener(object): |
263 | @@ -1983,7 +1984,7 @@ | |||
264 | 1983 | else: | 1984 | else: |
265 | 1984 | raise errors.BadHttpRequest(abspath, response.reason) | 1985 | raise errors.BadHttpRequest(abspath, response.reason) |
266 | 1985 | elif response.status not in (200, 206): | 1986 | elif response.status not in (200, 206): |
268 | 1986 | raise errors.UnexpectedHttpStatus(abspath, response.status) | 1987 | raise errors.UnexpectedHttpStatus(abspath, response.status, headers=response.getheaders()) |
269 | 1987 | 1988 | ||
270 | 1988 | data = handle_response( | 1989 | data = handle_response( |
271 | 1989 | abspath, response.status, response.getheader, response) | 1990 | abspath, response.status, response.getheader, response) |
272 | @@ -2214,7 +2215,7 @@ | |||
273 | 2214 | 'POST', abspath, body=body_bytes, | 2215 | 'POST', abspath, body=body_bytes, |
274 | 2215 | headers={'Content-Type': 'application/octet-stream'}) | 2216 | headers={'Content-Type': 'application/octet-stream'}) |
275 | 2216 | if response.status not in (200, 403): | 2217 | if response.status not in (200, 403): |
277 | 2217 | raise errors.UnexpectedHttpStatus(abspath, response.status) | 2218 | raise errors.UnexpectedHttpStatus(abspath, response.status, headers=response.getheaders()) |
278 | 2218 | code = response.status | 2219 | code = response.status |
279 | 2219 | data = handle_response( | 2220 | data = handle_response( |
280 | 2220 | abspath, code, response.getheader, response) | 2221 | abspath, code, response.getheader, response) |
281 | @@ -2228,7 +2229,7 @@ | |||
282 | 2228 | abspath = self._remote_path(relpath) | 2229 | abspath = self._remote_path(relpath) |
283 | 2229 | response = self.request('HEAD', abspath) | 2230 | response = self.request('HEAD', abspath) |
284 | 2230 | if response.status not in (200, 404): | 2231 | if response.status not in (200, 404): |
286 | 2231 | raise errors.UnexpectedHttpStatus(abspath, response.status) | 2232 | raise errors.UnexpectedHttpStatus(abspath, response.status, headers=response.getheaders()) |
287 | 2232 | 2233 | ||
288 | 2233 | return response | 2234 | return response |
289 | 2234 | 2235 | ||
290 | @@ -2457,7 +2458,8 @@ | |||
291 | 2457 | if resp.status in (403, 405): | 2458 | if resp.status in (403, 405): |
292 | 2458 | raise errors.InvalidHttpResponse( | 2459 | raise errors.InvalidHttpResponse( |
293 | 2459 | abspath, | 2460 | abspath, |
295 | 2460 | "OPTIONS not supported or forbidden for remote URL") | 2461 | "OPTIONS not supported or forbidden for remote URL", |
296 | 2462 | headers=resp.getheaders()) | ||
297 | 2461 | return resp.getheaders() | 2463 | return resp.getheaders() |
298 | 2462 | 2464 | ||
299 | 2463 | 2465 |
Running landing tests failed /ci.breezy- vcs.org/ job/brz/ job/brz- land/845/
https:/