refactor: fixup with ruff 0.8.1

Signed-off-by: Akhil Narang <me@akhilnarang.dev>
This commit is contained in:
Akhil Narang 2024-12-04 13:18:04 +05:30
parent df584ab891
commit 84ef6ec677
No known key found for this signature in database
GPG key ID: 9DCC61E211BF645F
83 changed files with 180 additions and 196 deletions

View file

@ -241,7 +241,7 @@ def init(site: str, sites_path: str = ".", new_site: bool = False, force: bool =
"read_only": False,
}
)
local.locked_documents: list["Document"] = []
local.locked_documents: list[Document] = []
local.test_objects = defaultdict(list)
local.site = site
@ -929,7 +929,7 @@ def is_whitelisted(method):
from frappe.utils import sanitize_html
is_guest = session["user"] == "Guest"
if method not in whitelisted or is_guest and method not in guest_methods:
if method not in whitelisted or (is_guest and method not in guest_methods):
summary = _("You are not permitted to access this resource.")
detail = _("Function {0} is not whitelisted.").format(bold(f"{method.__module__}.{method.__name__}"))
msg = f"<details><summary>{summary}</summary>{detail}</details>"

View file

@ -7,6 +7,7 @@ Note:
- None of the functions present here should be called from python code, their location and
internal implementation can change without treating it as "breaking change".
"""
import json
from typing import Any

View file

@ -334,10 +334,8 @@ def handle_exception(e):
http_status_code = getattr(e, "http_status_code", 500)
accept_header = frappe.get_request_header("Accept") or ""
respond_as_json = (
frappe.get_request_header("Accept")
and (frappe.local.is_ajax or "application/json" in accept_header)
or (frappe.local.request.path.startswith("/api/") and not accept_header.startswith("text"))
)
frappe.get_request_header("Accept") and (frappe.local.is_ajax or "application/json" in accept_header)
) or (frappe.local.request.path.startswith("/api/") and not accept_header.startswith("text"))
if not frappe.session.user:
# If session creation fails then user won't be unset. This causes a lot of code that

View file

@ -113,7 +113,7 @@ class HTTPRequest:
class LoginManager:
__slots__ = ("user", "info", "full_name", "user_type", "user_lang", "resume")
__slots__ = ("full_name", "info", "resume", "user", "user_lang", "user_type")
def __init__(self):
self.user = None

View file

@ -29,7 +29,7 @@ class MilestoneTracker(Document):
def apply(self, doc):
before_save = doc.get_doc_before_save()
from_value = before_save and before_save.get(self.track_field) or None
from_value = (before_save and before_save.get(self.track_field)) or None
if from_value != doc.get(self.track_field):
frappe.get_doc(
doctype="Milestone",

View file

@ -184,8 +184,10 @@ def load_desktop_data(bootinfo):
app_name=app_info.get("name") or app_name,
app_title=app_info.get("title")
or (
frappe.get_hooks("app_title", app_name=app_name)
and frappe.get_hooks("app_title", app_name=app_name)[0]
(
frappe.get_hooks("app_title", app_name=app_name)
and frappe.get_hooks("app_title", app_name=app_name)[0]
)
or ""
)
or app_name,

View file

@ -78,8 +78,8 @@ def get_assets_link(frappe_head) -> str:
import requests
tag = getoutput(
r"cd ../apps/frappe && git show-ref --tags -d | grep %s | sed -e 's,.*"
r" refs/tags/,,' -e 's/\^{}//'" % frappe_head
r"cd ../apps/frappe && git show-ref --tags -d | grep {} | sed -e 's,.*"
r" refs/tags/,,' -e 's/\^{{}}//'".format(frappe_head)
)
if tag:

View file

@ -489,7 +489,7 @@ def get_permission_query_conditions_for_communication(user):
if not accounts:
return """`tabCommunication`.communication_medium!='Email'"""
email_accounts = ['"%s"' % account.get("email_account") for account in accounts]
email_accounts = ['"{}"'.format(account.get("email_account")) for account in accounts]
return """`tabCommunication`.email_account in ({email_accounts})""".format(
email_accounts=",".join(email_accounts)
)
@ -623,9 +623,7 @@ def update_parent_document_on_communication(doc):
# if status has a "Open" option and status is "Replied", then update the status for received communication
if (
("Open" in options)
and parent.status == "Replied"
and doc.sent_or_received == "Received"
(("Open" in options) and parent.status == "Replied" and doc.sent_or_received == "Received")
or (
parent.doctype == "Issue" and ("Open" in options) and doc.sent_or_received == "Received"
) # For 'Issue', current status is not considered.

View file

@ -142,7 +142,7 @@ def _make(
cc = list_to_str(cc) if isinstance(cc, list) else cc
bcc = list_to_str(bcc) if isinstance(bcc, list) else bcc
comm: "Communication" = frappe.get_doc(
comm: Communication = frappe.get_doc(
{
"doctype": "Communication",
"subject": subject,

View file

@ -143,7 +143,7 @@ class TestCommunication(IntegrationTestCase):
self.assertNotEqual(2, len(comm.timeline_links))
def test_contacts_attached(self):
contact_sender: "Contact" = frappe.get_doc(
contact_sender: Contact = frappe.get_doc(
{
"doctype": "Contact",
"first_name": "contact_sender",
@ -152,7 +152,7 @@ class TestCommunication(IntegrationTestCase):
contact_sender.add_email("comm_sender@example.com")
contact_sender.insert(ignore_permissions=True)
contact_recipient: "Contact" = frappe.get_doc(
contact_recipient: Contact = frappe.get_doc(
{
"doctype": "Contact",
"first_name": "contact_recipient",
@ -161,7 +161,7 @@ class TestCommunication(IntegrationTestCase):
contact_recipient.add_email("comm_recipient@example.com")
contact_recipient.insert(ignore_permissions=True)
contact_cc: "Contact" = frappe.get_doc(
contact_cc: Contact = frappe.get_doc(
{
"doctype": "Contact",
"first_name": "contact_cc",

View file

@ -307,7 +307,7 @@ class DataExporter:
self.tablerow.append("")
self.fieldrow.append(docfield.fieldname)
self.labelrow.append(_(docfield.label, context=docfield.parent))
self.mandatoryrow.append(docfield.reqd and "Yes" or "No")
self.mandatoryrow.append((docfield.reqd and "Yes") or "No")
self.typerow.append(docfield.fieldtype)
self.inforow.append(self.getinforow(docfield))
self.columns.append(docfield.fieldname)
@ -328,9 +328,9 @@ class DataExporter:
if not docfield.options:
return ""
else:
return _("One of") + ": %s" % ", ".join(filter(None, docfield.options.split("\n")))
return _("One of") + ": {}".format(", ".join(filter(None, docfield.options.split("\n"))))
elif docfield.fieldtype == "Link":
return "Valid %s" % docfield.options
return "Valid {}".format(docfield.options)
elif docfield.fieldtype == "Int":
return "Integer"
elif docfield.fieldtype == "Check":

View file

@ -1003,7 +1003,7 @@ class DocType(Document):
def get_max_idx(self):
"""Return the highest `idx`."""
max_idx = frappe.db.sql("""select max(idx) from `tabDocField` where parent = %s""", self.name)
return max_idx and max_idx[0][0] or 0
return (max_idx and max_idx[0][0]) or 0
def validate_name(self, name=None):
if not name:
@ -1142,10 +1142,8 @@ def validate_autoincrement_autoname(dt: Union[DocType, "CustomizeForm"]) -> bool
autoname_before_save = get_autoname_before_save(dt)
is_autoname_autoincrement = dt.autoname == "autoincrement"
if (
is_autoname_autoincrement
and autoname_before_save != "autoincrement"
or (not is_autoname_autoincrement and autoname_before_save == "autoincrement")
if (is_autoname_autoincrement and autoname_before_save != "autoincrement") or (
not is_autoname_autoincrement and autoname_before_save == "autoincrement"
):
if dt.doctype == "Customize Form":
frappe.throw(_("Cannot change to/from autoincrement autoname in Customize Form"))
@ -1272,7 +1270,7 @@ def validate_fields(meta: Meta):
def check_unique_fieldname(docname, fieldname):
duplicates = list(
filter(None, map(lambda df: df.fieldname == fieldname and str(df.idx) or None, fields))
filter(None, map(lambda df: (df.fieldname == fieldname and str(df.idx)) or None, fields))
)
if len(duplicates) > 1:
frappe.throw(

View file

@ -656,7 +656,7 @@ class File(Document):
)
if duplicate_file:
file_doc: "File" = frappe.get_cached_doc("File", duplicate_file.name)
file_doc: File = frappe.get_cached_doc("File", duplicate_file.name)
if file_doc.exists_on_disk():
self.file_url = duplicate_file.file_url
file_exists = True

View file

@ -53,7 +53,7 @@ def make_test_image_file(private=False):
}
).insert()
# remove those flags
_test_file: "File" = frappe.get_doc("File", test_file.name)
_test_file: File = frappe.get_doc("File", test_file.name)
try:
yield _test_file
@ -469,7 +469,7 @@ class TestFile(IntegrationTestCase):
self.assertRaises(OSError, file1.save)
def test_file_url_validation(self):
test_file: "File" = frappe.new_doc("File")
test_file: File = frappe.new_doc("File")
test_file.update({"file_name": "logo", "file_url": "https://frappe.io/files/frappe.png"})
self.assertIsNone(test_file.validate())
@ -494,7 +494,7 @@ class TestFile(IntegrationTestCase):
def test_make_thumbnail(self):
# test web image
test_file: "File" = frappe.get_doc(
test_file: File = frappe.get_doc(
{
"doctype": "File",
"file_name": "logo",
@ -934,12 +934,12 @@ class TestGuestFileAndAttachments(IntegrationTestCase):
file_name = "test" + frappe.generate_hash()
content = file_name.encode()
doc_pub: "File" = frappe.new_doc("File") # type: ignore
doc_pub: File = frappe.new_doc("File") # type: ignore
doc_pub.file_url = f"/files/{file_name}.txt"
doc_pub.content = content
doc_pub.save()
doc_pri: "File" = frappe.new_doc("File") # type: ignore
doc_pri: File = frappe.new_doc("File") # type: ignore
doc_pri.file_url = f"/private/files/{file_name}.txt"
doc_pri.is_private = False
doc_pri.content = content

View file

@ -40,7 +40,7 @@ def make_home_folder() -> None:
def setup_folder_path(filename: str, new_parent: str) -> None:
file: "File" = frappe.get_doc("File", filename)
file: File = frappe.get_doc("File", filename)
file.folder = new_parent
file.save()
@ -355,7 +355,7 @@ def attach_files_to_document(doc: "Document", event) -> None:
)
continue
file: "File" = frappe.get_doc(
file: File = frappe.get_doc(
doctype="File",
file_url=value,
attached_to_name=doc.name,
@ -433,6 +433,6 @@ def find_file_by_url(path: str, name: str | None = None) -> Optional["File"]:
# if the file is accessible from any one of those documents
# then it should be downloadable
for file_data in files:
file: "File" = frappe.get_doc(doctype="File", **file_data)
file: File = frappe.get_doc(doctype="File", **file_data)
if file.is_downloadable():
return file

View file

@ -16,8 +16,7 @@ class LogType(Protocol):
"""Interface requirement for doctypes that can be cleared using log settings."""
@staticmethod
def clear_old_logs(days: int) -> None:
...
def clear_old_logs(days: int) -> None: ...
@site_cache

View file

@ -47,8 +47,7 @@ class Page(Document):
if frappe.db.exists("Page", self.name):
cnt = frappe.db.sql(
"""select name from tabPage
where name like "%s-%%" order by name desc limit 1"""
% self.name
where name like "{}-%" order by name desc limit 1""".format(self.name)
)
if cnt:
cnt = cint(cnt[0][0].split("-")[-1]) + 1

View file

@ -53,23 +53,17 @@ class PermissionInspector(Document):
def load_from_db(self):
super(Document, self).__init__({"modified": None, "permission_type": "read"})
def db_insert(self, *args, **kwargs):
...
def db_insert(self, *args, **kwargs): ...
def db_update(self):
...
def db_update(self): ...
@staticmethod
def get_list():
...
def get_list(): ...
@staticmethod
def get_count():
...
def get_count(): ...
@staticmethod
def get_stats():
...
def get_stats(): ...
def delete(self):
...
def delete(self): ...

View file

@ -97,7 +97,7 @@ class ServerScript(Document):
frappe.cache.delete_value("server_script_map")
if self.script_type == "Scheduler Event":
for job in self.scheduled_jobs:
scheduled_job_type: "ScheduledJobType" = frappe.get_doc("Scheduled Job Type", job.name)
scheduled_job_type: ScheduledJobType = frappe.get_doc("Scheduled Job Type", job.name)
scheduled_job_type.stopped = True
scheduled_job_type.server_script = None
scheduled_job_type.save()

View file

@ -58,7 +58,7 @@ def get_contact_number(contact_name, ref_doctype, ref_name):
(contact_name, ref_doctype, ref_name),
)
return number and (number[0][0] or number[0][1]) or ""
return (number and (number[0][0] or number[0][1])) or ""
@frappe.whitelist()

View file

@ -441,7 +441,7 @@ class User(Document):
def get_fullname(self):
"""get first_name space last_name"""
return (self.first_name or "") + (self.first_name and " " or "") + (self.last_name or "")
return (self.first_name or "") + ((self.first_name and " ") or "") + (self.last_name or "")
def password_reset_mail(self, link):
reset_password_template = frappe.db.get_system_setting("reset_password_template")
@ -501,8 +501,8 @@ class User(Document):
args.update(add_args)
sender = (
frappe.session.user not in STANDARD_USERS and get_formatted_email(frappe.session.user) or None
)
frappe.session.user not in STANDARD_USERS and get_formatted_email(frappe.session.user)
) or None
if custom_template:
from frappe.email.doctype.email_template.email_template import get_email_template

View file

@ -2,9 +2,10 @@
# MIT License. See LICENSE
"""
Customize Form is a Single DocType used to mask the Property Setter
Thus providing a better UI from user perspective
Customize Form is a Single DocType used to mask the Property Setter
Thus providing a better UI from user perspective
"""
import json
import frappe

View file

@ -83,7 +83,7 @@ def make_property_setter(
property_setter = frappe.get_doc(
{
"doctype": "Property Setter",
"doctype_or_field": for_doctype and "DocType" or "DocField",
"doctype_or_field": (for_doctype and "DocType") or "DocField",
"doc_type": doctype,
"field_name": fieldname,
"property": property,

View file

@ -116,8 +116,8 @@ class Database:
def connect(self):
"""Connects to a database as set in `site_config.json`."""
self._conn: "MariadbConnection" | "PostgresConnection" = self.get_connection()
self._cursor: "MariadbCursor" | "PostgresCursor" = self._conn.cursor()
self._conn: MariadbConnection | PostgresConnection = self.get_connection()
self._cursor: MariadbCursor | PostgresCursor = self._conn.cursor()
try:
if execution_timeout := get_query_execution_timeout():
@ -967,7 +967,7 @@ class Database:
def get_default(self, key, parent="__default"):
"""Return default value as a list if multiple or single."""
d = self.get_defaults(key, parent)
return isinstance(d, list) and d[0] or d
return (isinstance(d, list) and d[0]) or d
@staticmethod
def set_default(key, val, parent="__default", parenttype=None):

View file

@ -43,7 +43,7 @@ def setup_database(force, verbose, mariadb_user_host_login_scope=None):
dbman.create_database(db_name)
if verbose:
print("Created database %s" % db_name)
print("Created database {}".format(db_name))
dbman.grant_all_privileges(db_name, db_user, **dbman_kwargs)
dbman.flush_privileges()
@ -96,7 +96,7 @@ def import_db_from_sql(source_sql=None, verbose=False):
verbose, db_name, source_sql, frappe.conf.db_user, frappe.conf.db_password
)
if verbose:
print("Imported from database %s" % source_sql)
print("Imported from database {}".format(source_sql))
def check_compatible_versions():

View file

@ -55,7 +55,7 @@ def import_db_from_sql(source_sql=None, verbose=False):
verbose, db_name, source_sql, frappe.conf.db_user, frappe.conf.db_password
)
if verbose:
print("Imported from database %s" % source_sql)
print("Imported from database {}".format(source_sql))
def get_root_connection():

View file

@ -31,7 +31,7 @@ def get_user_default(key, user=None):
# If no default value is found, use the User Permission value
d = user_permission_default
value = isinstance(d, list | tuple) and d[0] or d
value = (isinstance(d, list | tuple) and d[0]) or d
if not_in_user_permission(key, value, user):
return
@ -68,7 +68,7 @@ def get_user_default_as_list(key, user=None):
else:
d = user_defaults.get(frappe.scrub(key), None)
d = list(filter(None, (not isinstance(d, list | tuple)) and [d] or d))
d = list(filter(None, ((not isinstance(d, list | tuple)) and [d]) or d))
# filter default values if not found in user permission
return [value for value in d if not not_in_user_permission(key, value)]
@ -135,7 +135,7 @@ def add_global_default(key, value):
def get_global_default(key):
d = get_defaults().get(key, None)
value = isinstance(d, list | tuple) and d[0] or d
value = (isinstance(d, list | tuple) and d[0]) or d
if not_in_user_permission(key, value):
return

View file

@ -46,8 +46,8 @@ def get_events(doctype, start, end, field_map, filters=None, fields=None):
if field_map.color:
fields.append(field_map.color)
start_date = "ifnull(%s, '0001-01-01 00:00:00')" % field_map.start
end_date = "ifnull(%s, '2199-12-31 00:00:00')" % field_map.end
start_date = "ifnull({}, '0001-01-01 00:00:00')".format(field_map.start)
end_date = "ifnull({}, '2199-12-31 00:00:00')".format(field_map.end)
filters += [
[doctype, start_date, "<=", end],

View file

@ -139,7 +139,7 @@ class Workspace:
item_type = item_type.lower()
if item_type == "doctype":
return name in self.can_read or [] and name in self.restricted_doctypes or []
return name in self.can_read or ([] and name in self.restricted_doctypes) or []
if item_type == "page":
return name in self.allowed_pages and name in self.restricted_pages
if item_type == "report":

View file

@ -15,7 +15,7 @@ FOLDER_NAME = "dashboard_chart_source"
@frappe.whitelist()
def get_config(name: str) -> str:
doc: "DashboardChartSource" = frappe.get_doc("Dashboard Chart Source", name)
doc: DashboardChartSource = frappe.get_doc("Dashboard Chart Source", name)
return doc.read_config()

View file

@ -12,7 +12,7 @@ from frappe.utils import get_url_to_form
@frappe.whitelist()
def update_follow(doctype: str, doc_name: str, following: bool):
if following:
return follow_document(doctype, doc_name, frappe.session.user) and True or False
return (follow_document(doctype, doc_name, frappe.session.user) and True) or False
else:
return unfollow_document(doctype, doc_name, frappe.session.user)

View file

@ -165,7 +165,7 @@ def get_script(report_name):
script += f"\n\n//# sourceURL={scrub(report.name)}__custom"
if not script:
script = "frappe.query_reports['%s']={}" % report_name
script = "frappe.query_reports['{}']={{}}".format(report_name)
return {
"script": render_include(script),

View file

@ -27,7 +27,7 @@ def execute(filters=None):
todo_list.sort(
key=lambda todo: (
priority_map.get(todo.priority, 0),
todo.date and getdate(todo.date) or getdate("1900-01-01"),
(todo.date and getdate(todo.date)) or getdate("1900-01-01"),
),
reverse=True,
)

View file

@ -666,7 +666,7 @@ def get_filter_dashboard_data(stats, doctype, filters=None):
tagcount = frappe.get_list(
doctype,
fields=[tag["name"], "count(*)"],
filters=[*filters, "ifnull(`%s`,'')!=''" % tag["name"]],
filters=[*filters, "ifnull(`{}`,'')!=''".format(tag["name"])],
group_by=tag["name"],
as_list=True,
)

View file

@ -1,6 +1,7 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# License: MIT. See LICENSE
import _socket
import datetime
import email
import email.utils
@ -14,7 +15,6 @@ from email.errors import HeaderParseError
from email.header import decode_header
from urllib.parse import unquote
import _socket
import chardet
from email_reply_parser import EmailReplyParser
@ -596,7 +596,7 @@ class Email:
def get_thread_id(self):
"""Extract thread ID from `[]`"""
l = THREAD_ID_PATTERN.findall(self.subject)
return l and l[0] or None
return (l and l[0]) or None
def is_reply(self):
return bool(self.in_reply_to)

View file

@ -37,7 +37,7 @@ class TestEmailAttachments(IntegrationTestCase):
email_account = frappe._dict({"email_id": "receive@example.com"})
mail = InboundMail(EMAIL_CONTENT, email_account)
communication = mail.process()
file: "File" = frappe.get_last_doc(
file: File = frappe.get_last_doc(
"File",
{
"attached_to_doctype": communication.doctype,
@ -51,7 +51,7 @@ class TestEmailAttachments(IntegrationTestCase):
def test_file_with_percent_in_filename(self):
def make_and_check_file(index: int, literal_file_name: str, disk_file_name: str):
content = "abcdefghijklmnop_attachment"
file: "File" = frappe.new_doc("File") # type: ignore
file: File = frappe.new_doc("File") # type: ignore
file.update(
{
"file_name": literal_file_name,

View file

@ -1,6 +1,7 @@
"""
FrappeClient is a library that helps you connect with other frappe systems
"""
import base64
import json

View file

@ -106,7 +106,7 @@ def extract_javascript(code, keywords=None, options=None, lineno=1):
if token.value in closing_operators:
tree_level -= 1
elif call_stack == -1 and token.type == "linecomment" or token.type == "multilinecomment":
elif (call_stack == -1 and token.type == "linecomment") or token.type == "multilinecomment":
pass # ignore comments
elif funcname and call_stack == 0:

View file

@ -129,7 +129,7 @@ def upload_file():
else:
raise frappe.PermissionError
else:
user: "User" = frappe.get_doc("User", frappe.session.user)
user: User = frappe.get_doc("User", frappe.session.user)
ignore_permissions = False
files = frappe.request.files
@ -227,7 +227,7 @@ def download_file(file_url: str):
Endpoints : download_file, frappe.core.doctype.file.file.download_file
URL Params : file_name = /path/to/file relative to site path
"""
file: "File" = frappe.get_doc("File", {"file_url": file_url})
file: File = frappe.get_doc("File", {"file_url": file_url})
if not file.is_downloadable():
raise frappe.PermissionError

View file

@ -205,7 +205,7 @@ class LDAPSettings(Document):
user.remove_roles(*roles_to_remove)
def create_or_update_user(self, user_data: dict, groups: list | None = None):
user: "User" = None
user: User = None
role: str = None
if frappe.db.exists("User", user_data["email"]):

View file

@ -38,11 +38,8 @@ class OAuthClient(Document):
self.add_default_role()
def validate_grant_and_response(self):
if (
self.grant_type == "Authorization Code"
and self.response_type != "Code"
or self.grant_type == "Implicit"
and self.response_type != "Token"
if (self.grant_type == "Authorization Code" and self.response_type != "Code") or (
self.grant_type == "Implicit" and self.response_type != "Token"
):
frappe.throw(
_(

View file

@ -190,7 +190,7 @@ def delete_fields(args_dict, delete=0):
)
else:
existing_fields = frappe.db.describe(dt)
existing_fields = existing_fields and [e[0] for e in existing_fields] or []
existing_fields = (existing_fields and [e[0] for e in existing_fields]) or []
fields_need_to_delete = set(fields) & set(existing_fields)
if not fields_need_to_delete:
continue
@ -199,8 +199,8 @@ def delete_fields(args_dict, delete=0):
# mariadb implicitly commits before DDL, make it explicit
frappe.db.commit()
query = "ALTER TABLE `tab%s` " % dt + ", ".join(
"DROP COLUMN `%s`" % f for f in fields_need_to_delete
query = "ALTER TABLE `tab{}` ".format(dt) + ", ".join(
"DROP COLUMN `{}`".format(f) for f in fields_need_to_delete
)
frappe.db.sql(query)

View file

@ -306,10 +306,10 @@ class DatabaseQuery:
self.set_order_by(args)
self.validate_order_by_and_group_by(args.order_by)
args.order_by = args.order_by and (" order by " + args.order_by) or ""
args.order_by = (args.order_by and (" order by " + args.order_by)) or ""
self.validate_order_by_and_group_by(self.group_by)
args.group_by = self.group_by and (" group by " + self.group_by) or ""
args.group_by = (self.group_by and (" group by " + self.group_by)) or ""
return args
@ -1261,7 +1261,7 @@ def get_between_date_filter(value, df=None):
no change is applied.
"""
fieldtype = df and df.fieldtype or "Datetime"
fieldtype = (df and df.fieldtype) or "Datetime"
from_date = frappe.utils.nowdate()
to_date = frappe.utils.nowdate()

View file

@ -518,7 +518,7 @@ class Document(BaseDocument, DocRef):
def update_child_table(self, fieldname: str, df: Optional["DocField"] = None):
"""sync child table for given fieldname"""
df: "DocField" = df or self.meta.get_field(fieldname)
df: DocField = df or self.meta.get_field(fieldname)
all_rows = self.get(df.fieldname)
# delete rows that do not match the ones in the document

View file

@ -592,8 +592,7 @@ class Meta(Document):
def get_fieldnames_with_value(self, with_field_meta=False, with_virtual_fields=False):
def is_value_field(docfield):
return not (
not with_virtual_fields
and docfield.get("is_virtual")
(not with_virtual_fields and docfield.get("is_virtual"))
or docfield.fieldtype in no_value_fields
)
@ -785,7 +784,7 @@ def is_single(doctype):
try:
return frappe.db.get_value("DocType", doctype, "issingle")
except IndexError:
raise Exception("Cannot determine whether %s is single" % doctype)
raise Exception("Cannot determine whether {} is single".format(doctype))
def get_parent_dt(dt):

View file

@ -1,9 +1,10 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# License: MIT. See LICENSE
"""
Sync's doctype and docfields from txt files to database
perms will get synced only if none exist
Sync's doctype and docfields from txt files to database
perms will get synced only if none exist
"""
import os
import frappe

View file

@ -78,7 +78,7 @@ def update_reports(doctype, old_fieldname, new_fieldname):
"""select name, ref_doctype, json from tabReport
where report_type = 'Report Builder' and ifnull(is_standard, 'No') = 'No'
and json like %s and json like %s""",
("%%%s%%" % old_fieldname, "%%%s%%" % doctype),
("%{}%".format(old_fieldname), "%{}%".format(doctype)),
as_dict=True,
)

View file

@ -19,7 +19,7 @@ def get_user_settings(doctype, for_update=False):
where `user`=%s and `doctype`=%s""",
(frappe.session.user, doctype),
)
user_settings = user_settings and user_settings[0][0] or "{}"
user_settings = (user_settings and user_settings[0][0]) or "{}"
if not for_update:
update_user_settings(doctype, user_settings, True)

View file

@ -176,7 +176,7 @@ def read_doc_from_file(path):
print(f"bad json: {path}")
raise
else:
raise OSError("%s missing" % path)
raise OSError("{} missing".format(path))
return doc

View file

@ -1,6 +1,6 @@
# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors
# License: MIT. See LICENSE
""" Patch Handler.
"""Patch Handler.
This file manages execution of manaully written patches. Patches are script
that apply changes in database schema or data to accomodate for changes in the

View file

@ -1,8 +1,9 @@
# Copyright (c) 2022, Frappe Technologies Pvt. Ltd. and Contributors
# License: MIT. See LICENSE
"""
Utilities for using modules
Utilities for using modules
"""
import json
import os
from textwrap import dedent, indent

View file

@ -1,6 +1,7 @@
"""
Run this after updating country_info.json and or
"""
import frappe

View file

@ -1,8 +1,9 @@
"""
Modify the Integer 10 Digits Value to BigInt 20 Digit value
to generate long Naming Series
Modify the Integer 10 Digits Value to BigInt 20 Digit value
to generate long Naming Series
"""
import frappe

View file

@ -1,6 +1,7 @@
"""
Run this after updating country_info.json and or
"""
from frappe.utils.install import import_country_and_currency

View file

@ -9,7 +9,7 @@ def execute():
imap_list = [folder.folder_name for folder in doc.imap_folder]
# and append the old data to the child table
if doc.uidvalidity or doc.uidnext and "INBOX" not in imap_list:
if doc.uidvalidity or (doc.uidnext and "INBOX" not in imap_list):
doc.append(
"imap_folder",
{

View file

@ -732,7 +732,7 @@ def filter_allowed_docs_for_doctype(user_permissions, doctype, with_default_doc=
for doc in user_permissions:
if not doc.get("applicable_for") or doc.get("applicable_for") == doctype:
allowed_doc.append(doc.get("doc"))
if doc.get("is_default") or len(user_permissions) == 1 and with_default_doc:
if doc.get("is_default") or (len(user_permissions) == 1 and with_default_doc):
default_doc = doc.get("doc")
return (allowed_doc, default_doc) if with_default_doc else allowed_doc

View file

@ -46,7 +46,7 @@ class TestPrintFormat(IntegrationTestCase):
os.access(frappe.get_app_path("frappe"), os.W_OK), "Only run if frappe app paths is writable"
)
def test_export_doc(self):
doc: "PrintFormat" = frappe.get_doc("Print Format", self.globalTestRecords["Print Format"][0]["name"])
doc: PrintFormat = frappe.get_doc("Print Format", self.globalTestRecords["Print Format"][0]["name"])
# this is only to make export_doc happy
doc.standard = "Yes"

View file

@ -6,6 +6,7 @@ Boot session from cache or build
Session bootstraps info needed by common client side activities including
permission, homepage, default variables, system defaults etc
"""
import json
from urllib.parse import unquote
@ -202,7 +203,7 @@ def generate_csrf_token():
class Session:
__slots__ = ("user", "user_type", "full_name", "data", "time_diff", "sid", "_update_in_cache")
__slots__ = ("_update_in_cache", "data", "full_name", "sid", "time_diff", "user", "user_type")
def __init__(self, user, resume=False, full_name=None, user_type=None):
self.sid = cstr(frappe.form_dict.get("sid") or unquote(frappe.request.cookies.get("sid", "Guest")))

View file

@ -261,14 +261,14 @@ def trace_fields(
# these can be general purpose context managers who do NOT depend on a particular
# test class setup, such as for example the IntegrationTestCase's connection to site
__all__ = [
"freeze_time",
"set_user",
"patch_hooks",
"change_settings",
"switch_site",
"enable_safe_exec",
"debug_on",
"timeout_context",
"enable_safe_exec",
"freeze_time",
"patch_hooks",
"set_user",
"switch_site",
"timeout",
"timeout_context",
"trace_fields",
]

View file

@ -55,8 +55,10 @@ class TestBackgroundJobs(IntegrationTestCase):
def test_job_hooks(self):
self.addCleanup(lambda: _test_JOB_HOOK.clear())
with freeze_local() as locals, frappe.init_site(locals.site), patch(
"frappe.get_hooks", patch_job_hooks
with (
freeze_local() as locals,
frappe.init_site(locals.site),
patch("frappe.get_hooks", patch_job_hooks),
):
frappe.connect()
self.assertIsNone(_test_JOB_HOOK.get("before_job"))

View file

@ -454,7 +454,7 @@ class TestCommands(BaseTestCommands):
# Reset it back to original password
original_password = frappe.conf.admin_password or "admin"
self.execute("bench --site {site} set-admin-password %s" % original_password)
self.execute("bench --site {{site}} set-admin-password {}".format(original_password))
self.assertEqual(self.returncode, 0)
self.assertEqual(check_password("Administrator", original_password), "Administrator")

View file

@ -64,7 +64,7 @@ class TestOAuth20(FrappeRequestTestCase):
cls.redirect_uri = "http://localhost"
# Set Frappe server URL reqired for id_token generation
frappe_login_key: "SocialLoginKey" = frappe.new_doc("Social Login Key")
frappe_login_key: SocialLoginKey = frappe.new_doc("Social Login Key")
frappe_login_key.get_social_login_provider("Frappe", initialize=True)
frappe_login_key.base_url = frappe.utils.get_url()
frappe_login_key.enable_social_login = 0

View file

@ -16,6 +16,7 @@ query. This test can be written like this.
>>> get_controller("User")
"""
import gc
import sys
import time

View file

@ -25,13 +25,13 @@ testing_logger = logging.getLogger("frappe.testing.generators")
datetime_like_types = (datetime.datetime, datetime.date, datetime.time, datetime.timedelta)
__all__ = [
"get_modules",
"get_missing_records_doctypes",
"get_missing_records_module_overrides",
"get_modules",
"load_test_records_for",
"make_test_objects",
"make_test_records",
"make_test_records_for_doctype",
"make_test_objects",
"load_test_records_for",
]

View file

@ -481,8 +481,8 @@ def get_messages_from_report(name):
)
if report.columns:
context = (
"Column of report '%s'" % report.name
context = "Column of report '{}'".format(
report.name
) # context has to match context in `prepare_columns` in query_report.js
messages.extend([(None, report_column.label, context) for report_column in report.columns])

View file

@ -35,16 +35,13 @@ class _dict(dict[_KT, _VT]):
return self
@overload # type: ignore[override]
def update(self, m: Mapping[_KT, _VT], /, **kwargs: _VT) -> Self:
...
def update(self, m: Mapping[_KT, _VT], /, **kwargs: _VT) -> Self: ...
@overload
def update(self, m: Iterable[tuple[_KT, _VT]], /, **kwargs: _VT) -> Self:
...
def update(self, m: Iterable[tuple[_KT, _VT]], /, **kwargs: _VT) -> Self: ...
@overload
def update(self, /, **kwargs: _VT) -> Self:
...
def update(self, /, **kwargs: _VT) -> Self: ...
@override
def update(

View file

@ -5,7 +5,7 @@ from frappe import _
@functools.total_ordering
class _LazyTranslate:
__slots__ = ("msg", "lang", "context")
__slots__ = ("context", "lang", "msg")
def __init__(self, msg: str, lang: str | None = None, context: str | None = None) -> None:
self.msg = msg

View file

@ -66,7 +66,7 @@ def _get_user_inputs(app_name):
input_type = config.get("type", str)
while value is None:
if input_type == bool:
if input_type is bool:
value = click.confirm(config["prompt"], default=config.get("default"))
else:
value = click.prompt(config["prompt"], default=config.get("default"), type=input_type)

View file

@ -223,8 +223,7 @@ def add_to_date(
seconds=0,
as_string: Literal[False] = False,
as_datetime: Literal[False] = False,
) -> datetime.date:
...
) -> datetime.date: ...
@typing.overload
@ -239,8 +238,7 @@ def add_to_date(
seconds=0,
as_string: Literal[False] = False,
as_datetime: Literal[True] = True,
) -> datetime.datetime:
...
) -> datetime.datetime: ...
@typing.overload
@ -255,8 +253,7 @@ def add_to_date(
seconds=0,
as_string: Literal[True] = True,
as_datetime: bool = False,
) -> str:
...
) -> str: ...
def add_to_date(
@ -441,13 +438,11 @@ def nowtime() -> str:
@typing.overload
def get_first_day(dt, d_years=0, d_months=0, as_str: Literal[False] = False) -> datetime.date:
...
def get_first_day(dt, d_years=0, d_months=0, as_str: Literal[False] = False) -> datetime.date: ...
@typing.overload
def get_first_day(dt, d_years=0, d_months=0, as_str: Literal[True] = False) -> str:
...
def get_first_day(dt, d_years=0, d_months=0, as_str: Literal[True] = False) -> str: ...
# TODO: first arg
@ -470,13 +465,13 @@ def get_first_day(dt, d_years: int = 0, d_months: int = 0, as_str: bool = False)
@typing.overload
def get_quarter_start(dt: DateTimeLikeObject | None = None, as_str: Literal[False] = False) -> datetime.date:
...
def get_quarter_start(
dt: DateTimeLikeObject | None = None, as_str: Literal[False] = False
) -> datetime.date: ...
@typing.overload
def get_quarter_start(dt: DateTimeLikeObject | None = None, as_str: Literal[True] = False) -> str:
...
def get_quarter_start(dt: DateTimeLikeObject | None = None, as_str: Literal[True] = False) -> str: ...
def get_quarter_start(dt: DateTimeLikeObject | None = None, as_str: bool = False) -> str | datetime.date:
@ -491,13 +486,11 @@ def get_quarter_start(dt: DateTimeLikeObject | None = None, as_str: bool = False
@typing.overload
def get_first_day_of_week(dt: DateTimeLikeObject, as_str: Literal[False] = False) -> datetime.date:
...
def get_first_day_of_week(dt: DateTimeLikeObject, as_str: Literal[False] = False) -> datetime.date: ...
@typing.overload
def get_first_day_of_week(dt: DateTimeLikeObject, as_str: Literal[True] = False) -> str:
...
def get_first_day_of_week(dt: DateTimeLikeObject, as_str: Literal[True] = False) -> str: ...
def get_first_day_of_week(dt: DateTimeLikeObject, as_str=False) -> datetime.date | str:
@ -526,13 +519,11 @@ def get_normalized_weekday_index(dt):
@typing.overload
def get_year_start(dt: DateTimeLikeObject, as_str: Literal[False] = False) -> datetime.date:
...
def get_year_start(dt: DateTimeLikeObject, as_str: Literal[False] = False) -> datetime.date: ...
@typing.overload
def get_year_start(dt: DateTimeLikeObject, as_str: Literal[True] = False) -> str:
...
def get_year_start(dt: DateTimeLikeObject, as_str: Literal[True] = False) -> str: ...
def get_year_start(dt: DateTimeLikeObject, as_str=False) -> str | datetime.date:
@ -543,13 +534,11 @@ def get_year_start(dt: DateTimeLikeObject, as_str=False) -> str | datetime.date:
@typing.overload
def get_last_day_of_week(dt: DateTimeLikeObject, as_str: Literal[False] = False) -> datetime.date:
...
def get_last_day_of_week(dt: DateTimeLikeObject, as_str: Literal[False] = False) -> datetime.date: ...
@typing.overload
def get_last_day_of_week(dt: DateTimeLikeObject, as_str: Literal[True] = False) -> str:
...
def get_last_day_of_week(dt: DateTimeLikeObject, as_str: Literal[True] = False) -> str: ...
def get_last_day_of_week(dt: DateTimeLikeObject, as_str=False) -> datetime.date | str:
@ -577,13 +566,13 @@ def is_last_day_of_the_month(dt):
@typing.overload
def get_quarter_ending(dt: DateTimeLikeObject | None = None, as_str: Literal[False] = False) -> datetime.date:
...
def get_quarter_ending(
dt: DateTimeLikeObject | None = None, as_str: Literal[False] = False
) -> datetime.date: ...
@typing.overload
def get_quarter_ending(dt: DateTimeLikeObject | None = None, as_str: Literal[True] = False) -> str:
...
def get_quarter_ending(dt: DateTimeLikeObject | None = None, as_str: Literal[True] = False) -> str: ...
def get_quarter_ending(date: DateTimeLikeObject | None = None, as_str=False) -> str | datetime.date:
@ -607,13 +596,13 @@ def get_quarter_ending(date: DateTimeLikeObject | None = None, as_str=False) ->
@typing.overload
def get_year_ending(dt: DateTimeLikeObject | None = None, as_str: Literal[False] = False) -> datetime.date:
...
def get_year_ending(
dt: DateTimeLikeObject | None = None, as_str: Literal[False] = False
) -> datetime.date: ...
@typing.overload
def get_year_ending(dt: DateTimeLikeObject | None = None, as_str: Literal[True] = False) -> str:
...
def get_year_ending(dt: DateTimeLikeObject | None = None, as_str: Literal[True] = False) -> str: ...
def get_year_ending(date: DateTimeLikeObject | None = None, as_str=False) -> datetime.date | str:
@ -1069,13 +1058,11 @@ def cast(fieldtype, value=None):
@typing.overload
def flt(s: NumericType | str, precision: Literal[0]) -> int:
...
def flt(s: NumericType | str, precision: Literal[0]) -> int: ...
@typing.overload
def flt(s: NumericType | str, precision: int | None = None) -> float:
...
def flt(s: NumericType | str, precision: int | None = None) -> float: ...
def flt(s: NumericType | str, precision: int | None = None, rounding_method: str | None = None) -> float:
@ -1408,7 +1395,8 @@ def fmt_money(
parts.reverse()
amount = number_format.thousands_separator.join(parts) + (
(precision and number_format.decimal_separator) and (number_format.decimal_separator + decimals) or ""
((precision and number_format.decimal_separator) and (number_format.decimal_separator + decimals))
or ""
)
if amount != "0":
amount = minus + amount
@ -1706,7 +1694,9 @@ def comma_sep(some_list: list | tuple, pattern: str, add_quotes=True) -> str:
elif len(some_list) == 1:
return some_list[0]
else:
some_list = ["'%s'" % s for s in some_list] if add_quotes else ["%s" % s for s in some_list]
some_list = (
["'{}'".format(s) for s in some_list] if add_quotes else ["{}".format(s) for s in some_list]
)
return pattern.format(", ".join(frappe._(s) for s in some_list[:-1]), some_list[-1])
else:
return some_list
@ -1725,7 +1715,7 @@ def new_line_sep(some_list: list | tuple) -> str:
elif len(some_list) == 1:
return some_list[0]
else:
some_list = ["%s" % s for s in some_list]
some_list = ["{}".format(s) for s in some_list]
return format("\n ".join(some_list))
else:
return some_list

View file

@ -43,7 +43,7 @@ def get_not_null_defaults(column_type: str) -> Literal["", 0] | None:
}
data_type = column_type_map.get(column_type.replace(" ", ""), str)
# data_type = eval(f"frappe.types.DF.{column_type.replace(' ', '')}")
if data_type == str:
if data_type is str:
return ""
if data_type in (int, float):
return 0

View file

@ -5,6 +5,7 @@ from strings.
It provides a (slighltly modified) version of https://github.com/evuez/identicons
which has been released under the MIT license, as described in attributions.md.
"""
from base64 import b64encode
from hashlib import md5
from io import BytesIO

View file

@ -48,7 +48,7 @@ def get_random(doctype: str, filters: dict | None = None, doc: bool = False):
}
)
out = out and out[0][0] or None
out = (out and out[0][0]) or None
if doc and out:
return frappe.get_doc(doctype, out)

View file

@ -16,8 +16,7 @@ if TYPE_CHECKING:
from frappe.core.doctype.user.user import User
class SignupDisabledError(frappe.PermissionError):
...
class SignupDisabledError(frappe.PermissionError): ...
def get_oauth2_providers() -> dict[str, dict]:
@ -235,7 +234,7 @@ def get_user_record(user: str, data: dict, provider: str) -> "User":
if not provider_allows_signup(provider):
raise SignupDisabledError
user: "User" = frappe.new_doc("User")
user: User = frappe.new_doc("User")
if gender := data.get("gender", "").title():
frappe.get_doc({"doctype": "Gender", "gender": gender}).insert(
@ -264,7 +263,7 @@ def update_oauth_user(user: str, data: dict, provider: str):
if isinstance(data.get("location"), dict):
data["location"] = data["location"].get("name")
user: "User" = get_user_record(user, data, provider)
user: User = get_user_record(user, data, provider)
update_user_record = user.is_new()
if not user.enabled:

View file

@ -281,7 +281,7 @@ def _get_base64_image(src):
mime_type = mimetypes.guess_type(path)[0]
if mime_type is None or not mime_type.startswith("image/"):
return
filename = query.get("fid") and query["fid"][0] or None
filename = (query.get("fid") and query["fid"][0]) or None
file = find_file_by_url(path, name=filename)
if not file or not file.is_private:
return

View file

@ -228,7 +228,7 @@ def json_handler(obj):
elif isinstance(obj, Match):
return obj.string
elif type(obj) == type or isinstance(obj, Exception):
elif type(obj) is type or isinstance(obj, Exception):
return repr(obj)
elif callable(obj):

View file

@ -184,7 +184,7 @@ def get_safe_globals():
if "_" in form_dict:
del frappe.local.form_dict["_"]
user = getattr(frappe.local, "session", None) and frappe.local.session.user or "Guest"
user = (getattr(frappe.local, "session", None) and frappe.local.session.user) or "Guest"
out = NamespaceDict(
# make available limited methods of frappe

View file

@ -1,4 +1,4 @@
""" Utils for thread/process synchronization. """
"""Utils for thread/process synchronization."""
import os
from contextlib import contextmanager

View file

@ -1,8 +1,9 @@
""" Basic telemetry for improving apps.
"""Basic telemetry for improving apps.
WARNING: Everything in this file should be treated "internal" and is subjected to change or get
removed without any warning.
"""
from contextlib import suppress
import frappe

View file

@ -323,10 +323,10 @@ def get_blog_list(doctype, txt=None, filters=None, limit_start=0, limit_page_len
)
if filters and filters.get("blogger"):
conditions.append("t1.blogger=%s" % frappe.db.escape(filters.get("blogger")))
conditions.append("t1.blogger={}".format(frappe.db.escape(filters.get("blogger"))))
if category:
conditions.append("t1.blog_category=%s" % frappe.db.escape(category))
conditions.append("t1.blog_category={}".format(frappe.db.escape(category)))
if txt:
conditions.append(

View file

@ -171,7 +171,7 @@ class WebsiteSettings(Document):
def get_website_settings(context=None):
hooks = frappe.get_hooks()
context = frappe._dict(context or {})
settings: "WebsiteSettings" = frappe.get_cached_doc("Website Settings")
settings: WebsiteSettings = frappe.get_cached_doc("Website Settings")
context = context.update(
{

View file

@ -23,7 +23,7 @@ UNSUPPORTED_STATIC_PAGE_TYPES = (
class StaticPage(BaseRenderer):
__slots__ = ("path", "file_path")
__slots__ = ("file_path", "path")
def __init__(self, path, http_status_code=None):
super().__init__(path=path, http_status_code=http_status_code)

View file

@ -18,7 +18,7 @@ from frappe.website.utils import can_cache, get_home_page
class PathResolver:
__slots__ = ("path", "http_status_code")
__slots__ = ("http_status_code", "path")
def __init__(self, path, http_status_code=None):
self.path = path.strip("/ ")

View file

@ -12,7 +12,7 @@ def get_context(context):
context.javascript = frappe.db.get_single_value("Website Script", "javascript") or ""
theme = get_active_theme()
js = strip(theme and theme.js or "")
js = strip((theme and theme.js) or "")
if js:
context.javascript += "\n" + js