From 81b37cb7d2160866afa2496873656afe53f0c145 Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Fri, 1 Jul 2022 11:51:05 +0530 Subject: [PATCH] refactor: clean up code to py310 supported features (#17367) refactor: clean up code to py39+ supported syntax - f-strings instead of format - latest typing support instead of pre 3.9 TitleCase - remove UTF-8 declarations. - many more changes Powered by https://github.com/asottile/pyupgrade/ + manual cleanups --- frappe/__init__.py | 40 +++--- frappe/api.py | 2 +- frappe/app.py | 9 +- frappe/auth.py | 2 +- .../assignment_rule/assignment_rule.py | 10 +- .../assignment_rule_day.py | 1 - .../assignment_rule_user.py | 1 - .../doctype/auto_repeat/auto_repeat.py | 1 - .../doctype/auto_repeat/test_auto_repeat.py | 3 +- .../auto_repeat_day/auto_repeat_day.py | 1 - .../automation/doctype/milestone/milestone.py | 1 - .../doctype/milestone/test_milestone.py | 1 - .../milestone_tracker/milestone_tracker.py | 1 - .../test_milestone_tracker.py | 1 - frappe/build.py | 8 +- frappe/client.py | 4 +- frappe/commands/scheduler.py | 8 +- frappe/commands/site.py | 30 ++-- frappe/commands/utils.py | 14 +- frappe/contacts/address_and_contact.py | 13 +- frappe/contacts/doctype/address/address.py | 7 +- .../contacts/doctype/address/test_address.py | 1 - .../address_template/address_template.py | 1 - .../address_template/test_address_template.py | 1 - frappe/contacts/doctype/contact/contact.py | 2 +- .../contacts/doctype/contact/test_contact.py | 1 - .../doctype/contact_email/contact_email.py | 1 - .../doctype/contact_phone/contact_phone.py | 1 - frappe/contacts/doctype/gender/gender.py | 1 - frappe/contacts/doctype/gender/test_gender.py | 1 - .../contacts/doctype/salutation/salutation.py | 1 - .../doctype/salutation/test_salutation.py | 1 - frappe/core/api/file.py | 9 +- .../doctype/access_log/test_access_log.py | 3 +- frappe/core/doctype/activity_log/feed.py | 4 +- .../doctype/activity_log/test_activity_log.py | 1 - .../core/doctype/block_module/block_module.py | 1 - frappe/core/doctype/comment/comment.py | 5 +- frappe/core/doctype/comment/test_comment.py | 1 - .../doctype/communication/communication.py | 15 +- frappe/core/doctype/communication/email.py | 6 +- frappe/core/doctype/communication/mixins.py | 4 +- .../communication/test_communication.py | 2 +- .../communication_link/communication_link.py | 1 - .../doctype/custom_docperm/custom_docperm.py | 1 - .../custom_docperm/test_custom_docperm.py | 1 - .../core/doctype/custom_role/custom_role.py | 1 - .../doctype/custom_role/test_custom_role.py | 1 - .../core/doctype/data_export/data_export.py | 1 - frappe/core/doctype/data_export/exporter.py | 2 +- .../doctype/data_export/test_data_exporter.py | 1 - .../core/doctype/data_import/data_import.py | 1 - frappe/core/doctype/data_import/exporter.py | 20 ++- frappe/core/doctype/data_import/importer.py | 48 +++---- .../doctype/data_import/test_data_import.py | 1 - .../core/doctype/data_import/test_exporter.py | 1 - .../core/doctype/data_import/test_importer.py | 1 - .../deleted_document/deleted_document.py | 1 - .../deleted_document/test_deleted_document.py | 1 - frappe/core/doctype/doctype/doctype.py | 14 +- frappe/core/doctype/doctype/test_doctype.py | 8 +- .../doctype/doctype_action/doctype_action.py | 1 - .../core/doctype/doctype_link/doctype_link.py | 1 - .../document_naming_rule.py | 1 - .../test_document_naming_rule.py | 1 - .../document_naming_rule_condition.py | 1 - .../test_document_naming_rule_condition.py | 1 - .../document_naming_settings.py | 9 +- frappe/core/doctype/domain/domain.py | 9 +- frappe/core/doctype/domain/test_domain.py | 1 - .../domain_settings/domain_settings.py | 3 +- .../core/doctype/dynamic_link/dynamic_link.py | 1 - frappe/core/doctype/error_log/error_log.py | 1 - .../core/doctype/error_log/test_error_log.py | 1 - .../doctype/error_snapshot/error_snapshot.py | 1 - .../error_snapshot/test_error_snapshot.py | 1 - frappe/core/doctype/file/file.py | 13 +- frappe/core/doctype/file/utils.py | 20 +-- frappe/core/doctype/has_domain/has_domain.py | 1 - frappe/core/doctype/has_role/has_role.py | 1 - .../installed_application.py | 1 - .../installed_applications.py | 1 - .../test_installed_applications.py | 1 - frappe/core/doctype/language/language.py | 5 +- frappe/core/doctype/language/test_language.py | 1 - .../log_setting_user/log_setting_user.py | 1 - .../log_setting_user/test_log_setting_user.py | 1 - .../core/doctype/log_settings/log_settings.py | 1 - frappe/core/doctype/module_def/module_def.py | 4 +- .../doctype/module_def/test_module_def.py | 1 - .../doctype/module_profile/module_profile.py | 1 - .../module_profile/test_module_profile.py | 1 - .../core/doctype/navbar_item/navbar_item.py | 1 - .../doctype/navbar_item/test_navbar_item.py | 1 - .../navbar_settings/navbar_settings.py | 1 - .../navbar_settings/test_navbar_settings.py | 1 - frappe/core/doctype/package/package.py | 4 +- .../doctype/package_import/package_import.py | 4 +- .../package_release/package_release.py | 2 +- frappe/core/doctype/page/page.py | 8 +- .../core/doctype/patch_log/test_patch_log.py | 1 - .../payment_gateway/payment_gateway.py | 1 - .../payment_gateway/test_payment_gateway.py | 1 - .../prepared_report/prepared_report.py | 3 +- .../prepared_report/test_prepared_report.py | 1 - frappe/core/doctype/report/report.py | 6 +- frappe/core/doctype/report/test_report.py | 4 +- .../doctype/report_column/report_column.py | 1 - .../doctype/report_filter/report_filter.py | 1 - frappe/core/doctype/role/role.py | 2 +- .../role_permission_for_page_and_report.py | 1 - .../core/doctype/role_profile/role_profile.py | 1 - .../doctype/role_profile/test_role_profile.py | 1 - .../scheduled_job_log/scheduled_job_log.py | 1 - .../test_scheduled_job_log.py | 1 - .../scheduled_job_type/scheduled_job_type.py | 11 +- .../test_scheduled_job_type.py | 1 - .../doctype/server_script/server_script.py | 8 +- .../server_script/test_server_script.py | 1 - .../session_default/session_default.py | 1 - .../session_default_settings.py | 1 - .../test_session_default_settings.py | 1 - frappe/core/doctype/sms_parameter/__init__.py | 1 - frappe/core/doctype/sms_settings/__init__.py | 1 - .../core/doctype/sms_settings/sms_settings.py | 1 - .../doctype/sms_settings/test_sms_settings.py | 1 - .../doctype/success_action/success_action.py | 1 - .../system_settings/test_system_settings.py | 1 - frappe/core/doctype/test/test.py | 11 +- frappe/core/doctype/test/test_test.py | 1 - .../transaction_log/test_transaction_log.py | 1 - .../doctype/translation/test_translation.py | 1 - .../core/doctype/translation/translation.py | 1 - frappe/core/doctype/user/user.py | 12 +- .../user_document_type/user_document_type.py | 1 - frappe/core/doctype/user_email/user_email.py | 1 - .../doctype/user_group/test_user_group.py | 1 - frappe/core/doctype/user_group/user_group.py | 1 - .../test_user_group_member.py | 1 - .../user_group_member/user_group_member.py | 1 - .../user_select_document_type.py | 1 - .../user_social_login/user_social_login.py | 1 - .../core/doctype/user_type/test_user_type.py | 1 - frappe/core/doctype/user_type/user_type.py | 5 +- .../user_type_module/user_type_module.py | 1 - frappe/core/doctype/version/version.py | 3 +- frappe/core/doctype/view_log/test_view_log.py | 1 - frappe/core/doctype/view_log/view_log.py | 1 - .../page/background_jobs/background_jobs.py | 4 +- .../permission_manager/permission_manager.py | 3 +- .../permitted_documents_for_user.py | 6 +- .../client_script/test_client_script.py | 1 - .../doctype/custom_field/test_custom_field.py | 2 - .../doctype/customize_form/customize_form.py | 2 +- .../doctype/doctype_layout/doctype_layout.py | 1 - .../doctype_layout/test_doctype_layout.py | 1 - .../doctype_layout_field.py | 1 - .../property_setter/test_property_setter.py | 1 - .../test_rename_new/test_rename_new.py | 1 - .../test_rename_new/test_test_rename_new.py | 1 - frappe/database/database.py | 25 ++-- frappe/database/db_manager.py | 12 +- frappe/database/mariadb/database.py | 12 +- frappe/database/mariadb/schema.py | 16 +-- frappe/database/mariadb/setup_db.py | 4 +- frappe/database/postgres/database.py | 23 ++- frappe/database/postgres/schema.py | 16 +-- frappe/database/postgres/setup_db.py | 18 ++- frappe/database/query.py | 28 ++-- frappe/database/schema.py | 14 +- frappe/deferred_insert.py | 6 +- frappe/desk/desktop.py | 6 +- .../desk/doctype/bulk_update/bulk_update.py | 3 +- .../doctype/calendar_view/calendar_view.py | 1 - .../desk/doctype/console_log/console_log.py | 1 - .../doctype/console_log/test_console_log.py | 1 - frappe/desk/doctype/dashboard/dashboard.py | 2 +- .../desk/doctype/dashboard/test_dashboard.py | 1 - .../dashboard_chart/dashboard_chart.py | 19 ++- .../dashboard_chart/test_dashboard_chart.py | 1 - .../dashboard_chart_field.py | 1 - .../dashboard_chart_link.py | 1 - .../dashboard_chart_source.py | 2 - .../test_dashboard_chart_source.py | 1 - .../dashboard_settings/dashboard_settings.py | 3 +- .../desk/doctype/desktop_icon/desktop_icon.py | 3 +- frappe/desk/doctype/event/event.py | 6 +- frappe/desk/doctype/event/test_event.py | 2 +- .../event_participants/event_participants.py | 1 - .../global_search_doctype.py | 1 - .../global_search_settings.py | 1 - .../desk/doctype/kanban_board/kanban_board.py | 5 +- .../doctype/kanban_board/test_kanban_board.py | 1 - .../kanban_board_column.py | 1 - .../desk/doctype/list_filter/list_filter.py | 1 - .../list_view_settings/list_view_settings.py | 1 - .../test_list_view_settings.py | 1 - .../module_onboarding/module_onboarding.py | 1 - .../test_module_onboarding.py | 1 - frappe/desk/doctype/note/note.py | 2 +- .../desk/doctype/note_seen_by/note_seen_by.py | 1 - .../notification_log/notification_log.py | 5 +- .../notification_log/test_notification_log.py | 1 - .../notification_settings.py | 3 +- .../notification_subscribed_document.py | 1 - .../desk/doctype/number_card/number_card.py | 5 +- .../doctype/number_card/test_number_card.py | 1 - .../number_card_link/number_card_link.py | 1 - .../onboarding_permission.py | 1 - .../test_onboarding_permission.py | 1 - .../onboarding_step/onboarding_step.py | 1 - .../onboarding_step/test_onboarding_step.py | 1 - .../onboarding_step_map.py | 1 - .../doctype/system_console/system_console.py | 1 - .../system_console/test_system_console.py | 1 - frappe/desk/doctype/tag/tag.py | 4 +- frappe/desk/doctype/tag_link/tag_link.py | 1 - frappe/desk/doctype/tag_link/test_tag_link.py | 1 - frappe/desk/doctype/todo/test_todo.py | 1 - .../desk/doctype/workspace/test_workspace.py | 1 - frappe/desk/doctype/workspace/workspace.py | 9 +- .../workspace_chart/workspace_chart.py | 1 - .../doctype/workspace_link/workspace_link.py | 1 - .../workspace_shortcut/workspace_shortcut.py | 1 - frappe/desk/form/assign_to.py | 2 +- frappe/desk/form/document_follow.py | 4 +- frappe/desk/form/linked_with.py | 27 ++-- frappe/desk/form/load.py | 9 +- frappe/desk/form/meta.py | 6 +- frappe/desk/form/utils.py | 2 +- frappe/desk/like.py | 2 +- frappe/desk/listview.py | 3 +- frappe/desk/moduleview.py | 6 +- frappe/desk/page/activity/__init__.py | 1 - frappe/desk/page/backups/backups.py | 4 +- frappe/desk/page/setup_wizard/setup_wizard.py | 6 +- frappe/desk/query_report.py | 2 +- frappe/desk/report/todo/todo.py | 2 +- frappe/desk/report_dump.py | 2 +- frappe/desk/reportview.py | 2 +- frappe/desk/search.py | 10 +- frappe/desk/treeview.py | 4 +- frappe/email/__init__.py | 2 +- .../auto_email_report/auto_email_report.py | 7 +- .../test_auto_email_report.py | 1 - .../document_follow/document_follow.py | 1 - .../document_follow/test_document_follow.py | 1 - .../doctype/email_account/email_account.py | 13 +- .../email_account/test_email_account.py | 12 +- .../doctype/email_domain/email_domain.py | 13 +- .../doctype/email_domain/test_email_domain.py | 1 - .../email_flag_queue/email_flag_queue.py | 1 - .../email_flag_queue/test_email_flag_queue.py | 1 - .../email/doctype/email_group/email_group.py | 3 +- .../doctype/email_group/test_email_group.py | 1 - .../email_group_member/email_group_member.py | 1 - .../test_email_group_member.py | 1 - .../email/doctype/email_queue/email_queue.py | 9 +- .../doctype/email_queue/test_email_queue.py | 1 - .../email_queue_recipient.py | 1 - frappe/email/doctype/email_rule/email_rule.py | 1 - .../doctype/email_rule/test_email_rule.py | 1 - .../email_template/test_email_template.py | 1 - .../email_unsubscribe/email_unsubscribe.py | 1 - .../test_email_unsubscribe.py | 1 - frappe/email/doctype/newsletter/newsletter.py | 23 ++- .../doctype/newsletter/test_newsletter.py | 3 +- .../newsletter_email_group.py | 1 - .../doctype/notification/notification.py | 5 +- .../doctype/notification/test_notification.py | 1 - .../notification_recipient.py | 1 - .../unhandled_email/test_unhandled_email.py | 1 - .../unhandled_email/unhandled_email.py | 1 - frappe/email/email_body.py | 5 +- frappe/email/receive.py | 12 +- frappe/email/test_email_body.py | 2 +- .../document_type_field_mapping.py | 1 - .../document_type_mapping.py | 1 - .../test_document_type_mapping.py | 1 - .../doctype/event_consumer/event_consumer.py | 1 - .../event_consumer/test_event_consumer.py | 1 - .../event_consumer_document_type.py | 1 - .../doctype/event_producer/event_producer.py | 1 - .../event_producer/test_event_producer.py | 1 - .../event_producer_document_type.py | 1 - .../event_producer_last_update.py | 1 - .../test_event_producer_last_update.py | 1 - .../doctype/event_sync_log/event_sync_log.py | 1 - .../event_sync_log/test_event_sync_log.py | 1 - .../event_update_log/event_update_log.py | 1 - .../event_update_log/test_event_update_log.py | 1 - .../event_update_log_consumer.py | 1 - frappe/exceptions.py | 2 +- frappe/frappeclient.py | 10 +- frappe/geo/country_info.py | 4 +- frappe/geo/doctype/country/__init__.py | 1 - frappe/geo/doctype/currency/__init__.py | 1 - frappe/geo/utils.py | 5 +- frappe/installer.py | 23 ++- .../braintree_settings/braintree_settings.py | 3 +- .../test_braintree_settings.py | 1 - .../doctype/connected_app/connected_app.py | 1 - .../connected_app/test_connected_app.py | 1 - .../dropbox_settings/dropbox_settings.py | 9 +- .../dropbox_settings/test_dropbox_settings.py | 1 - .../google_calendar/google_calendar.py | 3 +- .../google_contacts/google_contacts.py | 3 +- .../doctype/google_drive/google_drive.py | 7 +- .../doctype/google_drive/test_google_drive.py | 1 - .../google_settings/google_settings.py | 1 - .../google_settings/test_google_settings.py | 2 - .../integration_request.py | 1 - .../test_integration_request.py | 1 - .../ldap_group_mapping/ldap_group_mapping.py | 1 - .../doctype/ldap_settings/ldap_settings.py | 15 +- .../ldap_settings/test_ldap_settings.py | 17 +-- .../oauth_authorization_code.py | 1 - .../test_oauth_authorization_code.py | 1 - .../oauth_bearer_token/oauth_bearer_token.py | 1 - .../test_oauth_bearer_token.py | 1 - .../doctype/oauth_client/oauth_client.py | 1 - .../doctype/oauth_client/test_oauth_client.py | 1 - .../oauth_provider_settings.py | 1 - .../doctype/oauth_scope/oauth_scope.py | 1 - .../paypal_settings/paypal_settings.py | 15 +- .../doctype/paytm_settings/paytm_settings.py | 3 +- .../paytm_settings/test_paytm_settings.py | 1 - .../query_parameters/query_parameters.py | 1 - .../razorpay_settings/razorpay_settings.py | 23 ++- .../s3_backup_settings/s3_backup_settings.py | 1 - .../test_s3_backup_settings.py | 1 - .../slack_webhook_url/slack_webhook_url.py | 1 - .../test_slack_webhook_url.py | 1 - .../social_login_key/social_login_key.py | 3 +- .../social_login_key/test_social_login_key.py | 1 - .../stripe_settings/stripe_settings.py | 5 +- .../stripe_settings/test_stripe_settings.py | 1 - .../doctype/token_cache/test_token_cache.py | 1 - .../doctype/token_cache/token_cache.py | 1 - .../integrations/doctype/webhook/__init__.py | 1 - .../doctype/webhook/test_webhook.py | 1 - .../integrations/doctype/webhook/webhook.py | 4 +- .../doctype/webhook_data/webhook_data.py | 1 - .../doctype/webhook_header/webhook_header.py | 1 - .../integrations/frappe_providers/__init__.py | 2 +- .../frappe_providers/frappecloud.py | 4 +- frappe/integrations/offsite_backup_utils.py | 11 +- frappe/integrations/utils.py | 7 +- frappe/middlewares.py | 2 +- frappe/model/base_document.py | 17 +-- frappe/model/db_query.py | 11 +- frappe/model/delete_doc.py | 7 +- frappe/model/docfield.py | 4 +- frappe/model/document.py | 25 ++-- frappe/model/mapper.py | 2 +- frappe/model/meta.py | 15 +- frappe/model/naming.py | 18 +-- frappe/model/rename_doc.py | 30 ++-- frappe/model/sync.py | 2 +- frappe/model/utils/__init__.py | 4 +- frappe/model/utils/link_count.py | 2 +- frappe/model/utils/rename_doc.py | 7 +- frappe/model/utils/rename_field.py | 2 +- frappe/model/utils/user_settings.py | 12 +- frappe/model/workflow.py | 14 +- frappe/modules/export_file.py | 2 +- frappe/modules/import_file.py | 12 +- frappe/modules/patch_handler.py | 7 +- frappe/modules/utils.py | 5 +- frappe/monitor.py | 1 - frappe/parallel_test_runner.py | 2 +- .../increase_single_table_column_length.py | 2 +- .../delete_duplicate_user_permissions.py | 2 +- .../drop_column_apply_user_permissions.py | 2 +- .../v11_0/fix_order_by_in_reports_json.py | 4 +- .../v11_0/update_list_user_settings.py | 2 +- .../patches/v12_0/delete_duplicate_indexes.py | 4 +- .../patches/v12_0/fix_public_private_files.py | 2 +- .../move_timeline_links_to_dynamic_links.py | 6 +- .../patches/v12_0/set_correct_url_in_files.py | 6 +- frappe/patches/v12_0/setup_tags.py | 2 +- .../patches/v13_0/set_unique_for_page_view.py | 4 +- frappe/patches/v14_0/copy_mail_data.py | 2 - ...date_color_names_in_kanban_board_column.py | 1 - frappe/permissions.py | 5 +- .../doctype/letter_head/test_letter_head.py | 1 - .../doctype/print_format/print_format.py | 1 - .../doctype/print_heading/print_heading.py | 1 - .../print_heading/test_print_heading.py | 1 - .../doctype/print_settings/print_settings.py | 1 - .../print_settings/test_print_settings.py | 1 - .../doctype/print_style/print_style.py | 1 - .../doctype/print_style/test_print_style.py | 1 - .../print_format_builder_beta.py | 3 +- frappe/query_builder/custom.py | 16 +-- frappe/query_builder/functions.py | 4 +- frappe/query_builder/terms.py | 10 +- frappe/query_builder/utils.py | 6 +- frappe/rate_limiter.py | 7 +- frappe/recorder.py | 9 +- .../energy_point_log/energy_point_log.py | 5 +- .../energy_point_log/test_energy_point_log.py | 1 - .../energy_point_rule/energy_point_rule.py | 1 - .../energy_point_settings.py | 1 - .../doctype/review_level/review_level.py | 1 - .../templates/includes/comments/comments.py | 2 +- .../templates/includes/feedback/feedback.py | 3 +- frappe/test_runner.py | 14 +- frappe/tests/test_api.py | 5 +- frappe/tests/test_bot.py | 2 - frappe/tests/test_caching.py | 3 +- frappe/tests/test_client.py | 4 +- frappe/tests/test_commands.py | 29 ++-- frappe/tests/test_db.py | 8 +- frappe/tests/test_db_update.py | 8 +- frappe/tests/test_email.py | 2 +- frappe/tests/test_fixture_import.py | 5 +- frappe/tests/test_form_load.py | 2 +- frappe/tests/test_formatter.py | 1 - frappe/tests/test_frappe_client.py | 8 +- frappe/tests/test_monitor.py | 1 - frappe/tests/test_naming.py | 14 +- frappe/tests/test_permissions.py | 2 +- frappe/tests/test_query_builder.py | 8 +- frappe/tests/test_rate_limiter.py | 2 - frappe/tests/test_recorder.py | 2 - frappe/tests/test_rename_doc.py | 5 +- frappe/tests/test_twofactor.py | 4 +- frappe/tests/test_utils.py | 16 +-- frappe/tests/tests_geo_utils.py | 1 - frappe/tests/ui_test_helpers.py | 4 +- frappe/translate.py | 21 ++- frappe/twofactor.py | 20 +-- frappe/utils/__init__.py | 26 ++-- frappe/utils/background_jobs.py | 6 +- frappe/utils/backups.py | 43 +++--- frappe/utils/boilerplate.py | 2 +- frappe/utils/caching.py | 6 +- frappe/utils/change_log.py | 14 +- frappe/utils/connections.py | 2 +- frappe/utils/csvutils.py | 2 +- frappe/utils/dashboard.py | 6 +- frappe/utils/data.py | 134 +++++++++--------- frappe/utils/dateutils.py | 2 +- frappe/utils/diff.py | 7 +- frappe/utils/doctor.py | 8 +- frappe/utils/error.py | 13 +- frappe/utils/file_manager.py | 8 +- frappe/utils/fixtures.py | 4 +- frappe/utils/formatters.py | 6 +- frappe/utils/global_search.py | 4 +- frappe/utils/goal.py | 9 +- frappe/utils/identicon.py | 4 +- frappe/utils/image.py | 2 +- frappe/utils/jinja.py | 6 +- frappe/utils/logger.py | 6 +- frappe/utils/make_random.py | 2 +- frappe/utils/nestedset.py | 2 +- frappe/utils/oauth.py | 6 +- frappe/utils/password.py | 2 +- frappe/utils/pdf.py | 9 +- frappe/utils/print_format.py | 10 +- frappe/utils/redis_wrapper.py | 42 +++--- frappe/utils/response.py | 6 +- frappe/utils/safe_exec.py | 2 +- frappe/utils/scheduler.py | 8 +- frappe/utils/user.py | 20 +-- frappe/utils/verified_command.py | 2 +- frappe/website/doctype/__init__.py | 1 - .../test_about_us_settings.py | 1 - frappe/website/doctype/blog_post/blog_post.py | 18 +-- .../blog_settings/test_blog_settings.py | 1 - frappe/website/doctype/color/color.py | 1 - frappe/website/doctype/color/test_color.py | 1 - .../doctype/help_article/test_help_article.py | 1 - .../help_category/test_help_category.py | 1 - .../personal_data_deletion_request.py | 3 +- .../test_personal_data_deletion_request.py | 1 - .../personal_data_deletion_step.py | 1 - .../personal_data_download_request.py | 1 - .../test_personal_data_download_request.py | 1 - .../portal_menu_item/portal_menu_item.py | 1 - .../portal_settings/portal_settings.py | 1 - .../portal_settings/test_portal_settings.py | 1 - .../social_link_settings.py | 1 - .../website/doctype/top_bar_item/__init__.py | 1 - frappe/website/doctype/web_form/web_form.py | 18 +-- frappe/website/doctype/web_page/__init__.py | 1 - frappe/website/doctype/web_page/web_page.py | 4 +- .../doctype/web_page_block/web_page_block.py | 1 - .../web_page_view/test_web_page_view.py | 1 - .../doctype/web_page_view/web_page_view.py | 1 - .../doctype/web_template/test_web_template.py | 1 - .../doctype/web_template/web_template.py | 3 +- .../test_web_template_field.py | 1 - .../web_template_field/web_template_field.py | 1 - .../website_meta_tag/website_meta_tag.py | 1 - .../test_website_route_meta.py | 1 - .../website_route_meta/website_route_meta.py | 1 - .../website_route_redirect.py | 1 - .../doctype/website_settings/__init__.py | 1 - .../website_settings/google_indexing.py | 3 +- .../website_settings/test_website_settings.py | 1 - .../website_settings/website_settings.py | 5 +- .../website_sidebar/test_website_sidebar.py | 1 - .../website_sidebar/website_sidebar.py | 1 - .../website_sidebar_item.py | 1 - .../test_website_slideshow.py | 1 - .../doctype/website_theme/website_theme.py | 2 +- .../website_theme_ignore_app.py | 1 - .../website/page_renderers/base_renderer.py | 2 +- .../page_renderers/base_template_page.py | 2 +- .../website/page_renderers/redirect_page.py | 2 +- .../website/page_renderers/template_page.py | 6 +- .../website_analytics/website_analytics.py | 2 +- frappe/website/router.py | 6 +- frappe/website/utils.py | 15 +- frappe/website/website_generator.py | 4 +- .../doctype/workflow/test_workflow.py | 2 +- .../workflow_action_master.py | 1 - frappe/www/__init__.py | 1 - frappe/www/_test/_test_metatags.py | 2 - frappe/www/app.py | 8 +- frappe/www/list.py | 4 +- frappe/www/login.py | 2 +- frappe/www/message.py | 2 +- frappe/www/printview.py | 10 +- frappe/www/qrcode.py | 4 +- frappe/www/rss.py | 2 +- 529 files changed, 977 insertions(+), 1441 deletions(-) diff --git a/frappe/__init__.py b/frappe/__init__.py index 063a62c84b..8e0cc8f0a8 100644 --- a/frappe/__init__.py +++ b/frappe/__init__.py @@ -17,7 +17,7 @@ import json import os import re import warnings -from typing import TYPE_CHECKING, Any, Callable, Dict, List, Optional, Union +from typing import TYPE_CHECKING, Any, Callable import click from werkzeug.local import Local, release_local @@ -103,7 +103,7 @@ def _(msg, lang=None, context=None) -> str: translated_string = "" if context: - string_key = "{msg}:{context}".format(msg=msg, context=context) + string_key = f"{msg}:{context}" translated_string = get_full_dict(lang).get(string_key) if not translated_string: @@ -168,8 +168,8 @@ if TYPE_CHECKING: from frappe.query_builder.builder import MariaDB, Postgres from frappe.utils.redis_wrapper import RedisWrapper - db: Union[MariaDBDatabase, PostgresDatabase] - qb: Union[MariaDB, Postgres] + db: MariaDBDatabase | PostgresDatabase + qb: MariaDB | Postgres # end: static analysis hack @@ -308,10 +308,10 @@ def get_site_config(sites_path=None, site_path=None): try: config.update(get_file_json(site_config)) except Exception as error: - click.secho("{0}/site_config.json is invalid".format(local.site), fg="red") + click.secho(f"{local.site}/site_config.json is invalid", fg="red") print(error) elif local.site and not local.flags.new_site: - raise IncorrectSitePath("{0} does not exist".format(local.site)) + raise IncorrectSitePath(f"{local.site} does not exist") return _dict(config) @@ -993,7 +993,7 @@ def get_precision(doctype, fieldname, currency=None, doc=None): return get_field_precision(get_meta(doctype).get_field(fieldname), doc, currency) -def generate_hash(txt: Optional[str] = None, length: Optional[int] = None) -> str: +def generate_hash(txt: str | None = None, length: int | None = None) -> str: """Generates random hash for given text + current timestamp + random string.""" import hashlib import time @@ -1399,7 +1399,7 @@ def get_doc_hooks(): @request_cache -def _load_app_hooks(app_name: Optional[str] = None): +def _load_app_hooks(app_name: str | None = None): hooks = {} apps = [app_name] if app_name else get_installed_apps(sort=True) @@ -1422,7 +1422,7 @@ def _load_app_hooks(app_name: Optional[str] = None): def get_hooks( - hook: str = None, default: Optional[Any] = "_KEEP_DEFAULT_LIST", app_name: str = None + hook: str = None, default: Any | None = "_KEEP_DEFAULT_LIST", app_name: str = None ) -> _dict: """Get hooks via `app/hooks.py` @@ -1505,7 +1505,7 @@ def get_file_items(path, raise_not_found=False, ignore_empty_lines=True): def get_file_json(path): """Read a file and return parsed JSON object.""" - with open(path, "r") as f: + with open(path) as f: return json.load(f) @@ -1515,10 +1515,10 @@ def read_file(path, raise_not_found=False): path = path.encode("utf-8") if os.path.exists(path): - with open(path, "r") as f: + with open(path) as f: return as_unicode(f.read()) elif raise_not_found: - raise IOError("{} Not Found".format(path)) + raise OSError(f"{path} Not Found") else: return None @@ -1548,7 +1548,7 @@ def call(fn, *args, **kwargs): return fn(*args, **newargs) -def get_newargs(fn: Callable, kwargs: Dict[str, Any]) -> Dict[str, Any]: +def get_newargs(fn: Callable, kwargs: dict[str, Any]) -> dict[str, Any]: """Remove any kwargs that are not supported by the function. Example: @@ -1785,8 +1785,8 @@ def redirect_to_message(title, html, http_status_code=None, context=None, indica if indicator_color: message["context"].update({"indicator_color": indicator_color}) - cache().set_value("message_id:{0}".format(message_id), message, expires_in_sec=60) - location = "/message?id={0}".format(message_id) + cache().set_value(f"message_id:{message_id}", message, expires_in_sec=60) + location = f"/message?id={message_id}" if not getattr(local, "is_ajax", False): local.response["type"] = "redirect" @@ -1872,7 +1872,7 @@ def get_value(*args, **kwargs): return db.get_value(*args, **kwargs) -def as_json(obj: Union[Dict, List], indent=1, separators=None) -> str: +def as_json(obj: dict | list, indent=1, separators=None) -> str: from frappe.utils.response import json_handler if separators is None: @@ -1903,7 +1903,7 @@ def get_test_records(doctype): get_module_path(get_doctype_module(doctype)), "doctype", scrub(doctype), "test_records.json" ) if os.path.exists(path): - with open(path, "r") as f: + with open(path) as f: return json.loads(f.read()) else: return [] @@ -2183,7 +2183,7 @@ def get_desk_link(doctype, name): def bold(text): - return "{0}".format(text) + return f"{text}" def safe_eval(code, eval_globals=None, eval_locals=None): @@ -2211,10 +2211,10 @@ def safe_eval(code, eval_globals=None, eval_locals=None): for attribute in UNSAFE_ATTRIBUTES: if attribute in code: - throw('Illegal rule {0}. Cannot use "{1}"'.format(bold(code), attribute)) + throw(f'Illegal rule {bold(code)}. Cannot use "{attribute}"') if "__" in code: - throw('Illegal rule {0}. Cannot use "__"'.format(bold(code))) + throw(f'Illegal rule {bold(code)}. Cannot use "__"') if not eval_globals: eval_globals = {} diff --git a/frappe/api.py b/frappe/api.py index 32e19a1b43..1048468077 100644 --- a/frappe/api.py +++ b/frappe/api.py @@ -167,7 +167,7 @@ def validate_auth(): """ Authenticate and sets user for the request. """ - authorization_header = frappe.get_request_header("Authorization", str()).split(" ") + authorization_header = frappe.get_request_header("Authorization", "").split(" ") if len(authorization_header) == 2: validate_oauth(authorization_header) diff --git a/frappe/app.py b/frappe/app.py index f8c81478c0..d05febba9e 100644 --- a/frappe/app.py +++ b/frappe/app.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors # License: MIT. See LICENSE @@ -34,7 +33,7 @@ SAFE_HTTP_METHODS = ("GET", "HEAD", "OPTIONS") UNSAFE_HTTP_METHODS = ("POST", "PUT", "DELETE", "PATCH") -class RequestContext(object): +class RequestContext: def __init__(self, environ): self.request = Request(environ) @@ -331,12 +330,10 @@ def serve( if not os.environ.get("NO_STATICS"): application = SharedDataMiddleware( - application, {str("/assets"): str(os.path.join(sites_path, "assets"))} + application, {"/assets": str(os.path.join(sites_path, "assets"))} ) - application = StaticDataMiddleware( - application, {str("/files"): str(os.path.abspath(sites_path))} - ) + application = StaticDataMiddleware(application, {"/files": str(os.path.abspath(sites_path))}) application.debug = True application.config = {"SERVER_NAME": "localhost:8000"} diff --git a/frappe/auth.py b/frappe/auth.py index 80141d1d6c..3737681d71 100644 --- a/frappe/auth.py +++ b/frappe/auth.py @@ -471,7 +471,7 @@ def get_login_attempt_tracker(user_name: str, raise_locked_exception: bool = Tru return tracker -class LoginAttemptTracker(object): +class LoginAttemptTracker: """Track login attemts of a user. Lock the account for s number of seconds if there have been n consecutive unsuccessful attempts to log in. diff --git a/frappe/automation/doctype/assignment_rule/assignment_rule.py b/frappe/automation/doctype/assignment_rule/assignment_rule.py index 0ca64e54c2..508ed317c6 100644 --- a/frappe/automation/doctype/assignment_rule/assignment_rule.py +++ b/frappe/automation/doctype/assignment_rule/assignment_rule.py @@ -1,7 +1,7 @@ # Copyright (c) 2022, Frappe Technologies and contributors # License: MIT. See LICENSE -from typing import Dict, Iterable, List +from collections.abc import Iterable import frappe from frappe import _ @@ -157,7 +157,7 @@ class AssignmentRule(Document): return assignment_days and today not in assignment_days -def get_assignments(doc) -> List[Dict]: +def get_assignments(doc) -> list[dict]: return frappe.get_all( "ToDo", fields=["name", "assignment_rule"], @@ -228,7 +228,7 @@ def apply(doc=None, method=None, doctype=None, name=None): ) # multiple auto assigns - assignment_rule_docs: List[AssignmentRule] = [ + assignment_rule_docs: list[AssignmentRule] = [ frappe.get_cached_doc("Assignment Rule", d.get("name")) for d in assignment_rules ] @@ -356,11 +356,11 @@ def update_due_date(doc, state=None): todo_doc.save(ignore_permissions=True) -def get_assignment_rules() -> List[str]: +def get_assignment_rules() -> list[str]: return frappe.get_all("Assignment Rule", filters={"disabled": 0}, pluck="document_type") -def get_repeated(values: Iterable) -> List: +def get_repeated(values: Iterable) -> list: unique = set() repeated = set() diff --git a/frappe/automation/doctype/assignment_rule_day/assignment_rule_day.py b/frappe/automation/doctype/assignment_rule_day/assignment_rule_day.py index 2a7e6dd66f..5a1af94696 100644 --- a/frappe/automation/doctype/assignment_rule_day/assignment_rule_day.py +++ b/frappe/automation/doctype/assignment_rule_day/assignment_rule_day.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/automation/doctype/assignment_rule_user/assignment_rule_user.py b/frappe/automation/doctype/assignment_rule_user/assignment_rule_user.py index 3f47f3c866..8b848589c3 100644 --- a/frappe/automation/doctype/assignment_rule_user/assignment_rule_user.py +++ b/frappe/automation/doctype/assignment_rule_user/assignment_rule_user.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/automation/doctype/auto_repeat/auto_repeat.py b/frappe/automation/doctype/auto_repeat/auto_repeat.py index d3399f7726..0442be0976 100644 --- a/frappe/automation/doctype/auto_repeat/auto_repeat.py +++ b/frappe/automation/doctype/auto_repeat/auto_repeat.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors # License: MIT. See LICENSE diff --git a/frappe/automation/doctype/auto_repeat/test_auto_repeat.py b/frappe/automation/doctype/auto_repeat/test_auto_repeat.py index e1db7ca6d1..ee0addf847 100644 --- a/frappe/automation/doctype/auto_repeat/test_auto_repeat.py +++ b/frappe/automation/doctype/auto_repeat/test_auto_repeat.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2018, Frappe Technologies and Contributors # License: MIT. See LICENSE import unittest @@ -200,7 +199,7 @@ class TestAutoRepeat(unittest.TestCase): # next_schedule_date is set as on or after current date # it should not be a previous month's date - self.assertTrue((doc.next_schedule_date >= current_date)) + self.assertTrue(doc.next_schedule_date >= current_date) todo = frappe.get_doc( dict( diff --git a/frappe/automation/doctype/auto_repeat_day/auto_repeat_day.py b/frappe/automation/doctype/auto_repeat_day/auto_repeat_day.py index 95d75bf9da..6453f2e80d 100644 --- a/frappe/automation/doctype/auto_repeat_day/auto_repeat_day.py +++ b/frappe/automation/doctype/auto_repeat_day/auto_repeat_day.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2020, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/automation/doctype/milestone/milestone.py b/frappe/automation/doctype/milestone/milestone.py index 4059a2eb73..40d6fae989 100644 --- a/frappe/automation/doctype/milestone/milestone.py +++ b/frappe/automation/doctype/milestone/milestone.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/automation/doctype/milestone/test_milestone.py b/frappe/automation/doctype/milestone/test_milestone.py index 1824220497..5ac0754e5a 100644 --- a/frappe/automation/doctype/milestone/test_milestone.py +++ b/frappe/automation/doctype/milestone/test_milestone.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and Contributors # License: MIT. See LICENSE # import frappe diff --git a/frappe/automation/doctype/milestone_tracker/milestone_tracker.py b/frappe/automation/doctype/milestone_tracker/milestone_tracker.py index 16b2fe9204..5388797b80 100644 --- a/frappe/automation/doctype/milestone_tracker/milestone_tracker.py +++ b/frappe/automation/doctype/milestone_tracker/milestone_tracker.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/automation/doctype/milestone_tracker/test_milestone_tracker.py b/frappe/automation/doctype/milestone_tracker/test_milestone_tracker.py index 4e53072348..2b48a76805 100644 --- a/frappe/automation/doctype/milestone_tracker/test_milestone_tracker.py +++ b/frappe/automation/doctype/milestone_tracker/test_milestone_tracker.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and Contributors # License: MIT. See LICENSE import unittest diff --git a/frappe/build.py b/frappe/build.py index a7fdb47677..e66da4bd79 100644 --- a/frappe/build.py +++ b/frappe/build.py @@ -200,7 +200,7 @@ def symlink(target, link_name, overwrite=False): try: # Pre-empt os.replace on a directory with a nicer message if os.path.isdir(link_name): - raise IsADirectoryError("Cannot symlink over existing directory: '{}'".format(link_name)) + raise IsADirectoryError(f"Cannot symlink over existing directory: '{link_name}'") try: os.replace(temp_link_name, link_name) except AttributeError: @@ -239,10 +239,10 @@ def bundle( make_asset_dirs(hard_link=hard_link) mode = "production" if mode == "production" else "build" - command = "yarn run {mode}".format(mode=mode) + command = f"yarn run {mode}" if apps: - command += " --apps {apps}".format(apps=apps) + command += f" --apps {apps}" if skip_frappe: command += " --skip_frappe" @@ -263,7 +263,7 @@ def watch(apps=None): command = "yarn run watch" if apps: - command += " --apps {apps}".format(apps=apps) + command += f" --apps {apps}" live_reload = frappe.utils.cint(os.environ.get("LIVE_RELOAD", frappe.conf.live_reload)) diff --git a/frappe/client.py b/frappe/client.py index d5dc890f56..bd5c3b275b 100644 --- a/frappe/client.py +++ b/frappe/client.py @@ -349,13 +349,13 @@ def get_js(items): frappe.throw(_("Invalid file path: {0}").format("/".join(src))) contentpath = os.path.join(frappe.local.sites_path, *src) - with open(contentpath, "r") as srcfile: + with open(contentpath) as srcfile: code = frappe.utils.cstr(srcfile.read()) if frappe.local.lang != "en": messages = frappe.get_lang_dict("jsfile", contentpath) messages = json.dumps(messages) - code += "\n\n$.extend(frappe._messages, {})".format(messages) + code += f"\n\n$.extend(frappe._messages, {messages})" out.append(code) diff --git a/frappe/commands/scheduler.py b/frappe/commands/scheduler.py index a39a604ece..f26180e169 100755 --- a/frappe/commands/scheduler.py +++ b/frappe/commands/scheduler.py @@ -114,7 +114,7 @@ def scheduler(context, state, site=None): frappe.utils.scheduler.enable_scheduler() frappe.db.commit() - print("Scheduler {0}d for site {1}".format(state, site)) + print(f"Scheduler {state}d for site {site}") finally: frappe.destroy() @@ -182,7 +182,7 @@ def purge_jobs(site=None, queue=None, event=None): frappe.init(site or "") count = purge_pending_jobs(event=event, site=site, queue=queue) - print("Purged {} jobs".format(count)) + print(f"Purged {count} jobs") @click.command("schedule") @@ -218,11 +218,11 @@ def ready_for_migration(context, site=None): pending_jobs = get_pending_jobs(site=site) if pending_jobs: - print("NOT READY for migration: site {0} has pending background jobs".format(site)) + print(f"NOT READY for migration: site {site} has pending background jobs") sys.exit(1) else: - print("READY for migration: site {0} does not have any background jobs".format(site)) + print(f"READY for migration: site {site} does not have any background jobs") return 0 finally: diff --git a/frappe/commands/site.py b/frappe/commands/site.py index a8667d6595..626da058c3 100644 --- a/frappe/commands/site.py +++ b/frappe/commands/site.py @@ -256,7 +256,7 @@ def restore( os.remove(private) _backup.decryption_rollback() - success_message = "Site {0} has been restored{1}".format( + success_message = "Site {} has been restored{}".format( site, " with files" if (with_public_files or with_private_files) else "" ) click.secho(success_message, fg="green") @@ -413,12 +413,12 @@ def install_app(context, apps, force=False): try: _install_app(app, verbose=context.verbose, force=force) except frappe.IncompatibleApp as err: - err_msg = ":\n{}".format(err) if str(err) else "" - print("App {} is Incompatible with Site {}{}".format(app, site, err_msg)) + err_msg = f":\n{err}" if str(err) else "" + print(f"App {app} is Incompatible with Site {site}{err_msg}") exit_code = 1 except Exception as err: - err_msg = ": {}\n{}".format(str(err), frappe.get_traceback()) - print("An error occurred while installing {}{}".format(app, err_msg)) + err_msg = f": {str(err)}\n{frappe.get_traceback()}" + print(f"An error occurred while installing {app}{err_msg}") exit_code = 1 frappe.destroy() @@ -448,8 +448,8 @@ def list_apps(context, format): apps = frappe.get_single("Installed Applications").installed_applications if apps: - name_len, ver_len = [max([len(x.get(y)) for x in apps]) for y in ["app_name", "app_version"]] - template = "{{0:{0}}} {{1:{1}}} {{2}}".format(name_len, ver_len) + name_len, ver_len = (max(len(x.get(y)) for x in apps) for y in ["app_name", "app_version"]) + template = f"{{0:{name_len}}} {{1:{ver_len}}} {{2}}" installed_applications = [ template.format(app.app_name, app.app_version, app.git_branch) for app in apps @@ -607,7 +607,7 @@ def reload_doctype(context, doctype): def add_to_hosts(context): "Add site to hosts" for site in context.sites: - frappe.commands.popen("echo 127.0.0.1\t{0} | sudo tee -a /etc/hosts".format(site)) + frappe.commands.popen(f"echo 127.0.0.1\t{site} | sudo tee -a /etc/hosts") if not context.sites: raise SiteNotSpecifiedError @@ -623,9 +623,9 @@ def use(site, sites_path="."): if os.path.exists(os.path.join(sites_path, site)): with open(os.path.join(sites_path, "currentsite.txt"), "w") as sitefile: sitefile.write(site) - print("Current Site set to {}".format(site)) + print(f"Current Site set to {site}") else: - print("Site {} does not exist".format(site)) + print(f"Site {site} does not exist") @click.command("backup") @@ -699,7 +699,7 @@ def backup( ) except Exception: click.secho( - "Backup failed for Site {0}. Database or site_config.json may be corrupted".format(site), + f"Backup failed for Site {site}. Database or site_config.json may be corrupted", fg="red", ) if verbose: @@ -713,7 +713,7 @@ def backup( odb.print_summary() click.secho( - "Backup for Site {0} has been successfully completed{1}".format( + "Backup for Site {} has been successfully completed{}".format( site, " with files" if with_files else "" ), fg="green", @@ -830,8 +830,8 @@ def _drop_site( else: messages = [ "=" * 80, - "Error: The operation has stopped because backup of {0}'s database failed.".format(site), - "Reason: {0}\n".format(str(err)), + f"Error: The operation has stopped because backup of {site}'s database failed.", + f"Reason: {str(err)}\n", "Fix the issue and try again.", "Hint: Use 'bench drop-site {0} --force' to force the removal of {0}".format(site), ] @@ -1080,7 +1080,7 @@ def build_search_index(context): if not site: raise SiteNotSpecifiedError - print("Building search index for {}".format(site)) + print(f"Building search index for {site}") frappe.init(site=site) frappe.connect() try: diff --git a/frappe/commands/utils.py b/frappe/commands/utils.py index 41a4b27bcf..1b63914030 100644 --- a/frappe/commands/utils.py +++ b/frappe/commands/utils.py @@ -387,7 +387,7 @@ def import_doc(context, path, force=False): if not os.path.exists(path): path = os.path.join("..", path) if not os.path.exists(path): - print("Invalid path {0}".format(path)) + print(f"Invalid path {path}") sys.exit(1) for site in context.sites: @@ -471,7 +471,7 @@ def bulk_rename(context, doctype, path): site = get_site(context) - with open(path, "r") as csvfile: + with open(path) as csvfile: rows = read_csv_content(csvfile.read()) frappe.init(site=site) @@ -566,7 +566,7 @@ def jupyter(context): try: os.stat(jupyter_notebooks_path) except OSError: - print("Creating folder to keep jupyter notebooks at {}".format(jupyter_notebooks_path)) + print(f"Creating folder to keep jupyter notebooks at {jupyter_notebooks_path}") os.mkdir(jupyter_notebooks_path) bin_path = os.path.abspath("../env/bin") print( @@ -585,9 +585,9 @@ frappe.db.connect() ) ) os.execv( - "{0}/jupyter".format(bin_path), + f"{bin_path}/jupyter", [ - "{0}/jupyter".format(bin_path), + f"{bin_path}/jupyter", "notebook", jupyter_notebooks_path, ], @@ -780,7 +780,7 @@ def run_tests( if not (allow_tests or os.environ.get("CI")): click.secho("Testing is disabled for the site!", bold=True) click.secho("You can enable tests by entering following command:") - click.secho("bench --site {0} set-config allow_tests true".format(site), fg="green") + click.secho(f"bench --site {site} set-config allow_tests true", fg="green") return frappe.init(site=site) @@ -955,7 +955,7 @@ def request(context, args=None, path=None): if args.startswith("/api/method"): frappe.local.form_dict.cmd = args.split("?")[0].split("/")[-1] elif path: - with open(os.path.join("..", path), "r") as f: + with open(os.path.join("..", path)) as f: args = json.loads(f.read()) frappe.local.form_dict = frappe._dict(args) diff --git a/frappe/contacts/address_and_contact.py b/frappe/contacts/address_and_contact.py index 1c5803ffea..4df32c6705 100644 --- a/frappe/contacts/address_and_contact.py +++ b/frappe/contacts/address_and_contact.py @@ -3,7 +3,6 @@ import functools import re -from typing import Dict, List import frappe from frappe import _ @@ -117,9 +116,7 @@ def get_permission_query_conditions(doctype): # when everything is not permitted for df in links.get("not_permitted_links"): # like ifnull(customer, '')='' and ifnull(supplier, '')='' - conditions.append( - "ifnull(`tab{doctype}`.`{fieldname}`, '')=''".format(doctype=doctype, fieldname=df.fieldname) - ) + conditions.append(f"ifnull(`tab{doctype}`.`{df.fieldname}`, '')=''") return "( " + " and ".join(conditions) + " )" @@ -128,9 +125,7 @@ def get_permission_query_conditions(doctype): for df in links.get("permitted_links"): # like ifnull(customer, '')!='' or ifnull(supplier, '')!='' - conditions.append( - "ifnull(`tab{doctype}`.`{fieldname}`, '')!=''".format(doctype=doctype, fieldname=df.fieldname) - ) + conditions.append(f"ifnull(`tab{doctype}`.`{df.fieldname}`, '')!=''") return "( " + " or ".join(conditions) + " )" @@ -171,8 +166,8 @@ def delete_contact_and_address(doctype, docname): @frappe.whitelist() @frappe.validate_and_sanitize_search_inputs def filter_dynamic_link_doctypes( - doctype, txt: str, searchfield, start, page_len, filters: Dict -) -> List[List[str]]: + doctype, txt: str, searchfield, start, page_len, filters: dict +) -> list[list[str]]: from frappe.permissions import get_doctypes_with_read txt = txt or "" diff --git a/frappe/contacts/doctype/address/address.py b/frappe/contacts/doctype/address/address.py index c7564e8866..42dbdd6177 100644 --- a/frappe/contacts/doctype/address/address.py +++ b/frappe/contacts/doctype/address/address.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies and contributors # License: MIT. See LICENSE @@ -236,7 +235,7 @@ def address_query(doctype, txt, searchfield, start, page_len, filters): meta = frappe.get_meta("Address") for fieldname, value in filters.items(): if meta.get_field(fieldname) or fieldname in frappe.db.DEFAULT_COLUMNS: - condition += " and {field}={value}".format(field=fieldname, value=frappe.db.escape(value)) + condition += f" and {fieldname}={frappe.db.escape(value)}" searchfields = meta.get_search_fields() @@ -246,9 +245,9 @@ def address_query(doctype, txt, searchfield, start, page_len, filters): search_condition = "" for field in searchfields: if search_condition == "": - search_condition += "`tabAddress`.`{field}` like %(txt)s".format(field=field) + search_condition += f"`tabAddress`.`{field}` like %(txt)s" else: - search_condition += " or `tabAddress`.`{field}` like %(txt)s".format(field=field) + search_condition += f" or `tabAddress`.`{field}` like %(txt)s" return frappe.db.sql( """select diff --git a/frappe/contacts/doctype/address/test_address.py b/frappe/contacts/doctype/address/test_address.py index 4a6e6e53f7..edcf87f5bc 100644 --- a/frappe/contacts/doctype/address/test_address.py +++ b/frappe/contacts/doctype/address/test_address.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies and Contributors # License: MIT. See LICENSE import unittest diff --git a/frappe/contacts/doctype/address_template/address_template.py b/frappe/contacts/doctype/address_template/address_template.py index 85e9a986ef..a8806b336b 100644 --- a/frappe/contacts/doctype/address_template/address_template.py +++ b/frappe/contacts/doctype/address_template/address_template.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/contacts/doctype/address_template/test_address_template.py b/frappe/contacts/doctype/address_template/test_address_template.py index 699de5ada0..8045313c69 100644 --- a/frappe/contacts/doctype/address_template/test_address_template.py +++ b/frappe/contacts/doctype/address_template/test_address_template.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies and Contributors # License: MIT. See LICENSE import unittest diff --git a/frappe/contacts/doctype/contact/contact.py b/frappe/contacts/doctype/contact/contact.py index 4036cda853..a17f46216b 100644 --- a/frappe/contacts/doctype/contact/contact.py +++ b/frappe/contacts/doctype/contact/contact.py @@ -290,7 +290,7 @@ def get_contact_with_phone_number(number): return contacts = frappe.get_all( - "Contact Phone", filters=[["phone", "like", "%{0}".format(number)]], fields=["parent"], limit=1 + "Contact Phone", filters=[["phone", "like", f"%{number}"]], fields=["parent"], limit=1 ) return contacts[0].parent if contacts else None diff --git a/frappe/contacts/doctype/contact/test_contact.py b/frappe/contacts/doctype/contact/test_contact.py index 7ca47476e8..bf0d1037db 100644 --- a/frappe/contacts/doctype/contact/test_contact.py +++ b/frappe/contacts/doctype/contact/test_contact.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2017, Frappe Technologies and Contributors # License: MIT. See LICENSE import unittest diff --git a/frappe/contacts/doctype/contact_email/contact_email.py b/frappe/contacts/doctype/contact_email/contact_email.py index ed794ac06c..b6be852e57 100644 --- a/frappe/contacts/doctype/contact_email/contact_email.py +++ b/frappe/contacts/doctype/contact_email/contact_email.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/contacts/doctype/contact_phone/contact_phone.py b/frappe/contacts/doctype/contact_phone/contact_phone.py index 2a842c9c9e..ba6cd89834 100644 --- a/frappe/contacts/doctype/contact_phone/contact_phone.py +++ b/frappe/contacts/doctype/contact_phone/contact_phone.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/contacts/doctype/gender/gender.py b/frappe/contacts/doctype/gender/gender.py index 8e9951eaf9..fa38a5a6b0 100644 --- a/frappe/contacts/doctype/gender/gender.py +++ b/frappe/contacts/doctype/gender/gender.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2017, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/contacts/doctype/gender/test_gender.py b/frappe/contacts/doctype/gender/test_gender.py index 6b795749ee..c8df3b566d 100644 --- a/frappe/contacts/doctype/gender/test_gender.py +++ b/frappe/contacts/doctype/gender/test_gender.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2017, Frappe Technologies and Contributors # License: MIT. See LICENSE import unittest diff --git a/frappe/contacts/doctype/salutation/salutation.py b/frappe/contacts/doctype/salutation/salutation.py index 57fb2d6abc..66469c4700 100644 --- a/frappe/contacts/doctype/salutation/salutation.py +++ b/frappe/contacts/doctype/salutation/salutation.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2017, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/contacts/doctype/salutation/test_salutation.py b/frappe/contacts/doctype/salutation/test_salutation.py index 5149ced3dd..2c35e5bd2b 100644 --- a/frappe/contacts/doctype/salutation/test_salutation.py +++ b/frappe/contacts/doctype/salutation/test_salutation.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2017, Frappe Technologies and Contributors # License: MIT. See LICENSE import unittest diff --git a/frappe/core/api/file.py b/frappe/core/api/file.py index e558f2f7e3..ec305aff4f 100644 --- a/frappe/core/api/file.py +++ b/frappe/core/api/file.py @@ -1,5 +1,4 @@ import json -from typing import Dict, List import frappe from frappe.core.doctype.file.file import File, setup_folder_path @@ -14,7 +13,7 @@ def unzip_file(name: str): @frappe.whitelist() -def get_attached_images(doctype: str, names: List[str]) -> frappe._dict: +def get_attached_images(doctype: str, names: list[str]) -> frappe._dict: """get list of image urls attached in form returns {name: ['image.jpg', 'image.png']}""" @@ -40,7 +39,7 @@ def get_attached_images(doctype: str, names: List[str]) -> frappe._dict: @frappe.whitelist() -def get_files_in_folder(folder: str, start: int = 0, page_length: int = 20) -> Dict: +def get_files_in_folder(folder: str, start: int = 0, page_length: int = 20) -> dict: start = cint(start) page_length = cint(page_length) @@ -66,7 +65,7 @@ def get_files_in_folder(folder: str, start: int = 0, page_length: int = 20) -> D @frappe.whitelist() -def get_files_by_search_text(text: str) -> List[Dict]: +def get_files_by_search_text(text: str) -> list[dict]: if not text: return [] @@ -102,7 +101,7 @@ def create_new_folder(file_name: str, folder: str) -> File: @frappe.whitelist() -def move_file(file_list: List[File], new_parent: str, old_parent: str) -> None: +def move_file(file_list: list[File], new_parent: str, old_parent: str) -> None: if isinstance(file_list, str): file_list = json.loads(file_list) diff --git a/frappe/core/doctype/access_log/test_access_log.py b/frappe/core/doctype/access_log/test_access_log.py index 983e3cb5e4..ee0422e11a 100644 --- a/frappe/core/doctype/access_log/test_access_log.py +++ b/frappe/core/doctype/access_log/test_access_log.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and Contributors # License: MIT. See LICENSE @@ -28,7 +27,7 @@ class TestAccessLog(unittest.TestCase): "User", frappe.session.user, fieldname="api_secret" ) api_key = frappe.db.get_value("User", "Administrator", "api_key") - self.header = {"Authorization": "token {}:{}".format(api_key, generated_secret)} + self.header = {"Authorization": f"token {api_key}:{generated_secret}"} self.test_html_template = """ diff --git a/frappe/core/doctype/activity_log/feed.py b/frappe/core/doctype/activity_log/feed.py index 3e29154242..eb040927e1 100644 --- a/frappe/core/doctype/activity_log/feed.py +++ b/frappe/core/doctype/activity_log/feed.py @@ -74,9 +74,7 @@ def get_feed_match_conditions(user=None, doctype="Comment"): user_permissions = frappe.permissions.get_user_permissions(user) can_read = frappe.get_user().get_can_read() - can_read_doctypes = [ - "'{}'".format(dt) for dt in list(set(can_read) - set(list(user_permissions))) - ] + can_read_doctypes = [f"'{dt}'" for dt in list(set(can_read) - set(list(user_permissions)))] if can_read_doctypes: conditions += [ diff --git a/frappe/core/doctype/activity_log/test_activity_log.py b/frappe/core/doctype/activity_log/test_activity_log.py index f5f94dc44b..c362fca521 100644 --- a/frappe/core/doctype/activity_log/test_activity_log.py +++ b/frappe/core/doctype/activity_log/test_activity_log.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies and Contributors # License: MIT. See LICENSE import time diff --git a/frappe/core/doctype/block_module/block_module.py b/frappe/core/doctype/block_module/block_module.py index 456df5037c..b9de5b325e 100644 --- a/frappe/core/doctype/block_module/block_module.py +++ b/frappe/core/doctype/block_module/block_module.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors # License: MIT. See LICENSE diff --git a/frappe/core/doctype/comment/comment.py b/frappe/core/doctype/comment/comment.py index 1456f1ec93..dab9cfbfe4 100644 --- a/frappe/core/doctype/comment/comment.py +++ b/frappe/core/doctype/comment/comment.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and contributors # License: MIT. See LICENSE import json @@ -51,7 +50,7 @@ class Comment(Document): return frappe.publish_realtime( - "update_docinfo_for_{}_{}".format(self.reference_doctype, self.reference_name), + f"update_docinfo_for_{self.reference_doctype}_{self.reference_name}", {"doc": self.as_dict(), "key": key, "action": action}, after_commit=True, ) @@ -183,7 +182,7 @@ def update_comments_in_parent(reference_doctype, reference_name, _comments): try: # use sql, so that we do not mess with the timestamp frappe.db.sql( - """update `tab{0}` set `_comments`=%s where name=%s""".format(reference_doctype), # nosec + f"""update `tab{reference_doctype}` set `_comments`=%s where name=%s""", # nosec (json.dumps(_comments[-100:]), reference_name), ) diff --git a/frappe/core/doctype/comment/test_comment.py b/frappe/core/doctype/comment/test_comment.py index 3072f8b5b9..bedcea6e7e 100644 --- a/frappe/core/doctype/comment/test_comment.py +++ b/frappe/core/doctype/comment/test_comment.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and Contributors # License: MIT. See LICENSE import json diff --git a/frappe/core/doctype/communication/communication.py b/frappe/core/doctype/communication/communication.py index 9b86f18726..fac8ac74b9 100644 --- a/frappe/core/doctype/communication/communication.py +++ b/frappe/core/doctype/communication/communication.py @@ -3,7 +3,6 @@ from collections import Counter from email.utils import getaddresses -from typing import List from urllib.parse import unquote from parse import compile @@ -204,7 +203,7 @@ class Communication(Document, CommunicationEmailMixin): """ emails = split_emails(emails) if isinstance(emails, str) else (emails or []) if exclude_displayname: - return [email.lower() for email in set([parse_addr(email)[1] for email in emails]) if email] + return [email.lower() for email in {parse_addr(email)[1] for email in emails} if email] return [email.lower() for email in set(emails) if email] def to_list(self, exclude_displayname=True): @@ -229,7 +228,7 @@ class Communication(Document, CommunicationEmailMixin): def notify_change(self, action): frappe.publish_realtime( - "update_docinfo_for_{}_{}".format(self.reference_doctype, self.reference_name), + f"update_docinfo_for_{self.reference_doctype}_{self.reference_name}", {"doc": self.as_dict(), "key": "communications", "action": action}, after_commit=True, ) @@ -425,7 +424,7 @@ def get_permission_query_conditions_for_communication(user): ) -def get_contacts(email_strings: List[str], auto_create_contact=False) -> List[str]: +def get_contacts(email_strings: list[str], auto_create_contact=False) -> list[str]: email_addrs = get_emails(email_strings) contacts = [] for email in email_addrs: @@ -437,9 +436,7 @@ def get_contacts(email_strings: List[str], auto_create_contact=False) -> List[st first_name = frappe.unscrub(email_parts[0]) try: - contact_name = ( - "{0}-{1}".format(first_name, email_parts[1]) if first_name == "Contact" else first_name - ) + contact_name = f"{first_name}-{email_parts[1]}" if first_name == "Contact" else first_name contact = frappe.get_doc( {"doctype": "Contact", "first_name": contact_name, "name": contact_name} ) @@ -455,7 +452,7 @@ def get_contacts(email_strings: List[str], auto_create_contact=False) -> List[st return contacts -def get_emails(email_strings: List[str]) -> List[str]: +def get_emails(email_strings: list[str]) -> list[str]: email_addrs = [] for email_string in email_strings: @@ -522,7 +519,7 @@ def get_email_without_link(email): except IndexError: return email - return "{0}@{1}".format(email_id, email_host) + return f"{email_id}@{email_host}" def update_parent_document_on_communication(doc): diff --git a/frappe/core/doctype/communication/email.py b/frappe/core/doctype/communication/email.py index 2c8a65fafe..c5585fd463 100755 --- a/frappe/core/doctype/communication/email.py +++ b/frappe/core/doctype/communication/email.py @@ -2,7 +2,7 @@ # License: MIT. See LICENSE import json -from typing import TYPE_CHECKING, Dict +from typing import TYPE_CHECKING import frappe import frappe.email.smtp @@ -45,7 +45,7 @@ def make( email_template=None, communication_type=None, **kwargs, -) -> Dict[str, str]: +) -> dict[str, str]: """Make a new communication. Checks for email permissions for specified Document. :param doctype: Reference DocType. @@ -122,7 +122,7 @@ def _make( email_template=None, communication_type=None, add_signature=True, -) -> Dict[str, str]: +) -> dict[str, str]: """Internal method to make a new communication that ignores Permission checks.""" sender = sender or get_formatted_email(frappe.session.user) diff --git a/frappe/core/doctype/communication/mixins.py b/frappe/core/doctype/communication/mixins.py index 0263cfeac5..695b8bebae 100644 --- a/frappe/core/doctype/communication/mixins.py +++ b/frappe/core/doctype/communication/mixins.py @@ -1,5 +1,3 @@ -from typing import List - import frappe from frappe import _ from frappe.core.utils import get_parent_doc @@ -201,7 +199,7 @@ class CommunicationEmailMixin: return _("Leave this conversation") return "" - def exclude_emails_list(self, is_inbound_mail_communcation=False, include_sender=False) -> List: + def exclude_emails_list(self, is_inbound_mail_communcation=False, include_sender=False) -> list: """List of mail id's excluded while sending mail.""" all_ids = self.get_all_email_addresses(exclude_displayname=True) diff --git a/frappe/core/doctype/communication/test_communication.py b/frappe/core/doctype/communication/test_communication.py index a338295374..77f83b7f91 100644 --- a/frappe/core/doctype/communication/test_communication.py +++ b/frappe/core/doctype/communication/test_communication.py @@ -236,7 +236,7 @@ class TestCommunication(unittest.TestCase): "communication_medium": "Email", "subject": "Document Link in Email", "sender": "comm_sender@example.com", - "recipients": "comm_recipient+{0}+{1}@example.com".format(quote("Note"), quote(note.name)), + "recipients": "comm_recipient+{}+{}@example.com".format(quote("Note"), quote(note.name)), } ).insert(ignore_permissions=True) diff --git a/frappe/core/doctype/communication_link/communication_link.py b/frappe/core/doctype/communication_link/communication_link.py index 21b6a7828a..07633ad174 100644 --- a/frappe/core/doctype/communication_link/communication_link.py +++ b/frappe/core/doctype/communication_link/communication_link.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/core/doctype/custom_docperm/custom_docperm.py b/frappe/core/doctype/custom_docperm/custom_docperm.py index 23815e9bf6..e24c765df4 100644 --- a/frappe/core/doctype/custom_docperm/custom_docperm.py +++ b/frappe/core/doctype/custom_docperm/custom_docperm.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/core/doctype/custom_docperm/test_custom_docperm.py b/frappe/core/doctype/custom_docperm/test_custom_docperm.py index 51923718b6..4aa04f0223 100644 --- a/frappe/core/doctype/custom_docperm/test_custom_docperm.py +++ b/frappe/core/doctype/custom_docperm/test_custom_docperm.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies and Contributors # License: MIT. See LICENSE import unittest diff --git a/frappe/core/doctype/custom_role/custom_role.py b/frappe/core/doctype/custom_role/custom_role.py index dd215dea17..4d96def662 100644 --- a/frappe/core/doctype/custom_role/custom_role.py +++ b/frappe/core/doctype/custom_role/custom_role.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/core/doctype/custom_role/test_custom_role.py b/frappe/core/doctype/custom_role/test_custom_role.py index 9c12bddd26..79c66255c0 100644 --- a/frappe/core/doctype/custom_role/test_custom_role.py +++ b/frappe/core/doctype/custom_role/test_custom_role.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies and Contributors # License: MIT. See LICENSE import unittest diff --git a/frappe/core/doctype/data_export/data_export.py b/frappe/core/doctype/data_export/data_export.py index 268182fbd4..b27966aa3d 100644 --- a/frappe/core/doctype/data_export/data_export.py +++ b/frappe/core/doctype/data_export/data_export.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors # License: MIT. See LICENSE diff --git a/frappe/core/doctype/data_export/exporter.py b/frappe/core/doctype/data_export/exporter.py index 514be16694..b7f69ab43d 100644 --- a/frappe/core/doctype/data_export/exporter.py +++ b/frappe/core/doctype/data_export/exporter.py @@ -331,7 +331,7 @@ class DataExporter: order_by = None table_columns = frappe.db.get_table_columns(self.parent_doctype) if "lft" in table_columns and "rgt" in table_columns: - order_by = "`tab{doctype}`.`lft` asc".format(doctype=self.parent_doctype) + order_by = f"`tab{self.parent_doctype}`.`lft` asc" # get permitted data only self.data = frappe.get_list( self.doctype, fields=["*"], filters=self.filters, limit_page_length=None, order_by=order_by diff --git a/frappe/core/doctype/data_export/test_data_exporter.py b/frappe/core/doctype/data_export/test_data_exporter.py index 7b7dfc0069..812f65aaad 100644 --- a/frappe/core/doctype/data_export/test_data_exporter.py +++ b/frappe/core/doctype/data_export/test_data_exporter.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and Contributors # License: MIT. See LICENSE import unittest diff --git a/frappe/core/doctype/data_import/data_import.py b/frappe/core/doctype/data_import/data_import.py index 06282e5831..5ad603e416 100644 --- a/frappe/core/doctype/data_import/data_import.py +++ b/frappe/core/doctype/data_import/data_import.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/core/doctype/data_import/exporter.py b/frappe/core/doctype/data_import/exporter.py index b647bdcb62..8c73391bd0 100644 --- a/frappe/core/doctype/data_import/exporter.py +++ b/frappe/core/doctype/data_import/exporter.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and Contributors # License: MIT. See LICENSE @@ -132,8 +131,7 @@ class Exporter: child_doctype = table_df.options rows = self.add_data_row(child_doctype, child_row.parentfield, child_row, rows, i) - for row in rows: - yield row + yield from rows def add_data_row(self, doctype, parentfield, doc, rows, row_idx): if len(rows) < row_idx + 1: @@ -156,14 +154,14 @@ class Exporter: def get_data_as_docs(self): def format_column_name(df): - return "`tab{0}`.`{1}`".format(df.parent, df.fieldname) + return f"`tab{df.parent}`.`{df.fieldname}`" filters = self.export_filters if self.meta.is_nested_set(): - order_by = "`tab{0}`.`lft` ASC".format(self.doctype) + order_by = f"`tab{self.doctype}`.`lft` ASC" else: - order_by = "`tab{0}`.`creation` DESC".format(self.doctype) + order_by = f"`tab{self.doctype}`.`creation` DESC" parent_fields = [format_column_name(df) for df in self.fields if df.parent == self.doctype] parent_data = frappe.db.get_list( @@ -183,7 +181,7 @@ class Exporter: child_table_df = self.meta.get_field(key) child_table_doctype = child_table_df.options child_fields = ["name", "idx", "parent", "parentfield"] + list( - set([format_column_name(df) for df in self.fields if df.parent == child_table_doctype]) + {format_column_name(df) for df in self.fields if df.parent == child_table_doctype} ) data = frappe.db.get_all( child_table_doctype, @@ -211,16 +209,16 @@ class Exporter: if is_parent: label = _(df.label) else: - label = "{0} ({1})".format(_(df.label), _(df.child_table_df.label)) + label = f"{_(df.label)} ({_(df.child_table_df.label)})" if label in header: # this label is already in the header, # which means two fields with the same label # add the fieldname to avoid clash if is_parent: - label = "{0}".format(df.fieldname) + label = f"{df.fieldname}" else: - label = "{0}.{1}".format(df.child_table_df.fieldname, df.fieldname) + label = f"{df.child_table_df.fieldname}.{df.fieldname}" header.append(label) @@ -253,5 +251,5 @@ class Exporter: def build_xlsx_response(self): build_xlsx_response(self.get_csv_array_for_export(), _(self.doctype)) - def group_children_data_by_parent(self, children_data: typing.Dict[str, list]): + def group_children_data_by_parent(self, children_data: dict[str, list]): return groupby_metric(children_data, key="parent") diff --git a/frappe/core/doctype/data_import/importer.py b/frappe/core/doctype/data_import/importer.py index 06d7588aef..9e741ab590 100644 --- a/frappe/core/doctype/data_import/importer.py +++ b/frappe/core/doctype/data_import/importer.py @@ -150,7 +150,7 @@ class Importer: if self.console: update_progress_bar( - "Importing {0} records".format(total_payload_count), + f"Importing {total_payload_count} records", current_index, total_payload_count, ) @@ -342,7 +342,7 @@ class Importer: row_number = json.loads(log.get("row_indexes"))[0] status = "Success" if log.get("success") else "Failure" message = ( - "Successfully Imported {0}".format(log.get("docname")) + "Successfully Imported {}".format(log.get("docname")) if log.get("success") else log.get("messages") ) @@ -357,19 +357,17 @@ class Importer: if successful_records: print() - print( - "Successfully imported {0} records out of {1}".format(len(successful_records), len(import_log)) - ) + print(f"Successfully imported {len(successful_records)} records out of {len(import_log)}") if failed_records: - print("Failed to import {0} records".format(len(failed_records))) - file_name = "{0}_import_on_{1}.txt".format(self.doctype, frappe.utils.now()) - print("Check {0} for errors".format(os.path.join("sites", file_name))) + print(f"Failed to import {len(failed_records)} records") + file_name = f"{self.doctype}_import_on_{frappe.utils.now()}.txt" + print("Check {} for errors".format(os.path.join("sites", file_name))) text = "" for w in failed_records: - text += "Row Indexes: {0}\n".format(str(w.get("row_indexes", []))) - text += "Messages:\n{0}\n".format("\n".join(w.get("messages", []))) - text += "Traceback:\n{0}\n\n".format(w.get("exception")) + text += "Row Indexes: {}\n".format(str(w.get("row_indexes", []))) + text += "Messages:\n{}\n".format("\n".join(w.get("messages", []))) + text += "Traceback:\n{}\n\n".format(w.get("exception")) with open(file_name, "w") as f: f.write(text) @@ -384,7 +382,7 @@ class Importer: other_warnings.append(w) for row_number, warnings in warnings_by_row.items(): - print("Row {0}".format(row_number)) + print(f"Row {row_number}") for w in warnings: print(w.get("message")) @@ -578,7 +576,7 @@ class ImportFile: extn = os.path.splitext(file_path)[1][1:] file_content = None - with io.open(file_path, mode="rb") as f: + with open(file_path, mode="rb") as f: file_content = f.read() return file_content, extn @@ -991,9 +989,7 @@ class Column: self.warnings.append( { "col": self.column_number, - "message": ( - "The following values do not exist for {}: {}".format(self.df.options, missing_values) - ), + "message": (f"The following values do not exist for {self.df.options}: {missing_values}"), "type": "warning", } ) @@ -1023,8 +1019,8 @@ class Column: { "col": self.column_number, "message": ( - "The following values are invalid: {0}. Values must be" - " one of {1}".format(invalid_values, valid_values) + "The following values are invalid: {}. Values must be" + " one of {}".format(invalid_values, valid_values) ), } ) @@ -1110,9 +1106,9 @@ def build_fields_dict_for_column_matching(parent_doctype): ) else: name_headers = ( - "{0}.name".format(table_df.fieldname), # fieldname - "ID ({0})".format(table_df.label), # label - "{0} ({1})".format(_("ID"), translated_table_label), # translated label + f"{table_df.fieldname}.name", # fieldname + f"ID ({table_df.label})", # label + "{} ({})".format(_("ID"), translated_table_label), # translated label ) name_df.is_child_table_field = True @@ -1164,11 +1160,11 @@ def build_fields_dict_for_column_matching(parent_doctype): for header in ( # fieldname - "{0}.{1}".format(table_df.fieldname, df.fieldname), + f"{table_df.fieldname}.{df.fieldname}", # label - "{0} ({1})".format(label, table_df.label), + f"{label} ({table_df.label})", # translated label - "{0} ({1})".format(translated_label, translated_table_label), + f"{translated_label} ({translated_table_label})", ): out[header] = new_df @@ -1177,8 +1173,8 @@ def build_fields_dict_for_column_matching(parent_doctype): autoname_field = get_autoname_field(parent_doctype) if autoname_field: for header in ( - "ID ({})".format(autoname_field.label), # label - "{0} ({1})".format(_("ID"), _(autoname_field.label)), # translated label + f"ID ({autoname_field.label})", # label + "{} ({})".format(_("ID"), _(autoname_field.label)), # translated label # ID field should also map to the autoname field "ID", _("ID"), diff --git a/frappe/core/doctype/data_import/test_data_import.py b/frappe/core/doctype/data_import/test_data_import.py index fb15b3ad52..253882383c 100644 --- a/frappe/core/doctype/data_import/test_data_import.py +++ b/frappe/core/doctype/data_import/test_data_import.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2020, Frappe Technologies and Contributors # License: MIT. See LICENSE # import frappe diff --git a/frappe/core/doctype/data_import/test_exporter.py b/frappe/core/doctype/data_import/test_exporter.py index ed01a2648c..ceeac90e36 100644 --- a/frappe/core/doctype/data_import/test_exporter.py +++ b/frappe/core/doctype/data_import/test_exporter.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and Contributors # License: MIT. See LICENSE import unittest diff --git a/frappe/core/doctype/data_import/test_importer.py b/frappe/core/doctype/data_import/test_importer.py index 46b3c352ca..2c250a4e87 100644 --- a/frappe/core/doctype/data_import/test_importer.py +++ b/frappe/core/doctype/data_import/test_importer.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and Contributors # License: MIT. See LICENSE import unittest diff --git a/frappe/core/doctype/deleted_document/deleted_document.py b/frappe/core/doctype/deleted_document/deleted_document.py index f2c98a41b8..14b9bb5c11 100644 --- a/frappe/core/doctype/deleted_document/deleted_document.py +++ b/frappe/core/doctype/deleted_document/deleted_document.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/core/doctype/deleted_document/test_deleted_document.py b/frappe/core/doctype/deleted_document/test_deleted_document.py index 8985298498..f696689664 100644 --- a/frappe/core/doctype/deleted_document/test_deleted_document.py +++ b/frappe/core/doctype/deleted_document/test_deleted_document.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies and Contributors # License: MIT. See LICENSE import unittest diff --git a/frappe/core/doctype/doctype/doctype.py b/frappe/core/doctype/doctype/doctype.py index a965d9c1b2..40890e2a31 100644 --- a/frappe/core/doctype/doctype/doctype.py +++ b/frappe/core/doctype/doctype/doctype.py @@ -248,7 +248,7 @@ class DocType(Document): self.flags.update_fields_to_fetch_queries = [] - if set(old_fields_to_fetch) != set(df.fieldname for df in new_meta.get_fields_to_fetch()): + if set(old_fields_to_fetch) != {df.fieldname for df in new_meta.get_fields_to_fetch()}: for df in new_meta.get_fields_to_fetch(): if df.fieldname not in old_fields_to_fetch: link_fieldname, source_fieldname = df.fetch_from.split(".", 1) @@ -385,7 +385,7 @@ class DocType(Document): try: frappe.db.updatedb(self.name, Meta(self)) except Exception as e: - print("\n\nThere was an issue while migrating the DocType: {}\n".format(self.name)) + print(f"\n\nThere was an issue while migrating the DocType: {self.name}\n") raise e self.change_modified_of_parent() @@ -552,7 +552,7 @@ class DocType(Document): for fname in ("{}.js", "{}.py", "{}_list.js", "{}_calendar.js", "test_{}.py", "test_{}.js"): fname = os.path.join(new_path, fname.format(frappe.scrub(new))) if os.path.exists(fname): - with open(fname, "r") as f: + with open(fname) as f: code = f.read() with open(fname, "w") as f: if fname.endswith(".js"): @@ -569,7 +569,7 @@ class DocType(Document): f.write(file_content) # updating json file with new name - doctype_json_path = os.path.join(new_path, "{}.json".format(frappe.scrub(new))) + doctype_json_path = os.path.join(new_path, f"{frappe.scrub(new)}.json") current_data = frappe.get_file_json(doctype_json_path) current_data["name"] = new @@ -643,7 +643,7 @@ class DocType(Document): path = get_file_path(self.module, "DocType", self.name) if os.path.exists(path): try: - with open(path, "r") as txtfile: + with open(path) as txtfile: olddoc = json.loads(txtfile.read()) old_field_names = [f["fieldname"] for f in olddoc.get("fields", [])] @@ -804,7 +804,7 @@ class DocType(Document): {"label": "Old Parent", "fieldtype": "Link", "options": self.name, "fieldname": "old_parent"}, ) - parent_field_label = "Parent {}".format(self.name) + parent_field_label = f"Parent {self.name}" parent_field_name = frappe.scrub(parent_field_label) self.append( "fields", @@ -1417,7 +1417,7 @@ def validate_fields(meta): def check_max_height(docfield): if getattr(docfield, "max_height", None) and (docfield.max_height[-2:] not in ("px", "em")): - frappe.throw("Max for {} height must be in px, em, rem".format(frappe.bold(docfield.fieldname))) + frappe.throw(f"Max for {frappe.bold(docfield.fieldname)} height must be in px, em, rem") def check_no_of_ratings(docfield): if docfield.fieldtype == "Rating": diff --git a/frappe/core/doctype/doctype/test_doctype.py b/frappe/core/doctype/doctype/test_doctype.py index 5b0b575201..3a5ca4329f 100644 --- a/frappe/core/doctype/doctype/test_doctype.py +++ b/frappe/core/doctype/doctype/test_doctype.py @@ -1,10 +1,8 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors # License: MIT. See LICENSE import random import string import unittest -from typing import Dict, List, Optional from unittest.mock import patch import frappe @@ -187,7 +185,7 @@ class TestDocType(unittest.TestCase): "module": "Core", "custom": 1, "fields": [ - {"fieldname": "{0}_field".format(field_option), "fieldtype": "Data", "options": field_option} + {"fieldname": f"{field_option}_field", "fieldtype": "Data", "options": field_option} ], } ) @@ -711,10 +709,10 @@ class TestDocType(unittest.TestCase): def new_doctype( - name: Optional[str] = None, + name: str | None = None, unique: bool = False, depends_on: str = "", - fields: Optional[List[Dict]] = None, + fields: list[dict] | None = None, **kwargs, ): if not name: diff --git a/frappe/core/doctype/doctype_action/doctype_action.py b/frappe/core/doctype/doctype_action/doctype_action.py index 49cb21f99f..1c5be9ae01 100644 --- a/frappe/core/doctype/doctype_action/doctype_action.py +++ b/frappe/core/doctype/doctype_action/doctype_action.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/core/doctype/doctype_link/doctype_link.py b/frappe/core/doctype/doctype_link/doctype_link.py index f534cd1780..0658b1fb28 100644 --- a/frappe/core/doctype/doctype_link/doctype_link.py +++ b/frappe/core/doctype/doctype_link/doctype_link.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/core/doctype/document_naming_rule/document_naming_rule.py b/frappe/core/doctype/document_naming_rule/document_naming_rule.py index 41aa3d7aff..3fecf26ade 100644 --- a/frappe/core/doctype/document_naming_rule/document_naming_rule.py +++ b/frappe/core/doctype/document_naming_rule/document_naming_rule.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2020, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/core/doctype/document_naming_rule/test_document_naming_rule.py b/frappe/core/doctype/document_naming_rule/test_document_naming_rule.py index 459b17da8b..cc406ed5cd 100644 --- a/frappe/core/doctype/document_naming_rule/test_document_naming_rule.py +++ b/frappe/core/doctype/document_naming_rule/test_document_naming_rule.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2020, Frappe Technologies and Contributors # License: MIT. See LICENSE import unittest diff --git a/frappe/core/doctype/document_naming_rule_condition/document_naming_rule_condition.py b/frappe/core/doctype/document_naming_rule_condition/document_naming_rule_condition.py index dc45798c34..7ecc0162a5 100644 --- a/frappe/core/doctype/document_naming_rule_condition/document_naming_rule_condition.py +++ b/frappe/core/doctype/document_naming_rule_condition/document_naming_rule_condition.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2020, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/core/doctype/document_naming_rule_condition/test_document_naming_rule_condition.py b/frappe/core/doctype/document_naming_rule_condition/test_document_naming_rule_condition.py index d88335758a..68f0677f2c 100644 --- a/frappe/core/doctype/document_naming_rule_condition/test_document_naming_rule_condition.py +++ b/frappe/core/doctype/document_naming_rule_condition/test_document_naming_rule_condition.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2020, Frappe Technologies and Contributors # License: MIT. See LICENSE # import frappe diff --git a/frappe/core/doctype/document_naming_settings/document_naming_settings.py b/frappe/core/doctype/document_naming_settings/document_naming_settings.py index 46def88b65..5680b6c823 100644 --- a/frappe/core/doctype/document_naming_settings/document_naming_settings.py +++ b/frappe/core/doctype/document_naming_settings/document_naming_settings.py @@ -1,7 +1,6 @@ # Copyright (c) 2022, Frappe Technologies and contributors # For license information, please see license.txt -from typing import List, Set import frappe from frappe import _ @@ -25,7 +24,7 @@ class DocumentNamingSettings(Document): return {"transactions": transactions, "prefixes": prefixes} - def _get_transactions(self) -> List[str]: + def _get_transactions(self) -> list[str]: readable_doctypes = set(get_doctypes_with_read()) @@ -34,7 +33,7 @@ class DocumentNamingSettings(Document): return sorted(readable_doctypes.intersection(standard + custom)) - def _get_prefixes(self, doctypes) -> List[str]: + def _get_prefixes(self, doctypes) -> list[str]: """Get all prefixes for naming series. - For all templates prefix is evaluated considering today's date @@ -63,7 +62,7 @@ class DocumentNamingSettings(Document): return self._evaluate_and_clean_templates(series_templates) - def _evaluate_and_clean_templates(self, series_templates: Set[str]) -> List[str]: + def _evaluate_and_clean_templates(self, series_templates: set[str]) -> list[str]: evalauted_prefix = set() series = frappe.qb.DocType("Series") @@ -79,7 +78,7 @@ class DocumentNamingSettings(Document): return sorted(evalauted_prefix) - def get_options_list(self, options: str) -> List[str]: + def get_options_list(self, options: str) -> list[str]: return [op.strip() for op in options.split("\n") if op.strip()] @frappe.whitelist() diff --git a/frappe/core/doctype/domain/domain.py b/frappe/core/doctype/domain/domain.py index 897f7ee655..e0b0e80982 100644 --- a/frappe/core/doctype/domain/domain.py +++ b/frappe/core/doctype/domain/domain.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2017, Frappe Technologies and contributors # License: MIT. See LICENSE @@ -113,8 +112,8 @@ class Domain(Document): # enable frappe.db.sql( """update `tabPortal Menu Item` set enabled=1 - where route in ({0})""".format( - ", ".join('"{0}"'.format(d) for d in self.data.allow_sidebar_items) + where route in ({})""".format( + ", ".join(f'"{d}"' for d in self.data.allow_sidebar_items) ) ) @@ -125,7 +124,7 @@ class Domain(Document): # enable frappe.db.sql( """update `tabPortal Menu Item` set enabled=0 - where route in ({0})""".format( - ", ".join('"{0}"'.format(d) for d in self.data.remove_sidebar_items) + where route in ({})""".format( + ", ".join(f'"{d}"' for d in self.data.remove_sidebar_items) ) ) diff --git a/frappe/core/doctype/domain/test_domain.py b/frappe/core/doctype/domain/test_domain.py index 623d80a280..32592705b4 100644 --- a/frappe/core/doctype/domain/test_domain.py +++ b/frappe/core/doctype/domain/test_domain.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2017, Frappe Technologies and Contributors # License: MIT. See LICENSE import unittest diff --git a/frappe/core/doctype/domain_settings/domain_settings.py b/frappe/core/doctype/domain_settings/domain_settings.py index ba7f397c51..85b26f53dd 100644 --- a/frappe/core/doctype/domain_settings/domain_settings.py +++ b/frappe/core/doctype/domain_settings/domain_settings.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2017, Frappe Technologies and contributors # License: MIT. See LICENSE @@ -32,7 +31,7 @@ class DomainSettings(Document): def restrict_roles_and_modules(self): """Disable all restricted roles and set `restrict_to_domain` property in Module Def""" active_domains = frappe.get_active_domains() - all_domains = list((frappe.get_hooks("domains") or {})) + all_domains = list(frappe.get_hooks("domains") or {}) def remove_role(role): frappe.db.delete("Has Role", {"role": role}) diff --git a/frappe/core/doctype/dynamic_link/dynamic_link.py b/frappe/core/doctype/dynamic_link/dynamic_link.py index e253147167..53eb750b5c 100644 --- a/frappe/core/doctype/dynamic_link/dynamic_link.py +++ b/frappe/core/doctype/dynamic_link/dynamic_link.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/core/doctype/error_log/error_log.py b/frappe/core/doctype/error_log/error_log.py index 224a5673a7..c7ab98e034 100644 --- a/frappe/core/doctype/error_log/error_log.py +++ b/frappe/core/doctype/error_log/error_log.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/core/doctype/error_log/test_error_log.py b/frappe/core/doctype/error_log/test_error_log.py index a8511b238e..c7cf26a0cf 100644 --- a/frappe/core/doctype/error_log/test_error_log.py +++ b/frappe/core/doctype/error_log/test_error_log.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies and Contributors # License: MIT. See LICENSE import unittest diff --git a/frappe/core/doctype/error_snapshot/error_snapshot.py b/frappe/core/doctype/error_snapshot/error_snapshot.py index 6e13b7a654..6966cf0aca 100644 --- a/frappe/core/doctype/error_snapshot/error_snapshot.py +++ b/frappe/core/doctype/error_snapshot/error_snapshot.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors # License: MIT. See LICENSE diff --git a/frappe/core/doctype/error_snapshot/test_error_snapshot.py b/frappe/core/doctype/error_snapshot/test_error_snapshot.py index 121fe8a6f9..0c1f861b43 100644 --- a/frappe/core/doctype/error_snapshot/test_error_snapshot.py +++ b/frappe/core/doctype/error_snapshot/test_error_snapshot.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors # License: MIT. See LICENSE import unittest diff --git a/frappe/core/doctype/file/file.py b/frappe/core/doctype/file/file.py index bb4b441680..7a66d45c73 100755 --- a/frappe/core/doctype/file/file.py +++ b/frappe/core/doctype/file/file.py @@ -7,7 +7,6 @@ import os import re import shutil import zipfile -from typing import List, Optional, Union from urllib.parse import quote, unquote from PIL import Image, ImageFile, ImageOps @@ -134,7 +133,7 @@ class File(Document): shutil.move(source, target) self.flags.pop("original_path") - def get_name_based_on_parent_folder(self) -> Union[str, None]: + def get_name_based_on_parent_folder(self) -> str | None: if self.folder: return os.path.join(self.folder, self.file_name) @@ -328,7 +327,7 @@ class File(Document): file_path = get_files_path(file_name, is_private=self.is_private) with open(file_path, "rb") as f: self.content_hash = get_content_hash(f.read()) - except IOError: + except OSError: frappe.throw(_("File {0} does not exist").format(file_path)) def make_thumbnail( @@ -347,7 +346,7 @@ class File(Document): image, filename, extn = get_local_image(self.file_url) else: image, filename, extn = get_web_image(self.file_url) - except (HTTPError, SSLError, IOError, TypeError): + except (HTTPError, SSLError, OSError, TypeError): return size = width, height @@ -364,7 +363,7 @@ class File(Document): if set_as_thumbnail: self.db_set("thumbnail_url", thumbnail_url) - except IOError: + except OSError: frappe.msgprint(_("Unable to write file format for {0}").format(path)) return @@ -387,7 +386,7 @@ class File(Document): else: self.delete_file_data_content(only_thumbnail=True) - def unzip(self) -> List["File"]: + def unzip(self) -> list["File"]: """Unzip current file and replace it by its children""" if not self.file_url.endswith(".zip"): frappe.throw(_("{0} is not a zip file").format(self.file_name)) @@ -506,7 +505,7 @@ class File(Document): def save_file( self, - content: Optional[Union[bytes, str]] = None, + content: bytes | str | None = None, decode=False, ignore_existing_file_check=False, overwrite=False, diff --git a/frappe/core/doctype/file/utils.py b/frappe/core/doctype/file/utils.py index 632324c9cf..e59ec2aede 100644 --- a/frappe/core/doctype/file/utils.py +++ b/frappe/core/doctype/file/utils.py @@ -4,7 +4,7 @@ import mimetypes import os import re from io import BytesIO -from typing import TYPE_CHECKING, Optional, Tuple, Union +from typing import TYPE_CHECKING, Optional from urllib.parse import unquote import requests @@ -55,8 +55,8 @@ def setup_folder_path(filename: str, new_parent: str) -> None: def get_extension( filename, - extn: Optional[str] = None, - content: Optional[bytes] = None, + extn: str | None = None, + content: bytes | None = None, response: Optional["Response"] = None, ) -> str: mimetype = None @@ -83,7 +83,7 @@ def get_extension( return extn -def get_local_image(file_url: str) -> Tuple["ImageFile", str, str]: +def get_local_image(file_url: str) -> tuple["ImageFile", str, str]: if file_url.startswith("/private"): file_url_path = (file_url.lstrip("/"),) else: @@ -93,7 +93,7 @@ def get_local_image(file_url: str) -> Tuple["ImageFile", str, str]: try: image = Image.open(file_path) - except IOError: + except OSError: frappe.throw(_("Unable to read file format for {0}").format(file_url)) content = None @@ -102,7 +102,7 @@ def get_local_image(file_url: str) -> Tuple["ImageFile", str, str]: filename, extn = file_url.rsplit(".", 1) except ValueError: # no extn - with open(file_path, "r") as f: + with open(file_path) as f: content = f.read() filename = file_url @@ -113,7 +113,7 @@ def get_local_image(file_url: str) -> Tuple["ImageFile", str, str]: return image, filename, extn -def get_web_image(file_url: str) -> Tuple["ImageFile", str, str]: +def get_web_image(file_url: str) -> tuple["ImageFile", str, str]: # download file_url = frappe.utils.get_url(file_url) r = requests.get(file_url, stream=True) @@ -179,13 +179,13 @@ def remove_file_by_url(file_url: str, doctype: str = None, name: str = None) -> return remove_file(fid=fid) -def get_content_hash(content: Union[bytes, str]) -> str: +def get_content_hash(content: bytes | str) -> str: if isinstance(content, str): content = content.encode() return hashlib.md5(content).hexdigest() # nosec -def generate_file_name(name: str, suffix: Optional[str] = None, is_private: bool = False) -> str: +def generate_file_name(name: str, suffix: str | None = None, is_private: bool = False) -> str: """Generate conflict-free file name. Suffix will be ignored if name available. If the provided suffix doesn't result in an available path, a random suffix will be picked. """ @@ -203,7 +203,7 @@ def generate_file_name(name: str, suffix: Optional[str] = None, is_private: bool return candidate_path -def get_file_name(fname: str, optional_suffix: Optional[str] = None) -> str: +def get_file_name(fname: str, optional_suffix: str | None = None) -> str: # convert to unicode fname = cstr(fname) partial, extn = os.path.splitext(fname) diff --git a/frappe/core/doctype/has_domain/has_domain.py b/frappe/core/doctype/has_domain/has_domain.py index 8ef69ef0c4..0d8257fc33 100644 --- a/frappe/core/doctype/has_domain/has_domain.py +++ b/frappe/core/doctype/has_domain/has_domain.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2017, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/core/doctype/has_role/has_role.py b/frappe/core/doctype/has_role/has_role.py index 83cf90aac6..8798adf031 100644 --- a/frappe/core/doctype/has_role/has_role.py +++ b/frappe/core/doctype/has_role/has_role.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/core/doctype/installed_application/installed_application.py b/frappe/core/doctype/installed_application/installed_application.py index 07b6c105af..0a1dab8f2e 100644 --- a/frappe/core/doctype/installed_application/installed_application.py +++ b/frappe/core/doctype/installed_application/installed_application.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2020, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/core/doctype/installed_applications/installed_applications.py b/frappe/core/doctype/installed_applications/installed_applications.py index d13118e169..07b20db153 100644 --- a/frappe/core/doctype/installed_applications/installed_applications.py +++ b/frappe/core/doctype/installed_applications/installed_applications.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2020, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/core/doctype/installed_applications/test_installed_applications.py b/frappe/core/doctype/installed_applications/test_installed_applications.py index 24d3a9a49a..b67cc4c8c7 100644 --- a/frappe/core/doctype/installed_applications/test_installed_applications.py +++ b/frappe/core/doctype/installed_applications/test_installed_applications.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2020, Frappe Technologies and Contributors # License: MIT. See LICENSE # import frappe diff --git a/frappe/core/doctype/language/language.py b/frappe/core/doctype/language/language.py index 948810eb39..efac7b0d77 100644 --- a/frappe/core/doctype/language/language.py +++ b/frappe/core/doctype/language/language.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies and contributors # License: MIT. See LICENSE @@ -42,7 +41,7 @@ def export_languages_json(): def sync_languages(): """Sync frappe/geo/languages.json with Language""" - with open(frappe.get_app_path("frappe", "geo", "languages.json"), "r") as f: + with open(frappe.get_app_path("frappe", "geo", "languages.json")) as f: data = json.loads(f.read()) for l in data: @@ -59,7 +58,7 @@ def sync_languages(): def update_language_names(): """Update frappe/geo/languages.json names (for use via patch)""" - with open(frappe.get_app_path("frappe", "geo", "languages.json"), "r") as f: + with open(frappe.get_app_path("frappe", "geo", "languages.json")) as f: data = json.loads(f.read()) for l in data: diff --git a/frappe/core/doctype/language/test_language.py b/frappe/core/doctype/language/test_language.py index 305515c191..1f9c96a5d8 100644 --- a/frappe/core/doctype/language/test_language.py +++ b/frappe/core/doctype/language/test_language.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies and Contributors # License: MIT. See LICENSE import unittest diff --git a/frappe/core/doctype/log_setting_user/log_setting_user.py b/frappe/core/doctype/log_setting_user/log_setting_user.py index cf66da31b1..830d29e3be 100644 --- a/frappe/core/doctype/log_setting_user/log_setting_user.py +++ b/frappe/core/doctype/log_setting_user/log_setting_user.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2020, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/core/doctype/log_setting_user/test_log_setting_user.py b/frappe/core/doctype/log_setting_user/test_log_setting_user.py index dc70677079..9ea56e8ec4 100644 --- a/frappe/core/doctype/log_setting_user/test_log_setting_user.py +++ b/frappe/core/doctype/log_setting_user/test_log_setting_user.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2020, Frappe Technologies and Contributors # License: MIT. See LICENSE # import frappe diff --git a/frappe/core/doctype/log_settings/log_settings.py b/frappe/core/doctype/log_settings/log_settings.py index 1a7ce532cd..8009324e70 100644 --- a/frappe/core/doctype/log_settings/log_settings.py +++ b/frappe/core/doctype/log_settings/log_settings.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2020, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/core/doctype/module_def/module_def.py b/frappe/core/doctype/module_def/module_def.py index 8f80ffd4ee..c9dac11b69 100644 --- a/frappe/core/doctype/module_def/module_def.py +++ b/frappe/core/doctype/module_def/module_def.py @@ -29,7 +29,7 @@ class ModuleDef(Document): """Adds to `[app]/modules.txt`""" modules = None if not frappe.local.module_app.get(frappe.scrub(self.name)): - with open(frappe.get_app_path(self.app_name, "modules.txt"), "r") as f: + with open(frappe.get_app_path(self.app_name, "modules.txt")) as f: content = f.read() if not self.name in content.splitlines(): modules = list(filter(None, content.splitlines())) @@ -50,7 +50,7 @@ class ModuleDef(Document): modules = None if frappe.local.module_app.get(frappe.scrub(self.name)): - with open(frappe.get_app_path(self.app_name, "modules.txt"), "r") as f: + with open(frappe.get_app_path(self.app_name, "modules.txt")) as f: content = f.read() if self.name in content.splitlines(): modules = list(filter(None, content.splitlines())) diff --git a/frappe/core/doctype/module_def/test_module_def.py b/frappe/core/doctype/module_def/test_module_def.py index 3a6da6d854..914ba07949 100644 --- a/frappe/core/doctype/module_def/test_module_def.py +++ b/frappe/core/doctype/module_def/test_module_def.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors # License: MIT. See LICENSE import unittest diff --git a/frappe/core/doctype/module_profile/module_profile.py b/frappe/core/doctype/module_profile/module_profile.py index 7c5f896ba8..46c09827f3 100644 --- a/frappe/core/doctype/module_profile/module_profile.py +++ b/frappe/core/doctype/module_profile/module_profile.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2020, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/core/doctype/module_profile/test_module_profile.py b/frappe/core/doctype/module_profile/test_module_profile.py index e15a70d93f..099d1371fb 100644 --- a/frappe/core/doctype/module_profile/test_module_profile.py +++ b/frappe/core/doctype/module_profile/test_module_profile.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2020, Frappe Technologies and Contributors # License: MIT. See LICENSE import unittest diff --git a/frappe/core/doctype/navbar_item/navbar_item.py b/frappe/core/doctype/navbar_item/navbar_item.py index 27aa339c93..60be154e75 100644 --- a/frappe/core/doctype/navbar_item/navbar_item.py +++ b/frappe/core/doctype/navbar_item/navbar_item.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2020, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/core/doctype/navbar_item/test_navbar_item.py b/frappe/core/doctype/navbar_item/test_navbar_item.py index 913e84704b..7eeb4f642b 100644 --- a/frappe/core/doctype/navbar_item/test_navbar_item.py +++ b/frappe/core/doctype/navbar_item/test_navbar_item.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2020, Frappe Technologies and Contributors # License: MIT. See LICENSE # import frappe diff --git a/frappe/core/doctype/navbar_settings/navbar_settings.py b/frappe/core/doctype/navbar_settings/navbar_settings.py index 6243107d63..1eba0f8fa7 100644 --- a/frappe/core/doctype/navbar_settings/navbar_settings.py +++ b/frappe/core/doctype/navbar_settings/navbar_settings.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2020, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/core/doctype/navbar_settings/test_navbar_settings.py b/frappe/core/doctype/navbar_settings/test_navbar_settings.py index f63e361e8b..76fb3d298a 100644 --- a/frappe/core/doctype/navbar_settings/test_navbar_settings.py +++ b/frappe/core/doctype/navbar_settings/test_navbar_settings.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2020, Frappe Technologies and Contributors # License: MIT. See LICENSE # import frappe diff --git a/frappe/core/doctype/package/package.py b/frappe/core/doctype/package/package.py index a32f1bc534..c1cb482832 100644 --- a/frappe/core/doctype/package/package.py +++ b/frappe/core/doctype/package/package.py @@ -15,7 +15,5 @@ class Package(Document): @frappe.whitelist() def get_license_text(license_type): - with open( - os.path.join(os.path.dirname(__file__), "licenses", license_type + ".md"), "r" - ) as textfile: + with open(os.path.join(os.path.dirname(__file__), "licenses", license_type + ".md")) as textfile: return textfile.read() diff --git a/frappe/core/doctype/package_import/package_import.py b/frappe/core/doctype/package_import/package_import.py index 43a985af9b..19762eae4a 100644 --- a/frappe/core/doctype/package_import/package_import.py +++ b/frappe/core/doctype/package_import/package_import.py @@ -44,7 +44,7 @@ class PackageImport(Document): package_path = frappe.get_site_path("packages", package_name) # import Package - with open(os.path.join(package_path, package_name + ".json"), "r") as packagefile: + with open(os.path.join(package_path, package_name + ".json")) as packagefile: doc_dict = json.loads(packagefile.read()) frappe.flags.package = import_doc(doc_dict) @@ -60,6 +60,6 @@ class PackageImport(Document): # import files for file in files: import_file_by_path(file, force=self.force, ignore_version=True) - log.append("Imported {}".format(file)) + log.append(f"Imported {file}") self.log = "\n".join(log) diff --git a/frappe/core/doctype/package_release/package_release.py b/frappe/core/doctype/package_release/package_release.py index 05277dcf2e..58fdc2ab86 100644 --- a/frappe/core/doctype/package_release/package_release.py +++ b/frappe/core/doctype/package_release/package_release.py @@ -87,7 +87,7 @@ class PackageRelease(Document): def make_tarfile(self, package): # make tarfile - filename = "{}.tar.gz".format(self.name) + filename = f"{self.name}.tar.gz" subprocess.check_output( ["tar", "czf", filename, package.package_name], cwd=frappe.get_site_path("packages") ) diff --git a/frappe/core/doctype/page/page.py b/frappe/core/doctype/page/page.py index 7185a25e01..8210875b3a 100644 --- a/frappe/core/doctype/page/page.py +++ b/frappe/core/doctype/page/page.py @@ -79,7 +79,7 @@ class Page(Document): ) def as_dict(self, no_nulls=False): - d = super(Page, self).as_dict(no_nulls=no_nulls) + d = super().as_dict(no_nulls=no_nulls) for key in ("script", "style", "content"): d[key] = self.get(key) return d @@ -120,20 +120,20 @@ class Page(Document): # script fpath = os.path.join(path, page_name + ".js") if os.path.exists(fpath): - with open(fpath, "r") as f: + with open(fpath) as f: self.script = render_include(f.read()) self.script += f"\n\n//# sourceURL={page_name}.js" # css fpath = os.path.join(path, page_name + ".css") if os.path.exists(fpath): - with open(fpath, "r") as f: + with open(fpath) as f: self.style = safe_decode(f.read()) # html as js template for fname in os.listdir(path): if fname.endswith(".html"): - with open(os.path.join(path, fname), "r") as f: + with open(os.path.join(path, fname)) as f: template = f.read() if "" in template: context = frappe._dict({}) diff --git a/frappe/core/doctype/patch_log/test_patch_log.py b/frappe/core/doctype/patch_log/test_patch_log.py index 54cdc6416a..0c8a2ae4d4 100644 --- a/frappe/core/doctype/patch_log/test_patch_log.py +++ b/frappe/core/doctype/patch_log/test_patch_log.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors # License: MIT. See LICENSE import unittest diff --git a/frappe/core/doctype/payment_gateway/payment_gateway.py b/frappe/core/doctype/payment_gateway/payment_gateway.py index 7eb4c5481d..74306ae4ad 100644 --- a/frappe/core/doctype/payment_gateway/payment_gateway.py +++ b/frappe/core/doctype/payment_gateway/payment_gateway.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors # License: MIT. See LICENSE diff --git a/frappe/core/doctype/payment_gateway/test_payment_gateway.py b/frappe/core/doctype/payment_gateway/test_payment_gateway.py index 71766561b3..6900e79434 100644 --- a/frappe/core/doctype/payment_gateway/test_payment_gateway.py +++ b/frappe/core/doctype/payment_gateway/test_payment_gateway.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors # License: MIT. See LICENSE import unittest diff --git a/frappe/core/doctype/prepared_report/prepared_report.py b/frappe/core/doctype/prepared_report/prepared_report.py index e35ec43565..0ff4ce3070 100644 --- a/frappe/core/doctype/prepared_report/prepared_report.py +++ b/frappe/core/doctype/prepared_report/prepared_report.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2018, Frappe Technologies and contributors # License: MIT. See LICENSE @@ -103,7 +102,7 @@ def delete_prepared_reports(reports): def create_json_gz_file(data, dt, dn): # Storing data in CSV file causes information loss # Reports like P&L Statement were completely unsuable because of this - json_filename = "{0}.json.gz".format( + json_filename = "{}.json.gz".format( frappe.utils.data.format_datetime(frappe.utils.now(), "Y-m-d-H:M") ) encoded_content = frappe.safe_encode(frappe.as_json(data)) diff --git a/frappe/core/doctype/prepared_report/test_prepared_report.py b/frappe/core/doctype/prepared_report/test_prepared_report.py index 86793cb802..6d0c809a01 100644 --- a/frappe/core/doctype/prepared_report/test_prepared_report.py +++ b/frappe/core/doctype/prepared_report/test_prepared_report.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2018, Frappe Technologies and Contributors # License: MIT. See LICENSE import json diff --git a/frappe/core/doctype/report/report.py b/frappe/core/doctype/report/report.py index efb45f41c8..7fe3cadf9c 100644 --- a/frappe/core/doctype/report/report.py +++ b/frappe/core/doctype/report/report.py @@ -243,7 +243,7 @@ class Report(Document): @staticmethod def _format(parts): # sort by is saved as DocType.fieldname, covert it to sql - return "`tab{0}`.`{1}`".format(*parts) + return "`tab{}`.`{}`".format(*parts) def get_standard_report_columns(self, params): if params.get("fields"): @@ -365,9 +365,7 @@ def get_group_by_field(args, doctype): if args["aggregate_function"] == "count": group_by_field = "count(*) as _aggregate_column" else: - group_by_field = "{0}({1}) as _aggregate_column".format( - args.aggregate_function, args.aggregate_on - ) + group_by_field = f"{args.aggregate_function}({args.aggregate_on}) as _aggregate_column" return group_by_field diff --git a/frappe/core/doctype/report/test_report.py b/frappe/core/doctype/report/test_report.py index bbae616e93..0e1ed80eda 100644 --- a/frappe/core/doctype/report/test_report.py +++ b/frappe/core/doctype/report/test_report.py @@ -22,7 +22,7 @@ class TestReport(FrappeTestCase): if frappe.db.exists("Report", "User Activity Report"): frappe.delete_doc("Report", "User Activity Report") - with open(os.path.join(os.path.dirname(__file__), "user_activity_report.json"), "r") as f: + with open(os.path.join(os.path.dirname(__file__), "user_activity_report.json")) as f: frappe.get_doc(json.loads(f.read())).insert() report = frappe.get_doc("Report", "User Activity Report") @@ -223,7 +223,7 @@ class TestReport(FrappeTestCase): if frappe.db.exists("Report", "User Activity Report Without Sort"): frappe.delete_doc("Report", "User Activity Report Without Sort") with open( - os.path.join(os.path.dirname(__file__), "user_activity_report_without_sort.json"), "r" + os.path.join(os.path.dirname(__file__), "user_activity_report_without_sort.json") ) as f: frappe.get_doc(json.loads(f.read())).insert() diff --git a/frappe/core/doctype/report_column/report_column.py b/frappe/core/doctype/report_column/report_column.py index c0984a5ca8..0d6045d121 100644 --- a/frappe/core/doctype/report_column/report_column.py +++ b/frappe/core/doctype/report_column/report_column.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2020, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/core/doctype/report_filter/report_filter.py b/frappe/core/doctype/report_filter/report_filter.py index e35d7064d2..f3a9607e20 100644 --- a/frappe/core/doctype/report_filter/report_filter.py +++ b/frappe/core/doctype/report_filter/report_filter.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2020, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/core/doctype/role/role.py b/frappe/core/doctype/role/role.py index 2119f3caa1..97a0e9b581 100644 --- a/frappe/core/doctype/role/role.py +++ b/frappe/core/doctype/role/role.py @@ -99,7 +99,7 @@ def get_users(role): @frappe.whitelist() @frappe.validate_and_sanitize_search_inputs def role_query(doctype, txt, searchfield, start, page_len, filters): - report_filters = [["Role", "name", "like", "%{}%".format(txt)], ["Role", "is_custom", "=", 0]] + report_filters = [["Role", "name", "like", f"%{txt}%"], ["Role", "is_custom", "=", 0]] if filters and isinstance(filters, list): report_filters.extend(filters) diff --git a/frappe/core/doctype/role_permission_for_page_and_report/role_permission_for_page_and_report.py b/frappe/core/doctype/role_permission_for_page_and_report/role_permission_for_page_and_report.py index d89131b0d7..bd61995ba3 100644 --- a/frappe/core/doctype/role_permission_for_page_and_report/role_permission_for_page_and_report.py +++ b/frappe/core/doctype/role_permission_for_page_and_report/role_permission_for_page_and_report.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/core/doctype/role_profile/role_profile.py b/frappe/core/doctype/role_profile/role_profile.py index ab4660d7c9..a8abd6d1c1 100644 --- a/frappe/core/doctype/role_profile/role_profile.py +++ b/frappe/core/doctype/role_profile/role_profile.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2017, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/core/doctype/role_profile/test_role_profile.py b/frappe/core/doctype/role_profile/test_role_profile.py index 19239a81cd..726a5fc83e 100644 --- a/frappe/core/doctype/role_profile/test_role_profile.py +++ b/frappe/core/doctype/role_profile/test_role_profile.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2017, Frappe Technologies and Contributors # License: MIT. See LICENSE import unittest diff --git a/frappe/core/doctype/scheduled_job_log/scheduled_job_log.py b/frappe/core/doctype/scheduled_job_log/scheduled_job_log.py index 68541a36a0..01fa837af0 100644 --- a/frappe/core/doctype/scheduled_job_log/scheduled_job_log.py +++ b/frappe/core/doctype/scheduled_job_log/scheduled_job_log.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/core/doctype/scheduled_job_log/test_scheduled_job_log.py b/frappe/core/doctype/scheduled_job_log/test_scheduled_job_log.py index 3c99bb5cb8..11d60e35d8 100644 --- a/frappe/core/doctype/scheduled_job_log/test_scheduled_job_log.py +++ b/frappe/core/doctype/scheduled_job_log/test_scheduled_job_log.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and Contributors # License: MIT. See LICENSE # import frappe diff --git a/frappe/core/doctype/scheduled_job_type/scheduled_job_type.py b/frappe/core/doctype/scheduled_job_type/scheduled_job_type.py index 673805ae8b..f898311ca3 100644 --- a/frappe/core/doctype/scheduled_job_type/scheduled_job_type.py +++ b/frappe/core/doctype/scheduled_job_type/scheduled_job_type.py @@ -3,7 +3,6 @@ import json from datetime import datetime -from typing import Dict, List from croniter import croniter @@ -138,14 +137,14 @@ def run_scheduled_job(job_type: str): print(frappe.get_traceback()) -def sync_jobs(hooks: Dict = None): +def sync_jobs(hooks: dict = None): frappe.reload_doc("core", "doctype", "scheduled_job_type") scheduler_events = hooks or frappe.get_hooks("scheduler_events") all_events = insert_events(scheduler_events) clear_events(all_events) -def insert_events(scheduler_events: Dict) -> List: +def insert_events(scheduler_events: dict) -> list: cron_jobs, event_jobs = [], [] for event_type in scheduler_events: events = scheduler_events.get(event_type) @@ -157,7 +156,7 @@ def insert_events(scheduler_events: Dict) -> List: return cron_jobs + event_jobs -def insert_cron_jobs(events: Dict) -> List: +def insert_cron_jobs(events: dict) -> list: cron_jobs = [] for cron_format in events: for event in events.get(cron_format): @@ -166,7 +165,7 @@ def insert_cron_jobs(events: Dict) -> List: return cron_jobs -def insert_event_jobs(events: List, event_type: str) -> List: +def insert_event_jobs(events: list, event_type: str) -> list: event_jobs = [] for event in events: event_jobs.append(event) @@ -199,7 +198,7 @@ def insert_single_event(frequency: str, event: str, cron_format: str = None): doc.insert() -def clear_events(all_events: List): +def clear_events(all_events: list): for event in frappe.get_all("Scheduled Job Type", fields=["name", "method", "server_script"]): is_server_script = event.server_script is_defined_in_hooks = event.method in all_events diff --git a/frappe/core/doctype/scheduled_job_type/test_scheduled_job_type.py b/frappe/core/doctype/scheduled_job_type/test_scheduled_job_type.py index 3e63985692..5448bda91f 100644 --- a/frappe/core/doctype/scheduled_job_type/test_scheduled_job_type.py +++ b/frappe/core/doctype/scheduled_job_type/test_scheduled_job_type.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and Contributors # License: MIT. See LICENSE import unittest diff --git a/frappe/core/doctype/server_script/server_script.py b/frappe/core/doctype/server_script/server_script.py index 5fd59e1014..fda5ca8591 100644 --- a/frappe/core/doctype/server_script/server_script.py +++ b/frappe/core/doctype/server_script/server_script.py @@ -1,9 +1,7 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and contributors # License: MIT. See LICENSE from types import FunctionType, MethodType, ModuleType -from typing import Dict, List import frappe from frappe import _ @@ -31,7 +29,7 @@ class ServerScript(Document): return {"script": "py"} @property - def scheduled_jobs(self) -> List[Dict[str, str]]: + def scheduled_jobs(self) -> list[dict[str, str]]: return frappe.get_all( "Scheduled Job Type", filters={"server_script": self.name}, @@ -69,7 +67,7 @@ class ServerScript(Document): except Exception as e: frappe.msgprint(str(e), title=_("Compilation warning")) - def execute_method(self) -> Dict: + def execute_method(self) -> dict: """Specific to API endpoint Server Scripts Raises: @@ -110,7 +108,7 @@ class ServerScript(Document): safe_exec(self.script) - def get_permission_query_conditions(self, user: str) -> List[str]: + def get_permission_query_conditions(self, user: str) -> list[str]: """Specific to Permission Query Server Scripts Args: diff --git a/frappe/core/doctype/server_script/test_server_script.py b/frappe/core/doctype/server_script/test_server_script.py index fd600b8205..4c1c12b7f2 100644 --- a/frappe/core/doctype/server_script/test_server_script.py +++ b/frappe/core/doctype/server_script/test_server_script.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and Contributors # License: MIT. See LICENSE import unittest diff --git a/frappe/core/doctype/session_default/session_default.py b/frappe/core/doctype/session_default/session_default.py index df261f4a39..3fada1b5e0 100644 --- a/frappe/core/doctype/session_default/session_default.py +++ b/frappe/core/doctype/session_default/session_default.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/core/doctype/session_default_settings/session_default_settings.py b/frappe/core/doctype/session_default_settings/session_default_settings.py index 4ac9b61553..2b0d731920 100644 --- a/frappe/core/doctype/session_default_settings/session_default_settings.py +++ b/frappe/core/doctype/session_default_settings/session_default_settings.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/core/doctype/session_default_settings/test_session_default_settings.py b/frappe/core/doctype/session_default_settings/test_session_default_settings.py index f763f90a1d..aa60085ce9 100644 --- a/frappe/core/doctype/session_default_settings/test_session_default_settings.py +++ b/frappe/core/doctype/session_default_settings/test_session_default_settings.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and Contributors # License: MIT. See LICENSE import unittest diff --git a/frappe/core/doctype/sms_parameter/__init__.py b/frappe/core/doctype/sms_parameter/__init__.py index 8b13789179..e69de29bb2 100755 --- a/frappe/core/doctype/sms_parameter/__init__.py +++ b/frappe/core/doctype/sms_parameter/__init__.py @@ -1 +0,0 @@ - diff --git a/frappe/core/doctype/sms_settings/__init__.py b/frappe/core/doctype/sms_settings/__init__.py index 8b13789179..e69de29bb2 100755 --- a/frappe/core/doctype/sms_settings/__init__.py +++ b/frappe/core/doctype/sms_settings/__init__.py @@ -1 +0,0 @@ - diff --git a/frappe/core/doctype/sms_settings/sms_settings.py b/frappe/core/doctype/sms_settings/sms_settings.py index e1da200ee5..686890514a 100644 --- a/frappe/core/doctype/sms_settings/sms_settings.py +++ b/frappe/core/doctype/sms_settings/sms_settings.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors # License: MIT. See LICENSE diff --git a/frappe/core/doctype/sms_settings/test_sms_settings.py b/frappe/core/doctype/sms_settings/test_sms_settings.py index da1b807594..61be20ff66 100644 --- a/frappe/core/doctype/sms_settings/test_sms_settings.py +++ b/frappe/core/doctype/sms_settings/test_sms_settings.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2017, Frappe Technologies and Contributors # License: MIT. See LICENSE import unittest diff --git a/frappe/core/doctype/success_action/success_action.py b/frappe/core/doctype/success_action/success_action.py index 95a81ee0fb..e3db646a2e 100644 --- a/frappe/core/doctype/success_action/success_action.py +++ b/frappe/core/doctype/success_action/success_action.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2018, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/core/doctype/system_settings/test_system_settings.py b/frappe/core/doctype/system_settings/test_system_settings.py index 410762b4e7..b126976eeb 100644 --- a/frappe/core/doctype/system_settings/test_system_settings.py +++ b/frappe/core/doctype/system_settings/test_system_settings.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2017, Frappe Technologies and Contributors # License: MIT. See LICENSE import unittest diff --git a/frappe/core/doctype/test/test.py b/frappe/core/doctype/test/test.py index 8f3cf7111d..664d06ac84 100644 --- a/frappe/core/doctype/test/test.py +++ b/frappe/core/doctype/test/test.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2021, Frappe Technologies and contributors # License: MIT. See LICENSE @@ -15,7 +14,7 @@ class test(Document): json.dump(d, read_file) def load_from_db(self): - with open("data_file.json", "r") as read_file: + with open("data_file.json") as read_file: d = json.load(read_file) super(Document, self).__init__(d) @@ -25,20 +24,20 @@ class test(Document): json.dump(d, read_file) def get_list(self, args): - with open("data_file.json", "r") as read_file: + with open("data_file.json") as read_file: return [json.load(read_file)] def get_value(self, fields, filters, **kwargs): # return [] - with open("data_file.json", "r") as read_file: + with open("data_file.json") as read_file: return [json.load(read_file)] def get_count(self, args): # return [] - with open("data_file.json", "r") as read_file: + with open("data_file.json") as read_file: return [json.load(read_file)] def get_stats(self, args): # return [] - with open("data_file.json", "r") as read_file: + with open("data_file.json") as read_file: return [json.load(read_file)] diff --git a/frappe/core/doctype/test/test_test.py b/frappe/core/doctype/test/test_test.py index e4ee3de5dd..6080c200c1 100644 --- a/frappe/core/doctype/test/test_test.py +++ b/frappe/core/doctype/test/test_test.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2021, Frappe Technologies and Contributors # License: MIT. See LICENSE # import frappe diff --git a/frappe/core/doctype/transaction_log/test_transaction_log.py b/frappe/core/doctype/transaction_log/test_transaction_log.py index a4bb066eea..8b179f8d85 100644 --- a/frappe/core/doctype/transaction_log/test_transaction_log.py +++ b/frappe/core/doctype/transaction_log/test_transaction_log.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2018, Frappe Technologies and Contributors # License: MIT. See LICENSE import hashlib diff --git a/frappe/core/doctype/translation/test_translation.py b/frappe/core/doctype/translation/test_translation.py index df5ae3767a..c9f4e85086 100644 --- a/frappe/core/doctype/translation/test_translation.py +++ b/frappe/core/doctype/translation/test_translation.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies and Contributors # License: MIT. See LICENSE import unittest diff --git a/frappe/core/doctype/translation/translation.py b/frappe/core/doctype/translation/translation.py index 90ea4d1523..b08198eb13 100644 --- a/frappe/core/doctype/translation/translation.py +++ b/frappe/core/doctype/translation/translation.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/core/doctype/user/user.py b/frappe/core/doctype/user/user.py index cfb2f4d871..bc5c20eb92 100644 --- a/frappe/core/doctype/user/user.py +++ b/frappe/core/doctype/user/user.py @@ -489,7 +489,7 @@ class User(Document): self.save() def remove_roles(self, *roles): - existing_roles = dict((d.role, d) for d in self.get("roles")) + existing_roles = {d.role: d for d in self.get("roles")} for role in roles: if role in existing_roles: self.get("roles").remove(existing_roles[role]) @@ -498,7 +498,7 @@ class User(Document): def remove_all_roles_for_guest(self): if self.name == "Guest": - self.set("roles", list(set(d for d in self.get("roles") if d.role == "Guest"))) + self.set("roles", list({d for d in self.get("roles") if d.role == "Guest"})) def remove_disabled_roles(self): disabled_roles = [d.name for d in frappe.get_all("Role", filters={"disabled": 1})] @@ -557,7 +557,7 @@ class User(Document): if not username: # @firstname_last_name username = _check_suggestion( - frappe.scrub("{0} {1}".format(self.first_name, self.last_name or "")) + frappe.scrub("{} {}".format(self.first_name, self.last_name or "")) ) if username: @@ -918,7 +918,7 @@ def user_query(doctype, txt, searchfield, start, page_len, filters): user_type_condition = "" filters.pop("ignore_user_type") - txt = "%{}%".format(txt) + txt = f"%{txt}%" return frappe.db.sql( """SELECT `name`, CONCAT_WS(' ', first_name, middle_name, last_name) FROM `tabUser` @@ -970,7 +970,7 @@ def get_system_users(exclude_users=None, limit=None): limit_cond = "" if limit: - limit_cond = "limit {0}".format(limit) + limit_cond = f"limit {limit}" exclude_users += list(STANDARD_USERS) @@ -1036,7 +1036,7 @@ def notify_admin_access_to_system_manager(login_manager=None): ): site = '{0}'.format(frappe.local.request.host_url) - date_and_time = "{0}".format(format_datetime(now_datetime(), format_string="medium")) + date_and_time = "{}".format(format_datetime(now_datetime(), format_string="medium")) ip_address = frappe.local.request_ip access_message = _("Administrator accessed {0} on {1} via IP Address {2}.").format( diff --git a/frappe/core/doctype/user_document_type/user_document_type.py b/frappe/core/doctype/user_document_type/user_document_type.py index 1e7eab4bd4..731acf582b 100644 --- a/frappe/core/doctype/user_document_type/user_document_type.py +++ b/frappe/core/doctype/user_document_type/user_document_type.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2021, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/core/doctype/user_email/user_email.py b/frappe/core/doctype/user_email/user_email.py index 21167ad25d..ebca480f47 100644 --- a/frappe/core/doctype/user_email/user_email.py +++ b/frappe/core/doctype/user_email/user_email.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/core/doctype/user_group/test_user_group.py b/frappe/core/doctype/user_group/test_user_group.py index 546d4fd54c..368f4eaef2 100644 --- a/frappe/core/doctype/user_group/test_user_group.py +++ b/frappe/core/doctype/user_group/test_user_group.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2021, Frappe Technologies and Contributors # License: MIT. See LICENSE # import frappe diff --git a/frappe/core/doctype/user_group/user_group.py b/frappe/core/doctype/user_group/user_group.py index a59117426f..812f230f7a 100644 --- a/frappe/core/doctype/user_group/user_group.py +++ b/frappe/core/doctype/user_group/user_group.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2021, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/core/doctype/user_group_member/test_user_group_member.py b/frappe/core/doctype/user_group_member/test_user_group_member.py index f1bdc41cff..5d709d0bec 100644 --- a/frappe/core/doctype/user_group_member/test_user_group_member.py +++ b/frappe/core/doctype/user_group_member/test_user_group_member.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2021, Frappe Technologies and Contributors # License: MIT. See LICENSE # import frappe diff --git a/frappe/core/doctype/user_group_member/user_group_member.py b/frappe/core/doctype/user_group_member/user_group_member.py index 6b948d797f..e9722a07ad 100644 --- a/frappe/core/doctype/user_group_member/user_group_member.py +++ b/frappe/core/doctype/user_group_member/user_group_member.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2021, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/core/doctype/user_select_document_type/user_select_document_type.py b/frappe/core/doctype/user_select_document_type/user_select_document_type.py index 07b8123a13..9cf2e4856d 100644 --- a/frappe/core/doctype/user_select_document_type/user_select_document_type.py +++ b/frappe/core/doctype/user_select_document_type/user_select_document_type.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2021, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/core/doctype/user_social_login/user_social_login.py b/frappe/core/doctype/user_social_login/user_social_login.py index d12b5823d1..4cf3f720cd 100644 --- a/frappe/core/doctype/user_social_login/user_social_login.py +++ b/frappe/core/doctype/user_social_login/user_social_login.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2017, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/core/doctype/user_type/test_user_type.py b/frappe/core/doctype/user_type/test_user_type.py index 53999ed3df..235881517a 100644 --- a/frappe/core/doctype/user_type/test_user_type.py +++ b/frappe/core/doctype/user_type/test_user_type.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2021, Frappe Technologies and Contributors # License: MIT. See LICENSE import unittest diff --git a/frappe/core/doctype/user_type/user_type.py b/frappe/core/doctype/user_type/user_type.py index 7efb66f569..369e70bf56 100644 --- a/frappe/core/doctype/user_type/user_type.py +++ b/frappe/core/doctype/user_type/user_type.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2021, Frappe Technologies and contributors # License: MIT. See LICENSE @@ -211,7 +210,7 @@ def get_user_linked_doctypes(doctype, txt, searchfield, start, page_len, filters ["DocType", "issingle", "=", 0], ["DocType", "module", "not in", modules], ["DocType", "read_only", "=", 0], - ["DocType", "name", "like", "%{0}%".format(txt)], + ["DocType", "name", "like", f"%{txt}%"], ] doctypes = frappe.get_all( @@ -225,7 +224,7 @@ def get_user_linked_doctypes(doctype, txt, searchfield, start, page_len, filters ) custom_dt_filters = [ - ["Custom Field", "dt", "like", "%{0}%".format(txt)], + ["Custom Field", "dt", "like", f"%{txt}%"], ["Custom Field", "options", "=", "User"], ["Custom Field", "fieldtype", "=", "Link"], ] diff --git a/frappe/core/doctype/user_type_module/user_type_module.py b/frappe/core/doctype/user_type_module/user_type_module.py index 83662bfcaf..1dc7c849e8 100644 --- a/frappe/core/doctype/user_type_module/user_type_module.py +++ b/frappe/core/doctype/user_type_module/user_type_module.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2021, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/core/doctype/version/version.py b/frappe/core/doctype/version/version.py index fa6ba0a9cf..99eeb8c2b0 100644 --- a/frappe/core/doctype/version/version.py +++ b/frappe/core/doctype/version/version.py @@ -2,7 +2,6 @@ # License: MIT. See LICENSE import json -from typing import Optional import frappe from frappe.model import no_value_fields, table_fields @@ -10,7 +9,7 @@ from frappe.model.document import Document class Version(Document): - def update_version_info(self, old: Optional[Document], new: Document) -> bool: + def update_version_info(self, old: Document | None, new: Document) -> bool: """Update changed info and return true if change contains useful data.""" if not old: # Check if doc has some information about creation source like data import diff --git a/frappe/core/doctype/view_log/test_view_log.py b/frappe/core/doctype/view_log/test_view_log.py index 04a17cc526..5a88269028 100644 --- a/frappe/core/doctype/view_log/test_view_log.py +++ b/frappe/core/doctype/view_log/test_view_log.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2018, Frappe Technologies and Contributors # License: MIT. See LICENSE import unittest diff --git a/frappe/core/doctype/view_log/view_log.py b/frappe/core/doctype/view_log/view_log.py index 6156fb74df..8383af818e 100644 --- a/frappe/core/doctype/view_log/view_log.py +++ b/frappe/core/doctype/view_log/view_log.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2018, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/core/page/background_jobs/background_jobs.py b/frappe/core/page/background_jobs/background_jobs.py index 8c3c8ff41e..8ef15b65eb 100644 --- a/frappe/core/page/background_jobs/background_jobs.py +++ b/frappe/core/page/background_jobs/background_jobs.py @@ -1,7 +1,7 @@ # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors # License: MIT. See LICENSE -from typing import TYPE_CHECKING, Dict, List +from typing import TYPE_CHECKING import frappe from frappe.utils import convert_utc_to_user_timezone @@ -15,7 +15,7 @@ JOB_COLORS = {"queued": "orange", "failed": "red", "started": "blue", "finished" @frappe.whitelist() -def get_info(view=None, queue_timeout=None, job_status=None) -> List[Dict]: +def get_info(view=None, queue_timeout=None, job_status=None) -> list[dict]: jobs = [] def add_job(job: "Job", queue: str) -> None: diff --git a/frappe/core/page/permission_manager/permission_manager.py b/frappe/core/page/permission_manager/permission_manager.py index e2d08488c0..46c9e0aca2 100644 --- a/frappe/core/page/permission_manager/permission_manager.py +++ b/frappe/core/page/permission_manager/permission_manager.py @@ -1,7 +1,6 @@ # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors # License: MIT. See LICENSE -from typing import Optional import frappe import frappe.defaults @@ -71,7 +70,7 @@ def get_roles_and_doctypes(): @frappe.whitelist() -def get_permissions(doctype: Optional[str] = None, role: Optional[str] = None): +def get_permissions(doctype: str | None = None, role: str | None = None): frappe.only_for("System Manager") if role: diff --git a/frappe/core/report/permitted_documents_for_user/permitted_documents_for_user.py b/frappe/core/report/permitted_documents_for_user/permitted_documents_for_user.py index 6d7f394beb..362cc6b105 100644 --- a/frappe/core/report/permitted_documents_for_user/permitted_documents_for_user.py +++ b/frappe/core/report/permitted_documents_for_user/permitted_documents_for_user.py @@ -37,12 +37,12 @@ def validate(user, doctype): def get_columns_and_fields(doctype): - columns = ["Name:Link/{}:200".format(doctype)] + columns = [f"Name:Link/{doctype}:200"] fields = ["`name`"] for df in frappe.get_meta(doctype).fields: if df.in_list_view and df.fieldtype in data_fieldtypes: - fields.append("`{0}`".format(df.fieldname)) - fieldtype = "Link/{}".format(df.options) if df.fieldtype == "Link" else df.fieldtype + fields.append(f"`{df.fieldname}`") + fieldtype = f"Link/{df.options}" if df.fieldtype == "Link" else df.fieldtype columns.append( "{label}:{fieldtype}:{width}".format( label=df.label, fieldtype=fieldtype, width=df.width or 100 diff --git a/frappe/custom/doctype/client_script/test_client_script.py b/frappe/custom/doctype/client_script/test_client_script.py index 7497ab7780..c93df04c98 100644 --- a/frappe/custom/doctype/client_script/test_client_script.py +++ b/frappe/custom/doctype/client_script/test_client_script.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors # License: MIT. See LICENSE import unittest diff --git a/frappe/custom/doctype/custom_field/test_custom_field.py b/frappe/custom/doctype/custom_field/test_custom_field.py index 519ea7f2b4..34223315c5 100644 --- a/frappe/custom/doctype/custom_field/test_custom_field.py +++ b/frappe/custom/doctype/custom_field/test_custom_field.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors # License: MIT. See LICENSE diff --git a/frappe/custom/doctype/customize_form/customize_form.py b/frappe/custom/doctype/customize_form/customize_form.py index 20c3a7c025..4923bfc525 100644 --- a/frappe/custom/doctype/customize_form/customize_form.py +++ b/frappe/custom/doctype/customize_form/customize_form.py @@ -330,7 +330,7 @@ class CustomizeForm(Document): We need to maintain the order of the link/actions if the user has shuffled them. So we create a new property (ex `links_order`) to keep a list of items. """ - property_name = "{}_order".format(fieldname) + property_name = f"{fieldname}_order" if has_custom: # save the order of the actions and links self.make_property_setter( diff --git a/frappe/custom/doctype/doctype_layout/doctype_layout.py b/frappe/custom/doctype/doctype_layout/doctype_layout.py index f5d37d6f60..ea8e9acc99 100644 --- a/frappe/custom/doctype/doctype_layout/doctype_layout.py +++ b/frappe/custom/doctype/doctype_layout/doctype_layout.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2020, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/custom/doctype/doctype_layout/test_doctype_layout.py b/frappe/custom/doctype/doctype_layout/test_doctype_layout.py index 1373b4a53a..0e64a9e727 100644 --- a/frappe/custom/doctype/doctype_layout/test_doctype_layout.py +++ b/frappe/custom/doctype/doctype_layout/test_doctype_layout.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2020, Frappe Technologies and Contributors # License: MIT. See LICENSE # import frappe diff --git a/frappe/custom/doctype/doctype_layout_field/doctype_layout_field.py b/frappe/custom/doctype/doctype_layout_field/doctype_layout_field.py index 66fc111d32..f2b8c2b40b 100644 --- a/frappe/custom/doctype/doctype_layout_field/doctype_layout_field.py +++ b/frappe/custom/doctype/doctype_layout_field/doctype_layout_field.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2020, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/custom/doctype/property_setter/test_property_setter.py b/frappe/custom/doctype/property_setter/test_property_setter.py index a1bbc69235..1fa2d2cefb 100644 --- a/frappe/custom/doctype/property_setter/test_property_setter.py +++ b/frappe/custom/doctype/property_setter/test_property_setter.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors # License: MIT. See LICENSE import unittest diff --git a/frappe/custom/doctype/test_rename_new/test_rename_new.py b/frappe/custom/doctype/test_rename_new/test_rename_new.py index e79cb60bbe..ed89d1fad1 100644 --- a/frappe/custom/doctype/test_rename_new/test_rename_new.py +++ b/frappe/custom/doctype/test_rename_new/test_rename_new.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2021, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/custom/doctype/test_rename_new/test_test_rename_new.py b/frappe/custom/doctype/test_rename_new/test_test_rename_new.py index 513a9286a3..f1ccf42ede 100644 --- a/frappe/custom/doctype/test_rename_new/test_test_rename_new.py +++ b/frappe/custom/doctype/test_rename_new/test_test_rename_new.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2021, Frappe Technologies and Contributors # License: MIT. See LICENSE # import frappe diff --git a/frappe/database/database.py b/frappe/database/database.py index a52264ed6d..09d3424837 100644 --- a/frappe/database/database.py +++ b/frappe/database/database.py @@ -10,7 +10,6 @@ import re import string from contextlib import contextmanager from time import time -from typing import Dict, List, Optional, Tuple, Union from pypika.terms import Criterion, NullValue, PseudoColumn @@ -31,11 +30,11 @@ SINGLE_WORD_PATTERN = re.compile(r'([`"]?)(tab([A-Z]\w+))\1') MULTI_WORD_PATTERN = re.compile(r'([`"])(tab([A-Z]\w+)( [A-Z]\w+)+)\1') -def is_query_type(query: str, query_type: Union[str, Tuple[str]]) -> bool: +def is_query_type(query: str, query_type: str | tuple[str]) -> bool: return query.lstrip().split(maxsplit=1)[0].lower().startswith(query_type) -class Database(object): +class Database: """ Open a database connection with the given parmeters, if use_default is True, use the login details from `conf.py`. This is called by the request handler and is accessible using @@ -195,7 +194,7 @@ class Database(object): if debug: time_end = time() - frappe.errprint(("Execution time: {0} sec").format(round(time_end - time_start, 2))) + frappe.errprint(("Execution time: {} sec").format(round(time_end - time_start, 2))) except Exception as e: if self.is_syntax_error(e): @@ -670,8 +669,8 @@ class Database(object): def set_single_value( self, doctype: str, - fieldname: Union[str, Dict], - value: Optional[Union[str, int]] = None, + fieldname: str | dict, + value: str | int | None = None, *args, **kwargs, ): @@ -1023,7 +1022,7 @@ class Database(object): def a_row_exists(self, doctype): """Returns True if atleast one row exists.""" - return self.sql("select name from `tab{doctype}` limit 1".format(doctype=doctype)) + return self.sql(f"select name from `tab{doctype}` limit 1") def exists(self, dt, dn=None, cache=False): """Return the document name of a matching document, or None. @@ -1063,13 +1062,13 @@ class Database(object): def count(self, dt, filters=None, debug=False, cache=False, distinct: bool = True): """Returns `COUNT(*)` for given DocType and filters.""" if cache and not filters: - cache_count = frappe.cache().get_value("doctype:count:{}".format(dt)) + cache_count = frappe.cache().get_value(f"doctype:count:{dt}") if cache_count is not None: return cache_count query = self.query.get_sql(table=dt, filters=filters, fields=Count("*"), distinct=distinct) count = self.sql(query, debug=debug)[0][0] if not filters and cache: - frappe.cache().set_value("doctype:count:{}".format(dt), count, expires_in_sec=86400) + frappe.cache().set_value(f"doctype:count:{dt}", count, expires_in_sec=86400) return count @staticmethod @@ -1103,7 +1102,7 @@ class Database(object): now_datetime() - relativedelta(minutes=minutes), )[0][0] - def get_db_table_columns(self, table) -> List[str]: + def get_db_table_columns(self, table) -> list[str]: """Returns list of column names from given table.""" columns = frappe.cache().hget("table_columns", table) if columns is None: @@ -1137,7 +1136,7 @@ class Database(object): def get_column_type(self, doctype, column): return self.sql( """SELECT column_type FROM INFORMATION_SCHEMA.COLUMNS - WHERE table_name = 'tab{0}' AND column_name = '{1}' """.format( + WHERE table_name = 'tab{}' AND column_name = '{}' """.format( doctype, column ) )[0][0] @@ -1199,7 +1198,7 @@ class Database(object): query = sql_dict.get(current_dialect) return self.sql(query, values, **kwargs) - def delete(self, doctype: str, filters: Union[Dict, List] = None, debug=False, **kwargs): + def delete(self, doctype: str, filters: dict | list = None, debug=False, **kwargs): """Delete rows from a table in site which match the passed filters. This does trigger DocType hooks. Simply runs a DELETE query in the database. @@ -1305,7 +1304,7 @@ def enqueue_jobs_after_commit(): @contextmanager -def savepoint(catch: Union[type, Tuple[type, ...]] = Exception): +def savepoint(catch: type | tuple[type, ...] = Exception): """Wrapper for wrapping blocks of DB operations in a savepoint. as contextmanager: diff --git a/frappe/database/db_manager.py b/frappe/database/db_manager.py index 8f810fe54b..796f23a054 100644 --- a/frappe/database/db_manager.py +++ b/frappe/database/db_manager.py @@ -20,15 +20,15 @@ class DbManager: host = self.get_current_host() if password: - self.db.sql("CREATE USER '%s'@'%s' IDENTIFIED BY '%s';" % (user, host, password)) + self.db.sql(f"CREATE USER '{user}'@'{host}' IDENTIFIED BY '{password}';") else: - self.db.sql("CREATE USER '%s'@'%s';" % (user, host)) + self.db.sql(f"CREATE USER '{user}'@'{host}';") def delete_user(self, target, host=None): if not host: host = self.get_current_host() try: - self.db.sql("DROP USER '%s'@'%s';" % (target, host)) + self.db.sql(f"DROP USER '{target}'@'{host}';") except Exception as e: if e.args[0] == 1396: pass @@ -54,7 +54,7 @@ class DbManager: % (target, user, host) ) else: - self.db.sql("GRANT ALL PRIVILEGES ON `%s`.* TO '%s'@'%s';" % (target, user, host)) + self.db.sql(f"GRANT ALL PRIVILEGES ON `{target}`.* TO '{user}'@'{host}';") def flush_privileges(self): self.db.sql("FLUSH PRIVILEGES") @@ -73,11 +73,11 @@ class DbManager: pv = find_executable("pv") if pv: - pipe = "{pv} {source} |".format(pv=pv, source=source) + pipe = f"{pv} {source} |" source = "" else: pipe = "" - source = "< {source}".format(source=source) + source = f"< {source}" if pipe: print("Restoring Database file...") diff --git a/frappe/database/mariadb/database.py b/frappe/database/mariadb/database.py index 7505ef3a7f..047039b0df 100644 --- a/frappe/database/mariadb/database.py +++ b/frappe/database/mariadb/database.py @@ -1,5 +1,3 @@ -from typing import List, Tuple, Union - import pymysql from pymysql.constants import ER, FIELD_TYPE from pymysql.converters import conversions, escape_string @@ -144,18 +142,18 @@ class MariaDBDatabase(Database): def is_type_datetime(code): return code in (pymysql.DATE, pymysql.DATETIME) - def rename_table(self, old_name: str, new_name: str) -> Union[List, Tuple]: + def rename_table(self, old_name: str, new_name: str) -> list | tuple: old_name = get_table_name(old_name) new_name = get_table_name(new_name) return self.sql(f"RENAME TABLE `{old_name}` TO `{new_name}`") - def describe(self, doctype: str) -> Union[List, Tuple]: + def describe(self, doctype: str) -> list | tuple: table_name = get_table_name(doctype) return self.sql(f"DESC `{table_name}`") def change_column_type( self, doctype: str, column: str, type: str, nullable: bool = False - ) -> Union[List, Tuple]: + ) -> list | tuple: table_name = get_table_name(doctype) null_constraint = "NOT NULL" if not nullable else "" return self.sql_ddl(f"ALTER TABLE `{table_name}` MODIFY `{column}` {type} {null_constraint}") @@ -303,7 +301,7 @@ class MariaDBDatabase(Database): ) ) - def add_index(self, doctype: str, fields: List, index_name: str = None): + def add_index(self, doctype: str, fields: list, index_name: str = None): """Creates an index with given fields if not already created. Index name will be `fieldname1_fieldname2_index`""" index_name = index_name or self.get_index_name(fields) @@ -343,7 +341,7 @@ class MariaDBDatabase(Database): """ res = self.sql("select issingle from `tabDocType` where name=%s", (doctype,)) if not res: - raise Exception("Wrong doctype {0} in updatedb".format(doctype)) + raise Exception(f"Wrong doctype {doctype} in updatedb") if not res[0][0]: db_table = MariaDBTable(doctype, meta) diff --git a/frappe/database/mariadb/schema.py b/frappe/database/mariadb/schema.py index f402b4ec74..24a78012e1 100644 --- a/frappe/database/mariadb/schema.py +++ b/frappe/database/mariadb/schema.py @@ -77,15 +77,15 @@ class MariaDBTable(DBTable): columns_to_modify = set(self.change_type + self.add_unique + self.set_default) for col in self.add_column: - add_column_query.append("ADD COLUMN `{}` {}".format(col.fieldname, col.get_definition())) + add_column_query.append(f"ADD COLUMN `{col.fieldname}` {col.get_definition()}") for col in columns_to_modify: - modify_column_query.append("MODIFY `{}` {}".format(col.fieldname, col.get_definition())) + modify_column_query.append(f"MODIFY `{col.fieldname}` {col.get_definition()}") for col in self.add_index: # if index key does not exists if not frappe.db.has_index(self.table_name, col.fieldname + "_index"): - add_index_query.append("ADD INDEX `{}_index`(`{}`)".format(col.fieldname, col.fieldname)) + add_index_query.append(f"ADD INDEX `{col.fieldname}_index`(`{col.fieldname}`)") for col in self.drop_index + self.drop_unique: if col.fieldname != "name": # primary key @@ -95,7 +95,7 @@ class MariaDBTable(DBTable): # nosemgrep unique_index_record = frappe.db.sql( """ - SHOW INDEX FROM `{0}` + SHOW INDEX FROM `{}` WHERE Key_name=%s AND Non_unique=0 """.format( @@ -105,14 +105,14 @@ class MariaDBTable(DBTable): as_dict=1, ) if unique_index_record: - drop_index_query.append("DROP INDEX `{}`".format(unique_index_record[0].Key_name)) + drop_index_query.append(f"DROP INDEX `{unique_index_record[0].Key_name}`") index_constraint_changed = current_column.index != col.set_index # if index key exists if index_constraint_changed and not col.set_index: # nosemgrep index_record = frappe.db.sql( """ - SHOW INDEX FROM `{0}` + SHOW INDEX FROM `{}` WHERE Key_name=%s AND Non_unique=1 """.format( @@ -122,13 +122,13 @@ class MariaDBTable(DBTable): as_dict=1, ) if index_record: - drop_index_query.append("DROP INDEX `{}`".format(index_record[0].Key_name)) + drop_index_query.append(f"DROP INDEX `{index_record[0].Key_name}`") try: for query_parts in [add_column_query, modify_column_query, add_index_query, drop_index_query]: if query_parts: query_body = ", ".join(query_parts) - query = "ALTER TABLE `{}` {}".format(self.table_name, query_body) + query = f"ALTER TABLE `{self.table_name}` {query_body}" frappe.db.sql(query) except Exception as e: diff --git a/frappe/database/mariadb/setup_db.py b/frappe/database/mariadb/setup_db.py index 4399ccfa6a..5eef0ef2c6 100644 --- a/frappe/database/mariadb/setup_db.py +++ b/frappe/database/mariadb/setup_db.py @@ -42,7 +42,7 @@ def setup_database(force, source_sql, verbose, no_mariadb_socket=False): dbman.delete_user(db_name, **dbman_kwargs) dbman.drop_database(db_name) else: - raise Exception("Database %s already exists" % (db_name,)) + raise Exception(f"Database {db_name} already exists") dbman.create_user(db_name, frappe.conf.db_password, **dbman_kwargs) if verbose: @@ -55,7 +55,7 @@ def setup_database(force, source_sql, verbose, no_mariadb_socket=False): dbman.grant_all_privileges(db_name, db_name, **dbman_kwargs) dbman.flush_privileges() if verbose: - print("Granted privileges to user %s and database %s" % (db_name, db_name)) + print(f"Granted privileges to user {db_name} and database {db_name}") # close root connection root_conn.close() diff --git a/frappe/database/postgres/database.py b/frappe/database/postgres/database.py index f9a4723d72..2553ebaa26 100644 --- a/frappe/database/postgres/database.py +++ b/frappe/database/postgres/database.py @@ -1,5 +1,4 @@ import re -from typing import List, Tuple, Union import psycopg2 import psycopg2.extensions @@ -118,9 +117,7 @@ class PostgresDatabase(Database): # pylint: disable=W0221 def sql(self, query, values=(), *args, **kwargs): - return super(PostgresDatabase, self).sql( - modify_query(query), modify_values(values), *args, **kwargs - ) + return super().sql(modify_query(query), modify_values(values), *args, **kwargs) def get_tables(self, cached=True): return [ @@ -128,9 +125,9 @@ class PostgresDatabase(Database): for d in self.sql( """select table_name from information_schema.tables - where table_catalog='{0}' + where table_catalog='{}' and table_type = 'BASE TABLE' - and table_schema='{1}'""".format( + and table_schema='{}'""".format( frappe.conf.db_name, frappe.conf.get("db_schema", "public") ) ) @@ -208,12 +205,12 @@ class PostgresDatabase(Database): def is_data_too_long(e): return e.pgcode == STRING_DATA_RIGHT_TRUNCATION - def rename_table(self, old_name: str, new_name: str) -> Union[List, Tuple]: + def rename_table(self, old_name: str, new_name: str) -> list | tuple: old_name = get_table_name(old_name) new_name = get_table_name(new_name) return self.sql(f"ALTER TABLE `{old_name}` RENAME TO `{new_name}`") - def describe(self, doctype: str) -> Union[List, Tuple]: + def describe(self, doctype: str) -> list | tuple: table_name = get_table_name(doctype) return self.sql( f"SELECT COLUMN_NAME FROM information_schema.COLUMNS WHERE TABLE_NAME = '{table_name}'" @@ -221,7 +218,7 @@ class PostgresDatabase(Database): def change_column_type( self, doctype: str, column: str, type: str, nullable: bool = False, use_cast: bool = False - ) -> Union[List, Tuple]: + ) -> list | tuple: table_name = get_table_name(doctype) null_constraint = "SET NOT NULL" if not nullable else "DROP NOT NULL" using_cast = f'using "{column}"::{type}' if use_cast else "" @@ -290,9 +287,9 @@ class PostgresDatabase(Database): * updates columns * updates indices """ - res = self.sql("select issingle from `tabDocType` where name='{}'".format(doctype)) + res = self.sql(f"select issingle from `tabDocType` where name='{doctype}'") if not res: - raise Exception("Wrong doctype {0} in updatedb".format(doctype)) + raise Exception(f"Wrong doctype {doctype} in updatedb") if not res[0][0]: db_table = PostgresTable(doctype, meta) @@ -306,7 +303,7 @@ class PostgresDatabase(Database): def get_on_duplicate_update(key="name"): if isinstance(key, list): key = '", "'.join(key) - return 'ON CONFLICT ("{key}") DO UPDATE SET '.format(key=key) + return f'ON CONFLICT ("{key}") DO UPDATE SET ' def check_implicit_commit(self, query): pass # postgres can run DDL in transactions without implicit commits @@ -319,7 +316,7 @@ class PostgresDatabase(Database): ) ) - def add_index(self, doctype: str, fields: List, index_name: str = None): + def add_index(self, doctype: str, fields: list, index_name: str = None): """Creates an index with given fields if not already created. Index name will be `fieldname1_fieldname2_index`""" table_name = get_table_name(doctype) diff --git a/frappe/database/postgres/schema.py b/frappe/database/postgres/schema.py index ef7ba33e12..5e28c81455 100644 --- a/frappe/database/postgres/schema.py +++ b/frappe/database/postgres/schema.py @@ -79,7 +79,7 @@ class PostgresTable(DBTable): query = [] for col in self.add_column: - query.append("ADD COLUMN `{}` {}".format(col.fieldname, col.get_definition())) + query.append(f"ADD COLUMN `{col.fieldname}` {col.get_definition()}") for col in self.change_type: using_clause = "" @@ -87,12 +87,12 @@ class PostgresTable(DBTable): # The USING option of SET DATA TYPE can actually specify any expression # involving the old values of the row # read more https://www.postgresql.org/docs/9.1/sql-altertable.html - using_clause = "USING {}::timestamp without time zone".format(col.fieldname) + using_clause = f"USING {col.fieldname}::timestamp without time zone" elif col.fieldtype in ("Check"): - using_clause = "USING {}::smallint".format(col.fieldname) + using_clause = f"USING {col.fieldname}::smallint" query.append( - "ALTER COLUMN `{0}` TYPE {1} {2}".format( + "ALTER COLUMN `{}` TYPE {} {}".format( col.fieldname, get_definition(col.fieldtype, precision=col.precision, length=col.length), using_clause, @@ -113,9 +113,9 @@ class PostgresTable(DBTable): col_default = "NULL" else: - col_default = "{}".format(frappe.db.escape(col.default)) + col_default = f"{frappe.db.escape(col.default)}" - query.append("ALTER COLUMN `{}` SET DEFAULT {}".format(col.fieldname, col_default)) + query.append(f"ALTER COLUMN `{col.fieldname}` SET DEFAULT {col_default}") create_contraint_query = "" for col in self.add_index: @@ -139,13 +139,13 @@ class PostgresTable(DBTable): # primary key if col.fieldname != "name": # if index key exists - drop_contraint_query += 'DROP INDEX IF EXISTS "{}" ;'.format(col.fieldname) + drop_contraint_query += f'DROP INDEX IF EXISTS "{col.fieldname}" ;' for col in self.drop_unique: # primary key if col.fieldname != "name": # if index key exists - drop_contraint_query += 'DROP INDEX IF EXISTS "unique_{}" ;'.format(col.fieldname) + drop_contraint_query += f'DROP INDEX IF EXISTS "unique_{col.fieldname}" ;' try: if query: final_alter_query = "ALTER TABLE `{}` {}".format(self.table_name, ", ".join(query)) diff --git a/frappe/database/postgres/setup_db.py b/frappe/database/postgres/setup_db.py index 9a7f2b43c4..0a40e9eba7 100644 --- a/frappe/database/postgres/setup_db.py +++ b/frappe/database/postgres/setup_db.py @@ -7,12 +7,10 @@ def setup_database(force, source_sql=None, verbose=False): root_conn = get_root_connection(frappe.flags.root_login, frappe.flags.root_password) root_conn.commit() root_conn.sql("end") - root_conn.sql("DROP DATABASE IF EXISTS `{0}`".format(frappe.conf.db_name)) - root_conn.sql("DROP USER IF EXISTS {0}".format(frappe.conf.db_name)) - root_conn.sql("CREATE DATABASE `{0}`".format(frappe.conf.db_name)) - root_conn.sql( - "CREATE user {0} password '{1}'".format(frappe.conf.db_name, frappe.conf.db_password) - ) + root_conn.sql(f"DROP DATABASE IF EXISTS `{frappe.conf.db_name}`") + root_conn.sql(f"DROP USER IF EXISTS {frappe.conf.db_name}") + root_conn.sql(f"CREATE DATABASE `{frappe.conf.db_name}`") + root_conn.sql(f"CREATE user {frappe.conf.db_name} password '{frappe.conf.db_password}'") root_conn.sql("GRANT ALL PRIVILEGES ON DATABASE `{0}` TO {0}".format(frappe.conf.db_name)) root_conn.close() @@ -79,10 +77,10 @@ def import_db_from_sql(source_sql=None, verbose=False): def setup_help_database(help_db_name): root_conn = get_root_connection(frappe.flags.root_login, frappe.flags.root_password) - root_conn.sql("DROP DATABASE IF EXISTS `{0}`".format(help_db_name)) - root_conn.sql("DROP USER IF EXISTS {0}".format(help_db_name)) - root_conn.sql("CREATE DATABASE `{0}`".format(help_db_name)) - root_conn.sql("CREATE user {0} password '{1}'".format(help_db_name, help_db_name)) + root_conn.sql(f"DROP DATABASE IF EXISTS `{help_db_name}`") + root_conn.sql(f"DROP USER IF EXISTS {help_db_name}") + root_conn.sql(f"CREATE DATABASE `{help_db_name}`") + root_conn.sql(f"CREATE user {help_db_name} password '{help_db_name}'") root_conn.sql("GRANT ALL PRIVILEGES ON DATABASE `{0}` TO {0}".format(help_db_name)) diff --git a/frappe/database/query.py b/frappe/database/query.py index f7cc143cf7..c87117466b 100644 --- a/frappe/database/query.py +++ b/frappe/database/query.py @@ -1,7 +1,7 @@ import operator import re from functools import cached_property -from typing import Any, Callable, Dict, List, Tuple, Union +from typing import Any, Callable import frappe from frappe import _ @@ -26,7 +26,7 @@ def like(key: Field, value: str) -> frappe.qb: return key.like(value) -def func_in(key: Field, value: Union[List, Tuple]) -> frappe.qb: +def func_in(key: Field, value: list | tuple) -> frappe.qb: """Wrapper method for `IN` Args: @@ -52,7 +52,7 @@ def not_like(key: Field, value: str) -> frappe.qb: return key.not_like(value) -def func_not_in(key: Field, value: Union[List, Tuple]): +def func_not_in(key: Field, value: list | tuple): """Wrapper method for `NOT IN` Args: @@ -78,7 +78,7 @@ def func_regex(key: Field, value: str) -> frappe.qb: return key.regex(value) -def func_between(key: Field, value: Union[List, Tuple]) -> frappe.qb: +def func_between(key: Field, value: list | tuple) -> frappe.qb: """Wrapper method for `BETWEEN` Args: @@ -110,7 +110,7 @@ def func_timespan(key: Field, value: str) -> frappe.qb: return func_between(key, get_timespan_date_range(value)) -def make_function(key: Any, value: Union[int, str]): +def make_function(key: Any, value: int | str): """returns fucntion query Args: @@ -144,7 +144,7 @@ def change_orderby(order: str): # default operators -OPERATOR_MAP: Dict[str, Callable] = { +OPERATOR_MAP: dict[str, Callable] = { "+": operator.add, "=": operator.eq, "-": operator.sub, @@ -192,7 +192,7 @@ class Query: return all_operators - def get_condition(self, table: Union[str, Table], **kwargs) -> frappe.qb: + def get_condition(self, table: str | Table, **kwargs) -> frappe.qb: """Get initial table object Args: @@ -208,7 +208,7 @@ class Query: return frappe.qb.into(table_object) return frappe.qb.from_(table_object) - def get_table(self, table_name: Union[str, Table]) -> Table: + def get_table(self, table_name: str | Table) -> Table: if isinstance(table_name, Table): return table_name table_name = table_name.strip('"').strip("'") @@ -259,7 +259,7 @@ class Query: return conditions - def misc_query(self, table: str, filters: Union[List, Tuple] = None, **kwargs): + def misc_query(self, table: str, filters: list | tuple = None, **kwargs): """Build conditions using the given Lists or Tuple filters Args: @@ -291,9 +291,7 @@ class Query: return self.add_conditions(conditions, **kwargs) - def dict_query( - self, table: str, filters: Dict[str, Union[str, int]] = None, **kwargs - ) -> frappe.qb: + def dict_query(self, table: str, filters: dict[str, str | int] = None, **kwargs) -> frappe.qb: """Build conditions using the given dictionary filters Args: @@ -329,7 +327,7 @@ class Query: return self.add_conditions(conditions, **kwargs) def build_conditions( - self, table: str, filters: Union[Dict[str, Union[str, int]], str, int] = None, **kwargs + self, table: str, filters: dict[str, str | int] | str | int = None, **kwargs ) -> frappe.qb: """Build conditions for sql query @@ -357,8 +355,8 @@ class Query: def get_sql( self, table: str, - fields: Union[List, Tuple], - filters: Union[Dict[str, Union[str, int]], str, int, List[Union[List, str, int]]] = None, + fields: list | tuple, + filters: dict[str, str | int] | str | int | list[list | str | int] = None, **kwargs, ): # Clean up state before each query diff --git a/frappe/database/schema.py b/frappe/database/schema.py index 9a8307ddae..5920d14c3d 100644 --- a/frappe/database/schema.py +++ b/frappe/database/schema.py @@ -15,7 +15,7 @@ class InvalidColumnName(frappe.ValidationError): class DBTable: def __init__(self, doctype, meta=None): self.doctype = doctype - self.table_name = "tab{}".format(doctype) + self.table_name = f"tab{doctype}" self.meta = meta or frappe.get_meta(doctype, False) self.columns = {} self.current_columns = {} @@ -195,11 +195,11 @@ class DbColumn: if self.fieldtype in ("Check", "Int"): default_value = cint(self.default) or 0 - column_def += " not null default {0}".format(default_value) + column_def += f" not null default {default_value}" elif self.fieldtype in ("Currency", "Float", "Percent"): default_value = flt(self.default) or 0 - column_def += " not null default {0}".format(default_value) + column_def += f" not null default {default_value}" elif ( self.default @@ -207,7 +207,7 @@ class DbColumn: and not cstr(self.default).startswith(":") and column_def not in ("text", "longtext") ): - column_def += " default {}".format(frappe.db.escape(self.default)) + column_def += f" default {frappe.db.escape(self.default)}" if self.unique and (column_def not in ("text", "longtext")): column_def += " unique" @@ -308,7 +308,7 @@ class DbColumn: def validate_column_name(n): if special_characters := SPECIAL_CHAR_PATTERN.findall(n): - special_characters = ", ".join('"{0}"'.format(c) for c in special_characters) + special_characters = ", ".join(f'"{c}"' for c in special_characters) frappe.throw( _("Fieldname {0} cannot have special characters like {1}").format( frappe.bold(cstr(n)), special_characters @@ -352,7 +352,7 @@ def get_definition(fieldtype, precision=None, length=None): size = length if size is not None: - coltype = "{coltype}({size})".format(coltype=coltype, size=size) + coltype = f"{coltype}({size})" return coltype @@ -366,7 +366,7 @@ def add_column( frappe.db.commit() - query = "alter table `tab%s` add column %s %s" % ( + query = "alter table `tab{}` add column {} {}".format( doctype, column_name, get_definition(fieldtype, precision, length), diff --git a/frappe/deferred_insert.py b/frappe/deferred_insert.py index 3b47d46cdf..328d8dd555 100644 --- a/frappe/deferred_insert.py +++ b/frappe/deferred_insert.py @@ -1,5 +1,5 @@ import json -from typing import TYPE_CHECKING, Dict, List, Union +from typing import TYPE_CHECKING, Union import redis @@ -12,7 +12,7 @@ if TYPE_CHECKING: queue_prefix = "insert_queue_for_" -def deferred_insert(doctype: str, records: Union[List[Union[Dict, "Document"]], str]): +def deferred_insert(doctype: str, records: list[Union[dict, "Document"]] | str): if isinstance(records, (dict, list)): _records = json.dumps(records) else: @@ -43,7 +43,7 @@ def save_to_db(): insert_record(record, doctype) -def insert_record(record: Union[Dict, "Document"], doctype: str): +def insert_record(record: Union[dict, "Document"], doctype: str): try: record.update({"doctype": doctype}) frappe.get_doc(record).insert() diff --git a/frappe/desk/desktop.py b/frappe/desk/desktop.py index ca0d1e2353..e2be2656a9 100644 --- a/frappe/desk/desktop.py +++ b/frappe/desk/desktop.py @@ -486,9 +486,9 @@ def save_new_widget(doc, page, blocks, new_widgets): # Error log body log = """ - page: {0} - config: {1} - exception: {2} + page: {} + config: {} + exception: {} """.format( page, json_config, e ) diff --git a/frappe/desk/doctype/bulk_update/bulk_update.py b/frappe/desk/doctype/bulk_update/bulk_update.py index dc0a88178d..1e515bbc47 100644 --- a/frappe/desk/doctype/bulk_update/bulk_update.py +++ b/frappe/desk/doctype/bulk_update/bulk_update.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies and contributors # License: MIT. See LICENSE @@ -24,7 +23,7 @@ def update(doctype, field, value, condition="", limit=500): frappe.throw(_("; not allowed in condition")) docnames = frappe.db.sql_list( - """select name from `tab{0}`{1} limit {2} offset 0""".format(doctype, condition, limit) + f"""select name from `tab{doctype}`{condition} limit {limit} offset 0""" ) data = {} data[field] = value diff --git a/frappe/desk/doctype/calendar_view/calendar_view.py b/frappe/desk/doctype/calendar_view/calendar_view.py index 01968e835d..1e187682ec 100644 --- a/frappe/desk/doctype/calendar_view/calendar_view.py +++ b/frappe/desk/doctype/calendar_view/calendar_view.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2017, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/desk/doctype/console_log/console_log.py b/frappe/desk/doctype/console_log/console_log.py index ebe93f535d..7e20afb22f 100644 --- a/frappe/desk/doctype/console_log/console_log.py +++ b/frappe/desk/doctype/console_log/console_log.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2020, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/desk/doctype/console_log/test_console_log.py b/frappe/desk/doctype/console_log/test_console_log.py index 409ac88299..0579098382 100644 --- a/frappe/desk/doctype/console_log/test_console_log.py +++ b/frappe/desk/doctype/console_log/test_console_log.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2020, Frappe Technologies and Contributors # License: MIT. See LICENSE # import frappe diff --git a/frappe/desk/doctype/dashboard/dashboard.py b/frappe/desk/doctype/dashboard/dashboard.py index 61e997836c..960431d220 100644 --- a/frappe/desk/doctype/dashboard/dashboard.py +++ b/frappe/desk/doctype/dashboard/dashboard.py @@ -115,7 +115,7 @@ def get_non_standard_warning_message(non_standard_docs_map): message = _("""Please set the following documents in this Dashboard as standard first.""") def get_html(docs, doctype): - html = "

{}

".format(frappe.bold(doctype)) + html = f"

{frappe.bold(doctype)}

" for doc in docs: html += '
{doc}
'.format( doctype=doctype, doc=doc diff --git a/frappe/desk/doctype/dashboard/test_dashboard.py b/frappe/desk/doctype/dashboard/test_dashboard.py index ee3d1848e2..d2ba871509 100644 --- a/frappe/desk/doctype/dashboard/test_dashboard.py +++ b/frappe/desk/doctype/dashboard/test_dashboard.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and Contributors # License: MIT. See LICENSE import unittest diff --git a/frappe/desk/doctype/dashboard_chart/dashboard_chart.py b/frappe/desk/doctype/dashboard_chart/dashboard_chart.py index ca29bad33b..1145873a09 100644 --- a/frappe/desk/doctype/dashboard_chart/dashboard_chart.py +++ b/frappe/desk/doctype/dashboard_chart/dashboard_chart.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and contributors # License: MIT. See LICENSE @@ -212,7 +211,7 @@ def get_chart_config(chart, filters, timespan, timegrain, from_date, to_date): data = frappe.db.get_list( doctype, - fields=["{} as _unit".format(datefield), "SUM({})".format(value_field), "COUNT(*)"], + fields=[f"{datefield} as _unit", f"SUM({value_field})", "COUNT(*)"], filters=filters, group_by="_unit", order_by="_unit asc", @@ -242,13 +241,13 @@ def get_heatmap_chart_config(chart, filters, heatmap_year): year_start_date = datetime.date(year, 1, 1).strftime("%Y-%m-%d") next_year_start_date = datetime.date(year + 1, 1, 1).strftime("%Y-%m-%d") - filters.append([doctype, datefield, ">", "{date}".format(date=year_start_date), False]) - filters.append([doctype, datefield, "<", "{date}".format(date=next_year_start_date), False]) + filters.append([doctype, datefield, ">", f"{year_start_date}", False]) + filters.append([doctype, datefield, "<", f"{next_year_start_date}", False]) if frappe.db.db_type == "mariadb": - timestamp_field = "unix_timestamp({datefield})".format(datefield=datefield) + timestamp_field = f"unix_timestamp({datefield})" else: - timestamp_field = "extract(epoch from timestamp {datefield})".format(datefield=datefield) + timestamp_field = f"extract(epoch from timestamp {datefield})" data = dict( frappe.db.get_all( @@ -260,9 +259,9 @@ def get_heatmap_chart_config(chart, filters, heatmap_year): ), ], filters=filters, - group_by="date({datefield})".format(datefield=datefield), + group_by=f"date({datefield})", as_list=1, - order_by="{datefield} asc".format(datefield=datefield), + order_by=f"{datefield} asc", ignore_ifnull=True, ) ) @@ -284,7 +283,7 @@ def get_group_by_chart_config(chart, filters): data = frappe.db.get_list( doctype, fields=[ - "{} as name".format(group_by_field), + f"{group_by_field} as name", "{aggregate_function}({value_field}) as count".format( aggregate_function=aggregate_function, value_field=value_field ), @@ -351,7 +350,7 @@ def get_charts_for_user(doctype, txt, searchfield, start, page_len, filters): class DashboardChart(Document): def on_update(self): - frappe.cache().delete_key("chart-data:{}".format(self.name)) + frappe.cache().delete_key(f"chart-data:{self.name}") if frappe.conf.developer_mode and self.is_standard: export_to_files(record_list=[["Dashboard Chart", self.name]], record_module=self.module) diff --git a/frappe/desk/doctype/dashboard_chart/test_dashboard_chart.py b/frappe/desk/doctype/dashboard_chart/test_dashboard_chart.py index ca84b2c301..820f3c0555 100644 --- a/frappe/desk/doctype/dashboard_chart/test_dashboard_chart.py +++ b/frappe/desk/doctype/dashboard_chart/test_dashboard_chart.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and Contributors # License: MIT. See LICENSE diff --git a/frappe/desk/doctype/dashboard_chart_field/dashboard_chart_field.py b/frappe/desk/doctype/dashboard_chart_field/dashboard_chart_field.py index 41f35d2ee4..adc03663a2 100644 --- a/frappe/desk/doctype/dashboard_chart_field/dashboard_chart_field.py +++ b/frappe/desk/doctype/dashboard_chart_field/dashboard_chart_field.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2020, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/desk/doctype/dashboard_chart_link/dashboard_chart_link.py b/frappe/desk/doctype/dashboard_chart_link/dashboard_chart_link.py index b2a7caefeb..4d98b69458 100644 --- a/frappe/desk/doctype/dashboard_chart_link/dashboard_chart_link.py +++ b/frappe/desk/doctype/dashboard_chart_link/dashboard_chart_link.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/desk/doctype/dashboard_chart_source/dashboard_chart_source.py b/frappe/desk/doctype/dashboard_chart_source/dashboard_chart_source.py index 155a71a9b4..5519ad9097 100644 --- a/frappe/desk/doctype/dashboard_chart_source/dashboard_chart_source.py +++ b/frappe/desk/doctype/dashboard_chart_source/dashboard_chart_source.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and contributors # License: MIT. See LICENSE @@ -17,7 +16,6 @@ def get_config(name): os.path.join( get_module_path(doc.module), "dashboard_chart_source", scrub(doc.name), scrub(doc.name) + ".js" ), - "r", ) as f: return f.read() diff --git a/frappe/desk/doctype/dashboard_chart_source/test_dashboard_chart_source.py b/frappe/desk/doctype/dashboard_chart_source/test_dashboard_chart_source.py index 0c219c08cc..457487bb6d 100644 --- a/frappe/desk/doctype/dashboard_chart_source/test_dashboard_chart_source.py +++ b/frappe/desk/doctype/dashboard_chart_source/test_dashboard_chart_source.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and Contributors # License: MIT. See LICENSE import unittest diff --git a/frappe/desk/doctype/dashboard_settings/dashboard_settings.py b/frappe/desk/doctype/dashboard_settings/dashboard_settings.py index 01c3a87f20..489beda0bf 100644 --- a/frappe/desk/doctype/dashboard_settings/dashboard_settings.py +++ b/frappe/desk/doctype/dashboard_settings/dashboard_settings.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2020, Frappe Technologies and contributors # License: MIT. See LICENSE @@ -28,7 +27,7 @@ def get_permission_query_conditions(user): if not user: user = frappe.session.user - return """(`tabDashboard Settings`.name = {user})""".format(user=frappe.db.escape(user)) + return f"""(`tabDashboard Settings`.name = {frappe.db.escape(user)})""" @frappe.whitelist() diff --git a/frappe/desk/doctype/desktop_icon/desktop_icon.py b/frappe/desk/doctype/desktop_icon/desktop_icon.py index 29de1f56d9..5602f4da24 100644 --- a/frappe/desk/doctype/desktop_icon/desktop_icon.py +++ b/frappe/desk/doctype/desktop_icon/desktop_icon.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors # License: MIT. See LICENSE @@ -133,7 +132,7 @@ def add_user_icon(_doctype, _report=None, label=None, link=None, type="link", st if not label: label = _doctype or _report if not link: - link = "List/{0}".format(_doctype) + link = f"List/{_doctype}" # find if a standard icon exists icon_name = frappe.db.exists( diff --git a/frappe/desk/doctype/event/event.py b/frappe/desk/doctype/event/event.py index 6fdc95d3d0..e9104ef897 100644 --- a/frappe/desk/doctype/event/event.py +++ b/frappe/desk/doctype/event/event.py @@ -161,9 +161,9 @@ def delete_communication(event, reference_doctype, reference_docname): def get_permission_query_conditions(user): if not user: user = frappe.session.user - return """(`tabEvent`.`event_type`='Public' or `tabEvent`.`owner`=%(user)s)""" % { - "user": frappe.db.escape(user), - } + return """(`tabEvent`.`event_type`='Public' or `tabEvent`.`owner`={user})""".format( + user=frappe.db.escape(user), + ) def has_permission(doc, user): diff --git a/frappe/desk/doctype/event/test_event.py b/frappe/desk/doctype/event/test_event.py index 041bda643e..efbd54fb09 100644 --- a/frappe/desk/doctype/event/test_event.py +++ b/frappe/desk/doctype/event/test_event.py @@ -96,7 +96,7 @@ class TestEvent(unittest.TestCase): ev = frappe.get_doc("Event", ev.name) - self.assertEqual(set(json.loads(ev._assign)), set(["test@example.com", self.test_user])) + self.assertEqual(set(json.loads(ev._assign)), {"test@example.com", self.test_user}) # Remove an assignment todo = frappe.get_doc( diff --git a/frappe/desk/doctype/event_participants/event_participants.py b/frappe/desk/doctype/event_participants/event_participants.py index fdb834b285..869ae4092b 100644 --- a/frappe/desk/doctype/event_participants/event_participants.py +++ b/frappe/desk/doctype/event_participants/event_participants.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2018, Frappe Technologies and contributors # License: MIT. See LICENSE from frappe.model.document import Document diff --git a/frappe/desk/doctype/global_search_doctype/global_search_doctype.py b/frappe/desk/doctype/global_search_doctype/global_search_doctype.py index 8bdc05cd71..48fdb3d4d1 100644 --- a/frappe/desk/doctype/global_search_doctype/global_search_doctype.py +++ b/frappe/desk/doctype/global_search_doctype/global_search_doctype.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/desk/doctype/global_search_settings/global_search_settings.py b/frappe/desk/doctype/global_search_settings/global_search_settings.py index b7ffd7faf7..4e2b1e85f9 100644 --- a/frappe/desk/doctype/global_search_settings/global_search_settings.py +++ b/frappe/desk/doctype/global_search_settings/global_search_settings.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/desk/doctype/kanban_board/kanban_board.py b/frappe/desk/doctype/kanban_board/kanban_board.py index bc47bbbaf4..83f0f46df0 100644 --- a/frappe/desk/doctype/kanban_board/kanban_board.py +++ b/frappe/desk/doctype/kanban_board/kanban_board.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies and contributors # License: MIT. See LICENSE @@ -126,7 +125,7 @@ def update_order_for_single_card( if from_colname == to_colname: from_col_order = to_col_order - to_col_order.insert(new_index, from_col_order.pop((old_index))) + to_col_order.insert(new_index, from_col_order.pop(old_index)) # save updated order board.columns[from_col_idx].order = frappe.as_json(from_col_order) @@ -173,7 +172,7 @@ def quick_kanban_board(doctype, board_name, field_name, project=None): doc.field_name = field_name if project: - doc.filters = '[["Task","project","=","{0}"]]'.format(project) + doc.filters = f'[["Task","project","=","{project}"]]' options = "" for field in meta.fields: diff --git a/frappe/desk/doctype/kanban_board/test_kanban_board.py b/frappe/desk/doctype/kanban_board/test_kanban_board.py index d4504bf9d8..73f566b906 100644 --- a/frappe/desk/doctype/kanban_board/test_kanban_board.py +++ b/frappe/desk/doctype/kanban_board/test_kanban_board.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies and Contributors # License: MIT. See LICENSE import unittest diff --git a/frappe/desk/doctype/kanban_board_column/kanban_board_column.py b/frappe/desk/doctype/kanban_board_column/kanban_board_column.py index d905369a0b..e57d92857e 100644 --- a/frappe/desk/doctype/kanban_board_column/kanban_board_column.py +++ b/frappe/desk/doctype/kanban_board_column/kanban_board_column.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/desk/doctype/list_filter/list_filter.py b/frappe/desk/doctype/list_filter/list_filter.py index a5ba12df6a..e4c59ee9e4 100644 --- a/frappe/desk/doctype/list_filter/list_filter.py +++ b/frappe/desk/doctype/list_filter/list_filter.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2018, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/desk/doctype/list_view_settings/list_view_settings.py b/frappe/desk/doctype/list_view_settings/list_view_settings.py index 7d25f57acf..36ebce34d5 100644 --- a/frappe/desk/doctype/list_view_settings/list_view_settings.py +++ b/frappe/desk/doctype/list_view_settings/list_view_settings.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2020, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/desk/doctype/list_view_settings/test_list_view_settings.py b/frappe/desk/doctype/list_view_settings/test_list_view_settings.py index 0b6a0773e3..0eab9cd7a6 100644 --- a/frappe/desk/doctype/list_view_settings/test_list_view_settings.py +++ b/frappe/desk/doctype/list_view_settings/test_list_view_settings.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and Contributors # License: MIT. See LICENSE # import frappe diff --git a/frappe/desk/doctype/module_onboarding/module_onboarding.py b/frappe/desk/doctype/module_onboarding/module_onboarding.py index 7a12328ee0..ea02f5911d 100644 --- a/frappe/desk/doctype/module_onboarding/module_onboarding.py +++ b/frappe/desk/doctype/module_onboarding/module_onboarding.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2020, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/desk/doctype/module_onboarding/test_module_onboarding.py b/frappe/desk/doctype/module_onboarding/test_module_onboarding.py index 8def3ac40e..fa19794c1e 100644 --- a/frappe/desk/doctype/module_onboarding/test_module_onboarding.py +++ b/frappe/desk/doctype/module_onboarding/test_module_onboarding.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2020, Frappe Technologies and Contributors # License: MIT. See LICENSE # import frappe diff --git a/frappe/desk/doctype/note/note.py b/frappe/desk/doctype/note/note.py index a709b80f1d..c0a37d5f44 100644 --- a/frappe/desk/doctype/note/note.py +++ b/frappe/desk/doctype/note/note.py @@ -40,7 +40,7 @@ def get_permission_query_conditions(user): if user == "Administrator": return "" - return """(`tabNote`.public=1 or `tabNote`.owner={user})""".format(user=frappe.db.escape(user)) + return f"""(`tabNote`.public=1 or `tabNote`.owner={frappe.db.escape(user)})""" def has_permission(doc, ptype, user): diff --git a/frappe/desk/doctype/note_seen_by/note_seen_by.py b/frappe/desk/doctype/note_seen_by/note_seen_by.py index 7dde133e6d..5acdca222e 100644 --- a/frappe/desk/doctype/note_seen_by/note_seen_by.py +++ b/frappe/desk/doctype/note_seen_by/note_seen_by.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/desk/doctype/notification_log/notification_log.py b/frappe/desk/doctype/notification_log/notification_log.py index def626513c..3d16bdf32f 100644 --- a/frappe/desk/doctype/notification_log/notification_log.py +++ b/frappe/desk/doctype/notification_log/notification_log.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and contributors # License: MIT. See LICENSE @@ -29,7 +28,7 @@ def get_permission_query_conditions(for_user): if for_user == "Administrator": return - return """(`tabNotification Log`.for_user = {user})""".format(user=frappe.db.escape(for_user)) + return f"""(`tabNotification Log`.for_user = {frappe.db.escape(for_user)})""" def get_title(doctype, docname, title_field=None): @@ -40,7 +39,7 @@ def get_title(doctype, docname, title_field=None): def get_title_html(title): - return '{0}'.format(title) + return f'{title}' def enqueue_create_notification(users, doc): diff --git a/frappe/desk/doctype/notification_log/test_notification_log.py b/frappe/desk/doctype/notification_log/test_notification_log.py index 44b1b53ead..532f05ab57 100644 --- a/frappe/desk/doctype/notification_log/test_notification_log.py +++ b/frappe/desk/doctype/notification_log/test_notification_log.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and Contributors # License: MIT. See LICENSE import unittest diff --git a/frappe/desk/doctype/notification_settings/notification_settings.py b/frappe/desk/doctype/notification_settings/notification_settings.py index 2bf7347a4f..801d512fe7 100644 --- a/frappe/desk/doctype/notification_settings/notification_settings.py +++ b/frappe/desk/doctype/notification_settings/notification_settings.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and contributors # License: MIT. See LICENSE @@ -88,7 +87,7 @@ def get_permission_query_conditions(user): if "System Manager" in roles: return """(`tabNotification Settings`.name != 'Administrator')""" - return """(`tabNotification Settings`.name = {user})""".format(user=frappe.db.escape(user)) + return f"""(`tabNotification Settings`.name = {frappe.db.escape(user)})""" @frappe.whitelist() diff --git a/frappe/desk/doctype/notification_subscribed_document/notification_subscribed_document.py b/frappe/desk/doctype/notification_subscribed_document/notification_subscribed_document.py index b72f827cd7..551ee6dc85 100644 --- a/frappe/desk/doctype/notification_subscribed_document/notification_subscribed_document.py +++ b/frappe/desk/doctype/notification_subscribed_document/notification_subscribed_document.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/desk/doctype/number_card/number_card.py b/frappe/desk/doctype/number_card/number_card.py index 74c8e9eb99..1bffd68940 100644 --- a/frappe/desk/doctype/number_card/number_card.py +++ b/frappe/desk/doctype/number_card/number_card.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2020, Frappe Technologies and contributors # License: MIT. See LICENSE @@ -120,7 +119,7 @@ def get_result(doc, filters, to_date=None): function = sql_function_map[doc.function] if function == "count": - fields = ["{function}(*) as result".format(function=function)] + fields = [f"{function}(*) as result"] else: fields = [ "{function}({based_on}) as result".format( @@ -202,7 +201,7 @@ def get_cards_for_user(doctype, txt, searchfield, start, page_len, filters): numberCard = DocType("Number Card") if txt: - search_conditions = [numberCard[field].like("%{txt}%".format(txt=txt)) for field in searchfields] + search_conditions = [numberCard[field].like(f"%{txt}%") for field in searchfields] condition_query = frappe.db.query.build_conditions(doctype, filters) diff --git a/frappe/desk/doctype/number_card/test_number_card.py b/frappe/desk/doctype/number_card/test_number_card.py index 817ea2fad4..c0dda40104 100644 --- a/frappe/desk/doctype/number_card/test_number_card.py +++ b/frappe/desk/doctype/number_card/test_number_card.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2020, Frappe Technologies and Contributors # License: MIT. See LICENSE # import frappe diff --git a/frappe/desk/doctype/number_card_link/number_card_link.py b/frappe/desk/doctype/number_card_link/number_card_link.py index b630d7caa7..16cc7ba4e3 100644 --- a/frappe/desk/doctype/number_card_link/number_card_link.py +++ b/frappe/desk/doctype/number_card_link/number_card_link.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2020, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/desk/doctype/onboarding_permission/onboarding_permission.py b/frappe/desk/doctype/onboarding_permission/onboarding_permission.py index a0e87c3067..d7db13762a 100644 --- a/frappe/desk/doctype/onboarding_permission/onboarding_permission.py +++ b/frappe/desk/doctype/onboarding_permission/onboarding_permission.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2020, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/desk/doctype/onboarding_permission/test_onboarding_permission.py b/frappe/desk/doctype/onboarding_permission/test_onboarding_permission.py index 9a12b0aab9..cdfe0d7890 100644 --- a/frappe/desk/doctype/onboarding_permission/test_onboarding_permission.py +++ b/frappe/desk/doctype/onboarding_permission/test_onboarding_permission.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2020, Frappe Technologies and Contributors # License: MIT. See LICENSE # import frappe diff --git a/frappe/desk/doctype/onboarding_step/onboarding_step.py b/frappe/desk/doctype/onboarding_step/onboarding_step.py index 4a4d487cc8..b6807b62bd 100644 --- a/frappe/desk/doctype/onboarding_step/onboarding_step.py +++ b/frappe/desk/doctype/onboarding_step/onboarding_step.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2020, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/desk/doctype/onboarding_step/test_onboarding_step.py b/frappe/desk/doctype/onboarding_step/test_onboarding_step.py index 2342656a72..d8bf55584c 100644 --- a/frappe/desk/doctype/onboarding_step/test_onboarding_step.py +++ b/frappe/desk/doctype/onboarding_step/test_onboarding_step.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2020, Frappe Technologies and Contributors # License: MIT. See LICENSE # import frappe diff --git a/frappe/desk/doctype/onboarding_step_map/onboarding_step_map.py b/frappe/desk/doctype/onboarding_step_map/onboarding_step_map.py index 7c20e220db..8844316e68 100644 --- a/frappe/desk/doctype/onboarding_step_map/onboarding_step_map.py +++ b/frappe/desk/doctype/onboarding_step_map/onboarding_step_map.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2020, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/desk/doctype/system_console/system_console.py b/frappe/desk/doctype/system_console/system_console.py index 063b3d37d0..993af6e753 100644 --- a/frappe/desk/doctype/system_console/system_console.py +++ b/frappe/desk/doctype/system_console/system_console.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2020, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/desk/doctype/system_console/test_system_console.py b/frappe/desk/doctype/system_console/test_system_console.py index 372cbbc1f4..96bf555f59 100644 --- a/frappe/desk/doctype/system_console/test_system_console.py +++ b/frappe/desk/doctype/system_console/test_system_console.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2020, Frappe Technologies and Contributors # License: MIT. See LICENSE import unittest diff --git a/frappe/desk/doctype/tag/tag.py b/frappe/desk/doctype/tag/tag.py index aabf0351a5..ca167c148e 100644 --- a/frappe/desk/doctype/tag/tag.py +++ b/frappe/desk/doctype/tag/tag.py @@ -56,7 +56,7 @@ def get_tagged_docs(doctype, tag): @frappe.whitelist() def get_tags(doctype, txt): - tag = frappe.get_list("Tag", filters=[["name", "like", "%{}%".format(txt)]]) + tag = frappe.get_list("Tag", filters=[["name", "like", f"%{txt}%"]]) tags = [t.name for t in tag] return sorted(filter(lambda t: t and txt.lower() in t.lower(), list(set(tags)))) @@ -104,7 +104,7 @@ class DocTags: tags = "," + ",".join(tl) try: frappe.db.sql( - "update `tab%s` set _user_tags=%s where name=%s" % (self.dt, "%s", "%s"), (tags, dn) + "update `tab{}` set _user_tags={} where name={}".format(self.dt, "%s", "%s"), (tags, dn) ) doc = frappe.get_doc(self.dt, dn) update_tags(doc, tags) diff --git a/frappe/desk/doctype/tag_link/tag_link.py b/frappe/desk/doctype/tag_link/tag_link.py index ec816352ca..a67e6a62d3 100644 --- a/frappe/desk/doctype/tag_link/tag_link.py +++ b/frappe/desk/doctype/tag_link/tag_link.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/desk/doctype/tag_link/test_tag_link.py b/frappe/desk/doctype/tag_link/test_tag_link.py index d4d1dd61fa..59d7bcd2bc 100644 --- a/frappe/desk/doctype/tag_link/test_tag_link.py +++ b/frappe/desk/doctype/tag_link/test_tag_link.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and Contributors # License: MIT. See LICENSE # import frappe diff --git a/frappe/desk/doctype/todo/test_todo.py b/frappe/desk/doctype/todo/test_todo.py index 5c54889e00..56ca1f30e7 100644 --- a/frappe/desk/doctype/todo/test_todo.py +++ b/frappe/desk/doctype/todo/test_todo.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors # License: MIT. See LICENSE import unittest diff --git a/frappe/desk/doctype/workspace/test_workspace.py b/frappe/desk/doctype/workspace/test_workspace.py index 9281240e08..d0b0eba9e2 100644 --- a/frappe/desk/doctype/workspace/test_workspace.py +++ b/frappe/desk/doctype/workspace/test_workspace.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2020, Frappe Technologies and Contributors # License: MIT. See LICENSE import unittest diff --git a/frappe/desk/doctype/workspace/workspace.py b/frappe/desk/doctype/workspace/workspace.py index 284fecbe31..9fa99884fb 100644 --- a/frappe/desk/doctype/workspace/workspace.py +++ b/frappe/desk/doctype/workspace/workspace.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2020, Frappe Technologies and contributors # License: MIT. See LICENSE @@ -206,7 +205,7 @@ def update_page(name, title, icon, parent, public): doc.sequence_id = frappe.db.count("Workspace", {"public": public}, cache=True) doc.public = public doc.for_user = "" if public else doc.for_user or frappe.session.user - doc.label = new_name = "{0}-{1}".format(title, doc.for_user) if doc.for_user else title + doc.label = new_name = f"{title}-{doc.for_user}" if doc.for_user else title doc.save(ignore_permissions=True) if name != new_name: @@ -221,9 +220,7 @@ def update_page(name, title, icon, parent, public): child_doc.public = public child_doc.for_user = "" if public else child_doc.for_user or frappe.session.user child_doc.label = new_child_name = ( - "{0}-{1}".format(child_doc.title, child_doc.for_user) - if child_doc.for_user - else child_doc.title + f"{child_doc.title}-{child_doc.for_user}" if child_doc.for_user else child_doc.title ) child_doc.save(ignore_permissions=True) @@ -253,7 +250,7 @@ def duplicate_page(page_name, new_page): doc.label = doc.title if not doc.public: doc.for_user = doc.for_user or frappe.session.user - doc.label = "{0}-{1}".format(doc.title, doc.for_user) + doc.label = f"{doc.title}-{doc.for_user}" doc.name = doc.label if old_doc.public == doc.public: doc.sequence_id += 0.1 diff --git a/frappe/desk/doctype/workspace_chart/workspace_chart.py b/frappe/desk/doctype/workspace_chart/workspace_chart.py index e02cf06ee0..45f4229401 100644 --- a/frappe/desk/doctype/workspace_chart/workspace_chart.py +++ b/frappe/desk/doctype/workspace_chart/workspace_chart.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2021, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/desk/doctype/workspace_link/workspace_link.py b/frappe/desk/doctype/workspace_link/workspace_link.py index 5e55a7c2bd..5756846f38 100644 --- a/frappe/desk/doctype/workspace_link/workspace_link.py +++ b/frappe/desk/doctype/workspace_link/workspace_link.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2021, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/desk/doctype/workspace_shortcut/workspace_shortcut.py b/frappe/desk/doctype/workspace_shortcut/workspace_shortcut.py index 4ca86c8146..49ba37854c 100644 --- a/frappe/desk/doctype/workspace_shortcut/workspace_shortcut.py +++ b/frappe/desk/doctype/workspace_shortcut/workspace_shortcut.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2021, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/desk/form/assign_to.py b/frappe/desk/form/assign_to.py index 4107f95827..7853e807b8 100644 --- a/frappe/desk/form/assign_to.py +++ b/frappe/desk/form/assign_to.py @@ -217,7 +217,7 @@ def notify_assignment( # Search for email address in description -- i.e. assignee user_name = frappe.get_cached_value("User", frappe.session.user, "full_name") title = get_title(doc_type, doc_name) - description_html = "
{0}
".format(description) if description else None + description_html = f"
{description}
" if description else None if action == "CLOSE": subject = _("Your assignment on {0} {1} has been removed by {2}").format( diff --git a/frappe/desk/form/document_follow.py b/frappe/desk/form/document_follow.py index 527b9da036..86bd712926 100644 --- a/frappe/desk/form/document_follow.py +++ b/frappe/desk/form/document_follow.py @@ -192,9 +192,9 @@ def get_comments(doctype, doc_name, frequency, user): ) for comment in comments: if comment.comment_type == "Like": - by = """ By : {0}""".format(comment.modified_by) + by = f""" By : {comment.modified_by}""" elif comment.comment_type == "Comment": - by = """Commented by : {0}""".format(comment.modified_by) + by = f"""Commented by : {comment.modified_by}""" else: by = "" diff --git a/frappe/desk/form/linked_with.py b/frappe/desk/form/linked_with.py index 7a53c8b65a..b60c11774f 100644 --- a/frappe/desk/form/linked_with.py +++ b/frappe/desk/form/linked_with.py @@ -4,7 +4,6 @@ import itertools import json from collections import defaultdict -from typing import Dict, List, Optional import frappe import frappe.desk.form.load @@ -15,7 +14,7 @@ from frappe.modules import load_doctype_module @frappe.whitelist() -def get_submitted_linked_docs(doctype: str, name: str) -> List[tuple]: +def get_submitted_linked_docs(doctype: str, name: str) -> list[tuple]: """Get all the nested submitted documents those are present in referencing tables (dependent tables). :param doctype: Document type @@ -134,14 +133,14 @@ class SubmittableDocumentTree: """limit doctype links to these doctypes.""" return list(set(self.get_submittable_doctypes()) - set(get_exempted_doctypes() or [])) - def get_submittable_doctypes(self) -> List[str]: + def get_submittable_doctypes(self) -> list[str]: """Returns list of submittable doctypes.""" if not self._submittable_doctypes: self._submittable_doctypes = frappe.db.get_all("DocType", {"is_submittable": 1}, pluck="name") return self._submittable_doctypes -def get_child_tables_of_doctypes(doctypes: List[str] = None): +def get_child_tables_of_doctypes(doctypes: list[str] = None): """Returns child tables by doctype.""" filters = [["fieldtype", "=", "Table"]] filters_for_docfield = filters @@ -174,8 +173,8 @@ def get_child_tables_of_doctypes(doctypes: List[str] = None): def get_references_across_doctypes( - to_doctypes: List[str] = None, limit_link_doctypes: List[str] = None -) -> List: + to_doctypes: list[str] = None, limit_link_doctypes: list[str] = None +) -> list: """Find doctype wise foreign key references. :param to_doctypes: Get links of these doctypes. @@ -213,7 +212,7 @@ def get_references_across_doctypes( def get_references_across_doctypes_by_link_field( - to_doctypes: List[str] = None, limit_link_doctypes: List[str] = None + to_doctypes: list[str] = None, limit_link_doctypes: list[str] = None ): """Find doctype wise foreign key references based on link fields. @@ -253,7 +252,7 @@ def get_references_across_doctypes_by_link_field( def get_references_across_doctypes_by_dynamic_link_field( - to_doctypes: List[str] = None, limit_link_doctypes: List[str] = None + to_doctypes: list[str] = None, limit_link_doctypes: list[str] = None ): """Find doctype wise foreign key references based on dynamic link fields. @@ -304,10 +303,10 @@ def get_references_across_doctypes_by_dynamic_link_field( def get_referencing_documents( reference_doctype: str, - reference_names: List[str], + reference_names: list[str], link_info: dict, get_parent_if_child_table_doc: bool = True, - parent_filters: List[list] = None, + parent_filters: list[list] = None, child_filters=None, allowed_parents=None, ): @@ -340,7 +339,7 @@ def get_referencing_documents( for parent, rows in itertools.groupby(res, key=lambda row: row["parenttype"]): if allowed_parents and parent not in allowed_parents: continue - filters = (parent_filters or []) + [["name", "in", tuple([row.parent for row in rows])]] + filters = (parent_filters or []) + [["name", "in", tuple(row.parent for row in rows)]] documents[parent].extend(frappe.db.get_all(parent, filters=filters, pluck="name") or []) return documents @@ -407,7 +406,7 @@ def get_exempted_doctypes(): @frappe.whitelist() -def get_linked_docs(doctype: str, name: str, linkinfo: Optional[Dict] = None) -> Dict[str, List]: +def get_linked_docs(doctype: str, name: str, linkinfo: dict | None = None) -> dict[str, list]: if isinstance(linkinfo, str): # additional fields are added in linkinfo linkinfo = json.loads(linkinfo) @@ -447,9 +446,7 @@ def get_linked_docs(doctype: str, name: str, linkinfo: Optional[Dict] = None) -> if link.get("add_fields"): fields += link["add_fields"] - fields = [ - "`tab{dt}`.`{fn}`".format(dt=dt, fn=sf.strip()) for sf in fields if sf and "`tab" not in sf - ] + fields = [f"`tab{dt}`.`{sf.strip()}`" for sf in fields if sf and "`tab" not in sf] try: if link.get("filters"): diff --git a/frappe/desk/form/load.py b/frappe/desk/form/load.py index 5a6004652e..9e3a850bb0 100644 --- a/frappe/desk/form/load.py +++ b/frappe/desk/form/load.py @@ -2,7 +2,6 @@ # License: MIT. See LICENSE import json -from typing import List, Union from urllib.parse import quote import frappe @@ -218,8 +217,8 @@ def get_communications(doctype, name, start=0, limit=20): def get_comments( - doctype: str, name: str, comment_type: Union[str, List[str]] = "Comment" -) -> List[frappe._dict]: + doctype: str, name: str, comment_type: str | list[str] = "Comment" +) -> list[frappe._dict]: if isinstance(comment_type, list): comment_types = comment_type @@ -294,7 +293,7 @@ def get_communication_data( if after: # find after a particular date conditions += """ - AND C.creation > {0} + AND C.creation > {} """.format( after ) @@ -411,7 +410,7 @@ def get_document_email(doctype, name): return None email = email.split("@") - return "{0}+{1}+{2}@{3}".format(email[0], quote(doctype), quote(cstr(name)), email[1]) + return f"{email[0]}+{quote(doctype)}+{quote(cstr(name))}@{email[1]}" def get_automatic_email_link(): diff --git a/frappe/desk/form/meta.py b/frappe/desk/form/meta.py index dc26dfe5b0..5a426b4c63 100644 --- a/frappe/desk/form/meta.py +++ b/frappe/desk/form/meta.py @@ -52,7 +52,7 @@ def get_meta(doctype, cached=True): class FormMeta(Meta): def __init__(self, doctype): - super(FormMeta, self).__init__(doctype) + super().__init__(doctype) self.load_assets() def load_assets(self): @@ -74,7 +74,7 @@ class FormMeta(Meta): self.set("__assets_loaded", True) def as_dict(self, no_nulls=False): - d = super(FormMeta, self).as_dict(no_nulls=no_nulls) + d = super().as_dict(no_nulls=no_nulls) for k in ASSET_KEYS: d[k] = self.get(k) @@ -133,7 +133,7 @@ class FormMeta(Meta): templates = dict() for fname in os.listdir(path): if fname.endswith(".html"): - with io.open(os.path.join(path, fname), "r", encoding="utf-8") as f: + with open(os.path.join(path, fname), encoding="utf-8") as f: templates[fname.split(".")[0]] = scrub_html_template(f.read()) self.set("__templates", templates or None) diff --git a/frappe/desk/form/utils.py b/frappe/desk/form/utils.py index 573ec17979..9e10ced912 100644 --- a/frappe/desk/form/utils.py +++ b/frappe/desk/form/utils.py @@ -85,7 +85,7 @@ def get_next(doctype, value, prev, filters=None, sort_order="desc", sort_field=" doctype, fields=["name"], filters=filters, - order_by="`tab{0}`.{1}".format(doctype, sort_field) + " " + sort_order, + order_by=f"`tab{doctype}`.{sort_field}" + " " + sort_order, limit_start=0, limit_page_length=1, as_list=True, diff --git a/frappe/desk/like.py b/frappe/desk/like.py index 9e97cb269c..0f297455e7 100644 --- a/frappe/desk/like.py +++ b/frappe/desk/like.py @@ -90,7 +90,7 @@ def add_comment(doctype, name): link = get_link_to_form( doc.reference_doctype, doc.reference_name, - "{0} {1}".format(_(doc.reference_doctype), doc.reference_name), + f"{_(doc.reference_doctype)} {doc.reference_name}", ) doc.add_comment( diff --git a/frappe/desk/listview.py b/frappe/desk/listview.py index 5149f8bf86..d48a7f3de4 100644 --- a/frappe/desk/listview.py +++ b/frappe/desk/listview.py @@ -1,6 +1,5 @@ # Copyright (c) 2022, Frappe Technologies Pvt. Ltd. and Contributors # License: MIT. See LICENSE -from typing import Dict, List import frappe from frappe.query_builder import Order @@ -30,7 +29,7 @@ def set_list_settings(doctype, values): @frappe.whitelist() -def get_group_by_count(doctype: str, current_filters: str, field: str) -> List[Dict]: +def get_group_by_count(doctype: str, current_filters: str, field: str) -> list[dict]: current_filters = frappe.parse_json(current_filters) if field == "assigned_to": diff --git a/frappe/desk/moduleview.py b/frappe/desk/moduleview.py index a4fc2ccd1e..913b3406e3 100644 --- a/frappe/desk/moduleview.py +++ b/frappe/desk/moduleview.py @@ -253,13 +253,13 @@ def apply_permissions(data): def get_disabled_reports(): if not hasattr(frappe.local, "disabled_reports"): - frappe.local.disabled_reports = set(r.name for r in frappe.get_all("Report", {"disabled": 1})) + frappe.local.disabled_reports = {r.name for r in frappe.get_all("Report", {"disabled": 1})} return frappe.local.disabled_reports def get_config(app, module): """Load module info from `[app].config.[module]`.""" - config = frappe.get_module("{app}.config.{module}".format(app=app, module=module)) + config = frappe.get_module(f"{app}.config.{module}") config = config.get_data() sections = [s for s in config if s.get("condition", True)] @@ -283,7 +283,7 @@ def get_config(app, module): def config_exists(app, module): try: - frappe.get_module("{app}.config.{module}".format(app=app, module=module)) + frappe.get_module(f"{app}.config.{module}") return True except ImportError: return False diff --git a/frappe/desk/page/activity/__init__.py b/frappe/desk/page/activity/__init__.py index 8b13789179..e69de29bb2 100644 --- a/frappe/desk/page/activity/__init__.py +++ b/frappe/desk/page/activity/__init__.py @@ -1 +0,0 @@ - diff --git a/frappe/desk/page/backups/backups.py b/frappe/desk/page/backups/backups.py index ec5bea3c4b..2ef09df900 100644 --- a/frappe/desk/page/backups/backups.py +++ b/frappe/desk/page/backups/backups.py @@ -21,9 +21,9 @@ def get_context(context): def get_size(path): size = os.path.getsize(path) if size > 1048576: - return "{0:.1f}M".format(float(size) / 1048576) + return f"{float(size) / 1048576:.1f}M" else: - return "{0:.1f}K".format(float(size) / 1024) + return f"{float(size) / 1024:.1f}K" path = get_site_path("private", "backups") files = [x for x in os.listdir(path) if os.path.isfile(os.path.join(path, x))] diff --git a/frappe/desk/page/setup_wizard/setup_wizard.py b/frappe/desk/page/setup_wizard/setup_wizard.py index 8fc4b3f694..3422602720 100755 --- a/frappe/desk/page/setup_wizard/setup_wizard.py +++ b/frappe/desk/page/setup_wizard/setup_wizard.py @@ -339,11 +339,11 @@ def prettify_args(args): if isinstance(val, str) and "data:image" in val: filename = val.split("data:image", 1)[0].strip(", ") size = round((len(val) * 3 / 4) / 1048576.0, 2) - args[key] = "Image Attached: '{0}' of size {1} MB".format(filename, size) + args[key] = f"Image Attached: '{filename}' of size {size} MB" pretty_args = [] for key in sorted(args): - pretty_args.append("{} = {}".format(key, args[key])) + pretty_args.append(f"{key} = {args[key]}") return pretty_args @@ -386,7 +386,7 @@ def email_setup_wizard_exception(traceback, args): frappe.sendmail( recipients=frappe.conf.setup_wizard_exception_email, sender=frappe.session.user, - subject="Setup failed: {}".format(frappe.local.site), + subject=f"Setup failed: {frappe.local.site}", message=message, delayed=False, ) diff --git a/frappe/desk/query_report.py b/frappe/desk/query_report.py index a51fd8b1e3..29c8ed08d3 100644 --- a/frappe/desk/query_report.py +++ b/frappe/desk/query_report.py @@ -187,7 +187,7 @@ def get_script(report_name): script = None if os.path.exists(script_path): - with open(script_path, "r") as f: + with open(script_path) as f: script = f.read() script += f"\n\n//# sourceURL={scrub(report.name)}.js" diff --git a/frappe/desk/report/todo/todo.py b/frappe/desk/report/todo/todo.py index 7c566c74ea..e75b8d1900 100644 --- a/frappe/desk/report/todo/todo.py +++ b/frappe/desk/report/todo/todo.py @@ -46,7 +46,7 @@ def execute(filters=None): for todo in todo_list: if todo.owner == frappe.session.user or todo.assigned_by == frappe.session.user: if todo.reference_type: - todo.reference = """%s: %s""" % ( + todo.reference = """{}: {}""".format( todo.reference_type, todo.reference_name, todo.reference_type, diff --git a/frappe/desk/report_dump.py b/frappe/desk/report_dump.py index ac01cf892f..6650d24757 100644 --- a/frappe/desk/report_dump.py +++ b/frappe/desk/report_dump.py @@ -53,7 +53,7 @@ def get_data(doctypes, last_modified): out[dt]["data"] = [ list(t) for t in frappe.db.sql( - """select %s from %s %s %s""" % (",".join(args["columns"]), table, conditions, order_by) + """select {} from {} {} {}""".format(",".join(args["columns"]), table, conditions, order_by) ) ] diff --git a/frappe/desk/reportview.py b/frappe/desk/reportview.py index d6dce68399..caba0212b9 100644 --- a/frappe/desk/reportview.py +++ b/frappe/desk/reportview.py @@ -167,7 +167,7 @@ def setup_group_by(data): def raise_invalid_field(fieldname): - frappe.throw(_("Field not permitted in query") + ": {0}".format(fieldname), frappe.DataError) + frappe.throw(_("Field not permitted in query") + f": {fieldname}", frappe.DataError) def is_standard(fieldname): diff --git a/frappe/desk/search.py b/frappe/desk/search.py index eb1a2e82ba..8ae635093c 100644 --- a/frappe/desk/search.py +++ b/frappe/desk/search.py @@ -34,7 +34,7 @@ def sanitize_searchfield(searchfield): _raise_exception(searchfield) # to avoid and, or and like - elif any(" {0} ".format(keyword) in searchfield.split() for keyword in blacklisted_keywords): + elif any(f" {keyword} " in searchfield.split() for keyword in blacklisted_keywords): _raise_exception(searchfield) # to avoid select, delete, drop, update and case @@ -166,7 +166,7 @@ def search_widget( in ["Data", "Text", "Small Text", "Long Text", "Link", "Select", "Read Only", "Text Editor"] ) ): - or_filters.append([doctype, f.strip(), "like", "%{0}%".format(txt)]) + or_filters.append([doctype, f.strip(), "like", f"%{txt}%"]) if meta.get("fields", {"fieldname": "enabled", "fieldtype": "Check"}): filters.append([doctype, "enabled", "=", 1]) @@ -177,7 +177,7 @@ def search_widget( fields = get_std_fields_list(meta, searchfield or "name") if filter_fields: fields = list(set(fields + json.loads(filter_fields))) - formatted_fields = ["`tab%s`.`%s`" % (meta.name, f.strip()) for f in fields] + formatted_fields = [f"`tab{meta.name}`.`{f.strip()}`" for f in fields] title_field_query = get_title_field_query(meta) @@ -197,7 +197,7 @@ def search_widget( order_by_based_on_meta = get_order_by(doctype, meta) # 2 is the index of _relevance column - order_by = "_relevance, {0}, `tab{1}`.idx desc".format(order_by_based_on_meta, doctype) + order_by = f"_relevance, {order_by_based_on_meta}, `tab{doctype}`.idx desc" ptype = "select" if frappe.only_has_select_perm(doctype) else "read" ignore_permissions = ( @@ -270,7 +270,7 @@ def get_title_field_query(meta): field = None if title_field and show_title_field_in_link: - field = "`tab{0}`.{1} as `label`".format(meta.name, title_field) + field = f"`tab{meta.name}`.{title_field} as `label`" return field diff --git a/frappe/desk/treeview.py b/frappe/desk/treeview.py index d7a8db8792..f8b2a67c82 100644 --- a/frappe/desk/treeview.py +++ b/frappe/desk/treeview.py @@ -43,7 +43,7 @@ def get_children(doctype, parent="", **filters): def _get_children(doctype, parent="", ignore_permissions=False): parent_field = "parent_" + doctype.lower().replace(" ", "_") - filters = [["ifnull(`{0}`,'')".format(parent_field), "=", parent], ["docstatus", "<", 2]] + filters = [[f"ifnull(`{parent_field}`,'')", "=", parent], ["docstatus", "<", 2]] meta = frappe.get_meta(doctype) @@ -51,7 +51,7 @@ def _get_children(doctype, parent="", ignore_permissions=False): doctype, fields=[ "name as value", - "{0} as title".format(meta.get("title_field") or "name"), + "{} as title".format(meta.get("title_field") or "name"), "is_group as expandable", ], filters=filters, diff --git a/frappe/email/__init__.py b/frappe/email/__init__.py index 42fcb7b01a..0f0259653a 100644 --- a/frappe/email/__init__.py +++ b/frappe/email/__init__.py @@ -18,7 +18,7 @@ def get_contact_list(txt, page_length=20): return cached_contacts[:page_length] match_conditions = build_match_conditions("Contact") - match_conditions = "and {0}".format(match_conditions) if match_conditions else "" + match_conditions = f"and {match_conditions}" if match_conditions else "" out = frappe.db.sql( """select email_id as value, diff --git a/frappe/email/doctype/auto_email_report/auto_email_report.py b/frappe/email/doctype/auto_email_report/auto_email_report.py index 9f897a1308..b9b5e4e8d7 100644 --- a/frappe/email/doctype/auto_email_report/auto_email_report.py +++ b/frappe/email/doctype/auto_email_report/auto_email_report.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies and contributors # License: MIT. See LICENSE @@ -165,7 +164,7 @@ class AutoEmailReport(Document): ) def get_file_name(self): - return "{0}.{1}".format(self.report.replace(" ", "-").replace("/", "-"), self.format.lower()) + return "{}.{}".format(self.report.replace(" ", "-").replace("/", "-"), self.format.lower()) def prepare_dynamic_filters(self): self.filters = frappe.parse_json(self.filters) @@ -260,9 +259,7 @@ def send_daily(): try: auto_email_report.send() except Exception as e: - auto_email_report.log_error( - "Failed to send {0} Auto Email Report".format(auto_email_report.name) - ) + auto_email_report.log_error(f"Failed to send {auto_email_report.name} Auto Email Report") def send_monthly(): diff --git a/frappe/email/doctype/auto_email_report/test_auto_email_report.py b/frappe/email/doctype/auto_email_report/test_auto_email_report.py index aa8dffb9e0..ee0a363bd9 100644 --- a/frappe/email/doctype/auto_email_report/test_auto_email_report.py +++ b/frappe/email/doctype/auto_email_report/test_auto_email_report.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies and Contributors # License: MIT. See LICENSE import json diff --git a/frappe/email/doctype/document_follow/document_follow.py b/frappe/email/doctype/document_follow/document_follow.py index 3b7d411fb5..6f9d63f3be 100644 --- a/frappe/email/doctype/document_follow/document_follow.py +++ b/frappe/email/doctype/document_follow/document_follow.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/email/doctype/document_follow/test_document_follow.py b/frappe/email/doctype/document_follow/test_document_follow.py index 1f31338351..159a399ee8 100644 --- a/frappe/email/doctype/document_follow/test_document_follow.py +++ b/frappe/email/doctype/document_follow/test_document_follow.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and Contributors # License: MIT. See LICENSE import unittest diff --git a/frappe/email/doctype/email_account/email_account.py b/frappe/email/doctype/email_account/email_account.py index a89b9a2747..02afe4f4b5 100755 --- a/frappe/email/doctype/email_account/email_account.py +++ b/frappe/email/doctype/email_account/email_account.py @@ -8,7 +8,6 @@ import socket import time from datetime import datetime, timedelta from poplib import error_proto -from typing import List import frappe from frappe import _, are_emails_muted, safe_encode @@ -259,7 +258,7 @@ class EmailAccount(Document): else: frappe.throw(cstr(e)) - except socket.error: + except OSError: if in_receive: # timeout while connecting, see receive.py connect method description = frappe.message_log.pop() if frappe.message_log else "Socket Error" @@ -444,10 +443,10 @@ class EmailAccount(Document): frappe.cache().set_value("workers:no-internet", True) def set_failed_attempts_count(self, value): - frappe.cache().set("{0}:email-account-failed-attempts".format(self.name), value) + frappe.cache().set(f"{self.name}:email-account-failed-attempts", value) def get_failed_attempts_count(self): - return cint(frappe.cache().get("{0}:email-account-failed-attempts".format(self.name))) + return cint(frappe.cache().get(f"{self.name}:email-account-failed-attempts")) def receive(self): """Called by scheduler to receive emails from this EMail account using POP3/IMAP.""" @@ -485,7 +484,7 @@ class EmailAccount(Document): if exceptions: raise Exception(frappe.as_json(exceptions)) - def get_inbound_mails(self) -> List[InboundMail]: + def get_inbound_mails(self) -> list[InboundMail]: """retrive and return inbound mails.""" mails = [] @@ -595,7 +594,7 @@ class EmailAccount(Document): if self.email_sync_option == "ALL": max_uid = get_max_email_uid(self.name) last_uid = max_uid + int(self.initial_sync_count or 100) if max_uid == 1 else "*" - return "UID {}:{}".format(max_uid, last_uid) + return f"UID {max_uid}:{last_uid}" else: return self.email_sync_option or "UNSEEN" @@ -786,7 +785,7 @@ def pull(now=False): else: # job_name is used to prevent duplicates in queue - job_name = "pull_from_email_account|{0}".format(email_account.name) + job_name = f"pull_from_email_account|{email_account.name}" if job_name not in queued_jobs: enqueue( diff --git a/frappe/email/doctype/email_account/test_email_account.py b/frappe/email/doctype/email_account/test_email_account.py index 537bf9eb7f..9ab004cdd0 100644 --- a/frappe/email/doctype/email_account/test_email_account.py +++ b/frappe/email/doctype/email_account/test_email_account.py @@ -39,7 +39,7 @@ class TestEmailAccount(unittest.TestCase): frappe.db.delete("Unhandled Email") def get_test_mail(self, fname): - with open(os.path.join(os.path.dirname(__file__), "test_mails", fname), "r") as f: + with open(os.path.join(os.path.dirname(__file__), "test_mails", fname)) as f: return f.read() def test_incoming(self): @@ -211,7 +211,7 @@ class TestEmailAccount(unittest.TestCase): sent_mail = email.message_from_string(frappe.get_last_doc("Email Queue").message) - with open(os.path.join(os.path.dirname(__file__), "test_mails", "reply-1.raw"), "r") as f: + with open(os.path.join(os.path.dirname(__file__), "test_mails", "reply-1.raw")) as f: raw = f.read() raw = raw.replace("<-- in-reply-to -->", sent_mail.get("Message-Id")) @@ -233,10 +233,10 @@ class TestEmailAccount(unittest.TestCase): def test_threading_by_subject(self): cleanup(["in", ["test_sender@example.com", "test@example.com"]]) - with open(os.path.join(os.path.dirname(__file__), "test_mails", "reply-2.raw"), "r") as f: + with open(os.path.join(os.path.dirname(__file__), "test_mails", "reply-2.raw")) as f: test_mails = [f.read()] - with open(os.path.join(os.path.dirname(__file__), "test_mails", "reply-3.raw"), "r") as f: + with open(os.path.join(os.path.dirname(__file__), "test_mails", "reply-3.raw")) as f: test_mails.append(f.read()) # parse reply @@ -280,7 +280,7 @@ class TestEmailAccount(unittest.TestCase): last_mail = frappe.get_doc("Email Queue", dict(reference_name=event.name)) # get test mail with message-id as in-reply-to - with open(os.path.join(os.path.dirname(__file__), "test_mails", "reply-4.raw"), "r") as f: + with open(os.path.join(os.path.dirname(__file__), "test_mails", "reply-4.raw")) as f: messages = { # append_to = ToDo '"INBOX"': { @@ -451,7 +451,7 @@ class TestInboundMail(unittest.TestCase): frappe.db.delete("ToDo") def get_test_mail(self, fname): - with open(os.path.join(os.path.dirname(__file__), "test_mails", fname), "r") as f: + with open(os.path.join(os.path.dirname(__file__), "test_mails", fname)) as f: return f.read() def new_doc(self, doctype, **data): diff --git a/frappe/email/doctype/email_domain/email_domain.py b/frappe/email/doctype/email_domain/email_domain.py index ff59725fd7..ab6546e4e6 100644 --- a/frappe/email/doctype/email_domain/email_domain.py +++ b/frappe/email/doctype/email_domain/email_domain.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors # License: MIT. See LICENSE @@ -53,12 +52,10 @@ class EmailDomain(Document): test = poplib.POP3(self.email_server, port=get_port(self)) except Exception as e: - logger.warn( - 'Incoming email account "{host}" not correct'.format(host=self.email_server), exc_info=e - ) + logger.warn(f'Incoming email account "{self.email_server}" not correct', exc_info=e) frappe.throw( title=_("Incoming email account not correct"), - msg='Error connecting IMAP/POP3 "{host}": {e}'.format(host=self.email_server, e=e), + msg=f'Error connecting IMAP/POP3 "{self.email_server}": {e}', ) finally: @@ -94,12 +91,10 @@ class EmailDomain(Document): sess = smtplib.SMTP(cstr(self.smtp_server or ""), cint(self.smtp_port) or None) sess.quit() except Exception as e: - logger.warn( - 'Outgoing email account "{host}" not correct'.format(host=self.smtp_server), exc_info=e - ) + logger.warn(f'Outgoing email account "{self.smtp_server}" not correct', exc_info=e) frappe.throw( title=_("Outgoing email account not correct"), - msg='Error connecting SMTP "{host}": {e}'.format(host=self.smtp_server, e=e), + msg=f'Error connecting SMTP "{self.smtp_server}": {e}', ) def on_update(self): diff --git a/frappe/email/doctype/email_domain/test_email_domain.py b/frappe/email/doctype/email_domain/test_email_domain.py index 0162e4efe0..55a8d620a8 100644 --- a/frappe/email/doctype/email_domain/test_email_domain.py +++ b/frappe/email/doctype/email_domain/test_email_domain.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors # License: MIT. See LICENSE import unittest diff --git a/frappe/email/doctype/email_flag_queue/email_flag_queue.py b/frappe/email/doctype/email_flag_queue/email_flag_queue.py index b7ca48faf0..cf28ce0628 100644 --- a/frappe/email/doctype/email_flag_queue/email_flag_queue.py +++ b/frappe/email/doctype/email_flag_queue/email_flag_queue.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/email/doctype/email_flag_queue/test_email_flag_queue.py b/frappe/email/doctype/email_flag_queue/test_email_flag_queue.py index 11571da7d9..8bfc9230a4 100644 --- a/frappe/email/doctype/email_flag_queue/test_email_flag_queue.py +++ b/frappe/email/doctype/email_flag_queue/test_email_flag_queue.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies and Contributors # License: MIT. See LICENSE import unittest diff --git a/frappe/email/doctype/email_group/email_group.py b/frappe/email/doctype/email_group/email_group.py index 6489e82341..ea62a6e9ec 100755 --- a/frappe/email/doctype/email_group/email_group.py +++ b/frappe/email/doctype/email_group/email_group.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies and contributors # License: MIT. See LICENSE @@ -12,7 +11,7 @@ class EmailGroup(Document): def onload(self): singles = [d.name for d in frappe.db.get_all("DocType", "name", {"issingle": 1})] self.get("__onload").import_types = [ - {"value": d.parent, "label": "{0} ({1})".format(d.parent, d.label)} + {"value": d.parent, "label": f"{d.parent} ({d.label})"} for d in frappe.db.get_all("DocField", ("parent", "label"), {"options": "Email"}) if d.parent not in singles ] diff --git a/frappe/email/doctype/email_group/test_email_group.py b/frappe/email/doctype/email_group/test_email_group.py index 96032d35cc..aa41285f90 100644 --- a/frappe/email/doctype/email_group/test_email_group.py +++ b/frappe/email/doctype/email_group/test_email_group.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies and Contributors # License: MIT. See LICENSE import unittest diff --git a/frappe/email/doctype/email_group_member/email_group_member.py b/frappe/email/doctype/email_group_member/email_group_member.py index 76990b18fb..c0995d393b 100644 --- a/frappe/email/doctype/email_group_member/email_group_member.py +++ b/frappe/email/doctype/email_group_member/email_group_member.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/email/doctype/email_group_member/test_email_group_member.py b/frappe/email/doctype/email_group_member/test_email_group_member.py index ae608a4e15..749792fe52 100644 --- a/frappe/email/doctype/email_group_member/test_email_group_member.py +++ b/frappe/email/doctype/email_group_member/test_email_group_member.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies and Contributors # License: MIT. See LICENSE import unittest diff --git a/frappe/email/doctype/email_queue/email_queue.py b/frappe/email/doctype/email_queue/email_queue.py index c51446947c..7b57adf6fb 100644 --- a/frappe/email/doctype/email_queue/email_queue.py +++ b/frappe/email/doctype/email_queue/email_queue.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies and contributors # License: MIT. See LICENSE @@ -156,7 +155,7 @@ class EmailQueue(Document): ( frappe.qb.from_(email_queue) .delete() - .where((email_queue.modified < (Now() - Interval(days=days)))) + .where(email_queue.modified < (Now() - Interval(days=days))) ).run() # delete child tables, note that this has potential to leave some orphan @@ -165,7 +164,7 @@ class EmailQueue(Document): ( frappe.qb.from_(email_recipient) .delete() - .where((email_recipient.modified < (Now() - Interval(days=days)))) + .where(email_recipient.modified < (Now() - Interval(days=days))) ).run() @@ -244,7 +243,7 @@ class SendMailContext: self.sent_to.append(recipient.recipient) def is_mail_sent_to_all(self): - return sorted(self.sent_to) == sorted([rec.recipient for rec in self.queue_doc.recipients]) + return sorted(self.sent_to) == sorted(rec.recipient for rec in self.queue_doc.recipients) def get_message_object(self, message): return Parser(policy=SMTPUTF8).parsestr(message) @@ -660,7 +659,7 @@ class QueueBuilder: # bad Email Address - don't add to queue frappe.log_error( title="Invalid email address", - message="Invalid email address Sender: {0}, Recipients: {1}, \nTraceback: {2} ".format( + message="Invalid email address Sender: {}, Recipients: {}, \nTraceback: {} ".format( self.sender, ", ".join(self.final_recipients()), traceback.format_exc() ), reference_doctype=self.reference_doctype, diff --git a/frappe/email/doctype/email_queue/test_email_queue.py b/frappe/email/doctype/email_queue/test_email_queue.py index 435e4e691f..5a608b1b23 100644 --- a/frappe/email/doctype/email_queue/test_email_queue.py +++ b/frappe/email/doctype/email_queue/test_email_queue.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies and Contributors # License: MIT. See LICENSE diff --git a/frappe/email/doctype/email_queue_recipient/email_queue_recipient.py b/frappe/email/doctype/email_queue_recipient/email_queue_recipient.py index d2e4753ddf..bcb8d9b05d 100644 --- a/frappe/email/doctype/email_queue_recipient/email_queue_recipient.py +++ b/frappe/email/doctype/email_queue_recipient/email_queue_recipient.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/email/doctype/email_rule/email_rule.py b/frappe/email/doctype/email_rule/email_rule.py index 5075024b73..ab04632280 100644 --- a/frappe/email/doctype/email_rule/email_rule.py +++ b/frappe/email/doctype/email_rule/email_rule.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2017, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/email/doctype/email_rule/test_email_rule.py b/frappe/email/doctype/email_rule/test_email_rule.py index 7b7a9a5c23..1da5d34d6b 100644 --- a/frappe/email/doctype/email_rule/test_email_rule.py +++ b/frappe/email/doctype/email_rule/test_email_rule.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2017, Frappe Technologies and Contributors # License: MIT. See LICENSE import unittest diff --git a/frappe/email/doctype/email_template/test_email_template.py b/frappe/email/doctype/email_template/test_email_template.py index d37b5497fb..291f7e1df0 100644 --- a/frappe/email/doctype/email_template/test_email_template.py +++ b/frappe/email/doctype/email_template/test_email_template.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2018, Frappe Technologies and Contributors # License: MIT. See LICENSE import unittest diff --git a/frappe/email/doctype/email_unsubscribe/email_unsubscribe.py b/frappe/email/doctype/email_unsubscribe/email_unsubscribe.py index 131546a3c2..c9ab17d61d 100644 --- a/frappe/email/doctype/email_unsubscribe/email_unsubscribe.py +++ b/frappe/email/doctype/email_unsubscribe/email_unsubscribe.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors # License: MIT. See LICENSE diff --git a/frappe/email/doctype/email_unsubscribe/test_email_unsubscribe.py b/frappe/email/doctype/email_unsubscribe/test_email_unsubscribe.py index 0133c6c4b5..9ba99a6690 100644 --- a/frappe/email/doctype/email_unsubscribe/test_email_unsubscribe.py +++ b/frappe/email/doctype/email_unsubscribe/test_email_unsubscribe.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors # License: MIT. See LICENSE import unittest diff --git a/frappe/email/doctype/newsletter/newsletter.py b/frappe/email/doctype/newsletter/newsletter.py index 6fcdce482f..757a8c875b 100644 --- a/frappe/email/doctype/newsletter/newsletter.py +++ b/frappe/email/doctype/newsletter/newsletter.py @@ -1,7 +1,6 @@ # Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors # MIT License. See LICENSE -from typing import Dict, List import frappe import frappe.utils @@ -21,7 +20,7 @@ class Newsletter(WebsiteGenerator): self.validate_publishing() @property - def newsletter_recipients(self) -> List[str]: + def newsletter_recipients(self) -> list[str]: if getattr(self, "_recipients", None) is None: self._recipients = self.get_recipients() return self._recipients @@ -112,7 +111,7 @@ class Newsletter(WebsiteGenerator): if self.send_webview_link and not self.published: frappe.throw(_("Newsletter must be published to send webview link in email")) - def get_linked_email_queue(self) -> List[str]: + def get_linked_email_queue(self) -> list[str]: """Get list of email queue linked to this newsletter.""" return frappe.get_all( "Email Queue", @@ -123,7 +122,7 @@ class Newsletter(WebsiteGenerator): pluck="name", ) - def get_success_recipients(self) -> List[str]: + def get_success_recipients(self) -> list[str]: """Recipients who have already received the newsletter. Couldn't think of a better name ;) @@ -137,7 +136,7 @@ class Newsletter(WebsiteGenerator): pluck="recipient", ) - def get_pending_recipients(self) -> List[str]: + def get_pending_recipients(self) -> list[str]: """Get list of pending recipients of the newsletter. These recipients may not have receive the newsletter in the previous iteration. """ @@ -156,11 +155,11 @@ class Newsletter(WebsiteGenerator): self.total_recipients = len(recipients) self.save() - def get_newsletter_attachments(self) -> List[Dict[str, str]]: + def get_newsletter_attachments(self) -> list[dict[str, str]]: """Get list of attachments on current Newsletter""" return [{"file_url": row.attachment} for row in self.attachments] - def send_newsletter(self, emails: List[str]): + def send_newsletter(self, emails: list[str]): """Trigger email generation for `emails` and add it in Email Queue.""" attachments = self.get_newsletter_attachments() sender = self.send_from or frappe.utils.get_formatted_email(self.owner) @@ -197,7 +196,7 @@ class Newsletter(WebsiteGenerator): return frappe.render_template(message, {"doc": self.as_dict()}) - def get_recipients(self) -> List[str]: + def get_recipients(self) -> list[str]: """Get recipients from Email Group""" emails = frappe.get_all( "Email Group Member", @@ -206,7 +205,7 @@ class Newsletter(WebsiteGenerator): ) return list(set(emails)) - def get_email_groups(self) -> List[str]: + def get_email_groups(self) -> list[str]: # wondering why the 'or'? i can't figure out why both aren't equivalent - @gavin return [x.email_group for x in self.email_group] or frappe.get_all( "Newsletter Email Group", @@ -214,7 +213,7 @@ class Newsletter(WebsiteGenerator): pluck="email_group", ) - def get_attachments(self) -> List[Dict[str, str]]: + def get_attachments(self) -> list[dict[str, str]]: return frappe.get_all( "File", fields=["name", "file_name", "file_url", "is_private"], @@ -267,8 +266,8 @@ def subscribe(email, email_group=_("Website")): # noqa _("Click here to verify"), ) content = """ -

{0}. {1}.

-

{3}

+

{}. {}.

+

{}

""".format( *translatable_content ) diff --git a/frappe/email/doctype/newsletter/test_newsletter.py b/frappe/email/doctype/newsletter/test_newsletter.py index 550ee8164b..524289db7f 100644 --- a/frappe/email/doctype/newsletter/test_newsletter.py +++ b/frappe/email/doctype/newsletter/test_newsletter.py @@ -2,7 +2,6 @@ # MIT License. See LICENSE from random import choice -from typing import Union from unittest.mock import MagicMock, PropertyMock, patch import frappe @@ -79,7 +78,7 @@ class TestNewsletterMixin: frappe.db.release_savepoint(savepoint) - def send_newsletter(self, published=0, schedule_send=None) -> Union[str, None]: + def send_newsletter(self, published=0, schedule_send=None) -> str | None: frappe.db.delete("Email Queue") frappe.db.delete("Email Queue Recipient") frappe.db.delete("Newsletter") diff --git a/frappe/email/doctype/newsletter_email_group/newsletter_email_group.py b/frappe/email/doctype/newsletter_email_group/newsletter_email_group.py index 9fe1364d11..41ada8a491 100644 --- a/frappe/email/doctype/newsletter_email_group/newsletter_email_group.py +++ b/frappe/email/doctype/newsletter_email_group/newsletter_email_group.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/email/doctype/notification/notification.py b/frappe/email/doctype/notification/notification.py index 496a05bf6a..8d0857ac60 100644 --- a/frappe/email/doctype/notification/notification.py +++ b/frappe/email/doctype/notification/notification.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2018, Frappe Technologies and contributors # License: MIT. See LICENSE @@ -368,7 +367,7 @@ def get_context(context): template = "" template_path = os.path.join(os.path.dirname(module.__file__), frappe.scrub(self.name) + extn) if os.path.exists(template_path): - with open(template_path, "r") as f: + with open(template_path) as f: template = f.read() return template @@ -433,7 +432,7 @@ def evaluate_alert(doc: Document, alert, event): if event == "Value Change" and not doc.is_new(): if not frappe.db.has_column(doc.doctype, alert.value_changed): alert.db_set("enabled", 0) - alert.log_error("Notification {0} has been disabled due to missing field".format(alert.name)) + alert.log_error(f"Notification {alert.name} has been disabled due to missing field") return doc_before_save = doc.get_doc_before_save() diff --git a/frappe/email/doctype/notification/test_notification.py b/frappe/email/doctype/notification/test_notification.py index 7a31fc7434..4adaeae37e 100644 --- a/frappe/email/doctype/notification/test_notification.py +++ b/frappe/email/doctype/notification/test_notification.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2018, Frappe Technologies and Contributors # License: MIT. See LICENSE import unittest diff --git a/frappe/email/doctype/notification_recipient/notification_recipient.py b/frappe/email/doctype/notification_recipient/notification_recipient.py index 1785590e93..75bb274599 100644 --- a/frappe/email/doctype/notification_recipient/notification_recipient.py +++ b/frappe/email/doctype/notification_recipient/notification_recipient.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2018, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/email/doctype/unhandled_email/test_unhandled_email.py b/frappe/email/doctype/unhandled_email/test_unhandled_email.py index 1485f3bbaa..debc52d685 100644 --- a/frappe/email/doctype/unhandled_email/test_unhandled_email.py +++ b/frappe/email/doctype/unhandled_email/test_unhandled_email.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors # License: MIT. See LICENSE import unittest diff --git a/frappe/email/doctype/unhandled_email/unhandled_email.py b/frappe/email/doctype/unhandled_email/unhandled_email.py index e703f1ec97..1c315e2423 100644 --- a/frappe/email/doctype/unhandled_email/unhandled_email.py +++ b/frappe/email/doctype/unhandled_email/unhandled_email.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors # License: MIT. See LICENSE diff --git a/frappe/email/email_body.py b/frappe/email/email_body.py index 3a952e1487..3288ca2148 100755 --- a/frappe/email/email_body.py +++ b/frappe/email/email_body.py @@ -7,7 +7,6 @@ import re from email import policy from email.header import Header from email.mime.multipart import MIMEMultipart -from typing import Optional import frappe from frappe.email.doctype.email_account.email_account import EmailAccount @@ -354,7 +353,7 @@ def get_formatted_html( print_html=None, email_account=None, header=None, - unsubscribe_link: Optional[frappe._dict] = None, + unsubscribe_link: frappe._dict | None = None, sender=None, with_container=False, ): @@ -454,7 +453,7 @@ def add_attachment(fname, fcontent, content_type=None, parent=None, content_id=N attachment_type = "inline" if inline else "attachment" part.add_header("Content-Disposition", attachment_type, filename=str(fname)) if content_id: - part.add_header("Content-ID", "<{0}>".format(content_id)) + part.add_header("Content-ID", f"<{content_id}>") parent.attach(part) diff --git a/frappe/email/receive.py b/frappe/email/receive.py index dd8273d778..93e1a68285 100644 --- a/frappe/email/receive.py +++ b/frappe/email/receive.py @@ -269,7 +269,7 @@ class EmailServer: 1 if uidnext < (sync_count + 1) or (uidnext - sync_count) < 1 else uidnext - sync_count ) # sync last 100 email - self.settings.email_sync_rule = "UID {}:{}".format(from_uid, uidnext) + self.settings.email_sync_rule = f"UID {from_uid}:{uidnext}" self.uid_reindexed = True elif uid_validity == current_uid_validity: @@ -534,10 +534,10 @@ class Email: for key in ("From", "To", "Subject", "Date"): value = cstr(message.get(key)) if value: - headers.append("{label}: {value}".format(label=_(key), value=escape(value))) + headers.append(f"{_(key)}: {escape(value)}") self.text_content += "\n".join(headers) - self.html_content += "
" + "\n".join("

{0}

".format(h) for h in headers) + self.html_content += "
" + "\n".join(f"

{h}

" for h in headers) if not message.is_multipart() and message.get_content_type() == "text/plain": # email.parser didn't parse it! @@ -710,7 +710,7 @@ class InboundMail(Email): content = self.content for file in attachments: if file.name in self.cid_map and self.cid_map[file.name]: - content = content.replace("cid:{0}".format(self.cid_map[file.name]), file.file_url) + content = content.replace(f"cid:{self.cid_map[file.name]}", file.file_url) return content def is_notification(self): @@ -895,7 +895,7 @@ class InboundMail(Email): users = frappe.get_all( "User Email", filters={"email_account": email_account.name}, fields=["parent"] ) - return list(set([user.get("parent") for user in users])) + return list({user.get("parent") for user in users}) @staticmethod def clean_subject(subject): @@ -946,7 +946,7 @@ class InboundMail(Email): } -class TimerMixin(object): +class TimerMixin: def __init__(self, *args, **kwargs): self.timeout = kwargs.pop("timeout", 0.0) self.elapsed_time = 0.0 diff --git a/frappe/email/test_email_body.py b/frappe/email/test_email_body.py index 3de21f64ce..9f76ec6a59 100644 --- a/frappe/email/test_email_body.py +++ b/frappe/email/test_email_body.py @@ -128,7 +128,7 @@ w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> processed_message = """
- test + test
""".format( diff --git a/frappe/event_streaming/doctype/document_type_field_mapping/document_type_field_mapping.py b/frappe/event_streaming/doctype/document_type_field_mapping/document_type_field_mapping.py index 3019d70035..96d9e0fcb3 100644 --- a/frappe/event_streaming/doctype/document_type_field_mapping/document_type_field_mapping.py +++ b/frappe/event_streaming/doctype/document_type_field_mapping/document_type_field_mapping.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/event_streaming/doctype/document_type_mapping/document_type_mapping.py b/frappe/event_streaming/doctype/document_type_mapping/document_type_mapping.py index bcd2b275d1..04b5015296 100644 --- a/frappe/event_streaming/doctype/document_type_mapping/document_type_mapping.py +++ b/frappe/event_streaming/doctype/document_type_mapping/document_type_mapping.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and contributors # License: MIT. See LICENSE import json diff --git a/frappe/event_streaming/doctype/document_type_mapping/test_document_type_mapping.py b/frappe/event_streaming/doctype/document_type_mapping/test_document_type_mapping.py index 1d5c4862de..676d5040ff 100644 --- a/frappe/event_streaming/doctype/document_type_mapping/test_document_type_mapping.py +++ b/frappe/event_streaming/doctype/document_type_mapping/test_document_type_mapping.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and Contributors # License: MIT. See LICENSE # import frappe diff --git a/frappe/event_streaming/doctype/event_consumer/event_consumer.py b/frappe/event_streaming/doctype/event_consumer/event_consumer.py index bcd3d3be39..a2ae6f6651 100644 --- a/frappe/event_streaming/doctype/event_consumer/event_consumer.py +++ b/frappe/event_streaming/doctype/event_consumer/event_consumer.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/event_streaming/doctype/event_consumer/test_event_consumer.py b/frappe/event_streaming/doctype/event_consumer/test_event_consumer.py index 605fc7982a..6f04af643e 100644 --- a/frappe/event_streaming/doctype/event_consumer/test_event_consumer.py +++ b/frappe/event_streaming/doctype/event_consumer/test_event_consumer.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and Contributors # License: MIT. See LICENSE # import frappe diff --git a/frappe/event_streaming/doctype/event_consumer_document_type/event_consumer_document_type.py b/frappe/event_streaming/doctype/event_consumer_document_type/event_consumer_document_type.py index b33313087f..1ed15c5a75 100644 --- a/frappe/event_streaming/doctype/event_consumer_document_type/event_consumer_document_type.py +++ b/frappe/event_streaming/doctype/event_consumer_document_type/event_consumer_document_type.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/event_streaming/doctype/event_producer/event_producer.py b/frappe/event_streaming/doctype/event_producer/event_producer.py index adbb706c3d..f91c8a4fd4 100644 --- a/frappe/event_streaming/doctype/event_producer/event_producer.py +++ b/frappe/event_streaming/doctype/event_producer/event_producer.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/event_streaming/doctype/event_producer/test_event_producer.py b/frappe/event_streaming/doctype/event_producer/test_event_producer.py index eafa7a0b51..168c9a61cf 100644 --- a/frappe/event_streaming/doctype/event_producer/test_event_producer.py +++ b/frappe/event_streaming/doctype/event_producer/test_event_producer.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and Contributors # License: MIT. See LICENSE import json diff --git a/frappe/event_streaming/doctype/event_producer_document_type/event_producer_document_type.py b/frappe/event_streaming/doctype/event_producer_document_type/event_producer_document_type.py index 3e9623f56f..8f4c936792 100644 --- a/frappe/event_streaming/doctype/event_producer_document_type/event_producer_document_type.py +++ b/frappe/event_streaming/doctype/event_producer_document_type/event_producer_document_type.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/event_streaming/doctype/event_producer_last_update/event_producer_last_update.py b/frappe/event_streaming/doctype/event_producer_last_update/event_producer_last_update.py index 8e32e6fe6f..ec5cee7e78 100644 --- a/frappe/event_streaming/doctype/event_producer_last_update/event_producer_last_update.py +++ b/frappe/event_streaming/doctype/event_producer_last_update/event_producer_last_update.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2020, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/event_streaming/doctype/event_producer_last_update/test_event_producer_last_update.py b/frappe/event_streaming/doctype/event_producer_last_update/test_event_producer_last_update.py index 6054ec873f..ccdea6c694 100644 --- a/frappe/event_streaming/doctype/event_producer_last_update/test_event_producer_last_update.py +++ b/frappe/event_streaming/doctype/event_producer_last_update/test_event_producer_last_update.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2020, Frappe Technologies and Contributors # License: MIT. See LICENSE # import frappe diff --git a/frappe/event_streaming/doctype/event_sync_log/event_sync_log.py b/frappe/event_streaming/doctype/event_sync_log/event_sync_log.py index c26ca46e05..a1d82ad08f 100644 --- a/frappe/event_streaming/doctype/event_sync_log/event_sync_log.py +++ b/frappe/event_streaming/doctype/event_sync_log/event_sync_log.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/event_streaming/doctype/event_sync_log/test_event_sync_log.py b/frappe/event_streaming/doctype/event_sync_log/test_event_sync_log.py index da90c8e634..13028cbac7 100644 --- a/frappe/event_streaming/doctype/event_sync_log/test_event_sync_log.py +++ b/frappe/event_streaming/doctype/event_sync_log/test_event_sync_log.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and Contributors # License: MIT. See LICENSE # import frappe diff --git a/frappe/event_streaming/doctype/event_update_log/event_update_log.py b/frappe/event_streaming/doctype/event_update_log/event_update_log.py index 658a3b47cc..e40f600484 100644 --- a/frappe/event_streaming/doctype/event_update_log/event_update_log.py +++ b/frappe/event_streaming/doctype/event_update_log/event_update_log.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and contributors # License: MIT. See LICENSE diff --git a/frappe/event_streaming/doctype/event_update_log/test_event_update_log.py b/frappe/event_streaming/doctype/event_update_log/test_event_update_log.py index 673164b8d7..0cbff47912 100644 --- a/frappe/event_streaming/doctype/event_update_log/test_event_update_log.py +++ b/frappe/event_streaming/doctype/event_update_log/test_event_update_log.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and Contributors # License: MIT. See LICENSE # import frappe diff --git a/frappe/event_streaming/doctype/event_update_log_consumer/event_update_log_consumer.py b/frappe/event_streaming/doctype/event_update_log_consumer/event_update_log_consumer.py index 4f00504538..69da7db92e 100644 --- a/frappe/event_streaming/doctype/event_update_log_consumer/event_update_log_consumer.py +++ b/frappe/event_streaming/doctype/event_update_log_consumer/event_update_log_consumer.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2020, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/exceptions.py b/frappe/exceptions.py index 755c21c240..c3bb45caea 100644 --- a/frappe/exceptions.py +++ b/frappe/exceptions.py @@ -76,7 +76,7 @@ class ImproperDBConfigurationError(Exception): def __init__(self, reason, msg=None): if not msg: msg = "MariaDb is not properly configured" - super(ImproperDBConfigurationError, self).__init__(msg) + super().__init__(msg) self.reason = reason diff --git a/frappe/frappeclient.py b/frappe/frappeclient.py index 04087463bc..474a5b06c4 100644 --- a/frappe/frappeclient.py +++ b/frappe/frappeclient.py @@ -26,7 +26,7 @@ class FrappeException(Exception): pass -class FrappeClient(object): +class FrappeClient: def __init__( self, url, @@ -85,11 +85,9 @@ class FrappeClient(object): def setup_key_authentication_headers(self): if self.api_key and self.api_secret: - token = base64.b64encode( - ("{}:{}".format(self.api_key, self.api_secret)).encode("utf-8") - ).decode("utf-8") + token = base64.b64encode((f"{self.api_key}:{self.api_secret}").encode()).decode("utf-8") auth_header = { - "Authorization": "Basic {}".format(token), + "Authorization": f"Basic {token}", } self.headers.update(auth_header) @@ -266,7 +264,7 @@ class FrappeClient(object): # build - attach children to parents if tables: docs = [frappe._dict(doc) for doc in docs] - docs_map = dict((doc.name, doc) for doc in docs) + docs_map = {doc.name: doc for doc in docs} for fieldname in tables: for child in tables[fieldname]: diff --git a/frappe/geo/country_info.py b/frappe/geo/country_info.py index 1de8467a6a..2aefa27170 100644 --- a/frappe/geo/country_info.py +++ b/frappe/geo/country_info.py @@ -22,7 +22,7 @@ def get_country_info(country=None): def get_all(): - with open(os.path.join(os.path.dirname(__file__), "country_info.json"), "r") as local_info: + with open(os.path.join(os.path.dirname(__file__), "country_info.json")) as local_info: all_data = json.loads(local_info.read()) return all_data @@ -59,7 +59,7 @@ def get_translated_dict(): def update(): - with open(os.path.join(os.path.dirname(__file__), "currency_info.json"), "r") as nformats: + with open(os.path.join(os.path.dirname(__file__), "currency_info.json")) as nformats: nformats = json.loads(nformats.read()) all_data = get_all() diff --git a/frappe/geo/doctype/country/__init__.py b/frappe/geo/doctype/country/__init__.py index 8b13789179..e69de29bb2 100644 --- a/frappe/geo/doctype/country/__init__.py +++ b/frappe/geo/doctype/country/__init__.py @@ -1 +0,0 @@ - diff --git a/frappe/geo/doctype/currency/__init__.py b/frappe/geo/doctype/currency/__init__.py index 8b13789179..e69de29bb2 100644 --- a/frappe/geo/doctype/currency/__init__.py +++ b/frappe/geo/doctype/currency/__init__.py @@ -1 +0,0 @@ - diff --git a/frappe/geo/utils.py b/frappe/geo/utils.py index 577c5de2ff..c8e05be357 100644 --- a/frappe/geo/utils.py +++ b/frappe/geo/utils.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2020, Frappe Technologies and contributors # License: MIT. See LICENSE @@ -65,7 +64,7 @@ def return_location(doctype, filters_sql): if filters_sql: try: coords = frappe.db.sql( - """SELECT name, location FROM `tab{}` WHERE {}""".format(doctype, filters_sql), as_dict=True + f"""SELECT name, location FROM `tab{doctype}` WHERE {filters_sql}""", as_dict=True ) except InternalError: frappe.msgprint(frappe._("This Doctype does not contain location fields"), raise_exception=True) @@ -80,7 +79,7 @@ def return_coordinates(doctype, filters_sql): if filters_sql: try: coords = frappe.db.sql( - """SELECT name, latitude, longitude FROM `tab{}` WHERE {}""".format(doctype, filters_sql), + f"""SELECT name, latitude, longitude FROM `tab{doctype}` WHERE {filters_sql}""", as_dict=True, ) except InternalError: diff --git a/frappe/installer.py b/frappe/installer.py index 59c5dc6602..9d35f04e0d 100644 --- a/frappe/installer.py +++ b/frappe/installer.py @@ -5,7 +5,6 @@ import json import os import sys from collections import OrderedDict -from typing import Dict, List, Tuple import click @@ -38,7 +37,7 @@ def _new_site( from frappe.utils import get_site_path, scheduler, touch_file if not force and os.path.exists(site): - print("Site {0} already exists".format(site)) + print(f"Site {site} already exists") sys.exit(1) if no_mariadb_socket and not db_type == "mariadb": @@ -151,7 +150,7 @@ def install_db( frappe.flags.in_install_db = False -def find_org(org_repo: str) -> Tuple[str, str]: +def find_org(org_repo: str) -> tuple[str, str]: """find the org a repo is in find_org() @@ -179,7 +178,7 @@ def find_org(org_repo: str) -> Tuple[str, str]: raise InvalidRemoteException -def fetch_details_from_tag(_tag: str) -> Tuple[str, str, str]: +def fetch_details_from_tag(_tag: str) -> tuple[str, str, str]: """parse org, repo, tag from string fetch_details_from_tag() @@ -263,7 +262,7 @@ def install_app(name, verbose=False, set_as_patched=True, force=False): click.secho(f"App {name} already installed", fg="yellow") return - print("\nInstalling {0}...".format(name)) + print(f"\nInstalling {name}...") if name != "frappe": frappe.only_for("System Manager") @@ -371,7 +370,7 @@ def remove_app(app_name, dry_run=False, yes=False, no_backup=False, force=False) frappe.flags.in_uninstall = False -def _delete_modules(modules: List[str], dry_run: bool) -> List[str]: +def _delete_modules(modules: list[str], dry_run: bool) -> list[str]: """Delete modules belonging to the app and all related doctypes. Note: All record linked linked to Module Def are also deleted. @@ -404,7 +403,7 @@ def _delete_modules(modules: List[str], dry_run: bool) -> List[str]: def _delete_linked_documents( - module_name: str, doctype_linkfield_map: Dict[str, str], dry_run: bool + module_name: str, doctype_linkfield_map: dict[str, str], dry_run: bool ) -> None: """Deleted all records linked with module def""" @@ -415,7 +414,7 @@ def _delete_linked_documents( frappe.delete_doc(doctype, record, ignore_on_trash=True, force=True) -def _get_module_linked_doctype_field_map() -> Dict[str, str]: +def _get_module_linked_doctype_field_map() -> dict[str, str]: """Get all the doctypes which have module linked with them. returns ordered dictionary with doctype->link field mapping.""" @@ -444,7 +443,7 @@ def _get_module_linked_doctype_field_map() -> Dict[str, str]: return doctype_to_field_map -def _delete_doctypes(doctypes: List[str], dry_run: bool) -> None: +def _delete_doctypes(doctypes: list[str], dry_run: bool) -> None: for doctype in set(doctypes): print(f"* dropping Table for '{doctype}'...") if not dry_run: @@ -529,7 +528,7 @@ def update_site_config(key, value, validate=True, site_config_path=None): if not site_config_path: site_config_path = get_site_config_path() - with open(site_config_path, "r") as f: + with open(site_config_path) as f: site_config = json.loads(f.read()) # In case of non-int value @@ -664,7 +663,7 @@ def extract_sql_gzip(sql_gz_path): try: original_file = sql_gz_path decompressed_file = original_file.rstrip(".gz") - cmd = "gzip --decompress --force < {0} > {1}".format(original_file, decompressed_file) + cmd = f"gzip --decompress --force < {original_file} > {decompressed_file}" subprocess.check_call(cmd, shell=True) except Exception: raise @@ -800,7 +799,7 @@ def validate_database_sql(path, _raise=True): # dont bother checking if empty file if not empty_file: - with open(path, "r") as f: + with open(path) as f: for line in f: if "tabDefaultValue" in line: missing_table = False diff --git a/frappe/integrations/doctype/braintree_settings/braintree_settings.py b/frappe/integrations/doctype/braintree_settings/braintree_settings.py index 17330d7c84..35481c67c1 100644 --- a/frappe/integrations/doctype/braintree_settings/braintree_settings.py +++ b/frappe/integrations/doctype/braintree_settings/braintree_settings.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2018, Frappe Technologies and contributors # License: MIT. See LICENSE @@ -184,7 +183,7 @@ class BraintreeSettings(Document): ) def get_payment_url(self, **kwargs): - return get_url("./integrations/braintree_checkout?{0}".format(urlencode(kwargs))) + return get_url(f"./integrations/braintree_checkout?{urlencode(kwargs)}") def create_payment_request(self, data): self.data = frappe._dict(data) diff --git a/frappe/integrations/doctype/braintree_settings/test_braintree_settings.py b/frappe/integrations/doctype/braintree_settings/test_braintree_settings.py index 475a62be79..38d8909dfd 100644 --- a/frappe/integrations/doctype/braintree_settings/test_braintree_settings.py +++ b/frappe/integrations/doctype/braintree_settings/test_braintree_settings.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2018, Frappe Technologies and Contributors # License: MIT. See LICENSE import unittest diff --git a/frappe/integrations/doctype/connected_app/connected_app.py b/frappe/integrations/doctype/connected_app/connected_app.py index e472193da8..308d1ca84a 100644 --- a/frappe/integrations/doctype/connected_app/connected_app.py +++ b/frappe/integrations/doctype/connected_app/connected_app.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/integrations/doctype/connected_app/test_connected_app.py b/frappe/integrations/doctype/connected_app/test_connected_app.py index 1597ec75bf..1acedff160 100644 --- a/frappe/integrations/doctype/connected_app/test_connected_app.py +++ b/frappe/integrations/doctype/connected_app/test_connected_app.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and contributors # License: MIT. See LICENSE import unittest diff --git a/frappe/integrations/doctype/dropbox_settings/dropbox_settings.py b/frappe/integrations/doctype/dropbox_settings/dropbox_settings.py index 8a6a7a4bfb..50c5fa8fe6 100644 --- a/frappe/integrations/doctype/dropbox_settings/dropbox_settings.py +++ b/frappe/integrations/doctype/dropbox_settings/dropbox_settings.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies and contributors # License: MIT. See LICENSE @@ -89,7 +88,7 @@ def take_backup_to_dropbox(retry_count=0, upload_db_backup=True): "frappe.integrations.doctype.dropbox_settings.dropbox_settings.take_backup_to_dropbox", queue="long", timeout=1500, - **args + **args, ) except Exception: if isinstance(error_log, str): @@ -212,7 +211,7 @@ def upload_file_to_dropbox(filename, folder, dropbox_client): mode = dropbox.files.WriteMode.overwrite f = open(encode(filename), "rb") - path = "{0}/{1}".format(folder, os.path.basename(filename)) + path = f"{folder}/{os.path.basename(filename)}" try: if file_size <= chunk_size: @@ -234,7 +233,7 @@ def upload_file_to_dropbox(filename, folder, dropbox_client): cursor.offset = f.tell() except dropbox.exceptions.ApiError as e: if isinstance(e.error, dropbox.files.UploadError): - error = "File Path: {path}\n".format(path=path) + error = f"File Path: {path}\n" error += frappe.get_traceback() frappe.log_error(error) else: @@ -326,7 +325,7 @@ def delete_older_backups(dropbox_client, folder_path, to_keep): def get_redirect_url(): if not frappe.conf.dropbox_broker_site: frappe.conf.dropbox_broker_site = "https://dropbox.erpnext.com" - url = "{0}/api/method/dropbox_erpnext_broker.www.setup_dropbox.get_authotize_url".format( + url = "{}/api/method/dropbox_erpnext_broker.www.setup_dropbox.get_authotize_url".format( frappe.conf.dropbox_broker_site ) diff --git a/frappe/integrations/doctype/dropbox_settings/test_dropbox_settings.py b/frappe/integrations/doctype/dropbox_settings/test_dropbox_settings.py index e73cf03268..b165e03780 100644 --- a/frappe/integrations/doctype/dropbox_settings/test_dropbox_settings.py +++ b/frappe/integrations/doctype/dropbox_settings/test_dropbox_settings.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and Contributors # License: MIT. See LICENSE # import frappe diff --git a/frappe/integrations/doctype/google_calendar/google_calendar.py b/frappe/integrations/doctype/google_calendar/google_calendar.py index 71f0e83f80..d8dc7fab1d 100644 --- a/frappe/integrations/doctype/google_calendar/google_calendar.py +++ b/frappe/integrations/doctype/google_calendar/google_calendar.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and contributors # License: MIT. See LICENSE @@ -140,7 +139,7 @@ def authorize_access(g_calendar, reauthorize=None): frappe.db.commit() frappe.local.response["type"] = "redirect" - frappe.local.response["location"] = "/app/Form/{0}/{1}".format( + frappe.local.response["location"] = "/app/Form/{}/{}".format( quote("Google Calendar"), quote(google_calendar.name) ) diff --git a/frappe/integrations/doctype/google_contacts/google_contacts.py b/frappe/integrations/doctype/google_contacts/google_contacts.py index c26366f71a..5e4869be43 100644 --- a/frappe/integrations/doctype/google_contacts/google_contacts.py +++ b/frappe/integrations/doctype/google_contacts/google_contacts.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and contributors # License: MIT. See LICENSE @@ -91,7 +90,7 @@ def authorize_access(g_contact, reauthorize=None): frappe.db.commit() frappe.local.response["type"] = "redirect" - frappe.local.response["location"] = "/app/Form/Google%20Contacts/{}".format(google_contact.name) + frappe.local.response["location"] = f"/app/Form/Google%20Contacts/{google_contact.name}" frappe.msgprint(_("Google Contacts has been configured.")) except Exception as e: diff --git a/frappe/integrations/doctype/google_drive/google_drive.py b/frappe/integrations/doctype/google_drive/google_drive.py index 347488ee44..c472cbc741 100644 --- a/frappe/integrations/doctype/google_drive/google_drive.py +++ b/frappe/integrations/doctype/google_drive/google_drive.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and contributors # License: MIT. See LICENSE @@ -101,7 +100,7 @@ def authorize_access(reauthorize=None): frappe.db.commit() frappe.local.response["type"] = "redirect" - frappe.local.response["location"] = "/app/Form/{0}".format(quote("Google Drive")) + frappe.local.response["location"] = "/app/Form/{}".format(quote("Google Drive")) frappe.msgprint(_("Google Drive has been configured.")) except Exception as e: @@ -243,7 +242,7 @@ def upload_system_backup_to_google_drive(): media = MediaFileUpload( get_absolute_path(filename=fileurl), mimetype="application/gzip", resumable=True ) - except IOError as e: + except OSError as e: frappe.throw(_("Google Drive - Could not locate - {0}").format(e)) try: @@ -272,7 +271,7 @@ def weekly_backup(): def get_absolute_path(filename): file_path = os.path.join(get_backups_path()[2:], os.path.basename(filename)) - return "{0}/sites/{1}".format(get_bench_path(), file_path) + return f"{get_bench_path()}/sites/{file_path}" def set_progress(progress, message): diff --git a/frappe/integrations/doctype/google_drive/test_google_drive.py b/frappe/integrations/doctype/google_drive/test_google_drive.py index 17f5b152ca..4dcc79afd6 100644 --- a/frappe/integrations/doctype/google_drive/test_google_drive.py +++ b/frappe/integrations/doctype/google_drive/test_google_drive.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and Contributors # License: MIT. See LICENSE # import frappe diff --git a/frappe/integrations/doctype/google_settings/google_settings.py b/frappe/integrations/doctype/google_settings/google_settings.py index 0d5f9cb00d..c70a4b531f 100644 --- a/frappe/integrations/doctype/google_settings/google_settings.py +++ b/frappe/integrations/doctype/google_settings/google_settings.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/integrations/doctype/google_settings/test_google_settings.py b/frappe/integrations/doctype/google_settings/test_google_settings.py index 53d59b1be0..8d07ffa54f 100644 --- a/frappe/integrations/doctype/google_settings/test_google_settings.py +++ b/frappe/integrations/doctype/google_settings/test_google_settings.py @@ -1,7 +1,5 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2021, Frappe Technologies and Contributors # License: MIT. See LICENSE -from __future__ import unicode_literals import unittest diff --git a/frappe/integrations/doctype/integration_request/integration_request.py b/frappe/integrations/doctype/integration_request/integration_request.py index 4c99613161..334736bc9b 100644 --- a/frappe/integrations/doctype/integration_request/integration_request.py +++ b/frappe/integrations/doctype/integration_request/integration_request.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/integrations/doctype/integration_request/test_integration_request.py b/frappe/integrations/doctype/integration_request/test_integration_request.py index d14af481e8..45963d5096 100644 --- a/frappe/integrations/doctype/integration_request/test_integration_request.py +++ b/frappe/integrations/doctype/integration_request/test_integration_request.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies and Contributors # License: MIT. See LICENSE import unittest diff --git a/frappe/integrations/doctype/ldap_group_mapping/ldap_group_mapping.py b/frappe/integrations/doctype/ldap_group_mapping/ldap_group_mapping.py index f1b242e4bb..853cfc96a1 100644 --- a/frappe/integrations/doctype/ldap_group_mapping/ldap_group_mapping.py +++ b/frappe/integrations/doctype/ldap_group_mapping/ldap_group_mapping.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/integrations/doctype/ldap_settings/ldap_settings.py b/frappe/integrations/doctype/ldap_settings/ldap_settings.py index 96007ee918..ef6493717f 100644 --- a/frappe/integrations/doctype/ldap_settings/ldap_settings.py +++ b/frappe/integrations/doctype/ldap_settings/ldap_settings.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies and contributors # License: MIT. See LICENSE @@ -137,7 +136,7 @@ class LDAPSettings(Document): def sync_roles(self, user, additional_groups=None): - current_roles = set(d.role for d in user.get("roles")) + current_roles = {d.role for d in user.get("roles")} needed_roles = set() needed_roles.add(self.default_role) @@ -209,14 +208,12 @@ class LDAPSettings(Document): if type(user) is not ldap3.abstract.entry.Entry: raise TypeError( - "Invalid type, attribute {0} must be of type '{1}'".format( - "user", "ldap3.abstract.entry.Entry" - ) + "Invalid type, attribute {} must be of type '{}'".format("user", "ldap3.abstract.entry.Entry") ) if type(conn) is not ldap3.core.connection.Connection: raise TypeError( - "Invalid type, attribute {0} must be of type '{1}'".format("conn", "ldap3.Connection") + "Invalid type, attribute {} must be of type '{}'".format("conn", "ldap3.Connection") ) fetch_ldap_groups = None @@ -254,7 +251,7 @@ class LDAPSettings(Document): if ldap_object_class is not None: conn.search( search_base=self.ldap_search_path_group, - search_filter="(&(objectClass={0})({1}={2}))".format( + search_filter="(&(objectClass={})({}={}))".format( ldap_object_class, ldap_group_members_attribute, user_search_str ), attributes=["cn"], @@ -283,7 +280,7 @@ class LDAPSettings(Document): conn.search( search_base=self.ldap_search_path_user, - search_filter="{0}".format(user_filter), + search_filter=f"{user_filter}", attributes=ldap_attributes, ) @@ -309,7 +306,7 @@ class LDAPSettings(Document): from ldap3 import HASHED_SALTED_SHA, MODIFY_REPLACE from ldap3.utils.hashed import hashed - search_filter = "({0}={1})".format(self.ldap_email_field, user) + search_filter = f"({self.ldap_email_field}={user})" conn = self.connect_to_ldap( self.base_dn, self.get_password(raise_exception=False), read_only=False diff --git a/frappe/integrations/doctype/ldap_settings/test_ldap_settings.py b/frappe/integrations/doctype/ldap_settings/test_ldap_settings.py index 0651932843..f53b5291b3 100644 --- a/frappe/integrations/doctype/ldap_settings/test_ldap_settings.py +++ b/frappe/integrations/doctype/ldap_settings/test_ldap_settings.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and Contributors # License: MIT. See LICENSE import functools @@ -204,7 +203,7 @@ class LDAP_TestCase: frappe.get_doc(localdoc).save() - self.fail("Document LDAP Settings field [{0}] is not mandatory".format(mandatory_field)) + self.fail(f"Document LDAP Settings field [{mandatory_field}] is not mandatory") except frappe.exceptions.MandatoryError: pass @@ -227,9 +226,7 @@ class LDAP_TestCase: frappe.get_doc(localdoc).save() except frappe.exceptions.MandatoryError: - self.fail( - "Document LDAP Settings field [{0}] should not be mandatory".format(non_mandatory_field) - ) + self.fail(f"Document LDAP Settings field [{non_mandatory_field}] should not be mandatory") @mock_ldap_connection def test_validation_ldap_search_string(self): @@ -252,7 +249,7 @@ class LDAP_TestCase: try: frappe.get_doc(localdoc).save() - self.fail("LDAP search string [{0}] should not validate".format(invalid_search_string)) + self.fail(f"LDAP search string [{invalid_search_string}] should not validate") except frappe.exceptions.ValidationError: pass @@ -298,7 +295,7 @@ class LDAP_TestCase: ): self.fail( - "ldap3.Connection was called with {0}, failed reason: [{1}]".format( + "ldap3.Connection was called with {}, failed reason: [{}]".format( kwargs[connection_arg], prevent_connection_parameters[connection_arg][kwargs[connection_arg]], ) @@ -475,7 +472,7 @@ class LDAP_TestCase: self.assertTrue( len(updated_user_roles) == len(test_user_data[test_user]), - "syncing of the user roles failed. {0} != {1} for user {2}".format( + "syncing of the user roles failed. {} != {} for user {}".format( len(updated_user_roles), len(test_user_data[test_user]), test_user ), ) @@ -484,7 +481,7 @@ class LDAP_TestCase: self.assertTrue( role_to_group_map[user_role] in test_user_data[test_user], - "during sync_roles(), the user was given role {0} which should not have occured".format( + "during sync_roles(), the user was given role {} which should not have occured".format( user_role ), ) @@ -609,7 +606,7 @@ class LDAP_TestCase: self.assertTrue( str(display_massage.exception).lower() == "invalid username or password", - "invalid credentials passed authentication [user: {0}, password: {1}]".format( + "invalid credentials passed authentication [user: {}, password: {}]".format( username, password ), ) diff --git a/frappe/integrations/doctype/oauth_authorization_code/oauth_authorization_code.py b/frappe/integrations/doctype/oauth_authorization_code/oauth_authorization_code.py index 4ef6f65dc7..431d27bc04 100644 --- a/frappe/integrations/doctype/oauth_authorization_code/oauth_authorization_code.py +++ b/frappe/integrations/doctype/oauth_authorization_code/oauth_authorization_code.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/integrations/doctype/oauth_authorization_code/test_oauth_authorization_code.py b/frappe/integrations/doctype/oauth_authorization_code/test_oauth_authorization_code.py index 72cb789ebb..2036a42f15 100644 --- a/frappe/integrations/doctype/oauth_authorization_code/test_oauth_authorization_code.py +++ b/frappe/integrations/doctype/oauth_authorization_code/test_oauth_authorization_code.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies and Contributors # License: MIT. See LICENSE import unittest diff --git a/frappe/integrations/doctype/oauth_bearer_token/oauth_bearer_token.py b/frappe/integrations/doctype/oauth_bearer_token/oauth_bearer_token.py index 515d3d2ba3..2a17035571 100644 --- a/frappe/integrations/doctype/oauth_bearer_token/oauth_bearer_token.py +++ b/frappe/integrations/doctype/oauth_bearer_token/oauth_bearer_token.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/integrations/doctype/oauth_bearer_token/test_oauth_bearer_token.py b/frappe/integrations/doctype/oauth_bearer_token/test_oauth_bearer_token.py index 9dea8f482a..3439096809 100644 --- a/frappe/integrations/doctype/oauth_bearer_token/test_oauth_bearer_token.py +++ b/frappe/integrations/doctype/oauth_bearer_token/test_oauth_bearer_token.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies and Contributors # License: MIT. See LICENSE import unittest diff --git a/frappe/integrations/doctype/oauth_client/oauth_client.py b/frappe/integrations/doctype/oauth_client/oauth_client.py index 09f6e3aced..ab40467751 100644 --- a/frappe/integrations/doctype/oauth_client/oauth_client.py +++ b/frappe/integrations/doctype/oauth_client/oauth_client.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/integrations/doctype/oauth_client/test_oauth_client.py b/frappe/integrations/doctype/oauth_client/test_oauth_client.py index dd1b25239a..8fd732673e 100644 --- a/frappe/integrations/doctype/oauth_client/test_oauth_client.py +++ b/frappe/integrations/doctype/oauth_client/test_oauth_client.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies and Contributors # License: MIT. See LICENSE import unittest diff --git a/frappe/integrations/doctype/oauth_provider_settings/oauth_provider_settings.py b/frappe/integrations/doctype/oauth_provider_settings/oauth_provider_settings.py index 2aefd591a1..984382df9d 100644 --- a/frappe/integrations/doctype/oauth_provider_settings/oauth_provider_settings.py +++ b/frappe/integrations/doctype/oauth_provider_settings/oauth_provider_settings.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/integrations/doctype/oauth_scope/oauth_scope.py b/frappe/integrations/doctype/oauth_scope/oauth_scope.py index a30d087cc0..1db49a3818 100644 --- a/frappe/integrations/doctype/oauth_scope/oauth_scope.py +++ b/frappe/integrations/doctype/oauth_scope/oauth_scope.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2020, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/integrations/doctype/paypal_settings/paypal_settings.py b/frappe/integrations/doctype/paypal_settings/paypal_settings.py index 3568b77baf..99c499200b 100644 --- a/frappe/integrations/doctype/paypal_settings/paypal_settings.py +++ b/frappe/integrations/doctype/paypal_settings/paypal_settings.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies and contributors # License: MIT. See LICENSE @@ -193,7 +192,7 @@ class PayPalSettings(Document): params.update( { "METHOD": "SetExpressCheckout", - "returnUrl": get_url("{0}.get_express_checkout_details".format(api_path)), + "returnUrl": get_url(f"{api_path}.get_express_checkout_details"), "cancelUrl": get_url("/payment-cancel"), "PAYMENTREQUEST_0_PAYMENTACTION": "SALE", "PAYMENTREQUEST_0_AMT": kwargs["amount"], @@ -331,7 +330,7 @@ def confirm_payment(token): ).run_method("on_payment_authorized", "Completed") frappe.db.commit() - redirect_url = "/integrations/payment-success?doctype={0}&docname={1}".format( + redirect_url = "/integrations/payment-success?doctype={}&docname={}".format( data.get("reference_doctype"), data.get("reference_docname") ) else: @@ -404,7 +403,7 @@ def create_recurring_profile(token, payerid): ).run_method("on_payment_authorized", status_changed_to) frappe.db.commit() - redirect_url = "/integrations/payment-success?doctype={0}&docname={1}".format( + redirect_url = "/integrations/payment-success?doctype={}&docname={}".format( data.get("reference_doctype"), data.get("reference_docname") ) else: @@ -427,11 +426,9 @@ def get_redirect_uri(doc, token, payerid): data = json.loads(doc.data) if data.get("subscription_details") or data.get("subscription_id"): - return get_url( - "{0}.create_recurring_profile?token={1}&payerid={2}".format(api_path, token, payerid) - ) + return get_url(f"{api_path}.create_recurring_profile?token={token}&payerid={payerid}") else: - return get_url("{0}.confirm_payment?token={1}".format(api_path, token)) + return get_url(f"{api_path}.confirm_payment?token={token}") def manage_recurring_payment_profile_status(profile_id, action, args, url): @@ -474,7 +471,7 @@ def ipn_handler(): queue="long", timeout=600, is_async=True, - **{"doctype": "Integration Request", "docname": doc.name} + **{"doctype": "Integration Request", "docname": doc.name}, ) except frappe.InvalidStatusError: diff --git a/frappe/integrations/doctype/paytm_settings/paytm_settings.py b/frappe/integrations/doctype/paytm_settings/paytm_settings.py index d8c9159303..81a5f45f47 100644 --- a/frappe/integrations/doctype/paytm_settings/paytm_settings.py +++ b/frappe/integrations/doctype/paytm_settings/paytm_settings.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2020, Frappe Technologies and contributors # License: MIT. See LICENSE @@ -37,7 +36,7 @@ class PaytmSettings(Document): integration_request = create_request_log(kwargs, service_name="Paytm") kwargs.update(dict(order_id=integration_request.name)) - return get_url("./integrations/paytm_checkout?{0}".format(urlencode(kwargs))) + return get_url(f"./integrations/paytm_checkout?{urlencode(kwargs)}") def get_paytm_config(): diff --git a/frappe/integrations/doctype/paytm_settings/test_paytm_settings.py b/frappe/integrations/doctype/paytm_settings/test_paytm_settings.py index d9e72e344c..91b69d5aec 100644 --- a/frappe/integrations/doctype/paytm_settings/test_paytm_settings.py +++ b/frappe/integrations/doctype/paytm_settings/test_paytm_settings.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2020, Frappe Technologies and Contributors # License: MIT. See LICENSE # import frappe diff --git a/frappe/integrations/doctype/query_parameters/query_parameters.py b/frappe/integrations/doctype/query_parameters/query_parameters.py index 09f039a764..b501c0c3e8 100644 --- a/frappe/integrations/doctype/query_parameters/query_parameters.py +++ b/frappe/integrations/doctype/query_parameters/query_parameters.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2020, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/integrations/doctype/razorpay_settings/razorpay_settings.py b/frappe/integrations/doctype/razorpay_settings/razorpay_settings.py index b13319803f..a79e626b49 100644 --- a/frappe/integrations/doctype/razorpay_settings/razorpay_settings.py +++ b/frappe/integrations/doctype/razorpay_settings/razorpay_settings.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies and contributors # License: MIT. See LICENSE @@ -124,9 +123,7 @@ class RazorpaySettings(Document): "quantity": 1 (The total amount is calculated as item.amount * quantity) } """ - url = "https://api.razorpay.com/v1/subscriptions/{0}/addons".format( - kwargs.get("subscription_id") - ) + url = "https://api.razorpay.com/v1/subscriptions/{}/addons".format(kwargs.get("subscription_id")) try: if not frappe.conf.converted_rupee_to_paisa: @@ -195,7 +192,7 @@ class RazorpaySettings(Document): def get_payment_url(self, **kwargs): integration_request = create_request_log(kwargs, service_name="Razorpay") - return get_url("./integrations/razorpay_checkout?token={0}".format(integration_request.name)) + return get_url(f"./integrations/razorpay_checkout?token={integration_request.name}") def create_order(self, **kwargs): # Creating Orders https://razorpay.com/docs/api/orders/ @@ -257,7 +254,7 @@ class RazorpaySettings(Document): try: resp = make_get_request( - "https://api.razorpay.com/v1/payments/{0}".format(self.data.razorpay_payment_id), + f"https://api.razorpay.com/v1/payments/{self.data.razorpay_payment_id}", auth=(settings.api_key, settings.api_secret), ) @@ -303,7 +300,7 @@ class RazorpaySettings(Document): if custom_redirect_to: redirect_to = custom_redirect_to - redirect_url = "payment-success?doctype={0}&docname={1}".format( + redirect_url = "payment-success?doctype={}&docname={}".format( self.data.reference_doctype, self.data.reference_docname ) else: @@ -339,7 +336,7 @@ class RazorpaySettings(Document): try: resp = make_post_request( - "https://api.razorpay.com/v1/subscriptions/{0}/cancel".format(subscription_id), + f"https://api.razorpay.com/v1/subscriptions/{subscription_id}/cancel", auth=(settings.api_key, settings.api_secret), ) except Exception: @@ -383,14 +380,14 @@ def capture_payment(is_sandbox=False, sanbox_response=None): settings = controller.get_settings(data) resp = make_get_request( - "https://api.razorpay.com/v1/payments/{0}".format(data.get("razorpay_payment_id")), + "https://api.razorpay.com/v1/payments/{}".format(data.get("razorpay_payment_id")), auth=(settings.api_key, settings.api_secret), data={"amount": data.get("amount")}, ) if resp.get("status") == "authorized": resp = make_post_request( - "https://api.razorpay.com/v1/payments/{0}/capture".format(data.get("razorpay_payment_id")), + "https://api.razorpay.com/v1/payments/{}/capture".format(data.get("razorpay_payment_id")), auth=(settings.api_key, settings.api_secret), data={"amount": data.get("amount")}, ) @@ -403,7 +400,7 @@ def capture_payment(is_sandbox=False, sanbox_response=None): doc.status = "Failed" doc.error = frappe.get_traceback() doc.save() - frappe.log_error(doc.error, "{0} Failed".format(doc.name)) + frappe.log_error(doc.error, f"{doc.name} Failed") @frappe.whitelist(allow_guest=True) @@ -498,7 +495,7 @@ def razorpay_subscription_callback(): queue="long", timeout=600, is_async=True, - **{"doctype": "Integration Request", "docname": doc.name} + **{"doctype": "Integration Request", "docname": doc.name}, ) except frappe.InvalidStatusError: @@ -521,7 +518,7 @@ def validate_payment_callback(data): settings = controller.get_settings(data) resp = make_get_request( - "https://api.razorpay.com/v1/subscriptions/{0}".format(subscription_id), + f"https://api.razorpay.com/v1/subscriptions/{subscription_id}", auth=(settings.api_key, settings.api_secret), ) diff --git a/frappe/integrations/doctype/s3_backup_settings/s3_backup_settings.py b/frappe/integrations/doctype/s3_backup_settings/s3_backup_settings.py index 015d4f0467..1c2d39be10 100755 --- a/frappe/integrations/doctype/s3_backup_settings/s3_backup_settings.py +++ b/frappe/integrations/doctype/s3_backup_settings/s3_backup_settings.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2017, Frappe Technologies and contributors # License: MIT. See LICENSE import os diff --git a/frappe/integrations/doctype/s3_backup_settings/test_s3_backup_settings.py b/frappe/integrations/doctype/s3_backup_settings/test_s3_backup_settings.py index c6dbee2c20..48b1ccd113 100755 --- a/frappe/integrations/doctype/s3_backup_settings/test_s3_backup_settings.py +++ b/frappe/integrations/doctype/s3_backup_settings/test_s3_backup_settings.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2017, Frappe Technologies and Contributors # License: MIT. See LICENSE import unittest diff --git a/frappe/integrations/doctype/slack_webhook_url/slack_webhook_url.py b/frappe/integrations/doctype/slack_webhook_url/slack_webhook_url.py index cf6a23fb34..d71d7075a6 100644 --- a/frappe/integrations/doctype/slack_webhook_url/slack_webhook_url.py +++ b/frappe/integrations/doctype/slack_webhook_url/slack_webhook_url.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2018, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/integrations/doctype/slack_webhook_url/test_slack_webhook_url.py b/frappe/integrations/doctype/slack_webhook_url/test_slack_webhook_url.py index 4bd71033bb..16b1bcd3c2 100644 --- a/frappe/integrations/doctype/slack_webhook_url/test_slack_webhook_url.py +++ b/frappe/integrations/doctype/slack_webhook_url/test_slack_webhook_url.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2018, Frappe Technologies and Contributors # License: MIT. See LICENSE import unittest diff --git a/frappe/integrations/doctype/social_login_key/social_login_key.py b/frappe/integrations/doctype/social_login_key/social_login_key.py index 8c19767107..e38f19bb2b 100644 --- a/frappe/integrations/doctype/social_login_key/social_login_key.py +++ b/frappe/integrations/doctype/social_login_key/social_login_key.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2017, Frappe Technologies and contributors # License: MIT. See LICENSE @@ -69,7 +68,7 @@ class SocialLoginKey(Document): if self.provider_name in icon_map: icon_file = icon_map[self.provider_name] - self.icon = "/assets/frappe/icons/social/{0}".format(icon_file) + self.icon = f"/assets/frappe/icons/social/{icon_file}" @frappe.whitelist() def get_social_login_provider(self, provider, initialize=False): diff --git a/frappe/integrations/doctype/social_login_key/test_social_login_key.py b/frappe/integrations/doctype/social_login_key/test_social_login_key.py index be4c1f7c49..c51ccb2c0f 100644 --- a/frappe/integrations/doctype/social_login_key/test_social_login_key.py +++ b/frappe/integrations/doctype/social_login_key/test_social_login_key.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2017, Frappe Technologies and Contributors # License: MIT. See LICENSE import unittest diff --git a/frappe/integrations/doctype/stripe_settings/stripe_settings.py b/frappe/integrations/doctype/stripe_settings/stripe_settings.py index bc8b0dfa17..8e1d383790 100644 --- a/frappe/integrations/doctype/stripe_settings/stripe_settings.py +++ b/frappe/integrations/doctype/stripe_settings/stripe_settings.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2017, Frappe Technologies and contributors # License: MIT. See LICENSE @@ -163,7 +162,7 @@ class StripeSettings(Document): def validate_stripe_credentails(self): if self.publishable_key and self.secret_key: header = { - "Authorization": "Bearer {0}".format( + "Authorization": "Bearer {}".format( self.get_password(fieldname="secret_key", raise_exception=False) ) } @@ -190,7 +189,7 @@ class StripeSettings(Document): ) def get_payment_url(self, **kwargs): - return get_url("./integrations/stripe_checkout?{0}".format(urlencode(kwargs))) + return get_url(f"./integrations/stripe_checkout?{urlencode(kwargs)}") def create_request(self, data): import stripe diff --git a/frappe/integrations/doctype/stripe_settings/test_stripe_settings.py b/frappe/integrations/doctype/stripe_settings/test_stripe_settings.py index e13359fa6d..eed87bfcaf 100644 --- a/frappe/integrations/doctype/stripe_settings/test_stripe_settings.py +++ b/frappe/integrations/doctype/stripe_settings/test_stripe_settings.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2018, Frappe Technologies and Contributors # License: MIT. See LICENSE import unittest diff --git a/frappe/integrations/doctype/token_cache/test_token_cache.py b/frappe/integrations/doctype/token_cache/test_token_cache.py index 6a3b16e72c..a9366d84d3 100644 --- a/frappe/integrations/doctype/token_cache/test_token_cache.py +++ b/frappe/integrations/doctype/token_cache/test_token_cache.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and contributors # License: MIT. See LICENSE import unittest diff --git a/frappe/integrations/doctype/token_cache/token_cache.py b/frappe/integrations/doctype/token_cache/token_cache.py index 7d961fe1cc..25f07a16ba 100644 --- a/frappe/integrations/doctype/token_cache/token_cache.py +++ b/frappe/integrations/doctype/token_cache/token_cache.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/integrations/doctype/webhook/__init__.py b/frappe/integrations/doctype/webhook/__init__.py index 915d2819ee..8e9c72c1a9 100644 --- a/frappe/integrations/doctype/webhook/__init__.py +++ b/frappe/integrations/doctype/webhook/__init__.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2017, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/integrations/doctype/webhook/test_webhook.py b/frappe/integrations/doctype/webhook/test_webhook.py index 5386a75573..5ac75f5b52 100644 --- a/frappe/integrations/doctype/webhook/test_webhook.py +++ b/frappe/integrations/doctype/webhook/test_webhook.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2017, Frappe Technologies and Contributors # License: MIT. See LICENSE import unittest diff --git a/frappe/integrations/doctype/webhook/webhook.py b/frappe/integrations/doctype/webhook/webhook.py index 22abcf9a99..27fdd662ed 100644 --- a/frappe/integrations/doctype/webhook/webhook.py +++ b/frappe/integrations/doctype/webhook/webhook.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2017, Frappe Technologies and contributors # License: MIT. See LICENSE @@ -8,7 +7,6 @@ import hashlib import hmac import json from time import sleep -from typing import Dict, Optional from urllib.parse import urlparse import requests @@ -114,7 +112,7 @@ def enqueue_webhook(doc, webhook) -> None: webhook.log_error("Webhook failed") -def log_request(url: str, headers: Dict, data: Dict, res: Optional[requests.Response] = None): +def log_request(url: str, headers: dict, data: dict, res: requests.Response | None = None): request_log = frappe.get_doc( { "doctype": "Webhook Request Log", diff --git a/frappe/integrations/doctype/webhook_data/webhook_data.py b/frappe/integrations/doctype/webhook_data/webhook_data.py index 1bb0d901df..39016cb864 100644 --- a/frappe/integrations/doctype/webhook_data/webhook_data.py +++ b/frappe/integrations/doctype/webhook_data/webhook_data.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2017, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/integrations/doctype/webhook_header/webhook_header.py b/frappe/integrations/doctype/webhook_header/webhook_header.py index 9478d227e4..f5f85d1afe 100644 --- a/frappe/integrations/doctype/webhook_header/webhook_header.py +++ b/frappe/integrations/doctype/webhook_header/webhook_header.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2017, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/integrations/frappe_providers/__init__.py b/frappe/integrations/frappe_providers/__init__.py index 161937a936..630c2c08b4 100644 --- a/frappe/integrations/frappe_providers/__init__.py +++ b/frappe/integrations/frappe_providers/__init__.py @@ -9,5 +9,5 @@ def migrate_to(local_site, frappe_provider): if frappe_provider in ("frappe.cloud", "frappecloud.com"): return frappecloud_migrator(local_site) else: - print("{} is not supported yet".format(frappe_provider)) + print(f"{frappe_provider} is not supported yet") sys.exit(1) diff --git a/frappe/integrations/frappe_providers/frappecloud.py b/frappe/integrations/frappe_providers/frappecloud.py index 0a01989d5e..64aa847a0e 100644 --- a/frappe/integrations/frappe_providers/frappecloud.py +++ b/frappe/integrations/frappe_providers/frappecloud.py @@ -8,7 +8,7 @@ import frappe def frappecloud_migrator(local_site): print("Retrieving Site Migrator...") remote_site = frappe.conf.frappecloud_url or "frappecloud.com" - request_url = "https://{}/api/method/press.api.script".format(remote_site) + request_url = f"https://{remote_site}/api/method/press.api.script" request = requests.get(request_url) if request.status_code / 100 != 2: @@ -32,5 +32,5 @@ def frappecloud_migrator(local_site): py = sys.executable script = tempfile.NamedTemporaryFile(mode="w") script.write(script_contents) - print("Site Migrator stored at {}".format(script.name)) + print(f"Site Migrator stored at {script.name}") os.execv(py, [py, script.name, local_site]) diff --git a/frappe/integrations/offsite_backup_utils.py b/frappe/integrations/offsite_backup_utils.py index 307f1525fe..620f692ad0 100644 --- a/frappe/integrations/offsite_backup_utils.py +++ b/frappe/integrations/offsite_backup_utils.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and contributors # License: MIT. See LICENSE @@ -13,8 +12,8 @@ def send_email(success, service_name, doctype, email_field, error_status=None): recipients = get_recipients(doctype, email_field) if not recipients: frappe.log_error( - "No Email Recipient found for {0}".format(service_name), - "{0}: Failed to send backup status email".format(service_name), + f"No Email Recipient found for {service_name}", + f"{service_name}: Failed to send backup status email", ) return @@ -25,15 +24,15 @@ def send_email(success, service_name, doctype, email_field, error_status=None): subject = "Backup Upload Successful" message = """

Backup Uploaded Successfully!

-

Hi there, this is just to inform you that your backup was successfully uploaded to your {0} bucket. So relax!

""".format( +

Hi there, this is just to inform you that your backup was successfully uploaded to your {} bucket. So relax!

""".format( service_name ) else: subject = "[Warning] Backup Upload Failed" message = """

Backup Upload Failed!

-

Oops, your automated backup to {0} failed.

-

Error message: {1}

+

Oops, your automated backup to {} failed.

+

Error message: {}

Please contact your system manager for more information.

""".format( service_name, error_status ) diff --git a/frappe/integrations/utils.py b/frappe/integrations/utils.py index 1440c80399..f215a73dc6 100644 --- a/frappe/integrations/utils.py +++ b/frappe/integrations/utils.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and contributors # License: MIT. See LICENSE @@ -50,7 +49,7 @@ def create_request_log( error=None, request_headers=None, output=None, - **kwargs + **kwargs, ): """ DEPRECATED: The parameter integration_type will be removed in the next major release. @@ -102,7 +101,7 @@ def get_payment_gateway_controller(payment_gateway): gateway = frappe.get_doc("Payment Gateway", payment_gateway) if gateway.gateway_controller is None: try: - return frappe.get_doc("{0} Settings".format(payment_gateway)) + return frappe.get_doc(f"{payment_gateway} Settings") except Exception: frappe.throw(_("{0} Settings not found").format(payment_gateway)) else: @@ -116,7 +115,7 @@ def get_payment_gateway_controller(payment_gateway): def get_checkout_url(**kwargs): try: if kwargs.get("payment_gateway"): - doc = frappe.get_doc("{0} Settings".format(kwargs.get("payment_gateway"))) + doc = frappe.get_doc("{} Settings".format(kwargs.get("payment_gateway"))) return doc.get_payment_url(**kwargs) else: raise Exception diff --git a/frappe/middlewares.py b/frappe/middlewares.py index cd47b7210f..168d129ebe 100644 --- a/frappe/middlewares.py +++ b/frappe/middlewares.py @@ -13,7 +13,7 @@ from frappe.utils import cstr, get_site_name class StaticDataMiddleware(SharedDataMiddleware): def __call__(self, environ, start_response): self.environ = environ - return super(StaticDataMiddleware, self).__call__(environ, start_response) + return super().__call__(environ, start_response) def get_directory_loader(self, directory): def loader(path): diff --git a/frappe/model/base_document.py b/frappe/model/base_document.py index 8e417bb45c..d3e7656d6d 100644 --- a/frappe/model/base_document.py +++ b/frappe/model/base_document.py @@ -2,7 +2,6 @@ # License: MIT. See LICENSE import datetime import json -from typing import Dict, List import frappe from frappe import _, _dict @@ -59,9 +58,7 @@ def get_controller(doctype): module_path, classname = import_path.rsplit(".", 1) module = frappe.get_module(module_path) if not hasattr(module, classname): - raise ImportError( - "{0}: {1} does not exist in module {2}".format(doctype, classname, module_path) - ) + raise ImportError(f"{doctype}: {classname} does not exist in module {module_path}") else: module = load_doctype_module(doctype, module_name) classname = doctype.replace(" ", "").replace("-", "") @@ -86,7 +83,7 @@ def get_controller(doctype): return site_controllers[doctype] -class BaseDocument(object): +class BaseDocument: _reserved_keywords = { "doctype", "meta", @@ -300,7 +297,7 @@ class BaseDocument(object): def get_valid_dict( self, sanitize=True, convert_dates_to_str=False, ignore_nulls=False, ignore_virtual=False - ) -> Dict: + ) -> dict: d = _dict() for fieldname in self.meta.get_valid_columns(): # column is valid, we can use getattr @@ -382,7 +379,7 @@ class BaseDocument(object): if key not in self.__dict__: self.__dict__[key] = None - def get_valid_columns(self) -> List[str]: + def get_valid_columns(self) -> list[str]: if self.doctype not in frappe.local.valid_columns: if self.doctype in DOCTYPES_FOR_DOCTYPE: from frappe.model.meta import get_table_columns @@ -412,7 +409,7 @@ class BaseDocument(object): no_default_fields=False, convert_dates_to_str=False, no_child_table_fields=False, - ) -> Dict: + ) -> dict: doc = self.get_valid_dict(convert_dates_to_str=convert_dates_to_str, ignore_nulls=no_nulls) doc["doctype"] = self.doctype @@ -694,7 +691,7 @@ class BaseDocument(object): if self.get("parentfield"): return "{} #{}: {}: {}".format(_("Row"), self.idx, _(df.label), docname) - return "{}: {}".format(_(df.label), docname) + return f"{_(df.label)}: {docname}" invalid_links = [] cancelled_links = [] @@ -928,7 +925,7 @@ class BaseDocument(object): if self.get("parentfield"): reference = _("{0}, Row {1}").format(_(self.doctype), self.idx) else: - reference = "{0} {1}".format(_(self.doctype), self.name) + reference = f"{_(self.doctype)} {self.name}" frappe.throw( _("{0}: '{1}' ({3}) will get truncated, as max characters allowed is {2}").format( diff --git a/frappe/model/db_query.py b/frappe/model/db_query.py index 7fb38848e2..9cf831a8b9 100644 --- a/frappe/model/db_query.py +++ b/frappe/model/db_query.py @@ -6,7 +6,6 @@ import copy import json import re from datetime import datetime -from typing import List import frappe import frappe.defaults @@ -52,7 +51,7 @@ STRICT_UNION_PATTERN = re.compile(r".*\s(union).*\s") ORDER_GROUP_PATTERN = re.compile(r".*[^a-z0-9-_ ,`'\"\.\(\)].*") -class DatabaseQuery(object): +class DatabaseQuery: def __init__(self, doctype, user=None): self.doctype = doctype self.tables = [] @@ -98,7 +97,7 @@ class DatabaseQuery(object): pluck=None, ignore_ddl=False, parent_doctype=None, - ) -> List: + ) -> list: if ( not ignore_permissions @@ -926,7 +925,7 @@ class DatabaseQuery(object): def add_limit(self): if self.limit_page_length: - return "limit %s offset %s" % (self.limit_page_length, self.limit_start) + return f"limit {self.limit_page_length} offset {self.limit_start}" else: return "" @@ -1070,12 +1069,12 @@ def get_between_date_filter(value, df=None): to_date = add_to_date(to_date, days=1) if df and df.fieldtype == "Datetime": - data = "'%s' AND '%s'" % ( + data = "'{}' AND '{}'".format( frappe.db.format_datetime(from_date), frappe.db.format_datetime(to_date), ) else: - data = "'%s' AND '%s'" % (frappe.db.format_date(from_date), frappe.db.format_date(to_date)) + data = f"'{frappe.db.format_date(from_date)}' AND '{frappe.db.format_date(to_date)}'" return data diff --git a/frappe/model/delete_doc.py b/frappe/model/delete_doc.py index 606d3f89f1..b555dfc5dc 100644 --- a/frappe/model/delete_doc.py +++ b/frappe/model/delete_doc.py @@ -3,7 +3,6 @@ import os import shutil -from typing import List import frappe import frappe.defaults @@ -189,7 +188,7 @@ def update_naming_series(doc): revert_series_if_last(doc.meta.autoname, doc.name, doc) -def delete_from_table(doctype: str, name: str, ignore_doctypes: List[str], doc): +def delete_from_table(doctype: str, name: str, ignore_doctypes: list[str], doc): if doctype != "DocType" and doctype == name: frappe.db.delete("Singles", {"doctype": name}) else: @@ -339,7 +338,7 @@ def check_if_doc_is_dynamically_linked(doc, method="Delete"): reference_doctype = refdoc.parenttype if meta.istable else df.parent reference_docname = refdoc.parent if meta.istable else refdoc.name - at_position = "at Row: {0}".format(refdoc.idx) if meta.istable else "" + at_position = f"at Row: {refdoc.idx}" if meta.istable else "" raise_link_exists_exception(doc, reference_doctype, reference_docname, at_position) @@ -432,7 +431,7 @@ def insert_feed(doc): "doctype": "Comment", "comment_type": "Deleted", "reference_doctype": doc.doctype, - "subject": "{0} {1}".format(_(doc.doctype), doc.name), + "subject": f"{_(doc.doctype)} {doc.name}", "full_name": get_fullname(doc.owner), } ).insert(ignore_permissions=True) diff --git a/frappe/model/docfield.py b/frappe/model/docfield.py index 195385a2e1..c54a3855cb 100644 --- a/frappe/model/docfield.py +++ b/frappe/model/docfield.py @@ -45,7 +45,7 @@ def update_parent_field(f, new): if f["fieldtype"] in frappe.model.table_fields: frappe.db.begin() frappe.db.sql( - """update `tab%s` set parentfield=%s where parentfield=%s""" % (f["options"], "%s", "%s"), + """update `tab{}` set parentfield={} where parentfield={}""".format(f["options"], "%s", "%s"), (new, f["fieldname"]), ) frappe.db.commit() @@ -56,7 +56,7 @@ def get_change_column_query(f, new): desc = frappe.db.sql("desc `tab%s`" % f["parent"]) for d in desc: if d[0] == f["fieldname"]: - return "alter table `tab%s` change `%s` `%s` %s" % (f["parent"], f["fieldname"], new, d[1]) + return "alter table `tab{}` change `{}` `{}` {}".format(f["parent"], f["fieldname"], new, d[1]) def supports_translation(fieldtype): diff --git a/frappe/model/document.py b/frappe/model/document.py index 898c40861c..9b781b1999 100644 --- a/frappe/model/document.py +++ b/frappe/model/document.py @@ -3,7 +3,6 @@ import hashlib import json import time -from typing import List from werkzeug.exceptions import NotFound @@ -112,7 +111,7 @@ class Document(BaseDocument): if kwargs: # init base document - super(Document, self).__init__(kwargs) + super().__init__(kwargs) self.init_child_tables() self.init_valid_columns() @@ -136,7 +135,7 @@ class Document(BaseDocument): single_doc["name"] = self.doctype del single_doc["__islocal"] - super(Document, self).__init__(single_doc) + super().__init__(single_doc) self.init_valid_columns() self._fix_numeric_types() @@ -149,7 +148,7 @@ class Document(BaseDocument): _("{0} {1} not found").format(_(self.doctype), self.name), frappe.DoesNotExistError ) - super(Document, self).__init__(d) + super().__init__(d) for df in self._get_table_fields(): # Make sure not to query the DB for a child table, if it is a virtual one. @@ -401,9 +400,9 @@ class Document(BaseDocument): if rows: # select rows that do not match the ones in the document deleted_rows = frappe.db.sql( - """select name from `tab{0}` where parent=%s + """select name from `tab{}` where parent=%s and parenttype=%s and parentfield=%s - and name not in ({1})""".format( + and name not in ({})""".format( df.options, ",".join(["%s"] * len(rows)) ), [self.name, self.doctype, fieldname] + rows, @@ -756,7 +755,7 @@ class Document(BaseDocument): conflict = True else: tmp = frappe.db.sql( - """select modified, docstatus from `tab{0}` + """select modified, docstatus from `tab{}` where name = %s for update""".format( self.doctype ), @@ -779,7 +778,7 @@ class Document(BaseDocument): if conflict: frappe.msgprint( _("Error: Document has been modified after you have opened it") - + (" (%s, %s). " % (modified, self.modified)) + + (f" ({modified}, {self.modified}). ") + _("Please refresh to get the latest document."), raise_exception=frappe.TimestampMismatchError, ) @@ -874,7 +873,7 @@ class Document(BaseDocument): raise frappe.MandatoryError( "[{doctype}, {name}]: {fields}".format( - fields=", ".join((each[0] for each in missing)), doctype=self.doctype, name=self.name + fields=", ".join(each[0] for each in missing), doctype=self.doctype, name=self.name ) ) @@ -890,14 +889,14 @@ class Document(BaseDocument): cancelled_links.extend(result[1]) if invalid_links: - msg = ", ".join((each[2] for each in invalid_links)) + msg = ", ".join(each[2] for each in invalid_links) frappe.throw(_("Could not find {0}").format(msg), frappe.LinkValidationError) if cancelled_links: - msg = ", ".join((each[2] for each in cancelled_links)) + msg = ", ".join(each[2] for each in cancelled_links) frappe.throw(_("Cannot link cancelled document: {0}").format(msg), frappe.CancelledLinkError) - def get_all_children(self, parenttype=None) -> List["Document"]: + def get_all_children(self, parenttype=None) -> list["Document"]: """Returns all children documents from **Table** type fields in a list.""" children = [] @@ -1268,7 +1267,7 @@ class Document(BaseDocument): def is_whitelisted(self, method_name): method = getattr(self, method_name, None) if not method: - raise NotFound("Method {0} not found".format(method_name)) + raise NotFound(f"Method {method_name} not found") is_whitelisted(getattr(method, "__func__", method)) diff --git a/frappe/model/mapper.py b/frappe/model/mapper.py index 59f211e322..9df79ef276 100644 --- a/frappe/model/mapper.py +++ b/frappe/model/mapper.py @@ -231,7 +231,7 @@ def map_fetch_fields(target_doc, df, no_copy_fields): linked_doc = None # options should be like "link_fieldname.fieldname_in_liked_doc" - for fetch_df in target_doc.meta.get("fields", {"fetch_from": "^{0}.".format(df.fieldname)}): + for fetch_df in target_doc.meta.get("fields", {"fetch_from": f"^{df.fieldname}."}): if not (fetch_df.fieldtype == "Read Only" or fetch_df.read_only): continue diff --git a/frappe/model/meta.py b/frappe/model/meta.py index 9f5c2e7611..74b8be953b 100644 --- a/frappe/model/meta.py +++ b/frappe/model/meta.py @@ -17,7 +17,6 @@ Example: import json import os from datetime import datetime -from typing import List import click @@ -68,7 +67,7 @@ def get_table_columns(doctype): def load_doctype_from_file(doctype): fname = frappe.scrub(doctype) - with open(frappe.get_app_path("frappe", "core", "doctype", fname, fname + ".json"), "r") as f: + with open(frappe.get_app_path("frappe", "core", "doctype", fname, fname + ".json")) as f: txt = json.loads(f.read()) for d in txt.get("fields", []): @@ -104,19 +103,19 @@ class Meta(Document): def __init__(self, doctype): self._fields = {} if isinstance(doctype, dict): - super(Meta, self).__init__(doctype) + super().__init__(doctype) elif isinstance(doctype, Document): - super(Meta, self).__init__(doctype.as_dict()) + super().__init__(doctype.as_dict()) self.process() else: - super(Meta, self).__init__("DocType", doctype) + super().__init__("DocType", doctype) self.process() def load_from_db(self): try: - super(Meta, self).load_from_db() + super().load_from_db() except frappe.DoesNotExistError: if self.doctype == "DocType" and self.name in self.special_doctypes: self.__dict__.update(load_doctype_from_file(self.name)) @@ -347,7 +346,7 @@ class Meta(Document): def get_workflow(self): return get_workflow_name(self.name) - def get_naming_series_options(self) -> List[str]: + def get_naming_series_options(self) -> list[str]: """Get list naming series options.""" field = self.get_field("naming_series") @@ -434,7 +433,7 @@ class Meta(Document): # set the fields in order if specified # order is saved as `links_order` - order = json.loads(self.get("{}_order".format(fieldname)) or "[]") + order = json.loads(self.get(f"{fieldname}_order") or "[]") if order: name_map = {d.name: d for d in self.get(fieldname)} new_list = [] diff --git a/frappe/model/naming.py b/frappe/model/naming.py index b674b0cd81..bae40c68c1 100644 --- a/frappe/model/naming.py +++ b/frappe/model/naming.py @@ -2,7 +2,7 @@ # License: MIT. See LICENSE import re -from typing import TYPE_CHECKING, Callable, List, Optional, Union +from typing import TYPE_CHECKING, Callable, Optional import frappe from frappe import _ @@ -81,7 +81,7 @@ class NamingSeries: return prefix - def get_preview(self, doc=None) -> List[str]: + def get_preview(self, doc=None) -> list[str]: """Generate preview of naming series without using DB counters""" generated_names = [] for count in range(1, 4): @@ -271,10 +271,10 @@ def make_autoname(key="", doctype="", doc=""): def parse_naming_series( - parts: Union[List[str], str], + parts: list[str] | str, doctype=None, doc: Optional["Document"] = None, - number_generator: Optional[Callable[[str, int], str]] = None, + number_generator: Callable[[str, int], str] | None = None, ) -> str: """Parse the naming series and get next name. @@ -410,7 +410,7 @@ def revert_series_if_last(key, name, doc=None): frappe.db.sql("UPDATE `tabSeries` SET `current` = `current` - 1 WHERE `name`=%s", prefix) -def get_default_naming_series(doctype: str) -> Optional[str]: +def get_default_naming_series(doctype: str) -> str | None: """get default value for `naming_series` property""" naming_series_options = frappe.get_meta(doctype).get_naming_series_options() @@ -421,7 +421,7 @@ def get_default_naming_series(doctype: str) -> Optional[str]: return option -def validate_name(doctype: str, name: Union[int, str], case: Optional[str] = None): +def validate_name(doctype: str, name: int | str, case: str | None = None): if not name: frappe.throw(_("No Name Specified for {0}").format(doctype)) @@ -450,7 +450,7 @@ def validate_name(doctype: str, name: Union[int, str], case: Optional[str] = Non special_characters = "<>" if re.findall(f"[{special_characters}]+", name): - message = ", ".join("'{0}'".format(c) for c in special_characters) + message = ", ".join(f"'{c}'" for c in special_characters) frappe.throw( _("Name cannot contain special characters like {0}").format(message), frappe.NameError ) @@ -464,7 +464,7 @@ def append_number_if_name_exists(doctype, value, fieldname="name", separator="-" filters.update({fieldname: value}) exists = frappe.db.exists(doctype, filters) - regex = "^{value}{separator}\\d+$".format(value=re.escape(value), separator=separator) + regex = f"^{re.escape(value)}{separator}\\d+$" if exists: last = frappe.db.sql( @@ -482,7 +482,7 @@ def append_number_if_name_exists(doctype, value, fieldname="name", separator="-" else: count = "1" - value = "{0}{1}{2}".format(value, separator, count) + value = f"{value}{separator}{count}" return value diff --git a/frappe/model/rename_doc.py b/frappe/model/rename_doc.py index 25e471d4b0..b05df57364 100644 --- a/frappe/model/rename_doc.py +++ b/frappe/model/rename_doc.py @@ -1,6 +1,6 @@ # Copyright (c) 2022, Frappe Technologies Pvt. Ltd. and Contributors # License: MIT. See LICENSE -from typing import TYPE_CHECKING, Dict, List, Optional +from typing import TYPE_CHECKING import frappe from frappe import _, bold @@ -22,8 +22,8 @@ def update_document_title( *, doctype: str, docname: str, - title: Optional[str] = None, - name: Optional[str] = None, + title: str | None = None, + name: str | None = None, merge: bool = False, enqueue: bool = False, **kwargs, @@ -106,8 +106,8 @@ def update_document_title( def rename_doc( - doctype: Optional[str] = None, - old: Optional[str] = None, + doctype: str | None = None, + old: str | None = None, new: str = None, force: bool = False, merge: bool = False, @@ -115,7 +115,7 @@ def rename_doc( ignore_if_exists: bool = False, show_alert: bool = True, rebuild_search: bool = True, - doc: Optional[Document] = None, + doc: Document | None = None, validate: bool = True, ) -> str: """Rename a doc(dt, old) to doc(dt, new) and update all linked fields of type "Link". @@ -253,7 +253,7 @@ def update_assignments(old: str, new: str, doctype: str) -> None: frappe.db.set_value(doctype, new, "_assign", frappe.as_json(unique_assignments, indent=0)) -def update_user_settings(old: str, new: str, link_fields: List[Dict]) -> None: +def update_user_settings(old: str, new: str, link_fields: list[dict]) -> None: """ Update the user settings of all the linked doctypes while renaming. """ @@ -412,7 +412,7 @@ def update_child_docs(old: str, new: str, meta: "Meta") -> None: frappe.qb.update(df.options).set("parent", new).where(Field("parent") == old).run() -def update_link_field_values(link_fields: List[Dict], old: str, new: str, doctype: str) -> None: +def update_link_field_values(link_fields: list[dict], old: str, new: str, doctype: str) -> None: for field in link_fields: if field["issingle"]: try: @@ -448,7 +448,7 @@ def update_link_field_values(link_fields: List[Dict], old: str, new: str, doctyp field["parent"] = new -def get_link_fields(doctype: str) -> List[Dict]: +def get_link_fields(doctype: str) -> list[dict]: # get link fields from tabDocField if not frappe.flags.link_fields: frappe.flags.link_fields = {} @@ -519,7 +519,7 @@ def update_options_for_fieldtype(fieldtype: str, old: str, new: str) -> None: ).run() -def get_select_fields(old: str, new: str) -> List[Dict]: +def get_select_fields(old: str, new: str) -> list[dict]: """ get select type fields where doctype's name is hardcoded as new line separated list @@ -646,8 +646,8 @@ def rename_dynamic_links(doctype: str, old: str, new: str): def bulk_rename( - doctype: str, rows: Optional[List[List]] = None, via_console: bool = False -) -> Optional[List[str]]: + doctype: str, rows: list[list] | None = None, via_console: bool = False +) -> list[str] | None: """Bulk rename documents :param doctype: DocType to be renamed @@ -688,7 +688,7 @@ def bulk_rename( def update_linked_doctypes( - doctype: str, docname: str, linked_to: str, value: str, ignore_doctypes: Optional[List] = None + doctype: str, docname: str, linked_to: str, value: str, ignore_doctypes: list | None = None ) -> None: from frappe.model.utils.rename_doc import update_linked_doctypes @@ -704,8 +704,8 @@ def update_linked_doctypes( def get_fetch_fields( - doctype: str, linked_to: str, ignore_doctypes: Optional[List] = None -) -> List[Dict]: + doctype: str, linked_to: str, ignore_doctypes: list | None = None +) -> list[dict]: from frappe.model.utils.rename_doc import get_fetch_fields show_deprecation_warning("get_fetch_fields") diff --git a/frappe/model/sync.py b/frappe/model/sync.py index 93b883cda6..df3999054a 100644 --- a/frappe/model/sync.py +++ b/frappe/model/sync.py @@ -84,7 +84,7 @@ def sync_for(app_name, force=0, reset_permissions=False): frappe.db.commit() # show progress bar - update_progress_bar("Updating DocTypes for {0}".format(app_name), i, l) + update_progress_bar(f"Updating DocTypes for {app_name}", i, l) # print each progress bar on new line print() diff --git a/frappe/model/utils/__init__.py b/frappe/model/utils/__init__.py index 6385b61c38..351b19c8eb 100644 --- a/frappe/model/utils/__init__.py +++ b/frappe/model/utils/__init__.py @@ -47,7 +47,7 @@ def set_field_property(filters, key, value): for d in docs: d.get("fields", filters)[0].set(key, value) d.save() - print("Updated {0}".format(d.name)) + print(f"Updated {d.name}") frappe.db.commit() @@ -70,7 +70,7 @@ def render_include(content): for path in paths: app, app_path = path.split("/", 1) - with io.open(frappe.get_app_path(app, app_path), "r", encoding="utf-8") as f: + with open(frappe.get_app_path(app, app_path), encoding="utf-8") as f: include = f.read() if path.endswith(".html"): include = html_to_js_template(path, include) diff --git a/frappe/model/utils/link_count.py b/frappe/model/utils/link_count.py index 25dfe58139..9a7694b9f8 100644 --- a/frappe/model/utils/link_count.py +++ b/frappe/model/utils/link_count.py @@ -42,7 +42,7 @@ def update_link_count(): if key[0] not in ignore_doctypes: try: frappe.db.sql( - "update `tab{0}` set idx = idx + {1} where name=%s".format(key[0], count), + f"update `tab{key[0]}` set idx = idx + {count} where name=%s", key[1], auto_commit=1, ) diff --git a/frappe/model/utils/rename_doc.py b/frappe/model/utils/rename_doc.py index 00e2d78d5f..ae6649f057 100644 --- a/frappe/model/utils/rename_doc.py +++ b/frappe/model/utils/rename_doc.py @@ -2,14 +2,13 @@ # License: MIT. See LICENSE from itertools import product -from typing import Dict, List, Optional import frappe from frappe.model.rename_doc import get_link_fields def update_linked_doctypes( - doctype: str, docname: str, linked_to: str, value: str, ignore_doctypes: Optional[List] = None + doctype: str, docname: str, linked_to: str, value: str, ignore_doctypes: list | None = None ): """ linked_doctype_info_list = list formed by get_fetch_fields() function @@ -31,8 +30,8 @@ def update_linked_doctypes( def get_fetch_fields( - doctype: str, linked_to: str, ignore_doctypes: Optional[List] = None -) -> List[Dict]: + doctype: str, linked_to: str, ignore_doctypes: list | None = None +) -> list[dict]: """ doctype = Master DocType in which the changes are being made linked_to = DocType name of the field thats being updated in Master diff --git a/frappe/model/utils/rename_field.py b/frappe/model/utils/rename_field.py index 56e69455ef..9e4fc5d84a 100644 --- a/frappe/model/utils/rename_field.py +++ b/frappe/model/utils/rename_field.py @@ -40,7 +40,7 @@ def rename_field(doctype, old_fieldname, new_fieldname): ) else: # copy field value - frappe.db.sql("""update `tab%s` set `%s`=`%s`""" % (doctype, new_fieldname, old_fieldname)) + frappe.db.sql(f"""update `tab{doctype}` set `{new_fieldname}`=`{old_fieldname}`""") update_reports(doctype, old_fieldname, new_fieldname) update_users_report_view_settings(doctype, old_fieldname, new_fieldname) diff --git a/frappe/model/utils/user_settings.py b/frappe/model/utils/user_settings.py index a6ae1a818e..c12c7e27ba 100644 --- a/frappe/model/utils/user_settings.py +++ b/frappe/model/utils/user_settings.py @@ -11,9 +11,7 @@ filter_dict = {"doctype": 0, "docfield": 1, "operator": 2, "value": 3} def get_user_settings(doctype, for_update=False): - user_settings = frappe.cache().hget( - "_user_settings", "{0}::{1}".format(doctype, frappe.session.user) - ) + user_settings = frappe.cache().hget("_user_settings", f"{doctype}::{frappe.session.user}") if user_settings is None: user_settings = frappe.db.sql( @@ -43,9 +41,7 @@ def update_user_settings(doctype, user_settings, for_update=False): current.update(user_settings) - frappe.cache().hset( - "_user_settings", "{0}::{1}".format(doctype, frappe.session.user), json.dumps(current) - ) + frappe.cache().hset("_user_settings", f"{doctype}::{frappe.session.user}", json.dumps(current)) def sync_user_settings(): @@ -103,6 +99,4 @@ def update_user_settings_data( ) # clear that user settings from the redis cache - frappe.cache().hset( - "_user_settings", "{0}::{1}".format(user_setting.doctype, user_setting.user), None - ) + frappe.cache().hset("_user_settings", f"{user_setting.doctype}::{user_setting.user}", None) diff --git a/frappe/model/workflow.py b/frappe/model/workflow.py index 96fd710d91..923fbc1b3b 100644 --- a/frappe/model/workflow.py +++ b/frappe/model/workflow.py @@ -246,15 +246,15 @@ def bulk_workflow_approval(docnames, doctype, action): except Exception as e: if not frappe.message_log: # Exception is raised manually and not from msgprint or throw - message = "{0}".format(e.__class__.__name__) + message = f"{e.__class__.__name__}" if e.args: - message += " : {0}".format(e.args[0]) + message += f" : {e.args[0]}" message_dict = {"docname": docname, "message": message} failed_transactions[docname].append(message_dict) frappe.db.rollback() frappe.log_error( - title="Workflow {0} threw an error for {1} {2}".format(action, doctype, docname), + title=f"Workflow {action} threw an error for {doctype} {docname}", reference_doctype="Workflow", reference_name=action, ) @@ -286,19 +286,19 @@ def bulk_workflow_approval(docnames, doctype, action): def print_workflow_log(messages, title, doctype, indicator): if messages.keys(): - msg = "

{0}

".format(title) + msg = f"

{title}

" for doc in messages.keys(): if len(messages[doc]): - html = "
{0}".format(frappe.utils.get_link_to_form(doctype, doc)) + html = f"
{frappe.utils.get_link_to_form(doctype, doc)}" for log in messages[doc]: if log.get("message"): - html += "
{0}
".format( + html += "
{}
".format( log.get("message") ) html += "
" else: - html = "
{0}
".format(doc) + html = f"
{doc}
" msg += html frappe.msgprint(msg, title=_("Workflow Status"), indicator=indicator, is_minimizable=True) diff --git a/frappe/modules/export_file.py b/frappe/modules/export_file.py index 8eac7a9229..e3a80d6679 100644 --- a/frappe/modules/export_file.py +++ b/frappe/modules/export_file.py @@ -113,7 +113,7 @@ def create_folder(module, dt, dn, create_init): def get_custom_module_path(module): package = frappe.db.get_value("Module Def", module, "package") if not package: - frappe.throw("Package must be set for custom Module {module}".format(module=module)) + frappe.throw(f"Package must be set for custom Module {module}") path = os.path.join(get_package_path(package), scrub(module)) if not os.path.exists(path): diff --git a/frappe/modules/import_file.py b/frappe/modules/import_file.py index d39f98f966..3690da0657 100644 --- a/frappe/modules/import_file.py +++ b/frappe/modules/import_file.py @@ -109,7 +109,7 @@ def import_file_by_path( """ try: docs = read_doc_from_file(path) - except IOError: + except OSError: print(f"{path} missing") return @@ -172,14 +172,14 @@ def import_file_by_path( def read_doc_from_file(path): doc = None if os.path.exists(path): - with open(path, "r") as f: + with open(path) as f: try: doc = json.loads(f.read()) except ValueError: - print("bad json: {0}".format(path)) + print(f"bad json: {path}") raise else: - raise IOError("%s missing" % path) + raise OSError("%s missing" % path) return doc @@ -254,7 +254,7 @@ def load_code_properties(doc, path): for key, extn in doc.get_code_fields().items(): codefile = os.path.join(dirname, filename.split(".")[0] + "." + extn) if os.path.exists(codefile): - with open(codefile, "r") as txtfile: + with open(codefile) as txtfile: doc.set(key, txtfile.read()) @@ -285,6 +285,6 @@ def reset_tree_properties(doc): # "rgt". They are automatically set and kept up-to-date. Importing them # would destroy any existing tree structure. if getattr(doc.meta, "is_tree", None) and any([doc.lft, doc.rgt]): - print('Ignoring values of `lft` and `rgt` for {} "{}"'.format(doc.doctype, doc.name)) + print(f'Ignoring values of `lft` and `rgt` for {doc.doctype} "{doc.name}"') doc.lft = None doc.rgt = None diff --git a/frappe/modules/patch_handler.py b/frappe/modules/patch_handler.py index ae6d9a6de2..f389312a4f 100644 --- a/frappe/modules/patch_handler.py +++ b/frappe/modules/patch_handler.py @@ -38,7 +38,6 @@ import configparser import time from enum import Enum from textwrap import dedent, indent -from typing import List, Optional import frappe @@ -52,7 +51,7 @@ class PatchType(Enum): post_model_sync = "post_model_sync" -def run_all(skip_failing: bool = False, patch_type: Optional[PatchType] = None) -> None: +def run_all(skip_failing: bool = False, patch_type: PatchType | None = None) -> None: """run all pending patches""" executed = set(frappe.get_all("Patch Log", fields="patch", pluck="patch")) @@ -81,7 +80,7 @@ def run_all(skip_failing: bool = False, patch_type: Optional[PatchType] = None) run_patch(patch) -def get_all_patches(patch_type: Optional[PatchType] = None) -> List[str]: +def get_all_patches(patch_type: PatchType | None = None) -> list[str]: if patch_type and not isinstance(patch_type, PatchType): frappe.throw(f"Unsupported patch type specified: {patch_type}") @@ -93,7 +92,7 @@ def get_all_patches(patch_type: Optional[PatchType] = None) -> List[str]: return patches -def get_patches_from_app(app: str, patch_type: Optional[PatchType] = None) -> List[str]: +def get_patches_from_app(app: str, patch_type: PatchType | None = None) -> list[str]: """Get patches from an app's patches.txt patches.txt can be: diff --git a/frappe/modules/utils.py b/frappe/modules/utils.py index ad6a75e900..f4a386cfc9 100644 --- a/frappe/modules/utils.py +++ b/frappe/modules/utils.py @@ -105,7 +105,7 @@ def sync_customizations(app=None): if os.path.exists(folder): for fname in os.listdir(folder): if fname.endswith(".json"): - with open(os.path.join(folder, fname), "r") as f: + with open(os.path.join(folder, fname)) as f: data = json.loads(f.read()) if data.get("sync_on_migrate"): sync_customizations_for_doctype(data, folder) @@ -164,7 +164,7 @@ def sync_customizations_for_doctype(data, folder): if data.get("custom_perms"): sync("custom_perms", "Custom DocPerm", "parent") - print("Updating customizations for {0}".format(doctype)) + print(f"Updating customizations for {doctype}") validate_fields_for_doctype(doctype) if update_schema and not frappe.db.get_value("DocType", doctype, "issingle"): @@ -317,7 +317,6 @@ def make_boilerplate(template, doc, opts=None): with open(target_file_path, "w") as target: with open( os.path.join(get_module_path("core"), "doctype", scrub(doc.doctype), "boilerplate", template), - "r", ) as source: target.write( frappe.as_unicode( diff --git a/frappe/monitor.py b/frappe/monitor.py index 74f9e06ef3..e151944b1f 100644 --- a/frappe/monitor.py +++ b/frappe/monitor.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors # License: MIT. See LICENSE diff --git a/frappe/parallel_test_runner.py b/frappe/parallel_test_runner.py index 4fd03773ef..39a00235cb 100644 --- a/frappe/parallel_test_runner.py +++ b/frappe/parallel_test_runner.py @@ -83,7 +83,7 @@ class ParallelTestRunner: test_record_filename = re.sub("^test_", "", filename).replace(".py", ".json") test_record_file_path = os.path.join(path, test_record_filename) if os.path.exists(test_record_file_path): - with open(test_record_file_path, "r") as f: + with open(test_record_file_path) as f: doc = json.loads(f.read()) doctype = doc["name"] make_test_records(doctype, commit=True) diff --git a/frappe/patches/v10_0/increase_single_table_column_length.py b/frappe/patches/v10_0/increase_single_table_column_length.py index 21b5a790ab..0b8e94a3f7 100644 --- a/frappe/patches/v10_0/increase_single_table_column_length.py +++ b/frappe/patches/v10_0/increase_single_table_column_length.py @@ -6,4 +6,4 @@ import frappe def execute(): for col in ("field", "doctype"): - frappe.db.sql_ddl("alter table `tabSingles` modify column `{0}` varchar(255)".format(col)) + frappe.db.sql_ddl(f"alter table `tabSingles` modify column `{col}` varchar(255)") diff --git a/frappe/patches/v11_0/delete_duplicate_user_permissions.py b/frappe/patches/v11_0/delete_duplicate_user_permissions.py index b986c6f825..f2ca6d51fe 100644 --- a/frappe/patches/v11_0/delete_duplicate_user_permissions.py +++ b/frappe/patches/v11_0/delete_duplicate_user_permissions.py @@ -13,7 +13,7 @@ def execute(): for record in duplicateRecords: frappe.db.sql( """delete from `tabUser Permission` - where allow=%s and user=%s and for_value=%s limit {0}""".format( + where allow=%s and user=%s and for_value=%s limit {}""".format( record.count - 1 ), (record.allow, record.user, record.for_value), diff --git a/frappe/patches/v11_0/drop_column_apply_user_permissions.py b/frappe/patches/v11_0/drop_column_apply_user_permissions.py index bfc4aee72c..0a0091624e 100644 --- a/frappe/patches/v11_0/drop_column_apply_user_permissions.py +++ b/frappe/patches/v11_0/drop_column_apply_user_permissions.py @@ -8,7 +8,7 @@ def execute(): for doctype in to_remove: if frappe.db.table_exists(doctype): if column in frappe.db.get_table_columns(doctype): - frappe.db.sql("alter table `tab{0}` drop column {1}".format(doctype, column)) + frappe.db.sql(f"alter table `tab{doctype}` drop column {column}") frappe.reload_doc("core", "doctype", "docperm", force=True) frappe.reload_doc("core", "doctype", "custom_docperm", force=True) diff --git a/frappe/patches/v11_0/fix_order_by_in_reports_json.py b/frappe/patches/v11_0/fix_order_by_in_reports_json.py index 3dfec0954f..4e955a338b 100644 --- a/frappe/patches/v11_0/fix_order_by_in_reports_json.py +++ b/frappe/patches/v11_0/fix_order_by_in_reports_json.py @@ -28,8 +28,8 @@ def execute(): sort_by = parts[1].split(" ") - json_data["order_by"] = "`tab{0}`.`{1}`".format(doc.ref_doctype, sort_by[0]) - json_data["order_by"] += " {0}".format(sort_by[1]) if len(sort_by) > 1 else "" + json_data["order_by"] = f"`tab{doc.ref_doctype}`.`{sort_by[0]}`" + json_data["order_by"] += f" {sort_by[1]}" if len(sort_by) > 1 else "" doc.json = json.dumps(json_data) doc.save() diff --git a/frappe/patches/v11_0/update_list_user_settings.py b/frappe/patches/v11_0/update_list_user_settings.py index 146b29346c..5209b9e384 100644 --- a/frappe/patches/v11_0/update_list_user_settings.py +++ b/frappe/patches/v11_0/update_list_user_settings.py @@ -13,7 +13,7 @@ def execute(): # get user_settings for each user settings = frappe.db.sql( "select * from `__UserSettings` \ - where user={0}".format( + where user={}".format( frappe.db.escape(user.user) ), as_dict=True, diff --git a/frappe/patches/v12_0/delete_duplicate_indexes.py b/frappe/patches/v12_0/delete_duplicate_indexes.py index 6a6b0b3204..f1def21f7f 100644 --- a/frappe/patches/v12_0/delete_duplicate_indexes.py +++ b/frappe/patches/v12_0/delete_duplicate_indexes.py @@ -43,10 +43,10 @@ def execute(): # build drop index query for (table_name, index_list) in final_deletion_map.items(): query_list = [] - alter_query = "ALTER TABLE `{}`".format(table_name) + alter_query = f"ALTER TABLE `{table_name}`" for index in index_list: - query_list.append("{} DROP INDEX `{}`".format(alter_query, index)) + query_list.append(f"{alter_query} DROP INDEX `{index}`") for query in query_list: try: diff --git a/frappe/patches/v12_0/fix_public_private_files.py b/frappe/patches/v12_0/fix_public_private_files.py index e1ad2f1862..382e3c2db1 100644 --- a/frappe/patches/v12_0/fix_public_private_files.py +++ b/frappe/patches/v12_0/fix_public_private_files.py @@ -30,7 +30,7 @@ def generate_file(file_name): file_doc.file_url = new_doc.file_url file_doc.save() - except IOError: + except OSError: pass except Exception as e: print(e) diff --git a/frappe/patches/v12_0/move_timeline_links_to_dynamic_links.py b/frappe/patches/v12_0/move_timeline_links_to_dynamic_links.py index 2207edd958..4d2061c5ac 100644 --- a/frappe/patches/v12_0/move_timeline_links_to_dynamic_links.py +++ b/frappe/patches/v12_0/move_timeline_links_to_dynamic_links.py @@ -22,7 +22,7 @@ def execute(): if communication.timeline_doctype and communication.timeline_name: name += 1 values.append( - """({0}, "{1}", "timeline_links", "Communication", "{2}", "{3}", "{4}", "{5}", "{6}", "{7}")""".format( + """({}, "{}", "timeline_links", "Communication", "{}", "{}", "{}", "{}", "{}", "{}")""".format( counter, str(name), frappe.db.escape(communication.name), @@ -37,7 +37,7 @@ def execute(): if communication.link_doctype and communication.link_name: name += 1 values.append( - """({0}, "{1}", "timeline_links", "Communication", "{2}", "{3}", "{4}", "{5}", "{6}", "{7}")""".format( + """({}, "{}", "timeline_links", "Communication", "{}", "{}", "{}", "{}", "{}", "{}")""".format( counter, str(name), frappe.db.escape(communication.name), @@ -55,7 +55,7 @@ def execute(): INSERT INTO `tabCommunication Link` (`idx`, `name`, `parentfield`, `parenttype`, `parent`, `link_doctype`, `link_name`, `creation`, `modified`, `modified_by`) - VALUES {0} + VALUES {} """.format( ", ".join([d for d in values]) ) diff --git a/frappe/patches/v12_0/set_correct_url_in_files.py b/frappe/patches/v12_0/set_correct_url_in_files.py index dca42a3c04..fee0b5d6fc 100644 --- a/frappe/patches/v12_0/set_correct_url_in_files.py +++ b/frappe/patches/v12_0/set_correct_url_in_files.py @@ -30,12 +30,10 @@ def execute(): if file_is_private: public_file_url = os.path.join(public_file_path, file_name) if os.path.exists(public_file_url): - frappe.db.set_value( - "File", file.name, {"file_url": "/files/{0}".format(file_name), "is_private": 0} - ) + frappe.db.set_value("File", file.name, {"file_url": f"/files/{file_name}", "is_private": 0}) else: private_file_url = os.path.join(private_file_path, file_name) if os.path.exists(private_file_url): frappe.db.set_value( - "File", file.name, {"file_url": "/private/files/{0}".format(file_name), "is_private": 1} + "File", file.name, {"file_url": f"/private/files/{file_name}", "is_private": 1} ) diff --git a/frappe/patches/v12_0/setup_tags.py b/frappe/patches/v12_0/setup_tags.py index 46482a102b..6bff8d3dac 100644 --- a/frappe/patches/v12_0/setup_tags.py +++ b/frappe/patches/v12_0/setup_tags.py @@ -17,7 +17,7 @@ def execute(): continue for _user_tags in frappe.db.sql( - "select `name`, `_user_tags` from `tab{0}`".format(doctype.name), as_dict=True + f"select `name`, `_user_tags` from `tab{doctype.name}`", as_dict=True ): if not _user_tags.get("_user_tags"): continue diff --git a/frappe/patches/v13_0/set_unique_for_page_view.py b/frappe/patches/v13_0/set_unique_for_page_view.py index 1a674f6697..45351afdde 100644 --- a/frappe/patches/v13_0/set_unique_for_page_view.py +++ b/frappe/patches/v13_0/set_unique_for_page_view.py @@ -4,6 +4,4 @@ import frappe def execute(): frappe.reload_doc("website", "doctype", "web_page_view", force=True) site_url = frappe.utils.get_site_url(frappe.local.site) - frappe.db.sql( - """UPDATE `tabWeb Page View` set is_unique=1 where referrer LIKE '%{0}%'""".format(site_url) - ) + frappe.db.sql(f"""UPDATE `tabWeb Page View` set is_unique=1 where referrer LIKE '%{site_url}%'""") diff --git a/frappe/patches/v14_0/copy_mail_data.py b/frappe/patches/v14_0/copy_mail_data.py index 6b976ba6fb..c44b7c9e92 100644 --- a/frappe/patches/v14_0/copy_mail_data.py +++ b/frappe/patches/v14_0/copy_mail_data.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import frappe diff --git a/frappe/patches/v14_0/update_color_names_in_kanban_board_column.py b/frappe/patches/v14_0/update_color_names_in_kanban_board_column.py index f8d6f236cd..b568151273 100644 --- a/frappe/patches/v14_0/update_color_names_in_kanban_board_column.py +++ b/frappe/patches/v14_0/update_color_names_in_kanban_board_column.py @@ -1,7 +1,6 @@ # Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors # MIT License. See license.txt -from __future__ import unicode_literals import frappe diff --git a/frappe/permissions.py b/frappe/permissions.py index 55a7c0e5f3..25d054f2e3 100644 --- a/frappe/permissions.py +++ b/frappe/permissions.py @@ -1,7 +1,6 @@ # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors # License: MIT. See LICENSE import copy -from typing import List import frappe import frappe.share @@ -516,7 +515,7 @@ def clear_user_permissions_for_doctype(doctype, user=None): def can_import(doctype, raise_exception=False): if not ("System Manager" in frappe.get_roles() or has_permission(doctype, "import")): if raise_exception: - raise frappe.PermissionError("You are not allowed to import: {doctype}".format(doctype=doctype)) + raise frappe.PermissionError(f"You are not allowed to import: {doctype}") else: return False return True @@ -606,7 +605,7 @@ def reset_perms(doctype): frappe.db.delete("Custom DocPerm", {"parent": doctype}) -def get_linked_doctypes(dt: str) -> List: +def get_linked_doctypes(dt: str) -> list: meta = frappe.get_meta(dt) linked_doctypes = [dt] + [ d.options diff --git a/frappe/printing/doctype/letter_head/test_letter_head.py b/frappe/printing/doctype/letter_head/test_letter_head.py index 9357d15315..75019ce275 100644 --- a/frappe/printing/doctype/letter_head/test_letter_head.py +++ b/frappe/printing/doctype/letter_head/test_letter_head.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2017, Frappe Technologies and Contributors # License: MIT. See LICENSE import unittest diff --git a/frappe/printing/doctype/print_format/print_format.py b/frappe/printing/doctype/print_format/print_format.py index 2e12fdb8d8..e49db67512 100644 --- a/frappe/printing/doctype/print_format/print_format.py +++ b/frappe/printing/doctype/print_format/print_format.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2017, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/printing/doctype/print_heading/print_heading.py b/frappe/printing/doctype/print_heading/print_heading.py index c905e68d47..9daee06f03 100644 --- a/frappe/printing/doctype/print_heading/print_heading.py +++ b/frappe/printing/doctype/print_heading/print_heading.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2017, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/printing/doctype/print_heading/test_print_heading.py b/frappe/printing/doctype/print_heading/test_print_heading.py index 02eddb072f..74ff7ce74f 100644 --- a/frappe/printing/doctype/print_heading/test_print_heading.py +++ b/frappe/printing/doctype/print_heading/test_print_heading.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2017, Frappe Technologies and Contributors # License: MIT. See LICENSE import unittest diff --git a/frappe/printing/doctype/print_settings/print_settings.py b/frappe/printing/doctype/print_settings/print_settings.py index f52d08e6ec..36eaac2e68 100644 --- a/frappe/printing/doctype/print_settings/print_settings.py +++ b/frappe/printing/doctype/print_settings/print_settings.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2018, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/printing/doctype/print_settings/test_print_settings.py b/frappe/printing/doctype/print_settings/test_print_settings.py index ba22df4438..6a6437bf97 100644 --- a/frappe/printing/doctype/print_settings/test_print_settings.py +++ b/frappe/printing/doctype/print_settings/test_print_settings.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2018, Frappe Technologies and Contributors # License: MIT. See LICENSE import unittest diff --git a/frappe/printing/doctype/print_style/print_style.py b/frappe/printing/doctype/print_style/print_style.py index 00de829deb..2b0fbfe929 100644 --- a/frappe/printing/doctype/print_style/print_style.py +++ b/frappe/printing/doctype/print_style/print_style.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2017, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/printing/doctype/print_style/test_print_style.py b/frappe/printing/doctype/print_style/test_print_style.py index ad2b61cc87..f8ce54b9bb 100644 --- a/frappe/printing/doctype/print_style/test_print_style.py +++ b/frappe/printing/doctype/print_style/test_print_style.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2017, Frappe Technologies and Contributors # License: MIT. See LICENSE import unittest diff --git a/frappe/printing/page/print_format_builder_beta/print_format_builder_beta.py b/frappe/printing/page/print_format_builder_beta/print_format_builder_beta.py index 668be8d05a..d54624aaef 100644 --- a/frappe/printing/page/print_format_builder_beta/print_format_builder_beta.py +++ b/frappe/printing/page/print_format_builder_beta/print_format_builder_beta.py @@ -1,7 +1,6 @@ # Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors # MIT License. See license.txt -from __future__ import unicode_literals import functools @@ -13,7 +12,7 @@ def get_google_fonts(): return _get_google_fonts() -@functools.lru_cache() +@functools.lru_cache def _get_google_fonts(): file_path = frappe.get_app_path("frappe", "data", "google_fonts.json") return frappe.parse_json(frappe.read_file(file_path)) diff --git a/frappe/query_builder/custom.py b/frappe/query_builder/custom.py index 20827df190..3203c72b8d 100644 --- a/frappe/query_builder/custom.py +++ b/frappe/query_builder/custom.py @@ -1,4 +1,4 @@ -from typing import Any, Optional +from typing import Any from pypika.functions import DistinctOptionFunction from pypika.terms import Term @@ -8,17 +8,17 @@ import frappe class GROUP_CONCAT(DistinctOptionFunction): - def __init__(self, column: str, alias: Optional[str] = None): + def __init__(self, column: str, alias: str | None = None): """[ Implements the group concat function read more about it at https://www.geeksforgeeks.org/mysql-group_concat-function ] Args: column (str): [ name of the column you want to concat] alias (Optional[str], optional): [ is this an alias? ]. Defaults to None. """ - super(GROUP_CONCAT, self).__init__("GROUP_CONCAT", column, alias=alias) + super().__init__("GROUP_CONCAT", column, alias=alias) class STRING_AGG(DistinctOptionFunction): - def __init__(self, column: str, separator: str = ",", alias: Optional[str] = None): + def __init__(self, column: str, separator: str = ",", alias: str | None = None): """[ Implements the group concat function read more about it at https://docs.microsoft.com/en-us/sql/t-sql/functions/string-agg-transact-sql?view=sql-server-ver15 ] Args: @@ -26,7 +26,7 @@ class STRING_AGG(DistinctOptionFunction): separator (str, optional): [separator to be used]. Defaults to ",". alias (Optional[str], optional): [description]. Defaults to None. """ - super(STRING_AGG, self).__init__("STRING_AGG", column, separator, alias=alias) + super().__init__("STRING_AGG", column, separator, alias=alias) class MATCH(DistinctOptionFunction): @@ -37,7 +37,7 @@ class MATCH(DistinctOptionFunction): column (str):[ column to search in ] """ alias = kwargs.get("alias") - super(MATCH, self).__init__(" MATCH", column, *args, alias=alias) + super().__init__(" MATCH", column, *args, alias=alias) self._Against = False def get_function_sql(self, **kwargs): @@ -65,7 +65,7 @@ class TO_TSVECTOR(DistinctOptionFunction): column (str): [ column to search in ] """ alias = kwargs.get("alias") - super(TO_TSVECTOR, self).__init__("TO_TSVECTOR", column, *args, alias=alias) + super().__init__("TO_TSVECTOR", column, *args, alias=alias) self._PLAINTO_TSQUERY = False def get_function_sql(self, **kwargs): @@ -95,7 +95,7 @@ class ConstantColumn(Term): """ self.value = value - def get_sql(self, quote_char: Optional[str] = None, **kwargs: Any) -> str: + def get_sql(self, quote_char: str | None = None, **kwargs: Any) -> str: return format_alias_sql( format_quotes(self.value, kwargs.get("secondary_quote_char") or ""), self.alias or self.value, diff --git a/frappe/query_builder/functions.py b/frappe/query_builder/functions.py index f03c139f57..9e49756340 100644 --- a/frappe/query_builder/functions.py +++ b/frappe/query_builder/functions.py @@ -11,7 +11,7 @@ from .utils import PseudoColumn class Concat_ws(Function): def __init__(self, *terms, **kwargs): - super(Concat_ws, self).__init__("CONCAT_WS", *terms, **kwargs) + super().__init__("CONCAT_WS", *terms, **kwargs) GroupConcat = ImportMapper({db_type_is.MARIADB: GROUP_CONCAT, db_type_is.POSTGRES: STRING_AGG}) @@ -68,7 +68,7 @@ class Cast_(Function): if hasattr(self.as_type, "get_sql") else str(self.as_type).upper() ) - return "AS {type}".format(type=type_sql) + return f"AS {type_sql}" def _aggregate(function, dt, fieldname, filters, **kwargs): diff --git a/frappe/query_builder/terms.py b/frappe/query_builder/terms.py index 64a4707983..4d3c98b6a3 100644 --- a/frappe/query_builder/terms.py +++ b/frappe/query_builder/terms.py @@ -1,5 +1,5 @@ from datetime import timedelta -from typing import Any, Dict, Optional +from typing import Any from pypika.queries import QueryBuilder from pypika.terms import Criterion, Function, ValueWrapper @@ -27,7 +27,7 @@ class NamedParameterWrapper: self.parameters[param_key[2:-2]] = param_value return param_key - def get_parameters(self) -> Dict[str, Any]: + def get_parameters(self) -> dict[str, Any]: """get dict with parameters and values Returns: @@ -45,9 +45,9 @@ class ParameterizedValueWrapper(ValueWrapper): def get_sql( self, - quote_char: Optional[str] = None, + quote_char: str | None = None, secondary_quote_char: str = "'", - param_wrapper: Optional[NamedParameterWrapper] = None, + param_wrapper: NamedParameterWrapper | None = None, **kwargs: Any, ) -> str: if param_wrapper and isinstance(self.value, str): @@ -104,7 +104,7 @@ class SubQuery(Criterion): def __init__( self, subq: QueryBuilder, - alias: Optional[str] = None, + alias: str | None = None, ) -> None: super().__init__(alias) self.subq = subq diff --git a/frappe/query_builder/utils.py b/frappe/query_builder/utils.py index 10bab38a63..ad8ff4b0df 100644 --- a/frappe/query_builder/utils.py +++ b/frappe/query_builder/utils.py @@ -1,6 +1,6 @@ from enum import Enum from importlib import import_module -from typing import Any, Callable, Dict, Union, get_type_hints +from typing import Any, Callable, get_type_hints from pypika import Query from pypika.queries import Column @@ -18,7 +18,7 @@ class db_type_is(Enum): class ImportMapper: - def __init__(self, func_map: Dict[db_type_is, Callable]) -> None: + def __init__(self, func_map: dict[db_type_is, Callable]) -> None: self.func_map = func_map def __call__(self, *args: Any, **kwds: Any) -> Callable: @@ -31,7 +31,7 @@ class BuilderIdentificationFailed(Exception): super().__init__("Couldn't guess builder") -def get_query_builder(type_of_db: str) -> Union[Postgres, MariaDB]: +def get_query_builder(type_of_db: str) -> Postgres | MariaDB: """[return the query builder object] Args: diff --git a/frappe/rate_limiter.py b/frappe/rate_limiter.py index 6693f8abaf..0717124ba9 100644 --- a/frappe/rate_limiter.py +++ b/frappe/rate_limiter.py @@ -1,10 +1,9 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors # License: MIT. See LICENSE from datetime import datetime from functools import wraps -from typing import Callable, Union +from typing import Callable from werkzeug.wrappers import Response @@ -85,9 +84,9 @@ class RateLimiter: def rate_limit( key: str = None, - limit: Union[int, Callable] = 5, + limit: int | Callable = 5, seconds: int = 24 * 60 * 60, - methods: Union[str, list] = "ALL", + methods: str | list = "ALL", ip_based: bool = True, ): """Decorator to rate limit an endpoint. diff --git a/frappe/recorder.py b/frappe/recorder.py index 87e001fe31..0262f4cbce 100644 --- a/frappe/recorder.py +++ b/frappe/recorder.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors # License: MIT. See LICENSE import datetime @@ -36,7 +35,7 @@ def sql(*args, **kwargs): # Collect EXPLAIN for executed query if query.lower().strip().split()[0] in ("select", "update", "delete"): # Only SELECT/UPDATE/DELETE queries can be "EXPLAIN"ed - explain_result = frappe.db._sql("EXPLAIN {}".format(query), as_dict=True) + explain_result = frappe.db._sql(f"EXPLAIN {query}", as_dict=True) else: explain_result = [] @@ -45,7 +44,7 @@ def sql(*args, **kwargs): "stack": stack, "explain_result": explain_result, "time": start_time, - "duration": float("{:.3f}".format((end_time - start_time) * 1000)), + "duration": float(f"{(end_time - start_time) * 1000:.3f}"), } frappe.local._recorder.register(data) @@ -102,9 +101,7 @@ class Recorder: "time": self.time, "queries": len(self.calls), "time_queries": float("{:0.3f}".format(sum(call["duration"] for call in self.calls))), - "duration": float( - "{:0.3f}".format((datetime.datetime.now() - self.time).total_seconds() * 1000) - ), + "duration": float(f"{(datetime.datetime.now() - self.time).total_seconds() * 1000:0.3f}"), "method": self.method, } frappe.cache().hset(RECORDER_REQUEST_SPARSE_HASH, self.uuid, request_data) diff --git a/frappe/social/doctype/energy_point_log/energy_point_log.py b/frappe/social/doctype/energy_point_log/energy_point_log.py index a0c5120fa7..e888e9b53f 100644 --- a/frappe/social/doctype/energy_point_log/energy_point_log.py +++ b/frappe/social/doctype/energy_point_log/energy_point_log.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2018, Frappe Technologies and contributors # License: MIT. See LICENSE @@ -51,7 +50,7 @@ class EnergyPointLog(Document): "document_name": self.reference_name, "subject": get_notification_message(self), "from_user": reference_user, - "email_content": "
{}
".format(self.reason) if self.reason else None, + "email_content": f"
{self.reason}
" if self.reason else None, } enqueue_create_notification(self.user, notification_doc) @@ -360,7 +359,7 @@ def send_summary(timespan): ] frappe.sendmail( - subject="{} energy points summary".format(timespan), + subject=f"{timespan} energy points summary", recipients=all_users, template="energy_points_summary", args={ diff --git a/frappe/social/doctype/energy_point_log/test_energy_point_log.py b/frappe/social/doctype/energy_point_log/test_energy_point_log.py index 9a244a0a2c..3830f0505b 100644 --- a/frappe/social/doctype/energy_point_log/test_energy_point_log.py +++ b/frappe/social/doctype/energy_point_log/test_energy_point_log.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and Contributors # License: MIT. See LICENSE import frappe diff --git a/frappe/social/doctype/energy_point_rule/energy_point_rule.py b/frappe/social/doctype/energy_point_rule/energy_point_rule.py index 9d393dde48..1057ac2749 100644 --- a/frappe/social/doctype/energy_point_rule/energy_point_rule.py +++ b/frappe/social/doctype/energy_point_rule/energy_point_rule.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2018, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/social/doctype/energy_point_settings/energy_point_settings.py b/frappe/social/doctype/energy_point_settings/energy_point_settings.py index c1ff2707af..4156aa0094 100644 --- a/frappe/social/doctype/energy_point_settings/energy_point_settings.py +++ b/frappe/social/doctype/energy_point_settings/energy_point_settings.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/social/doctype/review_level/review_level.py b/frappe/social/doctype/review_level/review_level.py index b3418e913e..9734d45118 100644 --- a/frappe/social/doctype/review_level/review_level.py +++ b/frappe/social/doctype/review_level/review_level.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/templates/includes/comments/comments.py b/frappe/templates/includes/comments/comments.py index b98106c0dc..c90c07c776 100644 --- a/frappe/templates/includes/comments/comments.py +++ b/frappe/templates/includes/comments/comments.py @@ -44,7 +44,7 @@ def add_comment(comment, comment_email, comment_by, reference_doctype, reference content = ( comment.content - + "

{2}

".format( + + "

{}

".format( frappe.utils.get_request_site_address(), comment.name, _("View Comment") ) ) diff --git a/frappe/templates/includes/feedback/feedback.py b/frappe/templates/includes/feedback/feedback.py index 4c6a0588f5..16ebdaf741 100644 --- a/frappe/templates/includes/feedback/feedback.py +++ b/frappe/templates/includes/feedback/feedback.py @@ -1,6 +1,5 @@ # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors # License: MIT. See LICENSE -from __future__ import unicode_literals import frappe from frappe import _ @@ -40,7 +39,7 @@ def give_feedback(reference_doctype, reference_name, like): def send_mail(feedback, subject): doc = frappe.get_doc(feedback.reference_doctype, feedback.reference_name) if feedback.like: - message = "

Hey,

You have received a ❤️ heart on your blog post {0}

".format( + message = "

Hey,

You have received a ❤️ heart on your blog post {}

".format( feedback.reference_name ) else: diff --git a/frappe/test_runner.py b/frappe/test_runner.py index 82179d8fac..e8c1656ca8 100644 --- a/frappe/test_runner.py +++ b/frappe/test_runner.py @@ -57,7 +57,7 @@ def main( if doctype_list_path: app, doctype_list_path = doctype_list_path.split(os.path.sep, 1) - with open(frappe.get_app_path(app, doctype_list_path), "r") as f: + with open(frappe.get_app_path(app, doctype_list_path)) as f: doctype = f.read().strip().splitlines() if ui_tests: @@ -151,14 +151,14 @@ def set_test_email_config(): class TimeLoggingTestResult(unittest.TextTestResult): def startTest(self, test): self._started_at = time.time() - super(TimeLoggingTestResult, self).startTest(test) + super().startTest(test) def addSuccess(self, test): elapsed = time.time() - self._started_at name = self.getDescription(test) if elapsed >= SLOW_TEST_THRESHOLD: - self.stream.write("\n{} ({:.03}s)\n".format(name, elapsed)) - super(TimeLoggingTestResult, self).addSuccess(test) + self.stream.write(f"\n{name} ({elapsed:.03}s)\n") + super().addSuccess(test) def run_all_tests( @@ -227,7 +227,7 @@ def run_tests_for_doctype( for doctype in doctypes: module = frappe.db.get_value("DocType", doctype, "module") if not module: - print("Invalid doctype {0}".format(doctype)) + print(f"Invalid doctype {doctype}") sys.exit(1) test_module = get_module_name(doctype, module, "test_") @@ -351,7 +351,7 @@ def _add_test(app, path, filename, verbose, test_suite=None, ui_tests=False): if os.path.basename(os.path.dirname(path)) == "doctype": txt_file = os.path.join(path, filename[5:].replace(".py", ".json")) if os.path.exists(txt_file): - with open(txt_file, "r") as f: + with open(txt_file) as f: doc = json.loads(f.read()) doctype = doc["name"] make_test_records(doctype, verbose, commit=True) @@ -535,7 +535,7 @@ def get_test_record_log(): """Return the list of doctypes for which test records have been created""" if "test_record_log" not in frappe.flags: if os.path.exists(frappe.get_site_path(".test_log")): - with open(frappe.get_site_path(".test_log"), "r") as f: + with open(frappe.get_site_path(".test_log")) as f: frappe.flags.test_record_log = f.read().splitlines() else: frappe.flags.test_record_log = [] diff --git a/frappe/tests/test_api.py b/frappe/tests/test_api.py index bbb2280578..0464f54530 100644 --- a/frappe/tests/test_api.py +++ b/frappe/tests/test_api.py @@ -3,7 +3,6 @@ import unittest from contextlib import contextmanager from random import choice from threading import Thread -from typing import Dict, Optional, Tuple from unittest.mock import patch import requests @@ -33,7 +32,7 @@ def suppress_stdout(): def make_request( - target: str, args: Optional[Tuple] = None, kwargs: Optional[Dict] = None + target: str, args: tuple | None = None, kwargs: dict | None = None ) -> TestResponse: t = ThreadWithReturnValue(target=target, args=args, kwargs=kwargs) t.start() @@ -86,7 +85,7 @@ class FrappeAPITestCase(unittest.TestCase): return self._sid - def get(self, path: str, params: Optional[Dict] = None, **kwargs) -> TestResponse: + def get(self, path: str, params: dict | None = None, **kwargs) -> TestResponse: return make_request(target=self.TEST_CLIENT.get, args=(path,), kwargs={"data": params, **kwargs}) def post(self, path, data, **kwargs) -> TestResponse: diff --git a/frappe/tests/test_bot.py b/frappe/tests/test_bot.py index 222f35b99b..ffc3513619 100644 --- a/frappe/tests/test_bot.py +++ b/frappe/tests/test_bot.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors # License: MIT. See LICENSE diff --git a/frappe/tests/test_caching.py b/frappe/tests/test_caching.py index 6a1390f10c..66b47b6e31 100644 --- a/frappe/tests/test_caching.py +++ b/frappe/tests/test_caching.py @@ -1,6 +1,5 @@ import time import unittest -from typing import Dict, List, Tuple, Union from unittest.mock import MagicMock import frappe @@ -13,7 +12,7 @@ register_with_external_service = MagicMock(return_value=True) @request_cache -def request_specific_api(a: Union[List, Tuple, Dict, int], b: int) -> int: +def request_specific_api(a: list | tuple | dict | int, b: int) -> int: # API that takes very long to return a result todays_value = external_service() if not isinstance(a, (int, float)): diff --git a/frappe/tests/test_client.py b/frappe/tests/test_client.py index b5a1771800..1a1c4f3232 100644 --- a/frappe/tests/test_client.py +++ b/frappe/tests/test_client.py @@ -146,7 +146,7 @@ class TestClient(unittest.TestCase): from frappe.client import insert def get_random_title(): - return "test-{0}".format(frappe.generate_hash()) + return f"test-{frappe.generate_hash()}" # test insert dict doc = {"doctype": "Note", "title": get_random_title(), "content": "test"} @@ -183,7 +183,7 @@ class TestClient(unittest.TestCase): from frappe.client import insert, insert_many def get_random_title(): - return "test-{0}".format(frappe.generate_hash(length=5)) + return f"test-{frappe.generate_hash(length=5)}" # insert a (parent) doc note1 = {"doctype": "Note", "title": get_random_title(), "content": "test"} diff --git a/frappe/tests/test_commands.py b/frappe/tests/test_commands.py index aa00a884e1..cb8c3d266b 100644 --- a/frappe/tests/test_commands.py +++ b/frappe/tests/test_commands.py @@ -13,7 +13,6 @@ from contextlib import contextmanager from functools import wraps from glob import glob from pathlib import Path -from typing import List, Optional from unittest.case import skipIf from unittest.mock import patch @@ -34,7 +33,7 @@ from frappe.utils import add_to_date, get_bench_path, get_bench_relative_path, n from frappe.utils.backups import fetch_latest_backups from frappe.utils.jinja_globals import bundled_asset -_result: Optional[Result] = None +_result: Result | None = None TEST_SITE = "commands-site-O4PN2QKA.test" # added random string tag to avoid collisions CLI_CONTEXT = frappe._dict(sites=[TEST_SITE]) @@ -55,7 +54,7 @@ def clean(value) -> str: return value -def missing_in_backup(doctypes: List, file: os.PathLike) -> List: +def missing_in_backup(doctypes: list, file: os.PathLike) -> list: """Returns list of missing doctypes in the backup. Args: @@ -72,7 +71,7 @@ def missing_in_backup(doctypes: List, file: os.PathLike) -> List: return [doctype for doctype in doctypes if predicate.format(doctype).lower() not in content] -def exists_in_backup(doctypes: List, file: os.PathLike) -> bool: +def exists_in_backup(doctypes: list, file: os.PathLike) -> bool: """Checks if the list of doctypes exist in the database.sql.gz file supplied Args: @@ -111,7 +110,7 @@ def pass_test_context(f): @contextmanager -def cli(cmd: Command, args: Optional[List] = None): +def cli(cmd: Command, args: list | None = None): with maintain_locals(): global _result @@ -160,9 +159,7 @@ class BaseTestCommands(unittest.TestCase): click.secho(self.command, fg="bright_black") command = shlex.split(self.command) - self._proc = subprocess.run( - command, input=cmd_input, stdout=subprocess.PIPE, stderr=subprocess.PIPE - ) + self._proc = subprocess.run(command, input=cmd_input, capture_output=True) self.stdout = clean(self._proc.stdout) self.stderr = clean(self._proc.stderr) self.returncode = clean(self._proc.returncode) @@ -184,7 +181,7 @@ class BaseTestCommands(unittest.TestCase): ) def _formatMessage(self, msg, standardMsg): - output = super(BaseTestCommands, self)._formatMessage(msg, standardMsg) + output = super()._formatMessage(msg, standardMsg) if not hasattr(self, "command") and _result: command = _result.command @@ -201,14 +198,14 @@ class BaseTestCommands(unittest.TestCase): [ "-" * 70, "Last Command Execution Summary:", - "Command: {}".format(command) if command else "", - "Standard Output: {}".format(stdout) if stdout else "", - "Standard Error: {}".format(stderr) if stderr else "", - "Return Code: {}".format(returncode) if returncode else "", + f"Command: {command}" if command else "", + f"Standard Output: {stdout}" if stdout else "", + f"Standard Error: {stderr}" if stderr else "", + f"Return Code: {returncode}" if returncode else "", ] ).strip() - return "{}\n\n{}".format(output, cmd_execution_summary) + return f"{output}\n\n{cmd_execution_summary}" class TestCommands(BaseTestCommands): @@ -325,10 +322,10 @@ class TestCommands(BaseTestCommands): # test 2: bare functionality for single site self.execute("bench --site {site} list-apps") self.assertEqual(self.returncode, 0) - list_apps = set(_x.split()[0] for _x in self.stdout.split("\n")) + list_apps = {_x.split()[0] for _x in self.stdout.split("\n")} doctype = frappe.get_single("Installed Applications").installed_applications if doctype: - installed_apps = set(x.app_name for x in doctype) + installed_apps = {x.app_name for x in doctype} else: installed_apps = set(frappe.get_installed_apps()) self.assertSetEqual(list_apps, installed_apps) diff --git a/frappe/tests/test_db.py b/frappe/tests/test_db.py index 69f7a7d5aa..2ec1dd7fb2 100644 --- a/frappe/tests/test_db.py +++ b/frappe/tests/test_db.py @@ -119,7 +119,7 @@ class TestDB(unittest.TestCase): self.assertGreaterEqual(1, cint(frappe.db._cursor.rowcount)) def test_escape(self): - frappe.db.escape("香港濟生堂製藥有限公司 - IT".encode("utf-8")) + frappe.db.escape("香港濟生堂製藥有限公司 - IT".encode()) def test_get_single_value(self): # setup @@ -491,15 +491,15 @@ class TestDB(unittest.TestCase): frappe.get_doc(doctype="Note", title="note2", content="someting else").insert() # Count with no filtes - self.assertEquals((frappe.db.count("Note")), 2) + self.assertEqual((frappe.db.count("Note")), 2) # simple filters - self.assertEquals((frappe.db.count("Note", ["title", "=", "note1"])), 1) + self.assertEqual((frappe.db.count("Note", ["title", "=", "note1"])), 1) frappe.get_doc(doctype="Note", title="note3", content="something other").insert() # List of list filters with tables - self.assertEquals( + self.assertEqual( ( frappe.db.count( "Note", diff --git a/frappe/tests/test_db_update.py b/frappe/tests/test_db_update.py index 7c615f2df5..38cc8af2f3 100644 --- a/frappe/tests/test_db_update.py +++ b/frappe/tests/test_db_update.py @@ -18,7 +18,7 @@ class TestDBUpdate(unittest.TestCase): frappe.db.updatedb(doctype) field_defs = get_field_defs(doctype) - table_columns = frappe.db.get_table_columns_description("tab{}".format(doctype)) + table_columns = frappe.db.get_table_columns_description(f"tab{doctype}") self.assertEqual(len(field_defs), len(table_columns)) @@ -34,7 +34,7 @@ class TestDBUpdate(unittest.TestCase): default = field_def.default if field_def.default is not None else fallback_default self.assertEqual(fieldtype, table_column.type) - self.assertIn(cstr(table_column.default) or "NULL", [cstr(default), "'{}'".format(default)]) + self.assertIn(cstr(table_column.default) or "NULL", [cstr(default), f"'{default}'"]) def test_index_and_unique_constraints(self): doctype = "User" @@ -93,7 +93,7 @@ def get_fieldtype_from_def(field_def): fieldtuple = frappe.db.type_map.get(field_def.fieldtype, ("", 0)) fieldtype = fieldtuple[0] if fieldtype in ("varchar", "datetime", "int"): - fieldtype += "({})".format(field_def.length or fieldtuple[1]) + fieldtype += f"({field_def.length or fieldtuple[1]})" return fieldtype @@ -134,5 +134,5 @@ def get_other_fields_meta(meta): def get_table_column(doctype, fieldname): - table_columns = frappe.db.get_table_columns_description("tab{}".format(doctype)) + table_columns = frappe.db.get_table_columns_description(f"tab{doctype}") return find(table_columns, lambda d: d.get("name") == fieldname) diff --git a/frappe/tests/test_email.py b/frappe/tests/test_email.py index 3d6773044f..71886bb625 100644 --- a/frappe/tests/test_email.py +++ b/frappe/tests/test_email.py @@ -281,7 +281,7 @@ class TestEmail(unittest.TestCase): frappe.db.delete("Communication", {"sender": "sukh@yyy.com"}) - with open(frappe.get_app_path("frappe", "tests", "data", "email_with_image.txt"), "r") as raw: + with open(frappe.get_app_path("frappe", "tests", "data", "email_with_image.txt")) as raw: messages = { '"INBOX"': {"latest_messages": [raw.read()], "seen_status": {2: "UNSEEN"}, "uid_list": [2]} } diff --git a/frappe/tests/test_fixture_import.py b/frappe/tests/test_fixture_import.py index 5b776c0392..3113812fa6 100644 --- a/frappe/tests/test_fixture_import.py +++ b/frappe/tests/test_fixture_import.py @@ -1,6 +1,5 @@ import os import unittest -from typing import List import frappe from frappe.core.doctype.data_import.data_import import export_json, import_doc @@ -12,13 +11,13 @@ class TestFixtureImport(unittest.TestCase): def create_new_doctype(self, DocType: str) -> None: file = frappe.get_app_path("frappe", "custom", "fixtures", f"{DocType}.json") - file = open(file, "r") + file = open(file) doc = file.read() file.close() savedocs(doc, "Save") - def insert_dummy_data_and_export(self, DocType: str, dummy_name_list: List[str]) -> str: + def insert_dummy_data_and_export(self, DocType: str, dummy_name_list: list[str]) -> str: for name in dummy_name_list: doc = frappe.get_doc({"doctype": DocType, "member_name": name}) doc.insert() diff --git a/frappe/tests/test_form_load.py b/frappe/tests/test_form_load.py index 22db56eeef..83baf94b1c 100644 --- a/frappe/tests/test_form_load.py +++ b/frappe/tests/test_form_load.py @@ -31,7 +31,7 @@ class TestFormLoad(unittest.TestCase): "blog_intro": "Test Blog Intro", "blogger": "_Test Blogger 1", "content": "Test Blog Content", - "title": "_Test Blog Post {}".format(frappe.utils.now()), + "title": f"_Test Blog Post {frappe.utils.now()}", "published": 0, } ) diff --git a/frappe/tests/test_formatter.py b/frappe/tests/test_formatter.py index 1a195f9218..b34aa40e77 100644 --- a/frappe/tests/test_formatter.py +++ b/frappe/tests/test_formatter.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- import unittest import frappe diff --git a/frappe/tests/test_frappe_client.py b/frappe/tests/test_frappe_client.py index 2cca251718..facb0b3b72 100644 --- a/frappe/tests/test_frappe_client.py +++ b/frappe/tests/test_frappe_client.py @@ -193,7 +193,7 @@ class TestFrappeClient(unittest.TestCase): ) api_key = frappe.db.get_value("User", "Administrator", "api_key") - header = {"Authorization": "token {}:{}".format(api_key, generated_secret)} + header = {"Authorization": f"token {api_key}:{generated_secret}"} res = requests.post(get_url() + "/api/method/frappe.auth.get_logged_user", headers=header) self.assertEqual(res.status_code, 200) @@ -202,7 +202,7 @@ class TestFrappeClient(unittest.TestCase): header = { "Authorization": "Basic {}".format( - base64.b64encode(frappe.safe_encode("{}:{}".format(api_key, generated_secret))).decode() + base64.b64encode(frappe.safe_encode(f"{api_key}:{generated_secret}")).decode() ) } res = requests.post(get_url() + "/api/method/frappe.auth.get_logged_user", headers=header) @@ -211,13 +211,13 @@ class TestFrappeClient(unittest.TestCase): # Valid api key, invalid api secret api_secret = "ksk&93nxoe3os" - header = {"Authorization": "token {}:{}".format(api_key, api_secret)} + header = {"Authorization": f"token {api_key}:{api_secret}"} res = requests.post(get_url() + "/api/method/frappe.auth.get_logged_user", headers=header) self.assertEqual(res.status_code, 403) # random api key and api secret api_key = "@3djdk3kld" api_secret = "ksk&93nxoe3os" - header = {"Authorization": "token {}:{}".format(api_key, api_secret)} + header = {"Authorization": f"token {api_key}:{api_secret}"} res = requests.post(get_url() + "/api/method/frappe.auth.get_logged_user", headers=header) self.assertEqual(res.status_code, 401) diff --git a/frappe/tests/test_monitor.py b/frappe/tests/test_monitor.py index 0c26ec0e28..48de913241 100644 --- a/frappe/tests/test_monitor.py +++ b/frappe/tests/test_monitor.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors # License: MIT. See LICENSE diff --git a/frappe/tests/test_naming.py b/frappe/tests/test_naming.py index 305df66209..5feaad6f9b 100644 --- a/frappe/tests/test_naming.py +++ b/frappe/tests/test_naming.py @@ -139,16 +139,16 @@ class TestNaming(FrappeTestCase): week = determine_consecutive_week_number(now_datetime()) - self.assertEqual(todo.name, "TODO-{week}-{series}".format(week=week, series=series)) + self.assertEqual(todo.name, f"TODO-{week}-{series}") def test_revert_series(self): from datetime import datetime year = datetime.now().year - series = "TEST-{}-".format(year) + series = f"TEST-{year}-" key = "TEST-.YYYY.-" - name = "TEST-{}-00001".format(year) + name = f"TEST-{year}-00001" frappe.db.sql("""INSERT INTO `tabSeries` (name, current) values (%s, 1)""", (series,)) revert_series_if_last(key, name) current_index = frappe.db.sql( @@ -158,9 +158,9 @@ class TestNaming(FrappeTestCase): self.assertEqual(current_index.get("current"), 0) frappe.db.delete("Series", {"name": series}) - series = "TEST-{}-".format(year) + series = f"TEST-{year}-" key = "TEST-.YYYY.-.#####" - name = "TEST-{}-00002".format(year) + name = f"TEST-{year}-00002" frappe.db.sql("""INSERT INTO `tabSeries` (name, current) values (%s, 2)""", (series,)) revert_series_if_last(key, name) current_index = frappe.db.sql( @@ -235,11 +235,11 @@ class TestNaming(FrappeTestCase): amended_doc.docstatus = 0 amended_doc.amended_from = doc.name amended_doc.save() - self.assertEqual(amended_doc.name, "{}-1".format(original_name)) + self.assertEqual(amended_doc.name, f"{original_name}-1") amended_doc.submit() amended_doc.cancel() - self.assertEqual(amended_doc.name, "{}-1".format(original_name)) + self.assertEqual(amended_doc.name, f"{original_name}-1") submittable_doctype.delete() diff --git a/frappe/tests/test_permissions.py b/frappe/tests/test_permissions.py index 26d5c714ef..b4f0402a16 100644 --- a/frappe/tests/test_permissions.py +++ b/frappe/tests/test_permissions.py @@ -461,7 +461,7 @@ class TestPermissions(FrappeTestCase): self.assertIn( post.blogger, ["_Test Blogger", "_Test Blogger 1"], - "A post from {} is not expected.".format(post.blogger), + f"A post from {post.blogger} is not expected.", ) def test_if_owner_permission_overrides_properly(self): diff --git a/frappe/tests/test_query_builder.py b/frappe/tests/test_query_builder.py index 926bdedfbd..929a0ac451 100644 --- a/frappe/tests/test_query_builder.py +++ b/frappe/tests/test_query_builder.py @@ -1,5 +1,5 @@ import unittest -from typing import Callable +from collections.abc import Callable import frappe from frappe.query_builder import Case @@ -150,7 +150,7 @@ class TestCustomFunctionsPostgres(unittest.TestCase): ) -class TestBuilderBase(object): +class TestBuilderBase: def test_adding_tabs(self): self.assertEqual("tabNotes", frappe.qb.DocType("Notes").get_sql()) self.assertEqual("__Auth", frappe.qb.DocType("__Auth").get_sql()) @@ -186,9 +186,7 @@ class TestBuilderBase(object): class TestParameterization(unittest.TestCase): def test_where_conditions(self): DocType = frappe.qb.DocType("DocType") - query = ( - frappe.qb.from_(DocType).select(DocType.name).where((DocType.owner == "Administrator' --")) - ) + query = frappe.qb.from_(DocType).select(DocType.name).where(DocType.owner == "Administrator' --") self.assertTrue("walk" in dir(query)) query, params = query.walk() diff --git a/frappe/tests/test_rate_limiter.py b/frappe/tests/test_rate_limiter.py index 5cfe2694f6..90f69c502a 100644 --- a/frappe/tests/test_rate_limiter.py +++ b/frappe/tests/test_rate_limiter.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - # Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors # License: MIT. See LICENSE diff --git a/frappe/tests/test_recorder.py b/frappe/tests/test_recorder.py index 94b97cb3a6..78ef49062b 100644 --- a/frappe/tests/test_recorder.py +++ b/frappe/tests/test_recorder.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - # Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and Contributors # License: MIT. See LICENSE diff --git a/frappe/tests/test_rename_doc.py b/frappe/tests/test_rename_doc.py index 928953fe1c..f712965d67 100644 --- a/frappe/tests/test_rename_doc.py +++ b/frappe/tests/test_rename_doc.py @@ -6,7 +6,6 @@ import unittest from contextlib import contextmanager, redirect_stdout from io import StringIO from random import choice, sample -from typing import List from unittest.mock import patch import frappe @@ -23,7 +22,7 @@ from frappe.utils import add_to_date, now @contextmanager -def patch_db(endpoints: List[str] = None): +def patch_db(endpoints: list[str] = None): patched_endpoints = [] for point in endpoints: @@ -59,7 +58,7 @@ class TestRenameDoc(unittest.TestCase): { "doctype": self.test_doctype, "date": add_to_date(now(), days=num), - "description": "this is todo #{}".format(num), + "description": f"this is todo #{num}", } ).insert() self.available_documents.append(doc.name) diff --git a/frappe/tests/test_twofactor.py b/frappe/tests/test_twofactor.py index 82d39f40bb..d9bf982cd2 100644 --- a/frappe/tests/test_twofactor.py +++ b/frappe/tests/test_twofactor.py @@ -24,7 +24,7 @@ from . import get_system_setting, update_system_settings class TestTwoFactor(unittest.TestCase): def __init__(self, *args, **kwargs): - super(TestTwoFactor, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) self.default_allowed_login_attempts = get_system_setting("allow_consecutive_login_attempts") def setUp(self): @@ -60,7 +60,7 @@ class TestTwoFactor(unittest.TestCase): self.assertTrue(verification_obj) self.assertTrue(tmp_id) for k in ["_usr", "_pwd", "_otp_secret"]: - self.assertTrue(frappe.cache().get("{0}{1}".format(tmp_id, k)), "{} not available".format(k)) + self.assertTrue(frappe.cache().get(f"{tmp_id}{k}"), f"{k} not available") def test_two_factor_is_enabled(self): """ diff --git a/frappe/tests/test_utils.py b/frappe/tests/test_utils.py index 2a8d27cd19..e903c655b0 100644 --- a/frappe/tests/test_utils.py +++ b/frappe/tests/test_utils.py @@ -126,14 +126,14 @@ class TestMoney(unittest.TestCase): self.assertEqual( money_in_words(num[0], "BHD"), num[1], - "{0} is not the same as {1}".format(money_in_words(num[0], "BHD"), num[1]), + "{} is not the same as {}".format(money_in_words(num[0], "BHD"), num[1]), ) for num in nums_ngn: self.assertEqual( money_in_words(num[0], "NGN"), num[1], - "{0} is not the same as {1}".format(money_in_words(num[0], "NGN"), num[1]), + "{} is not the same as {}".format(money_in_words(num[0], "NGN"), num[1]), ) @@ -157,11 +157,11 @@ class TestDataManipulation(unittest.TestCase): url = get_url() self.assertTrue('Test link 1' in html) - self.assertTrue('Test link 2'.format(url) in html) - self.assertTrue('Test link 3'.format(url) in html) - self.assertTrue(''.format(url) in html) + self.assertTrue(f'Test link 2' in html) + self.assertTrue(f'Test link 3' in html) + self.assertTrue(f'' in html) self.assertTrue( - "style=\"background-image: url('{0}/assets/frappe/bg.jpg') !important\"".format(url) in html + f"style=\"background-image: url('{url}/assets/frappe/bg.jpg') !important\"" in html ) self.assertTrue('email' in html) @@ -304,7 +304,7 @@ class TestValidationUtils(unittest.TestCase): class TestImage(unittest.TestCase): def test_strip_exif_data(self): original_image = Image.open("../apps/frappe/frappe/tests/data/exif_sample_image.jpg") - original_image_content = io.open( + original_image_content = open( "../apps/frappe/frappe/tests/data/exif_sample_image.jpg", mode="rb" ).read() @@ -317,7 +317,7 @@ class TestImage(unittest.TestCase): def test_optimize_image(self): image_file_path = "../apps/frappe/frappe/tests/data/sample_image_for_optimization.jpg" content_type = guess_type(image_file_path)[0] - original_content = io.open(image_file_path, mode="rb").read() + original_content = open(image_file_path, mode="rb").read() optimized_content = optimize_image(original_content, content_type, max_width=500, max_height=500) optimized_image = Image.open(io.BytesIO(optimized_content)) diff --git a/frappe/tests/tests_geo_utils.py b/frappe/tests/tests_geo_utils.py index 2ac03e67e0..22ef74f721 100644 --- a/frappe/tests/tests_geo_utils.py +++ b/frappe/tests/tests_geo_utils.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2020, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/tests/ui_test_helpers.py b/frappe/tests/ui_test_helpers.py index 494ba8872d..92f4ca7eaf 100644 --- a/frappe/tests/ui_test_helpers.py +++ b/frappe/tests/ui_test_helpers.py @@ -86,7 +86,7 @@ def create_contact_phone_nos_records(): doc = frappe.new_doc("Contact") doc.first_name = "Test Contact" for index in range(1000): - doc.append("phone_nos", {"phone": "123456{}".format(index)}) + doc.append("phone_nos", {"phone": f"123456{index}"}) doc.insert() @@ -140,7 +140,7 @@ def create_multiple_todo_records(): if frappe.db.get_all("ToDo", {"description": "Multiple ToDo 1"}): return - values = [("100{}".format(i), "Multiple ToDo {}".format(i)) for i in range(1, 1002)] + values = [(f"100{i}", f"Multiple ToDo {i}") for i in range(1, 1002)] frappe.db.bulk_insert("ToDo", fields=["name", "description"], values=set(values)) diff --git a/frappe/translate.py b/frappe/translate.py index 5dbbbd31f2..dc1407cfdb 100644 --- a/frappe/translate.py +++ b/frappe/translate.py @@ -15,7 +15,6 @@ import operator import os import re from csv import reader -from typing import Dict, List, Optional, Tuple, Union from pypika.terms import PseudoColumn @@ -52,7 +51,7 @@ REPORT_TRANSLATE_PATTERN = re.compile('"([^:,^"]*):') CSV_STRIP_WHITESPACE_PATTERN = re.compile(r"{\s?([0-9]+)\s?}") -def get_language(lang_list: List = None) -> str: +def get_language(lang_list: list = None) -> str: """Set `frappe.local.lang` from HTTP headers at beginning of request Order of priority for setting language: @@ -102,7 +101,7 @@ def get_language(lang_list: List = None) -> str: return frappe.local.lang -@functools.lru_cache() +@functools.lru_cache def get_parent_language(lang: str) -> str: """If the passed language is a variant, return its parent @@ -134,7 +133,7 @@ def get_user_lang(user: str = None) -> str: return lang -def get_lang_code(lang: str) -> Union[str, None]: +def get_lang_code(lang: str) -> str | None: return frappe.db.get_value("Language", {"name": lang}) or frappe.db.get_value( "Language", {"language_name": lang} ) @@ -154,7 +153,7 @@ def get_lang_dict(): ) -def get_dict(fortype: str, name: Optional[str] = None) -> Dict: +def get_dict(fortype: str, name: str | None = None) -> dict: """Returns translation dict for a type of object. :param fortype: must be one of `doctype`, `page`, `report`, `include`, `jsfile`, `boot` @@ -205,7 +204,7 @@ def get_dict(fortype: str, name: Optional[str] = None) -> Dict: translation_assets[asset_key] = message_dict cache.hset("translation_assets", frappe.local.lang, translation_assets, shared=True) - translation_map: Dict = translation_assets[asset_key] + translation_map: dict = translation_assets[asset_key] translation_map.update(get_user_translations(frappe.local.lang)) @@ -680,7 +679,7 @@ def get_all_messages_from_js_files(app_name=None): return messages -def get_messages_from_file(path: str) -> List[Tuple[str, str, str, str]]: +def get_messages_from_file(path: str) -> list[tuple[str, str, str, str]]: """Returns a list of transatable strings from a code file :param path: path of the code file @@ -695,11 +694,11 @@ def get_messages_from_file(path: str) -> List[Tuple[str, str, str, str]]: bench_path = get_bench_path() if os.path.exists(path): - with open(path, "r") as sourcefile: + with open(path) as sourcefile: try: file_contents = sourcefile.read() except Exception: - print("Could not scan file for translation: {0}".format(path)) + print(f"Could not scan file for translation: {path}") return [] return [ @@ -722,7 +721,7 @@ def extract_messages_from_code(code): code = frappe.as_unicode(render_include(code)) # Exception will occur when it encounters John Resig's microtemplating code - except (TemplateError, ImportError, InvalidIncludePath, IOError) as e: + except (TemplateError, ImportError, InvalidIncludePath, OSError) as e: if isinstance(e, InvalidIncludePath): frappe.clear_last_message() @@ -769,7 +768,7 @@ def read_csv_file(path): :param path: File path""" - with io.open(path, mode="r", encoding="utf-8", newline="") as msgfile: + with open(path, encoding="utf-8", newline="") as msgfile: data = reader(msgfile) newdata = [[val for val in row] for row in data] diff --git a/frappe/twofactor.py b/frappe/twofactor.py index c803a5ff87..55c27e2bac 100644 --- a/frappe/twofactor.py +++ b/frappe/twofactor.py @@ -90,8 +90,8 @@ def cache_2fa_data(user, token, otp_secret, tmp_id): else: expiry_time = frappe.flags.otp_expiry or 180 for k, v in {"_usr": user, "_pwd": pwd, "_otp_secret": otp_secret}.items(): - frappe.cache().set("{0}{1}".format(tmp_id, k), v) - frappe.cache().expire("{0}{1}".format(tmp_id, k), expiry_time) + frappe.cache().set(f"{tmp_id}{k}", v) + frappe.cache().expire(f"{tmp_id}{k}", expiry_time) def two_factor_is_enabled_for_(user): @@ -287,14 +287,14 @@ def get_email_body_for_qr_code(kwargs_dict): def get_link_for_qrcode(user, totp_uri): """Get link to temporary page showing QRCode.""" key = frappe.generate_hash(length=20) - key_user = "{}_user".format(key) - key_uri = "{}_uri".format(key) + key_user = f"{key}_user" + key_uri = f"{key}_uri" lifespan = ( int(frappe.db.get_value("System Settings", "System Settings", "lifespan_qrcode_image")) or 240 ) frappe.cache().set_value(key_uri, totp_uri, expires_in_sec=lifespan) frappe.cache().set_value(key_user, user, expires_in_sec=lifespan) - return get_url("/qrcode?k={}".format(key)) + return get_url(f"/qrcode?k={key}") def send_token_via_sms(otpsecret, token=None, phone_no=None): @@ -312,7 +312,7 @@ def send_token_via_sms(otpsecret, token=None, phone_no=None): return False hotp = pyotp.HOTP(otpsecret) - args = {ss.message_parameter: "Your verification code is {}".format(hotp.at(int(token)))} + args = {ss.message_parameter: f"Your verification code is {hotp.at(int(token))}"} for d in ss.get("parameters"): args[d.parameter] = d.value @@ -328,7 +328,7 @@ def send_token_via_sms(otpsecret, token=None, phone_no=None): is_async=True, job_name=None, now=False, - **sms_args + **sms_args, ) return True @@ -364,7 +364,7 @@ def send_token_via_email(user, token, otp_secret, otp_issuer, subject=None, mess is_async=True, job_name=None, now=False, - **email_args + **email_args, ) return True @@ -386,7 +386,7 @@ def get_qr_svg_code(totp_uri): def qrcode_as_png(user, totp_uri): """Save temporary Qrcode to server.""" folder = create_barcode_folder() - png_file_name = "{}.png".format(frappe.generate_hash(length=20)) + png_file_name = f"{frappe.generate_hash(length=20)}.png" _file = frappe.get_doc( { "doctype": "File", @@ -484,7 +484,7 @@ def reset_otp_secret(user): is_async=True, job_name=None, now=False, - **email_args + **email_args, ) return frappe.msgprint( _("OTP Secret has been reset. Re-registration will be required on next login.") diff --git a/frappe/utils/__init__.py b/frappe/utils/__init__.py index 6872ace7d8..82e1cb3510 100644 --- a/frappe/utils/__init__.py +++ b/frappe/utils/__init__.py @@ -9,12 +9,10 @@ import os import re import sys import traceback -import typing -from collections.abc import MutableMapping, MutableSequence, Sequence +from collections.abc import Generator, Iterable, MutableMapping, MutableSequence, Sequence from email.header import decode_header, make_header from email.utils import formataddr, parseaddr from gzip import GzipFile -from typing import Generator, Iterable from urllib.parse import quote, urlparse from redis.exceptions import ConnectionError @@ -265,7 +263,7 @@ def has_gravatar(email): hexdigest = hashlib.md5(frappe.as_unicode(email).encode("utf-8")).hexdigest() - gravatar_url = "https://secure.gravatar.com/avatar/{hash}?d=404&s=200".format(hash=hexdigest) + gravatar_url = f"https://secure.gravatar.com/avatar/{hexdigest}?d=404&s=200" try: res = requests.get(gravatar_url) if res.status_code == 200: @@ -489,7 +487,7 @@ def get_request_site_address(full_address=False): def get_site_url(site): - return "http://{site}:{port}".format(site=site, port=frappe.get_conf(site).webserver_port) + return f"http://{site}:{frappe.get_conf(site).webserver_port}" def encode_dict(d, encoding="utf-8"): @@ -507,7 +505,7 @@ def decode_dict(d, encoding="utf-8"): return d -@functools.lru_cache() +@functools.lru_cache def get_site_name(hostname): return hostname.split(":")[0] @@ -517,7 +515,7 @@ def get_disk_usage(): files_path = get_files_path() if not os.path.exists(files_path): return 0 - err, out = execute_in_shell("du -hsm {files_path}".format(files_path=files_path)) + err, out = execute_in_shell(f"du -hsm {files_path}") return cint(out.split("\n")[-2].split("\t")[0]) @@ -584,21 +582,21 @@ def update_progress_bar(txt, i, l): complete = int(float(i + 1) / l * col) completion_bar = ("=" * complete).ljust(col, " ") percent_complete = str(int(float(i + 1) / l * 100)) - sys.stdout.write("\r{0}: [{1}] {2}%".format(txt, completion_bar, percent_complete)) + sys.stdout.write(f"\r{txt}: [{completion_bar}] {percent_complete}%") sys.stdout.flush() def get_html_format(print_path): html_format = None if os.path.exists(print_path): - with open(print_path, "r") as f: + with open(print_path) as f: html_format = f.read() for include_directive, path in INCLUDE_DIRECTIVE_PATTERN.findall(html_format): for app_name in frappe.get_installed_apps(): include_path = frappe.get_app_path(app_name, *path.split(os.path.sep)) if os.path.exists(include_path): - with open(include_path, "r") as f: + with open(include_path) as f: html_format = html_format.replace(include_directive, f.read()) break @@ -904,10 +902,10 @@ def get_file_size(path, format=False): for unit in ["", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi"]: if abs(num) < 1024: - return "{0:3.1f}{1}{2}".format(num, unit, suffix) + return f"{num:3.1f}{unit}{suffix}" num /= 1024 - return "{0:.1f}{1}{2}".format(num, "Yi", suffix) + return "{:.1f}{}{}".format(num, "Yi", suffix) def get_build_version(): @@ -962,13 +960,13 @@ def get_bench_relative_path(file_path): file_path = os.path.join(base_path, file_path) if not os.path.exists(file_path): - print("Invalid path {0}".format(file_path[3:])) + print(f"Invalid path {file_path[3:]}") sys.exit(1) return os.path.abspath(file_path) -def groupby_metric(iterable: typing.Dict[str, list], key: str): +def groupby_metric(iterable: dict[str, list], key: str): """Group records by a metric. Usecase: Lets assume we got country wise players list with the ranking given for each player(multiple players in a country can have same ranking aswell). diff --git a/frappe/utils/background_jobs.py b/frappe/utils/background_jobs.py index a7956717d4..3d3df3504d 100755 --- a/frappe/utils/background_jobs.py +++ b/frappe/utils/background_jobs.py @@ -3,7 +3,7 @@ import socket import time from collections import defaultdict from functools import lru_cache -from typing import TYPE_CHECKING, List +from typing import TYPE_CHECKING from uuid import uuid4 import redis @@ -23,7 +23,7 @@ if TYPE_CHECKING: from rq.job import Job -@lru_cache() +@lru_cache def get_queues_timeout(): common_site_config = frappe.get_conf() custom_workers_config = common_site_config.get("workers", {}) @@ -333,7 +333,7 @@ def get_redis_conn(username=None, password=None): return redis_connection -def get_queues() -> List[Queue]: +def get_queues() -> list[Queue]: """Get all the queues linked to the current bench.""" queues = Queue.all(connection=get_redis_conn()) return [q for q in queues if is_queue_accessible(q)] diff --git a/frappe/utils/backups.py b/frappe/utils/backups.py index 85826b4ce7..e6068fd299 100644 --- a/frappe/utils/backups.py +++ b/frappe/utils/backups.py @@ -103,14 +103,12 @@ class BackupGenerator: if self.backup_path: os.makedirs(self.backup_path, exist_ok=True) - for file_path in set( - [ - self.backup_path_files, - self.backup_path_db, - self.backup_path_private_files, - self.backup_path_conf, - ] - ): + for file_path in { + self.backup_path_files, + self.backup_path_db, + self.backup_path_private_files, + self.backup_path_conf, + }: if file_path: dir = os.path.dirname(file_path) os.makedirs(dir, exist_ok=True) @@ -337,13 +335,13 @@ class BackupGenerator: def print_summary(self): backup_summary = self.get_summary() - print("Backup Summary for {0} at {1}".format(frappe.local.site, now())) + print(f"Backup Summary for {frappe.local.site} at {now()}") title = max(len(x) for x in backup_summary) path = max(len(x["path"]) for x in backup_summary.values()) for _type, info in backup_summary.items(): - template = "{{0:{0}}}: {{1:{1}}} {{2}}".format(title, path) + template = f"{{0:{title}}}: {{1:{path}}} {{2}}" print(template.format(_type.title(), info["path"], info["size"])) def backup_files(self): @@ -417,12 +415,10 @@ class BackupGenerator: if self.db_type == "postgres": if self.backup_includes: - args["include"] = " ".join( - ["--table='public.\"{0}\"'".format(table) for table in self.backup_includes] - ) + args["include"] = " ".join([f"--table='public.\"{table}\"'" for table in self.backup_includes]) elif self.backup_excludes: args["exclude"] = " ".join( - ["--exclude-table-data='public.\"{0}\"'".format(table) for table in self.backup_excludes] + [f"--exclude-table-data='public.\"{table}\"'" for table in self.backup_excludes] ) cmd_string = ( @@ -432,13 +428,10 @@ class BackupGenerator: else: if self.backup_includes: - args["include"] = " ".join(["'{0}'".format(x) for x in self.backup_includes]) + args["include"] = " ".join([f"'{x}'" for x in self.backup_includes]) elif self.backup_excludes: args["exclude"] = " ".join( - [ - "--ignore-table='{0}.{1}'".format(frappe.conf.db_name, table) - for table in self.backup_excludes - ] + [f"--ignore-table='{frappe.conf.db_name}.{table}'" for table in self.backup_excludes] ) cmd_string = ( @@ -479,14 +472,14 @@ class BackupGenerator: Your backups are ready to be downloaded. -1. [Click here to download the database backup](%(db_backup_url)s) -2. [Click here to download the files backup](%(files_backup_url)s) +1. [Click here to download the database backup]({db_backup_url}) +2. [Click here to download the files backup]({files_backup_url}) This link will be valid for 24 hours. A new backup will be available for -download only after 24 hours.""" % { - "db_backup_url": db_backup_url, - "files_backup_url": files_backup_url, - } +download only after 24 hours.""".format( + db_backup_url=db_backup_url, + files_backup_url=files_backup_url, + ) datetime_str = datetime.fromtimestamp(os.stat(self.backup_path_db).st_ctime) subject = datetime_str.strftime("%d/%m/%Y %H:%M:%S") + """ - Backup ready to be downloaded""" diff --git a/frappe/utils/boilerplate.py b/frappe/utils/boilerplate.py index bd4cff9ef9..503ee6d338 100644 --- a/frappe/utils/boilerplate.py +++ b/frappe/utils/boilerplate.py @@ -110,7 +110,7 @@ def _create_app_boilerplate(dest, hooks, no_git=False): with open(os.path.join(dest, hooks.app_name, "README.md"), "w") as f: f.write( frappe.as_unicode( - "## {0}\n\n{1}\n\n#### License\n\n{2}".format( + "## {}\n\n{}\n\n#### License\n\n{}".format( hooks.app_title, hooks.app_description, hooks.app_license ) ) diff --git a/frappe/utils/caching.py b/frappe/utils/caching.py index 326dacfd5a..a2c9496098 100644 --- a/frappe/utils/caching.py +++ b/frappe/utils/caching.py @@ -5,14 +5,14 @@ import json from collections import defaultdict from datetime import datetime, timedelta from functools import wraps -from typing import Callable, Dict, Optional, Tuple +from typing import Callable import frappe _SITE_CACHE = defaultdict(lambda: defaultdict(dict)) -def __generate_request_cache_key(args: Tuple, kwargs: Dict): +def __generate_request_cache_key(args: tuple, kwargs: dict): """Generate a key for the cache.""" if not kwargs: return hash(args) @@ -61,7 +61,7 @@ def request_cache(func: Callable) -> Callable: return wrapper -def site_cache(ttl: Optional[int] = None, maxsize: Optional[int] = None) -> Callable: +def site_cache(ttl: int | None = None, maxsize: int | None = None) -> Callable: """Decorator to cache method calls across requests. The cache is stored in frappe.utils.caching._SITE_CACHE. The cache persists on the parent process. It offers a light-weight cache for the current process without the additional diff --git a/frappe/utils/change_log.py b/frappe/utils/change_log.py index 95a17f9dc1..12069cce09 100644 --- a/frappe/utils/change_log.py +++ b/frappe/utils/change_log.py @@ -65,9 +65,7 @@ def get_change_log_for_app(app, from_version, to_version): # remove pre-release part to_version.prerelease = None - major_version_folders = [ - "v{0}".format(i) for i in range(from_version.major, to_version.major + 1) - ] + major_version_folders = [f"v{i}" for i in range(from_version.major, to_version.major + 1)] app_change_log = [] for folder in os.listdir(change_log_folder): @@ -119,9 +117,9 @@ def get_versions(): } if versions[app]["branch"] != "master": - branch_version = app_hooks.get("{0}_version".format(versions[app]["branch"])) + branch_version = app_hooks.get("{}_version".format(versions[app]["branch"])) if branch_version: - versions[app]["branch_version"] = branch_version[0] + " ({0})".format( + versions[app]["branch_version"] = branch_version[0] + " ({})".format( get_app_last_commit_ref(app) ) @@ -238,9 +236,7 @@ def check_release_on_github(app: str): try: # Check if repo remote is on github - remote_url = subprocess.check_output( - "cd ../apps/{} && git ls-remote --get-url".format(app), shell=True - ) + remote_url = subprocess.check_output(f"cd ../apps/{app} && git ls-remote --get-url", shell=True) except subprocess.CalledProcessError: # Passing this since some apps may not have git initialized in them return @@ -305,7 +301,7 @@ def show_update_popup(): if release_links: message = _("New {} releases for the following apps are available").format(_(update_type)) update_message += ( - "
{0}
".format( + "
{}
".format( message, release_links ) ) diff --git a/frappe/utils/connections.py b/frappe/utils/connections.py index bf0a338681..6660e6ce19 100644 --- a/frappe/utils/connections.py +++ b/frappe/utils/connections.py @@ -13,7 +13,7 @@ def is_open(ip, port, timeout=10): s.connect((ip, int(port))) s.shutdown(socket.SHUT_RDWR) return True - except socket.error: + except OSError: return False finally: s.close() diff --git a/frappe/utils/csvutils.py b/frappe/utils/csvutils.py index 9d32712454..4840c806bb 100644 --- a/frappe/utils/csvutils.py +++ b/frappe/utils/csvutils.py @@ -188,7 +188,7 @@ def get_csv_content_from_google_sheets(url): # remove /edit path url = url.rsplit("/edit", 1)[0] # add /export path, - url = url + "/export?format=csv&gid={0}".format(gid) + url = url + f"/export?format=csv&gid={gid}" headers = {"Accept": "text/csv"} response = requests.get(url, headers=headers) diff --git a/frappe/utils/dashboard.py b/frappe/utils/dashboard.py index ad1f391831..6acd63274e 100644 --- a/frappe/utils/dashboard.py +++ b/frappe/utils/dashboard.py @@ -21,7 +21,7 @@ def cache_source(function): if no_cache: return function(chart=chart, no_cache=no_cache) chart_name = frappe.parse_json(chart).name - cache_key = "chart-data:{}".format(chart_name) + cache_key = f"chart-data:{chart_name}" if int(kwargs.get("refresh") or 0): results = generate_and_cache_results(kwargs, function, cache_key, chart) else: @@ -93,7 +93,7 @@ def sync_dashboards(app=None): apps = frappe.get_installed_apps() for app_name in apps: - print("Updating Dashboard for {app}".format(app=app_name)) + print(f"Updating Dashboard for {app_name}") for module_name in frappe.local.app_modules.get(app_name) or []: frappe.flags.in_import = True make_records_in_module(app_name, module_name) @@ -101,7 +101,7 @@ def sync_dashboards(app=None): def make_records_in_module(app, module): - dashboards_path = frappe.get_module_path(module, "{module}_dashboard".format(module=module)) + dashboards_path = frappe.get_module_path(module, f"{module}_dashboard") charts_path = frappe.get_module_path(module, "dashboard chart") cards_path = frappe.get_module_path(module, "number card") diff --git a/frappe/utils/data.py b/frappe/utils/data.py index 20c9dabfbf..7f590ed5e6 100644 --- a/frappe/utils/data.py +++ b/frappe/utils/data.py @@ -11,7 +11,7 @@ import time import typing from code import compile_command from enum import Enum -from typing import Any, Dict, List, Literal, Optional, Tuple, TypeVar, Union +from typing import Any, Literal, Optional, TypeVar, Union from urllib.parse import quote, urljoin from click import secho @@ -72,7 +72,7 @@ def is_invalid_date_string(date_string: str) -> bool: ) -def getdate(string_date: Optional["DateTimeLikeObject"] = None) -> Optional[datetime.date]: +def getdate(string_date: Optional["DateTimeLikeObject"] = None) -> datetime.date | None: """ Converts string date (yyyy-mm-dd) to datetime.date object. If no input is provided, current date is returned. @@ -101,7 +101,7 @@ def getdate(string_date: Optional["DateTimeLikeObject"] = None) -> Optional[date def get_datetime( datetime_str: Optional["DateTimeLikeObject"] = None, -) -> Optional[datetime.datetime]: +) -> datetime.datetime | None: from dateutil import parser if datetime_str is None: @@ -125,7 +125,7 @@ def get_datetime( return parser.parse(datetime_str) -def get_timedelta(time: Optional[str] = None) -> Optional[datetime.timedelta]: +def get_timedelta(time: str | None = None) -> datetime.timedelta | None: """Return `datetime.timedelta` object from string value of a valid time format. Returns None if `time` is not a valid format @@ -157,7 +157,7 @@ def get_timedelta(time: Optional[str] = None) -> Optional[datetime.timedelta]: return None -def to_timedelta(time_str: Union[str, datetime.time]) -> datetime.timedelta: +def to_timedelta(time_str: str | datetime.time) -> datetime.timedelta: from dateutil import parser if isinstance(time_str, datetime.time): @@ -393,7 +393,7 @@ def get_first_day(dt, d_years=0, d_months=0, as_str: Literal[True] = False) -> s # TODO: first arg def get_first_day( dt, d_years: int = 0, d_months: int = 0, as_str: bool = False -) -> Union[str, datetime.date]: +) -> str | datetime.date: """ Returns the first day of the month for the date specified by date object Also adds `d_years` and `d_months` if specified @@ -421,7 +421,7 @@ def get_quarter_start(dt, as_str: Literal[True] = False) -> str: ... -def get_quarter_start(dt, as_str: bool = False) -> Union[str, datetime.date]: +def get_quarter_start(dt, as_str: bool = False) -> str | datetime.date: date = getdate(dt) quarter = (date.month - 1) // 3 + 1 first_date_of_quarter = datetime.date(date.year, ((quarter - 1) * 3) + 1, 1) @@ -474,7 +474,7 @@ def get_quarter_ending(date): # find the earliest quarter ending date that is after # the given date for month in (3, 6, 9, 12): - quarter_end_month = getdate("{}-{}-01".format(date.year, month)) + quarter_end_month = getdate(f"{date.year}-{month}-01") quarter_end_date = getdate(get_last_day(quarter_end_month)) if date <= quarter_end_date: date = quarter_end_date @@ -487,7 +487,7 @@ def get_year_ending(date): """returns year ending of the given date""" date = getdate(date) # first day of next year (note year starts from 1) - date = add_to_date("{}-01-01".format(date.year), months=12) + date = add_to_date(f"{date.year}-01-01", months=12) # last day of this month return add_to_date(date, days=-1) @@ -528,7 +528,7 @@ def get_time_str(timedelta_obj) -> str: hours, remainder = divmod(timedelta_obj.seconds, 3600) minutes, seconds = divmod(remainder, 60) - return "{0}:{1}:{2}".format(hours, minutes, seconds) + return f"{hours}:{minutes}:{seconds}" def get_user_date_format() -> str: @@ -550,7 +550,7 @@ def get_user_time_format() -> str: return frappe.local.user_time_format or "HH:mm:ss" -def format_date(string_date=None, format_string: Optional[str] = None) -> str: +def format_date(string_date=None, format_string: str | None = None) -> str: """Converts the given string date to :data:`user_date_format` User format specified in defaults @@ -583,7 +583,7 @@ def format_date(string_date=None, format_string: Optional[str] = None) -> str: formatdate = format_date # For backwards compatibility -def format_time(time_string=None, format_string: Optional[str] = None) -> str: +def format_time(time_string=None, format_string: str | None = None) -> str: """Converts the given string time to :data:`user_time_format` User format specified in defaults @@ -610,9 +610,7 @@ def format_time(time_string=None, format_string: Optional[str] = None) -> str: return formatted_time -def format_datetime( - datetime_string: DateTimeLikeObject, format_string: Optional[str] = None -) -> str: +def format_datetime(datetime_string: DateTimeLikeObject, format_string: str | None = None) -> str: """Converts the given string time to :data:`user_datetime_format` User format specified in defaults @@ -719,14 +717,14 @@ def get_weekdays(): return ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"] -def get_weekday(datetime: Optional[datetime.datetime] = None) -> str: +def get_weekday(datetime: datetime.datetime | None = None) -> str: if not datetime: datetime = now_datetime() weekdays = get_weekdays() return weekdays[datetime.weekday()] -def get_timespan_date_range(timespan: str) -> Tuple[datetime.datetime, datetime.datetime]: +def get_timespan_date_range(timespan: str) -> tuple[datetime.datetime, datetime.datetime]: today = nowdate() date_range_map = { "last week": lambda: ( @@ -886,16 +884,16 @@ def cast(fieldtype, value=None): @typing.overload -def flt(s: Union[NumericType, str], precision: Literal[0]) -> int: +def flt(s: NumericType | str, precision: Literal[0]) -> int: ... @typing.overload -def flt(s: Union[NumericType, str], precision: Optional[int] = None) -> float: +def flt(s: NumericType | str, precision: int | None = None) -> float: ... -def flt(s: Union[NumericType, str], precision: Optional[int] = None) -> float: +def flt(s: NumericType | str, precision: int | None = None) -> float: """Convert to float (ignoring commas in string) :param s: Number in string or other numeric format. @@ -928,7 +926,7 @@ def flt(s: Union[NumericType, str], precision: Optional[int] = None) -> float: return num -def cint(s: Union[NumericType, str], default: int = 0) -> int: +def cint(s: NumericType | str, default: int = 0) -> int: """Convert to integer :param s: Number in string or other numeric format. @@ -997,7 +995,7 @@ def cstr(s, encoding="utf-8"): return frappe.as_unicode(s, encoding) -def sbool(x: str) -> Union[bool, Any]: +def sbool(x: str) -> bool | Any: """Converts str object to Boolean if possible. Example: "true" becomes True @@ -1113,10 +1111,10 @@ def parse_val(v): def fmt_money( - amount: Union[str, float, int], - precision: Optional[int] = None, - currency: Optional[str] = None, - format: Optional[str] = None, + amount: str | float | int, + precision: int | None = None, + currency: str | None = None, + format: str | None = None, ) -> str: """ Convert to string with commas for thousands, millions etc @@ -1206,7 +1204,7 @@ number_format_info = { } -def get_number_format_info(format: str) -> Tuple[str, str, int]: +def get_number_format_info(format: str) -> tuple[str, str, int]: return number_format_info.get(format) or (".", ",", 2) @@ -1214,9 +1212,9 @@ def get_number_format_info(format: str) -> Tuple[str, str, int]: # convert currency to words # def money_in_words( - number: Union[str, float, int], - main_currency: Optional[str] = None, - fraction_currency: Optional[str] = None, + number: str | float | int, + main_currency: str | None = None, + fraction_currency: str | None = None, ): """ Returns string in words with currency and fraction currency. @@ -1251,7 +1249,7 @@ def money_in_words( fraction_length = get_number_format_info(number_format)[2] - n = "%.{0}f".format(fraction_length) % number + n = f"%.{fraction_length}f" % number numbers = n.split(".") main, fraction = numbers if len(numbers) > 1 else [n, "00"] @@ -1266,7 +1264,7 @@ def money_in_words( # 0.00 if main == "0" and fraction in ["00", "000"]: - out = "{0} {1}".format(main_currency, _("Zero")) + out = "{} {}".format(main_currency, _("Zero")) # 0.XX elif main == "0": out = _(in_words(fraction, in_million).title()) + " " + fraction_currency @@ -1329,7 +1327,7 @@ def get_thumbnail_base64_for_image(src): from frappe.core.doctype.file.utils import get_local_image if not src: - frappe.throw("Invalid source for image: {0}".format(src)) + frappe.throw(f"Invalid source for image: {src}") if not src.startswith("/files") or ".." in src: return @@ -1344,7 +1342,7 @@ def get_thumbnail_base64_for_image(src): try: image, unused_filename, extn = get_local_image(src) - except IOError: + except OSError: return original_size = image.size @@ -1353,7 +1351,7 @@ def get_thumbnail_base64_for_image(src): base64_string = image_to_base64(image, extn) return { - "base64": "data:image/{0};base64,{1}".format(extn, safe_decode(base64_string)), + "base64": f"data:image/{extn};base64,{safe_decode(base64_string)}", "width": original_size[0], "height": original_size[1], } @@ -1372,7 +1370,7 @@ def image_to_base64(image, extn: str) -> bytes: return img_str -def pdf_to_base64(filename: str) -> Optional[bytes]: +def pdf_to_base64(filename: str) -> bytes | None: from frappe.utils.file_manager import get_file_path if "../" in filename or filename.rsplit(".")[-1] not in ["pdf", "PDF"]: @@ -1412,7 +1410,7 @@ def escape_html(text: str) -> str: return "".join(html_escape_table.get(c, c) for c in text) -def pretty_date(iso_datetime: Union[datetime.datetime, str]) -> str: +def pretty_date(iso_datetime: datetime.datetime | str) -> str: """ Takes an ISO time and returns a string representing how long ago the date represents. @@ -1462,7 +1460,7 @@ def pretty_date(iso_datetime: Union[datetime.datetime, str]) -> str: elif dt_diff_days < 550.0: return _("1 year ago") else: - return "{0} years ago".format(cint(math.floor(dt_diff_days / 365.0))) + return f"{cint(math.floor(dt_diff_days / 365.0))} years ago" def comma_or(some_list, add_quotes=True): @@ -1503,12 +1501,12 @@ def new_line_sep(some_list): return some_list -def filter_strip_join(some_list: List[str], sep: str) -> List[str]: +def filter_strip_join(some_list: list[str], sep: str) -> list[str]: """given a list, filter None values, strip spaces and join""" - return (cstr(sep)).join((cstr(a).strip() for a in filter(None, some_list))) + return (cstr(sep)).join(cstr(a).strip() for a in filter(None, some_list)) -def get_url(uri: Optional[str] = None, full_address: bool = False) -> str: +def get_url(uri: str | None = None, full_address: bool = False) -> str: """get app url from request""" host_name = frappe.local.conf.host_name or frappe.local.conf.hostname @@ -1582,19 +1580,19 @@ def get_host_name() -> str: return get_url().rsplit("//", 1)[-1] -def get_link_to_form(doctype: str, name: str, label: Optional[str] = None) -> str: +def get_link_to_form(doctype: str, name: str, label: str | None = None) -> str: if not label: label = name - return """{1}""".format(get_url_to_form(doctype, name), label) + return f"""{label}""" def get_link_to_report( name: str, - label: Optional[str] = None, - report_type: Optional[str] = None, - doctype: Optional[str] = None, - filters: Optional[Dict] = None, + label: str | None = None, + report_type: str | None = None, + doctype: str | None = None, + filters: dict | None = None, ) -> str: if not label: label = name @@ -1612,39 +1610,37 @@ def get_link_to_report( filters = "&".join(conditions) - return """{1}""".format( + return """{}""".format( get_url_to_report_with_filters(name, filters, report_type, doctype), label ) else: - return """{1}""".format(get_url_to_report(name, report_type, doctype), label) + return f"""{label}""" def get_absolute_url(doctype: str, name: str) -> str: - return "/app/{0}/{1}".format(quoted(slug(doctype)), quoted(name)) + return f"/app/{quoted(slug(doctype))}/{quoted(name)}" def get_url_to_form(doctype: str, name: str) -> str: - return get_url(uri="/app/{0}/{1}".format(quoted(slug(doctype)), quoted(name))) + return get_url(uri=f"/app/{quoted(slug(doctype))}/{quoted(name)}") def get_url_to_list(doctype: str) -> str: - return get_url(uri="/app/{0}".format(quoted(slug(doctype)))) + return get_url(uri=f"/app/{quoted(slug(doctype))}") -def get_url_to_report( - name, report_type: Optional[str] = None, doctype: Optional[str] = None -) -> str: +def get_url_to_report(name, report_type: str | None = None, doctype: str | None = None) -> str: if report_type == "Report Builder": - return get_url(uri="/app/{0}/view/report/{1}".format(quoted(slug(doctype)), quoted(name))) + return get_url(uri=f"/app/{quoted(slug(doctype))}/view/report/{quoted(name)}") else: - return get_url(uri="/app/query-report/{0}".format(quoted(name))) + return get_url(uri=f"/app/query-report/{quoted(name)}") def get_url_to_report_with_filters(name, filters, report_type=None, doctype=None): if report_type == "Report Builder": - return get_url(uri="/app/{0}/view/report?{1}".format(quoted(doctype), filters)) + return get_url(uri=f"/app/{quoted(doctype)}/view/report?{filters}") else: - return get_url(uri="/app/query-report/{0}?{1}".format(quoted(name), filters)) + return get_url(uri=f"/app/query-report/{quoted(name)}?{filters}") operator_map = { @@ -1665,7 +1661,7 @@ operator_map = { } -def evaluate_filters(doc, filters: Union[Dict, List, Tuple]): +def evaluate_filters(doc, filters: dict | list | tuple): """Returns true if doc matches filters""" if isinstance(filters, dict): for key, value in filters.items(): @@ -1682,7 +1678,7 @@ def evaluate_filters(doc, filters: Union[Dict, List, Tuple]): return True -def compare(val1: Any, condition: str, val2: Any, fieldtype: Optional[str] = None): +def compare(val1: Any, condition: str, val2: Any, fieldtype: str | None = None): ret = False if fieldtype: val2 = cast(fieldtype, val2) @@ -1692,7 +1688,7 @@ def compare(val1: Any, condition: str, val2: Any, fieldtype: Optional[str] = Non return ret -def get_filter(doctype: str, f: Union[Dict, List, Tuple], filters_config=None) -> "frappe._dict": +def get_filter(doctype: str, f: dict | list | tuple, filters_config=None) -> "frappe._dict": """Returns a _dict like { @@ -1825,7 +1821,7 @@ def sanitize_column(column_name: str) -> None: if "ifnull" in column_name: if regex.match(column_name): # to avoid and, or - if any(" {0} ".format(keyword) in column_name.split() for keyword in blacklisted_keywords): + if any(f" {keyword} " in column_name.split() for keyword in blacklisted_keywords): _raise_exception() # to avoid select, delete, drop, update and case @@ -1881,7 +1877,7 @@ def quote_urls(html: str) -> str: return URLS_HTTP_TAG_PATTERN.sub(_quote_url, html) -def unique(seq: typing.Sequence["T"]) -> List["T"]: +def unique(seq: typing.Sequence["T"]) -> list["T"]: """use this instead of list(set()) to preserve order of the original list. Thanks to Stackoverflow: http://stackoverflow.com/questions/480214/how-do-you-remove-duplicates-from-a-list-in-python-whilst-preserving-order""" @@ -1890,7 +1886,7 @@ def unique(seq: typing.Sequence["T"]) -> List["T"]: return [x for x in seq if not (x in seen or seen_add(x))] -def strip(val: str, chars: Optional[str] = None) -> str: +def strip(val: str, chars: str | None = None) -> str: # \ufeff is no-width-break, \u200b is no-width-space return (val or "").replace("\ufeff", "").replace("\u200b", "").strip(chars) @@ -1938,7 +1934,7 @@ def markdown(markdown_text): return md_to_html(markdown_text) -def is_subset(list_a: List, list_b: List) -> bool: +def is_subset(list_a: list, list_b: list) -> bool: """Returns whether list_a is a subset of list_b""" return len(list(set(list_a) & set(list_b))) == len(list_a) @@ -2032,7 +2028,7 @@ def validate_json_string(string: str) -> None: class _UserInfo(typing.TypedDict): email: str - image: Optional[str] + image: str | None name: str @@ -2047,7 +2043,7 @@ def get_user_info_for_avatar(user_id: str) -> _UserInfo: def validate_python_code( - string: str, fieldname: Optional[str] = None, is_expression: bool = True + string: str, fieldname: str | None = None, is_expression: bool = True ) -> None: """Validate python code fields by using compile_command to ensure that expression is valid python. @@ -2099,7 +2095,7 @@ def format_timedelta(o: datetime.timedelta) -> str: else: seconds = rounded_seconds - return "{:01}:{:02}:{:02}".format(int(hours), int(minutes), seconds) + return f"{int(hours):01}:{int(minutes):02}:{seconds:02}" def parse_timedelta(s: str) -> datetime.timedelta: diff --git a/frappe/utils/dateutils.py b/frappe/utils/dateutils.py index d7412a444f..ca147744d4 100644 --- a/frappe/utils/dateutils.py +++ b/frappe/utils/dateutils.py @@ -42,7 +42,7 @@ def user_to_str(date, date_format=None): try: return datetime.datetime.strptime(date, dateformats[date_format]).strftime("%Y-%m-%d") except ValueError: - raise ValueError("Date %s must be in format %s" % (date, date_format)) + raise ValueError(f"Date {date} must be in format {date_format}") def parse_date(date): diff --git a/frappe/utils/diff.py b/frappe/utils/diff.py index 02fa1ef4c7..2fbe555e12 100644 --- a/frappe/utils/diff.py +++ b/frappe/utils/diff.py @@ -1,6 +1,5 @@ import json from difflib import unified_diff -from typing import List, Union import frappe from frappe.utils import pretty_date @@ -9,8 +8,8 @@ from frappe.utils.data import cstr @frappe.whitelist() def get_version_diff( - from_version: Union[int, str], to_version: Union[int, str], fieldname: str = "script" -) -> List[str]: + from_version: int | str, to_version: int | str, fieldname: str = "script" +) -> list[str]: before, before_timestamp = _get_value_from_version(from_version, fieldname) after, after_timestamp = _get_value_from_version(to_version, fieldname) @@ -32,7 +31,7 @@ def get_version_diff( return list(diff) -def _get_value_from_version(version_name: Union[int, str], fieldname: str): +def _get_value_from_version(version_name: int | str, fieldname: str): version = frappe.get_list("Version", fields=["data", "modified"], filters={"name": version_name}) if version: data = json.loads(version[0].data) diff --git a/frappe/utils/doctor.py b/frappe/utils/doctor.py index a474ffc612..5b12a01990 100644 --- a/frappe/utils/doctor.py +++ b/frappe/utils/doctor.py @@ -74,7 +74,7 @@ def get_pending_jobs(site=None): for job in q.jobs: method_kwargs = job.kwargs["kwargs"] if job.kwargs["kwargs"] else "" if job.kwargs["site"] == site: - jobs_per_queue[queue].append("{0} {1}".format(job.kwargs["method"], method_kwargs)) + jobs_per_queue[queue].append("{} {}".format(job.kwargs["method"], method_kwargs)) return jobs_per_queue @@ -122,14 +122,14 @@ def doctor(site=None): # TODO improve this print("Workers online:", workers_online) - print("-----{0} Jobs-----".format(site)) + print(f"-----{site} Jobs-----") for queue in get_queue_list(): if jobs_per_queue[queue]: print("Queue:", queue) print("Number of Jobs: ", job_count[queue]) print("Methods:") for method, count in jobs_per_queue[queue].items(): - print("{0} : {1}".format(method, count)) + print(f"{method} : {count}") print("------------") return True @@ -140,5 +140,5 @@ def pending_jobs(site=None): pending_jobs = get_pending_jobs(site) for queue in get_queue_list(): if pending_jobs[queue]: - print("-----Queue :{0}-----".format(queue)) + print(f"-----Queue :{queue}-----") print("\n".join(pending_jobs[queue])) diff --git a/frappe/utils/error.py b/frappe/utils/error.py index bc369eccad..94b3cf3b2c 100644 --- a/frappe/utils/error.py +++ b/frappe/utils/error.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Maxwell Morais and contributors # License: MIT. See LICENSE @@ -32,16 +31,16 @@ def make_error_snapshot(exception): snapshot_folder = get_error_snapshot_path() frappe.create_folder(snapshot_folder) - snapshot_file_path = os.path.join(snapshot_folder, "{0}.json".format(error_id)) + snapshot_file_path = os.path.join(snapshot_folder, f"{error_id}.json") snapshot = get_snapshot(exception) with open(encode(snapshot_file_path), "wb") as error_file: error_file.write(encode(frappe.as_json(snapshot))) - logger.error("New Exception collected with id: {}".format(error_id)) + logger.error(f"New Exception collected with id: {error_id}") except Exception as e: - logger.error("Could not take error snapshot: {0}".format(e), exc_info=True) + logger.error(f"Could not take error snapshot: {e}", exc_info=True) def get_snapshot(exception, context=10): @@ -78,7 +77,7 @@ def get_snapshot(exception, context=10): if func != "?": call = inspect.formatargvalues( - args, varargs, varkw, locals, formatvalue=lambda value: "={}".format(pydoc.text.repr(value)) + args, varargs, varkw, locals, formatvalue=lambda value: f"={pydoc.text.repr(value)}" ) # basic frame information @@ -112,7 +111,7 @@ def get_snapshot(exception, context=10): continue if value is not cgitb.__UNDEF__: if where == "global": - name = "global {name:s}".format(name=name) + name = f"global {name:s}" elif where != "local": name = where + " " + name.split(".")[-1] f["dump"][name] = pydoc.text.repr(value) @@ -149,7 +148,7 @@ def collect_error_snapshots(): fullpath = os.path.join(path, fname) try: - with open(fullpath, "r") as filedata: + with open(fullpath) as filedata: data = json.load(filedata) except ValueError: diff --git a/frappe/utils/file_manager.py b/frappe/utils/file_manager.py index 620962004a..875ca10c63 100644 --- a/frappe/utils/file_manager.py +++ b/frappe/utils/file_manager.py @@ -209,9 +209,9 @@ def save_file_on_filesystem(fname, content, content_type=None, is_private=0): fpath = write_file(content, fname, is_private) if is_private: - file_url = "/private/files/{0}".format(fname) + file_url = f"/private/files/{fname}" else: - file_url = "/files/{0}".format(fname) + file_url = f"/files/{fname}" return {"file_name": os.path.basename(fpath), "file_url": file_url} @@ -342,7 +342,7 @@ def get_file(fname): file_path = get_file_path(fname) # read the file - with io.open(encode(file_path), mode="rb") as f: + with open(encode(file_path), mode="rb") as f: content = f.read() try: # for plain text files @@ -405,7 +405,7 @@ def get_file_name(fname, optional_suffix): partial, extn = f[0], "" else: partial, extn = f[0], "." + f[1] - return "{partial}{suffix}{extn}".format(partial=partial, extn=extn, suffix=optional_suffix) + return f"{partial}{optional_suffix}{extn}" return fname diff --git a/frappe/utils/fixtures.py b/frappe/utils/fixtures.py index 42e86e9f11..6b3166bfe6 100644 --- a/frappe/utils/fixtures.py +++ b/frappe/utils/fixtures.py @@ -58,9 +58,7 @@ def export_fixtures(app=None): filters = fixture.get("filters") or_filters = fixture.get("or_filters") fixture = fixture.get("doctype") or fixture.get("dt") - print( - "Exporting {0} app {1} filters {2}".format(fixture, app, (filters if filters else or_filters)) - ) + print(f"Exporting {fixture} app {app} filters {(filters if filters else or_filters)}") if not os.path.exists(frappe.get_app_path(app, "fixtures")): os.mkdir(frappe.get_app_path(app, "fixtures")) diff --git a/frappe/utils/formatters.py b/frappe/utils/formatters.py index 575a05a5c2..12b3ee11be 100644 --- a/frappe/utils/formatters.py +++ b/frappe/utils/formatters.py @@ -96,7 +96,7 @@ def format_value(value, df=None, doc=None, currency=None, translated=False, form return fmt_money(value, precision=precision, currency=currency) elif df.get("fieldtype") == "Percent": - return "{}%".format(flt(value, 2)) + return f"{flt(value, 2)}%" elif df.get("fieldtype") in ("Text", "Small Text"): if not BLOCK_TAGS_PATTERN.search(value): @@ -121,7 +121,7 @@ def format_value(value, df=None, doc=None, currency=None, translated=False, form return format_duration(value, hide_days) elif df.get("fieldtype") == "Text Editor": - return "
{}
".format(value) + return f"
{value}
" elif df.get("fieldtype") in ["Link", "Dynamic Link"]: if not doc or not doc.get("__link_titles") or not df.options: @@ -136,6 +136,6 @@ def format_value(value, df=None, doc=None, currency=None, translated=False, form _field = meta.get_field(df.options) doctype = _field.options - return doc.__link_titles.get("{0}::{1}".format(doctype, value), value) + return doc.__link_titles.get(f"{doctype}::{value}", value) return value diff --git a/frappe/utils/global_search.py b/frappe/utils/global_search.py index af6d9a3c28..14dcc0fdda 100644 --- a/frappe/utils/global_search.py +++ b/frappe/utils/global_search.py @@ -223,12 +223,12 @@ def insert_values_for_multiple_docs(all_contents): { "mariadb": """INSERT IGNORE INTO `__global_search` (doctype, name, content, published, title, route) - VALUES {0} """.format( + VALUES {} """.format( ", ".join(batch_values) ), "postgres": """INSERT INTO `__global_search` (doctype, name, content, published, title, route) - VALUES {0} + VALUES {} ON CONFLICT("name", "doctype") DO NOTHING""".format( ", ".join(batch_values) ), diff --git a/frappe/utils/goal.py b/frappe/utils/goal.py index fb348496da..fe8c2399a4 100644 --- a/frappe/utils/goal.py +++ b/frappe/utils/goal.py @@ -2,7 +2,6 @@ # License: MIT. See LICENSE from contextlib import suppress -from typing import Dict, Optional import frappe from frappe import _ @@ -16,9 +15,9 @@ def get_monthly_results( goal_doctype: str, goal_field: str, date_col: str, - filters: Dict, + filters: dict, aggregation: str = "sum", -) -> Dict: +) -> dict: """Get monthly aggregation values for given field of doctype""" Table = DocType(goal_doctype) @@ -49,8 +48,8 @@ def get_monthly_goal_graph_data( date_field: str, filter_str: str = None, aggregation: str = "sum", - filters: Optional[Dict] = None, -) -> Dict: + filters: dict | None = None, +) -> dict: """ Get month-wise graph data for a doctype based on aggregation values of a field in the goal doctype diff --git a/frappe/utils/identicon.py b/frappe/utils/identicon.py index 448f24657c..1267b8f9c3 100644 --- a/frappe/utils/identicon.py +++ b/frappe/utils/identicon.py @@ -10,7 +10,7 @@ BORDER_SIZE = 20 SQUARE_SIZE = 40 -class Identicon(object): +class Identicon: def __init__(self, str_, background="#fafbfc"): """ `str_` is the string used to generate the identicon. @@ -104,4 +104,4 @@ class Identicon(object): save_handler(self.image, fp, "") finally: fp.seek(0) - return "data:image/png;base64,{0}".format(base64.b64encode(fp.read())) # noqa + return f"data:image/png;base64,{base64.b64encode(fp.read())}" # noqa diff --git a/frappe/utils/image.py b/frappe/utils/image.py index 8823ea3dfe..11d9a86c4f 100644 --- a/frappe/utils/image.py +++ b/frappe/utils/image.py @@ -17,7 +17,7 @@ def resize_images(path, maxdim=700): im.thumbnail(size, Image.Resampling.LANCZOS) im.save(os.path.join(basepath, fname)) - print("resized {0}".format(os.path.join(basepath, fname))) + print(f"resized {os.path.join(basepath, fname)}") def strip_exif_data(content, content_type): diff --git a/frappe/utils/jinja.py b/frappe/utils/jinja.py index c7902e7096..5e3a70554d 100644 --- a/frappe/utils/jinja.py +++ b/frappe/utils/jinja.py @@ -56,7 +56,7 @@ def validate_template(html): try: jenv.from_string(html) except TemplateSyntaxError as e: - frappe.msgprint("Line {}: {}".format(e.lineno, e.message)) + frappe.msgprint(f"Line {e.lineno}: {e.message}") frappe.throw(frappe._("Syntax error in template")) @@ -86,7 +86,7 @@ def render_template(template, context, is_path=None, safe_render=True): except TemplateError: throw( title="Jinja Template Error", - msg="
{template}
{tb}
".format(template=template, tb=get_traceback()), + msg=f"
{template}
{get_traceback()}
", ) @@ -117,7 +117,7 @@ def get_jloader(): frappe.local.jloader = ChoiceLoader( # search for something like app/templates/... - [PrefixLoader(dict((app, PackageLoader(app, ".")) for app in apps))] + [PrefixLoader({app: PackageLoader(app, ".") for app in apps})] # search for something like templates/... + [PackageLoader(app, ".") for app in apps] ) diff --git a/frappe/utils/logger.py b/frappe/utils/logger.py index f2ce8a14c3..461204371e 100755 --- a/frappe/utils/logger.py +++ b/frappe/utils/logger.py @@ -41,7 +41,7 @@ def get_logger( else: site = False - logger_name = "{0}-{1}".format(module, site or "all") + logger_name = "{}-{}".format(module, site or "all") try: return frappe.loggers[logger_name] @@ -59,7 +59,7 @@ def get_logger( logger.setLevel(frappe.log_level or default_log_level) logger.propagate = False - formatter = logging.Formatter("%(asctime)s %(levelname)s {0} %(message)s".format(module)) + formatter = logging.Formatter(f"%(asctime)s %(levelname)s {module} %(message)s") if stream_only: handler = logging.StreamHandler() else: @@ -91,7 +91,7 @@ class SiteContextFilter(logging.Filter): if "Form Dict" not in str(record.msg): site = getattr(frappe.local, "site", None) form_dict = getattr(frappe.local, "form_dict", None) - record.msg = str(record.msg) + "\nSite: {0}\nForm Dict: {1}".format(site, form_dict) + record.msg = str(record.msg) + f"\nSite: {site}\nForm Dict: {form_dict}" return True diff --git a/frappe/utils/make_random.py b/frappe/utils/make_random.py index 41d6f89d72..1915cbb620 100644 --- a/frappe/utils/make_random.py +++ b/frappe/utils/make_random.py @@ -33,7 +33,7 @@ def get_random(doctype, filters=None, doc=False): condition = [] if filters: for key, val in filters.items(): - condition.append("%s='%s'" % (key, str(val).replace("'", "'"))) + condition.append("{}='{}'".format(key, str(val).replace("'", "'"))) if condition: condition = " where " + " and ".join(condition) else: diff --git a/frappe/utils/nestedset.py b/frappe/utils/nestedset.py index 681cd6439d..222f670e0f 100644 --- a/frappe/utils/nestedset.py +++ b/frappe/utils/nestedset.py @@ -10,7 +10,7 @@ # 3. call update_nsm(doc_obj) in the on_upate method # ------------------------------------------ -from typing import Iterator +from collections.abc import Iterator import frappe from frappe import _ diff --git a/frappe/utils/oauth.py b/frappe/utils/oauth.py index 9e7138cbbd..042fa24a8b 100644 --- a/frappe/utils/oauth.py +++ b/frappe/utils/oauth.py @@ -47,7 +47,7 @@ def get_oauth_keys(provider): """get client_id and client_secret from database or conf""" # try conf - keys = frappe.conf.get("{provider}_login".format(provider=provider)) + keys = frappe.conf.get(f"{provider}_login") if not keys: # try database @@ -100,7 +100,7 @@ def get_oauth2_flow(provider): def get_redirect_uri(provider): - keys = frappe.conf.get("{provider}_login".format(provider=provider)) + keys = frappe.conf.get(f"{provider}_login") if keys and keys.get("redirect_uri"): # this should be a fully qualified redirect uri @@ -223,7 +223,7 @@ def login_oauth_user( if frappe.utils.cint(generate_login_token): login_token = frappe.generate_hash(length=32) frappe.cache().set_value( - "login_token:{0}".format(login_token), frappe.local.session.sid, expires_in_sec=120 + f"login_token:{login_token}", frappe.local.session.sid, expires_in_sec=120 ) frappe.response["login_token"] = login_token diff --git a/frappe/utils/password.py b/frappe/utils/password.py index c539891ac7..9a2aa04bf7 100644 --- a/frappe/utils/password.py +++ b/frappe/utils/password.py @@ -29,7 +29,7 @@ class LegacyPassword(pbkdf2_sha256): secret[0] == "*" and len(secret) == 41 and all(c in string.hexdigits for c in secret[1:]) ): secret = mysql41.hash(secret + self.salt.decode("utf-8")) - return super(LegacyPassword, self)._calc_checksum(secret) + return super()._calc_checksum(secret) register_crypt_handler(LegacyPassword, force=True) diff --git a/frappe/utils/pdf.py b/frappe/utils/pdf.py index ddab2f2b18..678671bce2 100644 --- a/frappe/utils/pdf.py +++ b/frappe/utils/pdf.py @@ -5,7 +5,6 @@ import os import re import subprocess from distutils.version import LooseVersion -from typing import Optional import pdfkit from bs4 import BeautifulSoup @@ -24,7 +23,7 @@ PDF_CONTENT_ERRORS = [ ] -def get_pdf(html, options=None, output: Optional[PdfWriter] = None): +def get_pdf(html, options=None, output: PdfWriter | None = None): html = scrub_urls(html) html, options = prepare_options(html, options) @@ -135,13 +134,13 @@ def get_cookie_options(): options = {} if frappe.session and frappe.session.sid and hasattr(frappe.local, "request"): # Use wkhtmltopdf's cookie-jar feature to set cookies and restrict them to host domain - cookiejar = "/tmp/{}.jar".format(frappe.generate_hash()) + cookiejar = f"/tmp/{frappe.generate_hash()}.jar" # Remove port from request.host # https://werkzeug.palletsprojects.com/en/0.16.x/wrappers/#werkzeug.wrappers.BaseRequest.host domain = frappe.utils.get_host_name().split(":", 1)[0] with open(cookiejar, "w") as f: - f.write("sid={}; Domain={};\n".format(frappe.session.sid, domain)) + f.write(f"sid={frappe.session.sid}; Domain={domain};\n") options["cookie-jar"] = cookiejar @@ -211,7 +210,7 @@ def prepare_header_footer(soup): ) # create temp file - fname = os.path.join("/tmp", "frappe-pdf-{0}.html".format(frappe.generate_hash())) + fname = os.path.join("/tmp", f"frappe-pdf-{frappe.generate_hash()}.html") with open(fname, "wb") as f: f.write(html.encode("utf-8")) diff --git a/frappe/utils/print_format.py b/frappe/utils/print_format.py index a48d7ab84f..03d564b16c 100644 --- a/frappe/utils/print_format.py +++ b/frappe/utils/print_format.py @@ -96,11 +96,11 @@ def download_multi_pdf(doctype, name, format=None, no_letterhead=False, options= except Exception: frappe.log_error( title="Error in Multi PDF download", - message="Permission Error on doc {} of doctype {}".format(doc_name, doctype_name), + message=f"Permission Error on doc {doc_name} of doctype {doctype_name}", reference_doctype=doctype_name, reference_name=doc_name, ) - frappe.local.response.filename = "{}.pdf".format(name) + frappe.local.response.filename = f"{name}.pdf" frappe.local.response.filecontent = read_multi_pdf(output) frappe.local.response.type = "download" @@ -108,7 +108,7 @@ def download_multi_pdf(doctype, name, format=None, no_letterhead=False, options= def read_multi_pdf(output): # Get the content of the merged pdf files - fname = os.path.join("/tmp", "frappe-pdf-{0}.pdf".format(frappe.generate_hash())) + fname = os.path.join("/tmp", f"frappe-pdf-{frappe.generate_hash()}.pdf") output.write(open(fname, "wb")) with open(fname, "rb") as fileobj: @@ -157,10 +157,10 @@ def print_by_server( doctype, name, print_format, doc=doc, no_letterhead=no_letterhead, as_pdf=True, output=output ) if not file_path: - file_path = os.path.join("/", "tmp", "frappe-pdf-{0}.pdf".format(frappe.generate_hash())) + file_path = os.path.join("/", "tmp", f"frappe-pdf-{frappe.generate_hash()}.pdf") output.write(open(file_path, "wb")) conn.printFile(print_settings.printer_name, file_path, name, {}) - except IOError as e: + except OSError as e: if ( "ContentNotFoundError" in e.message or "ContentOperationNotPermittedError" in e.message diff --git a/frappe/utils/redis_wrapper.py b/frappe/utils/redis_wrapper.py index c29836af32..a41e47b0c6 100644 --- a/frappe/utils/redis_wrapper.py +++ b/frappe/utils/redis_wrapper.py @@ -26,9 +26,9 @@ class RedisWrapper(redis.Redis): if user is True: user = frappe.session.user - key = "user:{0}:{1}".format(user, key) + key = f"user:{user}:{key}" - return "{0}|{1}".format(frappe.conf.db_name, key).encode("utf-8") + return f"{frappe.conf.db_name}|{key}".encode() def set_value(self, key, val, user=None, expires_in_sec=None, shared=False, cache_locally=True): """Sets cache value. @@ -128,25 +128,25 @@ class RedisWrapper(redis.Redis): pass def lpush(self, key, value): - super(RedisWrapper, self).lpush(self.make_key(key), value) + super().lpush(self.make_key(key), value) def rpush(self, key, value): - super(RedisWrapper, self).rpush(self.make_key(key), value) + super().rpush(self.make_key(key), value) def lpop(self, key): - return super(RedisWrapper, self).lpop(self.make_key(key)) + return super().lpop(self.make_key(key)) def rpop(self, key): - return super(RedisWrapper, self).rpop(self.make_key(key)) + return super().rpop(self.make_key(key)) def llen(self, key): - return super(RedisWrapper, self).llen(self.make_key(key)) + return super().llen(self.make_key(key)) def lrange(self, key, start, stop): - return super(RedisWrapper, self).lrange(self.make_key(key), start, stop) + return super().lrange(self.make_key(key), start, stop) def ltrim(self, key, start, stop): - return super(RedisWrapper, self).ltrim(self.make_key(key), start, stop) + return super().ltrim(self.make_key(key), start, stop) def hset(self, name: str, key: str, value, shared: bool = False, cache_locally: bool = True): if key is None: @@ -160,7 +160,7 @@ class RedisWrapper(redis.Redis): # set in redis try: - super(RedisWrapper, self).hset(_name, key, pickle.dumps(value)) + super().hset(_name, key, pickle.dumps(value)) except redis.exceptions.ConnectionError: pass @@ -169,12 +169,12 @@ class RedisWrapper(redis.Redis): return False _name = self.make_key(name, shared=shared) try: - return super(RedisWrapper, self).hexists(_name, key) + return super().hexists(_name, key) except redis.exceptions.ConnectionError: return False def hgetall(self, name): - value = super(RedisWrapper, self).hgetall(self.make_key(name)) + value = super().hgetall(self.make_key(name)) return {key: pickle.loads(value) for key, value in value.items()} def hget(self, name, key, generator=None, shared=False): @@ -190,7 +190,7 @@ class RedisWrapper(redis.Redis): value = None try: - value = super(RedisWrapper, self).hget(_name, key) + value = super().hget(_name, key) except redis.exceptions.ConnectionError: pass @@ -209,7 +209,7 @@ class RedisWrapper(redis.Redis): if key in frappe.local.cache[_name]: del frappe.local.cache[_name][key] try: - super(RedisWrapper, self).hdel(_name, key) + super().hdel(_name, key) except redis.exceptions.ConnectionError: pass @@ -221,30 +221,30 @@ class RedisWrapper(redis.Redis): def hkeys(self, name): try: - return super(RedisWrapper, self).hkeys(self.make_key(name)) + return super().hkeys(self.make_key(name)) except redis.exceptions.ConnectionError: return [] def sadd(self, name, *values): """Add a member/members to a given set""" - super(RedisWrapper, self).sadd(self.make_key(name), *values) + super().sadd(self.make_key(name), *values) def srem(self, name, *values): """Remove a specific member/list of members from the set""" - super(RedisWrapper, self).srem(self.make_key(name), *values) + super().srem(self.make_key(name), *values) def sismember(self, name, value): """Returns True or False based on if a given value is present in the set""" - return super(RedisWrapper, self).sismember(self.make_key(name), value) + return super().sismember(self.make_key(name), value) def spop(self, name): """Removes and returns a random member from the set""" - return super(RedisWrapper, self).spop(self.make_key(name)) + return super().spop(self.make_key(name)) def srandmember(self, name, count=None): """Returns a random member from the set""" - return super(RedisWrapper, self).srandmember(self.make_key(name)) + return super().srandmember(self.make_key(name)) def smembers(self, name): """Return all members of the set""" - return super(RedisWrapper, self).smembers(self.make_key(name)) + return super().smembers(self.make_key(name)) diff --git a/frappe/utils/response.py b/frappe/utils/response.py index 80aeaa2ad0..ed2cee6208 100644 --- a/frappe/utils/response.py +++ b/frappe/utils/response.py @@ -96,7 +96,7 @@ def as_raw(): ) response.headers["Content-Disposition"] = ( f'{frappe.response.get("display_content_as","attachment")}; filename="{frappe.response["filename"].replace(" ", "_")}"' - ).encode("utf-8") + ).encode() response.data = frappe.response["filecontent"] return response @@ -184,7 +184,7 @@ def json_handler(obj): else: raise TypeError( - """Object of type %s with value of %s is not JSON serializable""" % (type(obj), repr(obj)) + f"""Object of type {type(obj)} with value of {repr(obj)} is not JSON serializable""" ) @@ -246,7 +246,7 @@ def send_private_file(path: str) -> Response: filepath = frappe.utils.get_site_path(path) try: f = open(filepath, "rb") - except IOError: + except OSError: raise NotFound response = Response(wrap_file(frappe.local.request.environ, f), direct_passthrough=True) diff --git a/frappe/utils/safe_exec.py b/frappe/utils/safe_exec.py index b29ae848aa..9136df1062 100644 --- a/frappe/utils/safe_exec.py +++ b/frappe/utils/safe_exec.py @@ -347,7 +347,7 @@ def _getattr(object, name, default=None): } if isinstance(name, str) and (name in UNSAFE_ATTRIBUTES): - raise SyntaxError("{name} is an unsafe attribute".format(name=name)) + raise SyntaxError(f"{name} is an unsafe attribute") return RestrictedPython.Guards.safer_getattr(object, name, default=default) diff --git a/frappe/utils/scheduler.py b/frappe/utils/scheduler.py index 48826b13c6..23b4949c38 100755 --- a/frappe/utils/scheduler.py +++ b/frappe/utils/scheduler.py @@ -60,12 +60,12 @@ def enqueue_events_for_all_sites(): try: enqueue_events_for_site(site=site) except Exception as e: - print(e.__class__, "Failed to enqueue events for site: {}".format(site)) + print(e.__class__, f"Failed to enqueue events for site: {site}") def enqueue_events_for_site(site): def log_and_raise(): - error_message = "Exception in Enqueue Events for Site {0}\n{1}".format( + error_message = "Exception in Enqueue Events for Site {}\n{}".format( site, frappe.get_traceback() ) frappe.logger("scheduler").error(error_message) @@ -78,10 +78,10 @@ def enqueue_events_for_site(site): enqueue_events(site=site) - frappe.logger("scheduler").debug("Queued events for site {0}".format(site)) + frappe.logger("scheduler").debug(f"Queued events for site {site}") except frappe.db.OperationalError as e: if frappe.db.is_access_denied(e): - frappe.logger("scheduler").debug("Access denied for site {0}".format(site)) + frappe.logger("scheduler").debug(f"Access denied for site {site}") else: log_and_raise() except Exception: diff --git a/frappe/utils/user.py b/frappe/utils/user.py index 308ab85f05..a9bec0affa 100644 --- a/frappe/utils/user.py +++ b/frappe/utils/user.py @@ -2,7 +2,7 @@ # License: MIT. See LICENSE from email.utils import formataddr -from typing import TYPE_CHECKING, Dict, List, Optional +from typing import TYPE_CHECKING import frappe import frappe.share @@ -284,7 +284,7 @@ def get_fullname_and_avatar(user: str) -> _dict: ) -def get_system_managers(only_name: bool = False) -> List[str]: +def get_system_managers(only_name: bool = False) -> list[str]: """returns all system manager's user details""" HasRole = DocType("Has Role") User = DocType("User") @@ -297,7 +297,7 @@ def get_system_managers(only_name: bool = False) -> List[str]: system_managers = ( frappe.qb.from_(User) .join(HasRole) - .on((HasRole.parent == User.name)) + .on(HasRole.parent == User.name) .where( (HasRole.parenttype == "User") & (User.enabled == 1) @@ -322,8 +322,8 @@ def add_role(user: str, role: str) -> None: def add_system_manager( email: str, - first_name: Optional[str] = None, - last_name: Optional[str] = None, + first_name: str | None = None, + last_name: str | None = None, send_welcome_email: bool = False, password: str = None, ) -> "User": @@ -359,7 +359,7 @@ def add_system_manager( return user -def get_enabled_system_users() -> List[Dict]: +def get_enabled_system_users() -> list[dict]: return frappe.get_all( "User", fields=["email", "language", "name"], @@ -371,11 +371,11 @@ def get_enabled_system_users() -> List[Dict]: ) -def is_website_user(username: Optional[str] = None) -> Optional[str]: +def is_website_user(username: str | None = None) -> str | None: return frappe.db.get_value("User", username or frappe.session.user, "user_type") == "Website User" -def is_system_user(username: Optional[str] = None) -> Optional[str]: +def is_system_user(username: str | None = None) -> str | None: return frappe.db.get_value( "User", { @@ -386,7 +386,7 @@ def is_system_user(username: Optional[str] = None) -> Optional[str]: ) -def get_users() -> List[Dict]: +def get_users() -> list[dict]: from frappe.core.doctype.user.user import get_system_users users = [] @@ -404,7 +404,7 @@ def get_users() -> List[Dict]: return users -def get_users_with_role(role: str) -> List[str]: +def get_users_with_role(role: str) -> list[str]: User = DocType("User") HasRole = DocType("Has Role") diff --git a/frappe/utils/verified_command.py b/frappe/utils/verified_command.py index e342ef1810..f46c8a8e73 100644 --- a/frappe/utils/verified_command.py +++ b/frappe/utils/verified_command.py @@ -62,7 +62,7 @@ def get_url(cmd, params, nonce=None, secret=None): def get_signature(params, nonce, secret=None): - params = "".join((frappe.utils.cstr(p) for p in params.values())) + params = "".join(frappe.utils.cstr(p) for p in params.values()) if not secret: secret = frappe.local.conf.get("secret") or "secret" diff --git a/frappe/website/doctype/__init__.py b/frappe/website/doctype/__init__.py index 8b13789179..e69de29bb2 100644 --- a/frappe/website/doctype/__init__.py +++ b/frappe/website/doctype/__init__.py @@ -1 +0,0 @@ - diff --git a/frappe/website/doctype/about_us_settings/test_about_us_settings.py b/frappe/website/doctype/about_us_settings/test_about_us_settings.py index a4b2da7718..6477d7fcf7 100644 --- a/frappe/website/doctype/about_us_settings/test_about_us_settings.py +++ b/frappe/website/doctype/about_us_settings/test_about_us_settings.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2020, Frappe Technologies and Contributors # License: MIT. See LICENSE # import frappe diff --git a/frappe/website/doctype/blog_post/blog_post.py b/frappe/website/doctype/blog_post/blog_post.py index 2f5d8e4ace..e411931694 100644 --- a/frappe/website/doctype/blog_post/blog_post.py +++ b/frappe/website/doctype/blog_post/blog_post.py @@ -37,7 +37,7 @@ class BlogPost(WebsiteGenerator): return self.title def validate(self): - super(BlogPost, self).validate() + super().validate() if not self.blog_intro: content = get_html_content_based_on_type(self, "content", self.content_type) @@ -73,11 +73,11 @@ class BlogPost(WebsiteGenerator): frappe.db.set_value("Blog Post", post.name, "featured", 0) def on_update(self): - super(BlogPost, self).on_update() + super().on_update() clear_cache("writers") def on_trash(self): - super(BlogPost, self).on_trash() + super().on_trash() def get_context(self, context): # this is for double precaution. usually it wont reach this code if not published @@ -317,13 +317,13 @@ def get_blog_list( from `tabBlog Post` t1, `tabBlogger` t2 where ifnull(t1.published,0)=1 and t1.blogger = t2.name - %(condition)s + {condition} order by featured desc, published_on desc, name asc - limit %(page_len)s OFFSET %(start)s""" % { - "start": limit_start, - "page_len": limit_page_length, - "condition": (" and " + " and ".join(conditions)) if conditions else "", - } + limit {page_len} OFFSET {start}""".format( + start=limit_start, + page_len=limit_page_length, + condition=(" and " + " and ".join(conditions)) if conditions else "", + ) posts = frappe.db.sql(query, as_dict=1) diff --git a/frappe/website/doctype/blog_settings/test_blog_settings.py b/frappe/website/doctype/blog_settings/test_blog_settings.py index 23607812fb..c4be6e270e 100644 --- a/frappe/website/doctype/blog_settings/test_blog_settings.py +++ b/frappe/website/doctype/blog_settings/test_blog_settings.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2020, Frappe Technologies and Contributors # License: MIT. See LICENSE # import frappe diff --git a/frappe/website/doctype/color/color.py b/frappe/website/doctype/color/color.py index 4d822d6b69..f720e86314 100644 --- a/frappe/website/doctype/color/color.py +++ b/frappe/website/doctype/color/color.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2020, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/website/doctype/color/test_color.py b/frappe/website/doctype/color/test_color.py index 2fd1cf1ba8..1b1e8c0774 100644 --- a/frappe/website/doctype/color/test_color.py +++ b/frappe/website/doctype/color/test_color.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2020, Frappe Technologies and Contributors # License: MIT. See LICENSE # import frappe diff --git a/frappe/website/doctype/help_article/test_help_article.py b/frappe/website/doctype/help_article/test_help_article.py index e7dec4080c..3cbd5ceb22 100644 --- a/frappe/website/doctype/help_article/test_help_article.py +++ b/frappe/website/doctype/help_article/test_help_article.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies and Contributors # License: MIT. See LICENSE import unittest diff --git a/frappe/website/doctype/help_category/test_help_category.py b/frappe/website/doctype/help_category/test_help_category.py index de7d288555..443cacfd3b 100644 --- a/frappe/website/doctype/help_category/test_help_category.py +++ b/frappe/website/doctype/help_category/test_help_category.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies and Contributors # License: MIT. See LICENSE import unittest diff --git a/frappe/website/doctype/personal_data_deletion_request/personal_data_deletion_request.py b/frappe/website/doctype/personal_data_deletion_request/personal_data_deletion_request.py index 45c1a5ad38..edeb44f015 100644 --- a/frappe/website/doctype/personal_data_deletion_request/personal_data_deletion_request.py +++ b/frappe/website/doctype/personal_data_deletion_request/personal_data_deletion_request.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and contributors # License: MIT. See LICENSE @@ -392,4 +391,4 @@ def confirm_deletion(email, name, host_name): def get_pattern(full_match): - return re.compile(r"(?
" - + "
".join("{0} ({1})".format(d.label, d.fieldtype) for d in missing) + + "
".join(f"{d.label} ({d.fieldtype})" for d in missing) ) def allow_website_search_indexing(self): @@ -671,4 +671,4 @@ def get_link_options(web_form_name, doctype, allow_read_on_all_link_options=Fals return "\n".join([doc.value for doc in link_options]) else: - raise frappe.PermissionError("Not Allowed, {0}".format(doctype)) + raise frappe.PermissionError(f"Not Allowed, {doctype}") diff --git a/frappe/website/doctype/web_page/__init__.py b/frappe/website/doctype/web_page/__init__.py index 8b13789179..e69de29bb2 100644 --- a/frappe/website/doctype/web_page/__init__.py +++ b/frappe/website/doctype/web_page/__init__.py @@ -1 +0,0 @@ - diff --git a/frappe/website/doctype/web_page/web_page.py b/frappe/website/doctype/web_page/web_page.py index fb94dc9165..a94838baed 100644 --- a/frappe/website/doctype/web_page/web_page.py +++ b/frappe/website/doctype/web_page/web_page.py @@ -33,10 +33,10 @@ class WebPage(WebsiteGenerator): return self.title def on_update(self): - super(WebPage, self).on_update() + super().on_update() def on_trash(self): - super(WebPage, self).on_trash() + super().on_trash() def get_context(self, context): context.main_section = get_html_content_based_on_type(self, "main_section", self.content_type) diff --git a/frappe/website/doctype/web_page_block/web_page_block.py b/frappe/website/doctype/web_page_block/web_page_block.py index 790ab98b6a..e700986739 100644 --- a/frappe/website/doctype/web_page_block/web_page_block.py +++ b/frappe/website/doctype/web_page_block/web_page_block.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2020, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/website/doctype/web_page_view/test_web_page_view.py b/frappe/website/doctype/web_page_view/test_web_page_view.py index 3f1d86ada4..d573402a08 100644 --- a/frappe/website/doctype/web_page_view/test_web_page_view.py +++ b/frappe/website/doctype/web_page_view/test_web_page_view.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2020, Frappe Technologies and Contributors # License: MIT. See LICENSE # import frappe diff --git a/frappe/website/doctype/web_page_view/web_page_view.py b/frappe/website/doctype/web_page_view/web_page_view.py index b1e64980d9..7417f2d290 100644 --- a/frappe/website/doctype/web_page_view/web_page_view.py +++ b/frappe/website/doctype/web_page_view/web_page_view.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2020, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/website/doctype/web_template/test_web_template.py b/frappe/website/doctype/web_template/test_web_template.py index 2d2d7faf36..b31d11e01f 100644 --- a/frappe/website/doctype/web_template/test_web_template.py +++ b/frappe/website/doctype/web_template/test_web_template.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2020, Frappe Technologies and Contributors # License: MIT. See LICENSE import unittest diff --git a/frappe/website/doctype/web_template/web_template.py b/frappe/website/doctype/web_template/web_template.py index 93b469fe96..a21affafc9 100644 --- a/frappe/website/doctype/web_template/web_template.py +++ b/frappe/website/doctype/web_template/web_template.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2020, Frappe Technologies and contributors # License: MIT. See LICENSE @@ -97,7 +96,7 @@ class WebTemplate(Document): """ if standard: template = self.get_template_path() - with open(template, "r") as template_file: + with open(template) as template_file: template = template_file.read() else: template = self.template diff --git a/frappe/website/doctype/web_template_field/test_web_template_field.py b/frappe/website/doctype/web_template_field/test_web_template_field.py index 3f9160edb9..0a5b74c1ad 100644 --- a/frappe/website/doctype/web_template_field/test_web_template_field.py +++ b/frappe/website/doctype/web_template_field/test_web_template_field.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2020, Frappe Technologies and Contributors # License: MIT. See LICENSE # import frappe diff --git a/frappe/website/doctype/web_template_field/web_template_field.py b/frappe/website/doctype/web_template_field/web_template_field.py index 082bde41f3..e86e630e81 100644 --- a/frappe/website/doctype/web_template_field/web_template_field.py +++ b/frappe/website/doctype/web_template_field/web_template_field.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2020, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/website/doctype/website_meta_tag/website_meta_tag.py b/frappe/website/doctype/website_meta_tag/website_meta_tag.py index 0ac84a632e..56b5f4f37b 100644 --- a/frappe/website/doctype/website_meta_tag/website_meta_tag.py +++ b/frappe/website/doctype/website_meta_tag/website_meta_tag.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/website/doctype/website_route_meta/test_website_route_meta.py b/frappe/website/doctype/website_route_meta/test_website_route_meta.py index 0a04207cea..55c95cdb9f 100644 --- a/frappe/website/doctype/website_route_meta/test_website_route_meta.py +++ b/frappe/website/doctype/website_route_meta/test_website_route_meta.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and Contributors # License: MIT. See LICENSE import unittest diff --git a/frappe/website/doctype/website_route_meta/website_route_meta.py b/frappe/website/doctype/website_route_meta/website_route_meta.py index 0c12b10583..12ae682a48 100644 --- a/frappe/website/doctype/website_route_meta/website_route_meta.py +++ b/frappe/website/doctype/website_route_meta/website_route_meta.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/website/doctype/website_route_redirect/website_route_redirect.py b/frappe/website/doctype/website_route_redirect/website_route_redirect.py index 29bcd82094..f84e68d2b2 100644 --- a/frappe/website/doctype/website_route_redirect/website_route_redirect.py +++ b/frappe/website/doctype/website_route_redirect/website_route_redirect.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2019, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/website/doctype/website_settings/__init__.py b/frappe/website/doctype/website_settings/__init__.py index 8b13789179..e69de29bb2 100644 --- a/frappe/website/doctype/website_settings/__init__.py +++ b/frappe/website/doctype/website_settings/__init__.py @@ -1 +0,0 @@ - diff --git a/frappe/website/doctype/website_settings/google_indexing.py b/frappe/website/doctype/website_settings/google_indexing.py index 6585642fe7..d0657a1928 100644 --- a/frappe/website/doctype/website_settings/google_indexing.py +++ b/frappe/website/doctype/website_settings/google_indexing.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2020, Frappe Technologies and contributors # License: MIT. See LICENSE @@ -52,7 +51,7 @@ def authorize_access(reauthorize=None): frappe.db.commit() frappe.local.response["type"] = "redirect" - frappe.local.response["location"] = "/app/Form/{0}".format(quote("Website Settings")) + frappe.local.response["location"] = "/app/Form/{}".format(quote("Website Settings")) frappe.msgprint(_("Google Indexing has been configured.")) except Exception as e: diff --git a/frappe/website/doctype/website_settings/test_website_settings.py b/frappe/website/doctype/website_settings/test_website_settings.py index c204bd7aea..40ca87efc9 100644 --- a/frappe/website/doctype/website_settings/test_website_settings.py +++ b/frappe/website/doctype/website_settings/test_website_settings.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2020, Frappe Technologies and Contributors # License: MIT. See LICENSE # import frappe diff --git a/frappe/website/doctype/website_settings/website_settings.py b/frappe/website/doctype/website_settings/website_settings.py index f249778c58..4088be88c2 100644 --- a/frappe/website/doctype/website_settings/website_settings.py +++ b/frappe/website/doctype/website_settings/website_settings.py @@ -1,6 +1,5 @@ # Copyright (c) 2022, Frappe Technologies Pvt. Ltd. and Contributors # License: MIT. See LICENSE -from typing import Dict, List from urllib.parse import quote import frappe @@ -180,7 +179,7 @@ def get_website_settings(context=None): if frappe.request: context.url = quote(str(get_request_site_address(full_address=True)), safe="/:") - context.encoded_title = quote(encode(context.title or ""), str("")) + context.encoded_title = quote(encode(context.title or ""), "") context.web_include_js = hooks.web_include_js or [] @@ -216,7 +215,7 @@ def get_website_settings(context=None): return context -def get_items(parentfield: str) -> List[Dict]: +def get_items(parentfield: str) -> list[dict]: _items = frappe.get_all( "Top Bar Item", filters={"parent": "Website Settings", "parentfield": parentfield}, diff --git a/frappe/website/doctype/website_sidebar/test_website_sidebar.py b/frappe/website/doctype/website_sidebar/test_website_sidebar.py index 5e92de0f6d..78c51546b7 100644 --- a/frappe/website/doctype/website_sidebar/test_website_sidebar.py +++ b/frappe/website/doctype/website_sidebar/test_website_sidebar.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies and Contributors # License: MIT. See LICENSE import unittest diff --git a/frappe/website/doctype/website_sidebar/website_sidebar.py b/frappe/website/doctype/website_sidebar/website_sidebar.py index 151446bac3..f120db1e87 100644 --- a/frappe/website/doctype/website_sidebar/website_sidebar.py +++ b/frappe/website/doctype/website_sidebar/website_sidebar.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/website/doctype/website_sidebar_item/website_sidebar_item.py b/frappe/website/doctype/website_sidebar_item/website_sidebar_item.py index e839de6d2b..febbafcaf7 100644 --- a/frappe/website/doctype/website_sidebar_item/website_sidebar_item.py +++ b/frappe/website/doctype/website_sidebar_item/website_sidebar_item.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/website/doctype/website_slideshow/test_website_slideshow.py b/frappe/website/doctype/website_slideshow/test_website_slideshow.py index c18835bdc1..45fe200949 100644 --- a/frappe/website/doctype/website_slideshow/test_website_slideshow.py +++ b/frappe/website/doctype/website_slideshow/test_website_slideshow.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors # License: MIT. See LICENSE import unittest diff --git a/frappe/website/doctype/website_theme/website_theme.py b/frappe/website/doctype/website_theme/website_theme.py index 9cb7095f40..442ebe284b 100644 --- a/frappe/website/doctype/website_theme/website_theme.py +++ b/frappe/website/doctype/website_theme/website_theme.py @@ -90,7 +90,7 @@ class WebsiteTheme(Document): if stderr: stderr = frappe.safe_decode(stderr) stderr = stderr.replace("\n", "
") - frappe.throw('
{stderr}
'.format(stderr=stderr)) + frappe.throw(f'
{stderr}
') else: self.theme_url = "/files/website_theme/" + file_name diff --git a/frappe/website/doctype/website_theme_ignore_app/website_theme_ignore_app.py b/frappe/website/doctype/website_theme_ignore_app/website_theme_ignore_app.py index 72652805ec..8c3f962b91 100644 --- a/frappe/website/doctype/website_theme_ignore_app/website_theme_ignore_app.py +++ b/frappe/website/doctype/website_theme_ignore_app/website_theme_ignore_app.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2020, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/website/page_renderers/base_renderer.py b/frappe/website/page_renderers/base_renderer.py index c8b4ac7344..e8421d17ab 100644 --- a/frappe/website/page_renderers/base_renderer.py +++ b/frappe/website/page_renderers/base_renderer.py @@ -2,7 +2,7 @@ import frappe from frappe.website.utils import build_response -class BaseRenderer(object): +class BaseRenderer: def __init__(self, path=None, http_status_code=None): self.headers = None self.http_status_code = http_status_code or 200 diff --git a/frappe/website/page_renderers/base_template_page.py b/frappe/website/page_renderers/base_template_page.py index f35a7e64f7..8163f113fa 100644 --- a/frappe/website/page_renderers/base_template_page.py +++ b/frappe/website/page_renderers/base_template_page.py @@ -46,7 +46,7 @@ class BaseTemplatePage(BaseRenderer): and self.context.title and not self.context.title.startswith(self.context.title_prefix) ): - self.context.title = "{0} - {1}".format(self.context.title_prefix, self.context.title) + self.context.title = f"{self.context.title_prefix} - {self.context.title}" def set_missing_values(self): # set using frappe.respond_as_web_page diff --git a/frappe/website/page_renderers/redirect_page.py b/frappe/website/page_renderers/redirect_page.py index b673fce3bb..be4a7bdf45 100644 --- a/frappe/website/page_renderers/redirect_page.py +++ b/frappe/website/page_renderers/redirect_page.py @@ -2,7 +2,7 @@ import frappe from frappe.website.utils import build_response -class RedirectPage(object): +class RedirectPage: def __init__(self, path, http_status_code=301): self.path = path self.http_status_code = http_status_code diff --git a/frappe/website/page_renderers/template_page.py b/frappe/website/page_renderers/template_page.py index 83f68d3716..daa4d54cc5 100644 --- a/frappe/website/page_renderers/template_page.py +++ b/frappe/website/page_renderers/template_page.py @@ -100,7 +100,7 @@ class TemplatePage(BaseTemplatePage): def post_process_context(self): self.set_user_info() self.add_sidebar_and_breadcrumbs() - super(TemplatePage, self).post_process_context() + super().post_process_context() def add_sidebar_and_breadcrumbs(self): if self.basepath: @@ -252,7 +252,7 @@ class TemplatePage(BaseTemplatePage): self.context.colocated_css = self.get_colocated_file(css_path) def get_colocated_file(self, path): - with io.open(path, "r", encoding="utf-8") as f: + with open(path, encoding="utf-8") as f: return f.read() def extract_frontmatter(self): @@ -289,7 +289,7 @@ class TemplatePage(BaseTemplatePage): self.app = "frappe" self.app_path = frappe.get_app_path("frappe") self.path = path - self.template_path = "www/{path}.html".format(path=path) + self.template_path = f"www/{path}.html" def set_missing_values(self): super().set_missing_values() diff --git a/frappe/website/report/website_analytics/website_analytics.py b/frappe/website/report/website_analytics/website_analytics.py index fd9bcc01ba..7e2e891081 100644 --- a/frappe/website/report/website_analytics/website_analytics.py +++ b/frappe/website/report/website_analytics/website_analytics.py @@ -13,7 +13,7 @@ def execute(filters=None): return WebsiteAnalytics(filters).run() -class WebsiteAnalytics(object): +class WebsiteAnalytics: def __init__(self, filters=None): self.filters = frappe._dict(filters or {}) diff --git a/frappe/website/router.py b/frappe/website/router.py index 8c21501a4e..24a085224b 100644 --- a/frappe/website/router.py +++ b/frappe/website/router.py @@ -204,13 +204,13 @@ def setup_source(page_info): # load css/js files js_path = os.path.join(page_info.basepath, (page_info.basename or "index") + ".js") if os.path.exists(js_path) and "{% block script %}" not in html: - with io.open(js_path, "r", encoding="utf-8") as f: + with open(js_path, encoding="utf-8") as f: js = f.read() page_info.colocated_js = js css_path = os.path.join(page_info.basepath, (page_info.basename or "index") + ".css") if os.path.exists(css_path) and "{% block style %}" not in html: - with io.open(css_path, "r", encoding="utf-8") as f: + with open(css_path, encoding="utf-8") as f: css = f.read() page_info.colocated_css = css @@ -249,7 +249,7 @@ def setup_index(page_info): # load index.txt if loading all pages index_txt_path = os.path.join(page_info.basepath, "index.txt") if os.path.exists(index_txt_path): - with open(index_txt_path, "r") as f: + with open(index_txt_path) as f: page_info.index = f.read().splitlines() diff --git a/frappe/website/utils.py b/frappe/website/utils.py index 6e34c05d40..cc39f11893 100644 --- a/frappe/website/utils.py +++ b/frappe/website/utils.py @@ -5,7 +5,6 @@ import mimetypes import os import re from functools import lru_cache, wraps -from typing import Dict, Optional import yaml from werkzeug.wrappers import Response @@ -81,9 +80,9 @@ def get_comment_list(doctype, name): reference_name=name, ), or_filters=[ - ["recipients", "like", "%{0}%".format(frappe.session.user)], - ["cc", "like", "%{0}%".format(frappe.session.user)], - ["bcc", "like", "%{0}%".format(frappe.session.user)], + ["recipients", "like", f"%{frappe.session.user}%"], + ["cc", "like", f"%{frappe.session.user}%"], + ["bcc", "like", f"%{frappe.session.user}%"], ], ) @@ -454,7 +453,7 @@ def get_sidebar_items_from_sidebar_file(basepath, look_for_sidebar_json): if not sidebar_json_path: return sidebar_items - with open(sidebar_json_path, "r") as sidebarfile: + with open(sidebar_json_path) as sidebarfile: try: sidebar_json = sidebarfile.read() sidebar_items = json.loads(sidebar_json) @@ -506,7 +505,7 @@ def cache_html(func): return cache_html_decorator -def build_response(path, data, http_status_code, headers: Optional[Dict] = None): +def build_response(path, data, http_status_code, headers: dict | None = None): # build response response = Response() response.data = set_content_type(response, data, path) @@ -559,7 +558,7 @@ def add_preload_headers(response): links = [] for _type, link in preload: - links.append("<{}>; rel=preload; as={}".format(link, _type)) + links.append(f"<{link}>; rel=preload; as={_type}") if links: response.headers["Link"] = ",".join(links) @@ -569,7 +568,7 @@ def add_preload_headers(response): traceback.print_exc() -@lru_cache() +@lru_cache def is_binary_file(path): # ref: https://stackoverflow.com/a/7392391/10309266 textchars = bytearray({7, 8, 9, 10, 12, 13, 27} | set(range(0x20, 0x100)) - {0x7F}) diff --git a/frappe/website/website_generator.py b/frappe/website/website_generator.py index 9d9fbd30e5..759b83d2e8 100644 --- a/frappe/website/website_generator.py +++ b/frappe/website/website_generator.py @@ -13,7 +13,7 @@ class WebsiteGenerator(Document): def __init__(self, *args, **kwargs): self.route = None - super(WebsiteGenerator, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) def get_website_properties(self, key=None, default=None): out = getattr(self, "_website", None) or getattr(self, "website", None) or {} @@ -70,7 +70,7 @@ class WebsiteGenerator(Document): return title_field def clear_cache(self): - super(WebsiteGenerator, self).clear_cache() + super().clear_cache() clear_cache(self.route) def scrub(self, text): diff --git a/frappe/workflow/doctype/workflow/test_workflow.py b/frappe/workflow/doctype/workflow/test_workflow.py index 0fb4eca232..be4708ee12 100644 --- a/frappe/workflow/doctype/workflow/test_workflow.py +++ b/frappe/workflow/doctype/workflow/test_workflow.py @@ -96,7 +96,7 @@ class TestWorkflow(unittest.TestCase): todo4 = create_new_todo() actions = get_common_transition_actions([todo1, todo2, todo3, todo4], "ToDo") - self.assertSetEqual(set(actions), set(["Approve", "Reject"])) + self.assertSetEqual(set(actions), {"Approve", "Reject"}) apply_workflow(todo1, "Reject") apply_workflow(todo2, "Reject") diff --git a/frappe/workflow/doctype/workflow_action_master/workflow_action_master.py b/frappe/workflow/doctype/workflow_action_master/workflow_action_master.py index eb227b6125..95c7aa7cee 100644 --- a/frappe/workflow/doctype/workflow_action_master/workflow_action_master.py +++ b/frappe/workflow/doctype/workflow_action_master/workflow_action_master.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2018, Frappe Technologies and contributors # License: MIT. See LICENSE diff --git a/frappe/www/__init__.py b/frappe/www/__init__.py index 8b13789179..e69de29bb2 100644 --- a/frappe/www/__init__.py +++ b/frappe/www/__init__.py @@ -1 +0,0 @@ - diff --git a/frappe/www/_test/_test_metatags.py b/frappe/www/_test/_test_metatags.py index b5b504a246..717b89e985 100644 --- a/frappe/www/_test/_test_metatags.py +++ b/frappe/www/_test/_test_metatags.py @@ -1,8 +1,6 @@ # Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors # MIT License. See license.txt -from __future__ import unicode_literals - def get_context(): return {"title": "Test Title Metatag", "description": "Test Description for Metatag"} diff --git a/frappe/www/app.py b/frappe/www/app.py index 0447d00f89..f75fe05c03 100644 --- a/frappe/www/app.py +++ b/frappe/www/app.py @@ -77,18 +77,18 @@ def get_desk_assets(build_version): if path.startswith("/assets/"): path = path.replace("/assets/", "assets/") try: - with open(os.path.join(frappe.local.sites_path, path), "r") as f: + with open(os.path.join(frappe.local.sites_path, path)) as f: assets[0]["data"] = assets[0]["data"] + "\n" + frappe.safe_decode(f.read(), "utf-8") - except IOError: + except OSError: pass for path in data["include_css"]: if path.startswith("/assets/"): path = path.replace("/assets/", "assets/") try: - with open(os.path.join(frappe.local.sites_path, path), "r") as f: + with open(os.path.join(frappe.local.sites_path, path)) as f: assets[1]["data"] = assets[1]["data"] + "\n" + frappe.safe_decode(f.read(), "utf-8") - except IOError: + except OSError: pass return {"build_version": data["build_version"], "boot": data["boot"], "assets": assets} diff --git a/frappe/www/list.py b/frappe/www/list.py index 2048f1223e..06a2ea48aa 100644 --- a/frappe/www/list.py +++ b/frappe/www/list.py @@ -125,11 +125,11 @@ def get_list_data( def set_route(context): """Set link for the list item""" if context.web_form_name: - context.route = "{0}?name={1}".format(context.pathname, quoted(context.doc.name)) + context.route = f"{context.pathname}?name={quoted(context.doc.name)}" elif context.doc and getattr(context.doc, "route", None): context.route = context.doc.route else: - context.route = "{0}/{1}".format( + context.route = "{}/{}".format( context.pathname or quoted(context.doc.doctype), quoted(context.doc.name) ) diff --git a/frappe/www/login.py b/frappe/www/login.py index 119dfefcd7..c29fdce9ce 100644 --- a/frappe/www/login.py +++ b/frappe/www/login.py @@ -129,7 +129,7 @@ def login_via_office365(code, state): @frappe.whitelist(allow_guest=True) def login_via_token(login_token): - sid = frappe.cache().get_value("login_token:{0}".format(login_token), expires=True) + sid = frappe.cache().get_value(f"login_token:{login_token}", expires=True) if not sid: frappe.respond_as_web_page(_("Invalid Request"), _("Invalid Login Token"), http_status_code=417) return diff --git a/frappe/www/message.py b/frappe/www/message.py index fa13f3ab75..b5035de20f 100644 --- a/frappe/www/message.py +++ b/frappe/www/message.py @@ -18,7 +18,7 @@ def get_context(context): elif frappe.local.form_dict.id: message_id = frappe.local.form_dict.id - key = "message_id:{0}".format(message_id) + key = f"message_id:{message_id}" message = frappe.cache().get_value(key, expires=True) if message: message_context.update(message.get("context", {})) diff --git a/frappe/www/printview.py b/frappe/www/printview.py index c8595a6f2c..3ba73fe348 100644 --- a/frappe/www/printview.py +++ b/frappe/www/printview.py @@ -242,9 +242,9 @@ def set_title_values_for_link_and_dynamic_link_fields(meta, doc, parent_doc=None link_title = frappe.get_cached_value(doctype, doc.get(field.fieldname), meta.title_field) if parent_doc: - parent_doc.__link_titles["{0}::{1}".format(doctype, doc.get(field.fieldname))] = link_title + parent_doc.__link_titles[f"{doctype}::{doc.get(field.fieldname)}"] = link_title elif doc: - doc.__link_titles["{0}::{1}".format(doctype, doc.get(field.fieldname))] = link_title + doc.__link_titles[f"{doctype}::{doc.get(field.fieldname)}"] = link_title def set_title_values_for_table_and_multiselect_fields(meta, doc): @@ -388,7 +388,7 @@ def get_print_format(doctype, print_format): ) if os.path.exists(path): - with open(path, "r") as pffile: + with open(path) as pffile: return pffile.read() else: if print_format.raw_printing: @@ -557,11 +557,11 @@ def get_font(print_settings, print_format=None, for_legacy=False): font = None if print_format: if print_format.font and print_format.font != "Default": - font = "{0}, sans-serif".format(print_format.font) + font = f"{print_format.font}, sans-serif" if not font: if print_settings.font and print_settings.font != "Default": - font = "{0}, sans-serif".format(print_settings.font) + font = f"{print_settings.font}, sans-serif" else: font = default diff --git a/frappe/www/qrcode.py b/frappe/www/qrcode.py index 7adde40fde..e76dc65540 100644 --- a/frappe/www/qrcode.py +++ b/frappe/www/qrcode.py @@ -29,8 +29,8 @@ def get_query_key(): def get_user_svg_from_cache(): """Get User and SVG code from cache.""" key = get_query_key() - totp_uri = frappe.cache().get_value("{}_uri".format(key)) - user = frappe.cache().get_value("{}_user".format(key)) + totp_uri = frappe.cache().get_value(f"{key}_uri") + user = frappe.cache().get_value(f"{key}_user") if not totp_uri or not user: frappe.throw(_("Page has expired!"), frappe.PermissionError) if not frappe.db.exists("User", user): diff --git a/frappe/www/rss.py b/frappe/www/rss.py index 1ebfb61482..dbd2aac9e9 100644 --- a/frappe/www/rss.py +++ b/frappe/www/rss.py @@ -29,7 +29,7 @@ def get_context(context): blog.content = escape_html(blog.content or "") if blog_list: - modified = max((blog["modified"] for blog in blog_list)) + modified = max(blog["modified"] for blog in blog_list) else: modified = now()