fix: add type hints to whitelisted methods 3 (#37149)

* fix(apps): add type hints to whitelisted methods

* fix(recorder): add type hints to whitelisted methods

* fix(comments): add type hints to whitelisted methods

* fix(oauth2): add type hints to whitelisted methods

* fix(google_calendar): add type hints to whitelisted methods

* fix(print): add type hints to whitelisted methods

* fix(print_format_builder): add type hints to whitelisted methods

* refactor(network_printer_settings): remove unused args

* fix(document): add type hints to whitelisted methods

* fix(user_settings): add type hints to whitelisted methods

* fix(mapper): add type hints to whitelisted methods

* fix(connected_app): add type hints to whitelisted methods

* fix(google_contacts): add type hints to whitelisted methods

* fix(frappecloud_billing): add type hints to whitelisted methods

* test: rewrite test to fit the strict type check

* fix(social_login_key): add type hints to whitelisted methods

* fix(share): add type hints to whitelisted methods

* fix(webhook): add type hints to whitelisted methods

* fix(workflow): add type hints to whitelisted methods

* fix(workflow main): add type hints to whitelisted methods

* fix(workflow_action): add type hints to whitelisted methods

* fix: flexible type hint

* fix(client): add type hints to whitelisted methods

* fix: fix some of the tighter types

* fix(frappecloud_billing): add str typehint to whitelisted endpoint

* fix: target_doc can be dict/json string

---------

Co-authored-by: Ankush Menat <ankush@frappe.io>
This commit is contained in:
Aarol D'Souza 2026-02-20 12:20:19 +05:30 committed by GitHub
parent 101a7f40b6
commit c55ff193a6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
24 changed files with 136 additions and 83 deletions

View file

@ -88,7 +88,7 @@ def get_default_path():
@frappe.whitelist() @frappe.whitelist()
def set_app_as_default(app_name): def set_app_as_default(app_name: str):
if frappe.db.get_value("User", frappe.session.user, "default_app") == app_name: if frappe.db.get_value("User", frappe.session.user, "default_app") == app_name:
frappe.db.set_value("User", frappe.session.user, "default_app", "") frappe.db.set_value("User", frappe.session.user, "default_app", "")
else: else:
@ -96,7 +96,7 @@ def set_app_as_default(app_name):
@frappe.whitelist() @frappe.whitelist()
def get_incomplete_setup_route(current_app, app_route): def get_incomplete_setup_route(current_app: str, app_route: str):
pending_apps = get_apps_with_incomplete_dependencies(current_app) pending_apps = get_apps_with_incomplete_dependencies(current_app)
if not pending_apps: if not pending_apps:

View file

@ -1,7 +1,7 @@
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors # Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
# License: MIT. See LICENSE # License: MIT. See LICENSE
from datetime import timedelta from datetime import datetime, timedelta
from dateutil.relativedelta import relativedelta from dateutil.relativedelta import relativedelta
@ -560,8 +560,8 @@ def make_auto_repeat(
doctype: str, doctype: str,
docname: str | int, docname: str | int,
frequency: str = "Daily", frequency: str = "Daily",
start_date: str | None = None, start_date: str | datetime | None = None,
end_date: str | None = None, end_date: str | datetime | None = None,
): ):
if not start_date: if not start_date:
start_date = getdate(today()) start_date = getdate(today())

View file

@ -2,7 +2,7 @@
# License: MIT. See LICENSE # License: MIT. See LICENSE
import json import json
import os import os
from typing import TYPE_CHECKING from typing import TYPE_CHECKING, Any
import frappe import frappe
import frappe.model import frappe.model
@ -25,18 +25,18 @@ Requests via FrappeClient are also handled here.
@frappe.whitelist() @frappe.whitelist()
def get_list( def get_list(
doctype, doctype: str,
fields=None, fields: str | list[str | dict[str, Any]] | None = None,
filters=None, filters: str | list | dict[str, Any] | None = None,
group_by=None, group_by: str | list[str] | None = None,
order_by=None, order_by: str | list[str] | None = None,
limit_start=None, limit_start: int | str | None = None,
limit_page_length=20, limit_page_length: int | str = 20,
parent=None, parent: str | None = None,
debug: bool = False, debug: bool | int = False,
as_dict: bool = True, as_dict: bool | int = True,
or_filters=None, or_filters: str | list[list] | dict[str, Any] | None = None,
expand=None, expand: str | list[str] | None = None,
): ):
"""Return a list of records by filters, fields, ordering and limit. """Return a list of records by filters, fields, ordering and limit.
@ -76,7 +76,12 @@ def get_list(
@frappe.whitelist() @frappe.whitelist()
def get_count(doctype, filters=None, debug=False, cache=False): def get_count(
doctype: str,
filters: str | list | dict[str, Any] | None = None,
debug: int | bool = False,
cache: int | bool = False,
):
from frappe.desk.reportview import get_count from frappe.desk.reportview import get_count
frappe.form_dict.doctype = doctype frappe.form_dict.doctype = doctype
@ -87,7 +92,12 @@ def get_count(doctype, filters=None, debug=False, cache=False):
@frappe.whitelist() @frappe.whitelist()
def get(doctype, name=None, filters=None, parent=None): def get(
doctype: str,
name: str | int | None = None,
filters: str | list | dict[str, Any] | None = None,
parent: str | None = None,
):
"""Return a document by name or filters. """Return a document by name or filters.
:param doctype: DocType of the document to be returned :param doctype: DocType of the document to be returned
@ -108,7 +118,14 @@ def get(doctype, name=None, filters=None, parent=None):
@frappe.whitelist() @frappe.whitelist()
def get_value(doctype, fieldname, filters=None, as_dict=True, debug=False, parent=None): def get_value(
doctype: str,
fieldname: str | list[str] | dict[str, Any],
filters: str | list | dict[str, Any] | None = None,
as_dict: int | bool = True,
debug: int | bool = False,
parent: str | None = None,
):
"""Return a value from a document. """Return a value from a document.
:param doctype: DocType to be queried :param doctype: DocType to be queried
@ -156,7 +173,7 @@ def get_value(doctype, fieldname, filters=None, as_dict=True, debug=False, paren
@frappe.whitelist() @frappe.whitelist()
def get_single_value(doctype, field): def get_single_value(doctype: str, field: str):
if not frappe.has_permission(doctype): if not frappe.has_permission(doctype):
frappe.throw(_("No permission for {0}").format(_(doctype)), frappe.PermissionError) frappe.throw(_("No permission for {0}").format(_(doctype)), frappe.PermissionError)
@ -164,7 +181,7 @@ def get_single_value(doctype, field):
@frappe.whitelist(methods=["POST", "PUT"]) @frappe.whitelist(methods=["POST", "PUT"])
def set_value(doctype, name, fieldname, value=None): def set_value(doctype: str, name: str | int, fieldname: str | dict[str, Any], value: Any | None = None):
"""Set a value using get_doc, group of values """Set a value using get_doc, group of values
:param doctype: DocType of the document :param doctype: DocType of the document
@ -201,7 +218,7 @@ def set_value(doctype, name, fieldname, value=None):
@frappe.whitelist(methods=["POST", "PUT"]) @frappe.whitelist(methods=["POST", "PUT"])
def insert(doc=None): def insert(doc: str | dict[str, Any] | None = None):
"""Insert a document """Insert a document
:param doc: JSON or dict object to be inserted""" :param doc: JSON or dict object to be inserted"""
@ -212,7 +229,7 @@ def insert(doc=None):
@frappe.whitelist(methods=["POST", "PUT"]) @frappe.whitelist(methods=["POST", "PUT"])
def insert_many(docs=None): def insert_many(docs: str | list[dict[str, Any]] | None = None):
"""Insert multiple documents """Insert multiple documents
:param docs: JSON or list of dict objects to be inserted in one request""" :param docs: JSON or list of dict objects to be inserted in one request"""
@ -226,7 +243,7 @@ def insert_many(docs=None):
@frappe.whitelist(methods=["POST", "PUT"]) @frappe.whitelist(methods=["POST", "PUT"])
def save(doc): def save(doc: str | dict[str, Any]):
"""Update (save) an existing document """Update (save) an existing document
:param doc: JSON or dict object with the properties of the document to be updated""" :param doc: JSON or dict object with the properties of the document to be updated"""
@ -240,7 +257,7 @@ def save(doc):
@frappe.whitelist(methods=["POST", "PUT"]) @frappe.whitelist(methods=["POST", "PUT"])
def rename_doc(doctype, old_name, new_name, merge=False): def rename_doc(doctype: str, old_name: str | int, new_name: str | int, merge: bool = False):
"""Rename document """Rename document
:param doctype: DocType of the document to be renamed :param doctype: DocType of the document to be renamed
@ -251,7 +268,7 @@ def rename_doc(doctype, old_name, new_name, merge=False):
@frappe.whitelist(methods=["POST", "PUT"]) @frappe.whitelist(methods=["POST", "PUT"])
def submit(doc): def submit(doc: str | dict[str, Any]):
"""Submit a document """Submit a document
:param doc: JSON or dict object to be submitted remotely""" :param doc: JSON or dict object to be submitted remotely"""
@ -265,7 +282,7 @@ def submit(doc):
@frappe.whitelist(methods=["POST", "PUT"]) @frappe.whitelist(methods=["POST", "PUT"])
def cancel(doctype, name): def cancel(doctype: str, name: str | int):
"""Cancel a document """Cancel a document
:param doctype: DocType of the document to be cancelled :param doctype: DocType of the document to be cancelled
@ -277,7 +294,7 @@ def cancel(doctype, name):
@frappe.whitelist(methods=["DELETE", "POST"]) @frappe.whitelist(methods=["DELETE", "POST"])
def delete(doctype, name): def delete(doctype: str, name: str | int):
"""Delete a remote document """Delete a remote document
:param doctype: DocType of the document to be deleted :param doctype: DocType of the document to be deleted
@ -286,7 +303,7 @@ def delete(doctype, name):
@frappe.whitelist(methods=["POST", "PUT"]) @frappe.whitelist(methods=["POST", "PUT"])
def bulk_update(docs): def bulk_update(docs: str):
"""Bulk update documents """Bulk update documents
:param docs: JSON list of documents to be updated remotely. Each document must have `docname` property""" :param docs: JSON list of documents to be updated remotely. Each document must have `docname` property"""
@ -305,7 +322,7 @@ def bulk_update(docs):
@frappe.whitelist() @frappe.whitelist()
def has_permission(doctype: str, docname: str, perm_type: str = "read"): def has_permission(doctype: str, docname: str | int, perm_type: str = "read"):
"""Return a JSON with data whether the document has the requested permission. """Return a JSON with data whether the document has the requested permission.
:param doctype: DocType of the document to be checked :param doctype: DocType of the document to be checked
@ -316,7 +333,7 @@ def has_permission(doctype: str, docname: str, perm_type: str = "read"):
@frappe.whitelist() @frappe.whitelist()
def get_doc_permissions(doctype: str, docname: str): def get_doc_permissions(doctype: str, docname: str | int):
"""Return an evaluated document permissions dict like `{"read":1, "write":1}`. """Return an evaluated document permissions dict like `{"read":1, "write":1}`.
:param doctype: DocType of the document to be evaluated :param doctype: DocType of the document to be evaluated
@ -327,7 +344,7 @@ def get_doc_permissions(doctype: str, docname: str):
@frappe.whitelist() @frappe.whitelist()
def get_password(doctype: str, name: str, fieldname: str): def get_password(doctype: str, name: str | int, fieldname: str):
"""Return a password type property. Only applicable for System Managers """Return a password type property. Only applicable for System Managers
:param doctype: DocType of the document that holds the password :param doctype: DocType of the document that holds the password
@ -351,14 +368,14 @@ def get_time_zone():
@frappe.whitelist(methods=["POST", "PUT"]) @frappe.whitelist(methods=["POST", "PUT"])
def attach_file( def attach_file(
filename=None, filename: str | None = None,
filedata=None, filedata: str | None = None,
doctype=None, doctype: str | None = None,
docname=None, docname: str | int | None = None,
folder=None, folder: str | None = None,
decode_base64=False, decode_base64: int | bool = False,
is_private=None, is_private: int | bool | None = None,
docfield=None, docfield: str | None = None,
): ):
"""Attach a file to Document """Attach a file to Document
@ -396,7 +413,7 @@ def attach_file(
@frappe.whitelist() @frappe.whitelist()
@http_cache(max_age=10 * 60) @http_cache(max_age=10 * 60)
def is_document_amended(doctype: str, docname: str): def is_document_amended(doctype: str, docname: str | int):
if frappe.permissions.has_permission(doctype): if frappe.permissions.has_permission(doctype):
try: try:
return frappe.db.exists(doctype, {"amended_from": docname}) return frappe.db.exists(doctype, {"amended_from": docname})
@ -409,7 +426,7 @@ def is_document_amended(doctype: str, docname: str):
@frappe.whitelist(methods=["GET", "POST"]) @frappe.whitelist(methods=["GET", "POST"])
def validate_link_and_fetch( def validate_link_and_fetch(
doctype: str, doctype: str,
docname: str, docname: str | int,
fields_to_fetch: list[str] | str | None = None, fields_to_fetch: list[str] | str | None = None,
# search_widget parameters # search_widget parameters
query: str | None = None, query: str | None = None,

View file

@ -88,7 +88,7 @@ class ConnectedApp(Document):
) )
@frappe.whitelist() @frappe.whitelist()
def initiate_web_application_flow(self, user=None, success_uri=None): def initiate_web_application_flow(self, user: str | None = None, success_uri: str | None = None):
"""Return an authorization URL for the user. Save state in Token Cache.""" """Return an authorization URL for the user. Save state in Token Cache."""
user = user or frappe.session.user user = user or frappe.session.user
oauth = self.get_oauth2_session(user, init=True) oauth = self.get_oauth2_session(user, init=True)
@ -184,7 +184,7 @@ class ConnectedApp(Document):
@frappe.whitelist(methods=["GET"], allow_guest=True) @frappe.whitelist(methods=["GET"], allow_guest=True)
def callback(code=None, state=None): def callback(code: str | None = None, state: str | None = None):
"""Handle client's code. """Handle client's code.
Called during the oauthorization flow by the remote oAuth2 server to Called during the oauthorization flow by the remote oAuth2 server to
@ -223,7 +223,7 @@ def callback(code=None, state=None):
@frappe.whitelist() @frappe.whitelist()
def has_token(connected_app, connected_user=None): def has_token(connected_app: str, connected_user: str | None = None):
app = frappe.get_doc("Connected App", connected_app) app = frappe.get_doc("Connected App", connected_app)
token_cache = app.get_token_cache(connected_user or frappe.session.user) token_cache = app.get_token_cache(connected_user or frappe.session.user)
return bool(token_cache and token_cache.get_password("access_token", False)) return bool(token_cache and token_cache.get_password("access_token", False))

View file

@ -192,7 +192,7 @@ def get_authentication_url(client_id=None, redirect_uri=None):
@frappe.whitelist() @frappe.whitelist()
def google_callback(code=None): def google_callback(code: str | None = None):
""" """
Authorization code is sent to callback as per the API configuration Authorization code is sent to callback as per the API configuration
""" """

View file

@ -49,7 +49,7 @@ class GoogleContacts(Document):
@frappe.whitelist(methods=["POST"]) @frappe.whitelist(methods=["POST"])
def authorize_access(g_contact, reauthorize=False, code=None): def authorize_access(g_contact: str, reauthorize: int | bool = False, code: str | None = None):
""" """
If no Authorization code get it from Google and then request for Refresh Token. If no Authorization code get it from Google and then request for Refresh Token.
Google Contact Name is set to flags to set_value after Authorization Code is obtained. Google Contact Name is set to flags to set_value after Authorization Code is obtained.
@ -88,7 +88,7 @@ def get_google_contacts_object(g_contact):
@frappe.whitelist() @frappe.whitelist()
def sync(g_contact=None): def sync(g_contact: str | None = None):
filters = {"enable": 1} filters = {"enable": 1}
if g_contact: if g_contact:

View file

@ -117,7 +117,7 @@ class SocialLoginKey(Document):
self.icon = f"/assets/frappe/icons/social/{icon_file}" self.icon = f"/assets/frappe/icons/social/{icon_file}"
@frappe.whitelist() @frappe.whitelist()
def get_social_login_provider(self, provider, initialize=False): def get_social_login_provider(self, provider: str, initialize: int | bool = False):
providers = {} providers = {}
providers["Office 365"] = { providers["Office 365"] = {

View file

@ -120,7 +120,7 @@ class Webhook(Document):
frappe.throw(_("Invalid Webhook Secret")) frappe.throw(_("Invalid Webhook Secret"))
@frappe.whitelist() @frappe.whitelist()
def preview_meets_condition(self, preview_document): def preview_meets_condition(self, preview_document: str):
if not self.condition: if not self.condition:
return _("Yes") return _("Yes")
try: try:
@ -132,7 +132,7 @@ class Webhook(Document):
return _("Yes") if met_condition else _("No") return _("Yes") if met_condition else _("No")
@frappe.whitelist() @frappe.whitelist()
def preview_request_body(self, preview_document): def preview_request_body(self, preview_document: str):
try: try:
doc = frappe.get_cached_doc(self.webhook_doctype, preview_document) doc = frappe.get_cached_doc(self.webhook_doctype, preview_document)
return frappe.as_json(get_webhook_data(doc, self)) return frappe.as_json(get_webhook_data(doc, self))

View file

@ -1,3 +1,5 @@
from typing import Any
import requests import requests
import frappe import frappe
@ -60,7 +62,7 @@ def current_site_info():
@frappe.whitelist() @frappe.whitelist()
def api(method, data=None): def api(method: str, data: str | dict[str, Any] | None = None):
if data is None: if data is None:
data = {} data = {}
request = requests.post( request = requests.post(

View file

@ -225,7 +225,7 @@ def get_openid_configuration():
@frappe.whitelist(allow_guest=True) @frappe.whitelist(allow_guest=True)
def introspect_token(token: str, token_type_hint=None): def introspect_token(token: str, token_type_hint: str | None = None):
if token_type_hint not in ["access_token", "refresh_token"]: if token_type_hint not in ["access_token", "refresh_token"]:
token_type_hint = "access_token" token_type_hint = "access_token"
try: try:

View file

@ -1424,7 +1424,7 @@ class Document(BaseDocument):
self.run_method("on_discard") self.run_method("on_discard")
@frappe.whitelist() @frappe.whitelist()
def rename(self, name: str | int, merge=False, force=False, validate_rename=True): def rename(self, name: str | int, merge: bool = False, force: bool = False, validate_rename: bool = True):
"""Rename the document to `name`. This transforms the current object.""" """Rename the document to `name`. This transforms the current object."""
return self._rename(name=name, merge=merge, force=force, validate_rename=validate_rename) return self._rename(name=name, merge=merge, force=force, validate_rename=validate_rename)
@ -1786,10 +1786,10 @@ class Document(BaseDocument):
@frappe.whitelist() @frappe.whitelist()
def add_comment( def add_comment(
self, self,
comment_type="Comment", comment_type: str = "Comment",
text=None, text: str | None = None,
comment_email=None, comment_email: str | None = None,
comment_by=None, comment_by: str | None = None,
): ):
"""Add a comment to this document. """Add a comment to this document.

View file

@ -5,11 +5,14 @@ import json
import frappe import frappe
from frappe import _ from frappe import _
from frappe.model import child_table_fields, default_fields, table_fields from frappe.model import child_table_fields, default_fields, table_fields
from frappe.model.document import Document
from frappe.utils import cstr from frappe.utils import cstr
@frappe.whitelist() @frappe.whitelist()
def make_mapped_doc(method, source_name, selected_children=None, args=None): def make_mapped_doc(
method: str, source_name: str, selected_children: str | None = None, args: str | None = None
):
"""Return the mapped document calling the given mapper method. """Return the mapped document calling the given mapper method.
Set `selected_children` as flags for the `get_mapped_doc` method. Set `selected_children` as flags for the `get_mapped_doc` method.
@ -30,7 +33,7 @@ def make_mapped_doc(method, source_name, selected_children=None, args=None):
@frappe.whitelist() @frappe.whitelist()
def map_docs(method, source_names, target_doc, args=None): def map_docs(method: str, source_names: str, target_doc: Document | dict | str, args: str | None = None):
"""Return the mapped document calling the given mapper method with each of the given source docs on the target doc. """Return the mapped document calling the given mapper method with each of the given source docs on the target doc.
:param args: Args as string to pass to the mapper method :param args: Args as string to pass to the mapper method

View file

@ -63,14 +63,14 @@ def sync_user_settings():
@frappe.whitelist() @frappe.whitelist()
def save(doctype, user_settings): def save(doctype: str, user_settings: str):
user_settings = json.loads(user_settings or "{}") user_settings = json.loads(user_settings or "{}")
update_user_settings(doctype, user_settings) update_user_settings(doctype, user_settings)
return user_settings return user_settings
@frappe.whitelist() @frappe.whitelist()
def get(doctype): def get(doctype: str):
return get_user_settings(doctype) return get_user_settings(doctype)

View file

@ -5,7 +5,7 @@ from __future__ import annotations
import json import json
from collections import defaultdict from collections import defaultdict
from typing import TYPE_CHECKING from typing import TYPE_CHECKING, Any
import frappe import frappe
from frappe import _ from frappe import _
@ -43,7 +43,7 @@ def get_workflow_name(doctype):
@frappe.whitelist() @frappe.whitelist()
def get_transitions( def get_transitions(
doc: Document | str | dict, workflow: Workflow = None, raise_exception: bool = False doc: Document | str | dict, workflow: Workflow | None = None, raise_exception: bool = False
) -> list[dict]: ) -> list[dict]:
"""Return list of possible transitions for the given doc""" """Return list of possible transitions for the given doc"""
from frappe.model.document import Document from frappe.model.document import Document
@ -117,7 +117,7 @@ def evaluate_workflow_value(value, evaluate_as_expression, doc):
@frappe.whitelist() @frappe.whitelist()
def apply_workflow(doc, action): def apply_workflow(doc: Document | str | dict, action: str):
"""Allow workflow action on the current doc""" """Allow workflow action on the current doc"""
doc = frappe.get_doc(frappe.parse_json(doc)) doc = frappe.get_doc(frappe.parse_json(doc))
doc.load_from_db() doc.load_from_db()
@ -228,7 +228,7 @@ def apply_workflow(doc, action):
@frappe.whitelist() @frappe.whitelist()
def can_cancel_document(doctype): def can_cancel_document(doctype: str):
workflow = get_workflow(doctype) workflow = get_workflow(doctype)
cancelling_states = [s.state for s in workflow.states if s.doc_status == "2"] cancelling_states = [s.state for s in workflow.states if s.doc_status == "2"]
if not cancelling_states: if not cancelling_states:
@ -312,7 +312,7 @@ def get_workflow_field_value(workflow_name, field):
@frappe.whitelist() @frappe.whitelist()
def bulk_workflow_approval(docnames, doctype, action): def bulk_workflow_approval(docnames: str, doctype: str, action: str):
docnames = json.loads(docnames) docnames = json.loads(docnames)
if len(docnames) < 20: if len(docnames) < 20:
_bulk_workflow_action(docnames, doctype, action) _bulk_workflow_action(docnames, doctype, action)
@ -407,7 +407,7 @@ def print_workflow_log(messages, title, doctype, indicator):
@frappe.whitelist() @frappe.whitelist()
def get_common_transition_actions(docs, doctype): def get_common_transition_actions(docs: str | list[dict[str, Any]], doctype: str):
common_actions = [] common_actions = []
if isinstance(docs, str): if isinstance(docs, str):
docs = json.loads(docs) docs = json.loads(docs)

View file

@ -21,7 +21,7 @@ class NetworkPrinterSettings(Document):
# end: auto-generated types # end: auto-generated types
@frappe.whitelist() @frappe.whitelist()
def get_printers_list(self, ip="127.0.0.1", port=631): def get_printers_list(self):
printer_list = [] printer_list = []
try: try:
import cups import cups

View file

@ -2,7 +2,7 @@ import frappe
@frappe.whitelist() @frappe.whitelist()
def get_print_settings_to_show(doctype, docname): def get_print_settings_to_show(doctype: str, docname: str):
doc = frappe.get_doc(doctype, docname) doc = frappe.get_doc(doctype, docname)
print_settings = frappe.get_single("Print Settings") print_settings = frappe.get_single("Print Settings")

View file

@ -2,7 +2,9 @@ import frappe
@frappe.whitelist() @frappe.whitelist()
def create_custom_format(doctype, name, based_on="Standard", beta=False): def create_custom_format(
doctype: str, name: str | int, based_on: str = "Standard", beta: str | int | bool = False
):
doc = frappe.new_doc("Print Format") doc = frappe.new_doc("Print Format")
doc.doc_type = doctype doc.doc_type = doctype
doc.name = name doc.name = name

View file

@ -364,7 +364,7 @@ def stop(*args, **kwargs):
@frappe.whitelist() @frappe.whitelist()
@do_not_record @do_not_record
@administrator_only @administrator_only
def get(uuid=None, *args, **kwargs): def get(uuid: str | None = None, *args, **kwargs):
if uuid: if uuid:
result = frappe.cache.hget(RECORDER_REQUEST_HASH, uuid) result = frappe.cache.hget(RECORDER_REQUEST_HASH, uuid)
else: else:

View file

@ -19,7 +19,18 @@ if TYPE_CHECKING:
@frappe.whitelist() @frappe.whitelist()
def add(doctype, name, user=None, read=1, write=0, submit=0, share=0, everyone=0, notify=0, **kwargs): def add(
doctype: str,
name: str | int,
user: str | None = None,
read: str | bool | int = 1,
write: str | bool | int = 0,
submit: str | bool | int = 0,
share: str | bool | int = 0,
everyone: str | bool | int = 0,
notify: str | bool | int = 0,
**kwargs,
):
"""Expose function without flags to the client-side""" """Expose function without flags to the client-side"""
return add_docshare( return add_docshare(
doctype, doctype,
@ -85,7 +96,14 @@ def remove(doctype, name, user, flags=None):
@frappe.whitelist() @frappe.whitelist()
def set_permission(doctype, name, user, permission_to, value=1, everyone=0): def set_permission(
doctype: str,
name: str | int,
user: str | None,
permission_to: str,
value: str | bool | int = 1,
everyone: str | bool | int = 0,
):
"""Expose function without flags to the client-side""" """Expose function without flags to the client-side"""
return set_docshare_permission(doctype, name, user, permission_to, value=value, everyone=everyone) return set_docshare_permission(doctype, name, user, permission_to, value=value, everyone=everyone)
@ -246,7 +264,7 @@ def check_share_permission(doctype, name, permissions=None, custom_perms=None):
def notify_assignment(shared_by, doctype, doc_name, everyone, notify=0): def notify_assignment(shared_by, doctype, doc_name, everyone, notify=0):
if not (shared_by and doctype and doc_name) or everyone or not notify: if not (shared_by and doctype and doc_name) or cint(everyone) or not cint(notify):
return return
from frappe.utils import get_fullname from frappe.utils import get_fullname

View file

@ -25,7 +25,9 @@ def get_limit():
@frappe.whitelist(allow_guest=True) @frappe.whitelist(allow_guest=True)
# @rate_limit(key="reference_name", limit=get_limit, seconds=60 * 60) # @rate_limit(key="reference_name", limit=get_limit, seconds=60 * 60)
def add_comment(comment, comment_email, comment_by, reference_doctype, reference_name, route): def add_comment(
comment: str, comment_email: str, comment_by: str, reference_doctype: str, reference_name: str, route: str
):
if frappe.session.user == "Guest": if frappe.session.user == "Guest":
allowed_doctypes = ["Web Page"] allowed_doctypes = ["Web Page"]
comments_permission_config = frappe.get_hooks("has_comment_permission") comments_permission_config = frappe.get_hooks("has_comment_permission")

View file

@ -249,7 +249,7 @@ class TestRenameDoc(IntegrationTestCase):
name = choice(self.available_documents) name = choice(self.available_documents)
new_name = f"{name}-{frappe.generate_hash(length=4)}" new_name = f"{name}-{frappe.generate_hash(length=4)}"
doc = frappe.get_doc(self.test_doctype, name) doc = frappe.get_doc(self.test_doctype, name)
doc.rename(new_name, merge=frappe.db.exists(self.test_doctype, new_name)) doc.rename(new_name, merge=bool(frappe.db.exists(self.test_doctype, new_name)))
self.assertEqual(doc.name, new_name) self.assertEqual(doc.name, new_name)
self.available_documents.append(new_name) self.available_documents.append(new_name)
self.available_documents.remove(name) self.available_documents.remove(name)

View file

@ -883,7 +883,7 @@ def deduplicate_messages(messages):
@frappe.whitelist() @frappe.whitelist()
def update_translations_for_source(source=None, translation_dict=None): def update_translations_for_source(source: str | None = None, translation_dict: str | None = None):
if not (source and translation_dict): if not (source and translation_dict):
return return

View file

@ -120,7 +120,7 @@ class Workflow(Document):
@frappe.whitelist() @frappe.whitelist()
def get_workflow_state_count(doctype, workflow_state_field, states): def get_workflow_state_count(doctype: str, workflow_state_field: str, states: str | list[str]):
frappe.has_permission(doctype=doctype, ptype="read", throw=True) frappe.has_permission(doctype=doctype, ptype="read", throw=True)
states = frappe.parse_json(states) states = frappe.parse_json(states)

View file

@ -1,6 +1,8 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# License: MIT. See LICENSE # License: MIT. See LICENSE
from datetime import datetime
import frappe import frappe
from frappe import _ from frappe import _
from frappe.desk.form.utils import get_pdf_link from frappe.desk.form.utils import get_pdf_link
@ -127,7 +129,14 @@ def process_workflow_actions(doc, state):
@frappe.whitelist(allow_guest=True) @frappe.whitelist(allow_guest=True)
def apply_action(action, doctype, docname, current_state, user=None, last_modified=None): def apply_action(
action: str,
doctype: str,
docname: str | int,
current_state: str,
user: str | None = None,
last_modified: str | datetime | None = None,
):
if not verify_request(): if not verify_request():
return return
@ -147,7 +156,7 @@ def apply_action(action, doctype, docname, current_state, user=None, last_modifi
@frappe.whitelist(allow_guest=True) @frappe.whitelist(allow_guest=True)
def confirm_action(doctype, docname, user, action): def confirm_action(doctype: str, docname: str | int, user: str, action: str):
if not verify_request(): if not verify_request():
return return