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 :py:mod:`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``.

def make_property_type(name, base_type=Property,
                       attrs=None, trait_name=None,
                       **default_kwargs):
    """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 :py:mod:`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``.
    """

    if not attrs:
        attrs = {}
    bases = base_type if isinstance(base_type, tuple) else (base_type,)
    self_type = []
    if not trait_name:
        global trait_num
        trait_num += 1
        trait_name = "trait%d" % trait_num

    def __init__(self, **kwargs):
        for arg, val in default_kwargs.iteritems():
            if arg not in kwargs:
                kwargs[arg] = val
        return super(self_type[0], self).__init__(**kwargs)

    attrs['default_kwargs'] = default_kwargs
    attrs['__init__'] = __init__
    attrs['__trait__'] = trait_name

    new_property_type = type(name, bases, attrs)
    self_type.append(new_property_type)
    return new_property_type