From 34ad0cf331f65a02b53314f432b3f82a0e7e2d35 Mon Sep 17 00:00:00 2001 From: Sagar Vora Date: Thu, 7 Jan 2021 10:57:08 +0530 Subject: [PATCH] fix: introduce frappe.controllers; clear global if cache is cleared; replace old references --- frappe/__init__.py | 1 + frappe/cache_manager.py | 10 ++++++++++ frappe/core/doctype/doctype/doctype.py | 8 +++----- frappe/model/base_document.py | 11 ++++------- frappe/tests/test_hooks.py | 4 ++-- 5 files changed, 20 insertions(+), 14 deletions(-) diff --git a/frappe/__init__.py b/frappe/__init__.py index 4040a38e62..f8ae6b4ec1 100644 --- a/frappe/__init__.py +++ b/frappe/__init__.py @@ -27,6 +27,7 @@ __version__ = '13.0.0-dev' __title__ = "Frappe Framework" local = Local() +controllers = {} class _dict(dict): """dict like object that exposes keys as attributes""" diff --git a/frappe/cache_manager.py b/frappe/cache_manager.py index 3b3d188999..ed5c7b64ad 100644 --- a/frappe/cache_manager.py +++ b/frappe/cache_manager.py @@ -72,6 +72,7 @@ def clear_document_cache(): frappe.cache().delete_key("document_cache") def clear_doctype_cache(doctype=None): + clear_controller_cache(doctype) cache = frappe.cache() if getattr(frappe.local, 'meta_cache') and (doctype in frappe.local.meta_cache): @@ -104,6 +105,15 @@ def clear_doctype_cache(doctype=None): # Clear all document's cache. To clear documents of a specific DocType document_cache should be restructured clear_document_cache() +def clear_controller_cache(doctype=None): + if not doctype: + del frappe.controllers + frappe.controllers = {} + return + + for site_controllers in frappe.controllers.values(): + site_controllers.pop(doctype, None) + def get_doctype_map(doctype, name, filters=None, order_by=None): cache = frappe.cache() cache_key = frappe.scrub(doctype) + '_map' diff --git a/frappe/core/doctype/doctype/doctype.py b/frappe/core/doctype/doctype/doctype.py index 3e283e1699..1daa7e8af7 100644 --- a/frappe/core/doctype/doctype/doctype.py +++ b/frappe/core/doctype/doctype/doctype.py @@ -5,7 +5,7 @@ from __future__ import unicode_literals import re, copy, os, shutil import json -from frappe.cache_manager import clear_user_cache +from frappe.cache_manager import clear_user_cache, clear_controller_cache # imports - third party imports import six @@ -408,13 +408,11 @@ class DocType(Document): if not frappe.flags.in_patch: self.rename_files_and_folders(old, new) - for site in frappe.utils.get_sites(): - frappe.cache().delete(f"{site}:doctype_classes", old) + clear_controller_cache(old) def after_delete(self): if not self.custom: - for site in frappe.utils.get_sites(): - frappe.cache().delete(f"{site}:doctype_classes", self.name) + clear_controller_cache(self.name) def rename_files_and_folders(self, old, new): # move files diff --git a/frappe/model/base_document.py b/frappe/model/base_document.py index 44394841d1..7a90ecaca5 100644 --- a/frappe/model/base_document.py +++ b/frappe/model/base_document.py @@ -26,14 +26,11 @@ max_positive_value = { DOCTYPES_FOR_DOCTYPE = ('DocType', 'DocField', 'DocPerm', 'DocType Action', 'DocType Link') -_classes = {} - def get_controller(doctype): """Returns the **class** object of the given DocType. For `custom` type, returns `frappe.model.document.Document`. :param doctype: DocType name as string.""" - global _classes def _get_controller(): from frappe.model.document import Document @@ -73,11 +70,11 @@ def get_controller(doctype): if frappe.local.dev_server: return _get_controller() - site_classes = _classes.setdefault(frappe.local.site, {}) - if doctype not in site_classes: - site_classes[doctype] = _get_controller() + site_controllers = frappe.controllers.setdefault(frappe.local.site, {}) + if doctype not in site_controllers: + site_controllers[doctype] = _get_controller() - return site_classes[doctype] + return site_controllers[doctype] class BaseDocument(object): ignore_in_getter = ("doctype", "_meta", "meta", "_table_fields", "_valid_columns") diff --git a/frappe/tests/test_hooks.py b/frappe/tests/test_hooks.py index fada861b79..ff71e2414c 100644 --- a/frappe/tests/test_hooks.py +++ b/frappe/tests/test_hooks.py @@ -5,6 +5,7 @@ from __future__ import unicode_literals import unittest import frappe from frappe.desk.doctype.todo.todo import ToDo +from frappe.cache_manager import clear_controller_cache class TestHooks(unittest.TestCase): def test_hooks(self): @@ -18,7 +19,6 @@ class TestHooks(unittest.TestCase): def test_override_doctype_class(self): from frappe import hooks - from frappe.model import base_document # Set hook hooks.override_doctype_class = { @@ -27,7 +27,7 @@ class TestHooks(unittest.TestCase): # Clear cache frappe.cache().delete_value('app_hooks') - base_document._classes = {} + clear_controller_cache('ToDo') todo = frappe.get_doc(doctype='ToDo', description='asdf') self.assertTrue(isinstance(todo, CustomToDo))