(self, batch: list[int])
| 346 | raise last_error |
| 347 | |
| 348 | def _fetch_batch(self, batch: list[int]) -> dict[int, PullRequestRecord]: |
| 349 | query_parts = [] |
| 350 | for number in batch: |
| 351 | query_parts.append( |
| 352 | f''' |
| 353 | pr_{number}: pullRequest(number: {number}) {{ |
| 354 | title |
| 355 | author {{ login }} |
| 356 | body |
| 357 | labels(first: 50) {{ |
| 358 | nodes {{ name }} |
| 359 | }} |
| 360 | reviews(first: 100, states: APPROVED) {{ |
| 361 | nodes {{ |
| 362 | author {{ login }} |
| 363 | }} |
| 364 | }} |
| 365 | }} |
| 366 | ''' |
| 367 | ) |
| 368 | payload = self._request_graphql( |
| 369 | f''' |
| 370 | query {{ |
| 371 | repository(owner: "{self.owner}", name: "{self.repo}") {{ |
| 372 | {''.join(query_parts)} |
| 373 | }} |
| 374 | }} |
| 375 | ''' |
| 376 | ) |
| 377 | repository = payload['data']['repository'] |
| 378 | results: dict[int, PullRequestRecord] = {} |
| 379 | for number in batch: |
| 380 | node = repository.get(f'pr_{number}') |
| 381 | if node is None: |
| 382 | continue |
| 383 | labels = [item['name'] for item in node['labels']['nodes']] |
| 384 | reviewers = sorted( |
| 385 | { |
| 386 | review['author']['login'] |
| 387 | for review in node['reviews']['nodes'] |
| 388 | if review.get('author') |
| 389 | } |
| 390 | ) |
| 391 | body = node.get('body') or '' |
| 392 | results[number] = PullRequestRecord( |
| 393 | number=number, |
| 394 | title=node.get('title') or f'PR #{number}', |
| 395 | author=(node.get('author') or {}).get('login', ''), |
| 396 | labels=labels, |
| 397 | reviewers=reviewers, |
| 398 | category=resolve_category(labels, body), |
| 399 | topic=resolve_topic(labels, body), |
| 400 | description=resolve_description(body), |
| 401 | ) |
| 402 | return results |
| 403 | |
| 404 | def fetch_pull_requests( |
| 405 | self, numbers: list[int], batch_size: int, workers: int |
no test coverage detected