diff --git a/affiliate/factories.py b/affiliate/factories.py index 3edd60728b..e802f932d6 100644 --- a/affiliate/factories.py +++ b/affiliate/factories.py @@ -12,7 +12,7 @@ class AffiliateFactory(DjangoModelFactory): """Factory for Affiliate""" - code = factory.Sequence("affiliate-code-{0}".format) + code = factory.Sequence("affiliate-code-{}".format) name = fuzzy.FuzzyText(prefix="Affiliate ", length=30) class Meta: diff --git a/authentication/middleware.py b/authentication/middleware.py index 258254dbd2..b52eeccb5b 100644 --- a/authentication/middleware.py +++ b/authentication/middleware.py @@ -30,7 +30,7 @@ def process_exception(self, request, exception): url = self.get_redirect_uri(request, exception) if url: # noqa: RET503 - url += ("?" in url and "&" or "?") + "message={0}&backend={1}".format( # noqa: UP030, UP032 + url += ("?" in url and "&" or "?") + "message={}&backend={}".format( # noqa: UP030, UP032 quote(message), backend_name ) return redirect(url) diff --git a/authentication/pipeline/user.py b/authentication/pipeline/user.py index 8baef17105..5c21c60ff6 100644 --- a/authentication/pipeline/user.py +++ b/authentication/pipeline/user.py @@ -145,7 +145,7 @@ def create_user_via_email( created_user = create_user_with_generated_username(serializer, username) if created_user is None: raise IntegrityError( # noqa: TRY301 - "Failed to create User with generated username ({})".format(username) # noqa: EM103, UP032 + f"Failed to create User with generated username ({username})" # noqa: EM103, UP032 ) except Exception as exc: raise UserCreationFailedException(backend, current_partial) from exc diff --git a/cms/factories.py b/cms/factories.py index 5398fb33bd..8368ff4ab1 100644 --- a/cms/factories.py +++ b/cms/factories.py @@ -69,7 +69,7 @@ class Meta: class ProgramPageFactory(wagtail_factories.PageFactory): """ProgramPage factory class""" - title = factory.Sequence("Test page - Program {0}".format) + title = factory.Sequence("Test page - Program {}".format) program = factory.SubFactory(ProgramFactory, page=None) subhead = factory.fuzzy.FuzzyText(prefix="Subhead ") thumbnail_image = factory.SubFactory(wagtail_factories.ImageFactory) @@ -99,7 +99,7 @@ def post_gen(obj, create, extracted, **kwargs): # noqa: ARG002, N805 class CoursePageFactory(wagtail_factories.PageFactory): """CoursePage factory class""" - title = factory.Sequence("Test page - Course {0}".format) + title = factory.Sequence("Test page - Course {}".format) course = factory.SubFactory(CourseFactory, page=None) subhead = factory.fuzzy.FuzzyText(prefix="Subhead ") thumbnail_image = factory.SubFactory(wagtail_factories.ImageFactory) @@ -131,7 +131,7 @@ class ExternalCoursePageFactory(wagtail_factories.PageFactory): course = factory.SubFactory(CourseFactory, page=None) - title = factory.Sequence("Test page - External Course {0}".format) + title = factory.Sequence("Test page - External Course {}".format) external_marketing_url = factory.Faker("uri") marketing_hubspot_form_id = factory.Faker("bothify", text="??????????") subhead = factory.fuzzy.FuzzyText(prefix="Subhead ") @@ -160,7 +160,7 @@ class ExternalProgramPageFactory(wagtail_factories.PageFactory): program = factory.SubFactory(ProgramFactory, page=None) - title = factory.Sequence("Test page - External Program {0}".format) + title = factory.Sequence("Test page - External Program {}".format) external_marketing_url = factory.Faker("uri") marketing_hubspot_form_id = factory.Faker("bothify", text="??????????") subhead = factory.fuzzy.FuzzyText(prefix="Subhead ") diff --git a/cms/models.py b/cms/models.py index cfcbf7b7a6..29471a899c 100644 --- a/cms/models.py +++ b/cms/models.py @@ -213,7 +213,7 @@ def get_context(self, request, *args, **kwargs): .exclude(Q(category=UPCOMING_WEBINAR) & Q(date__lt=now_in_utc().date())) .order_by("-category", "date") ) - webinars_dict = defaultdict(lambda: []) # noqa: PIE807 + webinars_dict = defaultdict(list) # noqa: PIE807 for webinar in webinars: webinar.detail_page_url = webinar.detail_page_url(request) webinars_dict[webinar.category].append(webinar) @@ -1026,7 +1026,7 @@ def get_url_parts(self, request=None): # of the Course/Program instead (e.g.: "/courses/course-v1:edX+DemoX+Demo_Course") re.sub( self.slugged_page_path_pattern, - r"\1{}\3".format(self.product.readable_id), # noqa: UP032 + fr"\1{self.product.readable_id}\3", # noqa: UP032 url_parts[2], ), ) @@ -1505,7 +1505,7 @@ class Meta: def can_create_at(cls, parent): # You can only create one of these page under course / program. return ( - super(CourseProgramChildPage, cls).can_create_at(parent) # noqa: UP008 + super().can_create_at(parent) # noqa: UP008 and parent.get_children().type(cls).count() == 0 ) diff --git a/compliance/test_utils.py b/compliance/test_utils.py index 0d950bad0c..f1937ea315 100644 --- a/compliance/test_utils.py +++ b/compliance/test_utils.py @@ -33,14 +33,14 @@ def mock_cybersource_wsdl(mocked_responses, settings, service_version=SERVICE_VE Mocks the responses to achieve a functional WSDL """ # in order for zeep to load the wsdl, it will load the wsdl and the accompanying xsd definitions - with open(f"{DATA_DIR}/CyberSourceTransaction_{service_version}.wsdl", "r") as wsdl: # noqa: PTH123, UP015 + with open(f"{DATA_DIR}/CyberSourceTransaction_{service_version}.wsdl") as wsdl: # noqa: PTH123, UP015 mocked_responses.add( mocked_responses.GET, settings.CYBERSOURCE_WSDL_URL, body=wsdl.read(), status=status.HTTP_200_OK, ) - with open(f"{DATA_DIR}/CyberSourceTransaction_{SERVICE_VERSION}.xsd", "r") as xsd: # noqa: PTH123, UP015 + with open(f"{DATA_DIR}/CyberSourceTransaction_{SERVICE_VERSION}.xsd") as xsd: # noqa: PTH123, UP015 mocked_responses.add( mocked_responses.GET, f"http://localhost/service/CyberSourceTransaction_{service_version}.xsd", diff --git a/courses/api.py b/courses/api.py index 6c86b2bd09..6d1e7136b7 100644 --- a/courses/api.py +++ b/courses/api.py @@ -57,7 +57,7 @@ def get_user_enrollments(user): for program_enrollment in program_enrollments ) ) - program_course_ids = set(course.id for course in program_courses) # noqa: C401 + program_course_ids = {course.id for course in program_courses} # noqa: C401 course_run_enrollments = ( CourseRunEnrollment.objects.select_related("run__course__coursepage", "company") .filter(user=user) @@ -316,7 +316,7 @@ def defer_enrollment( to_run = CourseRun.objects.get(courseware_id=to_courseware_id) if from_enrollment.run == to_run: raise ValidationError( - "Cannot defer to the same course run (run: {})".format(to_run.courseware_id) # noqa: EM103, UP032 + f"Cannot defer to the same course run (run: {to_run.courseware_id})" # noqa: EM103, UP032 ) if not force and not to_run.is_not_beyond_enrollment: raise ValidationError( diff --git a/courses/credentials.py b/courses/credentials.py index cafcf2ed77..46e0b3b6de 100644 --- a/courses/credentials.py +++ b/courses/credentials.py @@ -81,7 +81,7 @@ def build_course_run_credential(certificate: CourseRunCertificate) -> dict: def build_digital_credential( - certificate: Union[ProgramCertificate, CourseRunCertificate], # noqa: FA100 + certificate: ProgramCertificate | CourseRunCertificate, # noqa: FA100 learner_did: LearnerDID, ) -> dict: """Function for building certificate digital credentials""" diff --git a/courses/factories.py b/courses/factories.py index 23fd4c8079..4ba791e0ee 100644 --- a/courses/factories.py +++ b/courses/factories.py @@ -65,7 +65,7 @@ class ProgramRunFactory(DjangoModelFactory): """Factory for ProgramRuns""" program = factory.SubFactory(ProgramFactory) - run_tag = factory.Sequence("R{0}".format) + run_tag = factory.Sequence("R{}".format) class Meta: model = ProgramRun @@ -77,7 +77,7 @@ class CourseFactory(DjangoModelFactory): program = factory.SubFactory(ProgramFactory) position_in_program = None # will get populated in save() title = fuzzy.FuzzyText(prefix="Course ") - readable_id = factory.Sequence("course-{0}".format) + readable_id = factory.Sequence("course-{}".format) platform = factory.SubFactory(PlatformFactory) live = True @@ -96,7 +96,7 @@ class CourseRunFactory(DjangoModelFactory): course = factory.SubFactory(CourseFactory) title = factory.LazyAttribute(lambda x: "CourseRun " + FAKE.sentence()) # noqa: ARG005 courseware_id = factory.Sequence(lambda number: f"course:v{number}+{FAKE.slug()}") - run_tag = factory.Sequence("R{0}".format) + run_tag = factory.Sequence("R{}".format) courseware_url_path = factory.Faker("uri") start_date = factory.Faker( "date_time_this_month", before_now=True, after_now=False, tzinfo=timezone.utc diff --git a/courses/management/commands/defer_enrollment.py b/courses/management/commands/defer_enrollment.py index 43f84f8b6f..28c252de6a 100644 --- a/courses/management/commands/defer_enrollment.py +++ b/courses/management/commands/defer_enrollment.py @@ -63,12 +63,12 @@ def handle(self, *args, **options): # noqa: ARG002 if isinstance(exc, CourseRunEnrollment.DoesNotExist): message = f"'from' course run enrollment does not exist ({from_courseware_id})" elif isinstance(exc, CourseRun.DoesNotExist): - message = "'to' course does not exist ({})".format(to_courseware_id) # noqa: UP032 + message = f"'to' course does not exist ({to_courseware_id})" # noqa: UP032 else: message = str(exc) raise CommandError(message) # noqa: B904, TRY200 except ValidationError as exc: - raise CommandError("Invalid enrollment deferral - {}".format(exc)) # noqa: B904, EM103, TRY200, UP032 + raise CommandError(f"Invalid enrollment deferral - {exc}") # noqa: B904, EM103, TRY200, UP032 else: if not to_enrollment: raise CommandError( diff --git a/courses/management/commands/revoke_certificate.py b/courses/management/commands/revoke_certificate.py index c9a53e074d..da06b96c34 100644 --- a/courses/management/commands/revoke_certificate.py +++ b/courses/management/commands/revoke_certificate.py @@ -81,7 +81,7 @@ def handle(self, *args, **options): # noqa: ARG002 if updated: msg = "Certificate for {} has been {}".format( - "run: {}".format(run) if run else "program: {}".format(program), # noqa: UP032 + f"run: {run}" if run else f"program: {program}", # noqa: UP032 "revoked" if revoke else "un-revoked", ) self.stdout.write(self.style.SUCCESS(msg)) diff --git a/courses/management/commands/sync_grades_and_certificates.py b/courses/management/commands/sync_grades_and_certificates.py index 84aafff6d8..20631416bd 100644 --- a/courses/management/commands/sync_grades_and_certificates.py +++ b/courses/management/commands/sync_grades_and_certificates.py @@ -130,10 +130,10 @@ def handle( # noqa: C901, PLR0915 else: grade_status = "already exists" - grade_summary = ["passed: {}".format(course_run_grade.passed)] # noqa: UP032 + grade_summary = [f"passed: {course_run_grade.passed}"] # noqa: UP032 if override_grade is not None: grade_summary.append( - "value override: {}".format(course_run_grade.grade) # noqa: UP032 + f"value override: {course_run_grade.grade}" # noqa: UP032 ) if created_cert: diff --git a/courses/management/utils.py b/courses/management/utils.py index f1c830a5a5..d6d9a676b0 100644 --- a/courses/management/utils.py +++ b/courses/management/utils.py @@ -112,7 +112,7 @@ def fetch_enrollment(user, command_options): enrollment = CourseRunEnrollment.all_objects.filter(**query_params).first() if not enrollment: - raise CommandError("Enrollment not found for: {}".format(enrolled_obj)) # noqa: EM103, UP032 + raise CommandError(f"Enrollment not found for: {enrolled_obj}") # noqa: EM103, UP032 if not enrollment.active and not force: raise CommandError( "The given enrollment is not active ({}).\n" # noqa: EM103, UP032, RUF100 diff --git a/courses/models.py b/courses/models.py index 4956d0b5f0..10abee1b48 100644 --- a/courses/models.py +++ b/courses/models.py @@ -200,7 +200,7 @@ def catalog_image_url(self): validate_url_path_field = RegexValidator( - r"^[{}]+$".format(detail_path_char_pattern), # noqa: UP032 + fr"^[{detail_path_char_pattern}]+$", # noqa: UP032 f"This field is used to produce URL paths. It must contain only characters that match this pattern: [{detail_path_char_pattern}]", ) diff --git a/courses/serializers.py b/courses/serializers.py index e0e4142cd5..f8d44de049 100644 --- a/courses/serializers.py +++ b/courses/serializers.py @@ -350,12 +350,12 @@ def get_instructors(self, instance): def get_topics(self, instance): """List all topics in all courses in the program""" - topics = set( # noqa: C401 + topics = { # noqa: C401 topic.name for course in instance.courses.all() if course.page for topic in course.page.topics.all() - ) + } return [{"name": topic} for topic in sorted(topics)] def get_time_commitment(self, instance): diff --git a/courses/views_test.py b/courses/views_test.py index b65581c23c..3360782651 100644 --- a/courses/views_test.py +++ b/courses/views_test.py @@ -283,11 +283,11 @@ def test_course_view( # noqa: PLR0913 class_name = "enrolled" assert ( - f''.encode("utf-8") # noqa: UP012 + f''.encode() # noqa: UP012 in resp.content ) is has_button assert ( - "Please Sign In to MITx PRO to enroll in a course".encode("utf-8") # noqa: UP012 + b"Please Sign In to MITx PRO to enroll in a course" # noqa: UP012 in resp.content ) is (is_anonymous and has_product and has_unexpired_run) @@ -349,11 +349,11 @@ def test_program_view( # noqa: PLR0913 class_name = "enrolled" assert ( - f''.encode("utf-8") # noqa: UP012 + f''.encode() # noqa: UP012 in resp.content ) is has_button assert ( - "Please Sign In to MITx PRO to enroll in a course".encode("utf-8") # noqa: UP012 + b"Please Sign In to MITx PRO to enroll in a course" # noqa: UP012 in resp.content ) is (is_anonymous and has_product and has_unexpired_run) diff --git a/courseware/api.py b/courseware/api.py index 3fd4dbcf5d..af9c309826 100644 --- a/courseware/api.py +++ b/courseware/api.py @@ -508,7 +508,7 @@ def get_edx_api_client(user, ttl_in_seconds=OPENEDX_AUTH_DEFAULT_TTL_IN_SECONDS) auth = get_valid_edx_api_auth(user, ttl_in_seconds=ttl_in_seconds) except OpenEdxApiAuth.DoesNotExist: raise NoEdxApiAuthError( # noqa: B904, TRY200 - "{} does not have an associated OpenEdxApiAuth".format(str(user)) # noqa: EM103, UP032 + f"{str(user)} does not have an associated OpenEdxApiAuth" # noqa: EM103, UP032 ) return EdxApi( {"access_token": auth.access_token}, @@ -799,7 +799,7 @@ def create_oauth_application(): defaults=dict( # noqa: C408 redirect_uris=urljoin( settings.OPENEDX_BASE_REDIRECT_URL, - "/auth/complete/{}/".format(settings.MITXPRO_OAUTH_PROVIDER), # noqa: UP032 + f"/auth/complete/{settings.MITXPRO_OAUTH_PROVIDER}/", # noqa: UP032 ), client_type="confidential", authorization_grant_type="authorization-code", diff --git a/ecommerce/api.py b/ecommerce/api.py index 5127c299a3..604b2dd618 100644 --- a/ecommerce/api.py +++ b/ecommerce/api.py @@ -11,7 +11,8 @@ from base64 import b64encode from collections import defaultdict from datetime import timedelta -from typing import Iterable, NamedTuple, Optional # noqa: UP035 +from typing import NamedTuple, Optional # noqa: UP035 +from collections.abc import Iterable from urllib.parse import quote_plus, urljoin from django.conf import settings @@ -791,11 +792,10 @@ def enroll_user_in_order_items(order): ): voucher_target = voucher.product.content_object voucher_enrollment = first_or_none( - ( # noqa: UP034 + # noqa: UP034 enrollment for enrollment in successful_run_enrollments if enrollment.run == voucher_target - ) ) if voucher_enrollment is not None: voucher.enrollment = voucher_enrollment @@ -954,9 +954,9 @@ class ValidatedBasket(NamedTuple): basket: Basket basket_item: BasketItem product_version: ProductVersion - coupon_version: Optional[CouponVersion] # noqa: FA100 - run_selection_ids: Optional[Iterable[int]] # noqa: FA100 - data_consent_users: Optional[Iterable[DataConsentUser]] # noqa: FA100 + coupon_version: CouponVersion | None # noqa: FA100 + run_selection_ids: Iterable[int] | None # noqa: FA100 + data_consent_users: Iterable[DataConsentUser] | None # noqa: FA100 def _validate_basket_contents(basket): diff --git a/ecommerce/mail_api_test.py b/ecommerce/mail_api_test.py index 5275dffa77..b2c8a1002b 100644 --- a/ecommerce/mail_api_test.py +++ b/ecommerce/mail_api_test.py @@ -159,7 +159,7 @@ def test_send_course_run_enrollment_welcome_email(settings, mocker, enabled): enrollment = CourseRunEnrollmentFactory.create() run_start_date = enrollment.run.start_date - run_start_time = run_start_date.astimezone(datetime.timezone.utc).strftime( + run_start_time = run_start_date.astimezone(datetime.UTC).strftime( EMAIL_TIME_FORMAT ) run_end_date = enrollment.run.end_date @@ -265,7 +265,7 @@ def test_send_ecommerce_order_receipt(mocker, receipt_data, settings): """send_ecommerce_order_receipt should send a receipt email""" settings.FEATURES["ENABLE_TAXES_DISPLAY"] = False patched_mail_api = mocker.patch("ecommerce.mail_api.api") - date = datetime.datetime(2010, 1, 1, 0, tzinfo=datetime.timezone.utc) + date = datetime.datetime(2010, 1, 1, 0, tzinfo=datetime.UTC) user = UserFactory.create( name="test", email="test@example.com", diff --git a/ecommerce/management/commands/invalidate_payment_coupons.py b/ecommerce/management/commands/invalidate_payment_coupons.py index ecccaaee2b..bc16df51bd 100644 --- a/ecommerce/management/commands/invalidate_payment_coupons.py +++ b/ecommerce/management/commands/invalidate_payment_coupons.py @@ -61,7 +61,7 @@ def handle(self, *args, **kwargs): # noqa: ARG002 codes = Coupon.objects.filter(enabled=True, payment=payment).all() else: try: - with open(kwargs["codefile"], "r") as file: # noqa: PTH123, UP015 + with open(kwargs["codefile"]) as file: # noqa: PTH123, UP015 procCodes = [line.strip() for line in file] except Exception as e: # noqa: BLE001 raise CommandError( # noqa: B904, TRY200 diff --git a/ecommerce/utils.py b/ecommerce/utils.py index 627f539108..89afbbff58 100644 --- a/ecommerce/utils.py +++ b/ecommerce/utils.py @@ -171,7 +171,7 @@ def format_run_date(run_date): if run_date: from ecommerce.mail_api import EMAIL_DATE_FORMAT - formatted_date_time = run_date.astimezone(datetime.timezone.utc).strftime( + formatted_date_time = run_date.astimezone(datetime.UTC).strftime( f"{EMAIL_DATE_FORMAT}-{EMAIL_TIME_FORMAT}" ) return tuple(formatted_date_time.split("-", 1)) diff --git a/localdev/seed/api.py b/localdev/seed/api.py index 50276c210c..d588015f3c 100644 --- a/localdev/seed/api.py +++ b/localdev/seed/api.py @@ -186,7 +186,7 @@ def parse_datetime_from_string(dt_string): datetime.datetime: The parsed datetime """ return datetime.datetime.strptime(dt_string, "%Y-%m-%dT%H:%M:%S").astimezone( - datetime.timezone.utc + datetime.UTC ) @@ -207,7 +207,7 @@ def check_settings(): missing.append(variable) if missing: raise ImproperlyConfigured( - "Missing required voucher settings: {}".format(missing) # noqa: EM103, UP032 + f"Missing required voucher settings: {missing}" # noqa: EM103, UP032 ) diff --git a/localdev/seed/management/commands/delete_seed_data.py b/localdev/seed/management/commands/delete_seed_data.py index fcd79199a2..268eff4538 100644 --- a/localdev/seed/management/commands/delete_seed_data.py +++ b/localdev/seed/management/commands/delete_seed_data.py @@ -79,4 +79,4 @@ def handle(self, *args, **options): # noqa: ARG002 else: self.stdout.write(self.style.SUCCESS("RESULTS")) for k, v in results.report.items(): - self.stdout.write("{}: {}".format(k, v)) # noqa: UP032 + self.stdout.write(f"{k}: {v}") # noqa: UP032 diff --git a/localdev/seed/management/commands/seed_data.py b/localdev/seed/management/commands/seed_data.py index 07a0ea7ebb..e6eda3d4d4 100644 --- a/localdev/seed/management/commands/seed_data.py +++ b/localdev/seed/management/commands/seed_data.py @@ -24,4 +24,4 @@ def handle(self, *args, **options): # noqa: ARG002 else: self.stdout.write(self.style.SUCCESS("RESULTS")) for k, v in results.report.items(): - self.stdout.write("{}: {}".format(k, v)) # noqa: UP032 + self.stdout.write(f"{k}: {v}") # noqa: UP032 diff --git a/mitxpro/models.py b/mitxpro/models.py index 675d00a9ef..74d5543e21 100644 --- a/mitxpro/models.py +++ b/mitxpro/models.py @@ -3,7 +3,7 @@ """ import copy -from typing import Iterable # noqa: UP035 +from collections.abc import Iterable # noqa: UP035 from django.conf import settings from django.core.exceptions import ValidationError diff --git a/mitxpro/settings.py b/mitxpro/settings.py index 1e572f27b9..4abaf7bfa8 100644 --- a/mitxpro/settings.py +++ b/mitxpro/settings.py @@ -272,7 +272,7 @@ DEFAULT_DATABASE_CONFIG = dj_database_url.parse( get_string( name="DATABASE_URL", - default="sqlite:///{0}".format(os.path.join(BASE_DIR, "db.sqlite3")), # noqa: PTH118, UP030 + default="sqlite:///{}".format(os.path.join(BASE_DIR, "db.sqlite3")), # noqa: PTH118, UP030 description="The connection url to the Postgres database", required=True, write_app_json=False, @@ -426,7 +426,7 @@ ) if CLOUDFRONT_DIST: STATIC_URL = urljoin( - "https://{dist}.cloudfront.net".format(dist=CLOUDFRONT_DIST), # noqa: UP032 + f"https://{CLOUDFRONT_DIST}.cloudfront.net", # noqa: UP032 STATIC_URL, ) @@ -682,7 +682,7 @@ ) if MITXPRO_USE_S3: if CLOUDFRONT_DIST: - AWS_S3_CUSTOM_DOMAIN = "{dist}.cloudfront.net".format(dist=CLOUDFRONT_DIST) # noqa: UP032 + AWS_S3_CUSTOM_DOMAIN = f"{CLOUDFRONT_DIST}.cloudfront.net" # noqa: UP032 DEFAULT_FILE_STORAGE = "storages.backends.s3boto3.S3Boto3Storage" FEATURES = get_features() diff --git a/mitxpro/test_utils.py b/mitxpro/test_utils.py index ade1056d90..688cabc997 100644 --- a/mitxpro/test_utils.py +++ b/mitxpro/test_utils.py @@ -170,7 +170,7 @@ def create_tempfile_csv(rows_iter): writer = csv.writer(f, delimiter=",") for row in rows_iter: writer.writerow(row) - with open(f.name, "r") as user_csv: # noqa: PTH123, UP015 + with open(f.name) as user_csv: # noqa: PTH123, UP015 return SimpleUploadedFile( f.name, user_csv.read().encode("utf8"), content_type="application/csv" ) diff --git a/mitxpro/utils.py b/mitxpro/utils.py index 73a050a339..0873e173fe 100644 --- a/mitxpro/utils.py +++ b/mitxpro/utils.py @@ -72,7 +72,7 @@ def is_near_now(time): bool: True if near now, false otherwise """ - now = datetime.datetime.now(tz=datetime.timezone.utc) + now = datetime.datetime.now(tz=datetime.UTC) five_seconds = datetime.timedelta(0, 5) return now - five_seconds < time < now + five_seconds @@ -83,7 +83,7 @@ def now_in_utc(): Returns: datetime.datetime: A datetime object for the current time """ - return datetime.datetime.now(tz=datetime.timezone.utc) + return datetime.datetime.now(tz=datetime.UTC) def format_datetime_for_filename(datetime_object, include_time=False, include_ms=False): # noqa: FBT002 @@ -624,5 +624,5 @@ def strip_datetime(date_str, date_format, date_timezone=None): if not date_str or not date_format: return None - date_timezone = date_timezone if date_timezone else datetime.timezone.utc + date_timezone = date_timezone if date_timezone else datetime.UTC return datetime.datetime.strptime(date_str, date_format).astimezone(date_timezone) diff --git a/mitxpro/utils_test.py b/mitxpro/utils_test.py index 2bd824b016..96c48915c6 100644 --- a/mitxpro/utils_test.py +++ b/mitxpro/utils_test.py @@ -86,14 +86,14 @@ def test_now_in_utc(): """now_in_utc() should return the current time set to the UTC time zone""" now = now_in_utc() assert is_near_now(now) - assert now.tzinfo == datetime.timezone.utc + assert now.tzinfo == datetime.UTC def test_is_near_now(): """ Test is_near_now for now """ - now = datetime.datetime.now(tz=datetime.timezone.utc) + now = datetime.datetime.now(tz=datetime.UTC) assert is_near_now(now) is True later = now + datetime.timedelta(0, 6) assert is_near_now(later) is False diff --git a/repl.py b/repl.py index 5d909a5a8d..e310073d98 100755 --- a/repl.py +++ b/repl.py @@ -23,7 +23,7 @@ for app in settings.INSTALLED_APPS: try: # noqa: SIM105 exec( # noqa: S102 - "from {app}.models import *".format(app=app) # noqa: UP032 + f"from {app}.models import *" # noqa: UP032 ) except ModuleNotFoundError: # noqa: PERF203 pass diff --git a/sheets/api.py b/sheets/api.py index 6020904424..f15955575a 100644 --- a/sheets/api.py +++ b/sheets/api.py @@ -185,7 +185,7 @@ def get_metadata_for_matching_files(self, query, file_fields="id, name"): ) return self.pygsheets_client.drive.list( **extra_list_params, - fields="files({})".format(file_fields), # noqa: UP032 + fields=f"files({file_fields})", # noqa: UP032 q=query, ) diff --git a/sheets/api_test.py b/sheets/api_test.py index 309a638d33..d13aaf8788 100644 --- a/sheets/api_test.py +++ b/sheets/api_test.py @@ -26,7 +26,7 @@ def test_get_credentials_service_account(mocker, settings): get_credentials() settings.SHEETS_ADMIN_EMAILS.append( - "service-account@mitxpro.{}".format(GOOGLE_SERVICE_ACCOUNT_EMAIL_DOMAIN) # noqa: UP032 + f"service-account@mitxpro.{GOOGLE_SERVICE_ACCOUNT_EMAIL_DOMAIN}" # noqa: UP032 ) creds = get_credentials() diff --git a/sheets/coupon_assign_api.py b/sheets/coupon_assign_api.py index 925755ba7b..538f49d7ce 100644 --- a/sheets/coupon_assign_api.py +++ b/sheets/coupon_assign_api.py @@ -823,7 +823,7 @@ def get_desired_coupon_assignments(cls, assignment_rows): "codes listed in the Sheet. There may be an invalid coupon code in the Sheet." ) product_coupon_dict = dict(product_coupon_tuples) - return set((row.email, product_coupon_dict[row.code]) for row in valid_rows) # noqa: C401 + return {(row.email, product_coupon_dict[row.code]) for row in valid_rows} # noqa: C401 @staticmethod def get_assignments_to_create_and_remove( @@ -872,10 +872,10 @@ def get_assignments_to_create_and_remove( ) # If any of the assignments we want to create have the same product coupon as one # of these already-redeemed assignments, filter them out and log an info message. - product_coupon_ids = set( # noqa: C401 + product_coupon_ids = { # noqa: C401 assignment.product_coupon_id for assignment in already_redeemed_assignments - ) + } adjusted_create_iter, cannot_create_iter = partition( tuple_set_to_create, lambda assignment_tuple: assignment_tuple[1] in product_coupon_ids, @@ -988,7 +988,7 @@ def process_assignment_spreadsheet(self): # Validate emails before assignment so we can filter out and report on any bad emails try: validate_email_addresses( - (assignment_tuple[0] for assignment_tuple in assignments_to_create) # noqa: UP034 + assignment_tuple[0] for assignment_tuple in assignments_to_create # noqa: UP034 ) except MultiEmailValidationError as exc: invalid_emails = exc.invalid_emails diff --git a/sheets/coupon_request_api.py b/sheets/coupon_request_api.py index e697e76e92..9f26a19974 100644 --- a/sheets/coupon_request_api.py +++ b/sheets/coupon_request_api.py @@ -273,7 +273,7 @@ def create_assignment_sheet(self, coupon_req_row): worksheet = bulk_coupon_sheet.sheet1 # Add headers worksheet.update_values( - crange="A1:{}1".format(assign_sheet_metadata.LAST_COL_LETTER), # noqa: UP032 + crange=f"A1:{assign_sheet_metadata.LAST_COL_LETTER}1", # noqa: UP032 values=[assign_sheet_metadata.column_headers], ) # Write enrollment codes to the appropriate column of the worksheet @@ -311,7 +311,7 @@ def create_assignment_sheet(self, coupon_req_row): # Format header cells with bold text header_range = worksheet.get_values( start="A1", - end="{}1".format(assign_sheet_metadata.LAST_COL_LETTER), # noqa: UP032 + end=f"{assign_sheet_metadata.LAST_COL_LETTER}1", # noqa: UP032 returnas="range", ) first_cell = header_range.cells[0][0] @@ -444,7 +444,7 @@ def process_row(self, row_index, row_data): row_db_record=coupon_gen_request, row_object=None, result_type=ResultType.FAILED, - message="Parsing failure: {}".format(str(exc)), # noqa: UP032 + message=f"Parsing failure: {str(exc)}", # noqa: UP032 ) is_unchanged_error_row = ( coupon_req_row.errors and not request_created and not request_updated diff --git a/sheets/deferral_request_api.py b/sheets/deferral_request_api.py index c3136841ac..b2ef84b367 100644 --- a/sheets/deferral_request_api.py +++ b/sheets/deferral_request_api.py @@ -134,7 +134,7 @@ def process_row( # noqa: C901, PLR0911 row_db_record=deferral_request, row_object=None, result_type=ResultType.FAILED, - message="Parsing failure: {}".format(str(exc)), # noqa: UP032 + message=f"Parsing failure: {str(exc)}", # noqa: UP032 ) is_unchanged_error_row = ( deferral_req_row.errors and not request_created and not request_updated @@ -202,7 +202,7 @@ def process_row( # noqa: C901, PLR0911 row_db_record=deferral_request, row_object=None, result_type=ResultType.FAILED, - message="Invalid deferral: {}".format(exc), # noqa: UP032 + message=f"Invalid deferral: {exc}", # noqa: UP032 ) except EdxEnrollmentCreateError as exc: return RowResult( @@ -210,7 +210,7 @@ def process_row( # noqa: C901, PLR0911 row_db_record=deferral_request, row_object=None, result_type=ResultType.FAILED, - message="Unable to defer enrollment: {}".format(exc), # noqa: UP032 + message=f"Unable to defer enrollment: {exc}", # noqa: UP032 ) deferral_request.date_completed = now_in_utc() diff --git a/sheets/factories.py b/sheets/factories.py index e0e2c8b5b8..6d278c25a5 100644 --- a/sheets/factories.py +++ b/sheets/factories.py @@ -30,10 +30,10 @@ class GoogleFileWatchFactory(DjangoModelFactory): file_id = Faker("pystr", max_chars=15) channel_id = fuzzy.FuzzyText(prefix="Channel ") activation_date = Faker( - "past_datetime", start_date="-30d", tzinfo=datetime.timezone.utc + "past_datetime", start_date="-30d", tzinfo=datetime.UTC ) expiration_date = Faker( - "future_datetime", end_date="+30d", tzinfo=datetime.timezone.utc + "future_datetime", end_date="+30d", tzinfo=datetime.UTC ) class Meta: diff --git a/sheets/mail_api.py b/sheets/mail_api.py index df583e95e8..4f58cff220 100644 --- a/sheets/mail_api.py +++ b/sheets/mail_api.py @@ -69,8 +69,8 @@ def get_bulk_assignment_messages(event=None, begin=None, end=None): raw_next_url = resp_data["paging"]["next"] # The "next" url in the paging section does not contain necessary auth. Fill it in here. url = raw_next_url.replace( - "/{}/".format(MAILGUN_API_DOMAIN), # noqa: UP032 - "/api:{}@{}/".format(settings.MAILGUN_KEY, MAILGUN_API_DOMAIN), # noqa: UP032 + f"/{MAILGUN_API_DOMAIN}/", # noqa: UP032 + f"/api:{settings.MAILGUN_KEY}@{MAILGUN_API_DOMAIN}/", # noqa: UP032 ) resp = request_get_with_timeout_retry( url, retries=MAILGUN_API_TIMEOUT_RETRIES diff --git a/sheets/management/commands/process_coupon_requests.py b/sheets/management/commands/process_coupon_requests.py index e99ef07efe..a65202a84d 100644 --- a/sheets/management/commands/process_coupon_requests.py +++ b/sheets/management/commands/process_coupon_requests.py @@ -28,5 +28,5 @@ def handle(self, *args, **options): # noqa: ARG002 limit_row_index=options.get("row", None) ) self.stdout.write( - self.style.SUCCESS("Coupon generation succeeded.\n{}".format(results)) # noqa: UP032 + self.style.SUCCESS(f"Coupon generation succeeded.\n{results}") # noqa: UP032 ) diff --git a/sheets/management/commands/process_deferral_requests.py b/sheets/management/commands/process_deferral_requests.py index 0b947c4878..eba8e5408e 100644 --- a/sheets/management/commands/process_deferral_requests.py +++ b/sheets/management/commands/process_deferral_requests.py @@ -29,6 +29,6 @@ def handle(self, *args, **options): # noqa: ARG002 ) self.stdout.write( self.style.SUCCESS( - "Deferral sheet successfully processed.\n{}".format(results) # noqa: UP032 + f"Deferral sheet successfully processed.\n{results}" # noqa: UP032 ) ) diff --git a/sheets/management/commands/process_refund_requests.py b/sheets/management/commands/process_refund_requests.py index 79a5347ead..1b86920162 100644 --- a/sheets/management/commands/process_refund_requests.py +++ b/sheets/management/commands/process_refund_requests.py @@ -29,6 +29,6 @@ def handle(self, *args, **options): # noqa: ARG002 ) self.stdout.write( self.style.SUCCESS( - "Refund sheet successfully processed.\n{}".format(results) # noqa: UP032 + f"Refund sheet successfully processed.\n{results}" # noqa: UP032 ) ) diff --git a/sheets/management/commands/setup_file_watch.py b/sheets/management/commands/setup_file_watch.py index 44caec9901..e9b3fd66fc 100644 --- a/sheets/management/commands/setup_file_watch.py +++ b/sheets/management/commands/setup_file_watch.py @@ -135,7 +135,7 @@ def handle( # noqa: C901 else f"\n[{renewal_attempt.result_status_code}] {renewal_attempt.result}" ) self.style.ERROR( - "Failed to create/update file watch.{}".format(error_msg) # noqa: UP032 + f"Failed to create/update file watch.{error_msg}" # noqa: UP032 ) continue if file_watch_result.created: @@ -146,7 +146,7 @@ def handle( # noqa: C901 desc = "found (unexpired)" file_id_desc = "" if file_watch_result.metadata.sheet_type == SHEET_TYPE_COUPON_ASSIGN: - file_id_desc = " (file id: {})".format(file_watch.file_id) # noqa: UP032 + file_id_desc = f" (file id: {file_watch.file_id})" # noqa: UP032 self.stdout.write( self.style.SUCCESS( @@ -193,7 +193,7 @@ def handle( # noqa: C901 ) else: self.stdout.write( - self.style.ERROR("Request failed: {}".format(exc)) # noqa: UP032 + self.style.ERROR(f"Request failed: {exc}") # noqa: UP032 ) sys.exit(1) else: diff --git a/sheets/migrations/0007_fill_in_gen_request_date_completed.py b/sheets/migrations/0007_fill_in_gen_request_date_completed.py index 928303f72f..1c57581d8f 100644 --- a/sheets/migrations/0007_fill_in_gen_request_date_completed.py +++ b/sheets/migrations/0007_fill_in_gen_request_date_completed.py @@ -11,7 +11,7 @@ def now_in_utc(): Returns: datetime.datetime: A datetime object for the current time """ - return datetime.datetime.now(tz=datetime.timezone.utc) + return datetime.datetime.now(tz=datetime.UTC) def set_date_completed_to_none(apps, schema_editor): diff --git a/sheets/migrations/0010_fill_in_gen_request_coupon_name.py b/sheets/migrations/0010_fill_in_gen_request_coupon_name.py index 5a157d743b..5b4b140e85 100644 --- a/sheets/migrations/0010_fill_in_gen_request_coupon_name.py +++ b/sheets/migrations/0010_fill_in_gen_request_coupon_name.py @@ -29,7 +29,7 @@ def fill_in_coupon_name(apps, schema_editor): "raw_data is either not a list, or does not include a valid coupon name" # noqa: EM101 ) except Exception: # noqa: BLE001 - coupon_name = "COUPON NAME NEEDED ({})".format(coupon_gen_request.id) # noqa: UP032 + coupon_name = f"COUPON NAME NEEDED ({coupon_gen_request.id})" # noqa: UP032 else: coupon_name = raw_data[1] coupon_gen_request.coupon_name = coupon_name diff --git a/sheets/refund_request_api.py b/sheets/refund_request_api.py index af943e8f70..83ab3db3a0 100644 --- a/sheets/refund_request_api.py +++ b/sheets/refund_request_api.py @@ -226,7 +226,7 @@ def process_row(self, row_index, row_data): row_db_record=refund_request, row_object=None, result_type=ResultType.FAILED, - message="Parsing failure: {}".format(str(exc)), # noqa: UP032 + message=f"Parsing failure: {str(exc)}", # noqa: UP032 ) is_unchanged_error_row = ( refund_req_row.errors and not request_created and not request_updated diff --git a/sheets/sheet_handler_api.py b/sheets/sheet_handler_api.py index 6f3b239964..a16be6897c 100644 --- a/sheets/sheet_handler_api.py +++ b/sheets/sheet_handler_api.py @@ -214,7 +214,7 @@ def process_sheet(self, limit_row_index=None): row_db_record=None, row_object=None, result_type=ResultType.FAILED, - message="Error: {}".format(str(exc)), # noqa: UP032 + message=f"Error: {str(exc)}", # noqa: UP032 ) finally: if row_result: diff --git a/sheets/utils.py b/sheets/utils.py index 710d57e4c7..7e5bdcb6d6 100644 --- a/sheets/utils.py +++ b/sheets/utils.py @@ -460,8 +460,8 @@ def _parse_sheet_date_str(date_str, date_format): ) return ( dt - if settings.SHEETS_DATE_TIMEZONE == datetime.timezone.utc # noqa: SIM300 - else dt.astimezone(datetime.timezone.utc) + if settings.SHEETS_DATE_TIMEZONE == datetime.UTC # noqa: SIM300 + else dt.astimezone(datetime.UTC) ) @@ -503,7 +503,7 @@ def google_timestamp_to_datetime(google_timestamp): """ # Google timestamps are expressed in milliseconds, hence the '/ 1000' timestamp_in_seconds = int(google_timestamp) / 1000 - return datetime.datetime.fromtimestamp(timestamp_in_seconds, datetime.timezone.utc) + return datetime.datetime.fromtimestamp(timestamp_in_seconds, datetime.UTC) def google_date_string_to_datetime(google_date_str): @@ -518,7 +518,7 @@ def google_date_string_to_datetime(google_date_str): """ return datetime.datetime.strptime( google_date_str, "%Y-%m-%dT%H:%M:%S.%fZ" - ).astimezone(datetime.timezone.utc) + ).astimezone(datetime.UTC) def mailgun_timestamp_to_datetime(timestamp): @@ -531,7 +531,7 @@ def mailgun_timestamp_to_datetime(timestamp): Returns: datetime.datetime: The parsed timestamp """ - return datetime.datetime.fromtimestamp(timestamp, datetime.timezone.utc) + return datetime.datetime.fromtimestamp(timestamp, datetime.UTC) def build_multi_cell_update_request_body( diff --git a/users/api.py b/users/api.py index 37a172abc9..05672be0e5 100644 --- a/users/api.py +++ b/users/api.py @@ -75,7 +75,7 @@ def fetch_user(filter_value, ignore_case=True): # noqa: FBT002 filter_field = _determine_filter_field(filter_value) if _is_case_insensitive_searchable(filter_field) and ignore_case: - query = {"{}__iexact".format(filter_field): filter_value} # noqa: UP032 + query = {f"{filter_field}__iexact": filter_value} # noqa: UP032 else: query = {filter_field: filter_value} try: @@ -125,14 +125,14 @@ def fetch_users(filter_values, ignore_case=True): # noqa: FBT002 query = reduce( operator.or_, ( - Q(**{"{}__iexact".format(filter_field): filter_value}) # noqa: UP032 + Q(**{f"{filter_field}__iexact": filter_value}) # noqa: UP032 for filter_value in filter_values ), ) user_qset = User.objects.filter(query) else: user_qset = User.objects.filter( - **{"{}__in".format(filter_field): filter_values} # noqa: UP032 + **{f"{filter_field}__in": filter_values} # noqa: UP032 ) if user_qset.count() != len(filter_values): valid_values = user_qset.values_list(filter_field, flat=True) @@ -184,7 +184,7 @@ def find_available_username(initial_username_base): ] # Find usernames that match the username base and have a numerical suffix, then find the max suffix existing_usernames = User.objects.filter( - username__regex=r"{username_base}[0-9]+".format(username_base=username_base) # noqa: UP032 + username__regex=fr"{username_base}[0-9]+" # noqa: UP032 ).values_list("username", flat=True) max_suffix = max_or_none( int(re.search(r"\d+$", username).group()) for username in existing_usernames diff --git a/users/management/commands/retire_users.py b/users/management/commands/retire_users.py index 12cac99820..0747b084e5 100644 --- a/users/management/commands/retire_users.py +++ b/users/management/commands/retire_users.py @@ -92,7 +92,7 @@ def handle(self, *args, **kwargs): # noqa: ARG002 users = fetch_users(kwargs["users"]) for user in users: - self.stdout.write("Retiring user: {user}".format(user=user)) # noqa: UP032 + self.stdout.write(f"Retiring user: {user}") # noqa: UP032 if not user.is_active: self.stdout.write( self.style.ERROR( @@ -126,11 +126,11 @@ def handle(self, *args, **kwargs): # noqa: ARG002 if auth_deleted_count: self.stdout.write( - "For user: '{user}' SocialAuth rows deleted".format(user=user) # noqa: UP032 + f"For user: '{user}' SocialAuth rows deleted" # noqa: UP032 ) self.stdout.write( self.style.SUCCESS( - "User: '{user}' is retired from MIT xPRO".format(user=user) # noqa: UP032 + f"User: '{user}' is retired from MIT xPRO" # noqa: UP032 ) ) diff --git a/voucher/factories.py b/voucher/factories.py index 90635319e4..61a8b06633 100644 --- a/voucher/factories.py +++ b/voucher/factories.py @@ -18,7 +18,7 @@ class VoucherFactory(DjangoModelFactory): employee_id = factory.Faker("password", special_chars=False) course_start_date_input = factory.Faker("date_object") - course_id_input = factory.Sequence("course-{0}".format) + course_id_input = factory.Sequence("course-{}".format) course_title_input = factory.fuzzy.FuzzyText(prefix="Course ") user = factory.SubFactory(UserFactory)