fix!: Document.has_value_changed returns Truthy or False

- Return changed value to avoid re-accessing previous object & it's
   attribute
 - Wrap returned value as Truthy to avoid breaking change in API
This commit is contained in:
Gavin D'souza 2024-05-07 17:19:01 +02:00
parent 10f0f0d2e9
commit ffbf7fb9d1
No known key found for this signature in database
GPG key ID: 5413A43FBD450A34
3 changed files with 24 additions and 4 deletions

View file

@ -115,7 +115,7 @@ class ServerScript(Document):
if self.script_type != "Scheduler Event" or (
(previous_script_type := self.has_value_changed("script_type"))
# True will be sent if its a new record
and previous_script_type not in (True, "Scheduler Event")
and previous_script_type.value not in (True, "Scheduler Event")
):
return

View file

@ -21,7 +21,7 @@ from frappe.model.naming import set_new_name, validate_name
from frappe.model.utils import is_virtual_doctype
from frappe.model.workflow import set_workflow_state_on_action, validate_workflow
from frappe.types import DF
from frappe.utils import compare, cstr, date_diff, file_lock, flt, now
from frappe.utils import Truthy, compare, cstr, date_diff, file_lock, flt, now
from frappe.utils.data import get_absolute_url, get_datetime, get_timedelta, getdate
from frappe.utils.global_search import update_global_search
@ -468,7 +468,7 @@ class Document(BaseDocument):
previous = self.get_doc_before_save()
if not previous:
return True
return Truthy(context="New Document")
previous_value = previous.get(fieldname)
current_value = self.get(fieldname)
@ -480,7 +480,10 @@ class Document(BaseDocument):
elif isinstance(previous_value, timedelta):
current_value = get_timedelta(current_value)
return previous_value != current_value
if previous_value != current_value:
return Truthy(value=previous_value)
return False
def set_new_name(self, force=False, set_name=None, set_child_names=True):
"""Calls `frappe.naming.set_new_name` for parent and child docs."""

View file

@ -42,6 +42,8 @@ EMAIL_MATCH_PATTERN = re.compile(
re.IGNORECASE,
)
UNSET = object()
def get_fullname(user=None):
"""get the full name (first name + last name) of the user from User"""
@ -1166,3 +1168,18 @@ class CallbackManager:
def reset(self):
self._functions.clear()
class Truthy:
def __init__(self, value=UNSET, context=UNSET):
self.value = value
self.context = context
def __bool__(self):
return True
def __repr__(self) -> str:
_val = "UNSET" if self.value is UNSET else self.value
_ctx = "UNSET" if self.context is UNSET else self.context
return f"Truthy(value={_val}, context={_ctx})"