Implement general purpose cache_key function

This includes the non-instance logic from instance_cache_key. In addition
a warning is emitted for types that do not implement the __getstate__ method
for pickling.

Fix #258

Signed-off-by: Byron Ruth <b@devel.io>
Can you explain this if statement a bit? When will a string have a version attribute defined on it? It seems to me that this would make more sense to check that it is _not_ a string before checking if it has the `version` attribute.