DESCRIPTION.rst 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. ==============
  2. singledispatch
  3. ==============
  4. .. image:: https://secure.travis-ci.org/ambv/singledispatch.png
  5. :target: https://secure.travis-ci.org/ambv/singledispatch
  6. `PEP 443 <http://www.python.org/dev/peps/pep-0443/>`_ proposed to expose
  7. a mechanism in the ``functools`` standard library module in Python 3.4
  8. that provides a simple form of generic programming known as
  9. single-dispatch generic functions.
  10. This library is a backport of this functionality to Python 2.6 - 3.3.
  11. To define a generic function, decorate it with the ``@singledispatch``
  12. decorator. Note that the dispatch happens on the type of the first
  13. argument, create your function accordingly::
  14. >>> from singledispatch import singledispatch
  15. >>> @singledispatch
  16. ... def fun(arg, verbose=False):
  17. ... if verbose:
  18. ... print("Let me just say,", end=" ")
  19. ... print(arg)
  20. To add overloaded implementations to the function, use the
  21. ``register()`` attribute of the generic function. It is a decorator,
  22. taking a type parameter and decorating a function implementing the
  23. operation for that type::
  24. >>> @fun.register(int)
  25. ... def _(arg, verbose=False):
  26. ... if verbose:
  27. ... print("Strength in numbers, eh?", end=" ")
  28. ... print(arg)
  29. ...
  30. >>> @fun.register(list)
  31. ... def _(arg, verbose=False):
  32. ... if verbose:
  33. ... print("Enumerate this:")
  34. ... for i, elem in enumerate(arg):
  35. ... print(i, elem)
  36. To enable registering lambdas and pre-existing functions, the
  37. ``register()`` attribute can be used in a functional form::
  38. >>> def nothing(arg, verbose=False):
  39. ... print("Nothing.")
  40. ...
  41. >>> fun.register(type(None), nothing)
  42. The ``register()`` attribute returns the undecorated function which
  43. enables decorator stacking, pickling, as well as creating unit tests for
  44. each variant independently::
  45. >>> @fun.register(float)
  46. ... @fun.register(Decimal)
  47. ... def fun_num(arg, verbose=False):
  48. ... if verbose:
  49. ... print("Half of your number:", end=" ")
  50. ... print(arg / 2)
  51. ...
  52. >>> fun_num is fun
  53. False
  54. When called, the generic function dispatches on the type of the first
  55. argument::
  56. >>> fun("Hello, world.")
  57. Hello, world.
  58. >>> fun("test.", verbose=True)
  59. Let me just say, test.
  60. >>> fun(42, verbose=True)
  61. Strength in numbers, eh? 42
  62. >>> fun(['spam', 'spam', 'eggs', 'spam'], verbose=True)
  63. Enumerate this:
  64. 0 spam
  65. 1 spam
  66. 2 eggs
  67. 3 spam
  68. >>> fun(None)
  69. Nothing.
  70. >>> fun(1.23)
  71. 0.615
  72. Where there is no registered implementation for a specific type, its
  73. method resolution order is used to find a more generic implementation.
  74. The original function decorated with ``@singledispatch`` is registered
  75. for the base ``object`` type, which means it is used if no better
  76. implementation is found.
  77. To check which implementation will the generic function choose for
  78. a given type, use the ``dispatch()`` attribute::
  79. >>> fun.dispatch(float)
  80. <function fun_num at 0x1035a2840>
  81. >>> fun.dispatch(dict) # note: default implementation
  82. <function fun at 0x103fe0000>
  83. To access all registered implementations, use the read-only ``registry``
  84. attribute::
  85. >>> fun.registry.keys()
  86. dict_keys([<class 'NoneType'>, <class 'int'>, <class 'object'>,
  87. <class 'decimal.Decimal'>, <class 'list'>,
  88. <class 'float'>])
  89. >>> fun.registry[float]
  90. <function fun_num at 0x1035a2840>
  91. >>> fun.registry[object]
  92. <function fun at 0x103fe0000>
  93. The vanilla documentation is available at
  94. http://docs.python.org/3/library/functools.html#functools.singledispatch.
  95. Versioning
  96. ----------
  97. This backport is intended to keep 100% compatibility with the vanilla
  98. release in Python 3.4+. To help maintaining a version you want and
  99. expect, a versioning scheme is used where:
  100. * the first three numbers indicate the version of Python 3.x from which the
  101. backport is done
  102. * a backport release number is provided after the last dot
  103. For example, ``3.4.0.0`` is the **first** release of ``singledispatch``
  104. compatible with the library found in Python **3.4.0**.
  105. A single exception from the 100% compatibility principle is that bugs
  106. fixed before releasing another minor Python 3.x.y version **will be
  107. included** in the backport releases done in the mean time. This rule
  108. applies to bugs only.
  109. Maintenance
  110. -----------
  111. This backport is maintained on BitBucket by Łukasz Langa, one of the
  112. members of the core CPython team:
  113. * `singledispatch Mercurial repository <https://bitbucket.org/ambv/singledispatch>`_
  114. * `singledispatch issue tracker <https://bitbucket.org/ambv/singledispatch/issues>`_
  115. Change Log
  116. ----------
  117. 3.4.0.3
  118. ~~~~~~~
  119. Should now install flawlessly on PyPy as well. Thanks to Ryan Petrello
  120. for finding and fixing the ``setup.py`` issue.
  121. 3.4.0.2
  122. ~~~~~~~
  123. Updated to the reference implementation as of 02-July-2013.
  124. * more predictable dispatch order when abstract base classes are in use:
  125. abstract base classes are now inserted into the MRO of the argument's
  126. class where their functionality is introduced, i.e. issubclass(cls,
  127. abc) returns True for the class itself but returns False for all its
  128. direct base classes. Implicit ABCs for a given class (either
  129. registered or inferred from the presence of a special method like
  130. __len__) are inserted directly after the last ABC explicitly listed in
  131. the MRO of said class. This also means there are less "ambiguous
  132. dispatch" exceptions raised.
  133. * better test coverage and improved docstrings
  134. 3.4.0.1
  135. ~~~~~~~
  136. Updated to the reference implementation as of 31-May-2013.
  137. * better performance
  138. * fixed a corner case with PEP 435 enums
  139. * calls to `dispatch()` also cached
  140. * dispatching algorithm now now a module-level routine called `_find_impl()`
  141. with a simplified implementation and proper documentation
  142. * `dispatch()` now handles all caching-related activities
  143. * terminology more consistent: "overload" -> "implementation"
  144. 3.4.0.0
  145. ~~~~~~~
  146. * the first public release compatible with 3.4.0
  147. Conversion Process
  148. ------------------
  149. This section is technical and should bother you only if you are
  150. wondering how this backport is produced. If the implementation details
  151. of this backport are not important for you, feel free to ignore the
  152. following content.
  153. ``singledispatch`` is converted using `six
  154. <http://pypi.python.org/pypi/six>`_ so that a single codebase can be
  155. used for all compatible Python versions. Because a fully automatic
  156. conversion was not doable, I took the following branching approach:
  157. * the ``upstream`` branch holds unchanged files synchronized from the
  158. upstream CPython repository. The synchronization is currently done by
  159. manually copying the required code parts and stating from which
  160. CPython changeset they come from. The tests should pass on Python 3.4
  161. on this branch.
  162. * the ``default`` branch holds the manually translated version and this
  163. is where all tests are run for all supported Python versions using
  164. Tox.