Importing Schema from CSV Files
===============================

We allow users to spell schema definitions via CSV text files, where the
columns are 'Name', 'Type', 'Default'.  E.g.::

  >>> _SCHEMA = '''\
  ... foo,TextLine,Foo
  ... bar,Int,42
  ... spam,Float,3.1415926
  ... baz,Text,"Multi-line text is
  ... possible in CSV."
  ... qux,Choice,two,one,two,three
  ... quux,ChoiceSet,"two,three",one,two,three
  ... frobnatz,Bool,True'''

When we construct a schema from the CSV, we get a Zope3 interface (just
as though we had typed the equivalent Python faux-class syntax)::

  >>> from zope.interface.interface import InterfaceClass
  >>> from zope.schema import Bool
  >>> from zope.schema import Choice
  >>> from zope.schema import Float
  >>> from zope.schema import Int
  >>> from zope.schema import Text
  >>> from zope.schema import TextLine
  >>> from userschema.schema import ChoiceSet
  >>> from userschema.schema import fromCSV

We must pass the name of the generated schema to 'fromCSV', along with
the CSV text (or a file-like object)::

  >>> a_schema = fromCSV(_SCHEMA, 'a_schema')
  >>> type(a_schema) is InterfaceClass
  True
  >>> print a_schema.__name__
  a_schema

The '__module__' attribute of the generated interface defaults to
'userschema'::

  >>> print a_schema.__module__
  userschema

We can override that by passing 'module_name'::

  >>> a_schema = fromCSV(_SCHEMA, 'a_schema', module_name='somemodule')
  >>> print a_schema.__module__
  somemodule

The attributes of the generated schema correspond to the rows in
the CSV::

  >>> names = list(a_schema.names())
  >>> names.sort()
  >>> print names
  ['bar', 'baz', 'foo', 'frobnatz', 'quux', 'qux', 'spam']

We create the fields we would expect from the types defined in the CSV.
The 'foo' field is a TextLine::

  >>> field = a_schema.getDescriptionFor('foo')
  >>> isinstance(field, TextLine)
  True
  >>> print field.default
  Foo

The 'bar' field is an Int::

  >>> field = a_schema.getDescriptionFor('bar')
  >>> isinstance(field, Int)
  True
  >>> print field.default
  42

The 'spam' field is an Float::

  >>> field = a_schema.getDescriptionFor('spam')
  >>> isinstance(field, Float)
  True
  >>> print field.default
  3.1415926

The 'baz' field is a Text, with multi-line default::

  >>> field = a_schema.getDescriptionFor('baz')
  >>> isinstance(field, Text)
  True
  >>> print field.default
  Multi-line text is
  possible in CSV.


The 'qux' field is a Choice, with the vocabulary defined in the
extra columns::

  >>> field = a_schema.getDescriptionFor('qux')
  >>> isinstance(field, Choice)
  True
  >>> print field.default
  two
  >>> print [str(x.value) for x in field.vocabulary]
  ['one', 'two', 'three']

The 'quux' field is a ChoiceSet, with the vocabulary defined in the
extra columns::

  >>> field = a_schema.getDescriptionFor('quux')
  >>> isinstance(field, ChoiceSet)
  True
  >>> print field.default
  Set([u'two', u'three'])
  >>> print [str(x.value) for x in field.vocabulary]
  ['one', 'two', 'three']

The 'frobnatz' field is a TextLine::

  >>> field = a_schema.getDescriptionFor('frobnatz')
  >>> isinstance(field, Bool)
  True
  >>> print field.default
  True

CVS: $Id: csv-schema.txt,v 1.2 2007/01/31 16:58:07 tseaver Exp $
