FYI, I just finished a rough implementation of the phase 1 EIM API
(primitive types, aliasing, and conversion). It's not in SVN yet (so as
not to interfere with a4 work), but here is the current doctest, warts and
all. (Most of the warts will be fixed when phase 2 kicks in, adding
"Record" and "field" types that will produce better examples.)
Review and comments welcomed and requested.
----------------------
The Sharing Record API
----------------------
>>> import eim as sharing # API kludge during initial dev & testing
Defining and Using Field Types
==============================
Custom Types
------------
The most basic kinds of field types can be created using the ``BytesType``,
``TextType``, ``IntType``, ``DateType``, and ``LobType`` constructors::
>>> my_date = sharing.DateType()
>>> my_date
sharing.DateType(None)
Types can be given a unique URI, and they can be looked up by it::
>>> my_text = sharing.TextType("cid:[email protected]", size=99)
>>> my_text
sharing.TextType('cid:[email protected]', 99)
>>> sharing.typeinfo_for("cid:[email protected]")
sharing.TextType('cid:[email protected]', 99)
>>> my_text.uri
'cid:[email protected]'
>>> my_text.size
99
But only one type can exist for a given URI at a given point in time::
>>> another_text = sharing.TextType("cid:[email protected]", 99)
Traceback (most recent call last):
...
TypeError: A type already exists for 'cid:[email protected]'
>>> del my_text # no conflicting definition now
>>> another_text = sharing.TextType("cid:[email protected]", 99)
Type Aliasing
-------------
The ``sharing.typedef()`` API lets you register type information for
arbitrary Python objects, so that you can use existing types, kinds, etc.
as field types. For example::
>>> class my_int(int):
... """This is just a demonstration type"""
>>> sharing.typedef(my_int, sharing.IntType('cid:[email protected]'))
Now, ``my_int`` can be used directly as a field type in a
``sharing.Record`` class, instead of using the ``IntType`` object::
>>> sharing.typeinfo_for(my_int) # XXX demo w/field instead of typeinfo
sharing.IntType('cid:[email protected]')
You can alias more than one object to the same type, or alias an object to
an already-registered alias::
>>> class my_int2(int):
... """Another demonstration type"""
>>> sharing.typedef(my_int2, my_int)
>>> sharing.typeinfo_for(my_int2) is sharing.typeinfo_for(my_int)
True
There are also built-in aliases for anonymous versions of the sizeless
primitive types (``IntType``, ``LobType``, and ``DateType``), so you can
use them directly in fields::
>>> sharing.typeinfo_for(sharing.IntType)
sharing.IntType(None)
>>> sharing.typeinfo_for(sharing.LobType)
sharing.LobType(None)
>>> sharing.typeinfo_for(sharing.DateType)
sharing.DateType(None)
Type Conversion
---------------
Because there are only five primitive EIM types (bytes, text, integer,
date/time, and "lob"), it is usually necessary to convert some application-
level data types to the corresponding primitive type.
For example, let's say that an application has a value that is normally
represented as a hexidecimal string, but which for some reason it wants to
transmit as an integer in its sharing records. The application would need
to define a string converter to turn the hex string into an integer.
So let's define a ``hexint`` type that we can use in field definitions
where we want to be able to supply either integers or hex strings as input
when creating a record.
>>> hexint = sharing.IntType('cid:[email protected]')
By default, there is no converter registered to convert strings to
integers, although there is one for converting integers to integers::
>>> sharing.get_converter(hexint)(23)
23
>>> sharing.get_converter(hexint)("23")
Traceback (most recent call last):
...
TypeError: No converter registered for values of type <type 'str'>
The ``sharing.add_converter()`` API allows you to register a conversion
function to be used for a particular field or field type::
>>> sharing.add_converter(hexint, str, lambda v: int(v,16))
>>> sharing.get_converter(hexint)("23")
35
XXX this doc should probably use fields for examples, so as to hide
the use of get_converter(type)(value); normally this would only be
called by record constructors.
XXX Need more default encoders for primitive types; only int->IntType
currently works
Creating Subtypes
-----------------
Sometimes, it's useful to create a field type by copying an existing
type. The ``sharing.subtype()`` function creates a new type from an
existing one. The new type will be of the same primitive type, and it will
"inherit" any conversion functions defined for the base type::
>>> hexint2 = sharing.subtype(hexint)
>>> hexint2
sharing.IntType(None)
>>> sharing.get_converter(hexint2)("23")
35
XXX example of argument pass-through from ``subtype()`` to typeinfo constructor
XXX test generation-skipping in converter registration
---------
Internals
---------
TypeInfo instances are immutable once created::
>>> t = sharing.IntType()
>>> t.uri = "fhdsfblah"
Traceback (most recent call last):
...
TypeError: sharing.IntType instances are immutable
Misc. constructor data validation tests::
>>> sharing.TypeInfo()
Traceback (most recent call last):
...
TypeError: sharing.TypeInfo is an abstract type; use a subtype
>>> sharing.SizedType()
Traceback (most recent call last):
...
TypeError: size must be specified when creating a sharing.SizedType
>>> sharing.SizedType(size=53)
Traceback (most recent call last):
...
TypeError: sharing.SizedType is an abstract type; use a subtype
>>> sharing.BytesType()
Traceback (most recent call last):
...
TypeError: size must be specified when creating a sharing.BytesType
>>> sharing.TextType()
Traceback (most recent call last):
...
TypeError: size must be specified when creating a sharing.TextType
No such type::
>>> sharing.typeinfo_for('xyz:abc')
Traceback (most recent call last):
...
UnknownType: 'xyz:abc'
XXX typeinfo_for(obj) -> TypeInfo
field -> typeinfo_for(field.type)
descr -> typeinfo_for(descr.type)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
Open Source Applications Foundation "chandler-dev" mailing list
http://lists.osafoundation.org/mailman/listinfo/chandler-dev