[Checkins] SVN: zope.app.container/trunk/s removed code that has been moved to zope.container, leaving behind compatibility imports
Wolfgang Schnerring
wosc at wosc.de
Thu Jan 29 05:28:20 EST 2009
Log message for revision 95398:
removed code that has been moved to zope.container, leaving behind compatibility imports
Changed:
U zope.app.container/trunk/setup.py
D zope.app.container/trunk/src/zope/app/container/_zope_app_container_contained.c
D zope.app.container/trunk/src/zope/app/container/_zope_proxy_proxy.c
U zope.app.container/trunk/src/zope/app/container/btree.py
U zope.app.container/trunk/src/zope/app/container/configure.zcml
U zope.app.container/trunk/src/zope/app/container/constraints.py
D zope.app.container/trunk/src/zope/app/container/constraints.txt
U zope.app.container/trunk/src/zope/app/container/contained.py
U zope.app.container/trunk/src/zope/app/container/dependency.py
U zope.app.container/trunk/src/zope/app/container/directory.py
U zope.app.container/trunk/src/zope/app/container/find.py
U zope.app.container/trunk/src/zope/app/container/interfaces.py
U zope.app.container/trunk/src/zope/app/container/ordered.py
U zope.app.container/trunk/src/zope/app/container/sample.py
U zope.app.container/trunk/src/zope/app/container/size.py
D zope.app.container/trunk/src/zope/app/container/tests/test_btree.py
D zope.app.container/trunk/src/zope/app/container/tests/test_constraints.py
D zope.app.container/trunk/src/zope/app/container/tests/test_contained.py
D zope.app.container/trunk/src/zope/app/container/tests/test_containertraversable.py
D zope.app.container/trunk/src/zope/app/container/tests/test_containertraverser.py
D zope.app.container/trunk/src/zope/app/container/tests/test_dependency.py
D zope.app.container/trunk/src/zope/app/container/tests/test_directory.py
D zope.app.container/trunk/src/zope/app/container/tests/test_find.py
D zope.app.container/trunk/src/zope/app/container/tests/test_icontainer.py
D zope.app.container/trunk/src/zope/app/container/tests/test_objectcopier.py
D zope.app.container/trunk/src/zope/app/container/tests/test_objectmover.py
D zope.app.container/trunk/src/zope/app/container/tests/test_ordered.py
D zope.app.container/trunk/src/zope/app/container/tests/test_size.py
U zope.app.container/trunk/src/zope/app/container/traversal.py
-=-
Modified: zope.app.container/trunk/setup.py
===================================================================
--- zope.app.container/trunk/setup.py 2009-01-29 10:24:21 UTC (rev 95397)
+++ zope.app.container/trunk/setup.py 2009-01-29 10:28:20 UTC (rev 95398)
@@ -16,7 +16,7 @@
$Id$
"""
import os
-from setuptools import setup, find_packages, Extension
+from setuptools import setup, find_packages
def read(*rnames):
return open(os.path.join(os.path.dirname(__file__), *rnames)).read()
@@ -29,11 +29,6 @@
long_description=(
read('README.txt')
+ '\n\n' +
- 'Detailed Documentation\n'
- '**********************\n'
- + '\n\n' +
- read('src', 'zope', 'app', 'container', 'constraints.txt')
- + '\n\n' +
read('CHANGES.txt')
),
keywords = "zope3 container",
@@ -52,11 +47,6 @@
packages=find_packages('src'),
package_dir = {'': 'src'},
namespace_packages=['zope', 'zope.app'],
- ext_modules=[Extension("zope.app.container._zope_app_container_contained",
- [os.path.join("src", "zope", "app", "container",
- "_zope_app_container_contained.c")
- ], include_dirs=['include']),
- ],
extras_require=dict(test=['zope.app.testing',
'zope.app.securitypolicy',
@@ -64,9 +54,7 @@
'zope.app.file']),
install_requires=['setuptools',
'zope.interface',
- 'zope.app.publisher',
- 'zope.cachedescriptors',
- 'zope.dottedname',
+ 'zope.container',
'zope.schema',
'zope.component',
'zope.event',
@@ -74,17 +62,15 @@
'zope.exceptions',
'zope.security',
'zope.lifecycleevent',
+ 'zope.i18n',
'zope.i18nmessageid',
- 'zope.filerepresentation',
'zope.size',
'zope.traversing',
'zope.publisher',
'zope.dublincore',
- 'zope.app.broken',
'zope.copypastemove',
- 'ZODB3',
- 'zope.i18n',
],
include_package_data = True,
zip_safe = False,
)
+
Deleted: zope.app.container/trunk/src/zope/app/container/_zope_app_container_contained.c
===================================================================
--- zope.app.container/trunk/src/zope/app/container/_zope_app_container_contained.c 2009-01-29 10:24:21 UTC (rev 95397)
+++ zope.app.container/trunk/src/zope/app/container/_zope_app_container_contained.c 2009-01-29 10:28:20 UTC (rev 95398)
@@ -1,336 +0,0 @@
-/*############################################################################
-#
-# Copyright (c) 2003 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (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.
-#
-############################################################################*/
-
-#define _ZOPE_APP_CONTAINER_CONTAINED_C "$Id$\n"
-
-/* Contained Proxy Base class
-
- Contained proxies provide __parent__ and __name__ attributes for
- objects without them.
-
- There is something strange and, possibly cool, going on here, wrt
- persistence. To reuse the base proxy implementation we don't treat
- the proxied object as part of the persistent state of the proxy.
- This means that the proxy still operates as a proxy even if it is a
- ghost.
-
- The proxy will only be unghostified if you need to access one of the
- attributes provided by the proxy.
-
- */
-
-
-#include "Python.h"
-#include "persistent/cPersistence.h"
-
-static PyObject *str_p_deactivate;
-
-#if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN)
-typedef int Py_ssize_t;
-#define PY_SSIZE_T_MAX INT_MAX
-#define PY_SSIZE_T_MIN INT_MIN
-typedef Py_ssize_t (*lenfunc)(PyObject *);
-typedef PyObject *(*ssizeargfunc)(PyObject *, Py_ssize_t);
-typedef PyObject *(*ssizessizeargfunc)(PyObject *, Py_ssize_t, Py_ssize_t);
-typedef int(*ssizeobjargproc)(PyObject *, Py_ssize_t, PyObject *);
-typedef int(*ssizessizeobjargproc)(PyObject *, Py_ssize_t, Py_ssize_t, PyObject *);
-#endif
-
-typedef struct {
- cPersistent_HEAD
- PyObject *po_weaklist;
- PyObject *proxy_object;
- PyObject *__parent__;
- PyObject *__name__;
-} ProxyObject;
-
-typedef struct {
- PyTypeObject *proxytype;
- int (*check)(PyObject *obj);
- PyObject *(*create)(PyObject *obj);
- PyObject *(*getobject)(PyObject *proxy);
-} ProxyInterface;
-
-#define OBJECT(O) ((PyObject*)(O))
-#define Proxy_GET_OBJECT(ob) (((ProxyObject *)(ob))->proxy_object)
-
-#define CLEAR(O) \
- if (O) {PyObject *clr__tmp = O; O = NULL; Py_DECREF(clr__tmp); }
-
-/* Supress inclusion of the original proxy.h */
-#define _proxy_H_ 1
-
-/* Incude the proxy C source */
-#include "_zope_proxy_proxy.c"
-
-#define SPECIAL(NAME) ( \
- *(NAME) == '_' && \
- (((NAME)[1] == 'p' && (NAME)[2] == '_') \
- || \
- ((NAME)[1] == '_' && ( \
- strcmp((NAME), "__parent__") == 0 \
- || \
- strcmp((NAME), "__name__") == 0 \
- || \
- strcmp((NAME), "__getstate__") == 0 \
- || \
- strcmp((NAME), "__setstate__") == 0 \
- || \
- strcmp((NAME), "__getnewargs__") == 0 \
- || \
- strcmp((NAME), "__reduce__") == 0 \
- || \
- strcmp((NAME), "__reduce_ex__") == 0 \
- )) \
- ))
-
-static PyObject *
-CP_getattro(PyObject *self, PyObject *name)
-{
- char *cname;
-
- cname = PyString_AsString(name);
- if (cname == NULL)
- return NULL;
-
- if (SPECIAL(cname))
- /* delegate to persistent */
- return cPersistenceCAPI->pertype->tp_getattro(self, name);
-
- /* Use the wrapper version to delegate */
- return wrap_getattro(self, name);
-}
-
-static int
-CP_setattro(PyObject *self, PyObject *name, PyObject *v)
-{
- char *cname;
-
- cname = PyString_AsString(name);
- if (cname == NULL)
- return -1;
-
- if (SPECIAL(cname))
- /* delegate to persistent */
- return cPersistenceCAPI->pertype->tp_setattro(self, name, v);
-
- /* Use the wrapper version to delegate */
- return wrap_setattro(self, name, v);
-}
-
-static PyObject *
-CP_getstate(ProxyObject *self)
-{
- return Py_BuildValue("OO",
- self->__parent__ ? self->__parent__ : Py_None,
- self->__name__ ? self->__name__ : Py_None
- );
-}
-
-static PyObject *
-CP_getnewargs(ProxyObject *self)
-{
- return Py_BuildValue("(O)", self->proxy_object);
-}
-
-static PyObject *
-CP_setstate(ProxyObject *self, PyObject *state)
-{
- PyObject *parent, *name;
-
- if(! PyArg_ParseTuple(state, "OO", &parent, &name))
- return NULL;
-
- CLEAR(self->__parent__);
- CLEAR(self->__name__);
-
- Py_INCREF(parent);
- Py_INCREF(name);
-
- self->__parent__ = parent;
- self->__name__ = name;
-
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-static PyObject *
-CP_reduce(ProxyObject *self)
-{
- PyObject *result;
- if (! PER_USE(self))
- return NULL;
- result = Py_BuildValue("O(O)(OO)",
- self->ob_type,
- self->proxy_object,
- self->__parent__ ? self->__parent__ : Py_None,
- self->__name__ ? self->__name__ : Py_None
- );
- PER_ALLOW_DEACTIVATION(self);
- return result;
-}
-
-static PyObject *
-CP_reduce_ex(ProxyObject *self, PyObject *proto)
-{
- return CP_reduce(self);
-}
-
-static PyObject *
-CP__p_deactivate(ProxyObject *self)
-{
- PyObject *result;
-
- result = PyObject_CallMethodObjArgs(OBJECT(cPersistenceCAPI->pertype),
- str_p_deactivate,
- self, NULL);
- if (result == NULL)
- return NULL;
-
- if (self->jar && self->oid && self->state == cPersistent_UPTODATE_STATE)
- {
- Py_XDECREF(self->__parent__);
- self->__parent__ = NULL;
- Py_XDECREF(self->__name__);
- self->__name__ = NULL;
- }
-
- return result;
-}
-
-
-static PyMethodDef
-CP_methods[] = {
- {"__getstate__", (PyCFunction)CP_getstate, METH_NOARGS,
- "Get the object state"},
- {"__setstate__", (PyCFunction)CP_setstate, METH_O,
- "Set the object state"},
- {"__getnewargs__", (PyCFunction)CP_getnewargs, METH_NOARGS,
- "Get the arguments that must be passed to __new__"},
- {"__reduce__", (PyCFunction)CP_reduce, METH_NOARGS,
- "Reduce the object to constituent parts."},
- {"__reduce_ex__", (PyCFunction)CP_reduce_ex, METH_O,
- "Reduce the object to constituent parts."},
- {"_p_deactivate", (PyCFunction)CP__p_deactivate, METH_NOARGS,
- "Deactivate the object."},
- {NULL, NULL},
-};
-
-
-/* Code to access structure members by accessing attributes */
-
-#include "structmember.h"
-
-static PyMemberDef CP_members[] = {
- {"__parent__", T_OBJECT, offsetof(ProxyObject, __parent__)},
- {"__name__", T_OBJECT, offsetof(ProxyObject, __name__)},
- {NULL} /* Sentinel */
-};
-
-static int
-CP_traverse(ProxyObject *self, visitproc visit, void *arg)
-{
- if (cPersistenceCAPI->pertype->tp_traverse((PyObject *)self, visit, arg) < 0)
- return -1;
- if (self->proxy_object != NULL && visit(self->proxy_object, arg) < 0)
- return -1;
- if (self->__parent__ != NULL && visit(self->__parent__, arg) < 0)
- return -1;
- if (self->__name__ != NULL && visit(self->__name__, arg) < 0)
- return -1;
-
- return 0;
-}
-
-static int
-CP_clear(ProxyObject *self)
-{
- /* Drop references that may have created reference
- cycles. Immutable objects do not have to define this method
- since they can never directly create reference cycles. Note
- that the object must still be valid after calling this
- method (don't just call Py_DECREF() on a reference). The
- collector will call this method if it detects that this
- object is involved in a reference cycle.
- */
- if (cPersistenceCAPI->pertype->tp_clear != NULL)
- cPersistenceCAPI->pertype->tp_clear((PyObject*)self);
-
- CLEAR(self->proxy_object);
- CLEAR(self->__parent__);
- CLEAR(self->__name__);
-
- return 0;
-}
-
-static void
-CP_dealloc(ProxyObject *self)
-{
- if (self->po_weaklist != NULL)
- PyObject_ClearWeakRefs((PyObject *)self);
-
- CLEAR(self->proxy_object);
- CLEAR(self->__parent__);
- CLEAR(self->__name__);
-
- cPersistenceCAPI->pertype->tp_dealloc((PyObject*)self);
-}
-
-#ifndef PyMODINIT_FUNC /* declarations for DLL import/export */
-#define PyMODINIT_FUNC void
-#endif
-PyMODINIT_FUNC
-init_zope_app_container_contained(void)
-{
- PyObject *m;
-
- str_p_deactivate = PyString_FromString("_p_deactivate");
- if (str_p_deactivate == NULL)
- return;
-
- /* Try to fake out compiler nag function */
- if (0) init_zope_proxy_proxy();
-
- m = Py_InitModule3("_zope_app_container_contained",
- module_functions, module___doc__);
-
- if (m == NULL)
- return;
-
- if (empty_tuple == NULL)
- empty_tuple = PyTuple_New(0);
-
- /* Initialize the PyPersist_C_API and the type objects. */
- cPersistenceCAPI = PyCObject_Import("persistent.cPersistence", "CAPI");
- if (cPersistenceCAPI == NULL)
- return;
-
- ProxyType.tp_name = "zope.app.container.contained.ContainedProxyBase";
- ProxyType.ob_type = &PyType_Type;
- ProxyType.tp_base = cPersistenceCAPI->pertype;
- ProxyType.tp_getattro = CP_getattro;
- ProxyType.tp_setattro = CP_setattro;
- ProxyType.tp_members = CP_members;
- ProxyType.tp_methods = CP_methods;
- ProxyType.tp_traverse = (traverseproc) CP_traverse;
- ProxyType.tp_clear = (inquiry) CP_clear;
- ProxyType.tp_dealloc = (destructor) CP_dealloc;
- ProxyType.tp_weaklistoffset = offsetof(ProxyObject, po_weaklist);
-
- if (PyType_Ready(&ProxyType) < 0)
- return;
-
- Py_INCREF(&ProxyType);
- PyModule_AddObject(m, "ContainedProxyBase", (PyObject *)&ProxyType);
-}
Deleted: zope.app.container/trunk/src/zope/app/container/_zope_proxy_proxy.c
===================================================================
--- zope.app.container/trunk/src/zope/app/container/_zope_proxy_proxy.c 2009-01-29 10:24:21 UTC (rev 95397)
+++ zope.app.container/trunk/src/zope/app/container/_zope_proxy_proxy.c 2009-01-29 10:28:20 UTC (rev 95398)
@@ -1,1098 +0,0 @@
-/*############################################################################
-#
-# Copyright (c) 2004 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (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 file is also used as a really extensive macro in
- * ../app/container/_zope_app_container_contained.c. If you need to
- * change this file, you need to "svn copy" it to ../app/container/.
- *
- * This approach is taken to allow the sources for the two packages
- * to be compilable when the relative locations of these aren't
- * related in the same way as they are in a checkout.
- *
- * This will be revisited in the future, but works for now.
- */
-
-#include "Python.h"
-#include "modsupport.h"
-
-#define PROXY_MODULE
-#include "zope.proxy/proxy.h"
-
-static 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");
- return -1;
- }
- /* If the object in this proxy is not the one we
- * received in args, replace it with the new one.
- */
- if (wrapper->proxy_object != object) {
- PyObject *temp = wrapper->proxy_object;
- Py_INCREF(object);
- wrapper->proxy_object = object;
- Py_DECREF(temp);
- }
- result = 0;
- }
- return result;
-}
-
-static int
-wrap_traverse(PyObject *self, visitproc visit, void *arg)
-{
- PyObject *ob = Proxy_GET_OBJECT(self);
- if (ob != NULL)
- return visit(ob, arg);
- else
- return 0;
-}
-
-static int
-wrap_clear(PyObject *self)
-{
- ProxyObject *proxy = (ProxyObject *)self;
- PyObject *temp = proxy->proxy_object;
-
- if (temp != NULL) {
- proxy->proxy_object = NULL;
- Py_DECREF(temp);
- }
- return 0;
-}
-
-static PyObject *
-wrap_richcompare(PyObject* self, PyObject* other, int op)
-{
- if (Proxy_Check(self)) {
- self = Proxy_GET_OBJECT(self);
- }
- else {
- other = Proxy_GET_OBJECT(other);
- }
- return PyObject_RichCompare(self, other, op);
-}
-
-static PyObject *
-wrap_iter(PyObject *self)
-{
- return PyObject_GetIter(Proxy_GET_OBJECT(self));
-}
-
-static PyObject *
-wrap_iternext(PyObject *self)
-{
- return PyIter_Next(Proxy_GET_OBJECT(self));
-}
-
-static void
-wrap_dealloc(PyObject *self)
-{
- (void) wrap_clear(self);
- self->ob_type->tp_free(self);
-}
-
-/* A variant of _PyType_Lookup that doesn't look in ProxyType.
- *
- * If argument search_wrappertype is nonzero, we can look in WrapperType.
- */
-PyObject *
-WrapperType_Lookup(PyTypeObject *type, PyObject *name)
-{
- int i, n;
- PyObject *mro, *res, *base, *dict;
-
- /* Look in tp_dict of types in MRO */
- mro = type->tp_mro;
-
- /* If mro is NULL, the type is either not yet initialized
- by PyType_Ready(), or already cleared by type_clear().
- Either way the safest thing to do is to return NULL. */
- if (mro == NULL)
- return NULL;
-
- assert(PyTuple_Check(mro));
-
- n = PyTuple_GET_SIZE(mro)
- - 1; /* We don't want to look at the last item, which is object. */
-
- for (i = 0; i < n; i++) {
- base = PyTuple_GET_ITEM(mro, i);
-
- if (((PyTypeObject *)base) != &ProxyType) {
- if (PyClass_Check(base))
- dict = ((PyClassObject *)base)->cl_dict;
- else {
- assert(PyType_Check(base));
- dict = ((PyTypeObject *)base)->tp_dict;
- }
- assert(dict && PyDict_Check(dict));
- res = PyDict_GetItem(dict, name);
- if (res != NULL)
- return res;
- }
- }
- return NULL;
-}
-
-
-static PyObject *
-wrap_getattro(PyObject *self, PyObject *name)
-{
- PyObject *wrapped;
- PyObject *descriptor;
- PyObject *res = NULL;
- char *name_as_string;
- int maybe_special_name;
-
-#ifdef Py_USING_UNICODE
- /* The Unicode to string conversion is done here because the
- existing tp_getattro slots expect a string object as name
- and we wouldn't want to break those. */
- if (PyUnicode_Check(name)) {
- name = PyUnicode_AsEncodedString(name, NULL, NULL);
- if (name == NULL)
- return NULL;
- }
- else
-#endif
- if (!PyString_Check(name)){
- PyErr_SetString(PyExc_TypeError, "attribute name must be string");
- return NULL;
- }
- else
- Py_INCREF(name);
-
- name_as_string = PyString_AS_STRING(name);
- wrapped = Proxy_GET_OBJECT(self);
- if (wrapped == NULL) {
- PyErr_Format(PyExc_RuntimeError,
- "object is NULL; requested to get attribute '%s'",
- name_as_string);
- goto finally;
- }
-
- maybe_special_name = name_as_string[0] == '_' && name_as_string[1] == '_';
-
- if (!(maybe_special_name && strcmp(name_as_string, "__class__") == 0)) {
-
- descriptor = WrapperType_Lookup(self->ob_type, name);
-
- if (descriptor != NULL) {
- if (PyType_HasFeature(descriptor->ob_type, Py_TPFLAGS_HAVE_CLASS)
- && descriptor->ob_type->tp_descr_get != NULL) {
- res = descriptor->ob_type->tp_descr_get(
- descriptor,
- self,
- (PyObject *)self->ob_type);
- } else {
- Py_INCREF(descriptor);
- res = descriptor;
- }
- goto finally;
- }
- }
- res = PyObject_GetAttr(wrapped, name);
-
-finally:
- Py_DECREF(name);
- return res;
-}
-
-static int
-wrap_setattro(PyObject *self, PyObject *name, PyObject *value)
-{
- PyObject *wrapped;
- PyObject *descriptor;
- int res = -1;
-
-#ifdef Py_USING_UNICODE
- /* The Unicode to string conversion is done here because the
- existing tp_setattro slots expect a string object as name
- and we wouldn't want to break those. */
- if (PyUnicode_Check(name)) {
- name = PyUnicode_AsEncodedString(name, NULL, NULL);
- if (name == NULL)
- return -1;
- }
- else
-#endif
- if (!PyString_Check(name)){
- PyErr_SetString(PyExc_TypeError, "attribute name must be string");
- return -1;
- }
- else
- Py_INCREF(name);
-
- descriptor = WrapperType_Lookup(self->ob_type, name);
- if (descriptor != NULL) {
- if (PyType_HasFeature(descriptor->ob_type, Py_TPFLAGS_HAVE_CLASS) &&
- descriptor->ob_type->tp_descr_set != NULL) {
- res = descriptor->ob_type->tp_descr_set(descriptor, self, value);
- } else {
- PyErr_Format(PyExc_TypeError,
- "Tried to set attribute '%s' on wrapper, but it is not"
- " a data descriptor", PyString_AS_STRING(name));
- }
- goto finally;
- }
-
- wrapped = Proxy_GET_OBJECT(self);
- if (wrapped == NULL) {
- PyErr_Format(PyExc_RuntimeError,
- "object is NULL; requested to set attribute '%s'",
- PyString_AS_STRING(name));
- goto finally;
- }
- res = PyObject_SetAttr(wrapped, name, value);
-
-finally:
- Py_DECREF(name);
- return res;
-}
-
-static int
-wrap_print(PyObject *wrapper, FILE *fp, int flags)
-{
- return PyObject_Print(Proxy_GET_OBJECT(wrapper), fp, flags);
-}
-
-static PyObject *
-wrap_str(PyObject *wrapper) {
- return PyObject_Str(Proxy_GET_OBJECT(wrapper));
-}
-
-static PyObject *
-wrap_repr(PyObject *wrapper)
-{
- return PyObject_Repr(Proxy_GET_OBJECT(wrapper));
-}
-
-
-static int
-wrap_compare(PyObject *wrapper, PyObject *v)
-{
- return PyObject_Compare(Proxy_GET_OBJECT(wrapper), v);
-}
-
-static long
-wrap_hash(PyObject *self)
-{
- return PyObject_Hash(Proxy_GET_OBJECT(self));
-}
-
-static PyObject *
-wrap_call(PyObject *self, PyObject *args, PyObject *kw)
-{
- if (kw)
- return PyEval_CallObjectWithKeywords(Proxy_GET_OBJECT(self),
- args, kw);
- else
- return PyObject_CallObject(Proxy_GET_OBJECT(self), args);
-}
-
-/*
- * Number methods
- */
-
-/*
- * Number methods.
- */
-
-static PyObject *
-call_int(PyObject *self)
-{
- PyNumberMethods *nb = self->ob_type->tp_as_number;
- if (nb == NULL || nb->nb_int == NULL) {
- PyErr_SetString(PyExc_TypeError,
- "object can't be converted to int");
- return NULL;
- }
- return nb->nb_int(self);
-}
-
-static PyObject *
-call_long(PyObject *self)
-{
- PyNumberMethods *nb = self->ob_type->tp_as_number;
- if (nb == NULL || nb->nb_long == NULL) {
- PyErr_SetString(PyExc_TypeError,
- "object can't be converted to long");
- return NULL;
- }
- return nb->nb_long(self);
-}
-
-static PyObject *
-call_float(PyObject *self)
-{
- PyNumberMethods *nb = self->ob_type->tp_as_number;
- if (nb == NULL || nb->nb_float== NULL) {
- PyErr_SetString(PyExc_TypeError,
- "object can't be converted to float");
- return NULL;
- }
- return nb->nb_float(self);
-}
-
-static PyObject *
-call_oct(PyObject *self)
-{
- PyNumberMethods *nb = self->ob_type->tp_as_number;
- if (nb == NULL || nb->nb_oct== NULL) {
- PyErr_SetString(PyExc_TypeError,
- "object can't be converted to oct");
- return NULL;
- }
- return nb->nb_oct(self);
-}
-
-static PyObject *
-call_hex(PyObject *self)
-{
- PyNumberMethods *nb = self->ob_type->tp_as_number;
- if (nb == NULL || nb->nb_hex == NULL) {
- PyErr_SetString(PyExc_TypeError,
- "object can't be converted to hex");
- return NULL;
- }
- return nb->nb_hex(self);
-}
-
-static PyObject *
-call_ipow(PyObject *self, PyObject *other)
-{
- /* PyNumber_InPlacePower has three args. How silly. :-) */
- return PyNumber_InPlacePower(self, other, Py_None);
-}
-
-typedef PyObject *(*function1)(PyObject *);
-
-static PyObject *
-check1(ProxyObject *self, char *opname, function1 operation)
-{
- PyObject *result = NULL;
-
- result = operation(Proxy_GET_OBJECT(self));
-#if 0
- if (result != NULL)
- /* ??? create proxy for result? */
- ;
-#endif
- return result;
-}
-
-static PyObject *
-check2(PyObject *self, PyObject *other,
- char *opname, char *ropname, binaryfunc operation)
-{
- PyObject *result = NULL;
- PyObject *object;
-
- if (Proxy_Check(self)) {
- object = Proxy_GET_OBJECT(self);
- result = operation(object, other);
- }
- else if (Proxy_Check(other)) {
- object = Proxy_GET_OBJECT(other);
- result = operation(self, object);
- }
- else {
- Py_INCREF(Py_NotImplemented);
- return Py_NotImplemented;
- }
-#if 0
- if (result != NULL)
- /* ??? create proxy for result? */
- ;
-#endif
- return result;
-}
-
-static PyObject *
-check2i(ProxyObject *self, PyObject *other,
- char *opname, binaryfunc operation)
-{
- PyObject *result = NULL;
- PyObject *object = Proxy_GET_OBJECT(self);
-
- result = operation(object, other);
- if (result == object) {
- /* If the operation was really carried out inplace,
- don't create a new proxy, but use the old one. */
- Py_INCREF(self);
- Py_DECREF(object);
- result = (PyObject *)self;
- }
-#if 0
- else if (result != NULL)
- /* ??? create proxy for result? */
- ;
-#endif
- return result;
-}
-
-#define UNOP(NAME, CALL) \
- static PyObject *wrap_##NAME(PyObject *self) \
- { return check1((ProxyObject *)self, "__"#NAME"__", CALL); }
-
-#define BINOP(NAME, CALL) \
- static PyObject *wrap_##NAME(PyObject *self, PyObject *other) \
- { return check2(self, other, "__"#NAME"__", "__r"#NAME"__", CALL); }
-
-#define INPLACE(NAME, CALL) \
- static PyObject *wrap_i##NAME(PyObject *self, PyObject *other) \
- { return check2i((ProxyObject *)self, other, "__i"#NAME"__", CALL); }
-
-BINOP(add, PyNumber_Add)
-BINOP(sub, PyNumber_Subtract)
-BINOP(mul, PyNumber_Multiply)
-BINOP(div, PyNumber_Divide)
-BINOP(mod, PyNumber_Remainder)
-BINOP(divmod, PyNumber_Divmod)
-
-static PyObject *
-wrap_pow(PyObject *self, PyObject *other, PyObject *modulus)
-{
- PyObject *result = NULL;
- PyObject *object;
-
- if (Proxy_Check(self)) {
- object = Proxy_GET_OBJECT(self);
- result = PyNumber_Power(object, other, modulus);
- }
- else if (Proxy_Check(other)) {
- object = Proxy_GET_OBJECT(other);
- result = PyNumber_Power(self, object, modulus);
- }
- else if (modulus != NULL && Proxy_Check(modulus)) {
- object = Proxy_GET_OBJECT(modulus);
- result = PyNumber_Power(self, other, modulus);
- }
- else {
- Py_INCREF(Py_NotImplemented);
- return Py_NotImplemented;
- }
- return result;
-}
-
-BINOP(lshift, PyNumber_Lshift)
-BINOP(rshift, PyNumber_Rshift)
-BINOP(and, PyNumber_And)
-BINOP(xor, PyNumber_Xor)
-BINOP(or, PyNumber_Or)
-
-static int
-wrap_coerce(PyObject **p_self, PyObject **p_other)
-{
- PyObject *self = *p_self;
- PyObject *other = *p_other;
- PyObject *object;
- PyObject *left;
- PyObject *right;
- int r;
-
- assert(Proxy_Check(self));
- object = Proxy_GET_OBJECT(self);
-
- left = object;
- right = other;
- r = PyNumber_CoerceEx(&left, &right);
- if (r != 0)
- return r;
- /* Now left and right have been INCREF'ed. Any new value that
- comes out is proxied; any unchanged value is left unchanged. */
- if (left == object) {
- /* Keep the old proxy */
- Py_INCREF(self);
- Py_DECREF(left);
- left = self;
- }
-#if 0
- else {
- /* ??? create proxy for left? */
- }
- if (right != other) {
- /* ??? create proxy for right? */
- }
-#endif
- *p_self = left;
- *p_other = right;
- return 0;
-}
-
-UNOP(neg, PyNumber_Negative)
-UNOP(pos, PyNumber_Positive)
-UNOP(abs, PyNumber_Absolute)
-UNOP(invert, PyNumber_Invert)
-
-UNOP(int, call_int)
-UNOP(long, call_long)
-UNOP(float, call_float)
-UNOP(oct, call_oct)
-UNOP(hex, call_hex)
-
-INPLACE(add, PyNumber_InPlaceAdd)
-INPLACE(sub, PyNumber_InPlaceSubtract)
-INPLACE(mul, PyNumber_InPlaceMultiply)
-INPLACE(div, PyNumber_InPlaceDivide)
-INPLACE(mod, PyNumber_InPlaceRemainder)
-INPLACE(pow, call_ipow)
-INPLACE(lshift, PyNumber_InPlaceLshift)
-INPLACE(rshift, PyNumber_InPlaceRshift)
-INPLACE(and, PyNumber_InPlaceAnd)
-INPLACE(xor, PyNumber_InPlaceXor)
-INPLACE(or, PyNumber_InPlaceOr)
-
-BINOP(floordiv, PyNumber_FloorDivide)
-BINOP(truediv, PyNumber_TrueDivide)
-INPLACE(floordiv, PyNumber_InPlaceFloorDivide)
-INPLACE(truediv, PyNumber_InPlaceTrueDivide)
-
-static int
-wrap_nonzero(PyObject *self)
-{
- return PyObject_IsTrue(Proxy_GET_OBJECT(self));
-}
-
-/*
- * Sequence methods
- */
-
-static Py_ssize_t
-wrap_length(PyObject *self)
-{
- return PyObject_Length(Proxy_GET_OBJECT(self));
-}
-
-static PyObject *
-wrap_slice(PyObject *self, Py_ssize_t start, Py_ssize_t end)
-{
- return PySequence_GetSlice(Proxy_GET_OBJECT(self), start, end);
-}
-
-static int
-wrap_ass_slice(PyObject *self, Py_ssize_t i, Py_ssize_t j, PyObject *value)
-{
- return PySequence_SetSlice(Proxy_GET_OBJECT(self), i, j, value);
-}
-
-static int
-wrap_contains(PyObject *self, PyObject *value)
-{
- return PySequence_Contains(Proxy_GET_OBJECT(self), value);
-}
-
-/*
- * Mapping methods
- */
-
-static PyObject *
-wrap_getitem(PyObject *wrapper, PyObject *v) {
- return PyObject_GetItem(Proxy_GET_OBJECT(wrapper), v);
-}
-
-static int
-wrap_setitem(PyObject *self, PyObject *key, PyObject *value)
-{
- if (value == NULL)
- return PyObject_DelItem(Proxy_GET_OBJECT(self), key);
- else
- return PyObject_SetItem(Proxy_GET_OBJECT(self), key, value);
-}
-
-/*
- * Normal methods
- */
-
-static char
-reduce__doc__[] =
-"__reduce__()\n"
-"Raise an exception; this prevents proxies from being picklable by\n"
-"default, even if the underlying object is picklable.";
-
-static PyObject *
-wrap_reduce(PyObject *self)
-{
- PyObject *pickle_error = NULL;
- PyObject *pickle = PyImport_ImportModule("pickle");
-
- if (pickle == NULL)
- PyErr_Clear();
- else {
- pickle_error = PyObject_GetAttrString(pickle, "PicklingError");
- if (pickle_error == NULL)
- PyErr_Clear();
- }
- if (pickle_error == NULL) {
- pickle_error = PyExc_RuntimeError;
- Py_INCREF(pickle_error);
- }
- PyErr_SetString(pickle_error,
- "proxy instances cannot be pickled");
- Py_DECREF(pickle_error);
- return NULL;
-}
-
-static PyNumberMethods
-wrap_as_number = {
- wrap_add, /* nb_add */
- wrap_sub, /* nb_subtract */
- wrap_mul, /* nb_multiply */
- wrap_div, /* nb_divide */
- wrap_mod, /* nb_remainder */
- wrap_divmod, /* nb_divmod */
- wrap_pow, /* nb_power */
- wrap_neg, /* nb_negative */
- wrap_pos, /* nb_positive */
- wrap_abs, /* nb_absolute */
- wrap_nonzero, /* nb_nonzero */
- wrap_invert, /* nb_invert */
- wrap_lshift, /* nb_lshift */
- wrap_rshift, /* nb_rshift */
- wrap_and, /* nb_and */
- wrap_xor, /* nb_xor */
- wrap_or, /* nb_or */
- wrap_coerce, /* nb_coerce */
- wrap_int, /* nb_int */
- wrap_long, /* nb_long */
- wrap_float, /* nb_float */
- wrap_oct, /* nb_oct */
- wrap_hex, /* nb_hex */
-
- /* Added in release 2.0 */
- /* These require the Py_TPFLAGS_HAVE_INPLACEOPS flag */
- wrap_iadd, /* nb_inplace_add */
- wrap_isub, /* nb_inplace_subtract */
- wrap_imul, /* nb_inplace_multiply */
- wrap_idiv, /* nb_inplace_divide */
- wrap_imod, /* nb_inplace_remainder */
- (ternaryfunc)wrap_ipow, /* nb_inplace_power */
- wrap_ilshift, /* nb_inplace_lshift */
- wrap_irshift, /* nb_inplace_rshift */
- wrap_iand, /* nb_inplace_and */
- wrap_ixor, /* nb_inplace_xor */
- wrap_ior, /* nb_inplace_or */
-
- /* Added in release 2.2 */
- /* These require the Py_TPFLAGS_HAVE_CLASS flag */
- wrap_floordiv, /* nb_floor_divide */
- wrap_truediv, /* nb_true_divide */
- wrap_ifloordiv, /* nb_inplace_floor_divide */
- wrap_itruediv, /* nb_inplace_true_divide */
-};
-
-static PySequenceMethods
-wrap_as_sequence = {
- wrap_length, /* sq_length */
- 0, /* sq_concat */
- 0, /* sq_repeat */
- 0, /* sq_item */
- wrap_slice, /* sq_slice */
- 0, /* sq_ass_item */
- wrap_ass_slice, /* sq_ass_slice */
- wrap_contains, /* sq_contains */
-};
-
-static PyMappingMethods
-wrap_as_mapping = {
- wrap_length, /* mp_length */
- wrap_getitem, /* mp_subscript */
- wrap_setitem, /* mp_ass_subscript */
-};
-
-static PyMethodDef
-wrap_methods[] = {
- {"__reduce__", (PyCFunction)wrap_reduce, METH_NOARGS, reduce__doc__},
- {NULL, NULL},
-};
-
-/*
- * Note that the numeric methods are not supported. This is primarily
- * because of the way coercion-less operations are performed with
- * new-style numbers; since we can't tell which side of the operation
- * is 'self', we can't ensure we'd unwrap the right thing to perform
- * the actual operation. We also can't afford to just unwrap both
- * sides the way weakrefs do, since we don't know what semantics will
- * be associated with the wrapper itself.
- */
-
-statichere PyTypeObject
-ProxyType = {
- PyObject_HEAD_INIT(NULL) /* PyObject_HEAD_INIT(&PyType_Type) */
- 0,
- "zope.proxy.ProxyBase",
- sizeof(ProxyObject),
- 0,
- wrap_dealloc, /* tp_dealloc */
- wrap_print, /* tp_print */
- 0, /* tp_getattr */
- 0, /* tp_setattr */
- wrap_compare, /* tp_compare */
- wrap_repr, /* tp_repr */
- &wrap_as_number, /* tp_as_number */
- &wrap_as_sequence, /* tp_as_sequence */
- &wrap_as_mapping, /* tp_as_mapping */
- wrap_hash, /* tp_hash */
- wrap_call, /* tp_call */
- wrap_str, /* tp_str */
- wrap_getattro, /* tp_getattro */
- wrap_setattro, /* tp_setattro */
- 0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC
- | Py_TPFLAGS_CHECKTYPES | Py_TPFLAGS_BASETYPE, /* tp_flags */
- 0, /* tp_doc */
- wrap_traverse, /* tp_traverse */
- wrap_clear, /* tp_clear */
- wrap_richcompare, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- wrap_iter, /* tp_iter */
- wrap_iternext, /* tp_iternext */
- wrap_methods, /* tp_methods */
- 0, /* tp_members */
- 0, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- wrap_init, /* tp_init */
- 0, /* tp_alloc */
- wrap_new, /* tp_new */
- 0, /*_PyObject_GC_Del,*/ /* tp_free */
-};
-
-static PyObject *
-create_proxy(PyObject *object)
-{
- PyObject *result = NULL;
- PyObject *args;
-
- args = PyTuple_New(1);
- if (args != NULL) {
- Py_INCREF(object);
- PyTuple_SET_ITEM(args, 0, object);
- result = PyObject_CallObject((PyObject *)&ProxyType, args);
- Py_DECREF(args);
- }
- return result;
-}
-
-static int
-api_check(PyObject *obj)
-{
- return obj ? Proxy_Check(obj) : 0;
-}
-
-static PyObject *
-api_create(PyObject *object)
-{
- if (object == NULL) {
- PyErr_SetString(PyExc_ValueError,
- "cannot create proxy around NULL");
- return NULL;
- }
- return create_proxy(object);
-}
-
-static PyObject *
-api_getobject(PyObject *proxy)
-{
- if (proxy == NULL) {
- PyErr_SetString(PyExc_RuntimeError,
- "cannot pass NULL to ProxyAPI.getobject()");
- return NULL;
- }
- if (Proxy_Check(proxy))
- return Proxy_GET_OBJECT(proxy);
- else {
- PyErr_Format(PyExc_TypeError, "expected proxy object, got %s",
- proxy->ob_type->tp_name);
- return NULL;
- }
-}
-
-static ProxyInterface
-wrapper_capi = {
- &ProxyType,
- api_check,
- api_create,
- api_getobject,
-};
-
-static PyObject *api_object = NULL;
-
-
-static char
-getobject__doc__[] =
-"getProxiedObject(proxy) --> object\n"
-"\n"
-"Get the underlying object for proxy, or the object itself, if it is\n"
-"not a proxy.";
-
-static PyObject *
-wrapper_getobject(PyObject *unused, PyObject *obj)
-{
- if (Proxy_Check(obj))
- obj = Proxy_GET_OBJECT(obj);
-
- if (obj == NULL)
- obj = Py_None;
-
- Py_INCREF(obj);
- return obj;
-}
-
-static char
-isProxy__doc__[] =
-"Check whether the given object is a proxy\n"
-"\n"
-"If proxytype is not None, checkes whether the object is\n"
-"proxied by the given proxytype.\n"
-;
-
-static PyObject *
-wrapper_isProxy(PyObject *unused, PyObject *args)
-{
- PyObject *obj, *result;
- PyTypeObject *proxytype=&ProxyType;
-
- if (! PyArg_ParseTuple(args, "O|O!:isProxy",
- &obj, &PyType_Type, &proxytype)
- )
- return NULL;
-
- while (obj && Proxy_Check(obj))
- {
- if (PyObject_TypeCheck(obj, proxytype))
- {
- result = Py_True;
- Py_INCREF(result);
- return result;
- }
- obj = Proxy_GET_OBJECT(obj);
- }
- result = Py_False;
- Py_INCREF(result);
- return result;
-}
-
-static char
-removeAllProxies__doc__[] =
-"removeAllProxies(proxy) --> object\n"
-"\n"
-"Get the proxied object with no proxies\n"
-"\n"
-"If obj is not a proxied object, return obj.\n"
-"\n"
-"The returned object has no proxies.\n"
-;
-
-static PyObject *
-wrapper_removeAllProxies(PyObject *unused, PyObject *obj)
-{
- while (obj && Proxy_Check(obj))
- obj = Proxy_GET_OBJECT(obj);
-
- if (obj == NULL)
- obj = Py_None;
-
- Py_INCREF(obj);
- return obj;
-}
-
-static char
-sameProxiedObjects__doc__[] =
-"Check whether two objects are the same or proxies of the same object";
-
-static PyObject *
-wrapper_sameProxiedObjects(PyObject *unused, PyObject *args)
-{
- PyObject *ob1, *ob2;
-
- if (! PyArg_ParseTuple(args, "OO:sameProxiedObjects", &ob1, &ob2))
- return NULL;
-
- while (ob1 && Proxy_Check(ob1))
- ob1 = Proxy_GET_OBJECT(ob1);
-
- while (ob2 && Proxy_Check(ob2))
- ob2 = Proxy_GET_OBJECT(ob2);
-
- if (ob1 == ob2)
- ob1 = Py_True;
- else
- ob1 = Py_False;
-
- Py_INCREF(ob1);
- return ob1;
-}
-
-
-static char
-queryProxy__doc__[] =
-"Look for a proxy of the given type around the object\n"
-"\n"
-"If no such proxy can be found, return the default.\n"
-;
-
-static PyObject *
-wrapper_queryProxy(PyObject *unused, PyObject *args)
-{
- PyObject *obj, *result=Py_None;
- PyTypeObject *proxytype=&ProxyType;
-
- if (! PyArg_ParseTuple(args, "O|O!O:queryProxy",
- &obj, &PyType_Type, &proxytype, &result)
- )
- return NULL;
-
- while (obj && Proxy_Check(obj))
- {
- if (PyObject_TypeCheck(obj, proxytype))
- {
- Py_INCREF(obj);
- return obj;
- }
- obj = Proxy_GET_OBJECT(obj);
- }
-
- Py_INCREF(result);
- return result;
-}
-
-static char
-queryInnerProxy__doc__[] =
-"Look for the inner-most proxy of the given type around the object\n"
-"\n"
-"If no such proxy can be found, return the default.\n"
-"\n"
-"If there is such a proxy, return the inner-most one.\n"
-;
-
-static PyObject *
-wrapper_queryInnerProxy(PyObject *unused, PyObject *args)
-{
- PyObject *obj, *result=Py_None;
- PyTypeObject *proxytype=&ProxyType;
-
- if (! PyArg_ParseTuple(args, "O|O!O:queryInnerProxy",
- &obj, &PyType_Type, &proxytype, &result)
- )
- return NULL;
-
- while (obj && Proxy_Check(obj))
- {
- if (PyObject_TypeCheck(obj, proxytype))
- result = obj;
- obj = Proxy_GET_OBJECT(obj);
- }
-
- Py_INCREF(result);
- return result;
-}
-
-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 PyMethodDef
-module_functions[] = {
- {"getProxiedObject", wrapper_getobject, METH_O, getobject__doc__},
- {"isProxy", wrapper_isProxy, METH_VARARGS, isProxy__doc__},
- {"sameProxiedObjects", wrapper_sameProxiedObjects, METH_VARARGS,
- sameProxiedObjects__doc__},
- {"queryProxy", wrapper_queryProxy, METH_VARARGS, queryProxy__doc__},
- {"queryInnerProxy", wrapper_queryInnerProxy, METH_VARARGS,
- queryInnerProxy__doc__},
- {"removeAllProxies", wrapper_removeAllProxies, METH_O,
- removeAllProxies__doc__},
- {NULL}
-};
-
-void
-init_zope_proxy_proxy(void)
-{
- PyObject *m = Py_InitModule3("_zope_proxy_proxy",
- module_functions, module___doc__);
-
- if (m == NULL)
- return;
-
- if (empty_tuple == NULL)
- empty_tuple = PyTuple_New(0);
-
- ProxyType.tp_free = _PyObject_GC_Del;
-
- if (PyType_Ready(&ProxyType) < 0)
- return;
-
- Py_INCREF(&ProxyType);
- PyModule_AddObject(m, "ProxyBase", (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);
-}
Modified: zope.app.container/trunk/src/zope/app/container/btree.py
===================================================================
--- zope.app.container/trunk/src/zope/app/container/btree.py 2009-01-29 10:24:21 UTC (rev 95397)
+++ zope.app.container/trunk/src/zope/app/container/btree.py 2009-01-29 10:28:20 UTC (rev 95398)
@@ -11,106 +11,7 @@
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
-"""This module provides a sample btree container implementation.
-
-$Id$
+"""BBB this module moved to zope.container
"""
-__docformat__ = 'restructuredtext'
-from persistent import Persistent
-from BTrees.OOBTree import OOBTree
-from BTrees.Length import Length
-
-from zope.app.container.interfaces import IBTreeContainer
-from zope.app.container.contained import Contained, setitem, uncontained
-from zope.cachedescriptors.property import Lazy
-from zope.interface import implements
-
-
-class BTreeContainer(Contained, Persistent):
-
- implements(IBTreeContainer)
-
- def __init__(self):
- # We keep the previous attribute to store the data
- # for backward compatibility
- self._SampleContainer__data = self._newContainerData()
- self.__len = Length()
-
- def _newContainerData(self):
- """Construct an item-data container
-
- Subclasses should override this if they want different data.
-
- The value returned is a mapping object that also has get,
- has_key, keys, items, and values methods.
- The default implementation uses an OOBTree.
- """
- return OOBTree()
-
- def __contains__(self, key):
- '''See interface IReadContainer
-
- >>> c = BTreeContainer()
- >>> "a" in c
- False
- >>> c["a"] = 1
- >>> "a" in c
- True
- >>> "A" in c
- False
- '''
- return key in self._SampleContainer__data
-
- @Lazy
- def _BTreeContainer__len(self):
- l = Length()
- ol = len(self._SampleContainer__data)
- if ol > 0:
- l.change(ol)
- self._p_changed = True
- return l
-
- def __len__(self):
- return self.__len()
-
- def _setitemf(self, key, value):
- # make sure our lazy property gets set
- l = self.__len
- self._SampleContainer__data[key] = value
- l.change(1)
-
- def __iter__(self):
- return iter(self._SampleContainer__data)
-
- def __getitem__(self, key):
- '''See interface `IReadContainer`'''
- return self._SampleContainer__data[key]
-
- def get(self, key, default=None):
- '''See interface `IReadContainer`'''
- return self._SampleContainer__data.get(key, default)
-
- def __setitem__(self, key, value):
- setitem(self, self._setitemf, key, value)
-
- def __delitem__(self, key):
- # make sure our lazy property gets set
- l = self.__len
- uncontained(self._SampleContainer__data[key], self, key)
- del self._SampleContainer__data[key]
- l.change(-1)
-
- has_key = __contains__
-
- def items(self, key=None):
- return self._SampleContainer__data.items(key)
-
- def keys(self, key=None):
- return self._SampleContainer__data.keys(key)
-
- def values(self, key=None):
- return self._SampleContainer__data.values(key)
-
-
-
+from zope.container.btree import BTreeContainer # BBB
Modified: zope.app.container/trunk/src/zope/app/container/configure.zcml
===================================================================
--- zope.app.container/trunk/src/zope/app/container/configure.zcml 2009-01-29 10:24:21 UTC (rev 95397)
+++ zope.app.container/trunk/src/zope/app/container/configure.zcml 2009-01-29 10:28:20 UTC (rev 95398)
@@ -5,84 +5,5 @@
i18n_domain="zope"
>
- <adapter
- provides=".interfaces.IFind"
- for=".interfaces.IReadContainer"
- permission="zope.ManageContent"
- factory="zope.app.container.find.FindAdapter"
- />
-
- <adapter
- for=".interfaces.IReadContainer"
- provides="zope.filerepresentation.interfaces.IReadDirectory"
- factory=".directory.noop"
- />
-
- <adapter
- for=".interfaces.IWriteContainer"
- provides="zope.filerepresentation.interfaces.IWriteDirectory"
- factory=".directory.noop"
- />
-
- <adapter
- factory="zope.app.container.traversal.ContainerTraversable"
- provides="zope.traversing.interfaces.ITraversable"
- for="zope.app.container.interfaces.IReadContainer"
- />
-
-
- <adapter
- factory="zope.app.container.size.ContainerSized"
- provides="zope.size.interfaces.ISized"
- for="zope.app.container.interfaces.IReadContainer"
- />
-
- <adapter
- provides=".interfaces.INameChooser"
- for="zope.app.container.interfaces.IWriteContainer"
- factory=".contained.NameChooser"
- />
-
- <subscriber
- handler=".dependency.CheckDependency"
- for="zope.app.container.interfaces.IObjectRemovedEvent"
- trusted="y"
- />
-
- <subscriber
- for="zope.location.interfaces.ILocation
- zope.app.container.interfaces.IObjectMovedEvent"
- handler=".contained.dispatchToSublocations"
- >
- Handler dispatches moved events to sublocations of the original object.
- </subscriber>
-
- <adapter
- provides="zope.location.interfaces.ISublocations"
- for="zope.app.container.interfaces.IReadContainer"
- factory=".contained.ContainerSublocations"
- />
-
- <class class=".constraints.ItemTypePrecondition">
- <allow interface=".constraints.IItemTypePrecondition" />
- </class>
-
- <view
- for="zope.app.container.interfaces.IItemContainer"
- type="zope.publisher.interfaces.browser.IBrowserRequest"
- provides="zope.publisher.interfaces.browser.IBrowserPublisher"
- factory="zope.app.container.traversal.ItemTraverser"
- permission="zope.Public"
- allowed_interface="zope.publisher.interfaces.browser.IBrowserPublisher"
- />
-
- <view
- for="zope.app.container.interfaces.ISimpleReadContainer"
- type="zope.publisher.interfaces.browser.IBrowserRequest"
- provides="zope.publisher.interfaces.browser.IBrowserPublisher"
- factory="zope.app.container.traversal.ItemTraverser"
- permission="zope.Public"
- allowed_interface="zope.publisher.interfaces.browser.IBrowserPublisher"
- />
-
+ <include package="zope.container"/>
</configure>
Modified: zope.app.container/trunk/src/zope/app/container/constraints.py
===================================================================
--- zope.app.container/trunk/src/zope/app/container/constraints.py 2009-01-29 10:24:21 UTC (rev 95397)
+++ zope.app.container/trunk/src/zope/app/container/constraints.py 2009-01-29 10:28:20 UTC (rev 95398)
@@ -11,451 +11,28 @@
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
-"""Support for containment constraints
+"""BBB this module moved to zope.container
+"""
- Either a container or an object can provide constraints on the
- containment relationship.
+# BBB
+from zope.container.constraints import (
+ checkObject,
+ checkFactory,
+ IItemTypePrecondition,
+ _TypesBased,
+ ItemTypePrecondition,
+ contains,
+ IContainerTypesConstraint,
+ ContainerTypesConstraint,
+ containers
+)
- A container expresses constraints through a precondition on it's
- `__setitem__` method in it's interface.
- Preconditions can be simple callable objects, like functions. They
- should raise a ``zope.interface.Invalid`` exception to indicate that a
- constraint isn't satisfied:
- >>> def preNoZ(container, name, ob):
- ... "Silly precondition example"
- ... if name.startswith("Z"):
- ... raise zope.interface.Invalid("Names can not start with Z")
- >>> class I1(zope.interface.Interface):
- ... def __setitem__(name, on):
- ... "Add an item"
- ... __setitem__.precondition = preNoZ
- >>> from zope.app.container.interfaces import IContainer
- >>> class C1(object):
- ... zope.interface.implements(I1, IContainer)
- ... def __repr__(self):
- ... return 'C1'
- Given such a precondition, we can then check whether an object can be
- added:
- >>> c1 = C1()
- >>> checkObject(c1, "bob", None)
- >>> checkObject(c1, "Zbob", None)
- Traceback (most recent call last):
- ...
- Invalid: Names can not start with Z
- We can also express constaints on the containers an object can be
- added to. We do this by setting a field constraint on an object's
- `__parent__` attribute:
- >>> import zope.schema
- A field constraint is a callable object that returns a boolean value:
-
- >>> def con1(container):
- ... "silly container constraint"
- ... if not hasattr(container, 'x'):
- ... return False
- ... return True
-
- >>> class I2(zope.interface.Interface):
- ... __parent__ = zope.schema.Field(constraint = con1)
-
- >>> class O(object):
- ... zope.interface.implements(I2)
-
- If the constraint isn't satisfied, we'll get a validation error when we
- check whether the object can be added:
-
- >>> checkObject(c1, "bob", O())
- Traceback (most recent call last):
- ...
- ConstraintNotSatisfied: C1
-
- Note that the validation error isn't very informative. For that
- reason, it's better for constraints to raise Invalid errors when they
- aren't satisfied:
-
- >>> def con1(container):
- ... "silly container constraint"
- ... if not hasattr(container, 'x'):
- ... raise zope.interface.Invalid("What, no x?")
- ... return True
-
- >>> class I2(zope.interface.Interface):
- ... __parent__ = zope.schema.Field(constraint = con1)
-
- >>> class O(object):
- ... zope.interface.implements(I2)
-
- >>> checkObject(c1, "bob", O())
- Traceback (most recent call last):
- ...
- Invalid: What, no x?
-
- >>> c1.x = 1
- >>> checkObject(c1, "bob", O())
-
- The `checkObject` function is handy when checking whether we can add an
- existing object to a container, but, sometimes, we want to check
- whether an object produced by a factory can be added. To do this, we
- use `checkFactory`:
-
- >>> class Factory(object):
- ... def __call__(self):
- ... return O()
- ... def getInterfaces(self):
- ... return zope.interface.implementedBy(O)
-
- >>> factory = Factory()
-
- >>> checkFactory(c1, "bob", factory)
- True
-
- >>> del c1.x
- >>> checkFactory(c1, "bob", factory)
- False
-
- Unlike `checkObject`, `checkFactory`:
-
- - Returns a boolean value
-
- - Takes a factory (e.g. a class) rather than an argument.
-
- The container constraint we defined for C1 isn't actually used to
- check the factory:
-
- >>> c1.x = 1
- >>> checkFactory(c1, "Zbob", factory)
- True
-
- To work with `checkFactory`, a container precondition has to
- implement a factory method. This is because a factory, rather than
- an object is passed. To illustrate this, we'll make preNoZ its own
- factory method:
-
- >>> preNoZ.factory = preNoZ
-
- We can do this (silly thing) because preNoZ doesn't use the object
- argument.
-
- >>> checkFactory(c1, "Zbob", factory)
- False
-
- $Id$
- """
-__docformat__ = 'restructuredtext'
-
-import sys
-
-from zope.cachedescriptors.property import readproperty
-from zope.dottedname.resolve import resolve
-import zope.schema
-from zope.interface import providedBy
-from zope.app.container.interfaces import InvalidItemType, InvalidContainerType
-from zope.app.container.i18n import ZopeMessageFactory as _
-from zope.app.container.interfaces import IContainer
-
-def checkObject(container, name, object):
- """Check containement constraints for an object and container
- """
-
- # check __setitem__ precondition
- containerProvided = providedBy(container)
- __setitem__ = containerProvided.get('__setitem__')
- if __setitem__ is not None:
- precondition = __setitem__.queryTaggedValue('precondition')
- if precondition is not None:
- precondition(container, name, object)
-
- # check the constraint on __parent__
- __parent__ = providedBy(object).get('__parent__')
- if __parent__ is not None:
- try:
- validate = __parent__.validate
- except AttributeError:
- pass
- else:
- validate(container)
-
-
- if not containerProvided.extends(IContainer):
- # If it doesn't implement IContainer, it can't contain stuff.
- raise TypeError(
- _('Container is not a valid Zope container.')
- )
-
-def checkFactory(container, name, factory):
- __setitem__ = providedBy(container).get('__setitem__')
- if __setitem__ is not None:
- precondition = __setitem__.queryTaggedValue('precondition')
- if precondition is not None:
- try:
- precondition = precondition.factory
- except AttributeError:
- pass
- else:
- try:
- precondition(container, name, factory)
- except zope.interface.Invalid:
- return False
-
- # check the constraint on __parent__
- __parent__ = factory.getInterfaces().get('__parent__')
- if __parent__ is not None:
- try:
- validate = __parent__.validate
- except AttributeError:
- pass
- else:
- try:
- validate(container)
- except zope.interface.Invalid:
- return False
-
- return True
-
-class IItemTypePrecondition(zope.interface.Interface):
-
- def __call__(container, name, object):
- """Test whether container setitem arguments are valid.
-
- Raise zope.interface.Invalid if the object is invalid.
- """
-
- def factory(container, name, factory):
- """Test whether objects provided by the factory are acceptable
-
- Return a boolean value.
- """
-
-
-class _TypesBased(object):
-
- @readproperty
- def types(self):
- raw_types, module = self.raw_types
- types = []
- for t in raw_types:
- if isinstance(t, str):
- t = resolve(t, module)
- types.append(t)
-
- self.types = types
- return types
-
- def __init__(self, *types, **kw):
- if [t for t in types if isinstance(t, str)]:
- # have dotted names
- module = kw.get('module', sys._getframe(1).f_globals['__name__'])
- self.raw_types = types, module
- else:
- self.types = types
-
-
-class ItemTypePrecondition(_TypesBased):
- """Specify a `__setitem__` precondition that restricts item types
-
- Items must be one of the given types.
-
- >>> class I1(zope.interface.Interface):
- ... pass
- >>> class I2(zope.interface.Interface):
- ... pass
-
-
- >>> precondition = ItemTypePrecondition(I1, I2)
-
- >>> class Ob(object):
- ... pass
- >>> ob = Ob()
-
- >>> class Factory(object):
- ... def __call__(self):
- ... return Ob()
- ... def getInterfaces(self):
- ... return zope.interface.implementedBy(Ob)
-
- >>> factory = Factory()
-
- >>> try:
- ... precondition(None, 'foo', ob)
- ... except InvalidItemType, v:
- ... print v[0], (v[1] is ob), (v[2] == (I1, I2))
- ... else:
- ... print 'Should have failed'
- None True True
-
- >>> try:
- ... precondition.factory(None, 'foo', factory)
- ... except InvalidItemType, v:
- ... print v[0], (v[1] is factory), (v[2] == (I1, I2))
- ... else:
- ... print 'Should have failed'
- None True True
-
- >>> zope.interface.classImplements(Ob, I2)
- >>> precondition(None, 'foo', ob)
- >>> precondition.factory(None, 'foo', factory)
-
- """
-
- zope.interface.implements(IItemTypePrecondition)
-
- def __call__(self, container, name, object):
- for iface in self.types:
- if iface.providedBy(object):
- return
- raise InvalidItemType(container, object, self.types)
-
- def factory(self, container, name, factory):
- implemented = factory.getInterfaces()
-
- for iface in self.types:
- if implemented.isOrExtends(iface):
- return
- raise InvalidItemType(container, factory, self.types)
-
-
-def contains(*types):
- """Declare that a container type contains only the given types
-
- This is used within a class suite defining an interface to create
- a __setitem__ specification with a precondition allowing only the
- given types:
-
- >>> class IFoo(zope.interface.Interface):
- ... pass
- >>> class IBar(zope.interface.Interface):
- ... pass
- >>> class IFooBarContainer(IContainer):
- ... contains(IFoo, IBar)
-
- >>> __setitem__ = IFooBarContainer['__setitem__']
- >>> __setitem__.getTaggedValue('precondition').types == (IFoo, IBar)
- True
-
- It is invalid to call contains outside a class suite:
-
- >>> contains(IFoo, IBar)
- Traceback (most recent call last):
- ...
- TypeError: contains not called from suite
- """
-
- frame = sys._getframe(1)
- f_locals = frame.f_locals
- f_globals = frame.f_globals
-
- if not (f_locals is not f_globals
- and f_locals.get('__module__')
- and f_locals.get('__module__') == f_globals.get('__name__')
- ):
- raise TypeError("contains not called from suite")
-
- def __setitem__(key, value):
- pass
- __setitem__.__doc__ = IContainer['__setitem__'].__doc__
- __setitem__.precondition = ItemTypePrecondition(
- *types,
- **dict(module=f_globals['__name__'])
- )
- f_locals['__setitem__'] = __setitem__
-
-
-class IContainerTypesConstraint(zope.interface.Interface):
-
- def __call__(object):
- """Test whether object is valid.
-
- Return True if valid.
- Raise zope.interface.Invalid if the objet is invalid.
- """
-
-
-class ContainerTypesConstraint(_TypesBased):
- """Constrain a container to be one of a number of types
-
- >>> class I1(zope.interface.Interface):
- ... pass
- >>> class I2(zope.interface.Interface):
- ... pass
- >>> class Ob(object):
- ... pass
- >>> ob = Ob()
- >>> constraint = ContainerTypesConstraint(I1, I2)
- >>> try:
- ... constraint(ob)
- ... except InvalidContainerType, v:
- ... print (v[0] is ob), (v[1] == (I1, I2))
- ... else:
- ... print 'Should have failed'
- True True
-
- >>> zope.interface.classImplements(Ob, I2)
- >>> constraint(Ob())
- True
-
- """
-
- zope.interface.implements(IContainerTypesConstraint)
-
- def __call__(self, object):
- for iface in self.types:
- if iface.providedBy(object):
- return True
- else:
- raise InvalidContainerType(object, self.types)
-
-
-def containers(*types):
- """Declare the container types a type can be contained in
-
- This is used within a class suite defining an interface to create
- a __parent__ specification with a constraint allowing only the
- given types:
-
- >>> class IFoo(IContainer):
- ... pass
- >>> class IBar(IContainer):
- ... pass
-
- >>> from zope.app.container.interfaces import IContained
- >>> class IFooBarContained(IContained):
- ... containers(IFoo, IBar)
-
- >>> __parent__ = IFooBarContained['__parent__']
- >>> __parent__.constraint.types == (IFoo, IBar)
- True
-
- It is invalid to call containers outside a class suite:
-
- >>> containers(IFoo, IBar)
- Traceback (most recent call last):
- ...
- TypeError: containers not called from suite
- """
-
- frame = sys._getframe(1)
- f_locals = frame.f_locals
- f_globals = frame.f_globals
-
- if not (f_locals is not f_globals
- and f_locals.get('__module__')
- and f_locals.get('__module__') == f_globals.get('__name__')
- ):
- raise TypeError("containers not called from suite")
-
- __parent__ = zope.schema.Field(
- constraint = ContainerTypesConstraint(
- *types,
- **dict(module=f_globals['__name__'])
- )
- )
- f_locals['__parent__'] = __parent__
-
Deleted: zope.app.container/trunk/src/zope/app/container/constraints.txt
===================================================================
--- zope.app.container/trunk/src/zope/app/container/constraints.txt 2009-01-29 10:24:21 UTC (rev 95397)
+++ zope.app.container/trunk/src/zope/app/container/constraints.txt 2009-01-29 10:28:20 UTC (rev 95398)
@@ -1,97 +0,0 @@
-Containment constraints
-=======================
-
-Containment constraints allow us to express restrictions on the types
-of items that can be placed in containers or on the types of
-containers an item can be placed in. We express these constraints in
-interfaces. Let's define some container and item interfaces:
-
- >>> from zope.app.container.interfaces import IContainer, IContained
- >>> from zope.app.container.constraints import containers, contains
-
- >>> class IBuddyFolder(IContainer):
- ... contains('.IBuddy')
-
-
-In this example, we used the contains function to declare that objects
-that provide IBuddyFolder can only contain items that provide IBuddy.
-Note that we used a string containing a dotted name for the IBuddy
-interface. This is because IBuddy hasn't been defined yet. When we
-define IBuddy, we can use IBuddyFolder directly:
-
- >>> class IBuddy(IContained):
- ... containers(IBuddyFolder)
-
-
-Now, with these interfaces in place, we can define Buddy and
-BuddyFolder classes and verify that we can put buddies in buddy
-folders:
-
- >>> from zope import interface
-
- >>> class Buddy:
- ... interface.implements(IBuddy)
-
- >>> class BuddyFolder:
- ... interface.implements(IBuddyFolder)
-
- >>> from zope.app.container.constraints import checkObject, checkFactory
- >>> from zope.component.factory import Factory
-
- >>> checkObject(BuddyFolder(), 'x', Buddy())
- >>> checkFactory(BuddyFolder(), 'x', Factory(Buddy))
- True
-
-If we try to use other containers or folders, we'll get errors:
-
- >>> class Container:
- ... interface.implements(IContainer)
-
- >>> class Contained:
- ... interface.implements(IContained)
-
- >>> checkObject(Container(), 'x', Buddy())
- ... # doctest: +ELLIPSIS
- Traceback (most recent call last):
- InvalidContainerType: ...
-
- >>> checkFactory(Container(), 'x', Factory(Buddy))
- False
-
- >>> checkObject(BuddyFolder(), 'x', Contained())
- ... # doctest: +ELLIPSIS
- Traceback (most recent call last):
- InvalidItemType: ...
-
- >>> checkFactory(BuddyFolder(), 'x', Factory(Contained))
- False
-
-In the example, we defined the container first and then the items. We
-could have defined these in the opposite order:
-
- >>> class IContact(IContained):
- ... containers('.IContacts')
-
- >>> class IContacts(IContainer):
- ... contains(IContact)
-
- >>> class Contact:
- ... interface.implements(IContact)
-
- >>> class Contacts:
- ... interface.implements(IContacts)
-
- >>> checkObject(Contacts(), 'x', Contact())
-
- >>> checkFactory(Contacts(), 'x', Factory(Contact))
- True
-
- >>> checkObject(Contacts(), 'x', Buddy())
- ... # doctest: +ELLIPSIS
- Traceback (most recent call last):
- InvalidItemType: ...
-
- >>> checkFactory(Contacts(), 'x', Factory(Buddy))
- False
-
-
Modified: zope.app.container/trunk/src/zope/app/container/contained.py
===================================================================
--- zope.app.container/trunk/src/zope/app/container/contained.py 2009-01-29 10:24:21 UTC (rev 95397)
+++ zope.app.container/trunk/src/zope/app/container/contained.py 2009-01-29 10:28:20 UTC (rev 95398)
@@ -11,908 +11,27 @@
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
-"""Classes to support implementing `IContained`
-
-$Id$
+"""BBB this module moved to zope.container
"""
-__docformat__ = 'restructuredtext'
-import zope.component
-import zope.interface.declarations
-from zope.interface import providedBy
-from zope.interface.declarations import getObjectSpecification
-from zope.interface.declarations import ObjectSpecification
-from zope.event import notify
-from zope.component.interfaces import ObjectEvent
-from zope.location.interfaces import ILocation, ISublocations
-from zope.exceptions.interfaces import DuplicationError, UserError
-from zope.security.checker import selectChecker, CombinedChecker
-from zope.lifecycleevent import ObjectModifiedEvent
-
-from zope.app.container.i18n import ZopeMessageFactory as _
-from zope.app.container.interfaces import IContained
-from zope.app.container.interfaces import INameChooser
-from zope.app.container.interfaces import IObjectAddedEvent
-from zope.app.container.interfaces import IObjectMovedEvent
-from zope.app.container.interfaces import IObjectRemovedEvent
-from zope.app.container.interfaces import IContainerModifiedEvent
-from zope.app.container._zope_app_container_contained import ContainedProxyBase
-from zope.app.container._zope_app_container_contained import getProxiedObject
-from zope.app.broken.interfaces import IBroken
-
-class Contained(object):
- """Stupid mix-in that defines `__parent__` and `__name__` attributes"""
-
- zope.interface.implements(IContained)
-
- __parent__ = __name__ = None
-
-class ObjectMovedEvent(ObjectEvent):
- """An object has been moved"""
-
- zope.interface.implements(IObjectMovedEvent)
-
- def __init__(self, object, oldParent, oldName, newParent, newName):
- ObjectEvent.__init__(self, object)
- self.oldParent = oldParent
- self.oldName = oldName
- self.newParent = newParent
- self.newName = newName
-
-class ObjectAddedEvent(ObjectMovedEvent):
- """An object has been added to a container"""
-
- zope.interface.implements(IObjectAddedEvent)
-
- def __init__(self, object, newParent=None, newName=None):
- if newParent is None:
- newParent = object.__parent__
- if newName is None:
- newName = object.__name__
- ObjectMovedEvent.__init__(self, object, None, None, newParent, newName)
-
-class ObjectRemovedEvent(ObjectMovedEvent):
- """An object has been removed from a container"""
-
- zope.interface.implements(IObjectRemovedEvent)
-
- def __init__(self, object, oldParent=None, oldName=None):
- if oldParent is None:
- oldParent = object.__parent__
- if oldName is None:
- oldName = object.__name__
- ObjectMovedEvent.__init__(self, object, oldParent, oldName, None, None)
-
-class ContainerModifiedEvent(ObjectModifiedEvent):
- """The container has been modified."""
-
- zope.interface.implements(IContainerModifiedEvent)
-
-
-def dispatchToSublocations(object, event):
- """Dispatch an event to sublocations of a given object
-
- When a move event happens for an object, it's important to notify
- subobjects as well.
-
- We do this based on locations.
-
- Suppose, for example, that we define some location objects.
-
- >>> class L(object):
- ... zope.interface.implements(ILocation)
- ... def __init__(self, name):
- ... self.__name__ = name
- ... self.__parent__ = None
- ... def __repr__(self):
- ... return '%s(%s)' % (
- ... self.__class__.__name__, str(self.__name__))
-
- >>> class C(L):
- ... zope.interface.implements(ISublocations)
- ... def __init__(self, name, *subs):
- ... L.__init__(self, name)
- ... self.subs = subs
- ... for sub in subs:
- ... sub.__parent__ = self
- ... def sublocations(self):
- ... return self.subs
-
- >>> c = C(1,
- ... C(11,
- ... L(111),
- ... L(112),
- ... ),
- ... C(12,
- ... L(121),
- ... L(122),
- ... L(123),
- ... L(124),
- ... ),
- ... L(13),
- ... )
-
- Now, if we call the dispatcher, it should call event handlers
- for all of the objects.
-
- Lets create an event handler that records the objects it sees:
-
- >>> seen = []
- >>> def handler(ob, event):
- ... seen.append((ob, event.object))
-
- Note that we record the the object the handler is called on as
- well as the event object:
-
- Now we'll register it:
-
- >>> from zope.app.testing import ztapi
- >>> ztapi.subscribe([None, IObjectMovedEvent], None, handler)
-
- We also register our dispatcher:
-
- >>> ztapi.subscribe([None, IObjectMovedEvent], None,
- ... dispatchToSublocations)
-
- We can then call the dispatcher for the root object:
-
- >>> event = ObjectRemovedEvent(c)
- >>> dispatchToSublocations(c, event)
-
- Now, we should have seen all of the subobjects:
-
- >>> seenreprs = map(repr, seen)
- >>> seenreprs.sort()
- >>> seenreprs
- ['(C(11), C(1))', '(C(12), C(1))', '(L(111), C(1))',""" \
- """ '(L(112), C(1))', '(L(121), C(1))', '(L(122), C(1))',""" \
- """ '(L(123), C(1))', '(L(124), C(1))', '(L(13), C(1))']
-
- We see that we get entries for each of the subobjects and
- that,for each entry, the event object is top object.
-
- This suggests that location event handlers need to be aware that
- the objects they are called on and the event objects could be
- different.
-
- """
- subs = ISublocations(object, None)
- if subs is not None:
- for sub in subs.sublocations():
- for ignored in zope.component.subscribers((sub, event), None):
- pass # They do work in the adapter fetch
-
-class ContainerSublocations(object):
- """Get the sublocations for a container
-
- Obviously, this is the container values:
-
- >>> class MyContainer(object):
- ... def __init__(self, **data):
- ... self.data = data
- ... def __iter__(self):
- ... return iter(self.data)
- ... def __getitem__(self, key):
- ... return self.data[key]
-
- >>> container = MyContainer(x=1, y=2, z=42)
- >>> adapter = ContainerSublocations(container)
- >>> sublocations = list(adapter.sublocations())
- >>> sublocations.sort()
- >>> sublocations
- [1, 2, 42]
-
- """
-
- def __init__(self, container):
- self.container = container
-
- def sublocations(self):
- container = self.container
- for key in container:
- yield container[key]
-
-
-def containedEvent(object, container, name=None):
- """Establish the containment of the object in the container
-
- The object and necessary event are returned. The object may be a
- `ContainedProxy` around the original object. The event is an added
- event, a moved event, or None.
-
- If the object implements `IContained`, simply set its `__parent__`
- and `__name__` attributes:
-
- >>> container = {}
- >>> item = Contained()
- >>> x, event = containedEvent(item, container, u'foo')
- >>> x is item
- True
- >>> item.__parent__ is container
- True
- >>> item.__name__
- u'foo'
-
- We have an added event:
-
- >>> event.__class__.__name__
- 'ObjectAddedEvent'
- >>> event.object is item
- True
- >>> event.newParent is container
- True
- >>> event.newName
- u'foo'
- >>> event.oldParent
- >>> event.oldName
-
- Now if we call contained again:
-
- >>> x2, event = containedEvent(item, container, u'foo')
- >>> x2 is item
- True
- >>> item.__parent__ is container
- True
- >>> item.__name__
- u'foo'
-
- We don't get a new added event:
-
- >>> event
-
- If the object already had a parent but the parent or name was
- different, we get a moved event:
-
- >>> x, event = containedEvent(item, container, u'foo2')
- >>> event.__class__.__name__
- 'ObjectMovedEvent'
- >>> event.object is item
- True
- >>> event.newParent is container
- True
- >>> event.newName
- u'foo2'
- >>> event.oldParent is container
- True
- >>> event.oldName
- u'foo'
-
- If the `object` implements `ILocation`, but not `IContained`, set its
- `__parent__` and `__name__` attributes *and* declare that it
- implements `IContained`:
-
- >>> from zope.location import Location
- >>> item = Location()
- >>> IContained.providedBy(item)
- False
- >>> x, event = containedEvent(item, container, 'foo')
- >>> x is item
- True
- >>> item.__parent__ is container
- True
- >>> item.__name__
- 'foo'
- >>> IContained.providedBy(item)
- True
-
-
- If the `object` doesn't even implement `ILocation`, put a
- `ContainedProxy` around it:
-
- >>> item = []
- >>> x, event = containedEvent(item, container, 'foo')
- >>> x is item
- False
- >>> x.__parent__ is container
- True
- >>> x.__name__
- 'foo'
-
- Make sure we don't lose existing directly provided interfaces.
-
- >>> from zope.interface import Interface, directlyProvides
- >>> class IOther(Interface):
- ... pass
- >>> from zope.location import Location
- >>> item = Location()
- >>> directlyProvides(item, IOther)
- >>> IOther.providedBy(item)
- True
- >>> x, event = containedEvent(item, container, 'foo')
- >>> IOther.providedBy(item)
- True
- """
-
- if not IContained.providedBy(object):
- if ILocation.providedBy(object):
- zope.interface.alsoProvides(object, IContained)
- else:
- object = ContainedProxy(object)
-
- oldparent = object.__parent__
- oldname = object.__name__
-
- if oldparent is container and oldname == name:
- # No events
- return object, None
-
- object.__parent__ = container
- object.__name__ = name
-
- if oldparent is None or oldname is None:
- event = ObjectAddedEvent(object, container, name)
- else:
- event = ObjectMovedEvent(object, oldparent, oldname, container, name)
-
- return object, event
-
-def contained(object, container, name=None):
- """Establish the containment of the object in the container
-
- Just return the contained object without an event. This is a convenience
- "macro" for:
-
- ``containedEvent(object, container, name)[0]``
-
- This function is only used for tests.
- """
- return containedEvent(object, container, name)[0]
-
-def notifyContainerModified(object, *descriptions):
- """Notify that the container was modified."""
- notify(ContainerModifiedEvent(object, *descriptions))
-
-def setitem(container, setitemf, name, object):
- """Helper function to set an item and generate needed events
-
- This helper is needed, in part, because the events need to get
- published after the `object` has been added to the `container`.
-
- If the item implements `IContained`, simply set its `__parent__`
- and `__name__` attributes:
-
- >>> class IItem(zope.interface.Interface):
- ... pass
- >>> class Item(Contained):
- ... zope.interface.implements(IItem)
- ... def setAdded(self, event):
- ... self.added = event
- ... def setMoved(self, event):
- ... self.moved = event
-
- >>> from zope.app.container.interfaces import IObjectAddedEvent
- >>> from zope.app.container.interfaces import IObjectMovedEvent
- >>> from zope.app.testing import ztapi
-
- >>> ztapi.subscribe([IItem, IObjectAddedEvent], None,
- ... lambda obj, event: obj.setAdded(event))
-
- >>> ztapi.subscribe([IItem, IObjectMovedEvent], None,
- ... lambda obj, event: obj.setMoved(event))
-
- >>> item = Item()
-
- >>> container = {}
- >>> setitem(container, container.__setitem__, u'c', item)
- >>> container[u'c'] is item
- 1
- >>> item.__parent__ is container
- 1
- >>> item.__name__
- u'c'
-
- If we run this using the testing framework, we'll use `getEvents` to
- track the events generated:
-
- >>> from zope.component.eventtesting import getEvents
- >>> from zope.lifecycleevent.interfaces import IObjectModifiedEvent
-
- We have an added event:
-
- >>> len(getEvents(IObjectAddedEvent))
- 1
- >>> event = getEvents(IObjectAddedEvent)[-1]
- >>> event.object is item
- 1
- >>> event.newParent is container
- 1
- >>> event.newName
- u'c'
- >>> event.oldParent
- >>> event.oldName
-
- As well as a modification event for the container:
-
- >>> len(getEvents(IObjectModifiedEvent))
- 1
- >>> getEvents(IObjectModifiedEvent)[-1].object is container
- 1
-
- The item's hooks have been called:
-
- >>> item.added is event
- 1
- >>> item.moved is event
- 1
-
- We can suppress events and hooks by setting the `__parent__` and
- `__name__` first:
-
- >>> item = Item()
- >>> item.__parent__, item.__name__ = container, 'c2'
- >>> setitem(container, container.__setitem__, u'c2', item)
- >>> len(container)
- 2
- >>> len(getEvents(IObjectAddedEvent))
- 1
- >>> len(getEvents(IObjectModifiedEvent))
- 1
-
- >>> getattr(item, 'added', None)
- >>> getattr(item, 'moved', None)
-
- If the item had a parent or name (as in a move or rename),
- we generate a move event, rather than an add event:
-
- >>> setitem(container, container.__setitem__, u'c3', item)
- >>> len(container)
- 3
- >>> len(getEvents(IObjectAddedEvent))
- 1
- >>> len(getEvents(IObjectModifiedEvent))
- 2
- >>> len(getEvents(IObjectMovedEvent))
- 2
-
- (Note that we have 2 move events because add are move events.)
-
- We also get the move hook called, but not the add hook:
-
- >>> event = getEvents(IObjectMovedEvent)[-1]
- >>> getattr(item, 'added', None)
- >>> item.moved is event
- 1
-
- If we try to replace an item without deleting it first, we'll get
- an error:
-
- >>> setitem(container, container.__setitem__, u'c', [])
- Traceback (most recent call last):
- ...
- DuplicationError: c
-
-
- >>> del container[u'c']
- >>> setitem(container, container.__setitem__, u'c', [])
- >>> len(getEvents(IObjectAddedEvent))
- 2
- >>> len(getEvents(IObjectModifiedEvent))
- 3
-
-
- If the object implements `ILocation`, but not `IContained`, set it's
- `__parent__` and `__name__` attributes *and* declare that it
- implements `IContained`:
-
- >>> from zope.location import Location
- >>> item = Location()
- >>> IContained.providedBy(item)
- 0
- >>> setitem(container, container.__setitem__, u'l', item)
- >>> container[u'l'] is item
- 1
- >>> item.__parent__ is container
- 1
- >>> item.__name__
- u'l'
- >>> IContained.providedBy(item)
- 1
-
- We get new added and modification events:
-
- >>> len(getEvents(IObjectAddedEvent))
- 3
- >>> len(getEvents(IObjectModifiedEvent))
- 4
-
- If the object doesn't even implement `ILocation`, put a
- `ContainedProxy` around it:
-
- >>> item = []
- >>> setitem(container, container.__setitem__, u'i', item)
- >>> container[u'i']
- []
- >>> container[u'i'] is item
- 0
- >>> item = container[u'i']
- >>> item.__parent__ is container
- 1
- >>> item.__name__
- u'i'
- >>> IContained.providedBy(item)
- 1
-
- >>> len(getEvents(IObjectAddedEvent))
- 4
- >>> len(getEvents(IObjectModifiedEvent))
- 5
-
- We'll get type errors if we give keys that aren't unicode or ascii keys:
-
- >>> setitem(container, container.__setitem__, 42, item)
- Traceback (most recent call last):
- ...
- TypeError: name not unicode or ascii string
-
- >>> setitem(container, container.__setitem__, None, item)
- Traceback (most recent call last):
- ...
- TypeError: name not unicode or ascii string
-
- >>> setitem(container, container.__setitem__, 'hello ' + chr(200), item)
- Traceback (most recent call last):
- ...
- TypeError: name not unicode or ascii string
-
- and we'll get a value error of we give an empty string or unicode:
-
- >>> setitem(container, container.__setitem__, '', item)
- Traceback (most recent call last):
- ...
- ValueError: empty names are not allowed
-
- >>> setitem(container, container.__setitem__, u'', item)
- Traceback (most recent call last):
- ...
- ValueError: empty names are not allowed
-
- """
- # Do basic name check:
- if isinstance(name, str):
- try:
- name = unicode(name)
- except UnicodeError:
- raise TypeError("name not unicode or ascii string")
- elif not isinstance(name, unicode):
- raise TypeError("name not unicode or ascii string")
-
- if not name:
- raise ValueError("empty names are not allowed")
-
- old = container.get(name)
- if old is object:
- return
- if old is not None:
- raise DuplicationError(name)
-
- object, event = containedEvent(object, container, name)
- setitemf(name, object)
- if event:
- notify(event)
- notifyContainerModified(container)
-
-fixing_up = False
-def uncontained(object, container, name=None):
- """Clear the containment relationship between the `object` and
- the `container`.
-
- If we run this using the testing framework, we'll use `getEvents` to
- track the events generated:
-
- >>> from zope.component.eventtesting import getEvents
- >>> from zope.lifecycleevent.interfaces import IObjectModifiedEvent
- >>> from zope.app.container.interfaces import IObjectRemovedEvent
-
- We'll start by creating a container with an item:
-
- >>> class Item(Contained):
- ... pass
-
- >>> item = Item()
- >>> container = {u'foo': item}
- >>> x, event = containedEvent(item, container, u'foo')
- >>> item.__parent__ is container
- 1
- >>> item.__name__
- u'foo'
-
- Now we'll remove the item. It's parent and name are cleared:
-
- >>> uncontained(item, container, u'foo')
- >>> item.__parent__
- >>> item.__name__
-
- We now have a new removed event:
-
- >>> len(getEvents(IObjectRemovedEvent))
- 1
- >>> event = getEvents(IObjectRemovedEvent)[-1]
- >>> event.object is item
- 1
- >>> event.oldParent is container
- 1
- >>> event.oldName
- u'foo'
- >>> event.newParent
- >>> event.newName
-
- As well as a modification event for the container:
-
- >>> len(getEvents(IObjectModifiedEvent))
- 1
- >>> getEvents(IObjectModifiedEvent)[-1].object is container
- 1
-
- Now if we call uncontained again:
-
- >>> uncontained(item, container, u'foo')
-
- We won't get any new events, because __parent__ and __name__ are None:
-
- >>> len(getEvents(IObjectRemovedEvent))
- 1
- >>> len(getEvents(IObjectModifiedEvent))
- 1
-
- But, if either the name or parent are not ``None`` and they are not the
- container and the old name, we'll get a modified event but not a removed
- event.
-
- >>> item.__parent__, item.__name__ = container, None
- >>> uncontained(item, container, u'foo')
- >>> len(getEvents(IObjectRemovedEvent))
- 1
- >>> len(getEvents(IObjectModifiedEvent))
- 2
-
- >>> item.__parent__, item.__name__ = None, u'bar'
- >>> uncontained(item, container, u'foo')
- >>> len(getEvents(IObjectRemovedEvent))
- 1
- >>> len(getEvents(IObjectModifiedEvent))
- 3
-
- """
- try:
- oldparent = object.__parent__
- oldname = object.__name__
- except AttributeError:
- # The old object doesn't implements IContained
- # Maybe we're converting old data:
- if not fixing_up:
- raise
- oldparent = None
- oldname = None
-
- if oldparent is not container or oldname != name:
- if oldparent is not None or oldname is not None:
- notifyContainerModified(container)
- return
-
- event = ObjectRemovedEvent(object, oldparent, oldname)
- notify(event)
-
- if not IBroken.providedBy(object):
- object.__parent__ = None
- object.__name__ = None
- notifyContainerModified(container)
-
-class NameChooser(object):
-
- zope.interface.implements(INameChooser)
-
- def __init__(self, context):
- self.context = context
-
- def checkName(self, name, object):
- """See zope.app.container.interfaces.INameChooser
-
- We create and populate a dummy container
-
- >>> from zope.app.container.sample import SampleContainer
- >>> container = SampleContainer()
- >>> container['foo'] = 'bar'
- >>> from zope.app.container.contained import NameChooser
-
- All these names are invalid:
-
- >>> NameChooser(container).checkName('+foo', object())
- Traceback (most recent call last):
- ...
- UserError: Names cannot begin with '+' or '@' or contain '/'
- >>> NameChooser(container).checkName('@foo', object())
- Traceback (most recent call last):
- ...
- UserError: Names cannot begin with '+' or '@' or contain '/'
- >>> NameChooser(container).checkName('f/oo', object())
- Traceback (most recent call last):
- ...
- UserError: Names cannot begin with '+' or '@' or contain '/'
- >>> NameChooser(container).checkName('foo', object())
- Traceback (most recent call last):
- ...
- UserError: The given name is already being used
- >>> NameChooser(container).checkName(2, object())
- Traceback (most recent call last):
- ...
- TypeError: ('Invalid name type', <type 'int'>)
-
- This one is ok:
-
- >>> NameChooser(container).checkName('2', object())
- True
-
-
- """
-
- if not name:
- raise UserError(
- _("An empty name was provided. Names cannot be empty.")
- )
-
- if isinstance(name, str):
- name = unicode(name)
- elif not isinstance(name, unicode):
- raise TypeError("Invalid name type", type(name))
-
- if name[:1] in '+@' or '/' in name:
- raise UserError(
- _("Names cannot begin with '+' or '@' or contain '/'")
- )
-
- if name in self.context:
- raise UserError(
- _("The given name is already being used")
- )
-
- return True
-
-
- def chooseName(self, name, object):
- """See zope.app.container.interfaces.INameChooser
-
- The name chooser is expected to choose a name without error
-
- We create and populate a dummy container
-
- >>> from zope.app.container.sample import SampleContainer
- >>> container = SampleContainer()
- >>> container['foo.old.rst'] = 'rst doc'
-
- >>> from zope.app.container.contained import NameChooser
- >>> NameChooser(container).chooseName('+ at +@foo.old.rst', object())
- u'foo.old-2.rst'
- >>> NameChooser(container).chooseName('+ at +@foo/foo', object())
- u'foo-foo'
- >>> NameChooser(container).chooseName('', object())
- u'object'
- >>> NameChooser(container).chooseName('@+@', object())
- u'object'
-
- """
-
- container = self.context
-
- # remove characters that checkName does not allow
- name = unicode(name.replace('/', '-').lstrip('+@'))
-
- if not name:
- name = unicode(object.__class__.__name__)
-
- dot = name.rfind('.')
- if dot >= 0:
- suffix = name[dot:]
- name = name[:dot]
- else:
- suffix = ''
-
-
- n = name + suffix
- i = 1
- while n in container:
- i += 1
- n = name + u'-' + unicode(i) + suffix
-
- # Make sure the name is valid. We may have started with something bad.
- self.checkName(n, object)
-
- return n
-
-
-class DecoratorSpecificationDescriptor(
- zope.interface.declarations.ObjectSpecificationDescriptor):
- """Support for interface declarations on decorators
-
- >>> from zope.interface import *
- >>> class I1(Interface):
- ... pass
- >>> class I2(Interface):
- ... pass
- >>> class I3(Interface):
- ... pass
- >>> class I4(Interface):
- ... pass
-
- >>> class D1(ContainedProxy):
- ... implements(I1)
-
-
- >>> class D2(ContainedProxy):
- ... implements(I2)
-
- >>> class X:
- ... implements(I3)
-
- >>> x = X()
- >>> directlyProvides(x, I4)
-
- Interfaces of X are ordered with the directly-provided interfaces first
-
- >>> [interface.getName() for interface in list(providedBy(x))]
- ['I4', 'I3']
-
- When we decorate objects, what order should the interfaces come in? One
- could argue that decorators are less specific, so they should come last.
-
- >>> [interface.getName() for interface in list(providedBy(D1(x)))]
- ['I4', 'I3', 'I1', 'IContained', 'IPersistent']
-
- >>> [interface.getName() for interface in list(providedBy(D2(D1(x))))]
- ['I4', 'I3', 'I1', 'IContained', 'IPersistent', 'I2']
- """
- def __get__(self, inst, cls=None):
- if inst is None:
- return getObjectSpecification(cls)
- else:
- provided = providedBy(getProxiedObject(inst))
-
- # Use type rather than __class__ because inst is a proxy and
- # will return the proxied object's class.
- cls = type(inst)
- return ObjectSpecification(provided, cls)
-
-
-class DecoratedSecurityCheckerDescriptor(object):
- """Descriptor for a Decorator that provides a decorated security checker.
- """
- def __get__(self, inst, cls=None):
- if inst is None:
- return self
- else:
- proxied_object = getProxiedObject(inst)
- checker = getattr(proxied_object, '__Security_checker__', None)
- if checker is None:
- checker = selectChecker(proxied_object)
- wrapper_checker = selectChecker(inst)
- if wrapper_checker is None:
- return checker
- elif checker is None:
- return wrapper_checker
- else:
- return CombinedChecker(wrapper_checker, checker)
-
-class ContainedProxyClassProvides(zope.interface.declarations.ClassProvides):
-
- def __set__(self, inst, value):
- inst = getProxiedObject(inst)
- inst.__provides__ = value
-
- def __delete__(self, inst):
- inst = getProxiedObject(inst)
- del inst.__provides__
-
-class ContainedProxy(ContainedProxyBase):
-
- # Prevent proxies from having their own instance dictionaries:
- __slots__ = ()
-
- __safe_for_unpickling__ = True
-
- zope.interface.implements(IContained)
-
- __providedBy__ = DecoratorSpecificationDescriptor()
-
- __Security_checker__ = DecoratedSecurityCheckerDescriptor()
-
-ContainedProxy.__provides__ = ContainedProxyClassProvides(ContainedProxy, type)
-
+# BBB
+from zope.container.contained import (
+ Contained,
+ ObjectMovedEvent,
+ ObjectAddedEvent,
+ ObjectRemovedEvent,
+ ContainerModifiedEvent,
+ dispatchToSublocations,
+ ContainerSublocations,
+ containedEvent,
+ contained,
+ notifyContainerModified,
+ setitem,
+ fixing_up,
+ uncontained,
+ NameChooser,
+ DecoratorSpecificationDescriptor,
+ DecoratedSecurityCheckerDescriptor,
+ ContainedProxyClassProvides,
+ ContainedProxy,
+)
Modified: zope.app.container/trunk/src/zope/app/container/dependency.py
===================================================================
--- zope.app.container/trunk/src/zope/app/container/dependency.py 2009-01-29 10:24:21 UTC (rev 95397)
+++ zope.app.container/trunk/src/zope/app/container/dependency.py 2009-01-29 10:28:20 UTC (rev 95398)
@@ -12,34 +12,11 @@
#
##############################################################################
-"""Subscriber function checking dependencies if a removal is performed
-on an object having dependencies. It raises an exception if it's the
-case.
-
-$Id$
+"""BBB: this module moved to zope.container
"""
-__docformat__ = 'restructuredtext'
-from zope.i18nmessageid import Message
-from zope.app.container.i18n import ZopeMessageFactory as _
-from zope.app.dependable.interfaces import IDependable, DependencyError
-from zope.traversing.api import getPath
-
-exception_msg = _("""
-Removal of object (${object}) which has dependents (${dependents})
-is not possible !
-
-You must deactivate this object before trying to remove it.
-""")
-
-def CheckDependency(event):
- object = event.object
- dependency = IDependable(object, None)
- if dependency is not None:
- dependents = dependency.dependents()
- if dependents:
- mapping = {
- "object": getPath(object),
- "dependents": ", ".join(dependents)
- }
- raise DependencyError(Message(exception_msg, mapping=mapping))
+# BBB
+from zope.container.dependency import (
+ exception_msg,
+ CheckDependency
+)
Modified: zope.app.container/trunk/src/zope/app/container/directory.py
===================================================================
--- zope.app.container/trunk/src/zope/app/container/directory.py 2009-01-29 10:24:21 UTC (rev 95397)
+++ zope.app.container/trunk/src/zope/app/container/directory.py 2009-01-29 10:28:20 UTC (rev 95398)
@@ -9,54 +9,11 @@
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
##############################################################################
-"""File-system representation adapters for containers
-
-This module includes two adapters (adapter factories, really) for
-providing a file-system representation for containers:
-
-`noop`
- Factory that "adapts" `IContainer` to `IWriteDirectory`.
- This is a lie, since it just returns the original object.
-
-`Cloner`
- An `IDirectoryFactory` adapter that just clones the original object.
-
-$Id$
+"""BBB: this module moved to zope.container
"""
-__docformat__ = 'restructuredtext'
-import zope.filerepresentation.interfaces
-from zope.security.proxy import removeSecurityProxy
-from zope.interface import implements
-
-def noop(container):
- """Adapt an `IContainer` to an `IWriteDirectory` by just returning it
-
- This "works" because `IContainer` and `IWriteDirectory` have the same
- methods, however, the output doesn't actually implement `IWriteDirectory`.
- """
- return container
-
-
-class Cloner(object):
- """`IContainer` to `IDirectoryFactory` adapter that clones
-
- This adapter provides a factory that creates a new empty container
- of the same class as it's context.
- """
-
- implements(zope.filerepresentation.interfaces.IDirectoryFactory)
-
- def __init__(self, context):
- self.context = context
-
- def __call__(self, name):
-
- # We remove the security proxy so we can actually call the
- # class and return an unproxied new object. (We can't use a
- # trusted adapter, because the result must be unproxied.) By
- # registering this adapter, one effectively gives permission
- # to clone the class. Don't use this for classes that have
- # exciting side effects as a result of instantiation. :)
-
- return removeSecurityProxy(self.context).__class__()
+# BBB
+from zope.container.directory import (
+ noop,
+ Cloner
+)
Modified: zope.app.container/trunk/src/zope/app/container/find.py
===================================================================
--- zope.app.container/trunk/src/zope/app/container/find.py 2009-01-29 10:24:21 UTC (rev 95397)
+++ zope.app.container/trunk/src/zope/app/container/find.py 2009-01-29 10:28:20 UTC (rev 95398)
@@ -11,79 +11,13 @@
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
-"""Find Support
-
-$Id$
+"""BBB: this module moved to zope.container
"""
-__docformat__ = 'restructuredtext'
-from zope.interface import implements
-from interfaces import IFind, IIdFindFilter, IObjectFindFilter
-from interfaces import IReadContainer
-
-class FindAdapter(object):
-
- implements(IFind)
-
- __used_for__ = IReadContainer
-
- def __init__(self, context):
- self._context = context
-
- def find(self, id_filters=None, object_filters=None):
- 'See IFind'
- id_filters = id_filters or []
- object_filters = object_filters or []
- result = []
- container = self._context
- for id, object in container.items():
- _find_helper(id, object, container,
- id_filters, object_filters,
- result)
- return result
-
-
-def _find_helper(id, object, container, id_filters, object_filters, result):
- for id_filter in id_filters:
- if not id_filter.matches(id):
- break
- else:
- # if we didn't break out of the loop, all name filters matched
- # now check all object filters
- for object_filter in object_filters:
- if not object_filter.matches(object):
- break
- else:
- # if we didn't break out of the loop, all filters matched
- result.append(object)
-
- if not IReadContainer.providedBy(object):
- return
-
- container = object
- for id, object in container.items():
- _find_helper(id, object, container, id_filters, object_filters, result)
-
-class SimpleIdFindFilter(object):
-
- implements(IIdFindFilter)
-
- def __init__(self, ids):
- self._ids = ids
-
- def matches(self, id):
- 'See INameFindFilter'
- return id in self._ids
-
-class SimpleInterfacesFindFilter(object):
- """Filter objects on the provided interfaces"""
- implements(IObjectFindFilter)
-
- def __init__(self, *interfaces):
- self.interfaces = interfaces
-
- def matches(self, object):
- for iface in self.interfaces:
- if iface.providedBy(object):
- return True
- return False
+# BBB
+from zope.container.find import (
+ FindAdapter,
+ _find_helper,
+ SimpleIdFindFilter,
+ SimpleInterfacesFindFilter
+)
Modified: zope.app.container/trunk/src/zope/app/container/interfaces.py
===================================================================
--- zope.app.container/trunk/src/zope/app/container/interfaces.py 2009-01-29 10:24:21 UTC (rev 95397)
+++ zope.app.container/trunk/src/zope/app/container/interfaces.py 2009-01-29 10:28:20 UTC (rev 95398)
@@ -17,209 +17,39 @@
"""
__docformat__ = 'restructuredtext'
-from zope.interface import Interface, Attribute, Invalid
-from zope.component.interfaces import IView, IObjectEvent
-from zope.interface.common.mapping import IItemMapping
-from zope.interface.common.mapping import IReadMapping, IEnumerableMapping
-from zope.location.interfaces import ILocation
-from zope.lifecycleevent.interfaces import IObjectModifiedEvent
+# BBB
+from zope.container.interfaces import (
+ DuplicateIDError,
+ ContainerError,
+ InvalidContainerType,
+ InvalidItemType,
+ InvalidType,
+ IContained,
+ IItemContainer,
+ ISimpleReadContainer,
+ IReadContainer,
+ IWriteContainer,
+ IItemWriteContainer,
+ IContainer,
+ IBTreeContainer,
+ IOrderedContainer,
+ IContainerNamesContainer,
+ IObjectMovedEvent,
+ UnaddableError,
+ IObjectAddedEvent,
+ INameChooser,
+ IObjectRemovedEvent,
+ IContainerModifiedEvent,
+ IFind,
+ IObjectFindFilter,
+ IIdFindFilter
+)
-class DuplicateIDError(KeyError):
- pass
+import zope.component.interfaces
+import zope.interface
-class ContainerError(Exception):
- """An error of a container with one of its components."""
-class InvalidContainerType(Invalid, TypeError):
- """The type of a container is not valid."""
-
-class InvalidItemType(Invalid, TypeError):
- """The type of an item is not valid."""
-
-class InvalidType(Invalid, TypeError):
- """The type of an object is not valid."""
-
-
-
-class IContained(ILocation):
- """Objects contained in containers."""
-
-
-class IItemContainer(IItemMapping):
- """Minimal readable container."""
-
-
-class ISimpleReadContainer(IItemContainer, IReadMapping):
- """Readable content containers."""
-
-
-class IReadContainer(ISimpleReadContainer, IEnumerableMapping):
- """Readable containers that can be enumerated."""
-
-
-class IWriteContainer(Interface):
- """An interface for the write aspects of a container."""
-
- def __setitem__(name, object):
- """Add the given `object` to the container under the given name.
-
- Raises a ``TypeError`` if the key is not a unicode or ascii string.
- Raises a ``ValueError`` if key is empty.
-
- The container might choose to add a different object than the
- one passed to this method.
-
- If the object doesn't implement `IContained`, then one of two
- things must be done:
-
- 1. If the object implements `ILocation`, then the `IContained`
- interface must be declared for the object.
-
- 2. Otherwise, a `ContainedProxy` is created for the object and
- stored.
-
- The object's `__parent__` and `__name__` attributes are set to the
- container and the given name.
-
- If the old parent was ``None``, then an `IObjectAddedEvent` is
- generated, otherwise, an `IObjectMovedEvent` is generated. An
- `IContainerModifiedEvent` is generated for the container.
-
- If the object replaces another object, then the old object is
- deleted before the new object is added, unless the container
- vetos the replacement by raising an exception.
-
- If the object's `__parent__` and `__name__` were already set to
- the container and the name, then no events are generated and
- no hooks. This allows advanced clients to take over event
- generation.
-
- """
-
- def __delitem__(name):
- """Delete the named object from the container.
-
- Raises a ``KeyError`` if the object is not found.
-
- If the deleted object's `__parent__` and `__name__` match the
- container and given name, then an `IObjectRemovedEvent` is
- generated and the attributes are set to ``None``. If the object
- can be adapted to `IObjectMovedEvent`, then the adapter's
- `moveNotify` method is called with the event.
-
- Unless the object's `__parent__` and `__name__` attributes were
- initially ``None``, generate an `IContainerModifiedEvent` for the
- container.
-
- If the object's `__parent__` and `__name__` were already set to
- ``None``, then no events are generated. This allows advanced
- clients to take over event generation.
-
- """
-
-
-class IItemWriteContainer(IWriteContainer, IItemContainer):
- """A write container that also supports minimal reads."""
-
-
-class IContainer(IReadContainer, IWriteContainer):
- """Readable and writable content container."""
-
-
-class IBTreeContainer(IContainer):
- """Container that supports BTree semantics for some methods."""
-
- def items(key=None):
- """Return an iterator over the key-value pairs in the container.
-
- If ``None`` is passed as `key`, this method behaves as if no argument
- were passed; exactly as required for ``IContainer.items()``.
-
- If `key` is in the container, the first item provided by the iterator
- will correspond to that key. Otherwise, the first item will be for
- the key that would come next if `key` were in the container.
-
- """
-
- def keys(key=None):
- """Return an iterator over the keys in the container.
-
- If ``None`` is passed as `key`, this method behaves as if no argument
- were passed; exactly as required for ``IContainer.keys()``.
-
- If `key` is in the container, the first key provided by the iterator
- will be that key. Otherwise, the first key will be the one that would
- come next if `key` were in the container.
-
- """
-
- def values(key=None):
- """Return an iterator over the values in the container.
-
- If ``None`` is passed as `key`, this method behaves as if no argument
- were passed; exactly as required for ``IContainer.values()``.
-
- If `key` is in the container, the first value provided by the iterator
- will correspond to that key. Otherwise, the first value will be for
- the key that would come next if `key` were in the container.
-
- """
-
-
-class IOrderedContainer(IContainer):
- """Containers whose contents are maintained in order."""
-
- def updateOrder(order):
- """Revise the order of keys, replacing the current ordering.
-
- order is a list or a tuple containing the set of existing keys in
- the new order. `order` must contain ``len(keys())`` items and cannot
- contain duplicate keys.
-
- Raises ``TypeError`` if order is not a tuple or a list.
-
- Raises ``ValueError`` if order contains an invalid set of keys.
- """
-
-
-class IContainerNamesContainer(IContainer):
- """Containers that always choose names for their items."""
-
-
-##############################################################################
-# Moving Objects
-
-class IObjectMovedEvent(IObjectEvent):
- """An object has been moved."""
-
- oldParent = Attribute("The old location parent for the object.")
- oldName = Attribute("The old location name for the object.")
- newParent = Attribute("The new location parent for the object.")
- newName = Attribute("The new location name for the object.")
-
-
-##############################################################################
-# Adding objects
-
-class UnaddableError(ContainerError):
- """An object cannot be added to a container."""
-
- def __init__(self, container, obj, message=""):
- self.container = container
- self.obj = obj
- self.message = message and ": %s" % message
-
- def __str__(self):
- return ("%(obj)s cannot be added "
- "to %(container)s%(message)s" % self.__dict__)
-
-
-class IObjectAddedEvent(IObjectMovedEvent):
- """An object has been added to a container."""
-
-
-class IAdding(IView):
-
+class IAdding(zope.component.interfaces.IView):
def add(content):
"""Add content object to container.
@@ -230,7 +60,7 @@
``DuplicateIDError``.
"""
- contentName = Attribute(
+ contentName = zope.interface.Attribute(
"""The content name, as usually set by the Adder traverser.
If the content name hasn't been defined yet, returns ``None``.
@@ -265,70 +95,3 @@
def hasCustomAddView():
"This should be called only if there is `singleMenuItem` else return 0"
-
-
-class INameChooser(Interface):
-
- def checkName(name, object):
- """Check whether an object name is valid.
-
- Raises a user error if the name is not valid.
- """
-
- def chooseName(name, object):
- """Choose a unique valid name for the object.
-
- The given name and object may be taken into account when
- choosing the name.
-
- chooseName is expected to always choose a valid name (that would pass
- the checkName test) and never raise an error.
-
- """
-
-
-##############################################################################
-# Removing objects
-
-
-class IObjectRemovedEvent(IObjectMovedEvent):
- """An object has been removed from a container."""
-
-
-##############################################################################
-# Modifying containers
-
-
-class IContainerModifiedEvent(IObjectModifiedEvent):
- """The container has been modified.
-
- This event is specific to "containerness" modifications, which means
- addition, removal or reordering of sub-objects.
- """
-
-
-##############################################################################
-# Finding objects
-
-class IFind(Interface):
- """
- Find support for containers.
- """
-
- def find(id_filters=None, object_filters=None):
- """Find object that matches all filters in all sub-objects.
-
- This container itself is not included.
- """
-
-
-class IObjectFindFilter(Interface):
-
- def matches(object):
- """Return True if the object matches the filter criteria."""
-
-
-class IIdFindFilter(Interface):
-
- def matches(id):
- """Return True if the id matches the filter criteria."""
Modified: zope.app.container/trunk/src/zope/app/container/ordered.py
===================================================================
--- zope.app.container/trunk/src/zope/app/container/ordered.py 2009-01-29 10:24:21 UTC (rev 95397)
+++ zope.app.container/trunk/src/zope/app/container/ordered.py 2009-01-29 10:28:20 UTC (rev 95398)
@@ -11,297 +11,8 @@
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
-"""Ordered container implementation.
-
-$Id$
+"""BBB: this module moved to zope.container
"""
-__docformat__ = 'restructuredtext'
-from zope.app.container.interfaces import IOrderedContainer
-from zope.interface import implements
-from persistent import Persistent
-from persistent.dict import PersistentDict
-from persistent.list import PersistentList
-from types import StringTypes, TupleType, ListType
-from zope.app.container.contained import Contained, setitem, uncontained
-from zope.app.container.contained import notifyContainerModified
-
-class OrderedContainer(Persistent, Contained):
- """ `OrderedContainer` maintains entries' order as added and moved.
-
- >>> oc = OrderedContainer()
- >>> int(IOrderedContainer.providedBy(oc))
- 1
- >>> len(oc)
- 0
- """
-
- implements(IOrderedContainer)
-
- def __init__(self):
-
- self._data = PersistentDict()
- self._order = PersistentList()
-
- def keys(self):
- """ See `IOrderedContainer`.
-
- >>> oc = OrderedContainer()
- >>> oc.keys()
- []
- >>> oc['foo'] = 'bar'
- >>> oc.keys()
- ['foo']
- >>> oc['baz'] = 'quux'
- >>> oc.keys()
- ['foo', 'baz']
- >>> int(len(oc._order) == len(oc._data))
- 1
- """
-
- return self._order[:]
-
- def __iter__(self):
- """ See `IOrderedContainer`.
-
- >>> oc = OrderedContainer()
- >>> oc.keys()
- []
- >>> oc['foo'] = 'bar'
- >>> oc['baz'] = 'quux'
- >>> [i for i in oc]
- ['foo', 'baz']
- >>> int(len(oc._order) == len(oc._data))
- 1
- """
-
- return iter(self.keys())
-
- def __getitem__(self, key):
- """ See `IOrderedContainer`.
-
- >>> oc = OrderedContainer()
- >>> oc['foo'] = 'bar'
- >>> oc['foo']
- 'bar'
- """
-
- return self._data[key]
-
- def get(self, key, default=None):
- """ See `IOrderedContainer`.
-
- >>> oc = OrderedContainer()
- >>> oc['foo'] = 'bar'
- >>> oc.get('foo')
- 'bar'
- >>> oc.get('funky', 'No chance, dude.')
- 'No chance, dude.'
- """
-
- return self._data.get(key, default)
-
- def values(self):
- """ See `IOrderedContainer`.
-
- >>> oc = OrderedContainer()
- >>> oc.keys()
- []
- >>> oc['foo'] = 'bar'
- >>> oc.values()
- ['bar']
- >>> oc['baz'] = 'quux'
- >>> oc.values()
- ['bar', 'quux']
- >>> int(len(oc._order) == len(oc._data))
- 1
- """
-
- return [self._data[i] for i in self._order]
-
- def __len__(self):
- """ See `IOrderedContainer`.
-
- >>> oc = OrderedContainer()
- >>> int(len(oc) == 0)
- 1
- >>> oc['foo'] = 'bar'
- >>> int(len(oc) == 1)
- 1
- """
-
- return len(self._data)
-
- def items(self):
- """ See `IOrderedContainer`.
-
- >>> oc = OrderedContainer()
- >>> oc.keys()
- []
- >>> oc['foo'] = 'bar'
- >>> oc.items()
- [('foo', 'bar')]
- >>> oc['baz'] = 'quux'
- >>> oc.items()
- [('foo', 'bar'), ('baz', 'quux')]
- >>> int(len(oc._order) == len(oc._data))
- 1
- """
-
- return [(i, self._data[i]) for i in self._order]
-
- def __contains__(self, key):
- """ See `IOrderedContainer`.
-
- >>> oc = OrderedContainer()
- >>> oc['foo'] = 'bar'
- >>> int('foo' in oc)
- 1
- >>> int('quux' in oc)
- 0
- """
-
- return self._data.has_key(key)
-
- has_key = __contains__
-
- def __setitem__(self, key, object):
- """ See `IOrderedContainer`.
-
- >>> oc = OrderedContainer()
- >>> oc.keys()
- []
- >>> oc['foo'] = 'bar'
- >>> oc._order
- ['foo']
- >>> oc['baz'] = 'quux'
- >>> oc._order
- ['foo', 'baz']
- >>> int(len(oc._order) == len(oc._data))
- 1
- """
-
- existed = self._data.has_key(key)
-
- bad = False
- if isinstance(key, StringTypes):
- try:
- unicode(key)
- except UnicodeError:
- bad = True
- else:
- bad = True
- if bad:
- raise TypeError("'%s' is invalid, the key must be an "
- "ascii or unicode string" % key)
- if len(key) == 0:
- raise ValueError("The key cannot be an empty string")
-
- # We have to first update the order, so that the item is available,
- # otherwise most API functions will lie about their available values
- # when an event subscriber tries to do something with the container.
- if not existed:
- self._order.append(key)
-
- # This function creates a lot of events that other code listens to.
- try:
- setitem(self, self._data.__setitem__, key, object)
- except Exception, e:
- self._order.remove(key)
- raise e
-
- return key
-
- def __delitem__(self, key):
- """ See `IOrderedContainer`.
-
- >>> oc = OrderedContainer()
- >>> oc.keys()
- []
- >>> oc['foo'] = 'bar'
- >>> oc['baz'] = 'quux'
- >>> oc['zork'] = 'grue'
- >>> oc.items()
- [('foo', 'bar'), ('baz', 'quux'), ('zork', 'grue')]
- >>> int(len(oc._order) == len(oc._data))
- 1
- >>> del oc['baz']
- >>> oc.items()
- [('foo', 'bar'), ('zork', 'grue')]
- >>> int(len(oc._order) == len(oc._data))
- 1
- """
-
- uncontained(self._data[key], self, key)
- del self._data[key]
- self._order.remove(key)
-
- def updateOrder(self, order):
- """ See `IOrderedContainer`.
-
- >>> oc = OrderedContainer()
- >>> oc['foo'] = 'bar'
- >>> oc['baz'] = 'quux'
- >>> oc['zork'] = 'grue'
- >>> oc.keys()
- ['foo', 'baz', 'zork']
- >>> oc.updateOrder(['baz', 'foo', 'zork'])
- >>> oc.keys()
- ['baz', 'foo', 'zork']
- >>> oc.updateOrder(['baz', 'zork', 'foo'])
- >>> oc.keys()
- ['baz', 'zork', 'foo']
- >>> oc.updateOrder(['baz', 'zork', 'foo'])
- >>> oc.keys()
- ['baz', 'zork', 'foo']
- >>> oc.updateOrder(('zork', 'foo', 'baz'))
- >>> oc.keys()
- ['zork', 'foo', 'baz']
- >>> oc.updateOrder(['baz', 'zork'])
- Traceback (most recent call last):
- ...
- ValueError: Incompatible key set.
- >>> oc.updateOrder(['foo', 'bar', 'baz', 'quux'])
- Traceback (most recent call last):
- ...
- ValueError: Incompatible key set.
- >>> oc.updateOrder(1)
- Traceback (most recent call last):
- ...
- TypeError: order must be a tuple or a list.
- >>> oc.updateOrder('bar')
- Traceback (most recent call last):
- ...
- TypeError: order must be a tuple or a list.
- >>> oc.updateOrder(['baz', 'zork', 'quux'])
- Traceback (most recent call last):
- ...
- ValueError: Incompatible key set.
- >>> del oc['baz']
- >>> del oc['zork']
- >>> del oc['foo']
- >>> len(oc)
- 0
- """
-
- if not isinstance(order, ListType) and \
- not isinstance(order, TupleType):
- raise TypeError('order must be a tuple or a list.')
-
- if len(order) != len(self._order):
- raise ValueError("Incompatible key set.")
-
- was_dict = {}
- will_be_dict = {}
- new_order = PersistentList()
-
- for i in range(len(order)):
- was_dict[self._order[i]] = 1
- will_be_dict[order[i]] = 1
- new_order.append(order[i])
-
- if will_be_dict != was_dict:
- raise ValueError("Incompatible key set.")
-
- self._order = new_order
- notifyContainerModified(self)
+# BBB
+from zope.container.ordered import OrderedContainer
Modified: zope.app.container/trunk/src/zope/app/container/sample.py
===================================================================
--- zope.app.container/trunk/src/zope/app/container/sample.py 2009-01-29 10:24:21 UTC (rev 95397)
+++ zope.app.container/trunk/src/zope/app/container/sample.py 2009-01-29 10:28:20 UTC (rev 95398)
@@ -11,81 +11,8 @@
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
-"""Sample container implementation.
-
-This is primarily for testing purposes.
-
-It might be useful as a mix-in for some classes, but many classes will
-need a very different implementation.
-
-$Id$
+"""BBB: this module moved to zope.container
"""
-__docformat__ = 'restructuredtext'
-from zope.app.container.interfaces import IContainer
-from zope.interface import implements
-from zope.app.container.contained import Contained, setitem, uncontained
-
-
-class SampleContainer(Contained):
- """Sample container implementation suitable for testing.
-
- It is not suitable, directly as a base class unless the subclass
- overrides `_newContainerData` to return a persistent mapping object.
- """
- implements(IContainer)
-
- def __init__(self):
- self.__data = self._newContainerData()
-
- def _newContainerData(self):
- """Construct an item-data container
-
- Subclasses should override this if they want different data.
-
- The value returned is a mapping object that also has `get`,
- `has_key`, `keys`, `items`, and `values` methods.
- """
- return {}
-
- def keys(self):
- '''See interface `IReadContainer`'''
- return self.__data.keys()
-
- def __iter__(self):
- return iter(self.__data)
-
- def __getitem__(self, key):
- '''See interface `IReadContainer`'''
- return self.__data[key]
-
- def get(self, key, default=None):
- '''See interface `IReadContainer`'''
- return self.__data.get(key, default)
-
- def values(self):
- '''See interface `IReadContainer`'''
- return self.__data.values()
-
- def __len__(self):
- '''See interface `IReadContainer`'''
- return len(self.__data)
-
- def items(self):
- '''See interface `IReadContainer`'''
- return self.__data.items()
-
- def __contains__(self, key):
- '''See interface `IReadContainer`'''
- return self.__data.has_key(key)
-
- has_key = __contains__
-
- def __setitem__(self, key, object):
- '''See interface `IWriteContainer`'''
- setitem(self, self.__data.__setitem__, key, object)
-
- def __delitem__(self, key):
- '''See interface `IWriteContainer`'''
- uncontained(self.__data[key], self, key)
- del self.__data[key]
+# BBB
+from zope.container.sample import SampleContainer
Modified: zope.app.container/trunk/src/zope/app/container/size.py
===================================================================
--- zope.app.container/trunk/src/zope/app/container/size.py 2009-01-29 10:24:21 UTC (rev 95397)
+++ zope.app.container/trunk/src/zope/app/container/size.py 2009-01-29 10:28:20 UTC (rev 95398)
@@ -12,30 +12,8 @@
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
-"""Adapters that give the size of an object.
-
-$Id$
+"""BBB: this module moved to zope.container
"""
-__docformat__ = 'restructuredtext'
-from zope.app.container.i18n import ZopeMessageFactory as _
-from zope.size.interfaces import ISized
-from zope.interface import implements
-
-class ContainerSized(object):
-
- implements(ISized)
-
- def __init__(self, container):
- self._container = container
-
- def sizeForSorting(self):
- """See `ISized`"""
- return ('item', len(self._container))
-
- def sizeForDisplay(self):
- """See `ISized`"""
- num_items = len(self._container)
- if num_items == 1:
- return _('1 item')
- return _('${items} items', mapping={'items': str(num_items)})
+# BBB
+from zope.container.size import ContainerSized
Deleted: zope.app.container/trunk/src/zope/app/container/tests/test_btree.py
===================================================================
--- zope.app.container/trunk/src/zope/app/container/tests/test_btree.py 2009-01-29 10:24:21 UTC (rev 95397)
+++ zope.app.container/trunk/src/zope/app/container/tests/test_btree.py 2009-01-29 10:28:20 UTC (rev 95398)
@@ -1,177 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2004 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (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.
-#
-##############################################################################
-"""BTree Container Tests
-
-$Id$
-"""
-from unittest import TestCase, main, makeSuite, TestSuite
-from zope.interface.verify import verifyObject
-from zope.testing.doctestunit import DocTestSuite
-from zope.app.testing import placelesssetup
-from test_icontainer import TestSampleContainer
-from zope.app.container.btree import BTreeContainer
-from zope.app.container.interfaces import IBTreeContainer
-
-
-class TestBTreeContainer(TestSampleContainer, TestCase):
-
- def makeTestObject(self):
- return BTreeContainer()
-
-
-class TestBTreeSpecials(TestCase):
-
- def testStoredLength(self):
- # This is lazy for backward compatibility. If the len is not
- # stored already we set it to the length of the underlying
- # btree.
- bc = BTreeContainer()
- self.assertEqual(bc.__dict__['_BTreeContainer__len'](), 0)
- del bc.__dict__['_BTreeContainer__len']
- self.failIf(bc.__dict__.has_key('_BTreeContainer__len'))
- bc['1'] = 1
- self.assertEqual(len(bc), 1)
- self.assertEqual(bc.__dict__['_BTreeContainer__len'](), 1)
-
- # The tests which follow test the additional signatures and declarations
- # for the BTreeContainer that allow it to provide the IBTreeContainer
- # interface.
-
- def testBTreeContainerInterface(self):
- bc = BTreeContainer()
- self.assert_(verifyObject(IBTreeContainer, bc))
- self.checkIterable(bc.items())
- self.checkIterable(bc.keys())
- self.checkIterable(bc.values())
-
- def testEmptyItemsWithArg(self):
- bc = BTreeContainer()
- self.assertEqual(list(bc.items(None)), list(bc.items()))
- self.assertEqual(list(bc.items("")), [])
- self.assertEqual(list(bc.items("not-there")), [])
- self.checkIterable(bc.items(None))
- self.checkIterable(bc.items(""))
- self.checkIterable(bc.items("not-there"))
-
- def testEmptyKeysWithArg(self):
- bc = BTreeContainer()
- self.assertEqual(list(bc.keys(None)), list(bc.keys()))
- self.assertEqual(list(bc.keys("")), [])
- self.assertEqual(list(bc.keys("not-there")), [])
- self.checkIterable(bc.keys(None))
- self.checkIterable(bc.keys(""))
- self.checkIterable(bc.keys("not-there"))
-
- def testEmptyValuesWithArg(self):
- bc = BTreeContainer()
- self.assertEqual(list(bc.values(None)), list(bc.values()))
- self.assertEqual(list(bc.values("")), [])
- self.assertEqual(list(bc.values("not-there")), [])
- self.checkIterable(bc.values(None))
- self.checkIterable(bc.values(""))
- self.checkIterable(bc.values("not-there"))
-
- def testNonemptyItemsWithArg(self):
- bc = BTreeContainer()
- bc["0"] = 1
- bc["1"] = 2
- bc["2"] = 3
- self.assertEqual(list(bc.items(None)), list(bc.items()))
- self.assertEqual(list(bc.items("")), [("0", 1), ("1", 2), ("2", 3)])
- self.assertEqual(list(bc.items("3")), [])
- self.assertEqual(list(bc.items("2.")), [])
- self.assertEqual(list(bc.items("2")), [("2", 3)])
- self.assertEqual(list(bc.items("1.")), [("2", 3)])
- self.assertEqual(list(bc.items("1")), [("1", 2), ("2", 3)])
- self.assertEqual(list(bc.items("0.")), [("1", 2), ("2", 3)])
- self.assertEqual(list(bc.items("0")), [("0", 1), ("1", 2), ("2", 3)])
- self.checkIterable(bc.items(None))
- self.checkIterable(bc.items(""))
- self.checkIterable(bc.items("0."))
- self.checkIterable(bc.items("3"))
-
- def testNonemptyKeysWithArg(self):
- bc = BTreeContainer()
- bc["0"] = 1
- bc["1"] = 2
- bc["2"] = 3
- self.assertEqual(list(bc.keys(None)), list(bc.keys()))
- self.assertEqual(list(bc.keys("")), ["0", "1", "2"])
- self.assertEqual(list(bc.keys("3")), [])
- self.assertEqual(list(bc.keys("2.")), [])
- self.assertEqual(list(bc.keys("2")), ["2"])
- self.assertEqual(list(bc.keys("1.")), ["2"])
- self.assertEqual(list(bc.keys("1")), ["1", "2"])
- self.assertEqual(list(bc.keys("0.")), ["1", "2"])
- self.assertEqual(list(bc.keys("0")), ["0", "1", "2"])
- self.checkIterable(bc.keys(None))
- self.checkIterable(bc.keys(""))
- self.checkIterable(bc.keys("0."))
- self.checkIterable(bc.keys("3"))
-
- def testNonemptyValueWithArg(self):
- bc = BTreeContainer()
- bc["0"] = 1
- bc["1"] = 2
- bc["2"] = 3
- self.assertEqual(list(bc.values(None)), list(bc.values()))
- self.assertEqual(list(bc.values("")), [1, 2, 3])
- self.assertEqual(list(bc.values("3")), [])
- self.assertEqual(list(bc.values("2.")), [])
- self.assertEqual(list(bc.values("2")), [3])
- self.assertEqual(list(bc.values("1.")), [3])
- self.assertEqual(list(bc.values("1")), [2, 3])
- self.assertEqual(list(bc.values("0.")), [2, 3])
- self.assertEqual(list(bc.values("0")), [1, 2, 3])
- self.checkIterable(bc.values(None))
- self.checkIterable(bc.values(""))
- self.checkIterable(bc.values("0."))
- self.checkIterable(bc.values("3"))
-
- def testCorrectLengthWhenAddingExistingItem(self):
- """
- for bug #175388
- """
- bc = BTreeContainer()
- bc[u'x'] = object()
- self.assertEqual(len(bc), 1)
- bc[u'x'] = bc[u'x']
- self.assertEqual(len(bc), 1)
- self.assertEqual(list(bc), [u'x'])
-
-
- def checkIterable(self, iterable):
- it = iter(iterable)
- self.assert_(callable(it.next))
- self.assert_(callable(it.__iter__))
- self.assert_(iter(it) is it)
- # Exhaust the iterator:
- first_time = list(it)
- self.assertRaises(StopIteration, it.next)
- # Subsequent iterations will return the same values:
- self.assertEqual(list(iterable), first_time)
- self.assertEqual(list(iterable), first_time)
-
-
-def test_suite():
- return TestSuite((
- makeSuite(TestBTreeContainer),
- makeSuite(TestBTreeSpecials),
- DocTestSuite('zope.app.container.btree',
- setUp=placelesssetup.setUp,
- tearDown=placelesssetup.tearDown),
- ))
-
-if __name__=='__main__':
- main(defaultTest='test_suite')
Deleted: zope.app.container/trunk/src/zope/app/container/tests/test_constraints.py
===================================================================
--- zope.app.container/trunk/src/zope/app/container/tests/test_constraints.py 2009-01-29 10:24:21 UTC (rev 95397)
+++ zope.app.container/trunk/src/zope/app/container/tests/test_constraints.py 2009-01-29 10:28:20 UTC (rev 95398)
@@ -1,34 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2003 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (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.
-#
-##############################################################################
-"""Container constraint tests
-
-$Id$
-"""
-import unittest
-from zope.testing import doctest, module
-
-def setUp(test):
- module.setUp(test, 'zope.app.container.constraints_txt')
-
-def tearDown(test):
- module.tearDown(test, 'zope.app.container.constraints_txt')
-
-def test_suite():
- return unittest.TestSuite((
- doctest.DocTestSuite('zope.app.container.constraints'),
- doctest.DocFileSuite('../constraints.txt',
- setUp=setUp, tearDown=tearDown),
- ))
-
-if __name__ == '__main__': unittest.main()
Deleted: zope.app.container/trunk/src/zope/app/container/tests/test_contained.py
===================================================================
--- zope.app.container/trunk/src/zope/app/container/tests/test_contained.py 2009-01-29 10:24:21 UTC (rev 95397)
+++ zope.app.container/trunk/src/zope/app/container/tests/test_contained.py 2009-01-29 10:28:20 UTC (rev 95398)
@@ -1,327 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2003 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (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.
-#
-##############################################################################
-"""Contained Tests
-
-$Id$
-"""
-import unittest
-import gc
-from ZODB.DemoStorage import DemoStorage
-from ZODB.DB import DB
-import transaction
-from persistent import Persistent
-
-import zope.interface
-from zope.testing import doctest
-
-from zope.app.container.contained import ContainedProxy
-from zope.app.testing import placelesssetup
-
-class MyOb(Persistent):
- pass
-
-def test_basic_proxy_attribute_management_and_picklability():
- """Contained-object proxy
-
- This is a picklable proxy that can be put around objects that
- don't implement IContained.
-
- >>> l = [1, 2, 3]
- >>> p = ContainedProxy(l)
- >>> p.__parent__ = 'Dad'
- >>> p.__name__ = 'p'
- >>> p
- [1, 2, 3]
- >>> p.__parent__
- 'Dad'
- >>> p.__name__
- 'p'
-
- >>> import pickle
- >>> p2 = pickle.loads(pickle.dumps(p))
- >>> p2
- [1, 2, 3]
- >>> p2.__parent__
- 'Dad'
- >>> p2.__name__
- 'p'
- """
-
-def test_basic_persistent_w_non_persistent_proxied():
- """
- >>> p = ContainedProxy([1])
- >>> p.__parent__ = 2
- >>> p.__name__ = 'test'
- >>> db = DB(DemoStorage('test_storage'))
- >>> c = db.open()
- >>> c.root()['p'] = p
- >>> transaction.commit()
-
- >>> c2 = db.open()
- >>> p2 = c2.root()['p']
- >>> p2
- [1]
- >>> p2.__parent__
- 2
- >>> p2.__name__
- 'test'
-
- >>> p2._p_changed
- 0
- >>> p2._p_deactivate()
- >>> p2._p_changed
- >>> p2.__name__
- 'test'
-
- >>> db.close()
- """
-
-def test_declarations_on_ContainedProxy():
- r"""
-
- It is possible to make declarations on ContainedProxy objects.
-
- >>> class I1(zope.interface.Interface):
- ... pass
- >>> class C(object):
- ... zope.interface.implements(I1)
-
- >>> c = C()
- >>> p = ContainedProxy(c)
-
- ContainedProxy provides no interfaces on it's own:
-
- >>> tuple(zope.interface.providedBy(ContainedProxy))
- ()
-
- It implements IContained and IPersistent:
-
- >>> tuple(zope.interface.implementedBy(ContainedProxy))
- (<InterfaceClass zope.app.container.interfaces.IContained>,
- <InterfaceClass persistent.interfaces.IPersistent>)
-
- A proxied object has IContainer, in addition to what the unproxied
- object has:
-
- >>> tuple(zope.interface.providedBy(p))
- (<InterfaceClass zope.app.container.tests.test_contained.I1>,
- <InterfaceClass zope.app.container.interfaces.IContained>,
- <InterfaceClass persistent.interfaces.IPersistent>)
-
- >>> class I2(zope.interface.Interface):
- ... pass
- >>> zope.interface.directlyProvides(c, I2)
- >>> tuple(zope.interface.providedBy(p))
- (<InterfaceClass zope.app.container.tests.test_contained.I2>,
- <InterfaceClass zope.app.container.tests.test_contained.I1>,
- <InterfaceClass zope.app.container.interfaces.IContained>,
- <InterfaceClass persistent.interfaces.IPersistent>)
-
- We can declare interfaces through the proxy:
-
- >>> class I3(zope.interface.Interface):
- ... pass
- >>> zope.interface.directlyProvides(p, I3)
- >>> tuple(zope.interface.providedBy(p))
- (<InterfaceClass zope.app.container.tests.test_contained.I3>,
- <InterfaceClass zope.app.container.tests.test_contained.I1>,
- <InterfaceClass zope.app.container.interfaces.IContained>,
- <InterfaceClass persistent.interfaces.IPersistent>)
-
- """
-
-def test_basic_persistent_w_persistent_proxied():
- """
-
- Here, we'll verify that shared references work and
- that updates to both the proxies and the proxied objects
- are made correctly.
-
- ----------------------
- | |
- parent other
- | /
- ob <--------------
-
- Here we have an object, parent, that contains ob. There is another
- object, other, that has a non-container reference to ob.
-
- >>> parent = MyOb()
- >>> parent.ob = ContainedProxy(MyOb())
- >>> parent.ob.__parent__ = parent
- >>> parent.ob.__name__ = 'test'
- >>> other = MyOb()
- >>> other.ob = parent.ob
-
- We can change ob through either parent or other
-
- >>> parent.ob.x = 1
- >>> other.ob.y = 2
-
- Now we'll save the data:
-
- >>> db = DB(DemoStorage('test_storage'))
- >>> c1 = db.open()
- >>> c1.root()['parent'] = parent
- >>> c1.root()['other'] = other
- >>> transaction.commit()
-
- We'll open a second connection and verify that we have the data we
- expect:
-
- >>> c2 = db.open()
- >>> p2 = c2.root()['parent']
- >>> p2.ob.__parent__ is p2
- 1
- >>> p2.ob.x
- 1
- >>> p2.ob.y
- 2
- >>> o2 = c2.root()['other']
- >>> o2.ob is p2.ob
- 1
- >>> o2.ob is p2.ob
- 1
- >>> o2.ob.__name__
- 'test'
-
- Now we'll change things around a bit. We'll move things around
- a bit. We'll also add an attribute to ob
-
- >>> o2.ob.__name__ = 'test 2'
- >>> o2.ob.__parent__ = o2
- >>> o2.ob.z = 3
-
- >>> p2.ob.__parent__ is p2
- 0
- >>> p2.ob.__parent__ is o2
- 1
-
- And save the changes:
-
- >>> transaction.commit()
-
- Now we'll reopen the first connection and verify that we can see
- the changes:
-
- >>> c1.close()
- >>> c1 = db.open()
- >>> p2 = c1.root()['parent']
- >>> p2.ob.__name__
- 'test 2'
- >>> p2.ob.z
- 3
- >>> p2.ob.__parent__ is c1.root()['other']
- 1
-
- >>> db.close()
- """
-
-def test_proxy_cache_interaction():
- """Test to make sure the proxy properly interacts with the object cache
-
- Persistent objects are their own weak refs. Thier deallocators
- need to notify their connection's cache that their object is being
- deallocated, so that it is removed from the cache.
-
- >>> from ZODB.tests.util import DB
- >>> db = DB()
- >>> db.setCacheSize(5)
- >>> conn = db.open()
- >>> conn.root()['p'] = ContainedProxy(None)
-
- We need to create some filler objects to push our proxy out of the cache:
-
- >>> for i in range(10):
- ... conn.root()[i] = MyOb()
-
- >>> transaction.commit()
-
- Let's get the oid of our proxy:
-
- >>> oid = conn.root()['p']._p_oid
-
- Now, we'll access the filler object's:
-
- >>> x = [getattr(conn.root()[i], 'x', 0) for i in range(10)]
-
- We've also accessed the root object. If we garbage-collect the
- cache:
-
- >>> conn._cache.incrgc()
-
- Then the root object will still be active, because it was accessed
- recently:
-
- >>> conn.root()._p_changed
- 0
-
- And the proxy will be in the cache, because it's refernced from
- the root object:
-
- >>> conn._cache.get(oid) is not None
- True
-
- But it's a ghost:
-
- >>> conn.root()['p']._p_changed
-
- If we deactivate the root object:
-
- >>> conn.root()._p_deactivate()
-
- Then we'll release the last reference to the proxy and it should
- no longer be in the cache. To be sure, we'll call gc:
-
- >>> x = gc.collect()
- >>> conn._cache.get(oid) is not None
- False
-
- """
-
-def test_ContainedProxy_instances_have_no_instance_dictionaries():
- """Make sure that proxies don't introduce extra instance dictionaries
-
- >>> from zope.app.container.contained import ContainedProxy
- >>> class C:
- ... pass
-
- >>> c = C()
- >>> c.x = 1
- >>> c.__dict__
- {'x': 1}
-
- >>> p = ContainedProxy(c)
- >>> p.__dict__
- {'x': 1}
- >>> p.y = 3
- >>> p.__dict__
- {'y': 3, 'x': 1}
- >>> c.__dict__
- {'y': 3, 'x': 1}
-
- >>> p.__dict__ is c.__dict__
- True
-
- """
-
-def test_suite():
- return unittest.TestSuite((
- doctest.DocTestSuite('zope.app.container.contained',
- setUp=placelesssetup.setUp,
- tearDown=placelesssetup.tearDown),
- doctest.DocTestSuite(optionflags=doctest.NORMALIZE_WHITESPACE),
- ))
-
-if __name__ == '__main__': unittest.main()
Deleted: zope.app.container/trunk/src/zope/app/container/tests/test_containertraversable.py
===================================================================
--- zope.app.container/trunk/src/zope/app/container/tests/test_containertraversable.py 2009-01-29 10:24:21 UTC (rev 95397)
+++ zope.app.container/trunk/src/zope/app/container/tests/test_containertraversable.py 2009-01-29 10:28:20 UTC (rev 95398)
@@ -1,75 +0,0 @@
-##############################################################################
-#
-# 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.1 (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.
-#
-##############################################################################
-"""Container Traverser tests.
-
-$Id$
-"""
-import unittest
-from zope.testing.cleanup import CleanUp
-from zope.interface import implements
-from zope.traversing.interfaces import TraversalError
-
-from zope.app.container.traversal import ContainerTraversable
-from zope.app.container.interfaces import IContainer
-
-class Container(object):
-
- implements(IContainer)
-
- def __init__(self, attrs={}, objs={}):
- for attr,value in attrs.iteritems():
- setattr(self, attr, value)
-
- self.__objs = {}
- for name,value in objs.iteritems():
- self.__objs[name] = value
-
-
- def __getitem__(self, name):
- return self.__objs[name]
-
- def get(self, name, default=None):
- return self.__objs.get(name, default)
-
- def __contains__(self, name):
- return self.__objs.has_key(name)
-
-
-class Test(CleanUp, unittest.TestCase):
- def testAttr(self):
- # test container path traversal
- foo = Container()
- bar = Container()
- baz = Container()
- c = Container({'foo': foo}, {'bar': bar, 'foo': baz})
-
- T = ContainerTraversable(c)
- self.failUnless(T.traverse('foo', []) is baz)
- self.failUnless(T.traverse('bar', []) is bar)
-
- self.assertRaises(TraversalError , T.traverse, 'morebar', [])
- def test_unicode_attr(self):
- # test traversal with unicode
- voila = Container()
- c = Container({}, {u'voil\xe0': voila})
- self.failUnless(ContainerTraversable(c).traverse(u'voil\xe0', []) is voila)
-
-
-def test_suite():
- loader = unittest.TestLoader()
- return loader.loadTestsFromTestCase(Test)
-
-
-if __name__ == '__main__':
- unittest.TextTestRunner().run(test_suite())
Deleted: zope.app.container/trunk/src/zope/app/container/tests/test_containertraverser.py
===================================================================
--- zope.app.container/trunk/src/zope/app/container/tests/test_containertraverser.py 2009-01-29 10:24:21 UTC (rev 95397)
+++ zope.app.container/trunk/src/zope/app/container/tests/test_containertraverser.py 2009-01-29 10:28:20 UTC (rev 95398)
@@ -1,94 +0,0 @@
-##############################################################################
-#
-# 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.1 (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.
-#
-##############################################################################
-"""Container Traverser Tests
-
-$Id$
-"""
-import unittest
-from zope.app.container.traversal import ContainerTraverser
-from zope.app.container.interfaces import IReadContainer
-from zope.app.testing import ztapi, placelesssetup
-from zope.publisher.interfaces import NotFound
-from zope.publisher.browser import TestRequest
-from zope.interface import implements
-
-class TestContainer(object):
- implements(IReadContainer)
-
- def __init__(self, **kw):
- for name, value in kw.items():
- setattr(self, name , value)
-
- def get(self, name, default=None):
- return getattr(self, name, default)
-
-
-class View(object):
- def __init__(self, context, request):
- self.context = context
- self.request = request
-
-
-class TraverserTest(placelesssetup.PlacelessSetup, unittest.TestCase):
-
- # The following two methods exist, so that other container traversers can
- # use these tests as a base.
- def _getTraverser(self, context, request):
- return ContainerTraverser(context, request)
-
- def _getContainer(self, **kw):
- return TestContainer(**kw)
-
- def setUp(self):
- super(TraverserTest, self).setUp()
- # Create a small object tree
- self.foo = self._getContainer()
- foo2 = self._getContainer(Foo=self.foo)
- # Initiate a request
- self.request = TestRequest()
- # Create the traverser
- self.traverser = self._getTraverser(foo2, self.request)
- # Define a simple view for the container
- ztapi.browserView(IReadContainer, 'viewfoo', View)
-
- def test_itemTraversal(self):
- self.assertEqual(
- self.traverser.publishTraverse(self.request, 'Foo'),
- self.foo)
- self.assertRaises(
- NotFound,
- self.traverser.publishTraverse, self.request, 'morebar')
-
- def test_viewTraversal(self):
- self.assertEquals(
- self.traverser.publishTraverse(self.request, 'viewfoo').__class__,
- View)
- self.assertEquals(
- self.traverser.publishTraverse(self.request, 'Foo'),
- self.foo)
- self.assertRaises(
- NotFound,
- self.traverser.publishTraverse, self.request, 'morebar')
- self.assertRaises(
- NotFound,
- self.traverser.publishTraverse, self.request, '@@morebar')
-
-
-def test_suite():
- return unittest.TestSuite((
- unittest.makeSuite(TraverserTest),
- ))
-
-if __name__ == '__main__':
- unittest.main(defaultTest='test_suite')
Deleted: zope.app.container/trunk/src/zope/app/container/tests/test_dependency.py
===================================================================
--- zope.app.container/trunk/src/zope/app/container/tests/test_dependency.py 2009-01-29 10:24:21 UTC (rev 95397)
+++ zope.app.container/trunk/src/zope/app/container/tests/test_dependency.py 2009-01-29 10:28:20 UTC (rev 95398)
@@ -1,52 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2008 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (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.
-#
-##############################################################################
-"""Test the CheckDependency event subscriber.
-
-$Id$
-"""
-import unittest
-
-from zope.interface import implements
-from zope.app.dependable.interfaces import IDependable, DependencyError
-from zope.app.container.contained import ObjectRemovedEvent
-from zope.app.container.dependency import CheckDependency
-from zope.traversing.interfaces import IPhysicallyLocatable
-
-class DummyObject(object):
-
- implements(IDependable, IPhysicallyLocatable)
-
- def dependents(self):
- return ['dependency1', 'dependency2']
-
- def getPath(self):
- return '/dummy-object'
-
-
-class Test(unittest.TestCase):
-
- def testCheckDependency(self):
- obj = DummyObject()
- parent = object()
- event = ObjectRemovedEvent(obj, parent, 'oldName')
- self.assertRaises(DependencyError, CheckDependency, event)
-
-
-def test_suite():
- return unittest.TestSuite((
- unittest.makeSuite(Test),
- ))
-
-if __name__=='__main__':
- unittest.main()
Deleted: zope.app.container/trunk/src/zope/app/container/tests/test_directory.py
===================================================================
--- zope.app.container/trunk/src/zope/app/container/tests/test_directory.py 2009-01-29 10:24:21 UTC (rev 95397)
+++ zope.app.container/trunk/src/zope/app/container/tests/test_directory.py 2009-01-29 10:28:20 UTC (rev 95398)
@@ -1,39 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2003 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (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.
-#
-##############################################################################
-"""FS-based directory implementation tests for containers
-
-$Id$
-"""
-from unittest import TestCase, TestSuite, main, makeSuite
-import zope.app.container.directory
-
-class Directory(object):
- pass
-
-class Test(TestCase):
-
- def test_Cloner(self):
- d = Directory()
- d.a = 1
- clone = zope.app.container.directory.Cloner(d)('foo')
- self.assert_(clone != d)
- self.assertEqual(clone.__class__, d.__class__)
-
-def test_suite():
- return TestSuite((
- makeSuite(Test),
- ))
-
-if __name__=='__main__':
- main(defaultTest='test_suite')
Deleted: zope.app.container/trunk/src/zope/app/container/tests/test_find.py
===================================================================
--- zope.app.container/trunk/src/zope/app/container/tests/test_find.py 2009-01-29 10:24:21 UTC (rev 95397)
+++ zope.app.container/trunk/src/zope/app/container/tests/test_find.py 2009-01-29 10:28:20 UTC (rev 95398)
@@ -1,174 +0,0 @@
-##############################################################################
-#
-# 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.1 (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.
-#
-##############################################################################
-"""Find functionality tests
-
-$Id$
-"""
-from unittest import TestCase, main, makeSuite
-from zope.app.container.interfaces import IReadContainer
-from zope.app.container.interfaces import IObjectFindFilter
-from zope.app.container.find import FindAdapter, SimpleIdFindFilter
-from zope.app.container.find import SimpleInterfacesFindFilter
-from zope.interface import implements, Interface, directlyProvides
-
-class FakeContainer(object):
- implements(IReadContainer)
-
- def __init__(self, id, objects):
- self._id = id
- self._objects = objects
-
- def keys(self):
- return [object._id for object in self._objects]
-
- def values(self):
- return self._objects
-
- def items(self):
- return [(object._id, object) for object in self._objects]
-
- def __getitem__(self, id):
- for object in self._objects:
- if object._id == id:
- return object
- raise KeyError("Could not find %s" % id)
-
- def get(self, id, default=None):
- for object in self._objects:
- if object._id == id:
- return object
-
- return default
-
- def __contains__(self, id):
- for object in self._objects:
- if object.id == id:
- return True
- return False
-
- def __len__(self):
- return len(self._objects)
-
-class FakeInterfaceFoo(Interface):
- """Test interface Foo"""
-
-class FakeInterfaceBar(Interface):
- """Test interface Bar"""
-
-class FakeInterfaceSpam(Interface):
- """Test interface Spam"""
-
-class TestObjectFindFilter(object):
- implements(IObjectFindFilter)
-
- def __init__(self, count):
- self._count = count
-
- def matches(self, object):
- if IReadContainer.providedBy(object):
- return len(object) == self._count
- else:
- return False
-
-class Test(TestCase):
- def test_idFind(self):
- alpha = FakeContainer('alpha', [])
- delta = FakeContainer('delta', [])
- beta = FakeContainer('beta', [delta])
- gamma = FakeContainer('gamma', [])
- tree = FakeContainer(
- 'tree',
- [alpha, beta, gamma])
- find = FindAdapter(tree)
- # some simple searches
- result = find.find([SimpleIdFindFilter(['beta'])])
- self.assertEquals([beta], result)
- result = find.find([SimpleIdFindFilter(['gamma'])])
- self.assertEquals([gamma], result)
- result = find.find([SimpleIdFindFilter(['delta'])])
- self.assertEquals([delta], result)
- # we should not find the container we search on
- result = find.find([SimpleIdFindFilter(['tree'])])
- self.assertEquals([], result)
- # search for multiple ids
- result = find.find([SimpleIdFindFilter(['alpha', 'beta'])])
- self.assertEquals([alpha, beta], result)
- result = find.find([SimpleIdFindFilter(['beta', 'delta'])])
- self.assertEquals([beta, delta], result)
- # search without any filters, find everything
- result = find.find([])
- self.assertEquals([alpha, beta, delta, gamma], result)
- # search for something that doesn't exist
- result = find.find([SimpleIdFindFilter(['foo'])])
- self.assertEquals([], result)
- # find for something that has two ids at the same time,
- # can't ever be the case
- result = find.find([SimpleIdFindFilter(['alpha']),
- SimpleIdFindFilter(['beta'])])
- self.assertEquals([], result)
-
- def test_objectFind(self):
- alpha = FakeContainer('alpha', [])
- delta = FakeContainer('delta', [])
- beta = FakeContainer('beta', [delta])
- gamma = FakeContainer('gamma', [])
- tree = FakeContainer(
- 'tree',
- [alpha, beta, gamma])
- find = FindAdapter(tree)
- result = find.find(object_filters=[TestObjectFindFilter(0)])
- self.assertEquals([alpha, delta, gamma], result)
- result = find.find(object_filters=[TestObjectFindFilter(1)])
- self.assertEquals([beta], result)
- result = find.find(object_filters=[TestObjectFindFilter(2)])
- self.assertEquals([], result)
-
- def test_combinedFind(self):
- alpha = FakeContainer('alpha', [])
- delta = FakeContainer('delta', [])
- beta = FakeContainer('beta', [delta])
- gamma = FakeContainer('gamma', [])
- tree = FakeContainer(
- 'tree',
- [alpha, beta, gamma])
- find = FindAdapter(tree)
- result = find.find(id_filters=[SimpleIdFindFilter(['alpha'])],
- object_filters=[TestObjectFindFilter(0)])
- self.assertEquals([alpha], result)
-
- result = find.find(id_filters=[SimpleIdFindFilter(['alpha'])],
- object_filters=[TestObjectFindFilter(1)])
- self.assertEquals([], result)
-
- def test_interfaceFind(self):
- alpha = FakeContainer('alpha', [])
- directlyProvides(alpha, FakeInterfaceBar)
- delta = FakeContainer('delta', [])
- directlyProvides(delta, FakeInterfaceFoo)
- beta = FakeContainer('beta', [delta])
- directlyProvides(beta, FakeInterfaceSpam)
- gamma = FakeContainer('gamma', [])
- tree = FakeContainer(
- 'tree',
- [alpha, beta, gamma])
- find = FindAdapter(tree)
- result = find.find(object_filters=[
- SimpleInterfacesFindFilter(FakeInterfaceFoo, FakeInterfaceSpam)])
- self.assertEqual([beta, delta], result)
-
-def test_suite():
- return makeSuite(Test)
-
-if __name__=='__main__':
- main(defaultTest='test_suite')
Deleted: zope.app.container/trunk/src/zope/app/container/tests/test_icontainer.py
===================================================================
--- zope.app.container/trunk/src/zope/app/container/tests/test_icontainer.py 2009-01-29 10:24:21 UTC (rev 95397)
+++ zope.app.container/trunk/src/zope/app/container/tests/test_icontainer.py 2009-01-29 10:28:20 UTC (rev 95398)
@@ -1,319 +0,0 @@
-##############################################################################
-#
-# 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.1 (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.
-#
-##############################################################################
-"""Test the IContainer interface.
-
-$Id$
-"""
-from unittest import TestCase, main, makeSuite
-
-from zope.interface.verify import verifyObject
-from zope.app.container.interfaces import IContainer
-from zope.app.testing import placelesssetup
-
-
-def DefaultTestData():
- return [('3', '0'), ('2', '1'), ('4', '2'), ('6', '3'), ('0', '4'),
- ('5', '5'), ('1', '6'), ('8', '7'), ('7', '8'), ('9', '9')]
-
-class BaseTestIContainer(placelesssetup.PlacelessSetup):
- """Base test cases for containers.
-
- Subclasses must define a makeTestObject that takes no
- arguments and that returns a new empty test container,
- and a makeTestData that also takes no arguments and returns
- a sequence of (key, value) pairs that may be stored in
- the test container. The list must be at least ten items long.
- 'NoSuchKey' may not be used as a key value in the returned list.
- """
-
- def __setUp(self):
- self.__container = container = self.makeTestObject()
- self.__data = data = self.makeTestData()
- for k, v in data:
- container[k] = v
- return container, data
-
- ############################################################
- # Interface-driven tests:
-
- def testIContainerVerify(self):
- verifyObject(IContainer, self.makeTestObject())
-
- def test_keys(self):
- # See interface IReadContainer
- container = self.makeTestObject()
- keys = container.keys()
- self.assertEqual(list(keys), [])
-
- container, data = self.__setUp()
- keys = container.keys()
- keys = list(keys); keys.sort() # convert to sorted list
- ikeys = [ k for k, v in data ]; ikeys.sort() # sort input keys
- self.assertEqual(keys, ikeys)
-
- def test_get(self):
- # See interface IReadContainer
- default = object()
- data = self.makeTestData()
- container = self.makeTestObject()
- self.assertRaises(KeyError, container.__getitem__, data[0][0])
- self.assertEqual(container.get(data[0][0], default), default)
-
- container, data = self.__setUp()
- self.assertRaises(KeyError, container.__getitem__,
- self.getUnknownKey())
- self.assertEqual(container.get(self.getUnknownKey(), default), default)
- for i in (1, 8, 7, 3, 4):
- self.assertEqual(container.get(data[i][0], default), data[i][1])
- self.assertEqual(container.get(data[i][0]), data[i][1])
-
- def test_values(self):
- # See interface IReadContainer
- container = self.makeTestObject()
- values = container.values()
- self.assertEqual(list(values), [])
-
- container, data = self.__setUp()
- values = list(container.values())
- for k, v in data:
- try:
- values.remove(v)
- except ValueError:
- self.fail('Value not in list')
-
- self.assertEqual(values, [])
-
- def test_len(self):
- # See interface IReadContainer
- container = self.makeTestObject()
- self.assertEqual(len(container), 0)
-
- container, data = self.__setUp()
- self.assertEqual(len(container), len(data))
-
- def test_items(self):
- # See interface IReadContainer
- container = self.makeTestObject()
- items = container.items()
- self.assertEqual(list(items), [])
-
- container, data = self.__setUp()
- items = container.items()
- items = list(items); items.sort() # convert to sorted list
- data.sort() # sort input data
- self.assertEqual(items, data)
-
- def test___contains__(self):
- # See interface IReadContainer
- container = self.makeTestObject()
- data = self.makeTestData()
- self.assertEqual(not not (data[6][0] in container), False)
-
- container, data = self.__setUp()
- self.assertEqual(not not (data[6][0] in container), True)
- for i in (1, 8, 7, 3, 4):
- self.assertEqual(not not (data[i][0] in container), 1)
-
- def test_delObject(self):
- # See interface IWriteContainer
- default = object()
- data = self.makeTestData()
- container = self.makeTestObject()
- self.assertRaises(KeyError, container.__delitem__, data[0][0])
-
- container, data = self.__setUp()
- self.assertRaises(KeyError, container.__delitem__,
- self.getUnknownKey())
- for i in (1, 8, 7, 3, 4):
- del container[data[i][0]]
- for i in (1, 8, 7, 3, 4):
- self.assertRaises(KeyError, container.__getitem__, data[i][0])
- self.assertEqual(container.get(data[i][0], default), default)
- for i in (0, 2, 9, 6, 5):
- self.assertEqual(container[data[i][0]], data[i][1])
-
- ############################################################
- # Tests from Folder
-
- def testEmpty(self):
- folder = self.makeTestObject()
- data = self.makeTestData()
- self.failIf(folder.keys())
- self.failIf(folder.values())
- self.failIf(folder.items())
- self.failIf(len(folder))
- self.failIf(data[6][0] in folder)
-
- self.assertEquals(folder.get(data[6][0], None), None)
- self.assertRaises(KeyError, folder.__getitem__, data[6][0])
-
- self.assertRaises(KeyError, folder.__delitem__, data[6][0])
-
- def testBadKeyTypes(self):
- folder = self.makeTestObject()
- data = self.makeTestData()
- value = data[1][1]
- for name in self.getBadKeyTypes():
- self.assertRaises(TypeError, folder.__setitem__, name, value)
-
- def testOneItem(self):
- folder = self.makeTestObject()
- data = self.makeTestData()
-
- foo = data[0][1]
- name = data[0][0]
- folder[name] = foo
-
- self.assertEquals(len(folder.keys()), 1)
- self.assertEquals(folder.keys()[0], name)
- self.assertEquals(len(folder.values()), 1)
- self.assertEquals(folder.values()[0], foo)
- self.assertEquals(len(folder.items()), 1)
- self.assertEquals(folder.items()[0], (name, foo))
- self.assertEquals(len(folder), 1)
-
- self.failUnless(name in folder)
- # Use an arbitrary id frpm the data set; don;t just use any id, since
- # there might be restrictions on their form
- self.failIf(data[6][0] in folder)
-
- self.assertEquals(folder.get(name, None), foo)
- self.assertEquals(folder[name], foo)
-
- self.assertRaises(KeyError, folder.__getitem__, data[6][0])
-
- foo2 = data[1][1]
-
- name2 = data[1][0]
- folder[name2] = foo2
-
- self.assertEquals(len(folder.keys()), 2)
- self.assertEquals(not not name2 in folder.keys(), True)
- self.assertEquals(len(folder.values()), 2)
- self.assertEquals(not not foo2 in folder.values(), True)
- self.assertEquals(len(folder.items()), 2)
- self.assertEquals(not not (name2, foo2) in folder.items(), True)
- self.assertEquals(len(folder), 2)
-
- del folder[name]
- del folder[name2]
-
- self.failIf(folder.keys())
- self.failIf(folder.values())
- self.failIf(folder.items())
- self.failIf(len(folder))
- self.failIf(name in folder)
-
- self.assertRaises(KeyError, folder.__getitem__, name)
- self.assertEquals(folder.get(name, None), None)
- self.assertRaises(KeyError, folder.__delitem__, name)
-
- def testManyItems(self):
- folder = self.makeTestObject()
- data = self.makeTestData()
- objects = [ data[i][1] for i in range(4) ]
- name0 = data[0][0]
- name1 = data[1][0]
- name2 = data[2][0]
- name3 = data[3][0]
- folder[name0] = objects[0]
- folder[name1] = objects[1]
- folder[name2] = objects[2]
- folder[name3] = objects[3]
-
- self.assertEquals(len(folder.keys()), len(objects))
- self.failUnless(name0 in folder.keys())
- self.failUnless(name1 in folder.keys())
- self.failUnless(name2 in folder.keys())
- self.failUnless(name3 in folder.keys())
-
- self.assertEquals(len(folder.values()), len(objects))
- self.failUnless(objects[0] in folder.values())
- self.failUnless(objects[1] in folder.values())
- self.failUnless(objects[2] in folder.values())
- self.failUnless(objects[3] in folder.values())
-
- self.assertEquals(len(folder.items()), len(objects))
- self.failUnless((name0, objects[0]) in folder.items())
- self.failUnless((name1, objects[1]) in folder.items())
- self.failUnless((name2, objects[2]) in folder.items())
- self.failUnless((name3, objects[3]) in folder.items())
-
- self.assertEquals(len(folder), len(objects))
-
- self.failUnless(name0 in folder)
- self.failUnless(name1 in folder)
- self.failUnless(name2 in folder)
- self.failUnless(name3 in folder)
- self.failIf(data[5][0] in folder)
-
- self.assertEquals(folder.get(name0, None), objects[0])
- self.assertEquals(folder[name0], objects[0])
- self.assertEquals(folder.get(name1, None), objects[1])
- self.assertEquals(folder[name1], objects[1])
- self.assertEquals(folder.get(name2, None), objects[2])
- self.assertEquals(folder[name2], objects[2])
- self.assertEquals(folder.get(name3, None), objects[3])
- self.assertEquals(folder[name3], objects[3])
-
- self.assertEquals(folder.get(data[5][0], None), None)
- self.assertRaises(KeyError, folder.__getitem__, data[5][0])
-
- del folder[name0]
- self.assertEquals(len(folder), len(objects) - 1)
- self.failIf(name0 in folder)
- self.failIf(name0 in folder.keys())
-
- self.failIf(objects[0] in folder.values())
- self.failIf((name0, objects[0]) in folder.items())
-
- self.assertEquals(folder.get(name0, None), None)
- self.assertRaises(KeyError, folder.__getitem__, name0)
-
- self.assertRaises(KeyError, folder.__delitem__, name0)
-
- del folder[name1]
- del folder[name2]
- del folder[name3]
-
- self.failIf(folder.keys())
- self.failIf(folder.values())
- self.failIf(folder.items())
- self.failIf(len(folder))
- self.failIf(name0 in folder)
- self.failIf(name1 in folder)
- self.failIf(name2 in folder)
- self.failIf(name3 in folder)
-
-
-class TestSampleContainer(BaseTestIContainer, TestCase):
-
- def makeTestObject(self):
- from zope.app.container.sample import SampleContainer
- return SampleContainer()
-
- def makeTestData(self):
- return DefaultTestData()
-
- def getUnknownKey(self):
- return '10'
-
- def getBadKeyTypes(self):
- return [None, ['foo'], 1, '\xf3abc']
-
-def test_suite():
- return makeSuite(TestSampleContainer)
-
-if __name__=='__main__':
- main(defaultTest='test_suite')
Deleted: zope.app.container/trunk/src/zope/app/container/tests/test_objectcopier.py
===================================================================
--- zope.app.container/trunk/src/zope/app/container/tests/test_objectcopier.py 2009-01-29 10:24:21 UTC (rev 95397)
+++ zope.app.container/trunk/src/zope/app/container/tests/test_objectcopier.py 2009-01-29 10:28:20 UTC (rev 95398)
@@ -1,211 +0,0 @@
-##############################################################################
-#
-# 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.1 (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.
-#
-##############################################################################
-"""Object Copier Tests
-
-$Id$
-"""
-from unittest import TestCase, TestSuite, main, makeSuite
-
-import zope.component
-from zope.testing import doctest
-from zope.traversing.api import traverse
-from zope.component.eventtesting import getEvents, clearEvents
-from zope.copypastemove import ObjectCopier
-from zope.copypastemove.interfaces import IObjectCopier
-
-from zope.app.component.testing import PlacefulSetup
-from zope.app.testing import setup
-from zope.app.folder import Folder
-
-class File(object):
- pass
-
-def test_copy_events():
- """
- Prepare the setup::
-
- >>> root = setup.placefulSetUp(site=True)
- >>> zope.component.provideAdapter(ObjectCopier, (None,), IObjectCopier)
-
- Prepare some objects::
-
- >>> folder = Folder()
- >>> root[u'foo'] = File()
- >>> root[u'folder'] = folder
- >>> list(folder.keys())
- []
- >>> foo = traverse(root, 'foo') # wrap in ContainedProxy
-
- Now make a copy::
-
- >>> clearEvents()
- >>> copier = IObjectCopier(foo)
- >>> copier.copyTo(folder, u'bar')
- u'bar'
-
- Check that the copy has been done::
-
- >>> list(folder.keys())
- [u'bar']
-
- Check what events have been sent::
-
- >>> events = getEvents()
- >>> [event.__class__.__name__ for event in events]
- ['ObjectCopiedEvent', 'ObjectAddedEvent', 'ContainerModifiedEvent']
-
- Check that the ObjectCopiedEvent includes the correct data::
-
- >>> events[0].object is folder[u'bar']
- True
- >>> events[0].original is root[u'foo']
- True
-
- Finally, tear down::
-
- >>> setup.placefulTearDown()
- """
-
-
-class ObjectCopierTest(PlacefulSetup, TestCase):
-
- def setUp(self):
- PlacefulSetup.setUp(self)
- PlacefulSetup.buildFolders(self)
- zope.component.provideAdapter(ObjectCopier, (None,), IObjectCopier)
-
- def test_copytosame(self):
- root = self.rootFolder
- container = traverse(root, 'folder1')
- container['file1'] = File()
- file = traverse(root, 'folder1/file1')
- copier = IObjectCopier(file)
- copier.copyTo(container, 'file1')
- self.failUnless('file1' in container)
- self.failUnless('file1-2' in container)
-
- def test_copytosamewithnewname(self):
- root = self.rootFolder
- container = traverse(root, 'folder1')
- container['file1'] = File()
- file = traverse(root, 'folder1/file1')
- copier = IObjectCopier(file)
- copier.copyTo(container, 'file2')
- self.failUnless('file1' in container)
- self.failUnless('file2' in container)
-
- def test_copytoother(self):
- root = self.rootFolder
- container = traverse(root, 'folder1')
- container['file1'] = File()
- target = traverse(root, 'folder2')
- file = traverse(root, 'folder1/file1')
- copier = IObjectCopier(file)
- copier.copyTo(target, 'file1')
- self.failUnless('file1' in container)
- self.failUnless('file1' in target)
-
- def test_copytootherwithnewname(self):
- root = self.rootFolder
- container = traverse(root, 'folder1')
- container['file1'] = File()
- target = traverse(root, 'folder2')
- file = traverse(root, 'folder1/file1')
- copier = IObjectCopier(file)
- copier.copyTo(target, 'file2')
- self.failUnless('file1' in container)
- self.failUnless('file2' in target)
-
- def test_copytootherwithnamecollision(self):
- root = self.rootFolder
- container = traverse(root, 'folder1')
- container['file1'] = File()
- target = traverse(root, 'folder2')
- target['file1'] = File()
- file = traverse(root, 'folder1/file1')
- copier = IObjectCopier(file)
- copier.copyTo(target, 'file1')
- # we do it twice, just to test auto-name generation
- copier.copyTo(target, 'file1')
- self.failUnless('file1' in container)
- self.failUnless('file1' in target)
- self.failUnless('file1-2' in target)
- self.failUnless('file1-3' in target)
-
- def test_copyable(self):
- root = self.rootFolder
- container = traverse(root, 'folder1')
- container['file1'] = File()
- file = traverse(root, 'folder1/file1')
- copier = IObjectCopier(file)
- self.failUnless(copier.copyable())
-
- def test_copyableTo(self):
- # A file should be copyable to a folder that has an
- # object with the same id.
- root = self.rootFolder
- container = traverse(root, 'folder1')
- container['file1'] = File()
- file = traverse(root, 'folder1/file1')
- copier = IObjectCopier(file)
- self.failUnless(copier.copyableTo(container, 'file1'))
-
- def test_copyfoldertosibling(self):
- root = self.rootFolder
- target = traverse(root, '/folder2')
- source = traverse(root, '/folder1/folder1_1')
- copier = IObjectCopier(source)
- copier.copyTo(target)
- self.failUnless('folder1_1' in target)
-
- def test_copyfoldertosame(self):
- root = self.rootFolder
- target = traverse(root, '/folder1')
- source = traverse(root, '/folder1/folder1_1')
- copier = IObjectCopier(source)
- copier.copyTo(target)
- self.failUnless('folder1_1' in target)
-
- def test_copyfoldertosame2(self):
- root = self.rootFolder
- target = traverse(root, '/folder1/folder1_1')
- source = traverse(root, '/folder1/folder1_1/folder1_1_1')
- copier = IObjectCopier(source)
- copier.copyTo(target)
- self.failUnless('folder1_1_1' in target)
-
- def test_copyfolderfromroot(self):
- root = self.rootFolder
- target = traverse(root, '/folder2')
- source = traverse(root, '/folder1')
- copier = IObjectCopier(source)
- copier.copyTo(target)
- self.failUnless('folder1' in target)
-
- def test_copyfolderfromroot2(self):
- root = self.rootFolder
- target = traverse(root, '/folder2/folder2_1/folder2_1_1')
- source = traverse(root, '/folder1')
- copier = IObjectCopier(source)
- copier.copyTo(target)
- self.failUnless('folder1' in target)
-
-def test_suite():
- return TestSuite((
- makeSuite(ObjectCopierTest),
- doctest.DocTestSuite(),
- ))
-
-if __name__=='__main__':
- main(defaultTest='test_suite')
Deleted: zope.app.container/trunk/src/zope/app/container/tests/test_objectmover.py
===================================================================
--- zope.app.container/trunk/src/zope/app/container/tests/test_objectmover.py 2009-01-29 10:24:21 UTC (rev 95397)
+++ zope.app.container/trunk/src/zope/app/container/tests/test_objectmover.py 2009-01-29 10:28:20 UTC (rev 95398)
@@ -1,227 +0,0 @@
-##############################################################################
-#
-# 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.1 (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.
-#
-##############################################################################
-"""Object Mover Tests
-
-$Id$
-"""
-from unittest import TestCase, TestSuite, main, makeSuite
-
-import zope.component
-from zope.testing import doctest
-from zope.traversing.api import traverse
-from zope.component.eventtesting import getEvents, clearEvents
-from zope.copypastemove import ObjectMover
-from zope.copypastemove.interfaces import IObjectMover
-
-from zope.app.component.testing import PlacefulSetup
-from zope.app.testing import setup
-from zope.app.folder import Folder
-
-class File(object):
- pass
-
-def test_move_events():
- """
- Prepare the setup::
-
- >>> root = setup.placefulSetUp(site=True)
- >>> zope.component.provideAdapter(ObjectMover, (None,), IObjectMover)
-
- Prepare some objects::
-
- >>> folder = Folder()
- >>> root[u'foo'] = File()
- >>> root[u'folder'] = folder
- >>> list(folder.keys())
- []
- >>> foo = traverse(root, 'foo') # wrap in ContainedProxy
-
- Now move it::
-
- >>> clearEvents()
- >>> mover = IObjectMover(foo)
- >>> mover.moveableTo(folder)
- True
- >>> mover.moveTo(folder, u'bar')
- u'bar'
-
- Check that the move has been done::
-
- >>> list(root.keys())
- [u'folder']
- >>> list(folder.keys())
- [u'bar']
-
- Check what events have been sent::
-
- >>> events = getEvents()
- >>> [event.__class__.__name__ for event in events]
- ['ObjectMovedEvent', 'ContainerModifiedEvent', 'ContainerModifiedEvent']
-
- Verify that the ObjectMovedEvent includes the correct data::
-
- >>> events[0].oldName, events[0].newName
- (u'foo', u'bar')
- >>> events[0].oldParent is root
- True
- >>> events[0].newParent is folder
- True
-
- Let's look the other events:
-
- >>> events[1].object is folder
- True
- >>> events[2].object is root
- True
-
- Finally, tear down::
-
- >>> setup.placefulTearDown()
- """
-
-
-class ObjectMoverTest(PlacefulSetup, TestCase):
-
- def setUp(self):
- PlacefulSetup.setUp(self)
- PlacefulSetup.buildFolders(self)
- zope.component.provideAdapter(ObjectMover, (None,), )
-
- def test_movetosame(self):
- # Should be a noop, because "moving" to same location
- root = self.rootFolder
- container = traverse(root, 'folder1')
- container['file1'] = File()
- file = traverse(root, 'folder1/file1')
- mover = IObjectMover(file)
- mover.moveTo(container, 'file1')
- self.failUnless('file1' in container)
- self.assertEquals(len(container), 3)
-
- def test_movetosamewithnewname(self):
- root = self.rootFolder
- container = traverse(root, 'folder1')
- container['file1'] = File()
- file = traverse(root, 'folder1/file1')
- mover = IObjectMover(file)
- mover.moveTo(container, 'file2')
- self.failIf('file1' in container)
- self.failUnless('file2' in container)
-
- def test_movetoother(self):
- root = self.rootFolder
- container = traverse(root, 'folder1')
- container['file1'] = File()
- target = traverse(root, 'folder2')
- file = traverse(root, 'folder1/file1')
- mover = IObjectMover(file)
- mover.moveTo(target, 'file1')
- self.failIf('file1' in container)
- self.failUnless('file1' in target)
-
- def test_movetootherwithnewname(self):
- root = self.rootFolder
- container = traverse(root, 'folder1')
- container['file1'] = File()
- target = traverse(root, 'folder2')
- file = traverse(root, 'folder1/file1')
- mover = IObjectMover(file)
- mover.moveTo(target, 'file2')
- self.failIf('file1' in container)
- self.failUnless('file2' in target)
-
- def test_movetootherwithnamecollision(self):
- root = self.rootFolder
- container = traverse(root, 'folder1')
- container['file1'] = File()
- target = traverse(root, 'folder2')
- target['file1'] = File()
- file = traverse(root, 'folder1/file1')
- mover = IObjectMover(file)
- mover.moveTo(target, 'file1')
- self.failIf('file1' in container)
- self.failUnless('file1' in target)
- self.failUnless('file1-2' in target)
-
- def test_moveable(self):
- root = self.rootFolder
- container = traverse(root, 'folder1')
- container['file1'] = File()
- file = traverse(root, 'folder1/file1')
- mover = IObjectMover(file)
- self.failUnless(mover.moveable())
-
- def test_moveableTo(self):
- # A file should be moveable to a folder that has an
- # object with the same id.
- root = self.rootFolder
- container = traverse(root, 'folder1')
- container['file1'] = File()
- file = traverse(root, 'folder1/file1')
- mover = IObjectMover(file)
- self.failUnless(mover.moveableTo(container, 'file1'))
-
- def test_movefoldertosibling(self):
- root = self.rootFolder
- target = traverse(root, '/folder2')
- source = traverse(root, '/folder1/folder1_1')
- mover = IObjectMover(source)
- mover.moveTo(target)
- self.failUnless('folder1_1' in target)
-
- def test_movefoldertosame(self):
- # Should be a noop, because "moving" to same location
- root = self.rootFolder
- target = traverse(root, '/folder1')
- source = traverse(root, '/folder1/folder1_1')
- mover = IObjectMover(source)
- mover.moveTo(target)
- self.failUnless('folder1_1' in target)
- self.assertEquals(len(target), 2)
-
- def test_movefoldertosame2(self):
- # Should be a noop, because "moving" to same location
- root = self.rootFolder
- target = traverse(root, '/folder1/folder1_1')
- source = traverse(root, '/folder1/folder1_1/folder1_1_1')
- mover = IObjectMover(source)
- mover.moveTo(target)
- self.failUnless('folder1_1_1' in target)
- self.assertEquals(len(target), 2)
-
- def test_movefolderfromroot(self):
- root = self.rootFolder
- target = traverse(root, '/folder2')
- source = traverse(root, '/folder1')
- mover = IObjectMover(source)
- mover.moveTo(target)
- self.failUnless('folder1' in target)
-
- def test_movefolderfromroot2(self):
- root = self.rootFolder
- target = traverse(root, '/folder2/folder2_1/folder2_1_1')
- source = traverse(root, '/folder1')
- mover = IObjectMover(source)
- mover.moveTo(target)
- self.failUnless('folder1' in target)
-
-
-def test_suite():
- return TestSuite((
- makeSuite(ObjectMoverTest),
- doctest.DocTestSuite(),
- ))
-
-if __name__=='__main__':
- main(defaultTest='test_suite')
Deleted: zope.app.container/trunk/src/zope/app/container/tests/test_ordered.py
===================================================================
--- zope.app.container/trunk/src/zope/app/container/tests/test_ordered.py 2009-01-29 10:24:21 UTC (rev 95397)
+++ zope.app.container/trunk/src/zope/app/container/tests/test_ordered.py 2009-01-29 10:28:20 UTC (rev 95398)
@@ -1,138 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2003 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (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.
-#
-##############################################################################
-"""Test the OrderedContainer.
-
-$Id$
-"""
-import unittest
-from zope.testing.doctestunit import DocTestSuite
-from zope.component.eventtesting import getEvents, clearEvents
-from zope.app.testing import placelesssetup, setup
-
-def test_order_events():
- """
- Prepare the setup::
-
- >>> root = setup.placefulSetUp(site=True)
-
- Prepare some objects::
-
- >>> from zope.app.container.ordered import OrderedContainer
- >>> oc = OrderedContainer()
- >>> oc['foo'] = 'bar'
- >>> oc['baz'] = 'quux'
- >>> oc['zork'] = 'grue'
- >>> oc.keys()
- ['foo', 'baz', 'zork']
-
- Now change the order::
-
- >>> clearEvents()
- >>> oc.updateOrder(['baz', 'foo', 'zork'])
- >>> oc.keys()
- ['baz', 'foo', 'zork']
-
- Check what events have been sent::
-
- >>> events = getEvents()
- >>> [event.__class__.__name__ for event in events]
- ['ContainerModifiedEvent']
-
- This is in fact a specialized modification event::
-
- >>> from zope.lifecycleevent.interfaces import IObjectModifiedEvent
- >>> IObjectModifiedEvent.providedBy(events[0])
- True
-
- Finally, tear down::
-
- >>> setup.placefulTearDown()
- """
-
-def test_all_items_available_at_object_added_event():
- """
- Prepare the setup::
-
- >>> root = setup.placefulSetUp(site=True)
-
- Now register an event subscriber to object added events.
-
- >>> import zope.component
- >>> from zope.app.container import interfaces
-
- >>> @zope.component.adapter(interfaces.IObjectAddedEvent)
- ... def printContainerKeys(event):
- ... print event.newParent.keys()
-
- >>> zope.component.provideHandler(printContainerKeys)
-
- Now we are adding an object to the container.
-
- >>> from zope.app.container.ordered import OrderedContainer
- >>> oc = OrderedContainer()
- >>> oc['foo'] = 'FOO'
- ['foo']
-
- Finally, tear down::
-
- >>> setup.placefulTearDown()
- """
-
-def test_exception_causes_order_fix():
- """
- Prepare the setup::
-
- >>> root = setup.placefulSetUp(site=True)
-
- Now register an event subscriber to object added events that
- throws an error.
-
- >>> import zope.component
- >>> from zope.app.container import interfaces
-
- >>> @zope.component.adapter(interfaces.IObjectAddedEvent)
- ... def raiseException(event):
- ... raise Exception()
-
- >>> zope.component.provideHandler(raiseException)
-
- Now we are adding an object to the container.
-
- >>> from zope.app.container.ordered import OrderedContainer
- >>> oc = OrderedContainer()
- >>> oc['foo'] = 'FOO'
- Traceback (most recent call last):
- ...
- Exception
-
- The key 'foo' should not be around:
-
- >>> 'foo' in oc.keys()
- False
-
- Finally, tear down::
-
- >>> setup.placefulTearDown()
- """
-
-def test_suite():
- suite = unittest.TestSuite()
- suite.addTest(DocTestSuite("zope.app.container.ordered",
- setUp=placelesssetup.setUp,
- tearDown=placelesssetup.tearDown))
- suite.addTest(DocTestSuite())
- return suite
-
-if __name__ == '__main__':
- unittest.main()
Deleted: zope.app.container/trunk/src/zope/app/container/tests/test_size.py
===================================================================
--- zope.app.container/trunk/src/zope/app/container/tests/test_size.py 2009-01-29 10:24:21 UTC (rev 95397)
+++ zope.app.container/trunk/src/zope/app/container/tests/test_size.py 2009-01-29 10:28:20 UTC (rev 95398)
@@ -1,70 +0,0 @@
-##############################################################################
-#
-# 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.1 (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.
-#
-##############################################################################
-"""Test container ISized adapter.
-
-$Id$
-"""
-import unittest
-
-from zope.interface import implements
-from zope.size.interfaces import ISized
-from zope.app.container.interfaces import IContainer
-
-class DummyContainer(object):
-
- implements(IContainer)
-
- def __init__(self, numitems):
- self._numitems = numitems
-
- def __len__(self):
- return self._numitems
-
-
-class Test(unittest.TestCase):
-
- def testImplementsISized(self):
- from zope.app.container.size import ContainerSized
- sized = ContainerSized(DummyContainer(23))
- self.assert_(ISized.providedBy(sized))
-
- def testEmptyContainer(self):
- from zope.app.container.size import ContainerSized
- obj = DummyContainer(0)
- sized = ContainerSized(obj)
- self.assertEqual(sized.sizeForSorting(), ('item', 0))
- self.assertEqual(sized.sizeForDisplay(), u'${items} items')
- self.assertEqual(sized.sizeForDisplay().mapping['items'], '0')
-
- def testOneItem(self):
- from zope.app.container.size import ContainerSized
- obj = DummyContainer(1)
- sized = ContainerSized(obj)
- self.assertEqual(sized.sizeForSorting(), ('item', 1))
- self.assertEqual(sized.sizeForDisplay(), u'1 item')
-
- def testSeveralItems(self):
- from zope.app.container.size import ContainerSized
- obj = DummyContainer(2)
- sized = ContainerSized(obj)
- self.assertEqual(sized.sizeForSorting(), ('item', 2))
- self.assertEqual(sized.sizeForDisplay(), u'${items} items')
- self.assertEqual(sized.sizeForDisplay().mapping['items'], '2')
-
-def test_suite():
- loader = unittest.TestLoader()
- return loader.loadTestsFromTestCase(Test)
-
-if __name__=='__main__':
- unittest.TextTestRunner().run(test_suite())
Modified: zope.app.container/trunk/src/zope/app/container/traversal.py
===================================================================
--- zope.app.container/trunk/src/zope/app/container/traversal.py 2009-01-29 10:24:21 UTC (rev 95397)
+++ zope.app.container/trunk/src/zope/app/container/traversal.py 2009-01-29 10:28:20 UTC (rev 95398)
@@ -11,99 +11,13 @@
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
-"""Traversal components for containers
-
-$Id$
+"""BBB: this module moved to zope.container
"""
-__docformat__ = 'restructuredtext'
-from zope.interface import implements
-from zope.component import queryMultiAdapter
-from zope.traversing.interfaces import TraversalError, ITraversable
-from zope.publisher.interfaces.browser import IBrowserPublisher
-from zope.publisher.interfaces.xmlrpc import IXMLRPCPublisher
-from zope.publisher.interfaces import NotFound
-
-from zope.app.container.interfaces import ISimpleReadContainer, IItemContainer
-from zope.app.container.interfaces import IReadContainer
-from zope.app.publisher.browser import getDefaultViewName
-
-# Note that the next two classes are included here because they
-# can be used for multiple view types.
-
-class ContainerTraverser(object):
- """A traverser that knows how to look up objects by name in a container."""
-
- implements(IBrowserPublisher, IXMLRPCPublisher)
- __used_for__ = ISimpleReadContainer
-
- def __init__(self, container, request):
- self.context = container
- self.request = request
-
- def publishTraverse(self, request, name):
- """See zope.publisher.interfaces.IPublishTraverse"""
- subob = self.context.get(name, None)
- if subob is None:
- view = queryMultiAdapter((self.context, request), name=name)
- if view is not None:
- return view
-
- raise NotFound(self.context, name, request)
-
- return subob
-
- def browserDefault(self, request):
- """See zope.publisher.browser.interfaces.IBrowserPublisher"""
- view_name = getDefaultViewName(self.context, request)
- view_uri = "@@%s" %view_name
- return self.context, (view_uri,)
-
-
-class ItemTraverser(ContainerTraverser):
- """A traverser that knows how to look up objects by name in an item
- container."""
-
- __used_for__ = IItemContainer
-
- def publishTraverse(self, request, name):
- """See zope.publisher.interfaces.IPublishTraverse"""
- try:
- return self.context[name]
- except KeyError:
- view = queryMultiAdapter((self.context, request), name=name)
- if view is not None:
- return view
-
- raise NotFound(self.context, name, request)
-
-
-_marker = object()
-
-class ContainerTraversable(object):
- """Traverses containers via `getattr` and `get`."""
-
- implements(ITraversable)
- __used_for__ = IReadContainer
-
- def __init__(self, container):
- self._container = container
-
-
- def traverse(self, name, furtherPath):
- container = self._container
-
- v = container.get(name, _marker)
- if v is _marker:
- try:
- # Note that if name is a unicode string, getattr will
- # implicitly try to encode it using the system
- # encoding (usually ascii). Failure to encode means
- # invalid attribute name.
- v = getattr(container, name, _marker)
- except UnicodeEncodeError:
- raise TraversalError(container, name)
- if v is _marker:
- raise TraversalError(container, name)
-
- return v
+# BBB
+from zope.container.traversal import (
+ ContainerTraverser,
+ ItemTraverser,
+ _marker,
+ ContainerTraversable
+)
More information about the Checkins
mailing list