I rearranged the _encode method branching a bit. This resulted in a
little more than a 12% gain. Still slower than JSON or msgpack but it's
in python instead of C.
If someone explicitly removes the literal mappings, then refuse to
serialize None, True, and False instead of guessing. Note that I
explicitly included True and False in the branch logic since bool is a
subclass of int but str(True) != str(int(True)) :/
I ended up not using urllib.parse functions since they do not implement
the specification. The only difference is that the specification
requires that "~" is encoded.
NB - this commit is incomplete since it does not handle calling the
transcoder on simple objects. mypy will quite correctly fail.
If there is no transcoder for the default content type, sending a
response would fail with a "500 Internal Server Error" due to an
*unhandled* KeyError. This commit catches the KeyError and produces
an explicit "500 Internal Server Error" with an appropriate error
message being logged.
If there is no default content type and nothing matches in the Accept
header, previous versions would fail with an Internal Server Error
because of an unhandled exception. Instead we should be returning
a "406 Not Acceptable".
This allows us to remove the ImportError hack from __init__.py.
It also simplifies how the package is versioned - deriving it solely
from the repository tag.
Both version_info and __version__ have been removed with this change.
Given how these are a unofficial-standard at best, I've found it safer to
always use pkg_resources to determine the version when I need to.
Extended the `ImportError` handling hack to correctly handle the
case where we cannot import submodules AND someone is extending
one of the exported classes. Previously ContentMixin and
ContentSettings were functions when ImportError was raised which
causes really confusing errors.
The correct solution here is to stop exporting stuff at the top-
level and require clients to import from modules but that is for
another day.
This lets any transparent caches that our responses will vary based on
the Accept header. Without this, caches will assume that a cached
response can be used even if the Accept header differs.