8555c078c370 — Gerald Klix (speedy) 6 years ago
SUM: Updated the documentation for the next release.
CHG: Bumped the version to 0.2.0.
5 files changed, 224 insertions(+), 15 deletions(-)

M docs/acknowledgements.rst
M docs/api.rst
M docs/conf.py
M docs/overview.rst
M setup.py
M docs/acknowledgements.rst +2 -2
@@ 1,9 1,9 @@ 
 Acknowledgements
 ================
 Guido van Rossum created the core of this package. I just renamed some things
-and added some convenience stuff. Thank you Guido!
+and added some^H^H^H^H oodles of convenience stuff. Thank you Guido!
 
 Copyright
 =========
 © 2006-2013 Python Software Foundation.
-© 2013-2017 Gerald Klix.
+© 2013-2018 Gerald Klix.

          
M docs/api.rst +199 -3
@@ 183,9 183,9 @@ or the :meth:`<generic>.method` method.
         def varfun1(tc: TC, o1: object, o2: object: o3: object, o4: object):
             return (tc,) + (o4, o3, o2, o1)
 
-    Overlaps of variadic method definitions are always resolved
-    towards the method with the explicitly specified types.
-
+    Overlaps of variadic method definitions with non-variadic method
+    definitions are always resolved towards the non-variadic method
+    with the explicitly specified types.
 
 .. decorator:: <generic>.method(implementation_function)
 

          
@@ 228,11 228,38 @@ or the :meth:`<generic>.method` method.
 
 Calling Other Multi-Methods of The Same Generic
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+:mod:`gf` implements two ways to calls other methods of
+the same generic.
+
+New Style of :class:`super` Calls
+.................................
+
+The new way of calling other methods with the same arity of the same
+generic (mis)uses the built-in :class:`super` type.
+
+:class:`super` can be used to define :func:`foo` for integers:
+
+     >>> @method()
+     ... def foo(an_integer: int):
+     ...     return foo(super(str, str(an_integer)))
+
+Calling :func:`foo` with an integer now works as expected:
+
+     >>> foo(42)
+     '<42>'
+
+Old Style of :class:`super` Calls
+.................................
+
+.. note:: This way of calling other methods of a generic
+          function is deprecated.
+
 As it is sometimes necessary with ordinary single dispatch methods
 to call methods defined in a base class, it it is sometimes
 necessary to reuse other implementations of a generic.
 For this purpose the generic has :meth:`super`-method.
 
+.. deprecated:: 0.2
 .. method:: <generic>.super(*types)(*arguments)
 
     :param type types: An optionally empty list of built-in types or

          
@@ 264,6 291,175 @@ For this purpose the generic has :meth:`
            are actually instances of `types`. This is consistent
            with Python's notion of duck typing.
 
+Dispatch on Instances
+~~~~~~~~~~~~~~~~~~~~~
+
+Since version 0.2 :mod:`gf`'s
+default dispatch algorithm dispatches on single instances, too:
+
+    >>> silly = generic('silly')
+    >>> @method()
+    ... def silly(bla: str):
+    ...     return '<S|' + bla + '|S>'
+
+Thus we can call :func:`silly` with a string:
+
+    >>> silly('Hello')
+    '<S|Hello|S>'
+
+But we can also define :func:`silly` for two integers:
+
+    >>> @method()
+    ... def silly(hitchhiker: 42, star_trek: 47):
+    ...     return 'Bingo'
+
+Now we can call :func:`silly` with exactly the right numbers:
+
+    >>> silly(42, 47)
+    'Bingo'
+
+But calling silly with others fails like this:
+
+    >>> silly(21, 21)
+    Traceback (most recent call last):
+    ...
+    NotImplementedError: Generic 'silly' has no implementation for type(s): builtins.int, builtins.int
+
+The old behavior can be achieved by using the dispatch type 
+:attr:`Dispatch.ON_CLASS`.
+
+    >>> from gf import Dispatch
+    >>> even_sillier = generic(Dispatch.ON_CLASS)
+    >>> @method()
+    ... def even_sillier(bla: str):
+    ...     return '<SS|' + bla + '|SS>'
+
+Thus we can call :func:`even_sillier` with a string:
+
+    >>> even_sillier('Hello')
+    '<SS|Hello|SS>'
+
+But we can't define :func:`even_sillier` for two integers:
+
+    >>> @method()
+    ... def even_sillier(hitchhiker: 42, star_trek: 47):
+    ...     return 'Bingo'
+    Traceback (most recent call last):
+    ...
+    TypeError: Can't dispatch on instances in state: Dispatch.ON_CLASS
+
+.. note:: The enumeration :class:`Dispatch` also has the option 
+          :attr:`ON_OBJECT`, which is the new default for generic functions.
+
+Class-Generics
+~~~~~~~~~~~~~~
+
+Since release 0.2 :mod:`gf` has some means to define the equivalent
+of a class function with generic functions. This capability is defined
+on a per :func:`generic` basis and not -- as one might expect -- on
+a per :func:`method` basis.
+
+The following example will explain this feature:
+
+    >>> cm = generic(
+    ...     'cm', 
+    ...     """A class method (sort of)""",
+    ...     Dispatch.ON_OBJECT_AND_CLASS_HIERARCHY)
+
+
+One now can add methods to :func:`cm` that dispatch on the class
+passed:
+
+    >>> @method()
+    ... def cm(integer: int):
+    ...     return 'Integer'
+    >>> @method()
+    ... def cm(string: str):
+    ...     return 'String'
+
+This way we can dispatch on classes like:
+
+    >>> cm(int)
+    'Integer'
+    >>> cm(str)
+    'String'
+    >>> cm(1)
+    'Integer'
+    >>> cm('Sepp')
+    'String'
+
+With the same dispatch type it is also possible to dispatch on instances:
+
+    >>> @method()
+    ... def cm(wow: 42):
+    ...     return 'Jackpot'
+    >>> cm(42)
+    'Jackpot'
+    >>> cm(4711)
+    'Integer'
+
+The normal -- and also the pre version 0.2 -- behavior is to dispatch
+on the type of an instance only:
+
+    >>> im = generic(
+    ...     'im', 
+    ...     """An instance method""",
+    ...     Dispatch.ON_OBJECT)
+
+
+One now can add methods to :func:`im` that dispatch on the class
+of an instance passed as argument:
+
+    >>> @method()
+    ... def im(integer: int):
+    ...     return 'Integer'
+    >>> @method()
+    ... def im(string: str):
+    ...     return 'String'
+
+But we can't dispatch on class arguments:
+
+    >>> im(int)
+    Traceback (most recent call last):
+    ...
+    NotImplementedError: Generic 'im' has no implementation for type(s): builtins.type
+    >>> im(str)
+    Traceback (most recent call last):
+    ...
+    NotImplementedError: Generic 'im' has no implementation for type(s): builtins.type
+    >>> im(1)
+    'Integer'
+    >>> im('Sepp')
+    'String'
+
+
+Since the type of class is :class:`type` we can write one method
+to dispatch on all classes:
+
+    >>> @method()
+    ... def im(cls: type):
+    ...     return 'Class'
+
+and get at least:
+
+    >>> im(int)
+    'Class'
+    >>> im(str)
+    'Class'
+
+
+
+As mentioned above, it is also possible to dispatch on instances 
+with the default dispatch type :attr:`Dispatch.ON_OBJECT`:
+
+    >>> @method()
+    ... def im(wow: 42):
+    ...     return 'Oh Baby'
+    >>> im(42)
+    'Oh Baby'
+    >>> im(4711)
+    'Integer'
+
 
 Advanced Usage
 --------------

          
M docs/conf.py +11 -6
@@ 28,7 28,12 @@ sys.path.insert(0, os.path.abspath(os.pa
 # Add any Sphinx extension module names here, as strings. They can be extensions
 # coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
 #o#extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.intersphinx', 'sphinx.ext.ifconfig', 'sphinx.ext.viewcode']
-extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.ifconfig', 'sphinx.ext.viewcode']
+extensions = [
+    'sphinx.ext.autodoc',
+    'sphinx.ext.doctest', 
+    'sphinx.ext.ifconfig',
+    'sphinx.ext.viewcode'
+]
 
 # Add any paths that contain templates here, relative to this directory.
 templates_path = ['_templates']

          
@@ 44,16 49,16 @@ master_doc = 'index'
 
 # General information about the project.
 project = 'gf'
-copyright = '2006-2013 PSF, 2013-2017 Gerald Klix'
+copyright = '2006-2013 PSF, 2013-2018 Gerald Klix'
 
 # The version info for the project you're documenting, acts as replacement for
 # |version| and |release|, also used in various other places throughout the
 # built documents.
 #
 # The short X.Y version.
-version = '0.2.0'
+version = '0.2'
 # The full version, including alpha/beta/rc tags.
-release = '0.2.0b'
+release = '0.2.0'
 
 # The language for content autogenerated by Sphinx. Refer to documentation
 # for a list of supported languages.

          
@@ 97,7 102,7 @@ exclude_patterns = ['_build']
 
 # The theme to use for HTML and HTML Help pages.  See the documentation for
 # a list of builtin themes.
-html_theme = 'default'
+html_theme = 'python_docs_theme'
 
 # Theme options are theme-specific and customize the look and feel of a theme
 # further.  For a list of options available for each theme, see the

          
@@ 258,7 263,7 @@ texinfo_documents = [
 epub_title = u'gf'
 epub_author = u'Gerald Klix'
 epub_publisher = u'Gerald Klix'
-epub_copyright = u'2013-2017, Gerald Klix'
+epub_copyright = u'2013-2018, Gerald Klix'
 
 # The language of the text. It defaults to the language option
 # or en if the language is not set.

          
M docs/overview.rst +8 -1
@@ 117,14 117,21 @@ Release 0.2.0
 
 The following was change in Release 0.2.0:
 
-  * Ported the whole module to Python 3.6. 
+  * Ported the whole module to Python 3.6 and Python 3.7. 
   * Exclusively uses `parameter annotations`_ to specify the types to dispatch on.
   * Added standard conforming default implementations for methods
     like :meth:`__add__`. All these methods now raise a proper
     `TypeError` instead of raising a `NotImplementedError`.
+  * Added some means to write generic functions that dispatch types only.
+    This is the generic function equivalent of a class-method.
+  * Added some means to dispatch on single objects.
+    This is the equivalent adding methods to class-instances [#]_.
 
 .. _parameter annotations: https://docs.python.org/3/reference/compound_stmts.html#grammar-token-parameter
 
+.. [#] Of course this is not possible with standard python classes
+       and their instances.
+
 Release 0.1.4
 ~~~~~~~~~~~~~
 

          
M setup.py +4 -3
@@ 25,8 25,8 @@ except IOError:
 
 sys.path.insert(0, "tests")
 
-setup(name="gf",
-      version='0.2.0b',
+setup(name="gf3",
+      version='0.2.0',
       description="A package with lisp-like generic functions for python 3.",
       long_description = long_description,
       keywords="generic-function multi-method",

          
@@ 35,6 35,7 @@ setup(name="gf",
             "Intended Audience :: Developers",
             "License :: OSI Approved :: Python Software Foundation License",
             "Operating System :: OS Independent",
+            "Programming Language :: Python :: 3.7",
             "Programming Language :: Python :: 3.6",
             "Programming Language :: Python :: 3 :: Only",
             "Programming Language :: Python :: Implementation",

          
@@ 43,7 44,7 @@ setup(name="gf",
       author="Gerald Klix",
       author_email="gf@klix.ch",
       packages=['gf'],
-      url="http://pypi.python.org/pypi/gf3",
+      url="https://pythonhosted.org/gf3/",
       zip_safe=True,
       test_suite="testgo",
       license="PSF",