TypeQuery 0.1.5
A simple and dirty way to define generic methods to existing types.
License: MIT License

TypeQuery
=========

.. note::

   Since Python 3.3 there's ``functools.singledispatch()`` function
   which does the similar work in the standard library.  We recommend
   you to use it instead of this.

   See also `PEP 443`_.

.. image:: https://drone.io/bitbucket.org/dahlia/typequery/status.png
   :alt: Build Status
   :target: https://drone.io/bitbucket.org/dahlia/typequery/latest

It provides a simple and dirty way to define generic methods to existing
types.  You can make overloaded methods using this.

.. _PEP 443: http://www.python.org/dev/peps/pep-0443/


Compatibility
-------------

TypeQuery does not depend on any non-standard libraries.  It works on
these environments:

- Python 2.5--2.7, 3.2--3.5
- CPython, Stackless, PyPy, Jython


Install
-------

Install using ``pip``::

    $ pip install TypeQuery


Example: JSON encoder
---------------------

::

    from typequery import GenericMethod
    from sys import version_info
    from re import sub
    from numbers import Real
    from collections import Mapping, Iterable

    if version_info.major > 2:
        basestring = string = str
    else:
        string = unicode

    json = GenericMethod('json')

    @json.of(type(None))
    def json(value):
        return 'null'

    @json.of(bool)
    def json(value):
        return 'true' if value else 'false'

    @json.of(Real)
    def json(value):
        return str(value)

    @json.of(string)
    def json(value):
        def escape(match):
            s = match.group(0)
            if s in ('\\', '"', '\b', '\f', '\n', '\r', '\t'):
                return '\\' + s
            n = ord(s)
            if n < 0x10000:
                return r'\u%04x' % n
            n -= 0x10000
            s1 = 0xd800 | ((n >> 10) & 0x3ff)
            s2 = 0xdc00 | (n & 0x3ff)
            return r'\u%04x\u%04x' % (s1, s2)
        return '"%s"' % sub(r'([\\"]|[^\ -~])', escape, value)

    @json.of(Iterable)
    def json(value):
        return '[%s]' % ', '.join(json(element) for element in value)

    @json.of(Mapping)
    def json(value):
        return '{%s}' % ', '.join('%s: %s' % (json(string(key)), json(value))
                                  for key, value in value.items())

And defined ``json`` function works like:

>>> json(123)
'123'
>>> json(True)
'true'
>>> json({'apple': 3, 'banana': 5, 'carrot': 1})
'{"apple": 3, "banana": 5, "carrot": 1}'

As the above shows, you can define type-aware instance methods to existing
types even including ABCs like ``collections.Iterable``.


Author and license
------------------

Written by `Hong Minhee <http://dahlia.kr/>`_.  Distributed under `MIT license
<http://minhee.mit-license.org/>`_.  You can find the source code from the
`Bitbucket repository <https://bitbucket.org/dahlia/typequery>`_::

    $ hg clone https://bitbucket.org/dahlia/typequery


Changelog
---------

Version 0.1.5
'''''''''''''

Released on June 23, 2016.

- Compatibility with recent Python versions: Python 3.3 to 3.5, and PyPy3.


Version 0.1.4
'''''''''''''

Released on October 18, 2012.

- Don't use bitbucket-distutils_ anymore to prevent several headaches
  related packaging and distribution.

.. _bitbucket-distutils: https://bitbucket.org/dahlia/bitbucket-distutils


Version 0.1.3
'''''''''''''

Released on August 29, 2012.

- Fixed a bug of handling multiple types by one function.
  [`#2 <https://bitbucket.org/dahlia/typequery/issue/2/>`_]


Version 0.1.2
'''''''''''''

Released on August 15, 2012.

- You can inherit existing generic methods using ``GenericMethod.inherit()``
  method.
- Added ``with_receiver`` option for ``GenericMethod.of()`` decorator and
  ``Decorator`` constructor.


Version 0.1.1
'''''''''''''

Released on May 22, 2012.

- Now it works well with abstract base classes other than ``abc.ABCMeta``.
- Fixed a bug of ``GenericMethod.clone()`` method.  It does not reflect
  cloned one's changes to the original anymore.
  [`#1 <https://bitbucket.org/dahlia/typequery/issue/1/>`_]


Version 0.1.0
'''''''''''''

Released on May 21, 2012.

- Initial release.