示例#1
0
 def test_default(self):
     # First default wins from left to right
     def1 = default(1)
     self.assertTrue(def1 + def1 is def1)
     def2 = default(2)
     self.assertTrue(def1 + def2 is def1)
     self.assertTrue(def2 + def1 is def2)
     # Override wins over default
     ext3 = override(3)
     self.assertTrue(def1 + ext3 is ext3)
     # Finalize wins over default
     fin4 = finalize(4)
     self.assertTrue(def1 + fin4 is fin4)
     # Adding with something else than default/override, raises
     # ``PlumbingCollision``
     err = None
     try:
         def1 + Instruction('foo')
     except PlumbingCollision as e:
         err = e
     finally:
         self.assertEqual(err.left.__class__.__name__, 'default')
         self.assertEqual(err.left.payload, 1)
         self.assertEqual(err.right.__class__.__name__, 'Instruction')
         self.assertEqual(err.right.payload, 'foo')
示例#2
0
 def test_finalize(self):
     # First override wins against following equal overrides and arbitrary
     # defaults
     fin1 = finalize(1)
     self.assertTrue(fin1 + fin1 is fin1)
     self.assertTrue(fin1 + finalize(1) is fin1)
     self.assertTrue(fin1 + default(2) is fin1)
     self.assertTrue(fin1 + override(2) is fin1)
     # Two unequal finalize collide
     err = None
     try:
         fin1 + finalize(2)
     except PlumbingCollision as e:
         err = e
     finally:
         self.assertEqual(err.left.__class__.__name__, 'finalize')
         self.assertEqual(err.left.payload, 1)
         self.assertEqual(err.right.__class__.__name__, 'finalize')
         self.assertEqual(err.right.payload, 2)
     # Everything except default/override collides
     try:
         fin1 + Instruction(1)
     except PlumbingCollision as e:
         err = e
     finally:
         self.assertEqual(err.left.__class__.__name__, 'finalize')
         self.assertEqual(err.left.payload, 1)
         self.assertEqual(err.right.__class__.__name__, 'Instruction')
         self.assertEqual(err.right.payload, 1)
示例#3
0
 def test_finalize(self):
     # First override wins against following equal overrides and arbitrary
     # defaults
     fin1 = finalize(1)
     self.assertTrue(fin1 + fin1 is fin1)
     self.assertTrue(fin1 + finalize(1) is fin1)
     self.assertTrue(fin1 + default(2) is fin1)
     self.assertTrue(fin1 + override(2) is fin1)
     # Two unequal finalize collide
     err = None
     try:
         fin1 + finalize(2)
     except PlumbingCollision as e:
         err = e
     finally:
         self.assertEqual(err.left.__class__.__name__, 'finalize')
         self.assertEqual(err.left.payload, 1)
         self.assertEqual(err.right.__class__.__name__, 'finalize')
         self.assertEqual(err.right.payload, 2)
     # Everything except default/override collides
     try:
         fin1 + Instruction(1)
     except PlumbingCollision as e:
         err = e
     finally:
         self.assertEqual(err.left.__class__.__name__, 'finalize')
         self.assertEqual(err.left.payload, 1)
         self.assertEqual(err.right.__class__.__name__, 'Instruction')
         self.assertEqual(err.right.payload, 1)
示例#4
0
 def test_default(self):
     # First default wins from left to right
     def1 = default(1)
     self.assertTrue(def1 + def1 is def1)
     def2 = default(2)
     self.assertTrue(def1 + def2 is def1)
     self.assertTrue(def2 + def1 is def2)
     # Override wins over default
     ext3 = override(3)
     self.assertTrue(def1 + ext3 is ext3)
     # Finalize wins over default
     fin4 = finalize(4)
     self.assertTrue(def1 + fin4 is fin4)
     # Adding with something else than default/override, raises
     # ``PlumbingCollision``
     err = None
     try:
         def1 + Instruction('foo')
     except PlumbingCollision as e:
         err = e
     finally:
         self.assertEqual(err.left.__class__.__name__, 'default')
         self.assertEqual(err.left.payload, 1)
         self.assertEqual(err.right.__class__.__name__, 'Instruction')
         self.assertEqual(err.right.payload, 'foo')
示例#5
0
        class Behavior3(Behavior):
            def set_foo(self, value):
                self._foo = value

            foo = plumb(property(
                None,
                override(set_foo),
            ))
示例#6
0
class OverlayForm(Behavior):
    """Form behavior rendering to overlay.
    """
    action_resource = override('overlayform')
    overlay_selector = override('#ajax-overlay')
    overlay_content_selector = override('.overlay_content')

    @plumb
    def __call__(_next, self, model, request):
        form = _next(self, model, request)
        selector = '%s %s' % (self.overlay_selector,
                              self.overlay_content_selector)
        ajax_form_fiddle(request, selector, 'inner')
        return form

    @default
    def next(self, request):
        return [AjaxOverlay(selector=self.overlay_selector, close=True)]
示例#7
0
class ContentAddForm(AddFactoryProxy, AddFormHeading, ContentForm,
                     CameFromNext):
    """Form behavior rendering add form to content area.
    """
    action_resource = override('add')

    @default
    @property
    def rendered_contextmenu(self):
        return render_tile(self.model.parent, self.request, 'contextmenu')
示例#8
0
 def test_override(self):
     # First override wins against following equal overrides and arbitrary
     # defaults
     ext1 = override(1)
     self.assertTrue(ext1 + ext1 is ext1)
     self.assertTrue(ext1 + override(1) is ext1)
     self.assertTrue(ext1 + override(2) is ext1)
     self.assertTrue(ext1 + default(2) is ext1)
     fin3 = finalize(3)
     self.assertTrue(ext1 + fin3 is fin3)
     # Everything except default/override collides
     err = None
     try:
         ext1 + Instruction(1)
     except PlumbingCollision as e:
         err = e
     finally:
         self.assertEqual(err.left.__class__.__name__, 'override')
         self.assertEqual(err.left.payload, 1)
         self.assertEqual(err.right.__class__.__name__, 'Instruction')
         self.assertEqual(err.right.payload, 1)
示例#9
0
 def test_override(self):
     # First override wins against following equal overrides and arbitrary
     # defaults
     ext1 = override(1)
     self.assertTrue(ext1 + ext1 is ext1)
     self.assertTrue(ext1 + override(1) is ext1)
     self.assertTrue(ext1 + override(2) is ext1)
     self.assertTrue(ext1 + default(2) is ext1)
     fin3 = finalize(3)
     self.assertTrue(ext1 + fin3 is fin3)
     # Everything except default/override collides
     err = None
     try:
         ext1 + Instruction(1)
     except PlumbingCollision as e:
         err = e
     finally:
         self.assertEqual(err.left.__class__.__name__, 'override')
         self.assertEqual(err.left.payload, 1)
         self.assertEqual(err.right.__class__.__name__, 'Instruction')
         self.assertEqual(err.right.payload, 1)
示例#10
0
class ChildFactory(Behavior):
    factories = default(odict())

    @override
    def __iter__(self):
        return self.factories.__iter__()

    iterkeys = override(__iter__)

    @plumb
    def __getitem__(_next, self, key):
        try:
            child = _next(self, key)
        except KeyError:
            child = self.factories[key]()
            self[key] = child
        return child
示例#11
0
class Nodify(FullMapping):
    __name__ = default(None)
    __parent__ = default(None)

    @plumb
    def copy(_next, self):
        new = _next(self)
        new.__name__ = self.__name__
        new.__parent__ = self.__parent__
        return new

    @override
    @property
    def name(self):
        return self.__name__

    @override
    @property
    def parent(self):
        return self.__parent__

    @override
    @property
    def path(self):
        path = [parent.name for parent in LocationIterator(self)]
        path.reverse()
        return path

    @override
    @property
    def root(self):
        root = None
        for parent in LocationIterator(self):
            root = parent
        return root

    @override
    def detach(self, key):
        node = self[key]
        del self[key]
        return node

    @override
    def acquire(self, interface):
        node = self.parent
        while node:
            if (IInterface.providedBy(interface) and
                    interface.providedBy(node)) or \
                    isinstance(node, interface):
                return node
            node = node.parent

    @override
    def filtereditervalues(self, interface):
        for val in self.itervalues():
            if interface.providedBy(val):
                yield val

    @override
    def filteredvalues(self, interface):
        return [val for val in self.filtereditervalues(interface)]

    # B/C 2010-12-23
    filtereditems = override(filtereditervalues)

    @override
    @property
    def noderepr(self):
        """``noderepr`` is used in ``treerepr``.

        Thus, we can overwrite it in subclass and return any debug information
        we need while ``__repr__`` is an enhanced standard object
        representation, also used as ``__str__`` on nodes.
        """
        class_name = self.__class__
        name = self.name.encode('ascii', 'replace') \
            if IS_PY2 and isinstance(self.name, unicode) \
            else str(self.name)
        return str(class_name) + ': ' + name[name.find(':') + 1:]

    @override
    def treerepr(self, indent=0, prefix=' '):
        res = '{}{}\n'.format(indent * prefix, self.noderepr)
        items = self.items() \
            if IOrdered.providedBy(self) \
            else sorted(self.items(), key=lambda x: safe_decode(x[0]))
        for key, value in items:
            if INode.providedBy(value):
                res += value.treerepr(indent=indent + 2, prefix=prefix)
            else:
                res += '{}{}: {}\n'.format((indent + 2) * prefix, key,
                                           repr(value))
        return res

    @override
    def printtree(self):
        print(self.treerepr())  # pragma: no cover

    @default
    def __nonzero__(self):
        return True

    __bool__ = default(__nonzero__)

    @override
    def __repr__(self):
        class_name = self.__class__.__name__
        name = self.name.encode('ascii', 'replace') \
            if IS_PY2 and isinstance(self.name, unicode) \
            else str(self.name)
        return '<{} object \'{}\' at {}>'.format(class_name, name,
                                                 hex(id(self))[:-1])

    __str__ = override(__repr__)
class Reference(Behavior):
    _uuid = default(None)

    @plumb
    def __init__(_next, self, *args, **kw):
        self._index = dict()
        self.uuid = uuid.uuid4()
        _next(self, *args, **kw)

    @plumb
    def __setitem__(_next, self, key, val):
        if INode.providedBy(val):
            try:
                next(val.iterkeys())
                keys = set(self._index.keys())
                if keys.intersection(val._index.keys()):
                    raise ValueError('Node with uuid already exists')
            except StopIteration:
                pass
            self._index.update(val._index)
            val._index = self._index
        _next(self, key, val)

    @plumb
    def __delitem__(_next, self, key):
        # fail immediately if key does not exist
        todel = self[key]
        if hasattr(todel, '_to_delete'):
            for iuuid in todel._to_delete():
                del self._index[iuuid]
        _next(self, key)

    @plumb
    def detach(_next, self, key):
        node = _next(self, key)
        node._index = {int(node.uuid): node}
        node._index_nodes()
        return node

    def _get_uuid(self):
        return self._uuid

    def _set_uuid(self, uuid):
        iuuid = uuid is not None and int(uuid) or None
        if iuuid in self._index \
                and self._index[iuuid] is not self:
            raise ValueError('Given uuid was already used for another Node')
        siuuid = self._uuid is not None and int(self._uuid) or None
        if siuuid in self._index:
            del self._index[siuuid]
        self._index[iuuid] = self
        self._uuid = uuid

    uuid = override(property(_get_uuid, _set_uuid))

    @override
    @property
    def index(self):
        return NodeIndex(self._index)

    @override
    def node(self, uuid):
        return self._index.get(int(uuid))

    @default
    def _to_delete(self):
        todel = [int(self.uuid)]
        for childkey in self:
            try:
                todel += self[childkey]._to_delete()
            except AttributeError:
                # Non-Node values or non referencing children are not told
                # about deletion.
                continue
        return todel

    @default
    def _index_nodes(self):
        for node in self.values():
            try:
                uuid = int(node.uuid)
            except AttributeError:
                # non-Node values are a dead end, no magic for them
                continue
            self._index[uuid] = node
            node._index = self._index
            node._index_nodes()
示例#13
0
class OverlayEditForm(OverlayForm, EditFormHeading):
    """Edit form behavior rendering to overlay.
    """
    action_resource = override('overlayedit')
示例#14
0
class ContentEditForm(EditFormHeading, ContentForm, CameFromNext):
    """Form behavior rendering edit form to content area.
    """
    action_resource = override('edit')
示例#15
0
class OverlayAddForm(OverlayForm, AddFactoryProxy, AddFormHeading):
    """Add form behavior rendering to overlay.
    """
    action_resource = override('overlayadd')
示例#16
0
 class Behavior1(Behavior):
     K = override('Behavior1')
     M = override('Behavior1')
示例#17
0
 class Behavior2(Behavior):
     K = override('Behavior2')
     L = override('Behavior2')
     M = override('Behavior2')
示例#18
0
class Nodify(FullMapping):
    __name__ = default(None)
    __parent__ = default(None)

    @plumb
    def copy(_next, self):
        new = _next(self)
        new.__name__ = self.__name__
        new.__parent__ = self.__parent__
        return new

    @override
    @property
    def name(self):
        return self.__name__

    @override
    @property
    def parent(self):
        return self.__parent__

    @override
    @property
    def path(self):
        path = [parent.name for parent in LocationIterator(self)]
        path.reverse()
        return path

    @override
    @property
    def root(self):
        root = None
        for parent in LocationIterator(self):
            root = parent
        return root

    @override
    def detach(self, key):
        node = self[key]
        del self[key]
        return node

    @override
    def acquire(self, interface):
        node = self.parent
        while node:
            if (IInterface.providedBy(interface) \
              and interface.providedBy(node)) \
              or isinstance(node, interface):
                return node
            node = node.parent

    @override
    def filtereditervalues(self, interface):
        """Uses ``itervalues``.
        """
        for val in self.itervalues():
            if interface.providedBy(val):
                yield val

    @override
    def filteredvalues(self, interface):
        """Uses ``values``.
        """
        return [val for val in self.filtereditervalues(interface)]

    # BBB 2010-12-23
    filtereditems = override(filtereditervalues)

    @override
    @property
    def noderepr(self):
        """``noderepr`` is used in ``printtree``.

        Thus, we can overwrite it in subclass and return any debug information
        we need while ``__repr__`` is an enhanced standard object
        representation, also used as ``__str__`` on nodes.

        XXX: do we really need the difference or can we just override __repr__
        in subclasses and use __repr__ in printtree?
        """
        # XXX: is this a relict from plumber prototyping? -rn
        #if hasattr(self.__class__, '_wrapped'):
        #    class_ = self.__class__._wrapped
        #else:
        #    class_ = self.__class__
        class_ = self.__class__

        name = unicode(self.__name__).encode('ascii', 'replace')
        return str(class_) + ': ' + name[name.find(':') + 1:]

    @override
    def printtree(self, indent=0):
        """Uses ``values``.
        """
        print "%s%s" % (indent * ' ', self.noderepr)
        for node in self.values():
            try:
                node.printtree(indent + 2)
            except AttributeError:
                # Non-Node values are just printed
                print "%s%s" % (indent * ' ', node)

    # XXX: tricky one: If a base class provides a __nonzero__ and that
    # base class is nodified, should the base class' __nonzero__ be
    # used or this one? Please write your thoughts here -cfl
    #
    # I think @default is fine, leaves most possible flexibility to the user.
    # Other thoughts? -rn

    @default
    def __nonzero__(self):
        return True

    @override
    def __repr__(self):
        # XXX: is this a relict from plumber prototyping? -rn
        #if hasattr(self.__class__, '_wrapped'):
        #    class_name = self.__class__._wrapped.__name__
        #else:
        #    class_name = self.__class__.__name__
        class_name = self.__class__.__name__
        # XXX: This is mainly used in doctest, I think
        #      doctest fails if we output utf-8
        name = unicode(self.__name__).encode('ascii', 'replace')
        return "<%s object '%s' at %s>" % (class_name, name, hex(
            id(self))[:-1])

    __str__ = override(__repr__)
示例#19
0
 class Behavior1(Behavior):
     K = override('Behavior1')
     L = finalize('Behavior1')
示例#20
0
 class Behavior2(Behavior):
     K = finalize('Behavior2')
     L = override('Behavior2')
示例#21
0
 class Behavior1(Behavior):
     K = default('Behavior1')
     L = override('Behavior1')
示例#22
0
 class Behavior2(Behavior):
     K = override('Behavior2')
     L = default('Behavior2')
示例#23
0
 class Behavior1(Behavior):
     J = default('Behavior1')
     K = default('Behavior1')
     M = override('Behavior1')