本文整理汇总了Python中student.models.CourseEnrollment.get_enrollment方法的典型用法代码示例。如果您正苦于以下问题:Python CourseEnrollment.get_enrollment方法的具体用法?Python CourseEnrollment.get_enrollment怎么用?Python CourseEnrollment.get_enrollment使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类student.models.CourseEnrollment
的用法示例。
在下文中一共展示了CourseEnrollment.get_enrollment方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Python代码示例。
示例1: create
# 需要导入模块: from student.models import CourseEnrollment [as 别名]
# 或者: from student.models.CourseEnrollment import get_enrollment [as 别名]
def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
entitlement = serializer.instance
user = entitlement.user
# find all course_runs within the course
course_runs = get_course_runs_for_course(entitlement.course_uuid)
# check if the user has enrollments for any of the course_runs
user_run_enrollments = [
CourseEnrollment.get_enrollment(user, CourseKey.from_string(course_run.get('key')))
for course_run
in course_runs
if CourseEnrollment.get_enrollment(user, CourseKey.from_string(course_run.get('key')))
]
# filter to just enrollments that can be upgraded.
upgradeable_enrollments = [
enrollment
for enrollment
in user_run_enrollments
if enrollment.is_active and enrollment.upgrade_deadline and enrollment.upgrade_deadline > timezone.now()
]
# if there is only one upgradeable enrollment, convert it from audit to the entitlement.mode
# if there is any ambiguity about which enrollment to upgrade
# (i.e. multiple upgradeable enrollments or no available upgradeable enrollment), dont enroll
if len(upgradeable_enrollments) == 1:
enrollment = upgradeable_enrollments[0]
log.info(
'Upgrading enrollment [%s] from %s to %s while adding entitlement for user [%s] for course [%s]',
enrollment,
enrollment.mode,
serializer.data.get('mode'),
user.username,
serializer.data.get('course_uuid')
)
enrollment.update_enrollment(mode=entitlement.mode)
entitlement.set_enrollment(enrollment)
else:
log.info(
'No enrollment upgraded while adding entitlement for user [%s] for course [%s] ',
user.username,
serializer.data.get('course_uuid')
)
headers = self.get_success_headers(serializer.data)
# Note, the entitlement is re-serialized before getting added to the Response,
# so that the 'modified' date reflects changes that occur when upgrading enrollment.
return Response(
CourseEntitlementSerializer(entitlement).data,
status=status.HTTP_201_CREATED, headers=headers
)
示例2: test_course_home_for_global_staff
# 需要导入模块: from student.models import CourseEnrollment [as 别名]
# 或者: from student.models.CourseEnrollment import get_enrollment [as 别名]
def test_course_home_for_global_staff(self):
"""
Tests that staff user can access the course home without being enrolled
in the course.
"""
course = self.course
self.user.is_staff = True
self.user.save()
self.override_waffle_switch(True)
CourseEnrollment.get_enrollment(self.user, course.id).delete()
response = self.visit_course_home(course, start_count=1, resume_count=0)
content = pq(response.content)
self.assertTrue(content('.action-resume-course').attr('href').endswith('/course/' + course.url_name))
示例3: check_and_get_upgrade_link_and_date
# 需要导入模块: from student.models import CourseEnrollment [as 别名]
# 或者: from student.models.CourseEnrollment import get_enrollment [as 别名]
def check_and_get_upgrade_link_and_date(user, enrollment=None, course=None):
"""
For an authenticated user, return a link to allow them to upgrade
in the specified course.
"""
if enrollment is None and course is None:
raise ValueError("Must specify either an enrollment or a course")
if enrollment:
if course is None:
course = enrollment.course
elif enrollment.course_id != course.id:
raise ValueError("{} refers to a different course than {} which was supplied".format(
enrollment, course
))
if enrollment.user_id != user.id:
raise ValueError("{} refers to a different user than {} which was supplied".format(
enrollment, user
))
if enrollment is None:
enrollment = CourseEnrollment.get_enrollment(user, course.id)
if user.is_authenticated and verified_upgrade_link_is_valid(enrollment):
return (
verified_upgrade_deadline_link(user, course),
enrollment.upgrade_deadline
)
return (None, None)
示例4: register_alerts
# 需要导入模块: from student.models import CourseEnrollment [as 别名]
# 或者: from student.models.CourseEnrollment import get_enrollment [as 别名]
def register_alerts(self, request, course):
"""
Registers an alert if the course has not started yet.
"""
is_enrolled = CourseEnrollment.get_enrollment(request.user, course.id)
if not course.start or not is_enrolled:
return
days_until_start = (course.start - self.current_time).days
if course.start > self.current_time:
if days_until_start > 0:
CourseHomeMessages.register_info_message(
request,
Text(_(
"Don't forget to add a calendar reminder!"
)),
title=Text(_("Course starts in {time_remaining_string} on {course_start_date}.")).format(
time_remaining_string=self.time_remaining_string,
course_start_date=self.long_date_html,
)
)
else:
CourseHomeMessages.register_info_message(
request,
Text(_("Course starts in {time_remaining_string} at {course_start_time}.")).format(
time_remaining_string=self.time_remaining_string,
course_start_time=self.short_time_html,
)
)
示例5: course_run_refund_status
# 需要导入模块: from student.models import CourseEnrollment [as 别名]
# 或者: from student.models.CourseEnrollment import get_enrollment [as 别名]
def course_run_refund_status(request, course_id):
"""
Get Refundable status for a course.
Arguments:
request: The request object.
course_id (str): The unique identifier for the course.
Returns:
Json response.
"""
try:
course_key = CourseKey.from_string(course_id)
course_enrollment = CourseEnrollment.get_enrollment(request.user, course_key)
except InvalidKeyError:
logging.exception("The course key used to get refund status caused InvalidKeyError during look up.")
return JsonResponse({'course_refundable_status': ''}, status=406)
refundable_status = course_enrollment.refundable()
logging.info("Course refund status for course {0} is {1}".format(course_id, refundable_status))
return JsonResponse({'course_refundable_status': refundable_status}, status=200)
示例6: sync_cohort_with_mode
# 需要导入模块: from student.models import CourseEnrollment [as 别名]
# 或者: from student.models.CourseEnrollment import get_enrollment [as 别名]
def sync_cohort_with_mode(course_id, user_id, verified_cohort_name):
"""
If the learner's mode does not match their assigned cohort, move the learner into the correct cohort.
It is assumed that this task is only initiated for courses that are using the
Automatic Verified Track Cohorting MVP feature. It is also assumed that before
initiating this task, verification has been done to ensure that the course is
cohorted and has an appropriately named "verified" cohort.
"""
course_key = CourseKey.from_string(course_id)
user = User.objects.get(id=user_id)
enrollment = CourseEnrollment.get_enrollment(user, course_key)
# Note that this will enroll the user in the default cohort on initial enrollment.
# That's good because it will force creation of the default cohort if necessary.
current_cohort = get_cohort(user, course_key)
verified_cohort = get_cohort_by_name(course_key, verified_cohort_name)
if enrollment.mode == CourseMode.VERIFIED and (current_cohort.id != verified_cohort.id):
LOGGER.info(
"MOVING_TO_VERIFIED: Moving user '%s' to the verified cohort for course '%s'", user.username, course_id
)
add_user_to_cohort(verified_cohort, user.username)
elif enrollment.mode != CourseMode.VERIFIED and current_cohort.id == verified_cohort.id:
LOGGER.info(
"MOVING_TO_DEFAULT: Moving user '%s' to the default cohort for course '%s'", user.username, course_id
)
default_cohort = get_cohort_by_name(course_key, DEFAULT_COHORT_NAME)
add_user_to_cohort(default_cohort, user.username)
else:
LOGGER.info(
"NO_ACTION_NECESSARY: No action necessary for user '%s' in course '%s' and enrollment mode '%s'",
user.username, course_id, enrollment.mode
)
示例7: get_upgradeable_enrollments_for_entitlement
# 需要导入模块: from student.models import CourseEnrollment [as 别名]
# 或者: from student.models.CourseEnrollment import get_enrollment [as 别名]
def get_upgradeable_enrollments_for_entitlement(self, entitlement):
"""
Retrieve all the CourseEnrollments that are upgradeable for a given CourseEntitlement
Arguments:
entitlement: CourseEntitlement that we are requesting the CourseEnrollments for.
Returns:
list: List of upgradeable CourseEnrollments
"""
# find all course_runs within the course
course_runs = get_course_runs_for_course(entitlement.course_uuid)
# check if the user has enrollments for any of the course_runs
upgradeable_enrollments = []
for course_run in course_runs:
course_run_id = CourseKey.from_string(course_run.get('key'))
enrollment = CourseEnrollment.get_enrollment(entitlement.user, course_run_id)
if (enrollment and
enrollment.is_active and
is_course_run_entitlement_fulfillable(course_run_id, entitlement)):
upgradeable_enrollments.append(enrollment)
return upgradeable_enrollments
示例8: add_or_update_enrollment_attr
# 需要导入模块: from student.models import CourseEnrollment [as 别名]
# 或者: from student.models.CourseEnrollment import get_enrollment [as 别名]
def add_or_update_enrollment_attr(user_id, course_id, attributes):
"""Set enrollment attributes for the enrollment of given user in the
course provided.
Args:
course_id (str): The Course to set enrollment attributes for.
user_id (str): The User to set enrollment attributes for.
attributes (list): Attributes to be set.
Example:
>>>add_or_update_enrollment_attr(
"Bob",
"course-v1-edX-DemoX-1T2015",
[
{
"namespace": "credit",
"name": "provider_id",
"value": "hogwarts",
},
]
)
"""
course_key = CourseKey.from_string(course_id)
user = _get_user(user_id)
enrollment = CourseEnrollment.get_enrollment(user, course_key)
if not _invalid_attribute(attributes) and enrollment is not None:
CourseEnrollmentAttribute.add_enrollment_attr(enrollment, attributes)
示例9: handle
# 需要导入模块: from student.models import CourseEnrollment [as 别名]
# 或者: from student.models.CourseEnrollment import get_enrollment [as 别名]
def handle(self, *args, **options):
csv_path = options['csv_path']
with open(csv_path) as csvfile:
reader = unicodecsv.DictReader(csvfile)
for row in reader:
username = row['username']
email = row['email']
course_key = row['course_id']
try:
user = User.objects.get(Q(username=username) | Q(email=email))
except ObjectDoesNotExist:
user = None
msg = 'User with username {} or email {} does not exist'.format(username, email)
logger.warning(msg)
try:
course_id = CourseKey.from_string(course_key)
except InvalidKeyError:
course_id = None
msg = 'Invalid course id {course_id}, skipping un-enrollement for {username}, {email}'.format(**row)
logger.warning(msg)
if user and course_id:
enrollment = CourseEnrollment.get_enrollment(user, course_id)
if not enrollment:
msg = 'Enrollment for the user {} in course {} does not exist!'.format(username, course_key)
logger.info(msg)
else:
try:
CourseEnrollment.unenroll(user, course_id, skip_refund=True)
except Exception as err:
msg = 'Error un-enrolling User {} from course {}: '.format(username, course_key, err)
logger.error(msg, exc_info=True)
示例10: get_credit_state
# 需要导入模块: from student.models import CourseEnrollment [as 别名]
# 或者: from student.models.CourseEnrollment import get_enrollment [as 别名]
def get_credit_state(self, user_id, course_key_or_id, return_course_info=False):
"""
Return all information about the user's credit state inside of a given
course.
ARGS:
- user_id: The PK of the User in question
- course_key: The course ID (as string or CourseKey)
RETURNS:
NONE (user not found or is not enrolled or is not credit course)
- or -
{
'enrollment_mode': the mode that the user is enrolled in the course
'profile_fullname': the name that the student registered under, used for verification
'is_credit_course': if the course has been marked as a credit bearing course
'credit_requirement_status': the user's status in fulfilling those requirements
'course_name': optional display name of the course
'course_end_date': optional end date of the course
}
"""
# This seems to need to be here otherwise we get
# circular references when starting up the app
from openedx.core.djangoapps.credit.api.eligibility import (
is_credit_course,
get_credit_requirement_status,
)
# since we have to do name matching during various
# verifications, User must have a UserProfile
try:
user = User.objects.select_related('profile').get(id=user_id)
except ObjectDoesNotExist:
# bad user_id
return None
course_key = _get_course_key(course_key_or_id)
enrollment = CourseEnrollment.get_enrollment(user, course_key)
if not enrollment or not enrollment.is_active:
# not enrolled
return None
result = {
'enrollment_mode': enrollment.mode,
'profile_fullname': user.profile.name,
'student_email': user.email,
'is_credit_course': is_credit_course(course_key),
'credit_requirement_status': get_credit_requirement_status(course_key, user.username)
}
if return_course_info:
course = modulestore().get_course(course_key, depth=0)
result.update({
'course_name': course.display_name,
'course_end_date': course.end,
})
return result
示例11: enabled_for_enrollment
# 需要导入模块: from student.models import CourseEnrollment [as 别名]
# 或者: from student.models.CourseEnrollment import get_enrollment [as 别名]
def enabled_for_enrollment(cls, enrollment=None, user=None, course_key=None):
"""
Return whether Content Type Gating is enabled for this enrollment.
Content Type Gating is enabled for an enrollment if it is enabled for
the course being enrolled in (either specifically, or via a containing context,
such as the org, site, or globally), and if the configuration is specified to be
``enabled_as_of`` before the enrollment was created.
Only one of enrollment and (user, course_key) may be specified at a time.
Arguments:
enrollment: The enrollment being queried.
user: The user being queried.
course_key: The CourseKey of the course being queried.
"""
if CONTENT_TYPE_GATING_FLAG.is_enabled():
return True
if enrollment is not None and (user is not None or course_key is not None):
raise ValueError('Specify enrollment or user/course_key, but not both')
if enrollment is None and (user is None or course_key is None):
raise ValueError('Both user and course_key must be specified if no enrollment is provided')
if enrollment is None and user is None and course_key is None:
raise ValueError('At least one of enrollment or user and course_key must be specified')
if course_key is None:
course_key = enrollment.course_id
if enrollment is None:
enrollment = CourseEnrollment.get_enrollment(user, course_key)
# enrollment might be None if the user isn't enrolled. In that case,
# return enablement as if the user enrolled today
if enrollment is None:
return cls.enabled_for_course(course_key=course_key, target_datetime=timezone.now())
else:
# TODO: clean up as part of REV-100
experiment_data_holdback_key = EXPERIMENT_DATA_HOLDBACK_KEY.format(user)
is_in_holdback = False
no_masquerade = get_course_masquerade(user, course_key) is None
student_masquerade = is_masquerading_as_specific_student(user, course_key)
if user and (no_masquerade or student_masquerade):
try:
holdback_value = ExperimentData.objects.get(
user=user,
experiment_id=EXPERIMENT_ID,
key=experiment_data_holdback_key,
).value
is_in_holdback = holdback_value == 'True'
except ExperimentData.DoesNotExist:
pass
if is_in_holdback:
return False
current_config = cls.current(course_key=enrollment.course_id)
return current_config.enabled_as_of_datetime(target_datetime=enrollment.created)
示例12: get_enrollment_info
# 需要导入模块: from student.models import CourseEnrollment [as 别名]
# 或者: from student.models.CourseEnrollment import get_enrollment [as 别名]
def get_enrollment_info(self, user, course_id):
"""
Returns the User Enrollment information.
"""
course = get_course_by_id(course_id, depth=0)
is_course_staff = bool(has_access(user, 'staff', course))
manual_enrollment_reason = 'N/A'
# check the user enrollment role
if user.is_staff:
platform_name = configuration_helpers.get_value('platform_name', settings.PLATFORM_NAME)
enrollment_role = _('{platform_name} Staff').format(platform_name=platform_name)
elif is_course_staff:
enrollment_role = _('Course Staff')
else:
enrollment_role = _('Student')
course_enrollment = CourseEnrollment.get_enrollment(user=user, course_key=course_id)
if is_course_staff:
enrollment_source = _('Staff')
else:
# get the registration_code_redemption object if exists
registration_code_redemption = RegistrationCodeRedemption.registration_code_used_for_enrollment(
course_enrollment)
# get the paid_course registration item if exists
paid_course_reg_item = PaidCourseRegistration.get_course_item_for_user_enrollment(
user=user,
course_id=course_id,
course_enrollment=course_enrollment
)
# from where the user get here
if registration_code_redemption is not None:
enrollment_source = _('Used Registration Code')
elif paid_course_reg_item is not None:
enrollment_source = _('Credit Card - Individual')
else:
manual_enrollment = ManualEnrollmentAudit.get_manual_enrollment(course_enrollment)
if manual_enrollment is not None:
enrollment_source = _(
'manually enrolled by username: {username}'
).format(username=manual_enrollment.enrolled_by.username)
manual_enrollment_reason = manual_enrollment.reason
else:
enrollment_source = _('Manually Enrolled')
enrollment_date = course_enrollment.created.strftime("%B %d, %Y")
currently_enrolled = course_enrollment.is_active
course_enrollment_data = collections.OrderedDict()
course_enrollment_data['Enrollment Date'] = enrollment_date
course_enrollment_data['Currently Enrolled'] = currently_enrolled
course_enrollment_data['Enrollment Source'] = enrollment_source
course_enrollment_data['Manual (Un)Enrollment Reason'] = manual_enrollment_reason
course_enrollment_data['Enrollment Role'] = enrollment_role
return course_enrollment_data
示例13: post
# 需要导入模块: from student.models import CourseEnrollment [as 别名]
# 或者: from student.models.CourseEnrollment import get_enrollment [as 别名]
def post(self, request, *args, **kwargs):
"""
Attempt to enroll the user.
"""
user = request.user
valid, course_key, error = self._is_data_valid(request)
if not valid:
return DetailResponse(error, status=HTTP_406_NOT_ACCEPTABLE)
embargo_response = embargo_api.get_embargo_response(request, course_key, user)
if embargo_response:
return embargo_response
# Don't do anything if an enrollment already exists
course_id = unicode(course_key)
enrollment = CourseEnrollment.get_enrollment(user, course_key)
if enrollment and enrollment.is_active:
msg = Messages.ENROLLMENT_EXISTS.format(course_id=course_id, username=user.username)
return DetailResponse(msg, status=HTTP_409_CONFLICT)
# Check to see if enrollment for this course is closed.
course = courses.get_course(course_key)
if CourseEnrollment.is_enrollment_closed(user, course):
msg = Messages.ENROLLMENT_CLOSED.format(course_id=course_id)
log.info(u'Unable to enroll user %s in closed course %s.', user.id, course_id)
return DetailResponse(msg, status=HTTP_406_NOT_ACCEPTABLE)
# If there is no audit or honor course mode, this most likely
# a Prof-Ed course. Return an error so that the JS redirects
# to track selection.
honor_mode = CourseMode.mode_for_course(course_key, CourseMode.HONOR)
audit_mode = CourseMode.mode_for_course(course_key, CourseMode.AUDIT)
# Accept either honor or audit as an enrollment mode to
# maintain backwards compatibility with existing courses
default_enrollment_mode = audit_mode or honor_mode
if default_enrollment_mode:
msg = Messages.ENROLL_DIRECTLY.format(
username=user.username,
course_id=course_id
)
if not default_enrollment_mode.sku:
# If there are no course modes with SKUs, return a different message.
msg = Messages.NO_SKU_ENROLLED.format(
enrollment_mode=default_enrollment_mode.slug,
course_id=course_id,
username=user.username
)
log.info(msg)
self._enroll(course_key, user, default_enrollment_mode.slug)
self._handle_marketing_opt_in(request, course_key, user)
return DetailResponse(msg)
else:
msg = Messages.NO_DEFAULT_ENROLLMENT_MODE.format(course_id=course_id)
return DetailResponse(msg, status=HTTP_406_NOT_ACCEPTABLE)
示例14: test_lookup_valid_redeemed_registration_code
# 需要导入模块: from student.models import CourseEnrollment [as 别名]
# 或者: from student.models.CourseEnrollment import get_enrollment [as 别名]
def test_lookup_valid_redeemed_registration_code(self):
"""
test to lookup for the valid and redeemed registration code
and then mark that registration code as un_redeemed
which will unenroll the user and delete the redemption
entry from the database.
"""
student = UserFactory()
self.client.login(username=student.username, password='test')
cart = Order.get_cart_for_user(student)
cart.order_type = 'business'
cart.save()
CourseRegCodeItem.add_to_order(cart, self.course.id, 2)
cart.purchase()
reg_code = CourseRegistrationCode.objects.filter(order=cart)[0]
enrollment = CourseEnrollment.enroll(student, self.course.id)
RegistrationCodeRedemption.objects.create(
registration_code=reg_code,
redeemed_by=student,
course_enrollment=enrollment
)
self.client.login(username=self.instructor.username, password='test')
data = {
'registration_code': reg_code.code
}
response = self.client.get(self.lookup_code_url, data)
self.assertEqual(response.status_code, 200)
json_dict = json.loads(response.content)
self.assertTrue(json_dict['is_registration_code_valid'])
self.assertTrue(json_dict['is_registration_code_redeemed'])
# now mark the registration code as unredeemed
# this will unenroll the user and removed the redemption entry from
# the database.
data = {
'registration_code': reg_code.code,
'action_type': 'unredeem_registration_code'
}
response = self.client.post(self.registration_code_detail_url, data)
self.assertEqual(response.status_code, 200)
json_dict = json.loads(response.content)
message = _('This enrollment code has been marked as unused.')
self.assertEqual(message, json_dict['message'])
redemption = RegistrationCodeRedemption.get_registration_code_redemption(reg_code.code, self.course.id)
self.assertIsNone(redemption)
# now the student course enrollment should be false.
enrollment = CourseEnrollment.get_enrollment(student, self.course.id)
self.assertEqual(enrollment.is_active, False)
示例15: sync_cohort_with_mode
# 需要导入模块: from student.models import CourseEnrollment [as 别名]
# 或者: from student.models.CourseEnrollment import get_enrollment [as 别名]
def sync_cohort_with_mode(self, course_id, user_id, verified_cohort_name, default_cohort_name):
"""
If the learner's mode does not match their assigned cohort, move the learner into the correct cohort.
It is assumed that this task is only initiated for courses that are using the
Automatic Verified Track Cohorting MVP feature. It is also assumed that before
initiating this task, verification has been done to ensure that the course is
cohorted and has an appropriately named "verified" cohort.
"""
course_key = CourseKey.from_string(course_id)
user = User.objects.get(id=user_id)
try:
enrollment = CourseEnrollment.get_enrollment(user, course_key)
# Note that this will enroll the user in the default cohort on initial enrollment.
# That's good because it will force creation of the default cohort if necessary.
try:
current_cohort = get_cohort(user, course_key)
except IntegrityError as integrity_error:
# It is quite common that get_cohort will throw an IntegrityError. This happens
# when 2 celery workers are both handling enrollment change events for the same user
# (for example, if the enrollment mode goes from None -> Audit -> Honor); if the user
# was not previously in a cohort, calling get_cohort will result in a cohort assignment.
LOGGER.info(
"HANDLING_INTEGRITY_ERROR: IntegrityError encountered for course '%s' and user '%s': %s",
course_id, user.id, unicode(integrity_error)
)
current_cohort = get_cohort(user, course_key)
verified_cohort = get_cohort_by_name(course_key, verified_cohort_name)
if enrollment.mode == CourseMode.VERIFIED and (current_cohort.id != verified_cohort.id):
LOGGER.info(
"MOVING_TO_VERIFIED: Moving user '%s' to the verified cohort '%s' for course '%s'",
user.id, verified_cohort.name, course_id
)
add_user_to_cohort(verified_cohort, user.username)
elif enrollment.mode != CourseMode.VERIFIED and current_cohort.id == verified_cohort.id:
default_cohort = get_cohort_by_name(course_key, default_cohort_name)
LOGGER.info(
"MOVING_TO_DEFAULT: Moving user '%s' to the default cohort '%s' for course '%s'",
user.id, default_cohort.name, course_id
)
add_user_to_cohort(default_cohort, user.username)
else:
LOGGER.info(
"NO_ACTION_NECESSARY: No action necessary for user '%s' in course '%s' and enrollment mode '%s'. "
"The user is already in cohort '%s'.",
user.id, course_id, enrollment.mode, current_cohort.name
)
except Exception as exc:
LOGGER.warning(
"SYNC_COHORT_WITH_MODE_RETRY: Exception encountered for course '%s' and user '%s': %s",
course_id, user.id, unicode(exc)
)
raise self.retry(exc=exc)