From 6e818caa59080db662cd84504c220f49a88f4ca9 Mon Sep 17 00:00:00 2001 From: phot0n Date: Sun, 3 Jul 2022 13:17:30 +0530 Subject: [PATCH 01/10] ci: use different reference for fetched label in has_label --- .github/helper/roulette.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/helper/roulette.py b/.github/helper/roulette.py index ad2fd829dd..178526592f 100644 --- a/.github/helper/roulette.py +++ b/.github/helper/roulette.py @@ -9,7 +9,7 @@ from functools import lru_cache @lru_cache(maxsize=None) -def fetch_pr_data(pr_number, repo, endpoint): +def fetch_pr_data(pr_number, repo, endpoint=""): api_url = f"https://api.github.com/repos/{repo}/pulls/{pr_number}" if endpoint: @@ -37,7 +37,7 @@ def has_run_ui_tests_label(pr_number, repo="frappe/frappe"): return has_label(pr_number, "Run UI Tests", repo) def has_label(pr_number, label, repo="frappe/frappe"): - return any([label["name"] for label in fetch_pr_data(pr_number, repo, "")["labels"] if label["name"] == label]) + return any([fetched_label["name"] for fetched_label in fetch_pr_data(pr_number, repo)["labels"] if fetched_label["name"] == label]) def is_py(file): return file.endswith("py") From b0cea224c8b91ef01bbcf779463c41ad6861f7c6 Mon Sep 17 00:00:00 2001 From: phot0n Date: Sun, 3 Jul 2022 21:03:44 +0530 Subject: [PATCH 02/10] ci: consider svg as docs as well --- .github/helper/roulette.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/helper/roulette.py b/.github/helper/roulette.py index 178526592f..c240443e9a 100644 --- a/.github/helper/roulette.py +++ b/.github/helper/roulette.py @@ -49,7 +49,7 @@ def is_frontend_code(file): return file.lower().endswith((".css", ".scss", ".less", ".sass", ".styl", ".js", ".ts", ".vue")) def is_docs(file): - regex = re.compile(r'\.(md|png|jpg|jpeg|csv)$|^.github|LICENSE') + regex = re.compile(r'\.(md|png|jpg|jpeg|csv|svg)$|^.github|LICENSE') return bool(regex.search(file)) From e9a9496ebc698359d9c2c5e871c04a83c3649bbe Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Sat, 2 Jul 2022 20:21:09 +0530 Subject: [PATCH 03/10] fix: duplicate tracebacks in console --- frappe/app.py | 8 +++---- frappe/desk/form/load.py | 1 - frappe/desk/form/save.py | 45 ++++++++++++++++------------------------ 3 files changed, 22 insertions(+), 32 deletions(-) diff --git a/frappe/app.py b/frappe/app.py index d05febba9e..b9db59cdb1 100644 --- a/frappe/app.py +++ b/frappe/app.py @@ -222,10 +222,6 @@ def handle_exception(e): or (frappe.local.request.path.startswith("/api/") and not accept_header.startswith("text")) ) - if frappe.conf.get("developer_mode"): - # don't fail silently - print(frappe.get_traceback()) - if respond_as_json: # handle ajax responses first # if the request is ajax, send back the trace or error message @@ -289,6 +285,10 @@ def handle_exception(e): if return_as_message: response = get_response("message", http_status_code=http_status_code) + if frappe.conf.get("developer_mode") and not respond_as_json: + # don't fail silently for non-json response errors + print(frappe.get_traceback()) + return response diff --git a/frappe/desk/form/load.py b/frappe/desk/form/load.py index 9e3a850bb0..d32f8f6db8 100644 --- a/frappe/desk/form/load.py +++ b/frappe/desk/form/load.py @@ -50,7 +50,6 @@ def getdoc(doctype, name, user=None): get_docinfo(doc) except Exception: - frappe.errprint(frappe.utils.get_traceback()) raise doc.add_seen() diff --git a/frappe/desk/form/save.py b/frappe/desk/form/save.py index cc3865bc60..f3e7b6294f 100644 --- a/frappe/desk/form/save.py +++ b/frappe/desk/form/save.py @@ -10,42 +10,33 @@ from frappe.desk.form.load import run_onload @frappe.whitelist() def savedocs(doc, action): """save / submit / update doclist""" - try: - doc = frappe.get_doc(json.loads(doc)) - set_local_name(doc) + doc = frappe.get_doc(json.loads(doc)) + set_local_name(doc) - # action - doc.docstatus = {"Save": 0, "Submit": 1, "Update": 1, "Cancel": 2}[action] + # action + doc.docstatus = {"Save": 0, "Submit": 1, "Update": 1, "Cancel": 2}[action] - if doc.docstatus == 1: - doc.submit() - else: - doc.save() + if doc.docstatus == 1: + doc.submit() + else: + doc.save() - # update recent documents - run_onload(doc) - send_updated_docs(doc) + # update recent documents + run_onload(doc) + send_updated_docs(doc) - frappe.msgprint(frappe._("Saved"), indicator="green", alert=True) - except Exception: - frappe.errprint(frappe.utils.get_traceback()) - raise + frappe.msgprint(frappe._("Saved"), indicator="green", alert=True) @frappe.whitelist() def cancel(doctype=None, name=None, workflow_state_fieldname=None, workflow_state=None): """cancel a doclist""" - try: - doc = frappe.get_doc(doctype, name) - if workflow_state_fieldname and workflow_state: - doc.set(workflow_state_fieldname, workflow_state) - doc.cancel() - send_updated_docs(doc) - frappe.msgprint(frappe._("Cancelled"), indicator="red", alert=True) - - except Exception: - frappe.errprint(frappe.utils.get_traceback()) - raise + doc = frappe.get_doc(doctype, name) + if workflow_state_fieldname and workflow_state: + doc.set(workflow_state_fieldname, workflow_state) + doc.cancel() + send_updated_docs(doc) + frappe.msgprint(frappe._("Cancelled"), indicator="red", alert=True) def send_updated_docs(doc): From c12b52a259cf7bcd32398304969bd61da5959220 Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Sat, 2 Jul 2022 20:26:21 +0530 Subject: [PATCH 04/10] refactor: use frappe.get_system_settings Not sure why this needs YET ANOTHER separate cache. --- frappe/database/database.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/frappe/database/database.py b/frappe/database/database.py index 09d3424837..f40e9fe2ed 100644 --- a/frappe/database/database.py +++ b/frappe/database/database.py @@ -1157,10 +1157,7 @@ class Database: return INDEX_PATTERN.sub(r"", index_name) def get_system_setting(self, key): - def _load_system_settings(): - return self.get_singles_dict("System Settings") - - return frappe.cache().get_value("system_settings", _load_system_settings).get(key) + return frappe.get_system_settings(key) def close(self): """Close database connection.""" From 06ce1f33ec0aac7b6d6281911fd70e99999120b7 Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Mon, 4 Jul 2022 11:59:54 +0530 Subject: [PATCH 05/10] refactor: remove unnecessary exception handling --- frappe/desk/form/load.py | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/frappe/desk/form/load.py b/frappe/desk/form/load.py index d32f8f6db8..898c6461e9 100644 --- a/frappe/desk/form/load.py +++ b/frappe/desk/form/load.py @@ -33,24 +33,20 @@ def getdoc(doctype, name, user=None): if not frappe.db.exists(doctype, name): return [] - try: - doc = frappe.get_doc(doctype, name) - run_onload(doc) - - if not doc.has_permission("read"): - frappe.flags.error_message = _("Insufficient Permission for {0}").format( - frappe.bold(doctype + " " + name) - ) - raise frappe.PermissionError(("read", doctype, name)) + doc = frappe.get_doc(doctype, name) + run_onload(doc) - doc.apply_fieldlevel_read_permissions() + if not doc.has_permission("read"): + frappe.flags.error_message = _("Insufficient Permission for {0}").format( + frappe.bold(doctype + " " + name) + ) + raise frappe.PermissionError(("read", doctype, name)) - # add file list - doc.add_viewed() - get_docinfo(doc) + doc.apply_fieldlevel_read_permissions() - except Exception: - raise + # add file list + doc.add_viewed() + get_docinfo(doc) doc.add_seen() set_link_titles(doc) From 234c8beed6ab463c5d7737e2c53ec0d836a889c8 Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Mon, 4 Jul 2022 12:09:03 +0530 Subject: [PATCH 06/10] ci: faster patch test (#17386) * ci: slightly faster patch test This workflow doesn't seem to properly cache built versions :) * ci: bump pyenv action to latest version latest version has fix for tool cache [skip ci] --- .github/workflows/patch-mariadb-tests.yml | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/.github/workflows/patch-mariadb-tests.yml b/.github/workflows/patch-mariadb-tests.yml index 0c9fe2bb8a..523ff2d9f1 100644 --- a/.github/workflows/patch-mariadb-tests.yml +++ b/.github/workflows/patch-mariadb-tests.yml @@ -31,9 +31,9 @@ jobs: uses: actions/checkout@v3 - name: Setup Python - uses: "gabrielfalcao/pyenv-action@v9" + uses: "gabrielfalcao/pyenv-action@v10" with: - versions: 3.10:latest, 3.7:latest, 2.7:latest + versions: 3.10:latest, 3.7:latest - name: Setup Node uses: actions/setup-node@v3 @@ -120,14 +120,10 @@ jobs: cd apps/frappe/ git remote set-url upstream https://github.com/frappe/frappe.git + pyenv global $(pyenv versions | grep '3.7') for version in $(seq 12 13) do echo "Updating to v$version" - if [ $version == 12 ]; then - pyenv global $(pyenv versions | grep '2.7') - elif [ $version == 13 ]; then - pyenv global $(pyenv versions | grep '3.7') - fi branch_name="version-$version-hotfix" git fetch --depth 1 upstream $branch_name:$branch_name git checkout -q -f $branch_name From 862d4625be84aa421003e1c225312bf9bbd9af94 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Mon, 4 Jul 2022 13:19:55 +0530 Subject: [PATCH 07/10] fix: Retain value in the field instance when field is rendered on a dialog w/o doc --- frappe/public/js/frappe/form/controls/base_control.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/frappe/public/js/frappe/form/controls/base_control.js b/frappe/public/js/frappe/form/controls/base_control.js index f491fb1427..73831d493b 100644 --- a/frappe/public/js/frappe/form/controls/base_control.js +++ b/frappe/public/js/frappe/form/controls/base_control.js @@ -226,13 +226,16 @@ frappe.ui.form.Control = class BaseControl { } } set_model_value(value) { - if(this.frm) { + if (this.frm) { this.last_value = value; return frappe.model.set_value(this.doctype, this.docname, this.df.fieldname, value, this.df.fieldtype); } else { - if(this.doc) { + if (this.doc) { this.doc[this.df.fieldname] = value; + } else { + // case where input is rendered on dialog where doc is not maintained + this.value = value; } this.set_input(value); return Promise.resolve(); From 60c48193732905e8eab7179decdc75845c406fd4 Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Mon, 4 Jul 2022 13:39:56 +0530 Subject: [PATCH 08/10] refactor: safer binding of outer scope in closures (#17389) --- frappe/core/doctype/doctype/doctype.py | 8 ++++---- frappe/model/naming.py | 5 ++++- frappe/utils/error.py | 3 ++- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/frappe/core/doctype/doctype/doctype.py b/frappe/core/doctype/doctype/doctype.py index 40890e2a31..dbbbbc521a 100644 --- a/frappe/core/doctype/doctype/doctype.py +++ b/frappe/core/doctype/doctype/doctype.py @@ -652,14 +652,14 @@ class DocType(Document): remaining_field_names = [f.fieldname for f in self.fields] for fieldname in old_field_names: - field_dict = list(filter(lambda d: d["fieldname"] == fieldname, docdict["fields"])) + field_dict = [f for f in docdict["fields"] if f["fieldname"] == fieldname] if field_dict: new_field_dicts.append(field_dict[0]) if fieldname in remaining_field_names: remaining_field_names.remove(fieldname) for fieldname in remaining_field_names: - field_dict = list(filter(lambda d: d["fieldname"] == fieldname, docdict["fields"])) + field_dict = [f for f in docdict["fields"] if f["fieldname"] == fieldname] new_field_dicts.append(field_dict[0]) docdict["fields"] = new_field_dicts @@ -674,14 +674,14 @@ class DocType(Document): remaining_field_names = [f["fieldname"] for f in docdict.get("fields", [])] for fieldname in docdict.get("field_order"): - field_dict = list(filter(lambda d: d["fieldname"] == fieldname, docdict.get("fields", []))) + field_dict = [f for f in docdict.get("fields", []) if f["fieldname"] == fieldname] if field_dict: new_field_dicts.append(field_dict[0]) if fieldname in remaining_field_names: remaining_field_names.remove(fieldname) for fieldname in remaining_field_names: - field_dict = list(filter(lambda d: d["fieldname"] == fieldname, docdict.get("fields", []))) + field_dict = [f for f in docdict.get("fields", []) if f["fieldname"] == fieldname] new_field_dicts.append(field_dict[0]) docdict["fields"] = new_field_dicts diff --git a/frappe/model/naming.py b/frappe/model/naming.py index bae40c68c1..f7dbe23548 100644 --- a/frappe/model/naming.py +++ b/frappe/model/naming.py @@ -87,7 +87,10 @@ class NamingSeries: for count in range(1, 4): def fake_counter(_prefix, digits): - return str(count).zfill(digits) + # ignore B023: binding `count` is not necessary because + # function is evaluated immediately and it can not be done + # because of function signature requirement + return str(count).zfill(digits) # noqa: B023 generated_names.append(parse_naming_series(self.series, doc=doc, number_generator=fake_counter)) return generated_names diff --git a/frappe/utils/error.py b/frappe/utils/error.py index 94b3cf3b2c..92f99a05e1 100644 --- a/frappe/utils/error.py +++ b/frappe/utils/error.py @@ -85,7 +85,8 @@ def get_snapshot(exception, context=10): def reader(lnum=[lnum]): # noqa try: - return linecache.getline(file, lnum[0]) + # B023: function is evaluated immediately, binding not necessary + return linecache.getline(file, lnum[0]) # noqa: B023 finally: lnum[0] += 1 From 4e6ea5b554b482b9639a3adcebae9c67419105b2 Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Mon, 4 Jul 2022 16:27:57 +0530 Subject: [PATCH 09/10] fix: handle `None` as amount in fmt_money (#17395) --- frappe/tests/test_fmt_money.py | 1 + frappe/utils/data.py | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/frappe/tests/test_fmt_money.py b/frappe/tests/test_fmt_money.py index c27c13ad3b..275b1065f2 100644 --- a/frappe/tests/test_fmt_money.py +++ b/frappe/tests/test_fmt_money.py @@ -95,6 +95,7 @@ class TestFmtMoney(unittest.TestCase): def test_custom_fmt_money_format(self): self.assertEqual(fmt_money(100000, format="#,###.##"), "100,000.00") + self.assertEqual(fmt_money(None, format="#,###.##"), "0.00") if __name__ == "__main__": diff --git a/frappe/utils/data.py b/frappe/utils/data.py index 7f590ed5e6..92b390510e 100644 --- a/frappe/utils/data.py +++ b/frappe/utils/data.py @@ -1111,7 +1111,7 @@ def parse_val(v): def fmt_money( - amount: str | float | int, + amount: str | float | int | None, precision: int | None = None, currency: str | None = None, format: str | None = None, @@ -1135,6 +1135,9 @@ def fmt_money( if isinstance(amount, str): amount = flt(amount, precision) + if amount is None: + amount = 0 + if decimal_str: decimals_after = str(round(amount % 1, precision)) parts = decimals_after.split(".") From 87f77d4e8dd1f48fd35a9a2b6b1f9f0a55e0c741 Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Mon, 4 Jul 2022 16:46:06 +0530 Subject: [PATCH 10/10] fix: make language, source, translation mandatory (#17396) Translation doesn't make sense without these three fields --- frappe/core/doctype/translation/translation.json | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/frappe/core/doctype/translation/translation.json b/frappe/core/doctype/translation/translation.json index 560f3b2ce2..68b83ed5d9 100644 --- a/frappe/core/doctype/translation/translation.json +++ b/frappe/core/doctype/translation/translation.json @@ -1,6 +1,4 @@ { - "_comments": "[]", - "_liked_by": "[]", "actions": [], "allow_import": 1, "autoname": "hash", @@ -26,6 +24,7 @@ "fieldtype": "Link", "label": "Language", "options": "Language", + "reqd": 1, "search_index": 1 }, { @@ -72,20 +71,23 @@ "description": "If your data is in HTML, please copy paste the exact HTML code with the tags.", "fieldname": "source_text", "fieldtype": "Code", - "label": "Source Text" + "label": "Source Text", + "reqd": 1 }, { "fieldname": "translated_text", "fieldtype": "Code", "in_list_view": 1, - "label": "Translated Text" + "label": "Translated Text", + "reqd": 1 } ], "links": [], - "modified": "2021-12-31 10:19:52.541055", + "modified": "2022-07-04 06:53:54.997004", "modified_by": "Administrator", "module": "Core", "name": "Translation", + "naming_rule": "Random", "owner": "Administrator", "permissions": [ { @@ -103,6 +105,7 @@ ], "sort_field": "modified", "sort_order": "DESC", + "states": [], "title_field": "source_text", "track_changes": 1 } \ No newline at end of file