Defining Properties - normalize.property

Warning

The Property() constructor usually returns a different object type than the class name passed. It decides on the keyword arguments passed to it which subclass takes those arguments and calls that class’ constructor instead.

Hopefully, this implementation detail should not be of huge importance to most users. For more details on how a property class is selected, see Addendum: Property MetaClass.

Core Property Types

Property objects are “new”-style object data descriptors. They define getters and setters for object attribute access, and allow the module to hang on extra information and customize behavior.

For information on data descriptors, see the Descriptor HowTo Guide in the main python documentation.

Property

class normalize.property.Property(isa=None, coerce=None, check=None, required=False, default=<not set>, traits=None, extraneous=False, empty_attr=<not set>, empty=None, doc=None)[source]

This is the base class for all property types. It is a data descriptor, so care should be taken before adding any SPECIALMETHODS which might change the way it behaves.

__init__(isa=None, coerce=None, check=None, required=False, default=<not set>, traits=None, extraneous=False, empty_attr=<not set>, empty=None, doc=None)[source]

Declares a new standard Property. Note: if you pass arguments which are not understood by this constructor, or pass extra property traits to traits, then the call will be redirected to a sub-class; see normalize.property.meta for more.

Because of this magic, all Property arguments must be passed in keyword argument form. All arguments are optional.

isa=TYPE|TUPLE

Any assigned property must be one of these types according to isinstance(). Also used by visitor functions which are missing an instance, such as marshal in.

If isa is not set, then any value (including None) is acceptable.

coerce=FUNCTION
If the value fails the isa isinstance check, then this function is called with the value, and should return a value of a conformant type or throw an exception.
check=FUNCTION
Once the value is of the correct type, this function is called and should return something true (according to bool()) if the value is acceptable.
required=BOOL
If True, then the value must be passed during construction, and may not be None (this is only meaningful if isa= is not passed)
default=VALUE|FUNCTION
If no value is passed during construction, then use this value instead. If the argument is a function, then the function is called and the value it returns used as the default.
traits=LIST|SEQUENCE
Manually specify a list of named Property traits. The default is ["safe"], and any unknown keyword arguments will add extra traits on.
empty_attr=METHODNAME
Specify an auxiliary method name which returns the value if the attribute is set, otherwise an empty proxy value. Defaults to the name of the attribute with a 0 appended, or None if the attribute already ends with a number (disabling the accessor)
empty=IGNORED
For partial compatibility with normalize 0.7.x. This used to specify the value returned by the empty_attr attribute; now that attribute always returns a Falsy placeholder.
extraneous=BOOL
This Property is considered denormalized and does not affect the Record equality operator. Visitor functions typically ignore extraneous properties or require an extra option to process them.
doc=STR
Specify a docstring for the property.
fullname[source]

Returns the name of the Record class this Property is attached to, and attribute name it is attached as.

__get__(obj, type_=None)[source]

Default getter; does NOT fall back to regular descriptor behavior

aux_props()[source]

This method is available for property traits to provide extra class attributes which are added to the class they are defined in during class creation. The default implementation is responsible for defining empty_attr attributes.

The return value should be an iterable list of 2-tuples, with the first member of each 2-tuple being the attribute name and the second being the value to insert.

SafeProperty

class normalize.property.SafeProperty(isa=None, coerce=None, check=None, required=False, default=<not set>, traits=None, extraneous=False, empty_attr=<not set>, empty=None, doc=None)[source]

Bases: normalize.property.Property

A version of Property which always checks all assignments to properties.

Normalize gives you safe properties by default; if you want unsafe properties, then you (currently) need to pass traits=["unsafe"] to the Property() declaration.

LazyProperty

LazyProperty has a function which returns the value for a slot, if the slot is empty.

class normalize.property.LazyProperty(lazy=True, **kwargs)[source]

This declares a property which has late evaluation using its ‘default’ method. This type uses the support built-in to python for lazy attribute setting, which means subsequent attribute assignments will not be prevented or checked. See LazySafeProperty for the descriptor version.

__init__(lazy=True, **kwargs)[source]

Creates a Lazy property. In addition to the standard Property arguments, accepts:

lazy=BOOL
Must be True. Used as a “distinguishing argument” to request a lazy Property. Not required if you call LazyProperty() directly.
default=FUNCTION|METHOD
The default value for the property. Unlike a standard Property, the value can also be set to a method, which can reference other object properties.
__get__(obj, type_=None)[source]

This getter is called when there is no value set, and calls the default method/function.

class normalize.property.LazySafeProperty(lazy=True, **kwargs)[source]

Bases: normalize.property.SafeProperty, normalize.property.LazyProperty

__get__(obj, type_=None)[source]

This getter checks to see if the slot is already set in the object and if so, returns it.

ROProperty & ROLazyProperty

These types cannot be assigned; however ROLazyProperty may take a function which provides the initial value on first access; this function is called at most once for each instance.

class normalize.property.ROProperty(isa=None, coerce=None, check=None, required=False, default=<not set>, traits=None, extraneous=False, empty_attr=<not set>, empty=None, doc=None)[source]

A read-only property throws an exception when the attribute slot is assigned to

class normalize.property.ROLazyProperty(lazy=True, **kwargs)[source]

Bases: normalize.property.LazyProperty, normalize.property.ROProperty

__get__(obj, type_=None)[source]

This getter checks to see if the slot is already set in the object and if so, returns it.

Typed Properties

Typed properties are convenient shorthands to specifying the various isa and coerce parameters when declaring properties.

Bundled Typed Properties

normalize.property.types provides an assortment of pre-generated types

normalize.property.types.IntProperty

A property which must be an int

normalize.property.types.LongProperty

A property which must be a long

normalize.property.types.IntegerProperty

A property which may be either an int or a long

normalize.property.types.StringProperty

A property which must be a basestring, and if not, it is coerced using str

normalize.property.types.FloatProperty

A property which must be a floating point number.

normalize.property.types.UnicodeProperty

A property which must be a unicode, and if not, it is coerced using unicode

normalize.property.types.DateProperty

A property which must hold a python date (or datetime); coercion from string is provided via dateutil.parse. Note that datetime is a date subclass, and supports all its methods, so a DateProperty might contain a datetime instance.

normalize.property.types.DatetimeProperty

A property which must holds a python datetime. Correct timezone handling is currently TODO and users should not depend on timezone behavior until this message is removed (submit tests and a patch!)

Rolling your own typed properties

normalize.property.make_property_type(name, base_type=<class 'normalize.property.Property'>, attrs=None, trait_name=None, **default_kwargs)[source]

Makes a new Property type, which supplies the given arguments as defaults to the Property() constructor.

The typical use of this function is to make types for the API you are mapping so that, for instance, any time they use a date you can convert it in a consistent way to a datetime.date.

It’s also used by normalize.property.types to create all of its Property subclasses.

Args:
name=STR
Specifies the name of the new property type. This is entirely cosmetic, but it is probably a good idea to make this exactly the same as the symbol you are assigning the result to.
base_type=Property sub-class
Specifies which property type you are adding defaults to. You can pass in a tuple of types here.
attrs=DICT
This lets you pass in a dictionary that will be used as the new Property type’s class dictionary. i.e., it gets passed as the third argument to type(NAME, BASES, ATTRS), after the properties necessary to implement the defaults are added to it. If you use this for anything less than trivial, it may be simpler just to make a whole class definition.
trait_name=STR
Specify the unique identifier of the trait that is created. This probably doesn’t matter, unless you want to use the traits= keyword to Property(). The default is to make up a new numbered trait name, starting with “trait1”.
**kwargs
Everything not known is used as defaults for the eventual call to Property(). If the user of the Property type passes it as well, this overrides the defaults passed to make_property_type.

Properties containing collections

The following typed properties are similar to the other typed properties, in that they provide some checks and convenience around making new collection types and hooking them up correctly.

class normalize.property.coll.CollectionProperty(of=None, coll=None, isa=None, **kwargs)[source]

Bases: normalize.property.Property

Base class for properties which contain collections; responsible for creating new collection types (via normalize.coll._make_generic())

__init__(of=None, coll=None, isa=None, **kwargs)[source]

Create a new Collection property.

Args:
of=TYPE
Specifies what type each member of the collection must be.
coll=<Abstract Collection type>
Specify the container type for the collection. Should be a normalize.coll.Collection sub-class.
isa=<Concrete Collection type>
Specify both of= and isa= by passing in a ‘concrete’ Collection type (this means it already has itemtype set)
class normalize.property.coll.SafeCollectionProperty(of=None, coll=None, isa=None, **kwargs)[source]

Bases: normalize.property.coll.CollectionProperty, normalize.property.SafeProperty

class normalize.property.coll.ListProperty(list_of=None, **kwargs)[source]

Bases: normalize.property.coll.CollectionProperty

Declaring JSON hints on Properties

The various json_X parameters are distinguishing options which will select the “json” trait.

class normalize.property.json.JsonProperty(json_name=<prop.name>, json_in=None, json_out=None, **kwargs)[source]

Object property wrapper for record json data

json_name[source]

Key name for this attribute in JSON dictionary. Defaults to the attribute name in the class it is bound to.

to_json(propval, extraneous=False, to_json_func=None)[source]

This function calls the json_out function, if it was specified, otherwise continues with JSON conversion of the value in the slot by calling to_json_func on it.

from_json(json_data)[source]

This function calls the json_in function, if it was specified, otherwise passes through.

The other classes in this module are just mixed-in combinations of JsonProperty with various other base types. This is required because currently the metaclass does not mix them in dynamically. Once it does, the trivial, undocumented mixes here may be deprecated or removed.

class normalize.property.json.SafeJsonProperty(json_name=<prop.name>, json_in=None, json_out=None, **kwargs)[source]

Bases: normalize.property.json.JsonProperty, normalize.property.SafeProperty

class normalize.property.json.JsonListProperty(list_of=None, **kwargs)[source]

Bases: normalize.property.coll.ListProperty, normalize.property.json.JsonProperty

A property which map to a list of records in JSON.

It can also map a dictionary with some top level keys (eg, streaming information) and a key with the actual list contents. See normalize.record.json for more details.

There are also two deprecated aliases: JsonCollectionProperty is the same as JsonListProperty.

Addendum: Property MetaClass

normalize.property.meta.has(selfie, self, args, kwargs)[source]

This is called ‘has’ but is called indirectly. Each Property sub-class is installed with this function which replaces their __new__.

It is called ‘has’, because it runs during property declaration, processes the arguments and is responsible for returning an appropriate Property subclass. As such it is identical to the ‘has’ function in Perl’s Moose. The API does not use the word, but the semantics are the same.

It is responsible for picking which sub-class of ‘self’ to invoke. Unlike Moose, it will not dynamically create property types; if a type does not exist it will be a hard error.

This function should only be concerned with picking the appropriate object type, because unlike in Perl, python cannot re-bless objects from one class to another.

normalize.property.meta.create_property_type_from_traits(trait_set)[source]

Takes an iterable of trait names, and tries to compose a property type from that. Raises an exception if this is not possible. Extra traits not requested are not acceptable.

If this automatic generation doesn’t work for you for some reason, then compose your property types manually.

The details of this composition should not be relied upon; it may change in future releases. However, a given normalize version should behave consistently for multiple runs, given the same starting sets of properties, the composition order will be the same every time.

class normalize.property.meta.MetaProperty[source]

MetaClass for the various Property types, which allows for composing the various Property mix-ins, depending on options selected.

static __new__(mcs, name, bases, attrs)[source]

This __new__ method is called when new property trait combinations are created.