[Zope3-checkins] CVS: Zope3/src/zope/proxy/context - .cvsignore:1.1.2.1 __init__.py:1.1.2.1 containmentiterator.py:1.1.2.1 context.py:1.1.2.1 readme.txt:1.1.2.1 setup.py:1.1.2.1 wrapper.c:1.1.2.1 wrapper.h:1.1.2.1

Jim Fulton jim@zope.com
Mon, 23 Dec 2002 14:33:07 -0500


Update of /cvs-repository/Zope3/src/zope/proxy/context
In directory cvs.zope.org:/tmp/cvs-serv19908/zope/proxy/context

Added Files:
      Tag: NameGeddon-branch
	.cvsignore __init__.py containmentiterator.py context.py 
	readme.txt setup.py wrapper.c wrapper.h 
Log Message:
Initial renaming before debugging

=== Added File Zope3/src/zope/proxy/context/.cvsignore ===
build


=== Added File Zope3/src/zope/proxy/context/__init__.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.
# 
##############################################################################
"""ContextWrapper package initialization."""

from zope.proxy.context.wrapper import *

# import the current, and rather hacky, python implementation of
# method rebinding.
# 
# eventually this should be replaced by some C, and ContextMethod
# should be a decriptor class rather than a factory that hacks the
# method's __dict__, as the current ContextMethod does.
# 
from zope.proxy.context.context import wrapperCreator as Wrapper
from zope.proxy.context.context import ContextMethod, ContextProperty
from zope.proxy.context.context import ContextGetProperty, ContextSetProperty

from zope.proxy.context.context import wrapperTypes
from zope.proxy.context.context import ContextSuper



=== Added File Zope3/src/zope/proxy/context/containmentiterator.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.
# 
##############################################################################
"""

$Id: containmentiterator.py,v 1.1.2.1 2002/12/23 19:33:05 jim Exp $
"""

from zope.proxy.context import Wrapper, wrapperTypes, getinnercontext

class ContainmentIterator:

    def __init__(self, obj):
        self._ob = Wrapper(None, obj)

    def __iter__(self):
        return self
    
    def next(self):
        ob = self._ob
        if type(ob) not in wrapperTypes:
            raise StopIteration

        ob = getinnercontext(ob)
        self._ob = ob
        return ob
    


=== Added File Zope3/src/zope/proxy/context/context.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
# 
##############################################################################
"""Wrapping/proxy coordination

Specifically, coordinate use of context wrappers and security proxies.

Revision information:
$Id: context.py,v 1.1.2.1 2002/12/23 19:33:05 jim Exp $
"""

from zope.security.proxy import Proxy, getChecker, getObject
from zope.proxy.context import Wrapper as _Wrapper
from zope.proxy.context import wrapperTypes, getobject, getdict
from zope.proxy.context import getcontext, getinnercontext, getinnerwrapper
from zope.security.checker import defineChecker, selectChecker, BasicTypes

from zope.proxy.interfaces.context import IContextWrapper

__implements__ = IContextWrapper

def ContextWrapper(_ob, _parent, **kw):
    """Create a context wrapper around an object with data

    If the object is wrapped in a security proxy, then the context
    wrapper is inserted inside an equivalent security proxy.
    """
    
    if type(_ob) in BasicTypes:
        # Don't wrap basic objects
        return _ob
    elif type(_ob) is Proxy:
        # insert into proxies
        checker = getChecker(_ob)
        _ob = getObject(_ob)
        _ob = Proxy(_Wrapper(_ob, _parent, **kw), checker)
    else:
        _ob = _Wrapper(_ob, _parent, **kw)
        
    return _ob

def getWrapperObject(_ob):
    """Remove a context wrapper around an object with data

    If the object is wrapped in a security proxy, then the object
    is inserted inside an equivalent security proxy.
    """
    
    if type(_ob) in BasicTypes:
        # Don't wrap basic objects
        return _ob
    elif type(_ob) is Proxy:
        # insert into proxies
        checker = getChecker(_ob)
        _ob = getObject(_ob)
        _ob = Proxy(getobject(_ob), checker)
    else:
        _ob = getobject(_ob)
        
    return _ob

def _contextWrapperChecker(ob):
    return selectChecker(getobject(ob))

for wrapper_type in wrapperTypes:
    defineChecker(wrapper_type, _contextWrapperChecker)

def getWrapperData(_ob):
    if type(_ob) is Proxy:
        _ob = getObject(_ob)
    return getdict(_ob)

def getInnerWrapperData(_ob):
    if type(_ob) is Proxy:
        _ob = getObject(_ob)
    return getdict(getinnerwrapper(_ob))

def getWrapperContainer(_ob):
    if type(_ob) is Proxy:
        _ob = getObject(_ob)
    return getinnercontext(_ob)

def getWrapperContext(_ob):
    if type(_ob) is Proxy:
        _ob = getObject(_ob)
    return getcontext(_ob)
    
def isWrapper(_ob):
    if type(_ob) is Proxy:
        _ob = getObject(_ob)
    return type(_ob) in wrapperTypes 

class ContainmentIterator:

    def __init__(self, obj):
        self._ob = _Wrapper(None, obj)

    def __iter__(self):
        return self
    
    def next(self):
        _ob = self._ob

        if type(_ob) is Proxy:
            _ob = getObject(_ob)
        
        if type(_ob) not in wrapperTypes:
            raise StopIteration

        _ob = getinnercontext(_ob)
        self._ob = _ob
        return _ob

def getItem(collection, name):
    return ContextWrapper(collection[name], collection, name=name)

def getAttr(collection, name):
    return ContextWrapper(getattr(collection, name), collection, name=name)

def queryItem(collection, name, default=None):
    return ContextWrapper(collection.get(name, default),
                          collection, name=name)

def queryAttr(collection, name, default=None):
    return ContextWrapper(getattr(collection, name, default),
                          collection, name=name)



##############################################################################
# 
# Approach
#
# The facilities here work by adding markers on methods or properties
# that a custom wrapper class looks for.  We rely on the custom
# wrapper class's __getattribute__ to rebind things on the way out.
# 
# For further discission, see this wiki page (all on one line):
# http://dev.zope.org/Wikis/DevSite/Projects/ComponentArchitecture/...
# Zope.ContextWrapper.ContextMethod
#
##############################################################################


# This method wrapper does not work for builtin methods.

from zope.proxy.context.wrapper import Wrapper, getbaseobject

__metaclass__ = type

class ContextMethod:
    def __new__(cls, method):
        try:
            method.__Zope_ContextWrapper_contextful_get__ = True
        except AttributeError:
            raise TypeError(
                "Cannot make %s into a contextmethod" % type(method)
                )
        return method


class ContextProperty(property):
    """A property that provides a context wrapper to its getter and setter
    methods"""
    __Zope_ContextWrapper_contextful_get__ = True
    __Zope_ContextWrapper_contextful_set__ = True

class ContextGetProperty(property):
    """A property that provides a context wrapper to its getter method"""
    __Zope_ContextWrapper_contextful_get__ = True

class ContextSetProperty(property):
    """A property that provides a context wrapper to its setter method"""
    __Zope_ContextWrapper_contextful_set__ = True

def wrapperCreator(object, context=None, **data):
    has_call = (hasattr(object, '__call__') and 
                getattr(object.__call__,
                        '__Zope_ContextWrapper_contextful_get__', False))
    has_getitem = (hasattr(object, '__getitem__') and
                   getattr(object.__getitem__,
                           '__Zope_ContextWrapper_contextful_get__', False))
    if has_call and has_getitem:
        factory = SimpleCallableGetitemMethodWrapper
    elif has_call:
        factory = SimpleCallableMethodWrapper
    elif has_getitem:
        factory = SimpleGetitemMethodWrapper
    else:
        factory = SimpleMethodWrapper

    return factory(object, context, **data)

class SimpleMethodWrapper(Wrapper):

    def __getattribute__(self, name):
        """Support for ContextMethod and ContextProperty.__get__"""
        obj = getbaseobject(self)
        class_ = obj.__class__
        class_value = getattr(class_, name, None)
        if hasattr(class_value, '__get__'):
            if getattr(class_value,
                       '__Zope_ContextWrapper_contextful_get__', False):
                return class_value.__get__(self, class_)
            
        return Wrapper.__getattribute__(self, name)

    def __setattr__(self, name, value):
        """Support for ContextProperty.__set__"""
        obj = getbaseobject(self)
        class_ = obj.__class__
        class_value = getattr(class_, name, None)
        if hasattr(class_value, '__set__'):
            if getattr(class_value,
                       '__Zope_ContextWrapper_contextful_set__', False):
                class_value.__set__(self, value)
                return
        setattr(obj, name, value)


class SimpleCallableMethodWrapper(SimpleMethodWrapper):

    def __call__(self, *args, **kw):
        attr = Wrapper.__getattribute__(self, '__call__')
        return attr.__get__(self)(*args, **kw)

class SimpleGetitemMethodWrapper(SimpleMethodWrapper):

    def __getitem__(self, key, *args, **kw):
        attr = Wrapper.__getattribute__(self, '__getitem__')
        return attr.__get__(self)(key, *args, **kw)

class SimpleCallableGetitemMethodWrapper(SimpleCallableMethodWrapper,
                                         SimpleGetitemMethodWrapper):
    pass

wrapperTypes = (SimpleMethodWrapper, SimpleCallableMethodWrapper,
                SimpleGetitemMethodWrapper,
                SimpleCallableGetitemMethodWrapper)

class ContextSuper:

    def __init__(self, class_, inst):
        self.__inst = inst
        self.__class = class_

    def __getattr__(self, name):
        inst = self.__inst
        return getattr(super(self.__class, getbaseobject(inst)), name
                       ).__get__(inst)


=== Added File Zope3/src/zope/proxy/context/readme.txt ===
This is an implementation of the "Basic Context Wrapper" for Zope 3.
More design information and documentation is available at

http://dev.zope.org/Wikis/DevSite/Projects/ComponentArchitecture/BasicContextWrapper

This code requires Python 2.2.


=== Added File Zope3/src/zope/proxy/context/setup.py ===
#! /usr/bin/env python
##############################################################################
#
# 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.
# 
##############################################################################

from distutils.core import setup, Extension

setup(name="Zope.ContextWrapper", version = "0.2",
      ext_modules=[Extension("wrapper", ["wrapper.c"])])


=== Added File Zope3/src/zope/proxy/context/wrapper.c === (597/697 lines abridged)
#include <Python.h>
#include "modsupport.h"
#include "Zope/Proxy/proxy.h"
#define WRAPPER_MODULE
#include "Zope/ContextWrapper/wrapper.h"

#define Wrapper_Check(wrapper)   (PyObject_TypeCheck(wrapper, &WrapperType))

#define Wrapper_GetObject(wrapper) Proxy_GET_OBJECT((wrapper))

#define Wrapper_GetContext(wrapper) \
        (((WrapperObject *)wrapper)->wrap_context)

#define Wrapper_GetDict(wrapper) \
        (((WrapperObject *)wrapper)->wrap_dict)


static PyTypeObject WrapperType;

static PyObject *
empty_tuple = NULL;

/* Helper for wrap_new/wrap_init; return the base class args tuple
 * from the incoming args tuple.  Returns a new reference.
 */
static PyObject *
create_proxy_args(PyObject *args, PyObject *object)
{
    if (PyTuple_GET_SIZE(args) == 1)
        Py_INCREF(args);
    else {
        args = PyTuple_New(1);
        if (args != NULL) {
            Py_INCREF(object);
            PyTuple_SET_ITEM(args, 0, object);
        }
    }
    return args;
}

/*
 *   Slot methods.
 */

static PyObject *
wrap_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
    PyObject *result = NULL;
    PyObject *context;
    PyObject *object;

[-=- -=- -=- 597 lines omitted -=- -=- -=-]

    {"setcontext",      wrapper_setcontext,      METH_VARARGS,
     setcontext__doc__},
    {NULL, NULL, 0, NULL}
};

static char
module___doc__[] =
"Association between an object, a context object, and a dictionary.\n\
\n\
The context object and dictionary give additional context information\n\
associated with a reference to the basic object.  The wrapper objects\n\
act as proxies for the original object.";

static PyObject *
api_object = NULL;


void
initwrapper(void)
{
    PyObject *m;

    if (Proxy_Import() < 0)
        return;

    m = Py_InitModule3("wrapper", module_functions, module___doc__);
    if (m == NULL)
        return;

    WrapperType.ob_type = &PyType_Type;
    WrapperType.tp_base = ProxyType;
    WrapperType.tp_alloc = PyType_GenericAlloc;
    WrapperType.tp_free = _PyObject_GC_Del;
    if (PyType_Ready(&WrapperType) < 0)
        return;

    Py_INCREF(&WrapperType);
    PyModule_AddObject(m, "Wrapper", (PyObject *)&WrapperType);

    if (api_object == NULL) {
        api_object = PyCObject_FromVoidPtr(&wrapper_capi, NULL);
        if (api_object == NULL)
            return;
    }
    Py_INCREF(api_object);
    PyModule_AddObject(m, "_CAPI", api_object);

    if (empty_tuple == NULL)
        empty_tuple = PyTuple_New(0);
}


=== Added File Zope3/src/zope/proxy/context/wrapper.h ===
/* Context Wrapper object; see "BasicContextWrapper" in the Zope 3 wiki:
 * http://dev.zope.org/Wikis/DevSite/Projects/ComponentArchitecture/
 *
 * This is intended for use with Python 2.2.
 *
 * Created by Fred Drake, 2001-Nov-09.
 */

#ifndef _wrapper_H_
#define _wrapper_H_

#ifndef _proxy_H_
#include "Zope/Proxy/proxy.h"
#endif

typedef struct {
    PyObject_HEAD
    PyObject *proxy_object;
    PyObject *wrap_context;
    PyObject *wrap_dict;
} WrapperObject;

typedef struct {
    int (*check)(PyObject *obj);
    PyObject *(*create)(PyObject *object, PyObject *context);
    PyObject *(*getobject)(PyObject *wrapper);
    PyObject *(*getbaseobject)(PyObject *wrapper);
    PyObject *(*getcontext)(PyObject *wrapper);
    PyObject *(*getinnercontext)(PyObject *wrapper);
    PyObject *(*getinnerwrapper)(PyObject *wrapper);
    PyObject *(*getdict)(PyObject *wrapper);
    PyObject *(*getdictcreate)(PyObject *wrapper);
    int (*setobject)(PyObject *wrapper, PyObject *object);
    int (*setcontext)(PyObject *wrapper, PyObject *context);
} WrapperInterface;


#ifndef WRAPPER_MODULE

/* These are only defined in the public interface, and are not
 * available within the module implementation.  There we use the
 * classic Python/C API only.
 */

static WrapperInterface *_wrapper_api = NULL;

static int
Wrapper_Import(void)
{
    if (_wrapper_api == NULL) {
        PyObject *m = PyImport_ImportModule("Zope.ContextWrapper.wrapper");
        if (m != NULL) {
            PyObject *tmp = PyObject_GetAttrString(m, "_CAPI");
            if (tmp != NULL) {
                if (PyCObject_Check(tmp))
                    _wrapper_api = (WrapperInterface *)
                        PyCObject_AsVoidPtr(tmp);
                Py_DECREF(tmp);
            }
        }
    }
    return (_wrapper_api == NULL) ? -1 : 0;
}

#define Wrapper_Check(obj)                   \
        (_wrapper_api->check((obj)))
#define Wrapper_New(object, context)         \
        (_wrapper_api->create((object), (context)))
#define Wrapper_GetObject(wrapper)           \
        (_wrapper_api->getobject((wrapper)))
#define Wrapper_GetBaseObject(wrapper)           \
        (_wrapper_api->getbaseobject((wrapper)))
#define Wrapper_GetContext(wrapper)          \
        (_wrapper_api->getcontext((wrapper)))
#define Wrapper_GetInnerContext(wrapper)          \
        (_wrapper_api->getinnercontext((wrapper)))
#define Wrapper_GetInnerWrapper(wrapper)          \
        (_wrapper_api->getinnerwrapper((wrapper)))
#define Wrapper_GetDict(wrapper)             \
        (_wrapper_api->getdict((wrapper)))
#define Wrapper_GetDictCreate(wrapper)       \
        (_wrapper_api->getdictcreate((wrapper)))
#define Wrapper_SetObject(wrapper, object)   \
        (_wrapper_api->setobject((wrapper), (object)))
#define Wrapper_SetContext(wrapper, context) \
        (_wrapper_api->setcontext((wrapper), (context)))

#endif

#endif