This is a pre-production deployment of Warehouse. Changes made here affect the production instance of PyPI (pypi.python.org).
Help us improve Python packaging - Donate today!
Project Description

;--Doctest--

Field Events

EventProperty is a zope.schema FieldProperty that fires an event when the field is modified and sends the old and new values to the event.

>>> from zope import interface, schema
>>> import grouparchy.schema.event
>>> class IFoo(interface.Interface):
...     field = schema.Field()
>>> class Foo(object):
...     interface.implements(IFoo)
...     field = grouparchy.schema.event.EventProperty(
...         IFoo['field'])
>>> foo = Foo()

Before configuring a handler for the event nothing will happen:

>>> foo.field
>>> foo.field = 'foo'
>>> foo.field
'foo'

When we provide a handler for the event, it will be triggered when we change the value:

>>> from zope import component
>>> def handler(event):
...     print 'event: %s' % event
...     print 'object: %s' % event.object
...     print 'event.old: %s' % event.old
...     print 'event.new: %s' % event.new
>>> component.provideHandler(
...     handler, (grouparchy.schema.event.IFieldModifiedEvent,))

>>> foo.field = 'bar'
event: <grouparchy.schema.event.FieldModifiedEvent object at ...>
object: <Foo object at ...>
event.old: foo
event.new: bar

If the new value is equal to the existing value, the event isn’t triggered:

>>> foo.field
'bar'
>>> foo.field = 'bar'

A different event can also be passed in to the property:

>>> class FooEvent(grouparchy.schema.event.FieldModifiedEvent):
...     pass
>>> Foo.field = grouparchy.schema.event.EventProperty(
...     IFoo['field'], event=FooEvent)
>>> foo.field = 'foo'
event: <FooEvent object at ...>
object: <Foo object at ...>
event.old: bar
event.new: foo

If the event is None, no event will be triggered:

>>> Foo.field = grouparchy.schema.event.EventProperty(
...     IFoo['field'], event=None)
>>> foo.field = 'bar'

Descriptors that subclass EventProperty can override the notify() method for further control. For example, the descriptor below will trigger the event even if the field value is unchanged:

>>> from zope import event
>>> class AlwaysEventProperty(
...     grouparchy.schema.event.EventProperty):
...     def notify(self, instance, new, old):
...         event.notify(self.event(instance, new, old))
>>> Foo.field = AlwaysEventProperty(IFoo['field'])
>>> foo.field
'bar'
>>> foo.field = 'bar'
event: <grouparchy.schema.event.FieldModifiedEvent object at ...>
object: <Foo object at ...>
event.old: bar
event.new: bar

;--Doctest--

Interface Fields

grouparchy.schema.interface includes zope.schema fields for manipulating the interfaces provided by the context.

An implementation is included for managing the interfaces directly provided by an object:

>>> from zope import interface
>>> from grouparchy.schema.bbb import component_iface
>>> class IFoo(interface.Interface): pass
>>> component_iface.provideInterface('', IFoo)

>>> class Context(object):
...     interface.implements(interface.Interface)

>>> from zope import component
>>> import grouparchy.schema.interface
>>> component.provideAdapter(
...     factory=grouparchy.schema.interface.DirectlyProvided)

>>> provider = Context()
>>> directlyProvided = (
...     grouparchy.schema.interface.IDirectlyProvided(
...         provider))
>>> tuple(directlyProvided.directlyProvided)
()

>>> directlyProvided.directlyProvided = (IFoo,)

>>> tuple(directlyProvided.directlyProvided)
(<InterfaceClass __builtin__.IFoo>,)

The individual components offer much more flexibility.

Fields

InterfacesField describes a set of interfaces provided by the context.

An InterfacesField must have an InterfaceField or Choice value_type:

>>> from zope import schema
>>> grouparchy.schema.interface.InterfacesField()
Traceback (most recent call last):
...
ValueError: 'value_type' must be an InterfaceField or a Choice.
>>> grouparchy.schema.interface.InterfacesField(
...     value_type=schema.Field())
Traceback (most recent call last):
...
ValueError: 'value_type' must be an InterfaceField or a Choice.
>>> field = grouparchy.schema.interface.InterfacesField(
...     value_type=schema.InterfaceField())

Valid values are sequences of interfaces:

>>> foo = object()
>>> bound = field.bind(foo)
>>> bound.validate(interface.Interface)
Traceback (most recent call last):
...
WrongType: (<InterfaceClass zope.interface.Interface>,
            (<type 'set'>, <type 'tuple'>, <type 'list'>))
>>> bound.validate((None,))
Traceback (most recent call last):
...
WrongContainedType: []
>>> bound.validate((interface.Interface,))
>>> bound.validate([interface.Interface])

Like any Set field, it accepts a Choice field with a vocabulary or source to narrow the set of interfaces:

>>> field = grouparchy.schema.interface.InterfacesField(
...     value_type=schema.Choice(values=(IFoo,)))
>>> bound = field.bind(foo)
>>> bound.validate((interface.Interface,))
Traceback (most recent call last):
...
WrongContainedType: [<InterfaceClass zope.interface.Interface>]
>>> bound.validate((IFoo,))

A Choice field cannot circumvent the validation:

>>> field = grouparchy.schema.interface.InterfacesField(
...     value_type=schema.Choice(values=(None,)))
>>> bound = field.bind(foo)
>>> bound.validate((None,))
Traceback (most recent call last):
...
WrongContainedType: []

Sources

A source is also provided which can be used with an interface type used to determine set of valid interfaces for the field:

>>> [i for i in grouparchy.schema.interface.InterfacesSource()]
[<InterfaceClass __builtin__.IFoo>]

Subsets of interfaces can be specified by passing an interface type:

>>> import zope.interface.interfaces
>>> class IIBar(zope.interface.interfaces.IInterface): pass
>>> class IBar(interface.Interface): pass
>>> component_iface.provideInterface('', IBar)
>>> component_iface.provideInterface('', IBar, IIBar)
>>> [i for i in grouparchy.schema.interface.InterfacesSource()]
[<InterfaceClass __builtin__.IFoo>,
 <InterfaceClass __builtin__.IBar>]
>>> source = grouparchy.schema.interface.InterfacesSource(IIBar)
>>> [i for i in source]
[<InterfaceClass __builtin__.IBar>]

Properties

Two properties are also provided for getting and setting the field value for either interface objects or dotted names for interfaces:

>>> class IFoo(interface.Interface):
...     all = grouparchy.schema.interface.InterfacesField(
...         value_type=schema.InterfaceField())
...     bar = grouparchy.schema.interface.InterfacesField(
...         value_type=schema.Choice(source=source))
...     dotted = grouparchy.schema.interface.InterfacesField(
...         value_type=schema.InterfaceField())
>>> class Foo(object):
...     all = grouparchy.schema.interface.InterfacesProperty(
...         IFoo['all'])
...     bar = grouparchy.schema.interface.InterfacesProperty(
...         IFoo['bar'])
...     dotted = (
...         grouparchy.schema.interface.InterfaceIdentsProperty(
...             IFoo['dotted']))
>>> foo = Foo()

The properties return an IDeclaration:

>>> isinstance(foo.all, interface.Declaration)
True

Before the object provides anything, the declarations are empty:

>>> tuple(foo.all)
()
>>> tuple(foo.bar)
()
>>> tuple(foo.dotted)
()

>>> interface.alsoProvides(foo, interface.Interface)
>>> tuple(foo.all)
(<InterfaceClass zope.interface.Interface>,)
>>> tuple(foo.dotted)
('zope.interface.Interface',)

>>> interface.alsoProvides(foo, IBar)
>>> tuple(foo.all)
(<InterfaceClass zope.interface.Interface>,
 <InterfaceClass __builtin__.IBar>)
>>> tuple(foo.bar)
(<InterfaceClass __builtin__.IBar>,)

>>> IBar.providedBy(foo)
True
>>> foo.bar = ()
>>> tuple(foo.bar)
()
>>> IBar.providedBy(foo)
False
>>> foo.bar = (IBar,)
>>> tuple(foo.bar)
(<InterfaceClass __builtin__.IBar>,)
>>> IBar.providedBy(foo)
True

The properties need to know how to get the context providing the interfaces from the object the property lives on. This is accomplished with an adapter to the object. The following checks some names where the context is often found on adapters and fallsback to the object itself:

>>> context = foo.context = Foo()
>>> interface.alsoProvides(foo.context, interface.Interface)
>>> tuple(foo.all)
(<InterfaceClass zope.interface.Interface>,
 <InterfaceClass __builtin__.IBar>)

>>> component.provideAdapter(
...     grouparchy.schema.interface.getInterfacesContext)

>>> tuple(foo.all)
(<InterfaceClass zope.interface.Interface>,)
>>> del foo.context
>>> tuple(foo.all)
(<InterfaceClass zope.interface.Interface>,
 <InterfaceClass __builtin__.IBar>)
>>> foo.object = context
>>> tuple(foo.all)
(<InterfaceClass zope.interface.Interface>,)
>>> del foo.object

Events

The properties trigger an event by default:

>>> import zope.interface.interfaces
>>> def getIfacesStr(ifaces):
...     return ', '.join((str(i) for i in sorted(ifaces)))
>>> def printInterfacesModified(event):
...     print 'Event: %s' % event
...     print 'Object: %s' % event.object
...     print 'New: ' + getIfacesStr(event.new)
...     print 'Old: ' + getIfacesStr(event.old)
...     print 'Added: ' + getIfacesStr(event.added)
...     print 'Removed: ' + getIfacesStr(event.removed)
>>> component.provideHandler(
...     factory=printInterfacesModified,
...     adapts=(
...         grouparchy.schema.interface.IInterfacesModified,))

>>> class IBaz(interface.Interface): pass
>>> component_iface.provideInterface('', IBaz)
>>> component_iface.provideInterface('', IBaz, IIBar)

The default events all provide IInterfacesModified, but the event triggered provides one of the more specific IInterfacesPopulated, IInterfacesCleared, IInterfacesAdded, IInterfacesRemoved, or IInterfacesChanged as apporpriate:

>>> foo.bar = ()
Event:
<grouparchy.schema.interface.InterfacesCleared object at ...>
Object: <Foo object at ...>
New:
Old: <InterfaceClass __builtin__.IBar>
Added:
Removed: <InterfaceClass __builtin__.IBar>
>>> foo.bar = (IBar,)
Event:
<grouparchy.schema.interface.InterfacesPopulated object at ...>
Object: <Foo object at ...>
New: <InterfaceClass __builtin__.IBar>
Old:
Added: <InterfaceClass __builtin__.IBar>
Removed:
>>> foo.bar = (IBar, IBaz)
Event:
<grouparchy.schema.interface.InterfacesAdded object at ...>
Object: <Foo object at ...>
New: <InterfaceClass __builtin__.IBar>,
<InterfaceClass __builtin__.IBaz>
Old: <InterfaceClass __builtin__.IBar>
Added: <InterfaceClass __builtin__.IBaz>
Removed:
>>> foo.bar = (IBar,)
Event:
<grouparchy.schema.interface.InterfacesRemoved object at ...>
Object: <Foo object at ...>
New: <InterfaceClass __builtin__.IBar>
Old: <InterfaceClass __builtin__.IBar>,
<InterfaceClass __builtin__.IBaz>
Added:
Removed: <InterfaceClass __builtin__.IBaz>
>>> foo.bar = (IBaz,)
Event:
<grouparchy.schema.interface.InterfacesChanged object at ...>
Object: <Foo object at ...>
New: <InterfaceClass __builtin__.IBaz>
Old: <InterfaceClass __builtin__.IBar>
Added: <InterfaceClass __builtin__.IBaz>
Removed: <InterfaceClass __builtin__.IBar>

IInterfacesPopulated and IInterfacesCleared extend IInterfacesAdded and IInterfacesRemoved respectively. IInterfacesChanged extends both:

>>> def printInterfacesAdded(event): print 'Interfaces Added'
>>> component.provideHandler(
...     factory=printInterfacesAdded,
...     adapts=(
...         grouparchy.schema.interface.IInterfacesAdded,))

>>> def printInterfacesRemoved(event): print 'Interfaces Removed'
>>> component.provideHandler(
...     factory=printInterfacesRemoved,
...     adapts=(
...         grouparchy.schema.interface.IInterfacesRemoved,))

>>> foo.bar = ()
Event:
<grouparchy.schema.interface.InterfacesCleared object at ...>
Object: <Foo object at ...>
New:
Old: <InterfaceClass __builtin__.IBaz>
Added:
Removed: <InterfaceClass __builtin__.IBaz>
Interfaces Removed
>>> foo.bar = (IBar,)
Event:
<grouparchy.schema.interface.InterfacesPopulated object at ...>
Object: <Foo object at ...>
New: <InterfaceClass __builtin__.IBar>
Old:
Added: <InterfaceClass __builtin__.IBar>
Removed:
Interfaces Added
>>> foo.bar = (IBaz,)
Event:
<grouparchy.schema.interface.InterfacesChanged object at ...>
Object: <Foo object at ...>
New: <InterfaceClass __builtin__.IBaz>
Old: <InterfaceClass __builtin__.IBar>
Added: <InterfaceClass __builtin__.IBaz>
Removed: <InterfaceClass __builtin__.IBar>
Interfaces Removed
Interfaces Added

An event class can be passed to the property as with grouparchy.schema.event.EventProperty:

>>> import grouparchy.schema.event
>>> class IBarInterfacesModified(
...     grouparchy.schema.event.IFieldModifiedEvent): pass
>>> class BarInterfacesModified(
...     grouparchy.schema.event.FieldModifiedEvent):
...         interface.implements(IBarInterfacesModified)

>>> def printBarInterfacesModified(event):
...     print 'Event: %s' % event
...     print 'Object: %s' % event.object
...     print 'New: ' + getIfacesStr(event.new)
...     print 'Old: ' + getIfacesStr(event.old)
>>> component.provideHandler(
...     factory=printBarInterfacesModified,
...     adapts=(IBarInterfacesModified,))

>>> foo.bar = ()
Event:
<grouparchy.schema.interface.InterfacesCleared object at ...>
Object: <Foo object at ...>
New:
Old: <InterfaceClass __builtin__.IBaz>
Added:
Removed: <InterfaceClass __builtin__.IBaz>
Interfaces Removed
>>> foo.bar = (IBar,)
Event:
<grouparchy.schema.interface.InterfacesPopulated object at ...>
Object: <Foo object at ...>
New: <InterfaceClass __builtin__.IBar>
Old:
Added: <InterfaceClass __builtin__.IBar>
Removed:
Interfaces Added

>>> Foo.bar = grouparchy.schema.interface.InterfacesProperty(
...     IFoo['bar'],
...     event=BarInterfacesModified)

>>> foo.bar = ()
Event: <BarInterfacesModified object at ...>
Object: <Foo object at ...>
New:
Old: <InterfaceClass __builtin__.IBar>
>>> foo.bar = (IBar,)
Event: <BarInterfacesModified object at ...>
Object: <Foo object at ...>
New: <InterfaceClass __builtin__.IBar>
Old:
Release History

Release History

0.1

This version

History Node

TODO: Figure out how to actually get changelog content.

Changelog content for this version goes here.

Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit.

Show More

Download Files

Download Files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

File Name & Checksum SHA256 Checksum Help Version File Type Upload Date
grouparchy.schema-0.1.tar.gz (16.8 kB) Copy SHA256 Checksum SHA256 Source Apr 9, 2008

Supported By

WebFaction WebFaction Technical Writing Elastic Elastic Search Pingdom Pingdom Monitoring Dyn Dyn DNS Sentry Sentry Error Logging CloudAMQP CloudAMQP RabbitMQ Heroku Heroku PaaS Kabu Creative Kabu Creative UX & Design Fastly Fastly CDN DigiCert DigiCert EV Certificate Rackspace Rackspace Cloud Servers DreamHost DreamHost Log Hosting