[Checkins] SVN: Products.ZSQLMethods/trunk/ Copy code from `App.Extensions` to keep compatibility with Zope 2.14.

Hanno Schlichting hannosch at hannosch.eu
Sun Jul 3 12:06:58 EDT 2011


Log message for revision 122090:
  Copy code from `App.Extensions` to keep compatibility with Zope 2.14.
  

Changed:
  U   Products.ZSQLMethods/trunk/CHANGES.txt
  U   Products.ZSQLMethods/trunk/src/Shared/DC/ZRDB/DA.py

-=-
Modified: Products.ZSQLMethods/trunk/CHANGES.txt
===================================================================
--- Products.ZSQLMethods/trunk/CHANGES.txt	2011-07-03 15:58:42 UTC (rev 122089)
+++ Products.ZSQLMethods/trunk/CHANGES.txt	2011-07-03 16:06:58 UTC (rev 122090)
@@ -4,6 +4,7 @@
 2.13.4 (unreleased)
 -------------------
 
+- Copy code from `App.Extensions` to keep compatibility with Zope 2.14.
 
 2.13.3 (2010-08-31)
 -------------------

Modified: Products.ZSQLMethods/trunk/src/Shared/DC/ZRDB/DA.py
===================================================================
--- Products.ZSQLMethods/trunk/src/Shared/DC/ZRDB/DA.py	2011-07-03 15:58:42 UTC (rev 122089)
+++ Products.ZSQLMethods/trunk/src/Shared/DC/ZRDB/DA.py	2011-07-03 16:06:58 UTC (rev 122090)
@@ -13,6 +13,8 @@
 '''Generic Database adapter'''
 
 from cStringIO import StringIO
+import imp
+import os
 import re
 import string
 import sys
@@ -24,7 +26,7 @@
 from AccessControl.SecurityInfo import ClassSecurityInfo
 from AccessControl.SecurityManagement import getSecurityManager
 from Acquisition import Implicit
-from App.Extensions import getBrain
+from App.Extensions import getObject
 from App.special_dtml import DTMLFile
 from DocumentTemplate import HTML
 from DocumentTemplate.html_quote import html_quote
@@ -33,9 +35,11 @@
 from BTrees.OOBTree import OOBucket as Bucket
 from OFS.SimpleItem import Item
 from Persistence import Persistent
+import Products
 from webdav.Resource import Resource
 from webdav.Lockable import ResourceLockedError
 from zExceptions import BadRequest
+from zExceptions import NotFound
 
 # BBB Zope 2.12
 try:
@@ -66,6 +70,188 @@
 from sqlvar import SQLVar
 
 
+def _getPath(home, prefix, name, suffixes):
+
+    dir = os.path.join(home, prefix)
+    if dir == prefix:
+        raise ValueError('The prefix, %s, should be a relative path' % prefix)
+
+    fn = os.path.join(dir, name)
+    if fn == name:
+        # Paranoia
+        raise ValueError('The file name, %s, should be a simple file name'
+                            % name)
+
+    for suffix in suffixes:
+        if suffix:
+            fqn = "%s.%s" % (fn, suffix)
+        else:
+            fqn = fn
+        if os.path.exists(fqn):
+            return fqn
+
+
+def getPath(prefix, name, checkProduct=1, suffixes=('',), cfg=None):
+    """Find a file in one of several relative locations
+
+    Arguments:
+
+      prefix -- The location, relative to some home, to look for the
+                file
+
+      name -- The name of the file.  This must not be a path.
+
+      checkProduct -- a flag indicating whether product directories
+        should be used as additional hope ares to be searched. This
+        defaults to a true value.
+
+        If this is true and the name contains a dot, then the
+        text before the dot is treated as a product name and
+        the product package directory is used as anothe rhome.
+
+      suffixes -- a sequences of file suffixes to check.
+        By default, the name is used without a suffix.
+
+      cfg -- ease testing (not part of the API)
+
+    The search takes on multiple homes which are the instance home,
+    the directory containing the directory containing the software
+    home, and possibly product areas.
+    """
+    dir, ignored = os.path.split(name)
+    if dir:
+        raise ValueError('The file name, %s, should be a simple file name'
+                            % name)
+
+    if checkProduct:
+        dot = name.find('.')
+        if dot > 0:
+            product = name[:dot]
+            extname = name[dot + 1:]
+            for product_dir in Products.__path__:
+                found = _getPath(product_dir, os.path.join(product, prefix),
+                                 extname, suffixes)
+                if found is not None:
+                    return found
+
+    if cfg is None:
+        import App.config
+        cfg = App.config.getConfiguration()
+
+    if prefix == "Extensions" and getattr(cfg, 'extensions', None) is not None:
+        found = _getPath(cfg.extensions, '', name, suffixes)
+        if found is not None:
+            return found
+
+    locations = [cfg.instancehome]
+
+    for home in locations:
+        found = _getPath(home, prefix, name, suffixes)
+        if found is not None:
+            return found
+
+    try:
+        dot = name.rfind('.')
+        if dot > 0:
+            realName = name[dot+1:]
+            toplevel = name[:dot]
+            
+            rdot = toplevel.rfind('.')
+            if rdot > -1:
+                module = __import__(toplevel, globals(), {}, toplevel[rdot+1:])
+            else:
+                module = __import__(toplevel)
+    
+            prefix = os.path.join(module.__path__[0], prefix, realName)
+            
+            for suffix in suffixes:
+                if suffix:
+                    fn = "%s.%s" % (prefix, suffix)
+                else:
+                    fn = prefix
+                if os.path.exists(fn): 
+                    return fn
+    except:
+        pass
+
+
+def getObject(module, name, reload=0,
+              # The use of a mutable default is intentional here,
+              # because modules is a module cache.
+              modules={}
+              ):
+    # The use of modules here is not thread safe, however, there is
+    # no real harm in a race condition here.  If two threads
+    # update the cache, then one will have simply worked a little
+    # harder than need be.  So, in this case, we won't incur
+    # the expense of a lock.
+    old = modules.get(module)
+    if old is not None and name in old and not reload:
+        return old[name]
+
+    base, ext = os.path.splitext(module)
+    if ext in ('py', 'pyc'):
+        # XXX should never happen; splitext() keeps '.' with the extension
+        prefix = base
+    else:
+        prefix = module
+
+    path = getPath('Extensions', prefix, suffixes=('','py','pyc'))
+    if path is None:
+        raise NotFound("The specified module, '%s', couldn't be found."
+                        % module)
+
+    __traceback_info__= path, module
+
+    base, ext = os.path.splitext(path)
+    if ext=='.pyc':
+        file = open(path, 'rb')
+        binmod = imp.load_compiled('Extension', path, file)
+        file.close()
+        module_dict = binmod.__dict__
+    else:
+        try:
+            execsrc = open(path)
+        except:
+            raise NotFound("The specified module, '%s', "
+                           "couldn't be opened." % module)
+        module_dict = {}
+        exec execsrc in module_dict
+
+    if old is not None:
+        # XXX Accretive??
+        old.update(module_dict)
+    else:
+        modules[module] = module_dict
+
+    try:
+        return module_dict[name]
+    except KeyError:
+        raise NotFound("The specified object, '%s', was not found "
+                       "in module, '%s'." % (name, module))
+
+
+class NoBrains:
+    pass
+
+
+def getBrain(module, class_name, reload=0, modules=None):
+    """ Check/load a class from an extension.
+    """
+    if not module and not class_name:
+        return NoBrains
+
+    if modules is None:
+        c=getObject(module, class_name, reload)
+    else:
+        c=getObject(module, class_name, reload, modules=modules)
+
+    if getattr(c, '__bases__', None) is None:
+        raise ValueError('%s, is not a class' % class_name)
+
+    return c
+
+
 class DatabaseError(BadRequest):
    " base class for external relational data base connection problems "
    pass



More information about the checkins mailing list