def measure(y_truth, y_pred, method='abs_error'): """this function integrates several metric methods abs_error, rmse, r2, ndcg, cos precision, recall, f1_score, auc, map """ if method == 'abs_error': return AbsError.abs_error(y_truth, y_pred) elif method == 'rmse': return RMSE.rmse(y_truth, y_pred) elif method == 'r2': return R2.r2(y_truth, y_pred) elif method == 'ndcg': return NDCG.ndcg(y_truth, y_pred) elif method == 'cos': return Cosine.cos(y_truth, y_pred) elif method == 'precision': return PR.precision(y_truth, y_pred) elif method == 'recall': return PR.recall(y_truth, y_pred) elif method == 'f1_score': return PR.f1_score(y_truth, y_pred) elif method == 'auc': return AUC.auc(y_truth, y_pred) elif method == 'map': return MAP.map(y_truth, y_pred) raise IllegalInput('no such method!')
def get_dependents_prs(self, pr: PR) -> List[PR]: """ Return a list of dependent PRs. """ dependents = [] for dependent_pr in self.gh_repo.get_pulls(base=pr.head): element = [existing_pr for existing_pr in self.queue if existing_pr.nb == dependent_pr.number] if len(element) > 0: dependents.append(element[0]) else: new_pr = PR(dependent_pr) new_pr.dependents = self.get_dependents_prs(new_pr) dependents.append(new_pr) return dependents
def get_pr(source_ref): status = ci_get('/status', status_code=200) assert 'prs' in status assert '_watched_targets' in status all_prs = [PR.from_json(x) for x in status['prs']] prs = [pr for pr in all_prs if pr.source.ref.name == source_ref] assert len(prs) == 1, [str(x.source.ref) for x in all_prs] return prs[0]
def get_pr(self, pr_nb: int) -> Tuple[Union[PR], Union[Any]]: """ Get PR from the repo. """ try: gh_pr = self.gh_repo.get_pull(pr_nb) return PR(gh_pr), gh_pr except Exception: raise MergeQueueException('Could not find this PR.')
def poll_until_pr_exists_and(source_ref, poll_until_true, delay_in_seconds=DELAY_IN_SECONDS, max_polls=MAX_POLLS): prs = [] polls = 0 while (len(prs) == 0 or not poll_until_true(prs[0])) and polls < max_polls: time.sleep(delay_in_seconds) status = ci_get('/status', status_code=200) assert 'prs' in status assert '_watched_targets' in status all_prs = [PR.from_json(x) for x in status['prs']] prs = [pr for pr in all_prs if pr.source.ref.name == source_ref] assert len(prs) <= 1, [str(x.source.ref) for x in all_prs] polls = polls + 1 assert len(prs) == 1 return prs[0]
def check(self) -> Generator[Tuple[PR, List[PRTransitionParams]], None, None]: new_queue = [] already_merging_a_pr = False for idx, old_pr in enumerate(self.queue): log.debug('Checking pr %s...', old_pr.nb) new_pr, gh_pr = self.get_pr(old_pr.nb) if not new_pr: # it errored continue new_states = [] new_pr.dependents = self.get_dependents_prs(new_pr) if gh_pr.merged: new_states.append((PRTransition.MERGED, None)) if self.remove_pulled_pr(old_pr.nb): new_states.append((PRTransition.RELEASED, None)) for dependent in new_pr.dependents: _, dependent_gh_pr = self.get_pr(dependent.nb) if not _: # it errored continue try: dependent_gh_pr.edit(base=new_pr.base) new_states.append((PRTransition.NEW_BASE, (dependent.nb, dependent.url, new_pr.base))) except Exception: new_states.append((PRTransition.NEW_BASE_ERROR, (dependent.nb, dependent.url, new_pr.base))) # Automatically delete the branch that has been merged and after the children have been updated. try: self.gh_repo.get_git_ref(f'heads/{gh_pr.head.ref}').delete() except: log.exception('Could not remote a dangling PR branch.') elif new_pr.state != 'open': new_states.append((PRTransition.CLOSED, None)) if self.remove_pulled_pr(new_pr.nb): new_states.append((PRTransition.RELEASED, None)) else: # forward the state new_pr.blessed = old_pr.blessed new_pr.start_time = old_pr.start_time if hasattr(old_pr, 'start_time') else PR.generate_start_time() if new_pr.mergeable_state == 'unknown': # Keep the last known state: if it comes back # to the same state we don't spam the chat. new_pr.mergeable_state = old_pr.mergeable_state elif new_pr.mergeable_state == 'unstable': # The GH will mark a PR as unstable if a # non-required status check has not passed new_pr.mergeable_state = 'clean' if self.check_required_statuses(new_pr) else new_pr.mergeable_state elif new_pr.mergeable_state == 'dirty': #Dirty PR signify merge conflicts and will back up the pull queue self.remove_pulled_pr(new_pr.nb) new_queue.append(new_pr) if old_pr.positive != new_pr.positive: new_states.append((PRTransition.GOT_POSITIVE, new_pr.positive)) if old_pr.negative != new_pr.negative: new_states.append((PRTransition.GOT_NEGATIVE, new_pr.negative)) if old_pr.mergeable and not new_pr.mergeable: new_states.append((PRTransition.NO_LONGER_MERGEABLE, None)) if not old_pr.mergeable and new_pr.mergeable: new_states.append((PRTransition.NOW_MERGEABLE, None)) if self.count_dependent_prs(old_pr) != self.count_dependent_prs(new_pr): new_states.append((PRTransition.NEW_CHAINED_PR, self.count_dependent_prs(new_pr))) if not already_merging_a_pr and new_pr.mergeable_state == 'clean' and new_pr.is_ready_to_merge(): new_states.append((PRTransition.MERGING, None)) gh_pr.merge(commit_title='Merged automatically by argobot.') self.stats.send_event('merged', new_pr) self.stats.send_metric('queue_time_to_merge', new_pr.get_queue_time(), new_pr) already_merging_a_pr = True elif new_pr.blessed and new_pr.mergeable_state == 'behind': if new_pr.nb not in self.pulled_prs and len(self.pulled_prs) < self.max_pulled_prs: self.pulled_prs.append(new_pr.nb) new_states.append((PRTransition.PULLED, None)) # pull the base of the PR into the PR. if new_pr.nb in self.pulled_prs: if self.gh_repo.merge(base=gh_pr.head.ref, head=gh_pr.base.ref): new_states.append((PRTransition.PULLED_SUCCESS, None)) else: new_states.append((PRTransition.PULLED_FAILURE, None)) if new_states: yield new_pr, new_states self.queue = new_queue