[Zope3-checkins] CVS: Zope3/src/zope/app/utilities - wrapper.py:1.1 schema.py:1.10

Sidnei da Silva sidnei at x3ng.com.br
Sat Oct 18 14:56:55 EDT 2003


Update of /cvs-repository/Zope3/src/zope/app/utilities
In directory cvs.zope.org:/tmp/cvs-serv3618/src/zope/app/utilities

Modified Files:
	schema.py 
Added Files:
	wrapper.py 
Log Message:
Moved persistence wrapper code from persistence to zope.app.utilities,
as suggested by Jim. It needs to be like this because the wrapper
needs to know about checkers, and stuff in persistence should not
depend on Zope.

There are some warts still, but I hope someone with more knowledge
about the persistence machinery will be able to help me sort that
out. I really can't go more far than that.


=== Added File Zope3/src/zope/app/utilities/wrapper.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Provide persistent wrappers for objects that cannot derive from
persistence for some reason."""

from persistence import Persistent
from zope.interface import implementedBy
from zope.security.checker import selectChecker

class SecurityDescriptor:
    """ SecurityDescriptor is used by Struct to return the
    checker for the proxied object when its an instance,
    and return the checker for the Struct class, when its a class
    """

    def __get__(self, inst, cls=None):
        if inst is None:
            return selectChecker(cls)
        else:
            # XXX This is *VERY* tricky. There is a possibility that
            # the object was loaded, but not active by the time
            # __proxied__ needs to be accessed, which results
            # in an AttributeError here, which is swallowed
            # somewere inside the security machinery,
            # and then the object ends up using _defaultChecker
            #
            # Added the same code below, in ClassDescriptor,
            # though I'm not sure it is really needed there.
            if inst._p_state == 3:
                inst._p_activate()
            return selectChecker(inst.__proxied__)

class ClassDescriptor:
    """ ClassDescriptor is used by Struct to return the
    real class for Struct when a class is being used, and return
    the proxied object's class when its an instance.
    """

    def __get__(self, inst, cls=None):
        if inst is None:
            return cls
        else:
            if inst._p_state == 3:
                inst._p_activate()
            return inst.__proxied__.__class__


# Put those attributes in a list so its easier to add/remove
# when needed.
struct_attrs = ['__proxied__',
                '__dict__',
                '__reduce_ex__',
                '__reduce__',
                '__getstate__',
                '__setstate__',
                '__Security_checker__']

class Struct(Persistent):
  """Wraps a non-persistent object, assuming that *all* changes are
  made through external attribute assignments.
  """

  # XXX to do this right and expose both IPersistent and the
  # underlying object's interfaces, we'd need to use a specialized
  # descriptor.  This would create to great a dependency on
  # zope.interface.

  __class__ = ClassDescriptor()
  __Security_checker__ = SecurityDescriptor()


  def __init__(self, o):
      self.__proxied__ = o

  def __getattribute__(self, name):
      if name.startswith('_p_') or name in struct_attrs:
          v = object.__getattribute__(self, name)
          # Handle descriptors here, eg: __Security_checker__
          # is a descriptor for Struct objects.
          if hasattr(v, '__get__'):
              return v.__get__(self, type(self))
          return v
      # XXX This is butt ugly. See the comment on SecurityDescriptor.
      if self._p_state == 3:
          self._p_activate()
      proxied = self.__proxied__
      v = getattr(proxied, name)
      # And also handle descriptors for the proxied object,
      # but using the proxied object on __get__ calls.
      if hasattr(v, '__get__'):
          return v.__get__(proxied, type(proxied))
      return v

  def __setattr__(self, name, v):
      if name.startswith('_p_') or name in struct_attrs:
          return Persistent.__setattr__(self, name, v)
      # Set _p_changed before calling the mutator on the
      # proxied object, so we have the object marked
      # as dirty even if an exception takes place later.
      self._p_changed = 1
      setattr(self.__proxied__, name, v)

  def __delattr__(self, name):
      if name.startswith('_p_') or name in struct_attrs:
          return Persistent.__delattr__(self, name)
      # Set _p_changed before deleting the attribute. See
      # comment above, on __setattr__
      self._p_changed = 1
      delattr(self.__proxied__, name, v)



=== Zope3/src/zope/app/utilities/schema.py 1.9 => 1.10 ===
--- Zope3/src/zope/app/utilities/schema.py:1.9	Wed Oct  8 09:16:01 2003
+++ Zope3/src/zope/app/utilities/schema.py	Sat Oct 18 14:56:24 2003
@@ -18,9 +18,9 @@
 from types import FunctionType
 
 from persistence.dict import PersistentDict
-from persistence.wrapper import Struct
 
 from zope.security.proxy import trustedRemoveSecurityProxy
+from zope.proxy import removeAllProxies
 from zope.interface import Interface
 from zope.interface import implements
 from zope.interface import directlyProvides, directlyProvidedBy
@@ -28,6 +28,7 @@
 from zope.app.introspector import nameToInterface, interfaceToName
 from zope.app.browser.container.adding import Adding
 from zope.app.utilities.interfaces import IMutableSchemaContent
+from zope.app.utilities.wrapper import Struct
 from zope.app.interfaces.utilities.schema import \
      ISchemaAdding, IMutableSchema, ISchemaUtility
 from zope.app.services.interface import PersistentInterfaceClass
@@ -121,7 +122,7 @@
         del self._attrs[name]
 
     def __setitem__(self, name, value):
-        value = trustedRemoveSecurityProxy(value)
+        value = removeAllProxies(value)
         if isinstance(value, Attribute):
             value.interface = name
             if not value.__name__:




More information about the Zope3-Checkins mailing list