def rescore(self, only_if_higher):
        """
        Calculate a new raw score and save it to the block.  If only_if_higher
        is True and the score didn't improve, keep the existing score.

        Raises a TypeError if the block cannot be scored.
        Raises a ValueError if the user has not yet completed the problem.

        May also raise other errors in self.calculate_score().  Currently
        unconstrained.
        """

        _ = self.runtime.service(self, 'i18n').ugettext

        if not self.allows_rescore():
            raise TypeError(_('Problem does not support rescoring: {}').format(self.location))

        if not self.has_submitted_answer():
            raise ValueError(_('Cannot rescore unanswered problem: {}').format(self.location))

        new_score = self.calculate_score()
        self._publish_grade(new_score, only_if_higher)