[Zope3-checkins] SVN: Zope3/trunk/src/zope/schema/ Updated schema package's README.txt fiel and made it a doctest. The

Stephan Richter srichter at cosmos.phy.tufts.edu
Fri Mar 4 08:41:06 EST 2005


Log message for revision 29396:
  Updated schema package's README.txt fiel and made it a doctest. The 
  contents of the the file still sucks a lot, but a little less now.
  
  

Changed:
  U   Zope3/trunk/src/zope/schema/README.txt
  U   Zope3/trunk/src/zope/schema/fields.txt
  A   Zope3/trunk/src/zope/schema/tests/test_docs.py

-=-
Modified: Zope3/trunk/src/zope/schema/README.txt
===================================================================
--- Zope3/trunk/src/zope/schema/README.txt	2005-03-04 12:58:56 UTC (rev 29395)
+++ Zope3/trunk/src/zope/schema/README.txt	2005-03-04 13:41:06 UTC (rev 29396)
@@ -2,24 +2,21 @@
 Zope 3 Schemas
 ==============
 
-.. contents::
-
-
 Introduction
 ------------
 
-Schemas extend the notion of interfaces to descriptions of Attributes
-rather than methods.  Every Schema is an interface and specifies the
-public fields of an object.  A *Field* roughly corresponds to an
-attribute of a python object.  But a Field provides space for a title
-and a description.  It can also constrain its value and provide a
-validation method.  Besides you can optionally specify characteristics
-such as its value being read-only or not required.
+Schemas extend the notion of interfaces to detailed descriptions of Attributes
+(but not methods). Every schema is an interface and specifies the public
+fields of an object. A *field* roughly corresponds to an attribute of a
+python object. But a Field provides space for at least a title and a
+description. It can also constrain its value and provide a validation method.
+Besides you can optionally specify characteristics such as its value being
+read-only or not required.
 
 Zope 3 schemas were born when Jim Fulton and Martijn Faassen thought
-about Formulator for Zope 3 and PropertySets while at the `Zope 3
-sprint`_ at the `Zope BBQ`_ in Berlin.  They realized that if you strip
-all view logic from forms then you have something similar to interfaces.  And
+about Formulator for Zope 3 and ``PropertySets`` while at the `Zope 3
+sprint`_ at the `Zope BBQ`_ in Berlin. They realized that if you strip
+all view logic from forms then you have something similar to interfaces. And
 thus schemas were born.
 
 .. _Zope 3 sprint: http://dev.zope.org/Zope3/ZopeBBQ2002Sprint
@@ -36,87 +33,149 @@
 Simple Usage
 ------------
 
+Let's have a look at a simple example. First we write an interface as usual,
+but instead of describing the attributes of the interface with ``Attribute``
+instances, we now use schema fields:
 
+  >>> import zope.interface
+  >>> import zope.schema
 
-    
-    >>> class Bookmark:
-    ...     def __init__(self, url):
-    ...         self.url = url
-    ...
-    >>> from zope.schema import TextLine, validateMapping
-    >>> from zope.interface import Interface
-    >>> class IBookmark(Interface):
-    ...     url = TextLine(title=u'url of the bookmark')
-    ...
-    ...
-    >>> obj = Bookmark(u'zope website', u'http://www.zope.org',
-    ...                keywords=('web', 'python'))
-    >>> validateMapping(IBookmark, obj.__dict__)
+  >>> class IBookmark(zope.interface.Interface):
+  ...     title = zope.schema.TextLine(
+  ...         title=u'Title',
+  ...         description=u'The title of the bookmark',
+  ...         required=True)
+  ...
+  ...     url = zope.schema.URI(
+  ...         title=u'Bookmark URL',
+  ...         description=u'URL of the Bookmark',
+  ...         required=True)
+  ...
+  
+Now we create a class that implements this interface and create an isntance of
+it:
 
-The last statement validates that our object conforms to the
-``IBookmark`` Schema.
+  >>> class Bookmark(object):
+  ...     zope.interface.implements(IBookmark)
+  ...
+  ...     title = None
+  ...     url = None
 
+  >>> bm = Bookmark()
 
+We would now like to only add validated values to the class. This can be done
+by first validating and then setting the value on the object. The first step
+is to define some data:
+
+  >>> title = u'Zope 3 Website'
+  >>> url = 'http://dev.zope.org/Zope3'
+
+Now we, get the fields from the interface:
+
+  >>> title_field = IBookmark.get('title')
+  >>> url_field = IBookmark.get('url')
+
+Next we have to bind these fields to the context, so that instance-specific
+information can be used for validation:
+
+  >>> title_bound = title_field.bind(bm)
+  >>> url_bound = url_field.bind(bm)
+
+Now that the fields are bound, we can finally validate the data:
+
+  >>> title_bound.validate(title)
+  >>> url_bound.validate(url)
+
+If the validation is successful, ``None`` is returned. If a validation error
+occurs a ``ValidationError`` will be raised; for example:
+
+  >>> url_bound.validate(u'http://zope.org/foo')
+  Traceback (most recent call last):
+  ...
+  WrongType: (u'http://zope.org/foo', <type 'str'>)
+
+  >>> url_bound.validate('foo.bar')
+  Traceback (most recent call last):
+  ...
+  InvalidURI: foo.bar
+
+Now that the data has been successfully validated, we can set it on the
+object:
+
+  >>> title_bound.set(bm, title)
+  >>> url_bound.set(bm, url)
+
+That's it. You still might think this is a lot of work to validate and set a
+value for an object. Note, however, that it is very easy to write helper
+functions that automate these tasks. If correctly designed, you will never
+have to worry explicitely about validation again, since the system takes care
+of it automatically.
+
+
 What is a schema, how does it compare to an interface?
 ------------------------------------------------------
 
-A schema is an extended interface which defines Fields.  You can
-validate that attributes of an object conform to their Fields defined
-on the schema.  With plain interfaces you can only validate that
-methods conform to their interface specification.
+A schema is an extended interface which defines fields.  You can validate that
+the attributes of an object conform to their fields defined on the schema.
+With plain interfaces you can only validate that methods conform to their
+interface specification.
 
 So interfaces and schemas refer to different aspects of an object
 (respectively its code and state).
 
-A Schema starts out like an interface but defines certain Fields to
+A schema starts out like an interface but defines certain fields to
 which an object's attributes must conform.  Let's look at a stripped
-down example from the programmer's tutorial::
+down example from the programmer's tutorial:
 
-    from zope.interface import Interface
-    from zope.schema import Text, TextLine
+    >>> import re
 
-    class IContact(Interface):
-        """Provides access to basic contact information."""
+    >>> class IContact(zope.interface.Interface):
+    ...     """Provides access to basic contact information."""
+    ... 
+    ...     first = zope.schema.TextLine(title=u"First name")
+    ...
+    ...     last = zope.schema.TextLine(title=u"Last name")
+    ...
+    ...     email = zope.schema.TextLine(title=u"Electronic mail address")
+    ...
+    ...     address = zope.schema.Text(title=u"Postal address")
+    ...
+    ...     postalCode = zope.schema.TextLine(
+    ...         title=u"Postal code",
+    ...         constraint=re.compile("\d{5,5}(-\d{4,4})?$").match)
 
-        first = TextLine(title=u"First name")
-        last = TextLine(title=u"Last name")
-        email = TextLine(title=u"Electronic mail address")
-        address = Text(title=u"Postal address")
-        postalCode = TextLine(title=u"Postal code",
-                              constraint=re.compile(
-                                  "\d{5,5}(-\d{4,4})?$").match)
-
 ``TextLine`` is a field and expresses that an attribute is a single line
 of Unicode text.  ``Text`` expresses an arbitrary Unicode ("text")
 object.  The most interesting part is the last attribute
 specification.  It constrains the ``postalCode`` attribute to only have
 values that are US postal codes.
 
-Now we want a class that adheres to the IContact Schema::
+Now we want a class that adheres to the ``IContact`` schema:
 
-    class Contact(persistent.Persistent):
-        implements(IContact)
+    >>> class Contact(object):
+    ...     zope.interface.implements(IContact)
+    ... 
+    ...     def __init__(self, first, last, email, address, pc):
+    ...         self.first = first
+    ...         self.last = last
+    ...         self.email = email
+    ...         self.address = address
+    ...         self.postalCode = pc
 
-        def __init__(self, first, last, email, address, pc):
-            self.first = first
-            self.last = last
-            self.email = email
-            self.address = address
-            self.postalCode = pc
-
 Now you can see if an instance of ``Contact`` actually implements the
-schema::
+schema:
 
-    from zope.app.schema import validateMapping
-    someone = Contact('Tim','Roberts', 'tim at roberts', '','')
-    validateMapping(IContact, someone.__dict__)
+    >>> someone = Contact(u'Tim', u'Roberts', u'tim at roberts', u'', 
+    ...                   u'12032-3492')
+    
+    >>> for field in zope.schema.getFields(IContact).values():
+    ...     bound = field.bind(someone)
+    ...     bound.validate(bound.get(someone))
 
 
 Data Modeling Concepts
 -----------------------
 
-XXX much more is needed here!
-
 The ``zope.schema`` package provides a core set of field types,
 including single- and multi-line text fields, binary data fields,
 integers, floating-point numbers, and date/time values.
@@ -134,7 +193,7 @@
   same for all values of the type.  Changes to the list are driven by
   schema evolution.
 
-  This is done by mixing-in the IEnumerated interface into the field
+  This is done by mixing-in the ``IEnumerated`` interface into the field
   type, and the Enumerated mix-in for the implementation (or emulating
   it in a concrete class).
 
@@ -161,7 +220,7 @@
   If a field is designated as required, assigned field values must always
   be non-missing. See the next section for a description of missing values.
 
-- A value designated as 'missing'
+- A value designated as ``missing``
 
   Missing values, when assigned to an object, indicate that there is 'no
   data' for that field. Missing values are analogous to null values in
@@ -183,6 +242,7 @@
 
 Fields and Widgets
 ------------------
+
 Widgets are components that display field values and, in the case of
 writable fields, allow the user to edit those values.
 
@@ -201,8 +261,8 @@
   by the user need to be converted to numbers such as int or float.
 
 - Support the ability to assign a missing value to a field. For example,
-  a widget may present a "None" option for selection that, when selected,
-  indicates that the object should be updated with the field's 'missing'
+  a widget may present a ``None`` option for selection that, when selected,
+  indicates that the object should be updated with the field's ``missing``
   value.
 
 

Modified: Zope3/trunk/src/zope/schema/fields.txt
===================================================================
--- Zope3/trunk/src/zope/schema/fields.txt	2005-03-04 12:58:56 UTC (rev 29395)
+++ Zope3/trunk/src/zope/schema/fields.txt	2005-03-04 13:41:06 UTC (rev 29396)
@@ -2,9 +2,6 @@
 Fields
 ======
 
-.. contents::
-
-
 This document highlights unusual and subtle aspects of various fields and
 field classes, and is not intended to be a general introduction to schema
 fields.  Please see README.txt for a more general introduction.
@@ -17,7 +14,7 @@
 ("widgets").
 
 Collections
-===========
+-----------
 
 Normal fields typically describe the API of the attribute -- does it behave as a
 Python Int, or a Float, or a Bool -- and various constraints to the model, such
@@ -68,7 +65,7 @@
 would also be necessary to implement a Bag.
 
 Choices and Vocabularies
-========================
+------------------------
 
 Choice fields are the schema way of spelling enumerated fields and more.  By
 providing a dynamically generated vocabulary, the choices available to a
@@ -119,7 +116,7 @@
 not too difficult itself.
 
 Choices and Collections
-=======================
+-----------------------
 
 Choices are a field type and can be used as a value_type for collections.  Just
 as a collection of an "Int" value_type constrains members to integers, so a
@@ -129,7 +126,7 @@
 which the choice is based.
 
 Using Choice and Collection Fields within a Widget Framework
-============================================================
+------------------------------------------------------------
 
 While fields support several use cases, including code documentation and data
 description and even casting, a significant use case influencing their design is

Added: Zope3/trunk/src/zope/schema/tests/test_docs.py
===================================================================
--- Zope3/trunk/src/zope/schema/tests/test_docs.py	2005-03-04 12:58:56 UTC (rev 29395)
+++ Zope3/trunk/src/zope/schema/tests/test_docs.py	2005-03-04 13:41:06 UTC (rev 29396)
@@ -0,0 +1,27 @@
+##############################################################################
+#
+# Copyright (c) 2004 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Tests for the schema package's documentation files
+
+$Id: tests.py 29143 2005-02-14 22:43:16Z srichter $
+"""
+import unittest
+from zope.testing import doctest
+
+def test_suite():
+    return unittest.TestSuite((
+        doctest.DocFileSuite('../README.txt'),
+        ))
+
+if __name__ == '__main__':
+    unittest.main(default='test_suite')


Property changes on: Zope3/trunk/src/zope/schema/tests/test_docs.py
___________________________________________________________________
Name: svn:eol-style
   + native



More information about the Zope3-Checkins mailing list