diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index a49668a5f4..c3ad43c5be 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -22,3 +22,6 @@ b2fc959307c7c79f5584625569d5aed04133ba13 # Format codebase and sort imports c0c5b2ebdddbe8898ce2d5e5365f4931ff73b6bf + +# update python code to use 3.10 supported features +81b37cb7d2160866afa2496873656afe53f0c145 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e8a44f0d1e..b231221517 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -5,7 +5,7 @@ fail_fast: false repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.0.1 + rev: v4.3.0 hooks: - id: trailing-whitespace files: "frappe.*" @@ -15,6 +15,16 @@ repos: args: ['--branch', 'develop'] - id: check-merge-conflict - id: check-ast + - id: check-json + - id: check-toml + - id: check-yaml + - id: debug-statements + + - repo: https://github.com/asottile/pyupgrade + rev: v2.34.0 + hooks: + - id: pyupgrade + args: ['--py310-plus'] - repo: https://github.com/adityahase/black rev: 9cb0a69f4d0030cdf687eddf314468b39ed54119 @@ -31,9 +41,7 @@ repos: rev: 3.9.2 hooks: - id: flake8 - additional_dependencies: [ - 'flake8-bugbear', - ] + additional_dependencies: ['flake8-bugbear',] args: ['--config', '.github/helper/flake8.conf'] ci: diff --git a/frappe/__init__.py b/frappe/__init__.py index 0f55854535..63a0b945b1 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 @@ -108,7 +108,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: @@ -173,8 +173,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 @@ -313,10 +313,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) @@ -998,7 +998,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 @@ -1404,7 +1404,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) @@ -1427,7 +1427,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` @@ -1510,7 +1510,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) @@ -1520,10 +1520,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 @@ -1553,7 +1553,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: @@ -1790,8 +1790,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" @@ -1877,7 +1877,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: @@ -1908,7 +1908,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 [] @@ -2188,7 +2188,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): @@ -2216,10 +2216,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 4c5d54f857..e5f2aae61c 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 @@ -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 @@ -186,7 +185,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): @@ -661,8 +660,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, ): @@ -1007,7 +1006,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. @@ -1047,7 +1046,7 @@ 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 = frappe.qb.engine.get_query( @@ -1055,7 +1054,7 @@ class Database(object): ) 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 @@ -1089,7 +1088,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: @@ -1123,7 +1122,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] @@ -1185,7 +1184,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. @@ -1291,7 +1290,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 4a7d0e8a67..553160afc6 100644 --- a/frappe/database/query.py +++ b/frappe/database/query.py @@ -3,7 +3,7 @@ import re from ast import literal_eval from functools import cached_property from types import BuiltinFunctionType -from typing import TYPE_CHECKING, Any, Callable, Dict, List, Tuple, Union +from typing import TYPE_CHECKING, Any, Callable import frappe from frappe import _ @@ -34,7 +34,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: @@ -60,7 +60,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: @@ -86,7 +86,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: @@ -118,7 +118,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: @@ -159,7 +159,7 @@ def literal_eval_(literal): # default operators -OPERATOR_MAP: Dict[str, Callable] = { +OPERATOR_MAP: dict[str, Callable] = { "+": operator.add, "=": operator.eq, "-": operator.sub, @@ -209,7 +209,7 @@ class Engine: 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: @@ -225,7 +225,7 @@ class Engine: 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("'") @@ -280,7 +280,7 @@ class Engine: 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: @@ -312,9 +312,7 @@ class Engine: 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: @@ -355,7 +353,7 @@ class Engine: 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 @@ -508,8 +506,8 @@ class Engine: def get_query( 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 += ''.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 8d031aac01..053e2c3368 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.qb.engine.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}. {1}.
- +{}. {}.
+ """.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 c8079f94e8..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 @@ -13,7 +12,7 @@ from frappe.desk.doctype.notification_log.notification_log import enqueue_create from frappe.integrations.doctype.slack_webhook_url.slack_webhook_url import send_slack_message from frappe.model.document import Document from frappe.modules.utils import export_module_json, get_doc_module -from frappe.utils import add_to_date, is_html, nowdate, parse_val, validate_email_address +from frappe.utils import add_to_date, cast, is_html, nowdate, validate_email_address from frappe.utils.jinja import validate_template from frappe.utils.safe_exec import get_safe_globals @@ -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 @@ -417,7 +416,7 @@ def trigger_notifications(doc, method=None): frappe.db.commit() -def evaluate_alert(doc, alert, event): +def evaluate_alert(doc: Document, alert, event): from jinja2 import TemplateError try: @@ -433,14 +432,14 @@ def evaluate_alert(doc, 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() field_value_before_save = doc_before_save.get(alert.value_changed) if doc_before_save else None - field_value_before_save = parse_val(field_value_before_save) - if doc.get(alert.value_changed) == field_value_before_save: + fieldtype = doc.meta.get_field(alert.value_changed).fieldtype + if cast(fieldtype, doc.get(alert.value_changed)) == cast(fieldtype, field_value_before_save): # value not changed return diff --git a/frappe/email/doctype/notification/test_notification.py b/frappe/email/doctype/notification/test_notification.py index 4d8b26c559..4adaeae37e 100644 --- a/frappe/email/doctype/notification/test_notification.py +++ b/frappe/email/doctype/notification/test_notification.py @@ -1,7 +1,7 @@ -# -*- coding: utf-8 -*- # Copyright (c) 2018, Frappe Technologies and Contributors # License: MIT. See LICENSE import unittest +from contextlib import contextmanager import frappe import frappe.utils @@ -11,6 +11,15 @@ from frappe.desk.form import assign_to test_dependencies = ["User", "Notification"] +@contextmanager +def get_test_notification(config): + try: + notification = frappe.get_doc(doctype="Notification", **config).insert() + yield notification + finally: + notification.delete() + + class TestNotification(unittest.TestCase): def setUp(self): frappe.db.delete("Email Queue") @@ -345,6 +354,31 @@ class TestNotification(unittest.TestCase): self.assertTrue("test2@example.com" in recipients) self.assertTrue("test1@example.com" in recipients) + def test_notification_value_change_casted_types(self): + """Make sure value change event dont fire because of incorrect type comparisons.""" + frappe.set_user("Administrator") + + notification = { + "document_type": "User", + "subject": "User changed birthdate", + "event": "Value Change", + "channel": "System Notification", + "value_changed": "birth_date", + "recipients": [{"receiver_by_document_field": "email"}], + } + + with get_test_notification(notification) as n: + frappe.db.delete("Notification Log", {"subject": n.subject}) + + user = frappe.get_doc("User", "test@example.com") + user.birth_date = frappe.utils.add_days(user.birth_date, 1) + user.save() + + user.reload() + user.birth_date = frappe.utils.getdate(user.birth_date) + user.save() + self.assertEqual(1, frappe.db.count("Notification Log", {"subject": n.subject})) + @classmethod def tearDownClass(cls): frappe.delete_doc_if_exists("Notification", "ToDo Status Update") 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 += "{0}
".format(h) for h in headers) + self.html_content += "{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 = """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 = """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 = "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 += (
- "{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"(?