Joshua Bronson <jabron...@gmail.com> added the comment:
Thank you for confirming that ChainMap.__iter__() would be in the same boat as bidict if a similar .mapping attribute were ever added to dict_keyiterators. The specifics of this issue are interesting, but even more interesting to me is whatever learnings we can generalize from this. After testing that the performance impact would be significant, I created the feature request you suggested in https://bugs.python.org/issue46713. Thanks for suggesting that. In the meantime, I've updated the relevant docstrings: >>> help(b.keys) keys() -> KeysView[~KT] method of bidict.bidict instance A set-like object providing a view on the contained keys. When *b._fwdm* is a :class:`dict`, *b.keys()* returns a *dict_keys* object that behaves exactly the same as *collections.abc.KeysView(b)*, except for - offering better performance - being reversible on Python 3.8+ - having a .mapping attribute in Python 3.10+ that exposes a mappingproxy to *b._fwdm*. >>> help(b.values) values() -> bidict.BidictKeysView[~VT] method of bidict.bidict instance A set-like object providing a view on the contained values. Since the values of a bidict are equivalent to the keys of its inverse, this method returns a set-like object for this bidict's values rather than just a collections.abc.ValuesView. This object supports set operations like union and difference, and constant- rather than linear-time containment checks, and is no more expensive to provide than the less capable collections.abc.ValuesView would be. See :meth:`keys` for more information. etc. Regarding: > The values() call unexpectedly returns an instance of dict_keys(). At first, > I was surprised that this got past the type checker -- you can do set > operations with KeysView but not with a ValuesView. Check out https://github.com/jab/bidict/blob/82f931/bidict/_base.py#L38-L45: ``` class BidictKeysView(t.KeysView[KT], t.ValuesView[KT]): """Since the keys of a bidict are the values of its inverse (and vice versa), the ValuesView result of calling *bi.values()* is also a KeysView of *bi.inverse*. """ dict_keys: t.Type[t.KeysView[t.Any]] = type({}.keys()) BidictKeysView.register(dict_keys) ``` See also https://github.com/python/typeshed/issues/4435 for a request that typeshed use a Protocol (structural typing) here. Thanks again for taking the time to look at my code and discuss so generously. ---------- _______________________________________ Python tracker <rep...@bugs.python.org> <https://bugs.python.org/issue45670> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com