I wasn't actually thinking .get() or buckets would fully implement a Mapping, but rather just provide a similar mechanism through __getitem__. I was actually thinking of deviating from the expectation by having the default for get be an empty iterable instead of None (although allowing the default to be overridden), something like:

    def get(self, key, default=empty()):
        try:
            return self[key]
        except KeyError:
            return default

I went with that design because your proposed use case suggested to me that something returning an empty iterable is a valuable behavior.

As for the other mapping behaviors, I'm also not seeing the value in them. If one wants an actual in-memory mapping, that should probably be outside the scope of itertools.