DictCall
========
.. contents::
DictCall primarily exports the function `dictCall`, which may
raise the exceptions `NotFound` or `Invalid` (both of which
are inherited from `DictCallError`.
.. include: dictCall
.. _dictCall:
.. topic:: ``dictCall(func, d)``:
Calls the function `func` with the information from dictionary
`d`.
`d` is expected to be a dictionary of strings, possibly with
lists of strings for some keys, as might be generated by the
`cgi` module. `dictCall` will match the keys of the dictionary
with the arguments of the function.
The function can provide type information, so that the input is
verified and coerced in some fashion. However, type information
is not required.
**Defining Parameter Types**
There are two ways of providing type information: by the parameter
names themselves, or in the docstring.
Parameter names can be typed by appending the types to the name,
like ``var_int``. The dictionary will still be searched for a
variable ``var``, but then it will be converted into an int.
However, note that your parameter is still named var_int! This
can be annoying.
Instead you can put the type information in the docstring. You
should begin this information with a line like::
call types:
on a line by itself. Later lines should be of the format::
var: dict, int
where ``dict, int`` equivalent to var_dict_int (types are
described later). You end this section of information with a
blank line. Indentation is not significant. Variables that are
simply strings may be omited.
You can also put the information in a function attribute, like::
def myFunc(a, b, c):
pass
myFunc.callTypes={'a': 'dict,int', 'c': 'int'}
This is equivalent to ``myFunc(a_dict_int, b, c_int)``. Note
Python 2.3 you can use::
myFunc.callTypes=dict(a='dict,int', c='int')
**Parameter Types**
The basic types, besides the implicit string type, are ``int`` and
``float``.
In addition to these types there are three compound types:
``set``:
Sets are actually returned as lists, but they are not
generally ordered. When a dictionary is passed in like
``{'var': ['a', 'b']}``, this returns ``['a', 'b']`` (it's
Invalid if you don't indicate that it's a set). It also
promotes non-lists to a list, and if nothing is present
returns the empty list (i.e., ``{'var': 'a'}`` returns
``['a']``, and ``{}`` returns ``[]``).
Sets can be used with ``int`` and ``float``, i.e., a type
of ``set, int`` will return a list of integers. You cannot
put a ``dict`` or ``list`` inside a set, though a set can
go inside them.
``dict``:
A dictionary takes keys of the form ``var1:key`` and
turns them into nested dictionaries. So with a type
dict, ``{'var:a': 'apple', 'var:b': 'banana'}`` will
return ``{'a': 'apple', 'b': 'banana'}``.
Dict can be nested, so that keys like ``var1:key1:key2``
are possible, and can also be nested with ``list`` and
contain ``set``, ``int``, or ``float``.
``list``:
Essentially the same as dict, only it uses the keys only
for ordering, and expects those keys to be integers.
So ``{'var:1': 'first', 'var:2': 'second'}`` returns
``['first', 'second']``.
**Using Types Together**
If you are, for instance, collecting a list of first and
last names, you can use compound types to manage the fields.
Generate the form like::
for i in range(len(names)):
self.write(''
% (i, htmlEncode(names[i]['fname'])))
self.write(''
% (i, htmlEncode(names[i]['fname'])))
Then the method that accepts the form looks like::
def saveNames(self, names_list_dict)
``names_list_dict`` will look like
``[{'fname': ..., 'lname': ...}, ...]``
.. _specDict:
.. topic:: ``specDict(func)``:
Returns a dictionary that contains whatever type specification
there is for the function.
That dictionary has a key for each value expected or allowed in
the request dictionary -- essentially a key for each argument
variable. For each key there's another dictionary. There's keys
``targetName`` and ``type``, where targetName gives the variable
name in the function definition (which may contain type
information embedded, e.g. var1_int would be considered the
variable ``"var1"`` with a type ``["int"]`` and a targetName
``"var1_int"``. Also has the key ``default`` which is a boolean,
whether this key has a default value.
The presence of the key ``**`` means that extra keyword arguments
are allowed (always as strings, unparsed).