Minor docs improvements.

This commit is contained in:
Joshua Bronson 2022-02-28 00:21:03 +00:00
parent e7e456e885
commit 3050f9866b
4 changed files with 82 additions and 70 deletions

View File

@ -8,15 +8,25 @@
Changelog
=========
.. image:: https://img.shields.io/badge/GitHub-sponsor-ff69b4
:target: https://github.com/sponsors/jab
:alt: Sponsor through GitHub
.. image:: https://img.shields.io/github/sponsors/jab
:target: https://github.com/sponsors/jab
:alt: Sponsors on GitHub
Release Notifications
---------------------
.. duplicated in README.rst
(would use `.. include::` but GitHub doesn't understand it)
Tip: Watch releases
`on GitHub <https://github.blog/changelog/2018-11-27-watch-releases/>`__
to be notified when new versions of ``bidict`` are released.
Tip:
`Watch <https://github.blog/changelog/2018-11-27-watch-releases/>`__ releases
`on GitHub <https://github.com/jab/bidict>`__
to be notified when new versions of bidict are released.
0.22.0 (not yet released)
@ -57,10 +67,6 @@ to be notified when new versions of ``bidict`` are released.
In a microbenchmark on Python 3.10,
this now performs **5-30% faster**.
- Optimize pickling bidicts.
In a microbenchmark on Python 3.10,
this now performs **5-10% faster**.
- Optimize rolling back
:ref:`failed updates to a bidict <basic-usage:Updates Fail Clean>`
in the case that the number of items passed to the update call
@ -68,13 +74,14 @@ to be notified when new versions of ``bidict`` are released.
Previously this rollback was O(n) in the number of items passed.
Now it is O(1), i.e. **unboundedly faster**.
- Optimize :meth:`~bidict.BidictBase.__contains__`
(the method called when you run ``key in any_bidict``).
- Optimize :meth:`bidict.BidictBase.__contains__`
(the method called when you run ``key in mybidict``).
In a microbenchmark on Python 3.10,
this now performs over **3x faster** in the False case,
and at least **50% faster** in the True case.
- Optimize :meth:`~bidict.BidictBase.__eq__`.
- Optimize :meth:`bidict.BidictBase.__eq__`
(the method called when you run ``mybidict == other``).
In a microbenchmark on Python 3.10,
this now performs over **25x faster** for ordered bidicts,
and at least **10x faster** for unordered bidicts.
@ -151,9 +158,9 @@ to be notified when new versions of ``bidict`` are released.
an ``_isinv`` attribute,
which :class:`~bidict.BidictBase` subclasses no longer provide.
- When attempting to pickle a bidict's inverse
whose class was dynamically generated
(as in :ref:`extending:Dynamic Inverse Class Generation`),
- When attempting to pickle a bidict's inverse whose class was
:ref:`dynamically generated
<extending:Dynamic Inverse Class Generation>`,
and no reference to the dynamically-generated class has been stored
anywhere in :data:`sys.modules` where :mod:`pickle` can find it,
the pickle call is now more likely to succeed

View File

@ -144,14 +144,13 @@ Bidict is the product of thousands of hours of my unpaid work
over the ~15 years that I've been the sole maintainer.
If bidict has helped you or your company accomplish your work,
especially work that you or your company were paid for,
please `sponsor my work through GitHub <https://github.com/sponsors/jab>`__,
and ask others you know who got value from my work to do the same.
and/or ask your company to do the same.
Choose a tier and GitHub handles everything else.
Sponsorship just goes on the same bill that GitHub
already charges you or your company for automatically,
so after the one-time signup, there's nothing extra to do.
Your GitHub sponsorship will automatically go
on the same bill you already have set up with GitHub,
so after the one-click signup, there's nothing else to do.
You can also sponsor my work through
`Gumroad <https://gumroad.com/l/bidict>`__ or

View File

@ -149,8 +149,8 @@ Release Notifications
.. duplicated in CHANGELOG.rst:
(would use `.. include::` but GitHub doesn't understand it)
Watch releases
`on GitHub <https://github.blog/changelog/2018-11-27-watch-releases/>`__
`Watch <https://github.blog/changelog/2018-11-27-watch-releases/>`__ releases
`on GitHub <https://github.com/jab/bidict>`__
to be notified when new versions of bidict are released.
@ -196,14 +196,13 @@ Bidict is the product of thousands of hours of my unpaid work
over the ~15 years that I've been the sole maintainer.
If bidict has helped you or your company accomplish your work,
especially work that you or your company were paid for,
please `sponsor my work through GitHub <https://github.com/sponsors/jab>`__,
and ask others you know who got value from my work to do the same.
please `sponsor my work through GitHub <https://github.com/sponsors/jab>`__
and/or ask your company to do the same.
Choose a tier and GitHub handles everything else.
Sponsorship just goes on the same bill that GitHub
already charges you or your company for automatically,
so after the one-time signup, there's nothing extra to do.
Your GitHub sponsorship will automatically go
on the same bill you already have set up with GitHub,
so after the one-click signup, there's nothing else to do.
See the following for rationale and examples of companies
supporting the open source projects they depend on

View File

@ -1,45 +1,35 @@
Learning from ``bidict``
------------------------
Below is an outline of some of the more fascinating
and lesser-known Python corners I got to explore further
thanks to working on :mod:`bidict`.
Working on :mod:`bidict` has taken me to
some of the most interesting and unexpected places
I've ever been to in many years of programming.
(When I started :mod:`bidict` almost 15 years ago,
I didn't know what higher-kinded types even were,
let alone that I'd one day
`explain to Guido
<https://github.com/python/typing/issues/548#issuecomment-621195693>`__
how they're useful for bidirectional mapping types.)
If you would like to learn more about any of the topics below,
you may find `reading bidict's code
<https://github.com/jab/bidict/blob/main/bidict/__init__.py#L9>`__
particularly interesting.
The problem space that :mod:`bidict` inhabits
is abundant with beautiful symmetries,
delightful surprises, and rich opportunities
to come up with elegant solutions.
I've sought to optimize the code not just for correctness and performance,
but also to make for a clear and enjoyable read,
illuminating anything that could otherwise be obscure or subtle.
You can check out :mod:`bidict`'s source
to see for yourself.
I've sought to optimize the code
not just for correctness and performance,
but also for clarity, maintainability,
and to make for an enjoyable read.
I hope it brings you some of the
See below for more, and
`let me know <mailto:jabronson@gmail.com>`__
what you think.
I hope reading :mod:`bidict`'s code
gives you a taste of some of the immense
`joy <https://joy.recurse.com/posts/148-bidict>`__
it's brought me. 😊
Python syntax hacks
===================
:mod:`bidict` used to support
(ab)using a specialized form of Python's :ref:`slice <slicings>` syntax
for getting and setting keys by value:
.. use `code-block` rather than `doctest` for this
since slice syntax is no longer supported:
.. code-block:: python
>>> element_by_symbol = bidict(H='hydrogen')
>>> element_by_symbol['H'] # [normal] syntax for the forward mapping
'hydrogen'
>>> element_by_symbol[:'hydrogen'] # [:slice] syntax for the inverse (no longer supported)
'H'
See `this code <https://github.com/jab/bidict/blob/356dbe3/bidict/_bidict.py#L25>`__
for how this was implemented,
and `#19 <https://github.com/jab/bidict/issues/19>`__ for why this was dropped.
that :mod:`bidict` has given me.
Code structure
@ -55,7 +45,7 @@ as appropriate.
Factoring the code to maximize reuse, modularity, and
adherence to `SOLID <https://en.wikipedia.org/wiki/SOLID>`__ design principles
(while not missing any chances for special-case optimizations)
(while not missing any chances for specialized optimizations)
has been one of the most fun parts of working on bidict.
To see how this is done, check out the code starting with
@ -85,11 +75,8 @@ and you miss all the value that comes from ongoing, direct practical application
Bidict shows how fundamental data structures
can be implemented in Python for important real-world usage,
with practical concerns at top of mind.
Come to catch sight of a real, live, industrial-strength linked list in the wild.
Stay for the rare, exotic bidirectional mapping breeds you'll rarely see at home.
[#fn-data-struct]_
.. [#fn-data-struct] To give you a taste:
.. admonition:: To give you a taste...
A regular :class:`~bidict.bidict`
encapsulates two regular dicts,
@ -112,14 +99,34 @@ Stay for the rare, exotic bidirectional mapping breeds you'll rarely see at home
And since :class:`~bidict.OrderedBidictBase` needs to not only
look up nodes by key/value, but also key/value by node,
internally it uses an (unordered) :class:`~bidict.bidict` for this.
it uses an (unordered) :class:`~bidict.bidict` for this internally.
Bidicts all the way down!
Check out `_orderedbase.py <https://github.com/jab/bidict/blob/main/bidict/_orderedbase.py#L10>`__
to see this in action.
Python syntax hacks
===================
:mod:`bidict` used to support
(ab)using a specialized form of Python's :ref:`slice <slicings>` syntax
for getting and setting keys by value:
.. use `code-block` rather than `doctest` for this
since slice syntax is no longer supported:
.. code-block:: python
>>> element_by_symbol = bidict(H='hydrogen')
>>> element_by_symbol['H'] # [normal] syntax for the forward mapping
'hydrogen'
>>> element_by_symbol[:'hydrogen'] # [:slice] syntax for the inverse (no longer supported)
'H'
See `this code <https://github.com/jab/bidict/blob/356dbe3/bidict/_bidict.py#L25>`__
for how this was implemented,
and `#19 <https://github.com/jab/bidict/issues/19>`__ for why this was dropped.
Property-based testing is revolutionary
Property-based testing is indispensable
=======================================
When your automated tests run,