Previously we only supported `str` types exactly, or types that would be natively mapped to `str`. We now natively support `str` subclasses as dict keys in `msgspec.convert` as well as all `encode` functions. This is a bit inconsistent with the rest of msgspec, where `str` subclasses aren't natively supported and require an `enc_hook` to support. I think making an exception for dict keys is fine since: - In the long term the `enc_hook` design should be reworked, allowing us to natively handle `str` subclasses everywhere, provided the user doesn't override a serializer for that type. When that's done dicts with str subclasses as keys will "just work" out of the box, I see no reason not to allow that now as well. - The main reason we don't natively support encoding str subclasses (or most subclasses) is that there's no way for a user to override behavior for a natively supported object. Subclassing a str lets the user change how that str is serialized. While I still want to support this for *values*, I find it highly unlikely that a user would want to change how a dict key is serialized. Again, in the long run users should be able to override this behavior in an ergonomic way, but for now I'm making (IMO) the pragmatic choice of supporting the common case without requiring extra effort from users.