Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-multipledispatch for openSUSE:Factory checked in at 2023-09-14 16:26:20 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-multipledispatch (Old) and /work/SRC/openSUSE:Factory/.python-multipledispatch.new.1766 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-multipledispatch" Thu Sep 14 16:26:20 2023 rev:6 rq:1111344 version:1.0.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-multipledispatch/python-multipledispatch.changes 2021-11-09 23:55:03.999966573 +0100 +++ /work/SRC/openSUSE:Factory/.python-multipledispatch.new.1766/python-multipledispatch.changes 2023-09-14 16:29:21.942512909 +0200 @@ -1,0 +2,7 @@ +Thu Sep 14 12:38:16 UTC 2023 - pgaj...@suse.com + +- version update to 1.0.0 + * no upstream changelog +- python-six is not required + +------------------------------------------------------------------- Old: ---- 0.6.0.tar.gz New: ---- 1.0.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-multipledispatch.spec ++++++ --- /var/tmp/diff_new_pack.b2Qjg0/_old 2023-09-14 16:29:23.230558923 +0200 +++ /var/tmp/diff_new_pack.b2Qjg0/_new 2023-09-14 16:29:23.234559066 +0200 @@ -1,7 +1,7 @@ # # spec file for package python-multipledispatch # -# Copyright (c) 2021 SUSE LLC +# Copyright (c) 2023 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -16,23 +16,19 @@ # -%{?!python_module:%define python_module() python-%{**} python3-%{**}} Name: python-multipledispatch -Version: 0.6.0 +Version: 1.0.0 Release: 0 Summary: Multiple dispatch in Python License: BSD-3-Clause Group: Development/Languages/Python URL: https://multiple-dispatch.readthedocs.io/ -Source: https://github.com/mrocklin/multipledispatch/archive/0.6.0.tar.gz +Source: https://github.com/mrocklin/multipledispatch/archive/%{version}.tar.gz BuildRequires: %{python_module pytest-benchmark} BuildRequires: %{python_module pytest} BuildRequires: %{python_module setuptools} -BuildRequires: %{python_module six} BuildRequires: fdupes BuildRequires: python-rpm-macros -Requires: python-six -BuildRoot: %{_tmppath}/%{name}-%{version}-build BuildArch: noarch %python_subpackages @@ -44,8 +40,7 @@ support. %prep -%setup -q -n multipledispatch-%{version} -rm multipledispatch/tests/test_dispatcher_3only.py +%autosetup -n multipledispatch-%{version} %build %python_build @@ -58,8 +53,7 @@ %pytest %files %{python_files} -%defattr(-,root,root,-) %doc README.rst %license LICENSE.txt -%{python_sitelib}/* +%{python_sitelib}/multipledispatch* ++++++ 0.6.0.tar.gz -> 1.0.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/multipledispatch-0.6.0/.github/workflows/pre-commit.yml new/multipledispatch-1.0.0/.github/workflows/pre-commit.yml --- old/multipledispatch-0.6.0/.github/workflows/pre-commit.yml 1970-01-01 01:00:00.000000000 +0100 +++ new/multipledispatch-1.0.0/.github/workflows/pre-commit.yml 2023-06-27 18:28:30.000000000 +0200 @@ -0,0 +1,18 @@ +name: Linting + +on: + push: + branches: main + pull_request: + branches: main + +jobs: + checks: + name: pre-commit hooks + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3.5.2 + - uses: actions/setup-python@v4 + with: + python-version: '3.9' + - uses: pre-commit/action@v3.0.0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/multipledispatch-0.6.0/.github/workflows/test.yaml new/multipledispatch-1.0.0/.github/workflows/test.yaml --- old/multipledispatch-0.6.0/.github/workflows/test.yaml 1970-01-01 01:00:00.000000000 +0100 +++ new/multipledispatch-1.0.0/.github/workflows/test.yaml 2023-06-27 18:28:30.000000000 +0200 @@ -0,0 +1,24 @@ +name: Multiple dispatch + +on: [push] + +jobs: + build: + + runs-on: ubuntu-latest + strategy: + matrix: + python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"] + + steps: + - uses: actions/checkout@v3 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + python -m pip install --upgrade pip pytest pytest-benchmark . + - name: Test with pytest + run: | + pytest diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/multipledispatch-0.6.0/.gitignore new/multipledispatch-1.0.0/.gitignore --- old/multipledispatch-0.6.0/.gitignore 2018-08-08 19:53:11.000000000 +0200 +++ new/multipledispatch-1.0.0/.gitignore 2023-06-27 18:28:30.000000000 +0200 @@ -2,3 +2,10 @@ *.egg-info/ .cache/ .pytest_cache/ + +# Virtualenv +/venv/ +/.venv/ + +# For CLion or PyCharm +/.idea/ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/multipledispatch-0.6.0/.pre-commit-config.yaml new/multipledispatch-1.0.0/.pre-commit-config.yaml --- old/multipledispatch-0.6.0/.pre-commit-config.yaml 1970-01-01 01:00:00.000000000 +0100 +++ new/multipledispatch-1.0.0/.pre-commit-config.yaml 2023-06-27 18:28:30.000000000 +0200 @@ -0,0 +1,45 @@ +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.4.0 + hooks: + - id: end-of-file-fixer + - id: debug-statements + - repo: https://github.com/MarcoGorelli/absolufy-imports + rev: v0.3.1 + hooks: + - id: absolufy-imports + name: absolufy-imports + - repo: https://github.com/pycqa/isort + rev: 5.12.0 + hooks: + - id: isort + language_version: python3 + - repo: https://github.com/asottile/pyupgrade + rev: v3.3.2 + hooks: + - id: pyupgrade + args: + - --py38-plus + - repo: https://github.com/psf/black + rev: 23.3.0 + hooks: + - id: black + language_version: python3 + exclude: versioneer.py + args: + - --target-version=py38 + - repo: https://github.com/pycqa/flake8 + rev: 6.0.0 + hooks: + - id: flake8 + language_version: python3 + additional_dependencies: + # NOTE: autoupdate does not pick up flake8-bugbear since it is a transitive + # dependency. Make sure to update flake8-bugbear manually on a regular basis. + - flake8-bugbear==22.8.23 + - repo: https://github.com/codespell-project/codespell + rev: v2.2.4 + hooks: + - id: codespell + types_or: [rst, markdown] + files: docs diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/multipledispatch-0.6.0/.travis.yml new/multipledispatch-1.0.0/.travis.yml --- old/multipledispatch-0.6.0/.travis.yml 2018-08-08 19:53:11.000000000 +0200 +++ new/multipledispatch-1.0.0/.travis.yml 1970-01-01 01:00:00.000000000 +0100 @@ -1,30 +0,0 @@ -language: python -python: - - "2.7" - - "3.3" - - "3.4" - - "3.5" - - "3.6" - - "3.7-dev" - - "pypy" - - "pypy3" - -install: - - pip install --upgrade pip - - pip install coverage - - pip install --upgrade pytest pytest-benchmark - -script: - - | - if [[ $(bc <<< "$TRAVIS_PYTHON_VERSION >= 3.3") -eq 1 ]]; then - py.test --doctest-modules multipledispatch - else - py.test --doctest-modules --ignore=multipledispatch/tests/test_dispatcher_3only.py multipledispatch - fi - -after_success: - - | - if [[ $TRAVIS_PYTHON_VERSION != 'pypy' ]]; then pip install coveralls; coveralls ; fi - -notifications: - email: false diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/multipledispatch-0.6.0/README.rst new/multipledispatch-1.0.0/README.rst --- old/multipledispatch-0.6.0/README.rst 2018-08-08 19:53:11.000000000 +0200 +++ new/multipledispatch-1.0.0/README.rst 2023-06-27 18:28:30.000000000 +0200 @@ -82,18 +82,8 @@ pip install multipledispatch -or - -:: - - easy_install multipledispatch - - -``multipledispatch`` supports Python 2.6+ and Python 3.2+ with a common -codebase. It is pure Python and requires only the small `six -<https://pypi.org/project/six/>`_ library as a dependency. - -It is, in short, a light weight dependency. +It is Pure-Python and depends only on the standard library. +It is a light weight dependency. License @@ -124,7 +114,7 @@ .. _`Clojure Protocols`: http://clojure.org/protocols .. _`Julia methods docs`: - https://julia.readthedocs.io/en/latest/manual/methods/ + https://docs.julialang.org/en/v1/manual/methods/ .. _`Karpinksi notebook: *The Design Impact of Multiple Dispatch*`: http://nbviewer.ipython.org/gist/StefanKarpinski/b8fe9dbb36c1427b9f22 .. _`Wikipedia article`: @@ -132,10 +122,10 @@ .. _`PEP 3124 - *Overloading, Generic Functions, Interfaces, and Adaptation*`: http://legacy.python.org/dev/peps/pep-3124/ -.. |Build Status| image:: https://travis-ci.org/mrocklin/multipledispatch.png +.. |Build Status| image:: https://travis-ci.org/mrocklin/multipledispatch.svg :target: https://travis-ci.org/mrocklin/multipledispatch -.. |Version Status| image:: https://pypip.in/v/multipledispatch/badge.png +.. |Version Status| image:: https://pypip.in/v/multipledispatch/badge.svg :target: https://img.shields.io/pypi/v/multipledispatch.svg -.. |Coverage Status| image:: https://coveralls.io/repos/mrocklin/multipledispatch/badge.png +.. |Coverage Status| image:: https://coveralls.io/repos/mrocklin/multipledispatch/badge.svg :target: https://coveralls.io/r/mrocklin/multipledispatch .. _License file: https://github.com/mrocklin/multipledispatch/blob/master/LICENSE.txt diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/multipledispatch-0.6.0/bench/test_simple.py new/multipledispatch-1.0.0/bench/test_simple.py --- old/multipledispatch-0.6.0/bench/test_simple.py 2018-08-08 19:53:11.000000000 +0200 +++ new/multipledispatch-1.0.0/bench/test_simple.py 2023-06-27 18:28:30.000000000 +0200 @@ -1,5 +1,3 @@ -import six - from multipledispatch import dispatch @@ -14,6 +12,6 @@ def test_simple(): - for i in six.moves.xrange(100000): + for _ in range(100000): assert isint(5) - assert not isint('a') + assert not isint("a") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/multipledispatch-0.6.0/multipledispatch/__init__.py new/multipledispatch-1.0.0/multipledispatch/__init__.py --- old/multipledispatch-0.6.0/multipledispatch/__init__.py 2018-08-08 19:53:11.000000000 +0200 +++ new/multipledispatch-1.0.0/multipledispatch/__init__.py 2023-06-27 18:28:30.000000000 +0200 @@ -1,5 +1,9 @@ from .core import dispatch -from .dispatcher import (Dispatcher, halt_ordering, restart_ordering, - MDNotImplementedError) +from .dispatcher import ( + Dispatcher, + halt_ordering, + restart_ordering, + MDNotImplementedError, +) -__version__ = '0.6.0' +__version__ = "0.6.0" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/multipledispatch-0.6.0/multipledispatch/conflict.py new/multipledispatch-1.0.0/multipledispatch/conflict.py --- old/multipledispatch-0.6.0/multipledispatch/conflict.py 2018-08-08 19:53:11.000000000 +0200 +++ new/multipledispatch-1.0.0/multipledispatch/conflict.py 2023-06-27 18:28:30.000000000 +0200 @@ -7,7 +7,7 @@ def supercedes(a, b): - """ A is consistent and strictly more specific than B """ + """A is consistent and strictly more specific than B""" if len(a) < len(b): # only case is if a is empty and b is variadic return not a and len(b) == 1 and isvariadic(b[-1]) @@ -37,7 +37,7 @@ def consistent(a, b): - """ It is possible for an argument list to satisfy both A and B """ + """It is possible for an argument list to satisfy both A and B""" # Need to check for empty args if not a: @@ -47,8 +47,7 @@ # Non-empty args check for mutual subclasses if len(a) == len(b): - return all(issubclass(aa, bb) or issubclass(bb, aa) - for aa, bb in zip(a, b)) + return all(issubclass(aa, bb) or issubclass(bb, aa) for aa, bb in zip(a, b)) else: p1 = 0 p2 = 0 @@ -66,36 +65,37 @@ p1 += 1 # We only need to check for variadic ends # Variadic types are guaranteed to be the last element - return (isvariadic(cur_a) and p2 == len(b) or - isvariadic(cur_b) and p1 == len(a)) + return isvariadic(cur_a) and p2 == len(b) or isvariadic(cur_b) and p1 == len(a) def ambiguous(a, b): - """ A is consistent with B but neither is strictly more specific """ + """A is consistent with B but neither is strictly more specific""" return consistent(a, b) and not (supercedes(a, b) or supercedes(b, a)) def ambiguities(signatures): - """ All signature pairs such that A is ambiguous with B """ + """All signature pairs such that A is ambiguous with B""" signatures = list(map(tuple, signatures)) - return set((a, b) for a in signatures for b in signatures - if hash(a) < hash(b) - and ambiguous(a, b) - and not any(supercedes(c, a) and supercedes(c, b) - for c in signatures)) + return set( + (a, b) + for a in signatures + for b in signatures + if hash(a) < hash(b) + and ambiguous(a, b) + and not any(supercedes(c, a) and supercedes(c, b) for c in signatures) + ) def super_signature(signatures): - """ A signature that would break ambiguities """ + """A signature that would break ambiguities""" n = len(signatures[0]) assert all(len(s) == n for s in signatures) - return [max([type.mro(sig[i]) for sig in signatures], key=len)[0] - for i in range(n)] + return [max([type.mro(sig[i]) for sig in signatures], key=len)[0] for i in range(n)] def edge(a, b, tie_breaker=hash): - """ A should be checked before B + """A should be checked before B Tie broken by tie_breaker, defaults to ``hash`` """ @@ -107,7 +107,7 @@ def ordering(signatures): - """ A sane ordering of signatures to check, first to last + """A sane ordering of signatures to check, first to last Topoological sort of edges as given by ``edge`` and ``supercedes`` """ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/multipledispatch-0.6.0/multipledispatch/core.py new/multipledispatch-1.0.0/multipledispatch/core.py --- old/multipledispatch-0.6.0/multipledispatch/core.py 2018-08-08 19:53:11.000000000 +0200 +++ new/multipledispatch-1.0.0/multipledispatch/core.py 2023-06-27 18:28:30.000000000 +0200 @@ -1,4 +1,5 @@ import inspect +import sys from .dispatcher import Dispatcher, MethodDispatcher, ambiguity_warn @@ -6,7 +7,7 @@ def dispatch(*types, **kwargs): - """ Dispatch function on the types of the inputs + """Dispatch function on the types of the inputs Supports dispatch on all non-keyword arguments. @@ -48,11 +49,11 @@ ... def __init__(self, datum): ... self.data = [datum] """ - namespace = kwargs.get('namespace', global_namespace) + namespace = kwargs.get("namespace", global_namespace) types = tuple(types) - def _(func): + def _df(func): name = func.__name__ if ismethod(func): @@ -67,18 +68,22 @@ dispatcher.add(types, func) return dispatcher - return _ + + return _df def ismethod(func): - """ Is func a method? + """Is func a method? Note that this has to work as the method is defined but before the class is defined. At this stage methods look like functions. """ if hasattr(inspect, "signature"): signature = inspect.signature(func) - return signature.parameters.get('self', None) is not None + return signature.parameters.get("self", None) is not None else: - spec = inspect.getargspec(func) - return spec and spec.args and spec.args[0] == 'self' + if sys.version_info.major < 3: + spec = inspect.getargspec(func) + else: + spec = inspect.getfullargspec(func) + return spec and spec.args and spec.args[0] == "self" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/multipledispatch-0.6.0/multipledispatch/dispatcher.py new/multipledispatch-1.0.0/multipledispatch/dispatcher.py --- old/multipledispatch-0.6.0/multipledispatch/dispatcher.py 2018-08-08 19:53:11.000000000 +0200 +++ new/multipledispatch-1.0.0/multipledispatch/dispatcher.py 2023-06-27 18:28:30.000000000 +0200 @@ -7,11 +7,11 @@ class MDNotImplementedError(NotImplementedError): - """ A NotImplementedError for multiple dispatch """ + """A NotImplementedError for multiple dispatch""" def ambiguity_warn(dispatcher, ambiguities): - """ Raise warning when ambiguity is detected + """Raise warning when ambiguity is detected Parameters ---------- @@ -28,21 +28,19 @@ def halt_ordering(): - """Deprecated interface to temporarily disable ordering. - """ + """Deprecated interface to temporarily disable ordering.""" warn( - 'halt_ordering is deprecated, you can safely remove this call.', + "halt_ordering is deprecated, you can safely remove this call.", DeprecationWarning, ) def restart_ordering(on_ambiguity=ambiguity_warn): - """Deprecated interface to temporarily resume ordering. - """ + """Deprecated interface to temporarily resume ordering.""" warn( - 'restart_ordering is deprecated, if you would like to eagerly order' - 'the dispatchers, you should call the ``reorder()`` method on each' - ' dispatcher.', + "restart_ordering is deprecated, if you would like to eagerly order" + "the dispatchers, you should call the ``reorder()`` method on each" + " dispatcher.", DeprecationWarning, ) @@ -96,7 +94,7 @@ class Dispatcher(object): - """ Dispatch methods based on type signature + """Dispatch methods based on type signature Use ``dispatch`` to add implementations @@ -117,7 +115,8 @@ >>> f(3.0) 2.0 """ - __slots__ = '__name__', 'name', 'funcs', '_ordering', '_cache', 'doc' + + __slots__ = "__name__", "name", "funcs", "_ordering", "_cache", "doc" def __init__(self, name, doc=None): self.name = self.__name__ = name @@ -127,7 +126,7 @@ self._cache = {} def register(self, *types, **kwargs): - """ register dispatcher with new implementation + """register dispatcher with new implementation >>> f = Dispatcher('f') >>> @f.register(int) @@ -152,10 +151,12 @@ >>> f([1, 2, 3]) [3, 2, 1] """ - def _(func): + + def _df(func): self.add(types, func, **kwargs) return func - return _ + + return _df @classmethod def get_func_params(cls, func): @@ -165,26 +166,25 @@ @classmethod def get_func_annotations(cls, func): - """ get annotations of function positional parameters - """ + """get annotations of function positional parameters""" params = cls.get_func_params(func) if params: Parameter = inspect.Parameter - params = (param for param in params - if param.kind in - (Parameter.POSITIONAL_ONLY, - Parameter.POSITIONAL_OR_KEYWORD)) - - annotations = tuple( - param.annotation - for param in params) + params = ( + param + for param in params + if param.kind + in (Parameter.POSITIONAL_ONLY, Parameter.POSITIONAL_OR_KEYWORD) + ) + + annotations = tuple(param.annotation for param in params) if all(ann is not Parameter.empty for ann in annotations): return annotations def add(self, signature, func): - """ Add new types/method pair to dispatcher + """Add new types/method pair to dispatcher >>> D = Dispatcher('add') >>> D.add((int, int), lambda x, y: x + y) @@ -217,25 +217,25 @@ for index, typ in enumerate(signature, start=1): if not isinstance(typ, (type, list)): - str_sig = ', '.join(c.__name__ if isinstance(c, type) - else str(c) for c in signature) - raise TypeError("Tried to dispatch on non-type: %s\n" - "In signature: <%s>\n" - "In function: %s" % - (typ, str_sig, self.name)) + str_sig = ", ".join( + c.__name__ if isinstance(c, type) else str(c) for c in signature + ) + raise TypeError( + "Tried to dispatch on non-type: %s\n" + "In signature: <%s>\n" + "In function: %s" % (typ, str_sig, self.name) + ) # handle variadic signatures if isinstance(typ, list): if index != len(signature): - raise TypeError( - 'Variadic signature must be the last element' - ) + raise TypeError("Variadic signature must be the last element") if len(typ) != 1: raise TypeError( - 'Variadic signature must contain exactly one element. ' - 'To use a variadic union type place the desired types ' - 'inside of a tuple, e.g., [(int, str)]' + "Variadic signature must contain exactly one element. " + "To use a variadic union type place the desired types " + "inside of a tuple, e.g., [(int, str)]" ) new_signature.append(Variadic[typ[0]]) else: @@ -271,8 +271,9 @@ func = self.dispatch(*types) if not func: raise NotImplementedError( - 'Could not find signature for %s: <%s>' % - (self.name, str_signature(types))) + "Could not find signature for %s: <%s>" + % (self.name, str_signature(types)) + ) self._cache[types] = func try: return func(*args, **kwargs) @@ -288,13 +289,16 @@ raise NotImplementedError( "Matching functions for " - "%s: <%s> found, but none completed successfully" % ( - self.name, str_signature(types), + "%s: <%s> found, but none completed successfully" + % ( + self.name, + str_signature(types), ), ) def __str__(self): return "<dispatched %s>" % self.name + __repr__ = __str__ def dispatch(self, *types): @@ -328,7 +332,6 @@ return None def dispatch_iter(self, *types): - n = len(types) for signature in self.ordering: if len(signature) == n and all(map(issubclass, types, signature)): @@ -340,23 +343,21 @@ yield result def resolve(self, types): - """ Deterimine appropriate implementation for this type signature + """Deterimine appropriate implementation for this type signature .. deprecated:: 0.4.4 Use ``dispatch(*types)`` instead """ - warn("resolve() is deprecated, use dispatch(*types)", - DeprecationWarning) + warn("resolve() is deprecated, use dispatch(*types)", DeprecationWarning) return self.dispatch(*types) def __getstate__(self): - return {'name': self.name, - 'funcs': self.funcs} + return {"name": self.name, "funcs": self.funcs} def __setstate__(self, d): - self.name = d['name'] - self.funcs = d['funcs'] + self.name = d["name"] + self.funcs = d["funcs"] self._ordering = ordering(self.funcs) self._cache = dict() @@ -371,23 +372,23 @@ for sig in self.ordering[::-1]: func = self.funcs[sig] if func.__doc__: - s = 'Inputs: <%s>\n' % str_signature(sig) - s += '-' * len(s) + '\n' + s = "Inputs: <%s>\n" % str_signature(sig) + s += "-" * len(s) + "\n" s += func.__doc__.strip() docs.append(s) else: other.append(str_signature(sig)) if other: - docs.append('Other signatures:\n ' + '\n '.join(other)) + docs.append("Other signatures:\n " + "\n ".join(other)) - return '\n\n'.join(docs) + return "\n\n".join(docs) def _help(self, *args): return self.dispatch(*map(type, args)).__doc__ def help(self, *args, **kwargs): - """ Print docstring for the function corresponding to inputs """ + """Print docstring for the function corresponding to inputs""" print(self._help(*args)) def _source(self, *args): @@ -397,23 +398,24 @@ return source(func) def source(self, *args, **kwargs): - """ Print source code for the function corresponding to inputs """ + """Print source code for the function corresponding to inputs""" print(self._source(*args)) def source(func): - s = 'File: %s\n\n' % inspect.getsourcefile(func) + s = "File: %s\n\n" % inspect.getsourcefile(func) s = s + inspect.getsource(func) return s class MethodDispatcher(Dispatcher): - """ Dispatch methods based on type signature + """Dispatch methods based on type signature See Also: Dispatcher """ - __slots__ = ('obj', 'cls') + + __slots__ = ("obj", "cls") @classmethod def get_func_params(cls, func): @@ -430,28 +432,33 @@ types = tuple([type(arg) for arg in args]) func = self.dispatch(*types) if not func: - raise NotImplementedError('Could not find signature for %s: <%s>' % - (self.name, str_signature(types))) + raise NotImplementedError( + "Could not find signature for %s: <%s>" + % (self.name, str_signature(types)) + ) return func(self.obj, *args, **kwargs) def str_signature(sig): - """ String representation of type signature + """String representation of type signature >>> str_signature((int, float)) 'int, float' """ - return ', '.join(cls.__name__ for cls in sig) + return ", ".join(cls.__name__ for cls in sig) def warning_text(name, amb): - """ The text for ambiguity warnings """ + """The text for ambiguity warnings""" text = "\nAmbiguities exist in dispatched function %s\n\n" % (name) text += "The following signatures may result in ambiguous behavior:\n" for pair in amb: - text += "\t" + \ - ', '.join('[' + str_signature(s) + ']' for s in pair) + "\n" + text += "\t" + ", ".join("[" + str_signature(s) + "]" for s in pair) + "\n" text += "\n\nConsider making the following additions:\n\n" - text += '\n\n'.join(['@dispatch(' + str_signature(super_signature(s)) - + ')\ndef %s(...)' % name for s in amb]) + text += "\n\n".join( + [ + "@dispatch(" + str_signature(super_signature(s)) + ")\ndef %s(...)" % name + for s in amb + ] + ) return text diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/multipledispatch-0.6.0/multipledispatch/tests/test_benchmark.py new/multipledispatch-1.0.0/multipledispatch/tests/test_benchmark.py --- old/multipledispatch-0.6.0/multipledispatch/tests/test_benchmark.py 2018-08-08 19:53:11.000000000 +0200 +++ new/multipledispatch-1.0.0/multipledispatch/tests/test_benchmark.py 2023-06-27 18:28:30.000000000 +0200 @@ -17,7 +17,7 @@ return False -@pytest.mark.parametrize("val", [1, 'a']) +@pytest.mark.parametrize("val", [1, "a"]) def test_benchmark_call_single_dispatch(benchmark, val): benchmark(isint, val) @@ -49,6 +49,6 @@ return sum(args) mul(4, 5) - mul('x', 5) - mul(1, 2, 3., 4., 5.) + mul("x", 5) + mul(1, 2, 3.0, 4.0, 5.0) mul(1, 2, 3, 4, 5) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/multipledispatch-0.6.0/multipledispatch/tests/test_conflict.py new/multipledispatch-1.0.0/multipledispatch/tests/test_conflict.py --- old/multipledispatch-0.6.0/multipledispatch/tests/test_conflict.py 2018-08-08 19:53:11.000000000 +0200 +++ new/multipledispatch-1.0.0/multipledispatch/tests/test_conflict.py 2023-06-27 18:28:30.000000000 +0200 @@ -1,11 +1,25 @@ -from multipledispatch.conflict import (supercedes, ordering, ambiguities, - ambiguous, super_signature, consistent) +from multipledispatch.conflict import ( + supercedes, + ordering, + ambiguities, + ambiguous, + super_signature, + consistent, +) from multipledispatch.dispatcher import Variadic -class A(object): pass -class B(A): pass -class C(object): pass +class A(object): + pass + + +class B(A): + pass + + +class C(object): + pass + def _test_supercedes(a, b): assert supercedes(a, b) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/multipledispatch-0.6.0/multipledispatch/tests/test_core.py new/multipledispatch-1.0.0/multipledispatch/tests/test_core.py --- old/multipledispatch-0.6.0/multipledispatch/tests/test_core.py 2018-08-08 19:53:11.000000000 +0200 +++ new/multipledispatch-1.0.0/multipledispatch/tests/test_core.py 2023-06-27 18:28:30.000000000 +0200 @@ -25,7 +25,7 @@ assert g(1) == 3 assert f(1.0) == 0 - assert raises(NotImplementedError, lambda: f('hello')) + assert raises(NotImplementedError, lambda: f("hello")) def test_multipledispatch(benchmark): @@ -41,25 +41,38 @@ assert f(1.0, 2.0) == -1.0 -class A(object): pass -class B(object): pass -class C(A): pass -class D(C): pass -class E(C): pass +class A(object): + pass + + +class B(object): + pass + + +class C(A): + pass + + +class D(C): + pass + + +class E(C): + pass def test_inheritance(): @dispatch(A) def f(x): - return 'a' + return "a" @dispatch(B) def f(x): - return 'b' + return "b" - assert f(A()) == 'a' - assert f(B()) == 'b' - assert f(C()) == 'a' + assert f(A()) == "a" + assert f(B()) == "b" + assert f(C()) == "a" def test_inheritance_and_multiple_dispatch(): @@ -144,10 +157,12 @@ def foo(x): return 1 + foo1 = orig_dispatch(int, namespace=ns1)(foo) def foo(x): return 2 + foo2 = orig_dispatch(int, namespace=ns2)(foo) assert foo1(0) == 1 @@ -181,7 +196,6 @@ def g(self, x): return x + 3 - foo = Foo() assert foo.f(1) == 2 assert foo.f(1.0) == 0.0 @@ -198,7 +212,6 @@ def f(x, y): return 2 - foo = Foo() assert foo.f(A(), A()) == 1 assert foo.f(A(), C()) == 2 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/multipledispatch-0.6.0/multipledispatch/tests/test_dispatcher.py new/multipledispatch-1.0.0/multipledispatch/tests/test_dispatcher.py --- old/multipledispatch-0.6.0/multipledispatch/tests/test_dispatcher.py 2018-08-08 19:53:11.000000000 +0200 +++ new/multipledispatch-1.0.0/multipledispatch/tests/test_dispatcher.py 2023-06-27 18:28:30.000000000 +0200 @@ -1,8 +1,10 @@ - import warnings -from multipledispatch.dispatcher import (Dispatcher, MDNotImplementedError, - MethodDispatcher) +from multipledispatch.dispatcher import ( + Dispatcher, + MDNotImplementedError, + MethodDispatcher, +) from multipledispatch.conflict import ambiguities from multipledispatch.utils import raises @@ -20,7 +22,7 @@ def test_dispatcher(): - f = Dispatcher('f') + f = Dispatcher("f") f.add((int,), inc) f.add((float,), dec) @@ -34,7 +36,7 @@ def test_union_types(): - f = Dispatcher('f') + f = Dispatcher("f") f.register((int, float))(inc) assert f(1) == 2 @@ -42,7 +44,7 @@ def test_dispatcher_as_decorator(): - f = Dispatcher('f') + f = Dispatcher("f") @f.register(int) def inc(x): @@ -57,9 +59,8 @@ def test_register_instance_method(): - class Test(object): - __init__ = MethodDispatcher('f') + __init__ = MethodDispatcher("f") @__init__.register(list) def _init_list(self, data): @@ -75,7 +76,7 @@ def test_on_ambiguity(): - f = Dispatcher('f') + f = Dispatcher("f") def identity(x): return x @@ -95,72 +96,69 @@ def test_serializable(): - f = Dispatcher('f') + f = Dispatcher("f") f.add((int,), inc) f.add((float,), dec) f.add((object,), identity) import pickle + assert isinstance(pickle.dumps(f), (str, bytes)) g = pickle.loads(pickle.dumps(f)) assert g(1) == 2 assert g(1.0) == 0.0 - assert g('hello') == 'hello' + assert g("hello") == "hello" def test_raise_error_on_non_class(): - f = Dispatcher('f') + f = Dispatcher("f") assert raises(TypeError, lambda: f.add((1,), inc)) def test_docstring(): - def one(x, y): - """ Docstring number one """ + """Docstring number one""" return x + y def two(x, y): - """ Docstring number two """ + """Docstring number two""" return x + y def three(x, y): return x + y - master_doc = 'Doc of the multimethod itself' + master_doc = "Doc of the multimethod itself" - f = Dispatcher('f', doc=master_doc) + f = Dispatcher("f", doc=master_doc) f.add((object, object), one) f.add((int, int), two) f.add((float, float), three) assert one.__doc__.strip() in f.__doc__ assert two.__doc__.strip() in f.__doc__ - assert ( - f.__doc__.find(one.__doc__.strip()) < - f.__doc__.find(two.__doc__.strip()) - ) - assert 'object, object' in f.__doc__ + assert f.__doc__.find(one.__doc__.strip()) < f.__doc__.find(two.__doc__.strip()) + assert "object, object" in f.__doc__ assert master_doc in f.__doc__ def test_help(): def one(x, y): - """ Docstring number one """ + """Docstring number one""" return x + y def two(x, y): - """ Docstring number two """ + """Docstring number two""" return x + y def three(x, y): - """ Docstring number three """ + """Docstring number three""" return x + y - master_doc = 'Doc of the multimethod itself' + master_doc = "Doc of the multimethod itself" - f = Dispatcher('f', doc=master_doc) + f = Dispatcher("f", doc=master_doc) f.add((object, object), one) f.add((int, int), two) f.add((float, float), three) @@ -171,36 +169,36 @@ def test_source(): def one(x, y): - """ Docstring number one """ + """Docstring number one""" return x + y def two(x, y): - """ Docstring number two """ + """Docstring number two""" return x - y - master_doc = 'Doc of the multimethod itself' + master_doc = "Doc of the multimethod itself" - f = Dispatcher('f', doc=master_doc) + f = Dispatcher("f", doc=master_doc) f.add((int, int), one) f.add((float, float), two) - assert 'x + y' in f._source(1, 1) - assert 'x - y' in f._source(1.0, 1.0) + assert "x + y" in f._source(1, 1) + assert "x - y" in f._source(1.0, 1.0) def test_source_raises_on_missing_function(): - f = Dispatcher('f') + f = Dispatcher("f") assert raises(TypeError, lambda: f.source(1)) def test_no_implementations(): - f = Dispatcher('f') - assert raises(NotImplementedError, lambda: f('hello')) + f = Dispatcher("f") + assert raises(NotImplementedError, lambda: f("hello")) def test_register_stacking(): - f = Dispatcher('f') + f = Dispatcher("f") @f.register(list) @f.register(tuple) @@ -210,12 +208,12 @@ assert f((1, 2, 3)) == (3, 2, 1) assert f([1, 2, 3]) == [3, 2, 1] - assert raises(NotImplementedError, lambda: f('hello')) - assert rev('hello') == 'olleh' + assert raises(NotImplementedError, lambda: f("hello")) + assert rev("hello") == "olleh" def test_dispatch_method(): - f = Dispatcher('f') + f = Dispatcher("f") @f.register(list) def rev(x): @@ -234,27 +232,27 @@ def test_not_implemented(): - f = Dispatcher('f') + f = Dispatcher("f") @f.register(object) def _1(x): - return 'default' + return "default" @f.register(int) def _2(x): if x % 2 == 0: - return 'even' + return "even" else: raise MDNotImplementedError() - assert f('hello') == 'default' # default behavior - assert f(2) == 'even' # specialized behavior - assert f(3) == 'default' # fall back to default behavior + assert f("hello") == "default" # default behavior + assert f(2) == "even" # specialized behavior + assert f(3) == "default" # fall back to default behavior assert raises(NotImplementedError, lambda: f(1, 2)) def test_not_implemented_error(): - f = Dispatcher('f') + f = Dispatcher("f") @f.register(float) def _(a): @@ -264,17 +262,17 @@ def test_vararg_not_last_element_of_signature(): - f = Dispatcher('f') + f = Dispatcher("f") assert raises(TypeError, lambda: f.register([float], str)(lambda: None)) def test_vararg_has_multiple_elements(): - f = Dispatcher('f') + f = Dispatcher("f") assert raises(TypeError, lambda: f.register([float, str])(lambda: None)) def test_vararg_dispatch_simple(): - f = Dispatcher('f') + f = Dispatcher("f") @f.register([float]) def _1(*args): @@ -285,7 +283,7 @@ def test_vararg_dispatch_ambiguity(): - f = Dispatcher('f') + f = Dispatcher("f") @f.register(float, object, [int]) def _1(a, b, *args): @@ -299,7 +297,7 @@ def test_vararg_dispatch_ambiguity_in_variadic(): - f = Dispatcher('f') + f = Dispatcher("f") @f.register(float, [object]) def _1(a, b, *args): @@ -313,93 +311,93 @@ def test_vararg_dispatch_multiple_types_explicit_args(): - f = Dispatcher('f') + f = Dispatcher("f") @f.register(str, [float]) def _1(a, *b): return (a, b) - result = f('a', 1.0, 2.0, 3.0) - assert result == ('a', (1.0, 2.0, 3.0)) + result = f("a", 1.0, 2.0, 3.0) + assert result == ("a", (1.0, 2.0, 3.0)) def test_vararg_dispatch_multiple_implementations(): - f = Dispatcher('f') + f = Dispatcher("f") @f.register(str, [float]) def _1(a, *b): - return 'mixed_string_floats' + return "mixed_string_floats" @f.register([float]) def _2(*b): - return 'floats' + return "floats" @f.register([str]) def _3(*strings): - return 'strings' + return "strings" - assert f('a', 1.0, 2.0) == 'mixed_string_floats' - assert f(1.0, 2.0, 3.14) == 'floats' - assert f('a', 'b', 'c') == 'strings' + assert f("a", 1.0, 2.0) == "mixed_string_floats" + assert f(1.0, 2.0, 3.14) == "floats" + assert f("a", "b", "c") == "strings" def test_vararg_dispatch_unions(): - f = Dispatcher('f') + f = Dispatcher("f") @f.register(str, [(int, float)]) def _1(a, *b): - return 'mixed_string_ints_floats' + return "mixed_string_ints_floats" @f.register([str]) def _2(*strings): - return 'strings' + return "strings" @f.register([(str, int)]) def _3(*strings_ints): - return 'mixed_strings_ints' + return "mixed_strings_ints" @f.register([object]) def _4(*objects): - return 'objects' + return "objects" - assert f('a', 1.0, 7, 2.0, 11) == 'mixed_string_ints_floats' - assert f('a', 'b', 'c') == 'strings' - assert f('a', 1, 'b', 2) == 'mixed_strings_ints' - assert f([], (), {}) == 'objects' + assert f("a", 1.0, 7, 2.0, 11) == "mixed_string_ints_floats" + assert f("a", "b", "c") == "strings" + assert f("a", 1, "b", 2) == "mixed_strings_ints" + assert f([], (), {}) == "objects" def test_vararg_no_args(): - f = Dispatcher('f') + f = Dispatcher("f") @f.register([str]) def _1(*strings): - return 'strings' + return "strings" - assert f() == 'strings' + assert f() == "strings" def test_vararg_no_args_failure(): - f = Dispatcher('f') + f = Dispatcher("f") @f.register(str, [str]) def _2(*strings): - return 'strings' + return "strings" assert raises(NotImplementedError, f) -def test_vararg_no_args_failure(): - f = Dispatcher('f') +def test_vararg_no_args_failure_2(): + f = Dispatcher("f") @f.register([str]) def _2(*strings): - return 'strings' + return "strings" - assert raises(NotImplementedError, lambda: f('a', 'b', 1)) + assert raises(NotImplementedError, lambda: f("a", "b", 1)) def test_vararg_ordering(): - f = Dispatcher('f') + f = Dispatcher("f") @f.register(str, int, [object]) def _1(string, integer, *objects): @@ -413,11 +411,11 @@ def _3(*objects): return 3 - assert f('a', 1) == 1 - assert f('a', 1, ['a']) == 1 - assert f('a', 1, 'a') == 1 - assert f('a', 'a') == 2 - assert f('a') == 2 - assert f('a', ['a']) == 2 + assert f("a", 1) == 1 + assert f("a", 1, ["a"]) == 1 + assert f("a", 1, "a") == 1 + assert f("a", "a") == 2 + assert f("a") == 2 + assert f("a", ["a"]) == 2 assert f(1) == 3 assert f() == 3 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/multipledispatch-0.6.0/multipledispatch/tests/test_dispatcher_3only.py new/multipledispatch-1.0.0/multipledispatch/tests/test_dispatcher_3only.py --- old/multipledispatch-0.6.0/multipledispatch/tests/test_dispatcher_3only.py 2018-08-08 19:53:11.000000000 +0200 +++ new/multipledispatch-1.0.0/multipledispatch/tests/test_dispatcher_3only.py 2023-06-27 18:28:30.000000000 +0200 @@ -7,7 +7,7 @@ def test_function_annotation_register(): - f = Dispatcher('f') + f = Dispatcher("f") @f.register() def inc(x: int): @@ -48,12 +48,12 @@ assert inc(1) == 3 assert inc(1.0) == -1.0 - assert namespace['inc'] == inc + assert namespace["inc"] == inc assert set(inc.funcs.keys()) == set([(int,), (float,)]) def test_method_annotations(): - class Foo(): + class Foo: @dispatch() def f(self, x: int): return x + 1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/multipledispatch-0.6.0/multipledispatch/tests/test_variadic.py new/multipledispatch-1.0.0/multipledispatch/tests/test_variadic.py --- old/multipledispatch-0.6.0/multipledispatch/tests/test_variadic.py 2018-08-08 19:53:11.000000000 +0200 +++ new/multipledispatch-1.0.0/multipledispatch/tests/test_variadic.py 2023-06-27 18:28:30.000000000 +0200 @@ -1,9 +1,16 @@ from multipledispatch.variadic import isvariadic, Variadic -class A(object): pass -class B(A): pass -class C(object): pass +class A(object): + pass + + +class B(A): + pass + + +class C(object): + pass def test_is_variadic(): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/multipledispatch-0.6.0/multipledispatch/utils.py new/multipledispatch-1.0.0/multipledispatch/utils.py --- old/multipledispatch-0.6.0/multipledispatch/utils.py 2018-08-08 19:53:11.000000000 +0200 +++ new/multipledispatch-1.0.0/multipledispatch/utils.py 2023-06-27 18:28:30.000000000 +0200 @@ -31,7 +31,7 @@ # Taken from theano/theano/gof/sched.py # Avoids licensing issues because this was written by Matthew Rocklin def _toposort(edges): - """ Topological sort algorithm by Kahn [1] - O(nodes + vertices) + """Topological sort algorithm by Kahn [1] - O(nodes + vertices) inputs: edges - a dict of the form {a: {b, c}} where b and c depend on a @@ -48,8 +48,7 @@ [2] http://en.wikipedia.org/wiki/Toposort#Algorithms """ incoming_edges = reverse_dict(edges) - incoming_edges = OrderedDict((k, set(val)) - for k, val in incoming_edges.items()) + incoming_edges = OrderedDict((k, set(val)) for k, val in incoming_edges.items()) S = OrderedDict.fromkeys(v for v in edges if v not in incoming_edges) L = [] @@ -82,14 +81,14 @@ result = OrderedDict() for key in d: for val in d[key]: - result[val] = result.get(val, tuple()) + (key, ) + result[val] = result.get(val, tuple()) + (key,) return result # Taken from toolz # Avoids licensing issues because this version was authored by Matthew Rocklin def groupby(func, seq): - """ Group a collection by a key function + """Group a collection by a key function >>> names = ['Alice', 'Bob', 'Charlie', 'Dan', 'Edith', 'Frank'] >>> groupby(len, names) # doctest: +SKIP @@ -136,4 +135,4 @@ except AttributeError: if len(type) == 1: return typename(*type) - return '(%s)' % ', '.join(map(typename, type)) + return "(%s)" % ", ".join(map(typename, type)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/multipledispatch-0.6.0/multipledispatch/variadic.py new/multipledispatch-1.0.0/multipledispatch/variadic.py --- old/multipledispatch-0.6.0/multipledispatch/variadic.py 2018-08-08 19:53:11.000000000 +0200 +++ new/multipledispatch-1.0.0/multipledispatch/variadic.py 2023-06-27 18:28:30.000000000 +0200 @@ -1,13 +1,10 @@ -import six - -from .utils import typename +from multipledispatch.utils import typename class VariadicSignatureType(type): # checking if subclass is a subclass of self def __subclasscheck__(self, subclass): - other_type = (subclass.variadic_type if isvariadic(subclass) - else (subclass,)) + other_type = subclass.variadic_type if isvariadic(subclass) else (subclass,) return subclass is self or all( issubclass(other, self.variadic_type) for other in other_type ) @@ -26,8 +23,7 @@ bool Whether or not `other` is equal to `self` """ - return (isvariadic(other) and - set(self.variadic_type) == set(other.variadic_type)) + return isvariadic(other) and set(self.variadic_type) == set(other.variadic_type) def __hash__(self): return hash((type(self), frozenset(self.variadic_type))) @@ -61,21 +57,24 @@ generate a new type for Variadic signatures. See the Variadic class for examples of how this behaves. """ + def __getitem__(self, variadic_type): if not (isinstance(variadic_type, (type, tuple)) or type(variadic_type)): - raise ValueError("Variadic types must be type or tuple of types" - " (Variadic[int] or Variadic[(int, float)]") + raise ValueError( + "Variadic types must be type or tuple of types" + " (Variadic[int] or Variadic[(int, float)]" + ) if not isinstance(variadic_type, tuple): - variadic_type = variadic_type, + variadic_type = (variadic_type,) return VariadicSignatureType( - 'Variadic[%s]' % typename(variadic_type), + "Variadic[%s]" % typename(variadic_type), (), - dict(variadic_type=variadic_type, __slots__=()) + dict(variadic_type=variadic_type, __slots__=()), ) -class Variadic(six.with_metaclass(VariadicSignatureMeta)): +class Variadic(metaclass=VariadicSignatureMeta): """A class whose getitem method can be used to generate a new type representing a specific variadic signature. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/multipledispatch-0.6.0/setup.cfg new/multipledispatch-1.0.0/setup.cfg --- old/multipledispatch-0.6.0/setup.cfg 1970-01-01 01:00:00.000000000 +0100 +++ new/multipledispatch-1.0.0/setup.cfg 2023-06-27 18:28:30.000000000 +0200 @@ -0,0 +1,3 @@ +[flake8] +ignore= F811 +max-line-length = 100 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/multipledispatch-0.6.0/setup.py new/multipledispatch-1.0.0/setup.py --- old/multipledispatch-0.6.0/setup.py 2018-08-08 19:53:11.000000000 +0200 +++ new/multipledispatch-1.0.0/setup.py 2023-06-27 18:28:30.000000000 +0200 @@ -1,19 +1,19 @@ #!/usr/bin/env python from os.path import exists + from setuptools import setup -import multipledispatch -setup(name='multipledispatch', - version=multipledispatch.__version__, - description='Multiple dispatch', - url='http://github.com/mrocklin/multipledispatch/', - author='Matthew Rocklin', - author_email='mrock...@gmail.com', - install_requires=['six'], - license='BSD', - keywords='dispatch', - packages=['multipledispatch'], - long_description=(open('README.rst').read() if exists('README.rst') - else ''), - zip_safe=False) +setup( + name="multipledispatch", + version="1.0.0", + description="Multiple dispatch", + url="http://github.com/mrocklin/multipledispatch/", + author="Matthew Rocklin", + author_email="mrock...@gmail.com", + license="BSD", + keywords="dispatch", + packages=["multipledispatch"], + long_description=(open("README.rst").read() if exists("README.rst") else ""), + zip_safe=False, +)