def populate_groups(result: Result[Requirement, Candidate, str]) -> None:
    """Find where the candidates come from by traversing
    the dependency tree back to the top.
    """

    resolved: dict[str, set[str]] = {}

    def get_candidate_groups(key: str) -> set[str]:
        if key in resolved:
            return resolved[key]
        res = resolved[key] = set()
        crit = result.criteria[key]
        for req, parent in crit.information:
            res.update(req.groups)
            if parent is not None:
                pkey = _identify_parent(parent)
                res.update(get_candidate_groups(pkey))
        return res

    for k, can in result.mapping.items():
        can.req.groups = sorted(get_candidate_groups(k))
Find where the candidates come from by traversing
    the dependency tree back to the top.
    
src/pdm/resolver/graph.py