From 22cee6c5f7c14f9e4e48e1f4a55ebad8a944c915 Mon Sep 17 00:00:00 2001
From: Julien Muchembled <jm@nexedi.com>
Date: Tue, 14 Sep 2010 13:55:56 +0000
Subject: [PATCH] Deprecate passing a parameter to getTransactionalVariable

getTransactionalVariable has always been implemented to return a global
cache object (1 per thread): old implementation used the given context only to
have access to the portal.

So we enforce this with a warning to make sure people don't expect retrieving
1 cache object per given context.

git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@38366 20353a03-c40f-0410-a6d1-a30d3c3de9de
---
 product/CMFActivity/ActiveObject.py                 |  6 +++---
 product/CMFActivity/Activity/SQLBase.py             |  2 +-
 product/CMFActivity/ActivityRuntimeEnvironment.py   |  2 +-
 product/ERP5/Document/Amount.py                     |  2 +-
 product/ERP5/Document/AppliedRule.py                |  4 ++--
 product/ERP5/Document/BPMBuilder.py                 |  6 +++---
 product/ERP5/Document/Document.py                   |  2 +-
 product/ERP5/Document/SimulationMovement.py         |  4 ++--
 product/ERP5/ERP5Site.py                            |  8 ++++----
 product/ERP5/mixin/cached_convertable.py            |  4 ++--
 product/ERP5/mixin/document.py                      |  4 ++--
 product/ERP5Catalog/CatalogTool.py                  |  2 +-
 product/ERP5Form/PreferenceTool.py                  |  2 +-
 product/ERP5Form/ProxyField.py                      |  4 ++--
 product/ERP5Form/Tool/SelectionTool.py              |  4 ++--
 product/ERP5Type/Base.py                            | 12 ++++++------
 product/ERP5Type/Cache.py                           |  2 +-
 product/ERP5Type/TransactionalVariable.py           |  8 +++++++-
 product/ERP5Type/Utils.py                           |  4 ++--
 product/ERP5Type/tests/testTransactionalVariable.py |  6 +++---
 product/ZSQLCatalog/SQLCatalog.py                   |  4 ++--
 21 files changed, 49 insertions(+), 43 deletions(-)

diff --git a/product/CMFActivity/ActiveObject.py b/product/CMFActivity/ActiveObject.py
index e213edebf0..5d1f33b6d3 100644
--- a/product/CMFActivity/ActiveObject.py
+++ b/product/CMFActivity/ActiveObject.py
@@ -98,7 +98,7 @@ class ActiveObject(ExtensionClass.Base):
           kw[k] = v
 
     # Get default parameters from a transactional variable.
-    tv = getTransactionalVariable(self)
+    tv = getTransactionalVariable()
     key = ('default_activate_parameter', id(aq_base(self)))
     try:
       for k, v in tv[key].iteritems():
@@ -173,14 +173,14 @@ class ActiveObject(ExtensionClass.Base):
     # This method sets the default keyword parameters to activate. This is
     # useful when you need to specify special parameters implicitly (e.g. to
     # reindexObject).
-    tv = getTransactionalVariable(self)
+    tv = getTransactionalVariable()
     key = ('default_activate_parameter', id(aq_base(self)))
     tv[key] = kw
 
   def getDefaultActivateParameterDict(self, inherit_placeless=True):
     # This method returns default activate parameters to self.
     # The result can be either a dict object or None.
-    tv = getTransactionalVariable(self)
+    tv = getTransactionalVariable()
     if inherit_placeless:
       placeless = tv.get(('default_activate_parameter', ))
       if placeless is not None:
diff --git a/product/CMFActivity/Activity/SQLBase.py b/product/CMFActivity/Activity/SQLBase.py
index 9cc05053d1..0d7383d0de 100644
--- a/product/CMFActivity/Activity/SQLBase.py
+++ b/product/CMFActivity/Activity/SQLBase.py
@@ -322,7 +322,7 @@ class SQLBase:
       # So all connectors must be committed now that we have selected
       # everything needed from MySQL to get a fresh view of ZODB objects.
       transaction.commit()
-      tv = getTransactionalVariable(None)
+      tv = getTransactionalVariable()
       tv['activity_runtime_environment'] = activity_runtime_environment
       # Try to invoke
       try:
diff --git a/product/CMFActivity/ActivityRuntimeEnvironment.py b/product/CMFActivity/ActivityRuntimeEnvironment.py
index ea8b483995..ac145b7a25 100644
--- a/product/CMFActivity/ActivityRuntimeEnvironment.py
+++ b/product/CMFActivity/ActivityRuntimeEnvironment.py
@@ -4,7 +4,7 @@ def getActivityRuntimeEnvironment():
   """
     Raises KeyError if called outside activity.
   """
-  return getTransactionalVariable(None)['activity_runtime_environment']
+  return getTransactionalVariable()['activity_runtime_environment']
 
 def _getActivityRuntimeEnvironment():
   try:
diff --git a/product/ERP5/Document/Amount.py b/product/ERP5/Document/Amount.py
index b47a465cbb..b6552fe919 100644
--- a/product/ERP5/Document/Amount.py
+++ b/product/ERP5/Document/Amount.py
@@ -421,7 +421,7 @@ class Amount(Base, Variated):
     # Stop any recursive call to this method. This happens when a Path
     # does not have base unit price locally, so it looks it up, and
     # each path of a predicate list does the same again.
-    tv = getTransactionalVariable(self)
+    tv = getTransactionalVariable()
     key = '_getBaseUnitPrice'
     if key in tv:
       return
diff --git a/product/ERP5/Document/AppliedRule.py b/product/ERP5/Document/AppliedRule.py
index 359cddc832..fea1ee0033 100644
--- a/product/ERP5/Document/AppliedRule.py
+++ b/product/ERP5/Document/AppliedRule.py
@@ -98,7 +98,7 @@ class AppliedRule(XMLObject):
         An applied rule can be expanded only if its parent movement
         is expanded.
       """
-      tv = getTransactionalVariable(self)
+      tv = getTransactionalVariable()
       cache = tv.setdefault(TREE_DELIVERED_CACHE_KEY, {})
       cache_enabled = cache.get(TREE_DELIVERED_CACHE_ENABLED, 0)
 
@@ -247,7 +247,7 @@ class AppliedRule(XMLObject):
 
       see SimulationMovement._isTreeDelivered
       """
-      tv = getTransactionalVariable(self)
+      tv = getTransactionalVariable()
       cache = tv.setdefault(TREE_DELIVERED_CACHE_KEY, {})
       cache_enabled = cache.get(TREE_DELIVERED_CACHE_ENABLED, 0)
 
diff --git a/product/ERP5/Document/BPMBuilder.py b/product/ERP5/Document/BPMBuilder.py
index c36cae4f9c..c37bd8cc6a 100644
--- a/product/ERP5/Document/BPMBuilder.py
+++ b/product/ERP5/Document/BPMBuilder.py
@@ -762,16 +762,16 @@ class BPMBuilder(Alarm):
     return obj
 
   def _isUpdated(self, obj, level):
-    tv = getTransactionalVariable(self)
+    tv = getTransactionalVariable()
     return level in tv['builder_processed_list'].get(obj, [])
 
   def _setUpdated(self, obj, level):
-    tv = getTransactionalVariable(self)
+    tv = getTransactionalVariable()
     if tv.get('builder_processed_list', None) is None:
       self._resetUpdated()
     tv['builder_processed_list'][obj] = \
        tv['builder_processed_list'].get(obj, []) + [level]
 
   def _resetUpdated(self):
-    tv = getTransactionalVariable(self)
+    tv = getTransactionalVariable()
     tv['builder_processed_list'] = {}
diff --git a/product/ERP5/Document/Document.py b/product/ERP5/Document/Document.py
index e5a7d7b7ee..606a61e20a 100644
--- a/product/ERP5/Document/Document.py
+++ b/product/ERP5/Document/Document.py
@@ -357,7 +357,7 @@ class Document(DocumentExtensibleTraversableMixin, XMLObject, UrlMixIn, CachedCo
       NOTE: passing a group_by parameter may be useful at a
       later stage of the implementation.
     """
-    tv = getTransactionalVariable(self) # XXX Performance improvement required
+    tv = getTransactionalVariable() # XXX Performance improvement required
     cache_key = ('getImplicitSuccessorValueList', self.getPhysicalPath())
     try:
       return tv[cache_key]
diff --git a/product/ERP5/Document/SimulationMovement.py b/product/ERP5/Document/SimulationMovement.py
index e8f17dd78e..df1b61682e 100644
--- a/product/ERP5/Document/SimulationMovement.py
+++ b/product/ERP5/Document/SimulationMovement.py
@@ -231,7 +231,7 @@ class SimulationMovement(Movement, PropertyRecordableMixin):
     """
     portal_rules = getToolByName(self.getPortalObject(), 'portal_rules')
 
-    tv = getTransactionalVariable(self)
+    tv = getTransactionalVariable()
     cache = tv.setdefault(TREE_DELIVERED_CACHE_KEY, {})
     cache_enabled = cache.get(TREE_DELIVERED_CACHE_ENABLED, 0)
 
@@ -520,7 +520,7 @@ class SimulationMovement(Movement, PropertyRecordableMixin):
 
     see AppliedRule._isTreeDelivered
     """
-    tv = getTransactionalVariable(self)
+    tv = getTransactionalVariable()
     cache = tv.setdefault(TREE_DELIVERED_CACHE_KEY, {})
     cache_enabled = cache.get(TREE_DELIVERED_CACHE_ENABLED, 0)
 
diff --git a/product/ERP5/ERP5Site.py b/product/ERP5/ERP5Site.py
index 2a41da97a1..4c3c446623 100644
--- a/product/ERP5/ERP5Site.py
+++ b/product/ERP5/ERP5Site.py
@@ -1278,7 +1278,7 @@ class ERP5Site(FolderMixIn, CMFSite):
     # This method sets the default keyword parameters to reindex. This is useful
     # when you need to specify special parameters implicitly (e.g. to reindexObject).
     # Those parameters will affect all reindex calls, not just ones on self.
-    tv = getTransactionalVariable(self)
+    tv = getTransactionalVariable()
     key = ('default_reindex_parameter', )
     tv[key] = kw
 
@@ -1287,7 +1287,7 @@ class ERP5Site(FolderMixIn, CMFSite):
     # This method sets the default keyword parameters to activate. This is useful
     # when you need to specify special parameters implicitly (e.g. to reindexObject).
     # Those parameters will affect all activate calls, not just ones on self.
-    tv = getTransactionalVariable(self)
+    tv = getTransactionalVariable()
     key = ('default_activate_parameter', )
     tv[key] = kw
 
@@ -1295,7 +1295,7 @@ class ERP5Site(FolderMixIn, CMFSite):
   def getPlacelessDefaultReindexParameters(self):
     # This method returns default reindex parameters to self.
     # The result can be either a dict object or None.
-    tv = getTransactionalVariable(self)
+    tv = getTransactionalVariable()
     key = ('default_reindex_parameter', )
     return tv.get(key)
 
@@ -1303,7 +1303,7 @@ class ERP5Site(FolderMixIn, CMFSite):
   def getPlacelessDefaultActivateParameters(self):
     # This method returns default activate parameters to self.
     # The result can be either a dict object or None.
-    tv = getTransactionalVariable(self)
+    tv = getTransactionalVariable()
     key = ('default_activate_parameter', )
     return tv.get(key)
 
diff --git a/product/ERP5/mixin/cached_convertable.py b/product/ERP5/mixin/cached_convertable.py
index d3e59b13ba..98689cc340 100644
--- a/product/ERP5/mixin/cached_convertable.py
+++ b/product/ERP5/mixin/cached_convertable.py
@@ -157,7 +157,7 @@ class CachedConvertableMixin:
     cache_duration = cache_factory.cache_duration
     # The purpose of this transaction cache is to help calls
     # to the same cache value in the same transaction.
-    tv = getTransactionalVariable(None)
+    tv = getTransactionalVariable()
     tv[cache_id] = stored_data_dict
     for cache_plugin in cache_factory.getCachePluginList():
       cache_plugin.set(cache_id, DEFAULT_CACHE_SCOPE,
@@ -172,7 +172,7 @@ class CachedConvertableMixin:
       return getattr(aq_base(self), 'temp_conversion_data', {})[cache_id]
     # The purpose of this cache is to help calls to the same cache value
     # in the same transaction.
-    tv = getTransactionalVariable(None)
+    tv = getTransactionalVariable()
     try:
       return tv[cache_id]
     except KeyError:
diff --git a/product/ERP5/mixin/document.py b/product/ERP5/mixin/document.py
index c29b1bcac6..b49740ed99 100644
--- a/product/ERP5/mixin/document.py
+++ b/product/ERP5/mixin/document.py
@@ -61,7 +61,7 @@ class DocumentMixin:
       string (ex. jpeg, html, text, txt, etc.)
       **kw can be various things - e.g. resolution
     """
-    transaction_variable = getTransactionalVariable(self.getPortalObject())
+    transaction_variable = getTransactionalVariable()
     if LOCK_PERMISSION_KEY in transaction_variable:
       # in convert we want always to check conversion format permission
       # to bypass such check one should use _convert directly
@@ -95,7 +95,7 @@ class DocumentMixin:
     """Private method to check permission when access specified format.
     This method raises
     """
-    transaction_variable = getTransactionalVariable(self.getPortalObject())
+    transaction_variable = getTransactionalVariable()
     if transaction_variable.get(LOCK_PERMISSION_KEY, False):
       # Permission already checked in convert with final format,
       # do not check permission for intermediate formats
diff --git a/product/ERP5Catalog/CatalogTool.py b/product/ERP5Catalog/CatalogTool.py
index 4b12222e5e..9018e35b1b 100644
--- a/product/ERP5Catalog/CatalogTool.py
+++ b/product/ERP5Catalog/CatalogTool.py
@@ -546,7 +546,7 @@ class CatalogTool (UniqueObject, ZCatalog, CMFCoreCatalogTool, ActiveObject):
       if allowedRolesAndUsers:
         allowedRolesAndUsers.sort()
         cache_key = tuple(allowedRolesAndUsers)
-        tv = getTransactionalVariable(self)
+        tv = getTransactionalVariable()
         try:
           security_uid_cache = tv['getSecurityUidListAndRoleColumnDict']
         except KeyError:
diff --git a/product/ERP5Form/PreferenceTool.py b/product/ERP5Form/PreferenceTool.py
index fadf92fabf..fb320c60b5 100644
--- a/product/ERP5Form/PreferenceTool.py
+++ b/product/ERP5Form/PreferenceTool.py
@@ -226,7 +226,7 @@ class PreferenceTool(BaseTool):
     """ return the most appropriate preferences objects,
         sorted so that the first in the list should be applied first
     """
-    tv = getTransactionalVariable(self)
+    tv = getTransactionalVariable()
     user = getToolByName(self, 'portal_membership').getAuthenticatedMember()
     tv_key = 'PreferenceTool._getSortedPreferenceList/%s/%s' % (user,
                                                                 sql_catalog_id)
diff --git a/product/ERP5Form/ProxyField.py b/product/ERP5Form/ProxyField.py
index e4c113f039..79b012f71d 100644
--- a/product/ERP5Form/ProxyField.py
+++ b/product/ERP5Form/ProxyField.py
@@ -760,12 +760,12 @@ class ProxyField(ZMIField):
     return '%s%s' % ('ProxyField', self._p_oid or repr(self))
 
   def _setTemplateFieldCache(self, field):
-    getTransactionalVariable(self)[self._getCacheId()] = field
+    getTransactionalVariable()[self._getCacheId()] = field
 
   def _getTemplateFieldCache(self):
     parent = self.aq_parent
     if parent is not None:
-      cache = getTransactionalVariable(self)[self._getCacheId()]
+      cache = getTransactionalVariable()[self._getCacheId()]
       if cache is not None:
         return cache.__of__(parent)
     raise KeyError
diff --git a/product/ERP5Form/Tool/SelectionTool.py b/product/ERP5Form/Tool/SelectionTool.py
index b79907c891..6f6d2de4c0 100644
--- a/product/ERP5Form/Tool/SelectionTool.py
+++ b/product/ERP5Form/Tool/SelectionTool.py
@@ -1382,7 +1382,7 @@ class SelectionTool( BaseTool, SimpleItem ):
       return SelectionTool.inheritedAttribute('_aq_dynamic')(self, name)
 
     def _getUserId(self):
-      tv = getTransactionalVariable(self)
+      tv = getTransactionalVariable()
       user_id = tv.get('_user_id', None)
       if user_id is not None:
         return user_id
@@ -1400,7 +1400,7 @@ class SelectionTool( BaseTool, SimpleItem ):
       """ Temporary selections are used in push/pop nested scope,
       to prevent from editting for stored selection in the scope.
       Typically, it is used for ReportSection."""
-      tv = getTransactionalVariable(self)
+      tv = getTransactionalVariable()
       return tv.setdefault('_temporary_selection_dict', {})
 
     def pushSelection(self, selection_name):
diff --git a/product/ERP5Type/Base.py b/product/ERP5Type/Base.py
index 9b89f4bd2b..4b62796bb5 100644
--- a/product/ERP5Type/Base.py
+++ b/product/ERP5Type/Base.py
@@ -178,7 +178,7 @@ class WorkflowMethod(Method):
     # Build a list of transitions which may need to be invoked
     instance_path = instance.getPhysicalPath()
     portal_type = instance.portal_type
-    transactional_variable = getTransactionalVariable(instance)
+    transactional_variable = getTransactionalVariable()
     invoke_once_item_list = self._invoke_once.get(portal_type, {}).items()
     valid_invoke_once_item_list = []
     # Only keep those transitions which were never invoked
@@ -1086,7 +1086,7 @@ class Base( CopyContainer,
       going to edit the related object
     """
     # Push context to prevent loop
-    tv = getTransactionalVariable(self)
+    tv = getTransactionalVariable()
     if isinstance(portal_type, list):
       portal_type = tuple(portal_type)
     acquisition_key = ('_getDefaultAcquiredProperty', self.getPath(), key,
@@ -1265,7 +1265,7 @@ class Base( CopyContainer,
 
     """
     # Push context to prevent loop
-    tv = getTransactionalVariable(self)
+    tv = getTransactionalVariable()
     if isinstance(portal_type, list):
       portal_type = tuple(portal_type)
     acquisition_key = ('_getAcquiredPropertyList', self.getPath(), key, base_category,
@@ -3110,7 +3110,7 @@ class Base( CopyContainer,
     # use a transactional variable to cache results within the same
     # transaction
     portal_type = self.getPortalType()
-    tv = getTransactionalVariable(self)
+    tv = getTransactionalVariable()
     type_base_cache = tv.setdefault('Base.type_based_cache', {})
 
     cache_key = (portal_type, method_id)
@@ -3811,7 +3811,7 @@ class Base( CopyContainer,
   def setDefaultReindexParameters(self, **kw):
     # This method sets the default keyword parameters to reindex. This is useful
     # when you need to specify special parameters implicitly (e.g. to reindexObject).
-    tv = getTransactionalVariable(self)
+    tv = getTransactionalVariable()
     key = ('default_reindex_parameter', id(aq_base(self)))
     tv[key] = kw
 
@@ -3820,7 +3820,7 @@ class Base( CopyContainer,
   def getDefaultReindexParameterDict(self, inherit_placeless=True):
     # This method returns default reindex parameters to self.
     # The result can be either a dict object or None.
-    tv = getTransactionalVariable(self)
+    tv = getTransactionalVariable()
     if inherit_placeless:
       placeless = tv.get(('default_reindex_parameter', ))
       if placeless is not None:
diff --git a/product/ERP5Type/Cache.py b/product/ERP5Type/Cache.py
index 2b9f571712..ddeb9d617c 100644
--- a/product/ERP5Type/Cache.py
+++ b/product/ERP5Type/Cache.py
@@ -299,7 +299,7 @@ def transactional_cached(key_method=lambda *args: args):
   def decorator(function):
     key = repr(function)
     def wrapper(*args, **kw):
-      cache = getTransactionalVariable(None).setdefault(key, {})
+      cache = getTransactionalVariable().setdefault(key, {})
       subkey = key_method(*args, **kw)
       try:
         return cache[subkey]
diff --git a/product/ERP5Type/TransactionalVariable.py b/product/ERP5Type/TransactionalVariable.py
index 5105af8150..d61bf56333 100644
--- a/product/ERP5Type/TransactionalVariable.py
+++ b/product/ERP5Type/TransactionalVariable.py
@@ -55,6 +55,7 @@ Example::
     toto = tv['toto'] = getToto()
 """
 
+import warnings
 from UserDict import IterableUserDict
 from Shared.DC.ZRDB.TM import TM
 from threading import local
@@ -83,8 +84,13 @@ class TransactionalVariable(TM, IterableUserDict):
 
 transactional_variable_pool = local()
 
-def getTransactionalVariable(context):
+_MARKER = object()
+def getTransactionalVariable(context=_MARKER):
   """Return a transactional variable."""
+  if context is not _MARKER:
+    warnings.warn("Passing a parameter to getTransactionalVariable() is"
+                  " deprecated and will not be tolerated in the future",
+                  DeprecationWarning)
   try:
     return transactional_variable_pool.instance
   except AttributeError:
diff --git a/product/ERP5Type/Utils.py b/product/ERP5Type/Utils.py
index ab1a2119c8..55341063c3 100644
--- a/product/ERP5Type/Utils.py
+++ b/product/ERP5Type/Utils.py
@@ -1243,7 +1243,7 @@ def createExpressionContext(object, portal=None):
   """
     Return a context used for evaluating a TALES expression.
   """
-  tv = getTransactionalVariable(None)
+  tv = getTransactionalVariable()
   cache_key = ('createExpressionContext', id(object))
   try:
     return tv[cache_key]
@@ -1313,7 +1313,7 @@ def getExistingBaseCategoryList(portal, base_cat_list):
   cache = getReadOnlyTransactionCache(portal)
   if cache is None:
     from Products.ERP5Type.TransactionalVariable import getTransactionalVariable
-    cache = getTransactionalVariable(portal)
+    cache = getTransactionalVariable()
   category_tool = portal.portal_categories
   new_base_cat_list = []
   for base_cat in base_cat_list:
diff --git a/product/ERP5Type/tests/testTransactionalVariable.py b/product/ERP5Type/tests/testTransactionalVariable.py
index bb1b7fc646..15d7e00941 100644
--- a/product/ERP5Type/tests/testTransactionalVariable.py
+++ b/product/ERP5Type/tests/testTransactionalVariable.py
@@ -55,7 +55,7 @@ class TestTransactionalVariable(ERP5TypeTestCase, LogInterceptor):
     def test_01_DictInterface(self):
       """Check if a transaction variable behaves in the same way as a dict.  """
    
-      tv = getTransactionalVariable(self.portal)
+      tv = getTransactionalVariable()
       self.failIfEqual(tv, None)
 
       # Test frequently used dict methods. This does not cover everything,
@@ -82,7 +82,7 @@ class TestTransactionalVariable(ERP5TypeTestCase, LogInterceptor):
       """Check if a transaction variable does not persist over multiple
       transactions.
       """
-      tv = getTransactionalVariable(self.portal)
+      tv = getTransactionalVariable()
       self.failIfEqual(tv, None)
 
       tv.clear()
@@ -104,7 +104,7 @@ class TestTransactionalVariable(ERP5TypeTestCase, LogInterceptor):
       """Check if a transaction variable does not disappear within the same
       transaction.
       """
-      tv = getTransactionalVariable(self.portal)
+      tv = getTransactionalVariable()
       self.failIfEqual(tv, None)
 
       tv.clear()
diff --git a/product/ZSQLCatalog/SQLCatalog.py b/product/ZSQLCatalog/SQLCatalog.py
index 9e71caf30d..14e0b89e08 100644
--- a/product/ZSQLCatalog/SQLCatalog.py
+++ b/product/ZSQLCatalog/SQLCatalog.py
@@ -98,7 +98,7 @@ try:
   from Products.ERP5Type.TransactionalVariable import getTransactionalVariable
 except ImportError:
   LOG('SQLCatalog', WARNING, 'Count not import getTransactionalVariable, expect slowness.')
-  def getTransactionalVariable(context):
+  def getTransactionalVariable():
     return {}
 
 class transactional_cache_decorator:
@@ -111,7 +111,7 @@ class transactional_cache_decorator:
 
   def __call__(self, method):
     def wrapper(wrapped_self):
-      transactional_cache = getTransactionalVariable(None)
+      transactional_cache = getTransactionalVariable()
       cache_id = self.cache_id
       try:
         result = transactional_cache[cache_id]
-- 
2.30.9