diff options
author | nkozlovskiy <nmk@ydb.tech> | 2023-10-02 18:57:38 +0300 |
---|---|---|
committer | nkozlovskiy <nmk@ydb.tech> | 2023-10-02 19:39:06 +0300 |
commit | 6295ef4d23465c11296e898b9dc4524ad9592b5d (patch) | |
tree | fc0c852877b2c52f365a1f6ed0710955844338c2 /contrib/deprecated/python/singledispatch | |
parent | de63c80b75948ecc13894854514d147840ff8430 (diff) | |
download | ydb-6295ef4d23465c11296e898b9dc4524ad9592b5d.tar.gz |
oss ydb: fix dstool building and test run
Diffstat (limited to 'contrib/deprecated/python/singledispatch')
7 files changed, 701 insertions, 0 deletions
diff --git a/contrib/deprecated/python/singledispatch/.dist-info/METADATA b/contrib/deprecated/python/singledispatch/.dist-info/METADATA new file mode 100644 index 0000000000..280d474d35 --- /dev/null +++ b/contrib/deprecated/python/singledispatch/.dist-info/METADATA @@ -0,0 +1,91 @@ +Metadata-Version: 2.1 +Name: singledispatch +Version: 3.7.0 +Summary: Backport functools.singledispatch from Python 3.4 to Python 2.6-3.3. +Home-page: https://github.com/jaraco/singledispatch +Author: Jason R. Coombs +Author-email: jaraco@jaraco.com +License: UNKNOWN +Keywords: single,dispatch,generic,functions,singledispatch,genericfunctions,decorator,backport +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: MIT License +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: Programming Language :: Python :: 3.4 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Requires-Python: >=2.6 +License-File: LICENSE +Requires-Dist: six +Requires-Dist: ordereddict ; python_version < "2.7" +Provides-Extra: docs +Requires-Dist: sphinx ; extra == 'docs' +Requires-Dist: jaraco.packaging (>=8.2) ; extra == 'docs' +Requires-Dist: rst.linker (>=1.9) ; extra == 'docs' +Provides-Extra: testing +Requires-Dist: pytest (>=4.6) ; extra == 'testing' +Requires-Dist: pytest-flake8 ; extra == 'testing' +Requires-Dist: pytest-cov ; extra == 'testing' +Requires-Dist: pytest-black (>=0.3.7) ; (platform_python_implementation != "PyPy") and extra == 'testing' +Requires-Dist: unittest2 ; (python_version < "3") and extra == 'testing' +Requires-Dist: pytest-checkdocs (>=2.4) ; (python_version > "3.6") and extra == 'testing' + +.. image:: https://img.shields.io/pypi/v/singledispatch.svg + :target: `PyPI link`_ + +.. image:: https://img.shields.io/pypi/pyversions/singledispatch.svg + :target: `PyPI link`_ + +.. _PyPI link: https://pypi.org/project/singledispatch + +.. image:: https://github.com/jaraco/singledispatch/workflows/tests/badge.svg + :target: https://github.com/jaraco/singledispatch/actions?query=workflow%3A%22tests%22 + :alt: tests + +.. image:: https://img.shields.io/badge/code%20style-black-000000.svg + :target: https://github.com/psf/black + :alt: Code style: Black + +.. .. image:: https://readthedocs.org/projects/skeleton/badge/?version=latest +.. :target: https://skeleton.readthedocs.io/en/latest/?badge=latest + +.. image:: https://img.shields.io/badge/skeleton-2021-informational + :target: https://blog.jaraco.com/skeleton + +`PEP 443 <http://www.python.org/dev/peps/pep-0443/>`_ 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 and its evolution. + +Refer to the `upstream documentation +<http://docs.python.org/3/library/functools.html#functools.singledispatch>`_ +for API guidance. To use the backport, simply use +``from singledispatch import singledispatch, singledispatchmethod`` in place of +``from functools import singledispatch, singledispatchmethod``. + + + +Maintenance +----------- + +This backport is maintained on Github by Jason R. Coombs, one of the +members of the core CPython team: + +* `repository <https://github.com/jaraco/singledispatch>`_ + +* `issue tracker <https://github.com/jaraco/singledispatch/issues>`_ + + diff --git a/contrib/deprecated/python/singledispatch/.dist-info/top_level.txt b/contrib/deprecated/python/singledispatch/.dist-info/top_level.txt new file mode 100644 index 0000000000..ebb5ff79be --- /dev/null +++ b/contrib/deprecated/python/singledispatch/.dist-info/top_level.txt @@ -0,0 +1 @@ +singledispatch diff --git a/contrib/deprecated/python/singledispatch/LICENSE b/contrib/deprecated/python/singledispatch/LICENSE new file mode 100644 index 0000000000..353924be0e --- /dev/null +++ b/contrib/deprecated/python/singledispatch/LICENSE @@ -0,0 +1,19 @@ +Copyright Jason R. Coombs + +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. diff --git a/contrib/deprecated/python/singledispatch/README.rst b/contrib/deprecated/python/singledispatch/README.rst new file mode 100644 index 0000000000..05084c85fc --- /dev/null +++ b/contrib/deprecated/python/singledispatch/README.rst @@ -0,0 +1,46 @@ +.. image:: https://img.shields.io/pypi/v/singledispatch.svg + :target: `PyPI link`_ + +.. image:: https://img.shields.io/pypi/pyversions/singledispatch.svg + :target: `PyPI link`_ + +.. _PyPI link: https://pypi.org/project/singledispatch + +.. image:: https://github.com/jaraco/singledispatch/workflows/tests/badge.svg + :target: https://github.com/jaraco/singledispatch/actions?query=workflow%3A%22tests%22 + :alt: tests + +.. image:: https://img.shields.io/badge/code%20style-black-000000.svg + :target: https://github.com/psf/black + :alt: Code style: Black + +.. .. image:: https://readthedocs.org/projects/skeleton/badge/?version=latest +.. :target: https://skeleton.readthedocs.io/en/latest/?badge=latest + +.. image:: https://img.shields.io/badge/skeleton-2021-informational + :target: https://blog.jaraco.com/skeleton + +`PEP 443 <http://www.python.org/dev/peps/pep-0443/>`_ 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 and its evolution. + +Refer to the `upstream documentation +<http://docs.python.org/3/library/functools.html#functools.singledispatch>`_ +for API guidance. To use the backport, simply use +``from singledispatch import singledispatch, singledispatchmethod`` in place of +``from functools import singledispatch, singledispatchmethod``. + + + +Maintenance +----------- + +This backport is maintained on Github by Jason R. Coombs, one of the +members of the core CPython team: + +* `repository <https://github.com/jaraco/singledispatch>`_ + +* `issue tracker <https://github.com/jaraco/singledispatch/issues>`_ diff --git a/contrib/deprecated/python/singledispatch/singledispatch/__init__.py b/contrib/deprecated/python/singledispatch/singledispatch/__init__.py new file mode 100644 index 0000000000..f6ec6eaebe --- /dev/null +++ b/contrib/deprecated/python/singledispatch/singledispatch/__init__.py @@ -0,0 +1,300 @@ +#!/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', 'singledispatchmethod'] + +from weakref import WeakKeyDictionary + +from .helpers import MappingProxyType, get_cache_token, get_type_hints, update_wrapper + +################################################################################ +### 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 candidate is None: + 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 filter(_safe, 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 _safe(class_): + """ + Return if the class is safe for testing as subclass. Ref #2. + """ + return not getattr(class_, '__origin__', None) + + +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 _validate_annotation(annotation): + """Determine if an annotation is valid for registration. + + An annotation is considered valid for use in registration if it is an + instance of ``type`` and not a generic type from ``typing``. + """ + try: + # In Python earlier than 3.7, the classes in typing are considered + # instances of type, but they invalid for registering single dispatch + # functions so check against GenericMeta instead. + from typing import GenericMeta + valid = not isinstance(annotation, GenericMeta) + except ImportError: + # In Python 3.7+, classes in typing are not instances of type. + valid = isinstance(annotation, type) + return valid + +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) -> <function implementation> + + 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: + if isinstance(cls, type): + return lambda f: register(cls, f) + ann = getattr(cls, '__annotations__', {}) + if not ann: + raise TypeError( + "Invalid first argument to `register()`: {cls!r}. " + "Use either `@register(some_class)` or plain `@register` " + "on an annotated function.".format(**locals()) + ) + func = cls + + argname, cls = next(iter(get_type_hints(func).items())) + if not _validate_annotation(cls): + raise TypeError( + "Invalid annotation for {argname!r}. " + "{cls!r} is not a class.".format(**locals()) + ) + 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): + if not args: + raise TypeError('{0} requires at least ' + '1 positional argument'.format(funcname)) + + return dispatch(args[0].__class__)(*args, **kw) + + funcname = getattr(func, '__name__', 'singledispatch function') + 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 + + +# Descriptor version +class singledispatchmethod(object): + """Single-dispatch generic method descriptor. + + Supports wrapping existing descriptors and handles non-descriptor + callables as instance methods. + """ + + def __init__(self, func): + if not callable(func) and not hasattr(func, "__get__"): + raise TypeError("{!r} is not callable or a descriptor".format(func)) + + self.dispatcher = singledispatch(func) + self.func = func + + def register(self, cls, method=None): + """generic_method.register(cls, func) -> func + + Registers a new implementation for the given *cls* on a *generic_method*. + """ + return self.dispatcher.register(cls, func=method) + + def __get__(self, obj, cls=None): + def _method(*args, **kwargs): + method = self.dispatcher.dispatch(args[0].__class__) + return method.__get__(obj, cls)(*args, **kwargs) + + _method.__isabstractmethod__ = self.__isabstractmethod__ + _method.register = self.register + update_wrapper(_method, self.func) + return _method + + @property + def __isabstractmethod__(self): + return getattr(self.func, '__isabstractmethod__', False) diff --git a/contrib/deprecated/python/singledispatch/singledispatch/helpers.py b/contrib/deprecated/python/singledispatch/singledispatch/helpers.py new file mode 100644 index 0000000000..74e73b1799 --- /dev/null +++ b/contrib/deprecated/python/singledispatch/singledispatch/helpers.py @@ -0,0 +1,217 @@ +#!/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 + +import sys +from abc import ABCMeta + +try: + from collections.abc import MutableMapping +except ImportError: + from collections import MutableMapping + +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 + + +try: + from abc import get_cache_token +except ImportError: + 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 + + +def get_type_hints(func): + # only import typing if annotation parsing is necessary + from typing import get_type_hints + return get_type_hints(func) or getattr(func, '__annotations__', {}) + + +WRAPPER_ASSIGNMENTS = ('__module__', '__name__', '__qualname__', '__doc__', + '__annotations__') +WRAPPER_UPDATES = ('__dict__',) +def update_wrapper(wrapper, + wrapped, + assigned = WRAPPER_ASSIGNMENTS, + updated = WRAPPER_UPDATES): + """Update a wrapper function to look like the wrapped function + + wrapper is the function to be updated + wrapped is the original function + assigned is a tuple naming the attributes assigned directly + from the wrapped function to the wrapper function (defaults to + functools.WRAPPER_ASSIGNMENTS) + updated is a tuple naming the attributes of the wrapper that + are updated with the corresponding attribute from the wrapped + function (defaults to functools.WRAPPER_UPDATES) + """ + for attr in assigned: + try: + value = getattr(wrapped, attr) + except AttributeError: + pass + else: + setattr(wrapper, attr, value) + for attr in updated: + getattr(wrapper, attr).update(getattr(wrapped, attr, {})) + # Issue #17482: set __wrapped__ last so we don't inadvertently copy it + # from the wrapped function when updating __dict__ + wrapper.__wrapped__ = wrapped + # Return the wrapper so this can be used as a decorator via partial() + return wrapper diff --git a/contrib/deprecated/python/singledispatch/ya.make b/contrib/deprecated/python/singledispatch/ya.make new file mode 100644 index 0000000000..ee683e8690 --- /dev/null +++ b/contrib/deprecated/python/singledispatch/ya.make @@ -0,0 +1,27 @@ +# Generated by devtools/yamaker (pypi). + +PY2_LIBRARY() + +VERSION(3.7.0) + +LICENSE(MIT) + +PEERDIR( + contrib/python/six +) + +NO_LINT() + +PY_SRCS( + TOP_LEVEL + singledispatch/__init__.py + singledispatch/helpers.py +) + +RESOURCE_FILES( + PREFIX contrib/deprecated/python/singledispatch/ + .dist-info/METADATA + .dist-info/top_level.txt +) + +END() |