singledispatch-3.4.0.2/0000755000076700000240000000000012164513654014740 5ustar ambvstaff00000000000000singledispatch-3.4.0.2/MANIFEST.in0000644000076700000240000000002312150225563016463 0ustar ambvstaff00000000000000include README.rst singledispatch-3.4.0.2/PKG-INFO0000644000076700000240000002237312164513654016044 0ustar ambvstaff00000000000000Metadata-Version: 1.1 Name: singledispatch Version: 3.4.0.2 Summary: This library brings functools.singledispatch from Python 3.4 to Python 2.6-3.3. Home-page: http://docs.python.org/3/library/functools.html#functools.singledispatch Author: Łukasz Langa Author-email: lukasz@langa.pl License: MIT Description: ============== singledispatch ============== `PEP 443 `_ proposed to expose a mechanism in the ``functools`` standard library module in Python 3.4 that provides a simple form of generic programming known as single-dispatch generic functions. This library is a backport of this functionality to Python 2.6 - 3.3. To define a generic function, decorate it with the ``@singledispatch`` decorator. Note that the dispatch happens on the type of the first argument, create your function accordingly:: >>> from singledispatch import singledispatch >>> @singledispatch ... def fun(arg, verbose=False): ... if verbose: ... print("Let me just say,", end=" ") ... print(arg) To add overloaded implementations to the function, use the ``register()`` attribute of the generic function. It is a decorator, taking a type parameter and decorating a function implementing the operation for that type:: >>> @fun.register(int) ... def _(arg, verbose=False): ... if verbose: ... print("Strength in numbers, eh?", end=" ") ... print(arg) ... >>> @fun.register(list) ... def _(arg, verbose=False): ... if verbose: ... print("Enumerate this:") ... for i, elem in enumerate(arg): ... print(i, elem) To enable registering lambdas and pre-existing functions, the ``register()`` attribute can be used in a functional form:: >>> def nothing(arg, verbose=False): ... print("Nothing.") ... >>> fun.register(type(None), nothing) The ``register()`` attribute returns the undecorated function which enables decorator stacking, pickling, as well as creating unit tests for each variant independently:: >>> @fun.register(float) ... @fun.register(Decimal) ... def fun_num(arg, verbose=False): ... if verbose: ... print("Half of your number:", end=" ") ... print(arg / 2) ... >>> fun_num is fun False When called, the generic function dispatches on the type of the first argument:: >>> fun("Hello, world.") Hello, world. >>> fun("test.", verbose=True) Let me just say, test. >>> fun(42, verbose=True) Strength in numbers, eh? 42 >>> fun(['spam', 'spam', 'eggs', 'spam'], verbose=True) Enumerate this: 0 spam 1 spam 2 eggs 3 spam >>> fun(None) Nothing. >>> fun(1.23) 0.615 Where there is no registered implementation for a specific type, its method resolution order is used to find a more generic implementation. The original function decorated with ``@singledispatch`` is registered for the base ``object`` type, which means it is used if no better implementation is found. To check which implementation will the generic function choose for a given type, use the ``dispatch()`` attribute:: >>> fun.dispatch(float) >>> fun.dispatch(dict) # note: default implementation To access all registered implementations, use the read-only ``registry`` attribute:: >>> fun.registry.keys() dict_keys([, , , , , ]) >>> fun.registry[float] >>> fun.registry[object] The vanilla documentation is available at http://docs.python.org/3/library/functools.html#functools.singledispatch. Versioning ---------- This backport is intended to keep 100% compatibility with the vanilla release in Python 3.4+. To help maintaining a version you want and expect, a versioning scheme is used where: * the first three numbers indicate the version of Python 3.x from which the backport is done * a backport release number is provided after the last dot For example, ``3.4.0.0`` is the **first** release of ``singledispatch`` compatible with the library found in Python **3.4.0**. A single exception from the 100% compatibility principle is that bugs fixed before releasing another minor Python 3.x.y version **will be included** in the backport releases done in the mean time. This rule applies to bugs only. Maintenance ----------- This backport is maintained on BitBucket by Łukasz Langa, one of the members of the core CPython team: * `singledispatch Mercurial repository `_ * `singledispatch issue tracker `_ Change Log ---------- 3.4.0.2 ~~~~~~~ Updated to the reference implementation as of 02-July-2013. * more predictable dispatch order when abstract base classes are in use: abstract base classes are now inserted into the MRO of the argument's class where their functionality is introduced, i.e. issubclass(cls, abc) returns True for the class itself but returns False for all its direct base classes. Implicit ABCs for a given class (either registered or inferred from the presence of a special method like __len__) are inserted directly after the last ABC explicitly listed in the MRO of said class. This also means there are less "ambiguous dispatch" exceptions raised. * better test coverage and improved docstrings 3.4.0.1 ~~~~~~~ Updated to the reference implementation as of 31-May-2013. * better performance * fixed a corner case with PEP 435 enums * calls to `dispatch()` also cached * dispatching algorithm now now a module-level routine called `_find_impl()` with a simplified implementation and proper documentation * `dispatch()` now handles all caching-related activities * terminology more consistent: "overload" -> "implementation" 3.4.0.0 ~~~~~~~ * the first public release compatible with 3.4.0 Conversion Process ------------------ This section is technical and should bother you only if you are wondering how this backport is produced. If the implementation details of this backport are not important for you, feel free to ignore the following content. ``singledispatch`` is converted using `six `_ so that a single codebase can be used for all compatible Python versions. Because a fully automatic conversion was not doable, I took the following branching approach: * the ``upstream`` branch holds unchanged files synchronized from the upstream CPython repository. The synchronization is currently done by manually copying the required code parts and stating from which CPython changeset they come from. The tests should pass on Python 3.4 on this branch. * the ``default`` branch holds the manually translated version and this is where all tests are run for all supported Python versions using Tox. Keywords: single dispatch generic functions singledispatch genericfunctions decorator backport Platform: any Classifier: Development Status :: 5 - Production/Stable Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: MIT License Classifier: Natural Language :: English Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 2 Classifier: Programming Language :: Python :: 2.6 Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.2 Classifier: Programming Language :: Python :: 3.3 Classifier: Topic :: Software Development :: Libraries Classifier: Topic :: Software Development :: Libraries :: Python Modules singledispatch-3.4.0.2/README.rst0000644000076700000240000001500512164511757016432 0ustar ambvstaff00000000000000============== singledispatch ============== `PEP 443 `_ proposed to expose a mechanism in the ``functools`` standard library module in Python 3.4 that provides a simple form of generic programming known as single-dispatch generic functions. This library is a backport of this functionality to Python 2.6 - 3.3. To define a generic function, decorate it with the ``@singledispatch`` decorator. Note that the dispatch happens on the type of the first argument, create your function accordingly:: >>> from singledispatch import singledispatch >>> @singledispatch ... def fun(arg, verbose=False): ... if verbose: ... print("Let me just say,", end=" ") ... print(arg) To add overloaded implementations to the function, use the ``register()`` attribute of the generic function. It is a decorator, taking a type parameter and decorating a function implementing the operation for that type:: >>> @fun.register(int) ... def _(arg, verbose=False): ... if verbose: ... print("Strength in numbers, eh?", end=" ") ... print(arg) ... >>> @fun.register(list) ... def _(arg, verbose=False): ... if verbose: ... print("Enumerate this:") ... for i, elem in enumerate(arg): ... print(i, elem) To enable registering lambdas and pre-existing functions, the ``register()`` attribute can be used in a functional form:: >>> def nothing(arg, verbose=False): ... print("Nothing.") ... >>> fun.register(type(None), nothing) The ``register()`` attribute returns the undecorated function which enables decorator stacking, pickling, as well as creating unit tests for each variant independently:: >>> @fun.register(float) ... @fun.register(Decimal) ... def fun_num(arg, verbose=False): ... if verbose: ... print("Half of your number:", end=" ") ... print(arg / 2) ... >>> fun_num is fun False When called, the generic function dispatches on the type of the first argument:: >>> fun("Hello, world.") Hello, world. >>> fun("test.", verbose=True) Let me just say, test. >>> fun(42, verbose=True) Strength in numbers, eh? 42 >>> fun(['spam', 'spam', 'eggs', 'spam'], verbose=True) Enumerate this: 0 spam 1 spam 2 eggs 3 spam >>> fun(None) Nothing. >>> fun(1.23) 0.615 Where there is no registered implementation for a specific type, its method resolution order is used to find a more generic implementation. The original function decorated with ``@singledispatch`` is registered for the base ``object`` type, which means it is used if no better implementation is found. To check which implementation will the generic function choose for a given type, use the ``dispatch()`` attribute:: >>> fun.dispatch(float) >>> fun.dispatch(dict) # note: default implementation To access all registered implementations, use the read-only ``registry`` attribute:: >>> fun.registry.keys() dict_keys([, , , , , ]) >>> fun.registry[float] >>> fun.registry[object] The vanilla documentation is available at http://docs.python.org/3/library/functools.html#functools.singledispatch. Versioning ---------- This backport is intended to keep 100% compatibility with the vanilla release in Python 3.4+. To help maintaining a version you want and expect, a versioning scheme is used where: * the first three numbers indicate the version of Python 3.x from which the backport is done * a backport release number is provided after the last dot For example, ``3.4.0.0`` is the **first** release of ``singledispatch`` compatible with the library found in Python **3.4.0**. A single exception from the 100% compatibility principle is that bugs fixed before releasing another minor Python 3.x.y version **will be included** in the backport releases done in the mean time. This rule applies to bugs only. Maintenance ----------- This backport is maintained on BitBucket by Łukasz Langa, one of the members of the core CPython team: * `singledispatch Mercurial repository `_ * `singledispatch issue tracker `_ Change Log ---------- 3.4.0.2 ~~~~~~~ Updated to the reference implementation as of 02-July-2013. * more predictable dispatch order when abstract base classes are in use: abstract base classes are now inserted into the MRO of the argument's class where their functionality is introduced, i.e. issubclass(cls, abc) returns True for the class itself but returns False for all its direct base classes. Implicit ABCs for a given class (either registered or inferred from the presence of a special method like __len__) are inserted directly after the last ABC explicitly listed in the MRO of said class. This also means there are less "ambiguous dispatch" exceptions raised. * better test coverage and improved docstrings 3.4.0.1 ~~~~~~~ Updated to the reference implementation as of 31-May-2013. * better performance * fixed a corner case with PEP 435 enums * calls to `dispatch()` also cached * dispatching algorithm now now a module-level routine called `_find_impl()` with a simplified implementation and proper documentation * `dispatch()` now handles all caching-related activities * terminology more consistent: "overload" -> "implementation" 3.4.0.0 ~~~~~~~ * the first public release compatible with 3.4.0 Conversion Process ------------------ This section is technical and should bother you only if you are wondering how this backport is produced. If the implementation details of this backport are not important for you, feel free to ignore the following content. ``singledispatch`` is converted using `six `_ so that a single codebase can be used for all compatible Python versions. Because a fully automatic conversion was not doable, I took the following branching approach: * the ``upstream`` branch holds unchanged files synchronized from the upstream CPython repository. The synchronization is currently done by manually copying the required code parts and stating from which CPython changeset they come from. The tests should pass on Python 3.4 on this branch. * the ``default`` branch holds the manually translated version and this is where all tests are run for all supported Python versions using Tox. singledispatch-3.4.0.2/setup.cfg0000644000076700000240000000007312164513654016561 0ustar ambvstaff00000000000000[egg_info] tag_build = tag_date = 0 tag_svn_revision = 0 singledispatch-3.4.0.2/setup.py0000644000076700000240000000603312164507716016456 0ustar ambvstaff00000000000000#!/usr/bin/python # -*- coding: utf-8 -*- """This library brings functools.singledispatch from Python 3.4 to Python 2.6-3.3.""" # Copyright (C) 2013 by Łukasz Langa # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. import os import sys import codecs from setuptools import setup, find_packages PY3 = sys.version_info[0] == 3 if not PY3: reload(sys) sys.setdefaultencoding('utf8') with codecs.open( os.path.join(os.path.dirname(__file__), 'README.rst'), 'r', 'utf8', ) as ld_file: long_description = ld_file.read() # We let it die a horrible tracebacking death if reading the file fails. # We couldn't sensibly recover anyway: we need the long description. install_requires = ['six'] if sys.version_info[:2] < (2, 7): install_requires.append('ordereddict') setup ( name = 'singledispatch', version = '3.4.0.2', author = 'Łukasz Langa', author_email = 'lukasz@langa.pl', description = __doc__, long_description = long_description, url = 'http://docs.python.org/3/library/functools.html' '#functools.singledispatch', keywords = 'single dispatch generic functions singledispatch ' 'genericfunctions decorator backport', platforms = ['any'], license = 'MIT', py_modules = ('singledispatch', 'singledispatch_helpers'), zip_safe = True, install_requires = install_requires, classifiers = [ 'Development Status :: 5 - Production/Stable', 'Intended Audience :: Developers', 'License :: OSI Approved :: MIT License', 'Natural Language :: English', 'Operating System :: OS Independent', 'Programming Language :: Python', 'Programming Language :: Python :: 2', 'Programming Language :: Python :: 2.6', 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3.2', 'Programming Language :: Python :: 3.3', 'Topic :: Software Development :: Libraries', 'Topic :: Software Development :: Libraries :: Python Modules', ] ) singledispatch-3.4.0.2/singledispatch.egg-info/0000755000076700000240000000000012164513654021433 5ustar ambvstaff00000000000000singledispatch-3.4.0.2/singledispatch.egg-info/dependency_links.txt0000644000076700000240000000000112164513654025501 0ustar ambvstaff00000000000000 singledispatch-3.4.0.2/singledispatch.egg-info/PKG-INFO0000644000076700000240000002237312164513654022537 0ustar ambvstaff00000000000000Metadata-Version: 1.1 Name: singledispatch Version: 3.4.0.2 Summary: This library brings functools.singledispatch from Python 3.4 to Python 2.6-3.3. Home-page: http://docs.python.org/3/library/functools.html#functools.singledispatch Author: Łukasz Langa Author-email: lukasz@langa.pl License: MIT Description: ============== singledispatch ============== `PEP 443 `_ proposed to expose a mechanism in the ``functools`` standard library module in Python 3.4 that provides a simple form of generic programming known as single-dispatch generic functions. This library is a backport of this functionality to Python 2.6 - 3.3. To define a generic function, decorate it with the ``@singledispatch`` decorator. Note that the dispatch happens on the type of the first argument, create your function accordingly:: >>> from singledispatch import singledispatch >>> @singledispatch ... def fun(arg, verbose=False): ... if verbose: ... print("Let me just say,", end=" ") ... print(arg) To add overloaded implementations to the function, use the ``register()`` attribute of the generic function. It is a decorator, taking a type parameter and decorating a function implementing the operation for that type:: >>> @fun.register(int) ... def _(arg, verbose=False): ... if verbose: ... print("Strength in numbers, eh?", end=" ") ... print(arg) ... >>> @fun.register(list) ... def _(arg, verbose=False): ... if verbose: ... print("Enumerate this:") ... for i, elem in enumerate(arg): ... print(i, elem) To enable registering lambdas and pre-existing functions, the ``register()`` attribute can be used in a functional form:: >>> def nothing(arg, verbose=False): ... print("Nothing.") ... >>> fun.register(type(None), nothing) The ``register()`` attribute returns the undecorated function which enables decorator stacking, pickling, as well as creating unit tests for each variant independently:: >>> @fun.register(float) ... @fun.register(Decimal) ... def fun_num(arg, verbose=False): ... if verbose: ... print("Half of your number:", end=" ") ... print(arg / 2) ... >>> fun_num is fun False When called, the generic function dispatches on the type of the first argument:: >>> fun("Hello, world.") Hello, world. >>> fun("test.", verbose=True) Let me just say, test. >>> fun(42, verbose=True) Strength in numbers, eh? 42 >>> fun(['spam', 'spam', 'eggs', 'spam'], verbose=True) Enumerate this: 0 spam 1 spam 2 eggs 3 spam >>> fun(None) Nothing. >>> fun(1.23) 0.615 Where there is no registered implementation for a specific type, its method resolution order is used to find a more generic implementation. The original function decorated with ``@singledispatch`` is registered for the base ``object`` type, which means it is used if no better implementation is found. To check which implementation will the generic function choose for a given type, use the ``dispatch()`` attribute:: >>> fun.dispatch(float) >>> fun.dispatch(dict) # note: default implementation To access all registered implementations, use the read-only ``registry`` attribute:: >>> fun.registry.keys() dict_keys([, , , , , ]) >>> fun.registry[float] >>> fun.registry[object] The vanilla documentation is available at http://docs.python.org/3/library/functools.html#functools.singledispatch. Versioning ---------- This backport is intended to keep 100% compatibility with the vanilla release in Python 3.4+. To help maintaining a version you want and expect, a versioning scheme is used where: * the first three numbers indicate the version of Python 3.x from which the backport is done * a backport release number is provided after the last dot For example, ``3.4.0.0`` is the **first** release of ``singledispatch`` compatible with the library found in Python **3.4.0**. A single exception from the 100% compatibility principle is that bugs fixed before releasing another minor Python 3.x.y version **will be included** in the backport releases done in the mean time. This rule applies to bugs only. Maintenance ----------- This backport is maintained on BitBucket by Łukasz Langa, one of the members of the core CPython team: * `singledispatch Mercurial repository `_ * `singledispatch issue tracker `_ Change Log ---------- 3.4.0.2 ~~~~~~~ Updated to the reference implementation as of 02-July-2013. * more predictable dispatch order when abstract base classes are in use: abstract base classes are now inserted into the MRO of the argument's class where their functionality is introduced, i.e. issubclass(cls, abc) returns True for the class itself but returns False for all its direct base classes. Implicit ABCs for a given class (either registered or inferred from the presence of a special method like __len__) are inserted directly after the last ABC explicitly listed in the MRO of said class. This also means there are less "ambiguous dispatch" exceptions raised. * better test coverage and improved docstrings 3.4.0.1 ~~~~~~~ Updated to the reference implementation as of 31-May-2013. * better performance * fixed a corner case with PEP 435 enums * calls to `dispatch()` also cached * dispatching algorithm now now a module-level routine called `_find_impl()` with a simplified implementation and proper documentation * `dispatch()` now handles all caching-related activities * terminology more consistent: "overload" -> "implementation" 3.4.0.0 ~~~~~~~ * the first public release compatible with 3.4.0 Conversion Process ------------------ This section is technical and should bother you only if you are wondering how this backport is produced. If the implementation details of this backport are not important for you, feel free to ignore the following content. ``singledispatch`` is converted using `six `_ so that a single codebase can be used for all compatible Python versions. Because a fully automatic conversion was not doable, I took the following branching approach: * the ``upstream`` branch holds unchanged files synchronized from the upstream CPython repository. The synchronization is currently done by manually copying the required code parts and stating from which CPython changeset they come from. The tests should pass on Python 3.4 on this branch. * the ``default`` branch holds the manually translated version and this is where all tests are run for all supported Python versions using Tox. Keywords: single dispatch generic functions singledispatch genericfunctions decorator backport Platform: any Classifier: Development Status :: 5 - Production/Stable Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: MIT License Classifier: Natural Language :: English Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 2 Classifier: Programming Language :: Python :: 2.6 Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.2 Classifier: Programming Language :: Python :: 3.3 Classifier: Topic :: Software Development :: Libraries Classifier: Topic :: Software Development :: Libraries :: Python Modules singledispatch-3.4.0.2/singledispatch.egg-info/requires.txt0000644000076700000240000000000312164513654024024 0ustar ambvstaff00000000000000sixsingledispatch-3.4.0.2/singledispatch.egg-info/SOURCES.txt0000644000076700000240000000045112164513654023317 0ustar ambvstaff00000000000000MANIFEST.in README.rst setup.py singledispatch.py singledispatch_helpers.py singledispatch.egg-info/PKG-INFO singledispatch.egg-info/SOURCES.txt singledispatch.egg-info/dependency_links.txt singledispatch.egg-info/requires.txt singledispatch.egg-info/top_level.txt singledispatch.egg-info/zip-safesingledispatch-3.4.0.2/singledispatch.egg-info/top_level.txt0000644000076700000240000000004612164513654024165 0ustar ambvstaff00000000000000singledispatch singledispatch_helpers singledispatch-3.4.0.2/singledispatch.egg-info/zip-safe0000644000076700000240000000000112150226135023051 0ustar ambvstaff00000000000000 singledispatch-3.4.0.2/singledispatch.py0000644000076700000240000002014412164512672020313 0ustar ambvstaff00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- from __future__ import absolute_import from __future__ import division from __future__ import print_function from __future__ import unicode_literals __all__ = ['singledispatch'] from functools import update_wrapper from weakref import WeakKeyDictionary from singledispatch_helpers import MappingProxyType, get_cache_token ################################################################################ ### singledispatch() - single-dispatch generic function decorator ################################################################################ def _c3_merge(sequences): """Merges MROs in *sequences* to a single MRO using the C3 algorithm. Adapted from http://www.python.org/download/releases/2.3/mro/. """ result = [] while True: sequences = [s for s in sequences if s] # purge empty sequences if not sequences: return result for s1 in sequences: # find merge candidates among seq heads candidate = s1[0] for s2 in sequences: if candidate in s2[1:]: candidate = None break # reject the current head, it appears later else: break if not candidate: raise RuntimeError("Inconsistent hierarchy") result.append(candidate) # remove the chosen candidate for seq in sequences: if seq[0] == candidate: del seq[0] def _c3_mro(cls, abcs=None): """Computes the method resolution order using extended C3 linearization. If no *abcs* are given, the algorithm works exactly like the built-in C3 linearization used for method resolution. If given, *abcs* is a list of abstract base classes that should be inserted into the resulting MRO. Unrelated ABCs are ignored and don't end up in the result. The algorithm inserts ABCs where their functionality is introduced, i.e. issubclass(cls, abc) returns True for the class itself but returns False for all its direct base classes. Implicit ABCs for a given class (either registered or inferred from the presence of a special method like __len__) are inserted directly after the last ABC explicitly listed in the MRO of said class. If two implicit ABCs end up next to each other in the resulting MRO, their ordering depends on the order of types in *abcs*. """ for i, base in enumerate(reversed(cls.__bases__)): if hasattr(base, '__abstractmethods__'): boundary = len(cls.__bases__) - i break # Bases up to the last explicit ABC are considered first. else: boundary = 0 abcs = list(abcs) if abcs else [] explicit_bases = list(cls.__bases__[:boundary]) abstract_bases = [] other_bases = list(cls.__bases__[boundary:]) for base in abcs: if issubclass(cls, base) and not any( issubclass(b, base) for b in cls.__bases__ ): # If *cls* is the class that introduces behaviour described by # an ABC *base*, insert said ABC to its MRO. abstract_bases.append(base) for base in abstract_bases: abcs.remove(base) explicit_c3_mros = [_c3_mro(base, abcs=abcs) for base in explicit_bases] abstract_c3_mros = [_c3_mro(base, abcs=abcs) for base in abstract_bases] other_c3_mros = [_c3_mro(base, abcs=abcs) for base in other_bases] return _c3_merge( [[cls]] + explicit_c3_mros + abstract_c3_mros + other_c3_mros + [explicit_bases] + [abstract_bases] + [other_bases] ) def _compose_mro(cls, types): """Calculates the method resolution order for a given class *cls*. Includes relevant abstract base classes (with their respective bases) from the *types* iterable. Uses a modified C3 linearization algorithm. """ bases = set(cls.__mro__) # Remove entries which are already present in the __mro__ or unrelated. def is_related(typ): return (typ not in bases and hasattr(typ, '__mro__') and issubclass(cls, typ)) types = [n for n in types if is_related(n)] # Remove entries which are strict bases of other entries (they will end up # in the MRO anyway. def is_strict_base(typ): for other in types: if typ != other and typ in other.__mro__: return True return False types = [n for n in types if not is_strict_base(n)] # Subclasses of the ABCs in *types* which are also implemented by # *cls* can be used to stabilize ABC ordering. type_set = set(types) mro = [] for typ in types: found = [] for sub in typ.__subclasses__(): if sub not in bases and issubclass(cls, sub): found.append([s for s in sub.__mro__ if s in type_set]) if not found: mro.append(typ) continue # Favor subclasses with the biggest number of useful bases found.sort(key=len, reverse=True) for sub in found: for subcls in sub: if subcls not in mro: mro.append(subcls) return _c3_mro(cls, abcs=mro) def _find_impl(cls, registry): """Returns the best matching implementation from *registry* for type *cls*. Where there is no registered implementation for a specific type, its method resolution order is used to find a more generic implementation. Note: if *registry* does not contain an implementation for the base *object* type, this function may return None. """ mro = _compose_mro(cls, registry.keys()) match = None for t in mro: if match is not None: # If *match* is an implicit ABC but there is another unrelated, # equally matching implicit ABC, refuse the temptation to guess. if (t in registry and t not in cls.__mro__ and match not in cls.__mro__ and not issubclass(match, t)): raise RuntimeError("Ambiguous dispatch: {0} or {1}".format( match, t)) break if t in registry: match = t return registry.get(match) def singledispatch(func): """Single-dispatch generic function decorator. Transforms a function into a generic function, which can have different behaviours depending upon the type of its first argument. The decorated function acts as the default implementation, and additional implementations can be registered using the register() attribute of the generic function. """ registry = {} dispatch_cache = WeakKeyDictionary() def ns(): pass ns.cache_token = None def dispatch(cls): """generic_func.dispatch(cls) -> Runs the dispatch algorithm to return the best available implementation for the given *cls* registered on *generic_func*. """ if ns.cache_token is not None: current_token = get_cache_token() if ns.cache_token != current_token: dispatch_cache.clear() ns.cache_token = current_token try: impl = dispatch_cache[cls] except KeyError: try: impl = registry[cls] except KeyError: impl = _find_impl(cls, registry) dispatch_cache[cls] = impl return impl def register(cls, func=None): """generic_func.register(cls, func) -> func Registers a new implementation for the given *cls* on a *generic_func*. """ if func is None: return lambda f: register(cls, f) registry[cls] = func if ns.cache_token is None and hasattr(cls, '__abstractmethods__'): ns.cache_token = get_cache_token() dispatch_cache.clear() return func def wrapper(*args, **kw): return dispatch(args[0].__class__)(*args, **kw) registry[object] = func wrapper.register = register wrapper.dispatch = dispatch wrapper.registry = MappingProxyType(registry) wrapper._clear_cache = dispatch_cache.clear update_wrapper(wrapper, func) return wrapper singledispatch-3.4.0.2/singledispatch_helpers.py0000644000076700000240000001215412164510173022031 0ustar ambvstaff00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- from __future__ import absolute_import from __future__ import division from __future__ import print_function from __future__ import unicode_literals from abc import ABCMeta from collections import MutableMapping import sys try: from collections import UserDict except ImportError: from UserDict import UserDict try: from collections import OrderedDict except ImportError: from ordereddict import OrderedDict try: from thread import get_ident except ImportError: try: from _thread import get_ident except ImportError: from _dummy_thread import get_ident def recursive_repr(fillvalue='...'): 'Decorator to make a repr function return fillvalue for a recursive call' def decorating_function(user_function): repr_running = set() def wrapper(self): key = id(self), get_ident() if key in repr_running: return fillvalue repr_running.add(key) try: result = user_function(self) finally: repr_running.discard(key) return result # Can't use functools.wraps() here because of bootstrap issues wrapper.__module__ = getattr(user_function, '__module__') wrapper.__doc__ = getattr(user_function, '__doc__') wrapper.__name__ = getattr(user_function, '__name__') wrapper.__annotations__ = getattr(user_function, '__annotations__', {}) return wrapper return decorating_function class ChainMap(MutableMapping): ''' A ChainMap groups multiple dicts (or other mappings) together to create a single, updateable view. The underlying mappings are stored in a list. That list is public and can accessed or updated using the *maps* attribute. There is no other state. Lookups search the underlying mappings successively until a key is found. In contrast, writes, updates, and deletions only operate on the first mapping. ''' def __init__(self, *maps): '''Initialize a ChainMap by setting *maps* to the given mappings. If no mappings are provided, a single empty dictionary is used. ''' self.maps = list(maps) or [{}] # always at least one map def __missing__(self, key): raise KeyError(key) def __getitem__(self, key): for mapping in self.maps: try: return mapping[key] # can't use 'key in mapping' with defaultdict except KeyError: pass return self.__missing__(key) # support subclasses that define __missing__ def get(self, key, default=None): return self[key] if key in self else default def __len__(self): return len(set().union(*self.maps)) # reuses stored hash values if possible def __iter__(self): return iter(set().union(*self.maps)) def __contains__(self, key): return any(key in m for m in self.maps) @recursive_repr() def __repr__(self): return '{0.__class__.__name__}({1})'.format( self, ', '.join(map(repr, self.maps))) @classmethod def fromkeys(cls, iterable, *args): 'Create a ChainMap with a single dict created from the iterable.' return cls(dict.fromkeys(iterable, *args)) def copy(self): 'New ChainMap or subclass with a new copy of maps[0] and refs to maps[1:]' return self.__class__(self.maps[0].copy(), *self.maps[1:]) __copy__ = copy def new_child(self): # like Django's Context.push() 'New ChainMap with a new dict followed by all previous maps.' return self.__class__({}, *self.maps) @property def parents(self): # like Django's Context.pop() 'New ChainMap from maps[1:].' return self.__class__(*self.maps[1:]) def __setitem__(self, key, value): self.maps[0][key] = value def __delitem__(self, key): try: del self.maps[0][key] except KeyError: raise KeyError('Key not found in the first mapping: {!r}'.format(key)) def popitem(self): 'Remove and return an item pair from maps[0]. Raise KeyError is maps[0] is empty.' try: return self.maps[0].popitem() except KeyError: raise KeyError('No keys found in the first mapping.') def pop(self, key, *args): 'Remove *key* from maps[0] and return its value. Raise KeyError if *key* not in maps[0].' try: return self.maps[0].pop(key, *args) except KeyError: raise KeyError('Key not found in the first mapping: {!r}'.format(key)) def clear(self): 'Clear maps[0], leaving maps[1:] intact.' self.maps[0].clear() class MappingProxyType(UserDict): def __init__(self, data): UserDict.__init__(self) self.data = data def get_cache_token(): return ABCMeta._abc_invalidation_counter class Support(object): def dummy(self): pass def cpython_only(self, func): if 'PyPy' in sys.version: return self.dummy return func