nti.schema

Latest release Supported Python versions https://github.com/NextThought/nti.zope_catalog/workflows/tests/badge.svg https://coveralls.io/repos/github/NextThought/nti.schema/badge.svg Documentation Status

nti.schema includes utilities for working with schema-driven development using zope.schema.

For complete details and the changelog, see the documentation.

Overview

Some of the most useful features include:

  • nti.schema.interfaces.find_most_derived_interface for finding a bounded interface.
  • nti.schema.eqhash.EqHash is a class-decorator for creating efficient, correct implementations of equality and hashing.
  • nti.schema.field contains various schema fields, including a Variant type and more flexible collection types, all of which produce better validation errors.
  • nti.schema.fieldproperty contains field properties that can adapt to interfaces or decode incoming text. The function createDirectFieldProperties can assign just the necessary properties automatically.

nti.schema.interfaces

Interfaces describing the events and fields this package uses.

Also utility functions.

class BeforeCollectionAssignedEvent(obj, name, context)[source]

Bases: nti.schema.interfaces.BeforeSchemaFieldAssignedEvent

object = None
class BeforeDictAssignedEvent(obj, name, context)[source]

Bases: nti.schema.interfaces.BeforeSchemaFieldAssignedEvent

class BeforeSchemaFieldAssignedEvent(obj, name, context)[source]

Bases: object

class BeforeSequenceAssignedEvent(obj, name, context)[source]

Bases: nti.schema.interfaces.BeforeCollectionAssignedEvent

class BeforeSetAssignedEvent(obj, name, context)[source]

Bases: nti.schema.interfaces.BeforeCollectionAssignedEvent

class BeforeTextAssignedEvent(obj, name, context)[source]

Bases: nti.schema.interfaces.BeforeSchemaFieldAssignedEvent

class BeforeTextLineAssignedEvent(obj, name, context)[source]

Bases: nti.schema.interfaces.BeforeTextAssignedEvent

interface IBeforeCollectionAssignedEvent[source]

Extends: nti.schema.interfaces.IBeforeIterableAssignedEvent

Event for assigning collections.

object

The collection being assigned. May or may not be mutable.

interface IBeforeContainerAssignedEvent[source]

Extends: nti.schema.interfaces.IBeforeSchemaFieldAssignedEvent

Event for assigning containers (__contains__).

interface IBeforeDictAssignedEvent[source]

Extends: nti.schema.interfaces.IBeforeIterableAssignedEvent

Event for assigning dicts.

interface IBeforeIterableAssignedEvent[source]

Extends: nti.schema.interfaces.IBeforeContainerAssignedEvent

Event for assigning iterables.

interface IBeforeSchemaFieldAssignedEvent[source]

An event sent when certain schema fields will be assigning an object to a property of another object.

The interface zope.schema.interfaces.IBeforeObjectAssignedEvent is a sub-interface of this one once this module is imported.

object

The object that is going to be assigned. Subscribers may modify this

name

The name of the attribute under which the object will be assigned.

context

The context object where the object will be assigned to.

interface IBeforeSequenceAssignedEvent[source]

Extends: nti.schema.interfaces.IBeforeCollectionAssignedEvent

Event for assigning sequences.

object

The sequence being assigned. May or may not be mutable.

interface IBeforeSetAssignedEvent[source]

Extends: nti.schema.interfaces.IBeforeCollectionAssignedEvent

Event for assigning sets.

interface IBeforeTextAssignedEvent[source]

Extends: nti.schema.interfaces.IBeforeSchemaFieldAssignedEvent

Event for assigning text.

object

The text being assigned.

Implementation:zope.schema.Text
Read Only:False
Required:True
Default Value:None
Allowed Type:unicode
interface IBeforeTextLineAssignedEvent[source]

Extends: nti.schema.interfaces.IBeforeTextAssignedEvent

Event for assigning text lines.

object

The text being assigned.

Implementation:zope.schema.TextLine
Read Only:False
Required:True
Default Value:None
Allowed Type:unicode
interface IFromObject[source]

Something that can convert one type of object to another, following validation rules (see zope.schema.interfaces.IFromUnicode)

fromObject(obj)

Attempt to convert the object to the required type following the rules of this object. Raises a TypeError or zope.schema.interfaces.ValidationError if this isn’t possible.

interface IListOrTuple[source]

Extends: zope.schema.interfaces.IList

interface ISchemaConfigured[source]

marker interface for SchemaConfigured classes.

Used to facilitate the registration of forms and views.

interface IVariant[source]

Extends: zope.schema.interfaces.IField, nti.schema.interfaces.IFromObject

Similar to zope.schema.interfaces.IObject, but representing one of several different types.

If fromObject() or validate() fails, it should raise a VariantValidationError.

exception VariantValidationError(field, value, errors)[source]

Bases: zope.schema._bootstrapinterfaces.ValidationError

An error raised when a value is not suitable for any of the fields of the variant.

The errors attribute is an ordered sequence of validation errors, with one raised by each field of the variant in turn.

New in version 1.8.0.

errors = ()

A sequence of validation errors

find_most_derived_interface(ext_self, iface_upper_bound, possibilities=None)[source]

Search for the most derived version of the interface iface_upper_bound implemented by ext_self and return that. Always returns at least iface_upper_bound

Parameters:possibilities – An iterable of schemas to consider. If not given, all the interfaces provided by ext_self will be considered.
exception InvalidValue(*args, field=None, value=None)[source]

Adds a field specifically to carry the value that is invalid.

Deprecated since version 1.4.0: This is now just a convenience wrapper around zope.schema.interfaces.InvalidValue that calls zope.schema.interfaces.ValidationError.with_field_and_value() before returning the exception. You should always catch zope.schema.interfaces.InvalidValue.

nti.schema.schema

Helpers for writing code that implements schemas.

This module contains code based on code originally from dm.zope.schema.

class PermissiveSchemaConfigured(**kwargs)[source]

Bases: nti.schema.schema.SchemaConfigured

A mixin subclass of SchemaConfigured that allows for extra keywords (those not defined in the schema) to silently be ignored. This is an aid to evolution of code and can be helpful in testing.

To allow for one-by-one conversions and updates, this class defines an attribute SC_PERMISSIVE, defaulting to True, that controls this behaviour.

SC_PERMISSIVE = True
class SchemaConfigured(**kw)[source]

Bases: object

Mixin class to provide configuration by the provided schema components.

This class is fastest if most of the attributes are represented by FieldProperty objects.

Changed in version 1.15: Special case FieldProperty instances found in the type when checking whether a value has been provided. We now assume that if there is no matching item in the dict with the same name, no value was provided. Note that if the schema field contained in the FieldProperty did something funky in its bind() method to this object, that will no longer happen at construction time. This can be turned of by setting SC_OPTIMIZE_FIELD_PROPERTY to false.

If you add a FieldProperty to a SchemaConfigured class after an instance has been created, you must call sc_changed.

SC_OPTIMIZE_FIELD_PROPERTY = True
SC_SCHEMAS = None
classmethod sc_changed(orig_changed=None)[source]

Call this method if you assign a fieldproperty to this class after creation.

sc_schema_spec()[source]

the schema specification which determines the data schema.

This is determined by SC_SCHEMAS and defaults to providedBy(self).

schemadict(spec) → dict[source]

The schema part (fields) of interface specification spec as map from name to field.

The return value must be treated as immutable.

spec can be:

  • A single Interface;
  • An object implementing zope.interfaces.interfaces.ISpecification, such as that returned by providedBy(instance) or implementedBy(factory) (an Interface is a special case of this).
  • A list, tuple, or iterable of Interfaces.

In the first two cases, the results will be cached using the usual interface caching rules. That means that changes to interface bases, or changes to what an object or class provides or implements, will be properly detected. However, if you simply assign a new field to an existing interface, it may not be detected (things like Interface.get() also fail in that case) unless you call Interface.changed().

Changed in version 1.15.0: Added caching and re-implemented the schemadict algorithm for speed. The return value must now be treated as immutable.

schemaitems(spec) → [(name, field)][source]

The schema part (fields) of interface specification spec as a list of (name, field) pairs, in their definition order.

nti.schema.fieldproperty

Computed attributes based on schema fields.

class AcquisitionFieldProperty(field, name=None)[source]

Bases: zope.schema.fieldproperty.FieldProperty

A field property that supports acquisition. Returned objects will be __of__ the instance, and set objects will always be the unwrapped base.

class AdaptingFieldProperty(field, name=None)[source]

Bases: zope.schema.fieldproperty.FieldProperty

Primarily for legacy support and testing, adds adaptation to an interface when setting a field. This is most useful when the values are simple literals like strings.

class AdaptingFieldPropertyStoredThroughField(field, name=None)[source]

Bases: zope.schema.fieldproperty.FieldPropertyStoredThroughField

Primarily for legacy support and testing, adds adaptation to an interface when setting a field. This is most useful when the values are simple literals like strings.

class UnicodeConvertingFieldProperty(field, name=None)[source]

Bases: zope.schema.fieldproperty.FieldProperty

Accepts bytes input for the unicode property if it can be decoded as UTF-8. This is primarily to support legacy test cases and should be removed when all constants are unicode.

createDirectFieldProperties(__schema, omit=(), adapting=False)[source]

Like zope.schema.fieldproperty.createFieldProperties(), except only creates properties for fields directly contained within the given schema; inherited fields from parent interfaces are assummed to be implemented in a base class of the current class:

>>> from zope import interface
>>> from nti.schema.field import TextLine, Object
>>> class IA(interface.Interface):
...    a = TextLine(title=u"a")

>>> class IB(IA):
...    b = Object(interface.Interface)

>>> class A(object):
...    createFieldProperties(IA)

>>> class B(object):
...    createDirectFieldProperties(IB, adapting=True)

>>> 'a' in A.__dict__
True
>>> 'a' in B.__dict__
False
>>> 'b' in B.__dict__
True
Parameters:adapting – If set to True (not the default), fields that implement IObject will use an AdaptingFieldProperty.
field_name(field)[source]

Produce a clean version of a field’s name.

The zope.schema.fieldproperty.FieldPropertyStoredThroughField class mangles the field name, making it difficult to trace fields back to their intended attribute name. This undoes that mangling if possible.

The field in an interface has a normal name:

>>> from zope.schema.fieldproperty import FieldPropertyStoredThroughField
>>> from zope.schema import Field
>>> from zope import interface
>>> class IA(interface.Interface):
...    a = Field()
>>> IA['a'].__name__
'a'

The field as stored by a FieldProperty has a normal name:

>>> from zope.schema.fieldproperty import FieldProperty
>>> class A(object):
...    createFieldProperties(IA)
>>> A.a.__name__
'a'

But using a FieldPropertyStoredThroughField mangles the name (whether accessed through the FieldPropertyStoredThroughField or directly):

>>> from zope.schema.fieldproperty import FieldPropertyStoredThroughField
>>> class A2(object):
...    a = FieldPropertyStoredThroughField(IA['a'])
>>> A2.a.__name__
'__st_a_st'
>>> A2.a.field.__name__
'__st_a_st'

This function demangles the name (whether accessed through the FieldPropertyStoredThroughField or directly):

>>> from nti.schema.fieldproperty import field_name
>>> field_name(A2.a)
'a'
>>> field_name(A2.a.field)
'a'

Without damaging the names of regular fields or regular FieldProperty fields:

>>> field_name(IA['a'])
'a'
>>> field_name(A.a)
'a'

New in version 1.10.0.

nti.schema.field

Schema fields.

These fields produce better validation errors than the standard zope.schema fields do. All the standard fields are also aliased to be imported from this module.

class Bool(*args, **kw)[source]

Bases: zope.schema._bootstrapfields.Field

A field representing a Bool.

Changed in version 4.8.0: Implement zope.schema.interfaces.IFromBytes

fromBytes(value)[source]
>>> from zope.schema._bootstrapfields import Bool
>>> from zope.schema.interfaces import IFromBytes
>>> b = Bool()
>>> IFromBytes.providedBy(b)
True
>>> b.fromBytes(b'True')
True
>>> b.fromBytes(b'')
False
>>> b.fromBytes(b'true')
True
>>> b.fromBytes(b'false') or b.fromBytes(b'False')
False
>>> b.fromBytes(u'\u2603'.encode('utf-8'))
False
fromUnicode(value)[source]
>>> from zope.schema._bootstrapfields import Bool
>>> from zope.schema.interfaces import IFromUnicode
>>> b = Bool()
>>> IFromUnicode.providedBy(b)
True
>>> b.fromUnicode('True')
True
>>> b.fromUnicode('')
False
>>> b.fromUnicode('true')
True
>>> b.fromUnicode('false') or b.fromUnicode('False')
False
>>> b.fromUnicode(u'\u2603')
False
class Choice(values=None, vocabulary=None, source=None, **kw)[source]

Bases: zope.schema._bootstrapfields.Field

Choice fields can have a value found in a constant or dynamic set of values given by the field definition.

bind(context)[source]

See zope.schema._bootstrapinterfaces.IField.

fromUnicode(value)[source]

See IFromUnicode.

class Complex(min=None, max=None, default=None, **kw)[source]

Bases: zope.schema._bootstrapfields.Number

A field representing a numbers.Complex and implementing zope.schema.interfaces.IComplex.

The fromUnicode() method is like that for Number, but doesn’t allow Decimals:

>>> from zope.schema._bootstrapfields import Complex
>>> f = Complex()
>>> f.fromUnicode(u"1")
1
>>> f.fromUnicode(u"125.6")
125.6
>>> f.fromUnicode(u"1+0j")
(1+0j)
>>> f.fromUnicode(u"1/2")
Fraction(1, 2)
>>> f.fromUnicode(str(2**31234) + '.' + str(2**256))
... 
inf
>>> f.fromUnicode(u"not a number") 
Traceback (most recent call last):
...
InvalidNumberLiteral: Invalid literal for Decimal: 'not a number'

Similarly for fromBytes():

>>> from zope.schema._bootstrapfields import Complex
>>> f = Complex()
>>> f.fromBytes(b"1")
1
>>> f.fromBytes(b"125.6")
125.6
>>> f.fromBytes(b"1+0j")
(1+0j)
>>> f.fromBytes(b"1/2")
Fraction(1, 2)
>>> f.fromBytes((str(2**31234) + '.' + str(2**256)).encode('ascii'))
... # doctest: +ELLIPSIS
inf
>>> f.fromBytes(b"not a number") # doctest: +IGNORE_EXCEPTION_DETAIL
Traceback (most recent call last):
...
InvalidNumberLiteral: Invalid literal for Decimal: 'not a number'

New in version 4.6.0.

class Date(min=None, max=None, default=None, **kw)[source]

Bases: zope.schema._bootstrapfields.Orderable, zope.schema._bootstrapfields.Field

Field containing a date.

class Datetime(*args, **kw)[source]

Bases: zope.schema._bootstrapfields.Orderable, zope.schema._bootstrapfields.Field

Field containing a datetime.

class Decimal(min=None, max=None, default=None, **kw)[source]

Bases: zope.schema._bootstrapfields.Number

A field representing a native decimal.Decimal and implementing zope.schema.interfaces.IDecimal.

The fromUnicode() method only accepts values that can be parsed by the Decimal constructor:

>>> from zope.schema._field import Decimal
>>> f = Decimal()
>>> f.fromUnicode("1")
Decimal('1')
>>> f.fromUnicode("125.6")
Decimal('125.6')
>>> f.fromUnicode("1+0j") 
Traceback (most recent call last):
...
InvalidDecimalLiteral: Invalid literal for Decimal(): 1+0j
>>> f.fromUnicode("1/2") 
Traceback (most recent call last):
...
InvalidDecimalLiteral: Invalid literal for Decimal(): 1/2
>>> f.fromUnicode(str(2**31234) + '.' + str(2**256))
... 
Decimal('2349...936')
>>> f.fromUnicode("not a number") 
Traceback (most recent call last):
...
InvalidDecimalLiteral: could not convert string to float: not a number

Likewise for fromBytes():

>>> from zope.schema._field import Decimal
>>> f = Decimal()
>>> f.fromBytes(b"1")
Decimal('1')
>>> f.fromBytes(b"125.6")
Decimal('125.6')
>>> f.fromBytes(b"1+0j") 
Traceback (most recent call last):
...
InvalidDecimalLiteral: Invalid literal for Decimal(): 1+0j
>>> f.fromBytes(b"1/2") 
Traceback (most recent call last):
...
InvalidDecimalLiteral: Invalid literal for Decimal(): 1/2
>>> f.fromBytes((str(2**31234) + '.' + str(2**256)).encode("ascii"))
... 
Decimal('2349...936')
>>> f.fromBytes(b"not a number") 
Traceback (most recent call last):
...
InvalidDecimalLiteral: could not convert string to float: not a number
class DecodingValidTextLine(*args, **kw)[source]

Bases: nti.schema.field.ValidTextLine

A text type that will attempt to decode non-unicode data as UTF-8.

This primarily exists for legacy support (tests and persisted data).

class Dict(key_type=None, value_type=None, **kw)[source]

Bases: zope.schema._field.MutableMapping

A field representing a Dict.

class DictFromObject(*args, **kwargs)[source]

Bases: nti.schema.field._ValueTypeAddingDocMixin, nti.schema.field._MapFromObjectMixin, nti.schema.field.FieldValidationMixin, zope.schema._field.Mapping

The key_type and value_type must be supporting IFromObject or IFromUnicode or IFromBytes

Changed in version 1.4.0: Subclass zope.schema.Mapping instead of zope.schema.Dict, allowing for any mapping (such as BTrees), not just dicts. However, the validated value is still a dict.

Changed in version 1.9.0: Implementations of zope.schema.interfaces.ICollection (like zope.schema.List) and zope.schema.interfaces.IMapping (like zope.schema.Dict) will automatically be given a fromObject method when used as the value_type of this object if their value_type is an zope.schema.interfaces.IObject (recursively).

class FieldValidationMixin[source]

Bases: object

A field mixin that causes slightly better errors to be created.

class Float(min=None, max=None, default=None, **kw)[source]

Bases: nti.schema.field.FieldValidationMixin, zope.schema._field.Float

class FrozenSet(*args, **kwargs)[source]

Bases: zope.schema._field._AbstractSet

class HTTPURL(min_length=0, max_length=None, **kw)[source]

Bases: nti.schema.field.ValidURI

A URI field that ensures and requires its value to be an absolute HTTP/S URL.

fromUnicode(value)[source]

See IFromUnicode.

class IndexedIterable(value_type=<Not Given>, unique=<Not Given>, **kw)[source]

Bases: nti.schema.field._ValueTypeAddingDocMixin, nti.schema.field.FieldValidationMixin, zope.schema._field.Sequence

An arbitrary (indexable) iterable, not necessarily a list or tuple; either of those would be acceptable at any time (however, so would a string, so be careful. Try ListOrTuple if that’s a problem).

The values may be homogeneous by setting the value_type.

Changed in version 1.4.0: Subclass zope.schema.Sequence instead of zope.schema.List, which adds checking that the value is indeed a sequence.

class Int(min=None, max=None, default=None, **kw)[source]

Bases: nti.schema.field.FieldValidationMixin, zope.schema._bootstrapfields.Int

class Integral(min=None, max=None, default=None, **kw)[source]

Bases: zope.schema._bootstrapfields.Rational

A field representing a numbers.Integral and implementing zope.schema.interfaces.IIntegral.

The fromUnicode() method only allows integral values:

>>> from zope.schema._bootstrapfields import Integral
>>> f = Integral()
>>> f.fromUnicode("125")
125
>>> f.fromUnicode("125.6") 
Traceback (most recent call last):
...
InvalidIntLiteral: invalid literal for int(): 125.6

Similarly for fromBytes():

>>> from zope.schema._bootstrapfields import Integral
>>> f = Integral()
>>> f.fromBytes(b"125")
125
>>> f.fromBytes(b"125.6") #doctest: +IGNORE_EXCEPTION_DETAIL
Traceback (most recent call last):
...
InvalidIntLiteral: invalid literal for int(): 125.6

New in version 4.6.0.

class Iterable(title=u'', description=u'', __name__='', required=True, readonly=False, constraint=None, default=None, defaultFactory=None, missing_value=<Not Given>)[source]

Bases: zope.schema._bootstrapfields.Container

class List(value_type=<Not Given>, unique=<Not Given>, **kw)[source]

Bases: zope.schema._field.MutableSequence

A field representing a List.

class ListOrTuple(value_type=<Not Given>, unique=<Not Given>, **kw)[source]

Bases: nti.schema.field.IndexedIterable

Restrict sequence values specifically to list and tuple.

class ListOrTupleFromObject(*args, **kwargs)[source]

Bases: nti.schema.field._SequenceFromObjectMixin, nti.schema.field.ListOrTuple

The value_type MUST be a Variant, or more generally, something supporting IFromObject, IFromUnicode or IFromBytes.

Changed in version 1.9.0: Implementations of zope.schema.interfaces.ICollection (like zope.schema.List) and zope.schema.interfaces.IMapping (like zope.schema.Dict) will automatically be given a fromObject method when used as the value_type of this object if their value_type is an zope.schema.interfaces.IObject (recursively).

class Mapping(key_type=None, value_type=None, **kw)[source]

Bases: zope.schema._bootstrapfields.MinMaxLen, zope.schema._bootstrapfields.Iterable

A field representing a mapping.

New in version 4.6.0.

bind(object)[source]

See zope.schema._bootstrapinterfaces.IField.

class MutableMapping(key_type=None, value_type=None, **kw)[source]

Bases: zope.schema._field.Mapping

A field representing a mutable mapping.

New in version 4.6.0.

class MutableSequence(value_type=<Not Given>, unique=<Not Given>, **kw)[source]

Bases: zope.schema._field.Sequence

A field representing a mutable sequence.

New in version 4.6.0.

class Number(min=None, max=None, default=None, **kw)[source]

Bases: nti.schema.field.FieldValidationMixin, zope.schema._field.Float

A field that parses like a float from a string, but accepts any number.

Deprecated since version 1.4.0: Use zope.schema.Number if you really want arbitrary numbers (including fractions and decimals). You probably want zope.schema.Real instead, though.

class Object(schema=<Not Given>, **kw)[source]

Bases: nti.schema.field.FieldValidationMixin, zope.schema._bootstrapfields.Object

Improved zope.schema.Object.

class ObjectLen(sch, min_length=0, max_length=None, **kwargs)[source]

Bases: nti.schema.field.FieldValidationMixin, zope.schema._bootstrapfields.MinMaxLen, zope.schema._bootstrapfields.Object

Allows specifying a length for arbitrary object fields (though the objects themselves must support the len function.

class Rational(min=None, max=None, default=None, **kw)[source]

Bases: zope.schema._bootstrapfields.Real

A field representing a numbers.Rational and implementing zope.schema.interfaces.IRational.

The fromUnicode() method is like that for Real, but does not allow arbitrary floating point numbers:

>>> from zope.schema._bootstrapfields import Rational
>>> f = Rational()
>>> f.fromUnicode("1")
1
>>> f.fromUnicode("1/2")
Fraction(1, 2)
>>> f.fromUnicode("125.6")
Fraction(628, 5)
>>> f.fromUnicode("1+0j") 
Traceback (most recent call last):
...
InvalidNumberLiteral: Invalid literal for Fraction: '1+0j'
>>> f.fromUnicode(str(2**31234) + '.' + str(2**256))
... 
Fraction(777..., 330...)
>>> f.fromUnicode("not a number") 
Traceback (most recent call last):
...
InvalidNumberLiteral: Invalid literal for Decimal: 'not a number'

New in version 4.6.0.

class Real(min=None, max=None, default=None, **kw)[source]

Bases: zope.schema._bootstrapfields.Complex

A field representing a numbers.Real and implementing zope.schema.interfaces.IReal.

The fromUnicode() method is like that for Complex, but doesn’t allow Decimals or complex numbers:

>>> from zope.schema._bootstrapfields import Real
>>> f = Real()
>>> f.fromUnicode("1")
1
>>> f.fromUnicode("125.6")
125.6
>>> f.fromUnicode("1+0j") 
Traceback (most recent call last):
...
InvalidNumberLiteral: Invalid literal for Fraction: '1+0j'
>>> f.fromUnicode("1/2")
Fraction(1, 2)
>>> f.fromUnicode(str(2**31234) + '.' + str(2**256))
... 
inf
>>> f.fromUnicode("not a number") 
Traceback (most recent call last):
...
InvalidNumberLiteral: Invalid literal for Decimal: 'not a number'

New in version 4.6.0.

class Set(*args, **kwargs)[source]

Bases: zope.schema._field._AbstractSet

A field representing a set.

class Sequence(value_type=<Not Given>, unique=<Not Given>, **kw)[source]

Bases: zope.schema._field.Collection

A field representing an ordered sequence.

New in version 4.6.0.

class StrippedValidTextLine(*args, **kw)[source]

Bases: nti.schema.field.DecodingValidTextLine

A text line that strips whitespace from incoming values.

New in version 1.13.0.

Changed in version 1.13.1: Handle single character values correctly.

fromUnicode(value)[source]
>>> from zope.schema import Text
>>> t = Text(constraint=lambda v: 'x' in v)
>>> t.fromUnicode(b"foo x spam") # doctest: +IGNORE_EXCEPTION_DETAIL
Traceback (most recent call last):
...
zope.schema._bootstrapinterfaces.WrongType:
    ('foo x spam', <type 'unicode'>, '')
>>> result = t.fromUnicode(u"foo x spam")
>>> isinstance(result, bytes)
False
>>> str(result)
'foo x spam'
>>> t.fromUnicode(u"foo spam") # doctest: +IGNORE_EXCEPTION_DETAIL
Traceback (most recent call last):
...
zope.schema._bootstrapinterfaces.ConstraintNotSatisfied:
    (u'foo spam', '')
class Text(*args, **kw)[source]

Bases: zope.schema._bootstrapfields.MinMaxLen, zope.schema._bootstrapfields.Field

A field containing text used for human discourse.

fromUnicode(value)[source]
>>> from zope.schema import Text
>>> t = Text(constraint=lambda v: 'x' in v)
>>> t.fromUnicode(b"foo x spam") # doctest: +IGNORE_EXCEPTION_DETAIL
Traceback (most recent call last):
...
zope.schema._bootstrapinterfaces.WrongType:
    ('foo x spam', <type 'unicode'>, '')
>>> result = t.fromUnicode(u"foo x spam")
>>> isinstance(result, bytes)
False
>>> str(result)
'foo x spam'
>>> t.fromUnicode(u"foo spam") # doctest: +IGNORE_EXCEPTION_DETAIL
Traceback (most recent call last):
...
zope.schema._bootstrapinterfaces.ConstraintNotSatisfied:
    (u'foo spam', '')
class TextLine(*args, **kw)[source]

Bases: zope.schema._bootstrapfields.Text

A text field with no newlines.

class Timedelta(min=None, max=None, default=None, **kw)[source]

Bases: zope.schema._bootstrapfields.Orderable, zope.schema._bootstrapfields.Field

Field containing a timedelta.

class Tuple(value_type=<Not Given>, unique=<Not Given>, **kw)[source]

Bases: zope.schema._field.Sequence

A field representing a Tuple.

class TupleFromObject(*args, **kwargs)[source]

Bases: nti.schema.field._ValueTypeAddingDocMixin, nti.schema.field._SequenceFromObjectMixin, nti.schema.field.FieldValidationMixin, zope.schema._field.Tuple

The value_type MUST be a Variant, or more generally, something supporting IFromObject, IFromUnicode or IFromBytes.

When setting through this object, we will automatically convert lists and only lists to tuples (for convenience coming in through JSON).

Changed in version 1.9.0: Implementations of zope.schema.interfaces.ICollection (like zope.schema.List) and zope.schema.interfaces.IMapping (like zope.schema.Dict) will automatically be given a fromObject method when used as the value_type of this object if their value_type is an zope.schema.interfaces.IObject (recursively).

class UniqueIterable(*args, **kwargs)[source]

Bases: nti.schema.field.ValidSet

An arbitrary iterable, not necessarily an actual set object, but one whose contents are unique. Use this when you can return a set, frozenset or empty tuple. These should be sequences that suport the in operator.

Changed in version 1.5.0: Implement IFromObject.

Changed in version 1.9.0: Implementations of zope.schema.interfaces.ICollection (like zope.schema.List) and zope.schema.interfaces.IMapping (like zope.schema.Dict) will automatically be given a fromObject method when used as the value_type of this object if their value_type is an zope.schema.interfaces.IObject (recursively).

class ValidBytes(min_length=0, max_length=None, **kw)[source]

Bases: nti.schema.field.FieldValidationMixin, zope.schema._field.Bytes

class ValidBytesLine(min_length=0, max_length=None, **kw)[source]

Bases: nti.schema.field.FieldValidationMixin, zope.schema._field.BytesLine

class ValidChoice(values=None, vocabulary=None, source=None, **kw)[source]

Bases: nti.schema.field.FieldValidationMixin, zope.schema._field.Choice

class ValidDatetime(*args, **kw)[source]

Bases: nti.schema.field.FieldValidationMixin, zope.schema._field.Datetime

Unlike the standard datetime, this will check that the given object is an instance of IDatetime, and raise the same error as object does.

schema = <InterfaceClass zope.interface.common.idatetime.IDateTime>
ValidRegEx

alias of nti.schema.field.ValidRegularExpression

class ValidRegularExpression(pattern, flags=42, *args, **kwargs)[source]

Bases: nti.schema.field.ValidTextLine

class ValidSet(*args, **kwargs)[source]

Bases: nti.schema.field._ValueTypeAddingDocMixin, nti.schema.field._SequenceFromObjectMixin, nti.schema.field.FieldValidationMixin, zope.schema._field.Set

A set that is validated.

Changed in version 1.5.0: Implement IFromObject.

Changed in version 1.9.0: Implementations of zope.schema.interfaces.ICollection (like zope.schema.List) and zope.schema.interfaces.IMapping (like zope.schema.Dict) will automatically be given a fromObject method when used as the value_type of this object if their value_type is an zope.schema.interfaces.IObject (recursively).

class ValidText(*args, **kw)[source]

Bases: nti.schema.field.FieldValidationMixin, zope.schema._bootstrapfields.Text

A text line that produces slightly better error messages. They will all have the ‘field’ property.

We also fire IBeforeTextAssignedEvent, which the normal mechanism does not.

class ValidTextLine(*args, **kw)[source]

Bases: nti.schema.field.FieldValidationMixin, zope.schema._bootstrapfields.TextLine

A text line that produces slightly better error messages. They will all have the ‘field’ property.

We also fire IBeforeTextLineAssignedEvent, which the normal mechanism does not.

class ValidURI(min_length=0, max_length=None, **kw)[source]

Bases: nti.schema.field.FieldValidationMixin, zope.schema._field.URI

class Variant(fields, variant_raise_when_schema_provided=False, **kwargs)[source]

Bases: nti.schema.field.FieldValidationMixin, zope.schema._bootstrapfields.Field

Similar to zope.schema.Object, but accepts one of many non-overlapping interfaces.

Changed in version 1.9.0: Implementations of zope.schema.interfaces.ICollection (like zope.schema.List) and zope.schema.interfaces.IMapping (like zope.schema.Dict) will automatically be given a fromObject method when they are used as a field of this object if their value_type is an zope.schema.interfaces.IObject (recursively).

Changed in version 1.16.0: If one of the fields of the variant is (recursively) a IMapping such as a Dict, both the key and value type must be specified. Previously, if they were left None, a validation-time AttributeError would be raised. Now, constructing the variant will raise a RequiredMissing.

fromObject(obj)[source]

Similar to fromUnicode, attempts to turn the given object into something acceptable and valid for this field. Raises a VariantValidationError if this isn’t possible. Adaptation is attempted in the order in which fields were given to the constructor. Some fields cannot be used to adapt.

Changed in version 1.8.0: Raise VariantValidationError instead of whatever last error we got.

Changed in version 1.9.1: Respect self.missing_value and don’t raise an exception if it is passed to this method and we’re not required.

getExtraDocLines()[source]

Return a list of ReST formatted lines that will be added to the docstring returned by getDoc().

By default, this will include information about the various properties of this object, such as required and readonly status, required type, and so on.

This implementation uses a field list for this.

Subclasses may override or extend.

New in version 4.6.0.

nti.schema.jsonschema

For producing a JSON schema appropriate for use by clients, based on a Zope schema.

The TAG constants are intended to be set as (boolean) tagged values on fields of interfaces, helping determine how the schema is built.

Note

This schema is ad-hoc and non-standard.

class JsonSchemafier(schema, readonly_override=None, context=None)[source]

Bases: object

allow_field(name, field)[source]

Return if the field is allowed in the external schema.

By default, this checks to see if the field has a true value for the tag TAG_HIDDEN_IN_UI, or if the field’s name starts with an underscore.

Changed in version 1.12.0: This will now be called for nested fields, such as the value_type or key_type of collections and mappings. In those cases, commonly the name will be the empty string.

bind(schema)[source]
get_data_from_choice_field(field, base_type=None)[source]

Return the choices and base type for the specified field

get_ui_types_from_field(field)[source]

Return the type and base type for the specified field

make_schema()[source]

Create the JSON schema.

Individual fields of the schema will be checked and returned. See the various TAG constants for ways that the schema externalization can be influenced.

Returns:A dictionary consisting of dictionaries, one for each field. All the keys are strings and the values are strings, bools, numbers, or lists of primitives. Will be suitable for writing to JSON.
post_process_field(name, field, item_schema)[source]
process_choice_field(field, base_type=None)

Return the choices and base type for the specified field

ui_types_from_field(field)

Return the type and base type for the specified field

TAG_APPLICATION_INFO = 'nti.schema.jsonschema.field_application_info'

A tagged value that echos semi-arbitrary data back in the schema under the key application_info.

The value for this field must be a mapping object whose keys are strings and whose values are JSON serializable. Text values (specifically zope.i18nmessageid.Message objects) will be translated when put into the schema. The object in the schema will not be the object in the tagged value, and constituent composite values will also be copied. (In case any post-processing of the schema is done based on current user, request or site, this isolates such modifications.)

New in version 1.12.0.

TAG_HIDDEN_IN_UI = 'nti.dataserver.users.field_hidden_in_ui'

Don’t display this by default in the UI

TAG_READONLY_IN_UI = 'nti.dataserver.users.field_readonly'

Overrides the value from the field itself, if true

TAG_REQUIRED_IN_UI = 'nti.dataserver.users.field_required'

Overrides the value from the field itself

TAG_UI_TYPE = 'nti.dataserver.users.field_type'

Qualifying details about how the field should be treated, such as data source The UI_TYPE values are defined known values for this tag.

UI_TYPE_EMAIL = 'nti.dataserver.users.interfaces.EmailAddress'

The email type

UI_TYPE_HASHED_EMAIL = 'nti.dataserver.users.interfaces.EmailAddress:Hashed'

An email type that is stored as a non-recoverable hash. The value is chosen so that a begins-with test will match either this or UI_TYPE_EMAIL, making validation easier

UI_TYPE_ONE_TIME_CHOICE = 'nti.dataserver.users.interfaces.OneTimeChoice'

Something that can be set once, typically during account creation

get_data_from_choice_field(v, base_type=None)[source]
get_ui_type_from_field_interface(field)[source]
get_ui_type_from_interface(iface)[source]
get_ui_types_from_field(field)[source]
interface_to_ui_type(iface)
process_choice_field(v, base_type=None)
ui_type_from_field(field)
ui_type_from_field_iface(field)

nti.schema.subscribers

Event handlers.

before_object_assigned_event_dispatcher(event)[source]

Listens for zope.schema fields to fire IBeforeSchemaFieldAssignedEvent, and re-dispatches these events based on the value being assigned, the object being assigned to, and of course the event (note that IBeforeObjectAssignedEvent is a sub-interface of IBeforeSchemaFieldAssignedEvent).

This is analogous to zope.component.event.objectEventNotify()

nti.schema.vocabulary

Vocabularies and factories for use in schema fields.

When this package is configured (via configure.zcml) there will be a schema vocabulary named Countries available:

>>> from nti.schema.field import Choice
>>> from zope import interface

>>> class IA(interface.Interface):
...      choice = Choice(title=u"Choice",
...                      vocabulary="Countries")
class CountryTerm(*args, **kwargs)[source]

Bases: zope.schema.vocabulary.SimpleTerm

A titled, tokenized term representing a country. The token is the ISO3166 country code. The flag value is a browserresource path to an icon representing the country.

classmethod fromItem(item)[source]
toExternalObject()[source]
CountryVocabularyFactory(context)[source]

A vocabulary factory.

nti.schema.eqhash

Helpers for hashing and equality based on a list of names.

EqHash(*names, include_super=False, superhash=False, include_type=False)[source]

A class decorator factory for the common pattern of writing __eq__/__ne__ and __hash__ methods that check the same list of attributes on a given object.

Right now, you must pass as individual arguments the property names to check; in the future, you may be able to pass a schema interface that defines the property names. Property names are compared for equality in the order they are given, so place the cheapest first.

Additional parameters are only available via keywords:

>>> @EqHash('a', 'b')
... class Thing(object):
...   a = 1
...   b = 2
>>> hash(Thing()) == (hash(('a', 'b')) ^ hash((1, 2)))
True

>>> @EqHash('c', include_super=True)
... class ChildThing(Thing):
...   c = 3
>>> hash(ChildThing()) != hash(Thing()) != 0
True
Parameters:
  • include_super – If set to True (not the default) then the equality (and perhaps hash) values of super will be considered.
  • superhash – If set to True (not the default), then the hash function will be made to support certain mutable types (lists and dictionaries) that ordinarily cannot be hashed. Use this only when those items are functionally treated as immutable.
  • include_type – If set to True (not the default), equality will only be true if the other object is an instance of the class this is declared on. Use this only when there are a series of subclasses who differ in no attributes but should not compare equal to each other. Note that this can lead to violating the commutative property.

nti.schema.testing

nti.schema.testing has moved to nti.testing.matchers.

has_length(match)[source]

Matches if len(item) satisfies a given matcher.

Parameters:match – The matcher to satisfy, or an expected value for equal_to() matching.

This matcher invokes the len() function on the evaluated object to get its length, passing the result to a given matcher for evaluation.

If the match argument is not a matcher, it is implicitly wrapped in an equal_to() matcher to check for :equality.

Examples:

has_length(greater_than(6))
has_length(5)
has_attr(name, match=None)

Matches if object has a property with a given name whose value satisfies a given matcher.

Parameters:
  • name – The name of the property.
  • match – Optional matcher to satisfy.

This matcher determines if the evaluated object has a property with a given name. If no such property is found, has_property is not satisfied.

If the property is found, its value is passed to a given matcher for evaluation. If the match argument is not a matcher, it is implicitly wrapped in an equal_to() matcher to check for equality.

If the match argument is not provided, the anything() matcher is used so that has_property is satisfied if a matching property is found.

Examples:

has_property('name', starts_with('J'))
has_property('name', 'Jon')
has_property('name')
is_true()[source]

Matches an object with a true boolean value.

is_false()[source]

Matches an object with a false boolean value.

provides(iface)[source]

Matches an object that provides the given interface.

verifiably_provides(*ifaces)[source]

Matches if the object verifiably provides the correct interface(s), as defined by zope.interface.verify.verifyObject(). This means having the right attributes and methods with the right signatures.

Note

This does not test schema compliance. For that (stricter) test, see validly_provides().

validly_provides(*ifaces)[source]

Matches if the object verifiably and validly provides the given schema (interface(s)).

Verification is done with zope.interface and verifiably_provides(), while validation is done with zope.schema.getValidationErrors().

implements(iface)[source]

Matches if the object implements (is a factory for) the given interface.

See also

zope.interface.interfaces.ISpecification.implementedBy()

validated_by(field, invalid=<class 'zope.interface.exceptions.Invalid'>)[source]

Matches if the data is validated by the given IField.

Parameters:invalid (exception) – The types of exceptions that are considered invalid. Anything other than this is allowed to be raised.

Changed in version 2.0.1: Add invalid and change it from Exception to zope.interface.interfaces.Invalid

not_validated_by(field, invalid=<class 'zope.interface.exceptions.Invalid'>)[source]

Matches if the data is NOT validated by the given IField.

Parameters:invalid (exception) – The types of exceptions that are considered invalid. Anything other than this is allowed to be raised.

Changed in version 2.0.1: Add invalid and change it from Exception to zope.interface.interfaces.Invalid

aq_inContextOf(parent)[source]

Matches if the data is in the acquisition context of the given object.

class TypeCheckedDict(key_class=<type 'object'>, val_class=<type 'object'>, notify=None)[source]

Bases: dict

A dictionary that ensures keys and values are of the required type when set

Changes

1.16.0 (2021-05-08)

  • Add support for Python 3.9.

  • Drop support for Python 3.5.

  • Fix deprecation warnings emitted by using this package, and make the deprecation warnings it emits more precise. See issue 58.

  • Fix constructing a Variant to do some extra validation of IMapping fields to require that both the key_type and value_type are given. Previously, if one or both were left None, an AttributeError would be raised when the field was asked to validate data or its fromObject() method was called. Now, a RequiredMissing error will be raised when the Variant is created. Some other nested uses of Dict fields, such as a Sequence, could also have raised the AttributeError; this may change in the future to raise at construction time as well.

    See issue 59.

1.15.1 (2020-07-02)

  • Fix plurality of error message for fields with min length of 1.

1.15.0 (2020-05-06)

  • Improve the speed of SchemaConfigured subclasses. See issue 54.

    This involves some caching, so be sure to read the documentation for nti.schema.schema if you ever mutate classes directly, or mutate the results of schemadict.

1.14.0 (2020-03-27)

  • Require zope.interface 5.0.0 and related dependencies.
  • Ensure all objects have consistent interface resolution orders.
  • Add support for Python 3.8.

1.13.1 (2019-06-11)

  • StrippedValidTextLine should accept single character lines.

1.13.0 (2019-05-22)

  • Ensure StrippedValidTextLine correctly recognizes single character values as stripped. Previously, ‘b’ would have been rejected.

1.12.0 (2018-10-10)

  • JSON schemas report the schema for IObject fields and the schemas for the possible fields in IVariant.
  • Fields in JSON schemas may specify a JSON-serializable dictionary to be passed as the application_info schema value. See issue 44.
  • JSON schemas now output more constraints automatically. See issue 47.

1.11.0 (2018-10-10)

  • JSON schemas now include nested value_type and key_type for collection and mapping fields. See issue 42.
  • JSON schemas now include (translated) title and description values for fields. See issue 41.

1.10.0 (2018-10-04)

  • Add nti.schema.fieldproperty.field_name to compensate for the mangling that FieldPropertyStoredThroughField does.

1.9.2 (2018-10-04)

  • Fix Variant and other implementations of IFromObject to stop passing known non-text values to fromUnicode methods. This only worked with certain fields (such as zope.schema.Number) that could accept non-text values, usually by implementation accident, and could have surprising consequences. Instead, non-text values will be passed to the validate method.
  • Fix Variant to stop double-validating values. The underlying fromUnicode, fromBytes or fromObject methods were supposed to already validate.

1.9.1 (2018-10-03)

  • Make VariantValidationError and Variant have more useful string representations.
  • Make fromObject methods more gracefully handle an AttributeError raised by an underlying fromUnicode method on non-string input (such as None). This is especially helpful for Variant fields because they can catch the error and continue to the next field.
  • Fix Variant, TupleFromObject, DictFromObject, ListFromObject and ListOrTupleFromObject to allow the missing_value (which defaults to None) in their fromObject methods; passing that value in simply returns it without raising an exception if the field is not required. If the field is required, a RequiredMissing is raised. Previously the sequences raised a WrongType error, while Variant may or may not have raised an error, depending on the underlying fields in use.

1.9.0 (2018-10-02)

  • Variant objects now automatically add fromObject support to ICollection and IMapping fields that do not already provide it, if their value_type (and key_type) qualify by being either an Object field, or something that provides IFromObject or can be made to, such as a collection or mapping.

1.8.0 (2018-09-28)

  • Add VariantValidationError, an error raised by variant fields when none of their constituent fields could adapt or validate the value.

1.7.0 (2018-09-19)

  • Add support for IFromBytes in zope.schema 4.8.0.
  • The Variant and ListOrTupleFromObject, TupleFromObject, DictFromObject fields all have tweaked behaviour in fromObject. If the incoming value is a bytestring or text string, the underlying field’s fromBytes and fromUnicode will be called in preference to a fromObject, if that method is implemented.
  • ValidSet and UniqueIterable now implement fromObject.
  • All fields that implement fromObject now accept an Object field for their value_type (and key_type in the case of DictFromObject) and will attempt to adapt objects that do not provide the schema in fromObject.

1.6.0 (2018-09-18)

  • Adjust the deprecated zope.schema.interfaces.InvalidValue to be a simple alias for zope.schema.interfaces.InvalidValue (while preserving the constructor) for improved backwards compatibility.

1.5.0 (2018-09-11)

  • Add support for zope.schema 4.7.0; drop support for older versions.

1.4.2 (2018-09-10)

  • Fix the repr of nti.schema.interfaces.InvalidValue. See issue 26.
  • nti.schema.jsonschema turns more abstract field types into concrete types. See issue 29.

1.4.1 (2018-09-10)

  • Make nti.schema.interfaces.InvalidValue a class again. It is deprecated. See issue 24.

1.4.0 (2018-09-10)

  • Drop support for dm.zope.schema fields, in particular the Object field. The validation performed by zope.schema.Object is much improved.
  • Drop support for zope.schema older than 4.6.1.
  • Deprecate nti.schema.field.Number.
  • Add support for Python 3.7.

1.3.3 (2018-09-07)

  • Minor fix for changes in zope.schema 4.6.0 (import BeforeObjectAssignedEvent from its new, but still private, location).

1.3.2 (2017-10-24)

  • Depend on zope.deferredimport >= 4.2.1 to be able to generate Sphinx documentation.
  • Clean up code to match PEP8.

1.3.1 (2017-10-18)

  • Fix an UnboundLocalError on Python 3 in the Variant field. See issue 14.

1.3.0 (2017-07-06)

  • Drop the Python 2 dependency on plone.i18n in favor of the new library nti.i18n, which supports Python 3. If plone.i18n is installed, it should not be configured (ZCML), but its utility objects can be looked up by either interface.

1.2.0 (2017-05-17)

  • Remove use of unicode_literals.
  • Add support for Python 3.6.
  • The SchemaConfigured constructor doesn’t hide errors when checking for properties on Python 2. See issue 11.

1.1.3 (2017-01-17)

  • Add info to minLength validation message.

1.1.2 (2016-09-14)

  • Add Acquisition and zope.event as install dependencies. Previously they were only pulled in via the test extra.

1.1.1 (2016-09-08)

  • Substantial speedups to the hash functions generated by EqHash.
  • Substantial speedups to the equality functions generated by EqHash.

1.1.0 (2016-07-29)

  • Add support for Python 3. Note the countries vocabulary will not be complete on Python 3.
  • Drop the dolmen.builtins dependency.
  • Drop the dm.zope.schema dependency.
  • The plone.i18n dependency is Python 2 only (and can even be removed).
  • The matchers in nti.schema.testing have been moved to nti.testing.matchers.
  • Using AdaptingFieldProperty will now raise the more specific SchemaNotProvided error instead of a TypeError if adapting the value fails.
  • EqHash has moved from nti.schema.schema to nti.schema.eqhash. A compatibility shim remains.

Indices and tables