Add a more formal concept of field types for API resources.

Review Request #9682 — Created Feb. 20, 2018 and submitted — Latest diff uploaded


When defining fields for a resource's response, or fields accepted
during a request, we previously made use of some standard Python 2.7
primitives, such as unicode, file, int, and some special values
like a list or tuple containing possible choices for a value. These
were only handled in Djblets by the @webapi_request_fields decorator,
which had built-in support for specific types. Resources were free to
list fields as well, but they didn't do anything special with them
(though consuming applications could, for documentation purposes).

The real problem was that these types weren't all compatible with
Python 3. For instance, file does not exist. It was also just not very
future-proof in general, and while it served us well for a while,
there's more we can do with a new model.

This change introduces a new concept of field types, which are classes
that know how to do things like validate and normalize a value coming in
from a request, and generate a description of the type (intended for
documentation purposes). With these, @webapi_request_fields no longer
needs to know about specific types, and can therefore be more simple and
more maintainable.

Field types plug right into a field info dictionary's 'type' item,
where the old legacy types were. When instantiated (which happens on
demand, not during field list definition), they're passed the field info
dictionary, which may contain other data useful for that field type
(such as a list of choices, or a resource path/class).

There's a handful of built-in types, some geared more for documentation
purposes (like ResourceFieldType) and some for more specialized
handling of common request values (like DateTimeFieldType).

Existing dictionaries with legacy types going into
@webapi_request_fields are still supported. Legacy types are
automatically converted into the new types the first time the function
is called.

Going forward, we'll be able to use this to help further separate out
field validation/normalization from API logic in Review Board and in

Djblets unit tests pass.

Converted all of Review Board to the new field types (upcoming change)
and verified that all unit tests pass and all docs generated correctly.

Built the new docs. Didn't see any errors.