This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author jab
Recipients jab, rhettinger
Date 2022-02-10.20:48:44
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1644526124.97.0.327985085857.issue45670@roundup.psfhosted.org>
In-reply-to
Content
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.
History
Date User Action Args
2022-02-10 20:48:45jabsetrecipients: + jab, rhettinger
2022-02-10 20:48:44jabsetmessageid: <1644526124.97.0.327985085857.issue45670@roundup.psfhosted.org>
2022-02-10 20:48:44jablinkissue45670 messages
2022-02-10 20:48:44jabcreate