[Zope3-checkins] CVS: Zope3/src/zope/proxy/context - .cvsignore:1.2 __init__.py:1.2 containmentiterator.py:1.2 readme.txt:1.2 wrapper.c:1.2 wrapper.h:1.2
Jim Fulton
jim@zope.com
Wed, 25 Dec 2002 09:15:47 -0500
Update of /cvs-repository/Zope3/src/zope/proxy/context
In directory cvs.zope.org:/tmp/cvs-serv20790/src/zope/proxy/context
Added Files:
.cvsignore __init__.py containmentiterator.py readme.txt
wrapper.c wrapper.h
Log Message:
Grand renaming:
- Renamed most files (especially python modules) to lower case.
- Moved views and interfaces into separate hierarchies within each
project, where each top-level directory under the zope package
is a separate project.
- Moved everything to src from lib/python.
lib/python will eventually go away. I need access to the cvs
repository to make this happen, however.
There are probably some bits that are broken. All tests pass
and zope runs, but I haven't tried everything. There are a number
of cleanups I'll work on tomorrow.
=== Zope3/src/zope/proxy/context/.cvsignore 1.1 => 1.2 ===
--- /dev/null Wed Dec 25 09:15:47 2002
+++ Zope3/src/zope/proxy/context/.cvsignore Wed Dec 25 09:15:16 2002
@@ -0,0 +1 @@
+build
=== Zope3/src/zope/proxy/context/__init__.py 1.1 => 1.2 ===
--- /dev/null Wed Dec 25 09:15:47 2002
+++ Zope3/src/zope/proxy/context/__init__.py Wed Dec 25 09:15:16 2002
@@ -0,0 +1,262 @@
+##############################################################################
+#
+# 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$
+"""
+
+from zope.security.proxy import Proxy, getChecker, getObject
+from zope.proxy.context.wrapper import getobject, getdict
+from zope.proxy.context.wrapper import getcontext, getinnercontext
+from zope.proxy.context.wrapper import getinnerwrapper
+from zope.proxy.context.wrapper import Wrapper as _Wrapper, getbaseobject
+from zope.security.checker import defineChecker, selectChecker, BasicTypes
+
+
+__metaclass__ = type
+
+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(wrapperCreator(_ob, _parent, **kw), checker)
+ else:
+ _ob = wrapperCreator(_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))
+
+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 = wrapperCreator(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.proxy.context.ContextMethod
+#
+##############################################################################
+
+
+# This method wrapper does not work for builtin methods.
+
+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)
+
+Wrapper = wrapperCreator
+
+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)
+
+for wrapper_type in wrapperTypes:
+ defineChecker(wrapper_type, _contextWrapperChecker)
+
+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)
=== Zope3/src/zope/proxy/context/containmentiterator.py 1.1 => 1.2 ===
--- /dev/null Wed Dec 25 09:15:47 2002
+++ Zope3/src/zope/proxy/context/containmentiterator.py Wed Dec 25 09:15:16 2002
@@ -0,0 +1,36 @@
+##############################################################################
+#
+# 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$
+"""
+
+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
=== Zope3/src/zope/proxy/context/readme.txt 1.1 => 1.2 ===
--- /dev/null Wed Dec 25 09:15:47 2002
+++ Zope3/src/zope/proxy/context/readme.txt Wed Dec 25 09:15:16 2002
@@ -0,0 +1,6 @@
+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.
=== Zope3/src/zope/proxy/context/wrapper.c 1.1 => 1.2 === (600/700 lines abridged)
--- /dev/null Wed Dec 25 09:15:47 2002
+++ Zope3/src/zope/proxy/context/wrapper.c Wed Dec 25 09:15:16 2002
@@ -0,0 +1,697 @@
+#include <Python.h>
+#include "modsupport.h"
+#include "zope/proxy/proxy.h"
+#define WRAPPER_MODULE
+#include "zope/proxy/context/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)
+{
[-=- -=- -=- 600 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);
+}
=== Zope3/src/zope/proxy/context/wrapper.h 1.1 => 1.2 ===
--- /dev/null Wed Dec 25 09:15:47 2002
+++ Zope3/src/zope/proxy/context/wrapper.h Wed Dec 25 09:15:16 2002
@@ -0,0 +1,90 @@
+/* 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