Welcome, guest | Sign In | My Account | Store | Cart

Notice! PyPM is being replaced with the ActiveState Platform, which enhances PyPM’s build and deploy capabilities. Create your free Platform account to download ActivePython or customize Python with the packages you require and get automatic updates.

Download
ActivePython
INSTALL>
pypm install grouparchy.schema

How to install grouparchy.schema

  1. Download and install ActivePython
  2. Open Command Prompt
  3. Type pypm install grouparchy.schema
 Python 2.7Python 3.2Python 3.3
Windows (32-bit)
0.1 Available View build log
Windows (64-bit)
0.1 Available View build log
Mac OS X (10.5+)
0.1 Available View build log
Linux (32-bit)
0.1 Available View build log
Linux (64-bit)
0.1 Available View build log
 
License
GPL
Lastest release
version 0.1 on Jan 5th, 2011

;--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

System Message: ERROR/3 (<string>, line 25)

Inconsistent literal block quoting.

'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):

System Message: ERROR/3 (<string>, line 32)

Inconsistent literal block quoting.

... 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

System Message: ERROR/3 (<string>, line 49)

Inconsistent literal block quoting.

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

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

>>> class FooEvent(grouparchy.schema.event.FieldModifiedEvent):

System Message: ERROR/3 (<string>, line 55)

Inconsistent literal block quoting.

... 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(

System Message: ERROR/3 (<string>, line 67)

Inconsistent literal block quoting.

... 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(

System Message: ERROR/3 (<string>, line 76)

Inconsistent literal block quoting.

... 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()

System Message: ERROR/3 (<string>, line 137)

Inconsistent literal block quoting.

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)

System Message: ERROR/3 (<string>, line 153)

Inconsistent literal block quoting.

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(

System Message: ERROR/3 (<string>, line 168)

Inconsistent literal block quoting.

... 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(

System Message: ERROR/3 (<string>, line 179)

Inconsistent literal block quoting.

... 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()]

System Message: ERROR/3 (<string>, line 193)

Inconsistent literal block quoting.

[<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()]

System Message: ERROR/3 (<string>, line 203)

Inconsistent literal block quoting.

[<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):

System Message: ERROR/3 (<string>, line 216)

Inconsistent literal block quoting.

... 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)

System Message: ERROR/3 (<string>, line 235)

Inconsistent literal block quoting.

True

Before the object provides anything, the declarations are empty:

>>> tuple(foo.all)

System Message: ERROR/3 (<string>, line 240)

Inconsistent literal block quoting.

() >>> 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)

System Message: ERROR/3 (<string>, line 281)

Inconsistent literal block quoting.

(<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):

System Message: ERROR/3 (<string>, line 305)

Inconsistent literal block quoting.

... 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 = ()

System Message: ERROR/3 (<string>, line 328)

Inconsistent literal block quoting.

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(

System Message: ERROR/3 (<string>, line 376)

Inconsistent literal block quoting.

... 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(

System Message: ERROR/3 (<string>, line 420)

Inconsistent literal block quoting.

... 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:

Subscribe to package updates

Last updated Jan 5th, 2011

Download Stats

Last month:1

What does the lock icon mean?

Builds marked with a lock icon are only available via PyPM to users with a current ActivePython Business Edition subscription.

Need custom builds or support?

ActivePython Enterprise Edition guarantees priority access to technical support, indemnification, expert consulting and quality-assured language builds.

Plan on re-distributing ActivePython?

Get re-distribution rights and eliminate legal risks with ActivePython OEM Edition.