[Zope-Checkins] CVS: Zope3/lib/python/Zope/ContextWrapper - ContainmentIterator.py:1.2 SimpleMethodWrapper.py:1.2 __init__.py:1.2 proxy.c:1.2 proxy.h:1.2 IWrapper.py:1.2 setup.py:1.2 wrapper.c:1.13 wrapper.h:1.4 test_wrapper.py:NONE
Jim Fulton
jim@zope.com
Mon, 10 Jun 2002 19:29:56 -0400
Update of /cvs-repository/Zope3/lib/python/Zope/ContextWrapper
In directory cvs.zope.org:/tmp/cvs-serv20468/lib/python/Zope/ContextWrapper
Modified Files:
IWrapper.py setup.py wrapper.c wrapper.h
Added Files:
ContainmentIterator.py SimpleMethodWrapper.py __init__.py
proxy.c proxy.h
Removed Files:
test_wrapper.py
Log Message:
Merged Zope-3x-branch into newly forked Zope3 CVS Tree.
=== Zope3/lib/python/Zope/ContextWrapper/ContainmentIterator.py 1.1 => 1.2 ===
+#
+# 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.ContextWrapper 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/lib/python/Zope/ContextWrapper/SimpleMethodWrapper.py 1.1 => 1.2 ===
+#
+# 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.
+#
+##############################################################################
+
+# This method wrapper does not work for builtin methods.
+
+from Zope.ContextWrapper.wrapper import Wrapper
+
+class ContextMethod(object):
+ def __new__(cls, method):
+ try:
+ method.__dict__['Zope.ContextWrapper.contextful'] = 1
+ except AttributeError:
+ raise TypeError, \
+ "Cannot make %s into a contextmethod" % type(method)
+ return method
+
+
+def wrapperCreator(object, context=None, **data):
+ if hasattr(object, '__call__'):
+ attrdict = getattr(object.__call__, '__dict__', {})
+ if attrdict.get('Zope.ContextWrapper.contextful'):
+ return SimpleCallableMethodWrapper(object, context, **data)
+
+ return SimpleMethodWrapper(object, context, **data)
+
+
+class SimpleMethodWrapper(Wrapper):
+
+ def __getattribute__(self, name, empty_dict={}):
+ attr = Wrapper.__getattribute__(self, name)
+ attrdict = getattr(attr, '__dict__', empty_dict)
+ if attrdict.get('Zope.ContextWrapper.contextful'):
+ attr = attr.__get__(self)
+ return attr
+
+
+class SimpleCallableMethodWrapper(SimpleMethodWrapper):
+
+ def __call__(self, *args, **kw):
+ attr = Wrapper.__getattribute__(self, '__call__')
+ return attr.__get__(self)(*args, **kw)
=== Zope3/lib/python/Zope/ContextWrapper/__init__.py 1.1 => 1.2 ===
+#
+# 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 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 SimpleMethodWrapper import wrapperCreator as Wrapper
+from SimpleMethodWrapper import ContextMethod
+
+from SimpleMethodWrapper import SimpleMethodWrapper,SimpleCallableMethodWrapper
+wrapperTypes = (SimpleMethodWrapper, SimpleCallableMethodWrapper)
+del SimpleMethodWrapper, SimpleCallableMethodWrapper
=== Zope3/lib/python/Zope/ContextWrapper/proxy.c 1.1 => 1.2 === (664/764 lines abridged)
+#include "modsupport.h"
+
+#define PROXY_MODULE
+#include "proxy.h"
+
+staticforward PyTypeObject ProxyType;
+
+#define Proxy_Check(wrapper) (PyObject_TypeCheck((wrapper), &ProxyType))
+
+static PyObject *
+empty_tuple = NULL;
+
+
+/*
+ * Slot methods.
+ */
+
+static PyObject *
+wrap_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ PyObject *result = NULL;
+ PyObject *object;
+
+ if (PyArg_UnpackTuple(args, "__new__", 1, 1, &object)) {
+ if (kwds != NULL && PyDict_Size(kwds) != 0) {
+ PyErr_SetString(PyExc_TypeError,
+ "proxy.__new__ does not accept keyword args");
+ return NULL;
+ }
+ result = PyType_GenericNew(type, args, kwds);
+ if (result != NULL) {
+ ProxyObject *wrapper = (ProxyObject *) result;
+ Py_INCREF(object);
+ wrapper->proxy_object = object;
+ }
+ }
+ return result;
+}
+
+static int
+wrap_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+ int result = -1;
+ PyObject *object;
+
+ if (PyArg_UnpackTuple(args, "__init__", 1, 1, &object)) {
+ ProxyObject *wrapper = (ProxyObject *)self;
+ if (kwds != NULL && PyDict_Size(kwds) != 0) {
+ PyErr_SetString(PyExc_TypeError,
+ "proxy.__init__ does not accept keyword args");
[-=- -=- -=- 664 lines omitted -=- -=- -=-]
+ result = Proxy_GET_OBJECT(obj);
+ Py_INCREF(result);
+ }
+ else
+ PyErr_Format(PyExc_TypeError,
+ "expected proxy, got %s", obj->ob_type->tp_name);
+ return result;
+}
+
+static PyMethodDef
+module_functions[] = {
+ {"getobject", wrapper_getobject, METH_O, getobject__doc__},
+ {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.";
+
+
+void
+initproxy(void)
+{
+ PyObject *m = Py_InitModule3("proxy", module_functions, module___doc__);
+
+ if (m == NULL)
+ return;
+
+ if (empty_tuple == NULL)
+ empty_tuple = PyTuple_New(0);
+
+ ProxyType.ob_type = &PyType_Type;
+ if (PyType_Ready(&ProxyType) < 0)
+ return;
+
+ Py_INCREF(&ProxyType);
+ PyModule_AddObject(m, "proxy", (PyObject *)&ProxyType);
+
+ 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);
+}
=== Zope3/lib/python/Zope/ContextWrapper/proxy.h 1.1 => 1.2 ===
+#define _proxy_H_ 1
+
+typedef struct {
+ PyObject_HEAD
+ PyObject *proxy_object;
+} ProxyObject;
+
+#define Proxy_GET_OBJECT(ob) (((ProxyObject *)(ob))->proxy_object)
+
+typedef struct {
+ PyTypeObject *proxytype;
+ int (*check)(PyObject *obj);
+ PyObject *(*create)(PyObject *obj);
+ PyObject *(*getobject)(PyObject *proxy);
+} ProxyInterface;
+
+
+#ifndef PROXY_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 ProxyInterface *_proxy_api = NULL;
+
+static int
+Proxy_Import(void)
+{
+ if (_proxy_api == NULL) {
+ PyObject *m = PyImport_ImportModule("Zope.ContextWrapper.proxy");
+ if (m != NULL) {
+ PyObject *tmp = PyObject_GetAttrString(m, "_CAPI");
+ if (tmp != NULL) {
+ if (PyCObject_Check(tmp))
+ _proxy_api = (ProxyInterface *)
+ PyCObject_AsVoidPtr(tmp);
+ Py_DECREF(tmp);
+ }
+ }
+ }
+ return (_proxy_api == NULL) ? -1 : 0;
+}
+
+#define ProxyType (_proxy_api->proxytype)
+#define Proxy_Check(obj) (_proxy_api->check((obj)))
+#define Proxy_CheckExact(obj) ((obj)->ob_type == ProxyType)
+#define Proxy_New(obj) (_proxy_api->create((obj)))
+#define Proxy_GetObject(proxy) (_proxy_api->getobject((proxy)))
+
+#endif /* PROXY_MODULE */
+
+#endif /* _proxy_H_ */
=== Zope3/lib/python/Zope/ContextWrapper/IWrapper.py 1.1 => 1.2 ===
+#
+# 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.
+#
+##############################################################################
import Interface
class IWrapperFuncs(Interface.Base):
""" Interface implemented by callables in 'wrapper' module """
- def Wrapper(object, context=None):
+ def Wrapper(object, context=None, **data):
"""
- Create and return a new context wrapper for object. If context is
- given and not None, context will be the context object. Wrapper can
- be subclassed.
+ Create and return a new context wrapper for object. If context is given
+ and not None, context will be the context object. Wrapper can be
+ subclassed.
+
+ Wrapper data may be passed as keyword arguments. The data are
+ added to the context dictionary.
"""
+
def getobject(obj):
"""
Return the wrapped object. If obj is not a wrapper object, return obj.
"""
- def getinnerobject(obj):
+ def getbaseobject(obj):
+ """
+ Return the innermost wrapped object. If obj is not a wrapper,
+ return obj.
"""
- Return the innermost wrapped object in a chain of wrappers with obj
- at the head. If obj is not a wrapper object, just return obj.
+ def getinnerwrapper(obj):
+ """
+ Return the innermost wrapper in a chain of wrappers with obj at the
+ head. If obj is wrapped, just return obj.
"""
def getinnercontext(obj):
"""
- Return the context object from the innermost wrapper in a chain
- with obj at the head. If the innermost wrapper has not context
- object, return None. If obj is not a wrapper object, just return obj.
+ Return the context object from the innermost wrapper in a chain with
+ obj at the head. If the innermost wrapper has not context object,
+ return None. If obj is not a wrapper object, just return obj.
"""
def getcontext(obj):
"""
@@ -30,8 +52,8 @@
"""
def getdict(obj):
"""
- Return the context dictionary if there is one, or None. If obj is
- not a wrapper instance, return None.
+ Return the context dictionary if there is one, or None. If obj is not a
+ wrapper instance, return None.
"""
def getdictcreate(wrapper):
"""
@@ -40,13 +62,13 @@
"""
def setobject(wrapper, object):
"""
- Replace the wrapped object with object. Raises TypeError if wrapper
- is not a wrapper object.
+ Replace the wrapped object with object. Raises TypeError if wrapper is
+ not a wrapper object.
"""
def setcontext(wrapper, context):
"""
- Replace the context object with context. If context is None, it will
- be represented as NULL in C API. Raises TypeError if wrapper is not
+ Replace the context object with context. If context is None, it will be
+ represented as NULL in C API. Raises TypeError if wrapper is not
a wrapper object.
"""
=== Zope3/lib/python/Zope/ContextWrapper/setup.py 1.1 => 1.2 ===
+##############################################################################
+#
+# 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="wrapper", version = "0.1",
- ext_modules=[Extension("wrapper", ["wrapper.c"])])
+setup(name="wrapper", version = "0.2",
+ ext_modules=[Extension("wrapper", ["wrapper.c"]),
+ Extension("proxy", ["proxy.c"])])
=== Zope3/lib/python/Zope/ContextWrapper/wrapper.c 1.12 => 1.13 === (484/584 lines abridged)
#include "modsupport.h"
+#include "proxy.h"
#define WRAPPER_MODULE
#include "wrapper.h"
-#define Wrapper_Check(wrapper) \
- (((wrapper)->ob_type == &WrapperType) \
- || (PyObject_TypeCheck(wrapper, &WrapperType)))
+#define Wrapper_Check(wrapper) (PyObject_TypeCheck(wrapper, &WrapperType))
-#define Wrapper_GetObject(wrapper) \
- (((WrapperObject *)wrapper)->wrap_object)
+#define Wrapper_GetObject(wrapper) Proxy_GET_OBJECT((wrapper))
#define Wrapper_GetContext(wrapper) \
(((WrapperObject *)wrapper)->wrap_context)
@@ -17,29 +15,94 @@
(((WrapperObject *)wrapper)->wrap_dict)
+staticforward 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)
+{
[-=- -=- -=- 484 lines omitted -=- -=- -=-]
- {"getobject", getobject, METH_O, getobject__doc__},
- {"getinnerobject", getinnerobject, METH_O, getinnerobject__doc__},
- {"getcontext", getcontext, METH_O, getcontext__doc__},
- {"getinnercontext", getinnercontext, METH_O, getinnercontext__doc__},
- {"getdict", getdict, METH_O, getdict__doc__},
- {"getdictcreate", getdictcreate, METH_O, getdictcreate__doc__},
- {"setobject", setobject, METH_VARARGS, setobject__doc__},
- {"setcontext", setcontext, METH_VARARGS, setcontext__doc__},
+ {"getobject", wrapper_getobject, METH_O,
+ getobject__doc__},
+ {"getbaseobject", wrapper_getbaseobject, METH_O,
+ getbaseobject__doc__},
+ {"getcontext", wrapper_getcontext, METH_O,
+ getcontext__doc__},
+ {"getinnercontext", wrapper_getinnercontext, METH_O,
+ getinnercontext__doc__},
+ {"getinnerwrapper", wrapper_getinnerwrapper, METH_O,
+ getinnerwrapper__doc__},
+ {"getdict", wrapper_getdict, METH_O,
+ getdict__doc__},
+ {"getdictcreate", wrapper_getdictcreate, METH_O,
+ getdictcreate__doc__},
+ {"setobject", wrapper_setobject, METH_VARARGS,
+ setobject__doc__},
+ {"setcontext", wrapper_setcontext, METH_VARARGS,
+ setcontext__doc__},
{NULL, NULL, 0, NULL}
};
@@ -644,14 +665,17 @@
void
initwrapper(void)
{
- PyObject *m = Py_InitModule3("wrapper",
- module_functions,
- module___doc__);
+ 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;
if (PyType_Ready(&WrapperType) < 0)
return;
=== Zope3/lib/python/Zope/ContextWrapper/wrapper.h 1.3 => 1.4 ===
#define _wrapper_H_
+#ifndef _proxy_H_
+#include "proxy.h"
+#endif
+
typedef struct {
PyObject_HEAD
- PyObject *wrap_object;
+ PyObject *proxy_object;
PyObject *wrap_context;
PyObject *wrap_dict;
} WrapperObject;
@@ -20,9 +24,10 @@
int (*check)(PyObject *obj);
PyObject *(*create)(PyObject *object, PyObject *context);
PyObject *(*getobject)(PyObject *wrapper);
- PyObject *(*getinnerobject)(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);
@@ -43,7 +48,7 @@
Wrapper_Import(void)
{
if (_wrapper_api == NULL) {
- PyObject *m = PyImport_ImportModule("wrapper");
+ PyObject *m = PyImport_ImportModule("Zope.ContextWrapper.wrapper");
if (m != NULL) {
PyObject *tmp = PyObject_GetAttrString(m, "_CAPI");
if (tmp != NULL) {
@@ -63,12 +68,14 @@
(_wrapper_api->create((object), (context)))
#define Wrapper_GetObject(wrapper) \
(_wrapper_api->getobject((wrapper)))
-#define Wrapper_GetInnerObject(wrapper) \
- (_wrapper_api->getinnerobject((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) \
=== Removed File Zope3/lib/python/Zope/ContextWrapper/test_wrapper.py ===