API

recktype() factory function for record types

reck.recktype(typename, fieldnames, rename=False)

Create a new record class with fields accessible by named attributes.

The new type is a subclass of collections.Sequence named typename.

The new subclass is used to create record objects that have fields accessible by attribute lookup as well as being indexable and iterable. Per-field default values can be set. These are assigned to fields that are not supplied a value during instantiation.

Basic example:

>>> from reck import recktype
>>> Point3D = recktype('Point3D', 'x y z')  # Create new record type
>>> p = Point3D(x=1, y=2, z=3)
>>> # Make a new Point3D class in which 'z' defaults to zero
>>> Point3D = recktype('Point3D', ['x', 'y', ('z', 0)])
>>> p = Point3D(x=1, y=2)
>>> p                                   # z has been assigned its default value
Point3D(x=1, y=2, z=0)
Parameters:
  • typename – Name of the subclass to create, e.g. 'MyRecord'.
  • fieldnames

    Specifies the fieldnames and optional per-field default values of the record. It cam be a single string with each fieldname separated by whitespace and/or commas such as 'x, y'; a sequence of strings such as ['x', 'y'] and/or 2-tuples of the form (fieldname, default_value) such as [('x', None), ('y', None)]; a mapping of fieldname-default_value pairs such as collections.OrderedDict([('x', None), ('y', None)]). Note, it only makes sense to use an ordered mapping (e.g. OrderedDict) since access by index or iteration is affected by the order of the fieldnames.

    A fieldname may be any valid Python identifier except for names starting with an underscore.

  • rename – If set to True, invalid fieldnames are automatically replaced with positional names. For example, (‘abc’, ‘def’, ‘ghi’, ‘abc’) is converted to (‘abc’, ‘_1’, ‘ghi’, ‘_3’), eliminating the keyword ‘def’ and the duplicate fieldname ‘abc’.
Returns:

A subclass of of collections.Sequence named typename.

Raises:
  • ValueError – if typename is invalid; fieldnames contains an invalid fieldname and rename is False; fieldnames contains a sequence that is not length 2.
  • TypeError – if a fieldname is neither a string or a sequence.

Record type methods and attributes

These are the methods and attributes supported by record types. To prevent conflicts with fieldnames, the method and attribute names start with an underscore.

class somemodule.SomeReckType(*values_by_field_order, **values_by_fieldname)

Return a new record object.

Field values can be passed by field order, fieldname, or both.

The following examples all return a record equivalent to Rec(a=1, b=2, c=3):

>>> Rec = recktype('Rec', 'a b c')
>>> rec = Rec(1, 2, 3)                # using positional args
>>> rec = Rec(a=1, b=2, c=3)          # using keyword args
>>> rec = Rec(*[1, 2, 3])             # using an unpacked sequence
>>> rec = Rec(**dict(a=1, b=2, c=3))  # using an unpacked mapping
>>> rec = Rec(*[1, 2], c=3)           # using an unpacked sequence and a keyword arg
>>> rec
Rec(a=1, b=2, c=3)

Since record objects are iterable they can be used to initialise other objects of the same type by unpacking them:

>>> rec2 = Rec(*rec)
>>> rec2 == rec
True

If a field has not been supplied a value by an argument, its default value will be used (if one has been defined).

Parameters:
  • *values_by_field_order

    Field values passed by field order.

  • **values_by_fieldname

    Field values passed by fieldname.

Raises TypeError:
 

if the number of positional arguments exceeds the number of fields, a keyword argument does not match a fieldname, or a keyword argument redefines a positional argument.

Rasies ValueError:
 

if a field has not been defined by the positional or keyword arguments and has no default value set.

somerecord._asdict()

Return a new collections.OrderedDict which maps fieldnames to their values.

somerecord._asitems()

Return a list of (fieldname, value) 2-tuples.

somerecord._count(value)

Return a count of how many times value occurs in the record.

somerecord._index(value)

Return the index of the first occurrence of value in the record.

somerecord._fieldnames

Tuple of strings listing the fieldnames. Useful for introspection and creating new record types from existing record types. Should not be changed.

Example usage:

>>> Point = recktype('Point', 'x y')  # create a new record type
>>> Point._fieldnames       # view the fieldnames
('x', 'y')
>>> Point3D = recktype('Point3D', Point._fieldnames + ('z',))
>>> Point3D._fieldnames
('x', 'y', 'z')
classmethod somerecord._get_defaults()

Return a dict that maps fieldnames to their corresponding default_value. If no default values are set an empty dict is returned.

classmethod somerecord._replace_defaults(*values_by_field_order, **values_by_fieldname)

Replace the existing per-field default values.

The new default field values can be passed by field order, fieldname, or both.

Changing the defaults can be useful if you wish to use the same record class in different contexts which require different default values.

Example:

>>> Point3D = recktype('Point3D', [('x', 1), ('y', 2), 'z'])
>>> Point3D._get_defaults()
{'x': 1, 'y': 2}
>>> Point3D._replace_defaults(x=7, z=9)
>>> Point3D._get_defaults()  # 'y' was not supplied a default so it no longer has one
{'x': 7, 'z': 9}
>>> Point3D._replace_defaults()  # Remove all defaults
>>> Point3D._get_defaults()
{}
Parameters:
  • *values_by_field_order

    Default field values passed by field order.

  • **values_by_fieldname

    Default field values passed by fieldname.

Raises TypeError:
 

if the number of positional arguments exceeds the number of fields, a keyword argument does not match a fieldname, or a keyword argument redefines a positional argument.

somerecord._update(*values_by_field_order, **values_by_fieldname)

Update field values with values passed by field order, fieldname, or both.

Example:

>>> Rec = recktype('Rec', 'a b c')
>>> r = Rec(a=1, b=2, c=3)
>>> r._update(b=5, c=6)   # Using keyword arguments
>>> r
Rec(a=1, b=5, c=6)
>>> r._update(2, 3, c=4)  # Using values by field order and by name
>>> r
Rec(a=2, b=3, c=4)
Parameters:
  • *values_by_field_order

    Field values passed by field order.

  • **values_by_fieldname

    Field values passed by fieldname.

Raises TypeError:
 

if the number of positional arguments exceeds the number of fields, a keyword argument does not match a fieldname, or a keyword argument redefines a positional argument.

Operations supported by records

The following operations are supported by records:

len(rec)

Return the number of fields in the record rec.

rec[index]

Return the field values(s) in rec corresponding to the position(s) given by index. index can be an integer or slice object.

rec[index] = value

Set the value of the field corresponding to the position given by index, which may be an integer or slice object.

Note, the behaviour of setting field values using slices is different from that of lists. If values contains more items than slice the surplus values are discarded, whereas with lists the surplus items are inserted into the list. Similarly, if values contains fewer items than slice, the surplus fields in the slice remain unaffected, whereas with a list the surplus list items are removed.

Example:

>>> Rec = recktype('Rec', 'a b c')
>>> r = Rec(1, 2, 3)
>>> r[2] = 4            # using an integer index
>>> r[2]
4
>>> r[:2] = [5, 6, 7]   # using a slice
>>> r                   # the surplus value, 7, was discarded
Rec(a=5, b=6, c=4)

value in rec

Return True if record rec contains value, else False.

value not in rec

Equivalent to not value in rec.

iter(rec)

Return an iterator over the field values of record rec.

reversed(rec)

Return a reverse iterator over the field values of record rec.

vars(rec)

Return a new collections.OrderedDict which maps the fieldnames of rec to their corresponding values. This is equivalent to calling rec._asdict().

DefaultFactory

class reck.DefaultFactory(factory_func, args=(), kwargs={})

Wrap a default factory function.

Default factory functions must be wrapped using this class so that they can be distinguished from non-factory callable default values. The args and kwargs arguments can be used to specify optional positional and keyword arguments to be passed to the factory function when it is called.

Example of setting list as a default factory during record type creation:

>>> from reck import DefaultFactory
>>> Car = recktype('Car', [
...     'make',
...     'model',
...     ('colours', DefaultFactory(list))])
>>> car = Car(make='Lotus', model='Exige')
>>> car.colours.append('Orange')
>>> car.colours.append('Green')
>>> car
Car(name='Lotus', model='Exige', colours=['Orange', 'Green'])

An example using dict with positional and keyword arguments as a default factory:

 >>> Rec = recktype('Rec', [
 ...     ('a', DefaultFactory(dict, args=[[('b', 2)]], kwargs=dict(c=3)))])
 >>> rec = Rec()       # field 'a' will be set using the default factory
 >>> rec.a
{'b': 2, 'c': 3}
Parameters:
  • factory_func – the callable object to be invoked as a default factory function (with args and kwargs if provided).
  • args – a tuple of arguments for the factory function invocation.
  • kwargs – a dictionary of keyword arguments for the factory function invocation.