externals: add attrs for new jsonschema
				
					
				
			Updating `jsonschema` to 3.2.0 requires `attrs`. Add it to externals.
This commit is contained in:
		| @@ -38,6 +38,10 @@ PackageName: argparse | |||||||
| PackageHomePage: https://pypi.python.org/pypi/argparse | PackageHomePage: https://pypi.python.org/pypi/argparse | ||||||
| PackageLicenseDeclared: Python-2.0 | PackageLicenseDeclared: Python-2.0 | ||||||
|  |  | ||||||
|  | PackageName: attrs | ||||||
|  | PackageHomePage: https://github.com/python-attrs/attrs | ||||||
|  | PackageLicenseDeclared: MIT | ||||||
|  |  | ||||||
| PackageName: ctest_log_parser | PackageName: ctest_log_parser | ||||||
| PackageHomePage: https://github.com/Kitware/CMake | PackageHomePage: https://github.com/Kitware/CMake | ||||||
| PackageLicenseDeclared: BSD-3-Clause | PackageLicenseDeclared: BSD-3-Clause | ||||||
|   | |||||||
							
								
								
									
										7
									
								
								lib/spack/external/__init__.py
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										7
									
								
								lib/spack/external/__init__.py
									
									
									
									
										vendored
									
									
								
							| @@ -24,6 +24,13 @@ | |||||||
|   vendored copy ever needs to be updated again: |   vendored copy ever needs to be updated again: | ||||||
|   https://github.com/spack/spack/pull/6786/commits/dfcef577b77249106ea4e4c69a6cd9e64fa6c418 |   https://github.com/spack/spack/pull/6786/commits/dfcef577b77249106ea4e4c69a6cd9e64fa6c418 | ||||||
| 
 | 
 | ||||||
|  | attrs | ||||||
|  | ---------------- | ||||||
|  | 
 | ||||||
|  | * Homepage: https://github.com/python-attrs/attrs | ||||||
|  | * Usage: Needed by jsonschema. | ||||||
|  | * Version: 21.2.0 (83d3cd70f90a3f4d19ee8b508e58d1c58821c0ad) | ||||||
|  | 
 | ||||||
| ctest_log_parser | ctest_log_parser | ||||||
| ---------------- | ---------------- | ||||||
| 
 | 
 | ||||||
|   | |||||||
							
								
								
									
										21
									
								
								lib/spack/external/attr/LICENSE
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								lib/spack/external/attr/LICENSE
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | |||||||
|  | The MIT License (MIT) | ||||||
|  |  | ||||||
|  | Copyright (c) 2015 Hynek Schlawack | ||||||
|  |  | ||||||
|  | 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. | ||||||
							
								
								
									
										78
									
								
								lib/spack/external/attr/__init__.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								lib/spack/external/attr/__init__.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,78 @@ | |||||||
|  | from __future__ import absolute_import, division, print_function | ||||||
|  | 
 | ||||||
|  | import sys | ||||||
|  | 
 | ||||||
|  | from functools import partial | ||||||
|  | 
 | ||||||
|  | from . import converters, exceptions, filters, setters, validators | ||||||
|  | from ._cmp import cmp_using | ||||||
|  | from ._config import get_run_validators, set_run_validators | ||||||
|  | from ._funcs import asdict, assoc, astuple, evolve, has, resolve_types | ||||||
|  | from ._make import ( | ||||||
|  |     NOTHING, | ||||||
|  |     Attribute, | ||||||
|  |     Factory, | ||||||
|  |     attrib, | ||||||
|  |     attrs, | ||||||
|  |     fields, | ||||||
|  |     fields_dict, | ||||||
|  |     make_class, | ||||||
|  |     validate, | ||||||
|  | ) | ||||||
|  | from ._version_info import VersionInfo | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | __version__ = "21.2.0" | ||||||
|  | __version_info__ = VersionInfo._from_version_string(__version__) | ||||||
|  | 
 | ||||||
|  | __title__ = "attrs" | ||||||
|  | __description__ = "Classes Without Boilerplate" | ||||||
|  | __url__ = "https://www.attrs.org/" | ||||||
|  | __uri__ = __url__ | ||||||
|  | __doc__ = __description__ + " <" + __uri__ + ">" | ||||||
|  | 
 | ||||||
|  | __author__ = "Hynek Schlawack" | ||||||
|  | __email__ = "hs@ox.cx" | ||||||
|  | 
 | ||||||
|  | __license__ = "MIT" | ||||||
|  | __copyright__ = "Copyright (c) 2015 Hynek Schlawack" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | s = attributes = attrs | ||||||
|  | ib = attr = attrib | ||||||
|  | dataclass = partial(attrs, auto_attribs=True)  # happy Easter ;) | ||||||
|  | 
 | ||||||
|  | __all__ = [ | ||||||
|  |     "Attribute", | ||||||
|  |     "Factory", | ||||||
|  |     "NOTHING", | ||||||
|  |     "asdict", | ||||||
|  |     "assoc", | ||||||
|  |     "astuple", | ||||||
|  |     "attr", | ||||||
|  |     "attrib", | ||||||
|  |     "attributes", | ||||||
|  |     "attrs", | ||||||
|  |     "cmp_using", | ||||||
|  |     "converters", | ||||||
|  |     "evolve", | ||||||
|  |     "exceptions", | ||||||
|  |     "fields", | ||||||
|  |     "fields_dict", | ||||||
|  |     "filters", | ||||||
|  |     "get_run_validators", | ||||||
|  |     "has", | ||||||
|  |     "ib", | ||||||
|  |     "make_class", | ||||||
|  |     "resolve_types", | ||||||
|  |     "s", | ||||||
|  |     "set_run_validators", | ||||||
|  |     "setters", | ||||||
|  |     "validate", | ||||||
|  |     "validators", | ||||||
|  | ] | ||||||
|  | 
 | ||||||
|  | if sys.version_info[:2] >= (3, 6): | ||||||
|  |     from ._next_gen import define, field, frozen, mutable | ||||||
|  | 
 | ||||||
|  |     __all__.extend((define, field, frozen, mutable)) | ||||||
							
								
								
									
										152
									
								
								lib/spack/external/attr/_cmp.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										152
									
								
								lib/spack/external/attr/_cmp.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,152 @@ | |||||||
|  | from __future__ import absolute_import, division, print_function | ||||||
|  | 
 | ||||||
|  | import functools | ||||||
|  | 
 | ||||||
|  | from ._compat import new_class | ||||||
|  | from ._make import _make_ne | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | _operation_names = {"eq": "==", "lt": "<", "le": "<=", "gt": ">", "ge": ">="} | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def cmp_using( | ||||||
|  |     eq=None, | ||||||
|  |     lt=None, | ||||||
|  |     le=None, | ||||||
|  |     gt=None, | ||||||
|  |     ge=None, | ||||||
|  |     require_same_type=True, | ||||||
|  |     class_name="Comparable", | ||||||
|  | ): | ||||||
|  |     """ | ||||||
|  |     Create a class that can be passed into `attr.ib`'s ``eq``, ``order``, and | ||||||
|  |     ``cmp`` arguments to customize field comparison. | ||||||
|  | 
 | ||||||
|  |     The resulting class will have a full set of ordering methods if | ||||||
|  |     at least one of ``{lt, le, gt, ge}`` and ``eq``  are provided. | ||||||
|  | 
 | ||||||
|  |     :param Optional[callable] eq: `callable` used to evaluate equality | ||||||
|  |         of two objects. | ||||||
|  |     :param Optional[callable] lt: `callable` used to evaluate whether | ||||||
|  |         one object is less than another object. | ||||||
|  |     :param Optional[callable] le: `callable` used to evaluate whether | ||||||
|  |         one object is less than or equal to another object. | ||||||
|  |     :param Optional[callable] gt: `callable` used to evaluate whether | ||||||
|  |         one object is greater than another object. | ||||||
|  |     :param Optional[callable] ge: `callable` used to evaluate whether | ||||||
|  |         one object is greater than or equal to another object. | ||||||
|  | 
 | ||||||
|  |     :param bool require_same_type: When `True`, equality and ordering methods | ||||||
|  |         will return `NotImplemented` if objects are not of the same type. | ||||||
|  | 
 | ||||||
|  |     :param Optional[str] class_name: Name of class. Defaults to 'Comparable'. | ||||||
|  | 
 | ||||||
|  |     See `comparison` for more details. | ||||||
|  | 
 | ||||||
|  |     .. versionadded:: 21.1.0 | ||||||
|  |     """ | ||||||
|  | 
 | ||||||
|  |     body = { | ||||||
|  |         "__slots__": ["value"], | ||||||
|  |         "__init__": _make_init(), | ||||||
|  |         "_requirements": [], | ||||||
|  |         "_is_comparable_to": _is_comparable_to, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     # Add operations. | ||||||
|  |     num_order_functions = 0 | ||||||
|  |     has_eq_function = False | ||||||
|  | 
 | ||||||
|  |     if eq is not None: | ||||||
|  |         has_eq_function = True | ||||||
|  |         body["__eq__"] = _make_operator("eq", eq) | ||||||
|  |         body["__ne__"] = _make_ne() | ||||||
|  | 
 | ||||||
|  |     if lt is not None: | ||||||
|  |         num_order_functions += 1 | ||||||
|  |         body["__lt__"] = _make_operator("lt", lt) | ||||||
|  | 
 | ||||||
|  |     if le is not None: | ||||||
|  |         num_order_functions += 1 | ||||||
|  |         body["__le__"] = _make_operator("le", le) | ||||||
|  | 
 | ||||||
|  |     if gt is not None: | ||||||
|  |         num_order_functions += 1 | ||||||
|  |         body["__gt__"] = _make_operator("gt", gt) | ||||||
|  | 
 | ||||||
|  |     if ge is not None: | ||||||
|  |         num_order_functions += 1 | ||||||
|  |         body["__ge__"] = _make_operator("ge", ge) | ||||||
|  | 
 | ||||||
|  |     type_ = new_class(class_name, (object,), {}, lambda ns: ns.update(body)) | ||||||
|  | 
 | ||||||
|  |     # Add same type requirement. | ||||||
|  |     if require_same_type: | ||||||
|  |         type_._requirements.append(_check_same_type) | ||||||
|  | 
 | ||||||
|  |     # Add total ordering if at least one operation was defined. | ||||||
|  |     if 0 < num_order_functions < 4: | ||||||
|  |         if not has_eq_function: | ||||||
|  |             # functools.total_ordering requires __eq__ to be defined, | ||||||
|  |             # so raise early error here to keep a nice stack. | ||||||
|  |             raise ValueError( | ||||||
|  |                 "eq must be define is order to complete ordering from " | ||||||
|  |                 "lt, le, gt, ge." | ||||||
|  |             ) | ||||||
|  |         type_ = functools.total_ordering(type_) | ||||||
|  | 
 | ||||||
|  |     return type_ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def _make_init(): | ||||||
|  |     """ | ||||||
|  |     Create __init__ method. | ||||||
|  |     """ | ||||||
|  | 
 | ||||||
|  |     def __init__(self, value): | ||||||
|  |         """ | ||||||
|  |         Initialize object with *value*. | ||||||
|  |         """ | ||||||
|  |         self.value = value | ||||||
|  | 
 | ||||||
|  |     return __init__ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def _make_operator(name, func): | ||||||
|  |     """ | ||||||
|  |     Create operator method. | ||||||
|  |     """ | ||||||
|  | 
 | ||||||
|  |     def method(self, other): | ||||||
|  |         if not self._is_comparable_to(other): | ||||||
|  |             return NotImplemented | ||||||
|  | 
 | ||||||
|  |         result = func(self.value, other.value) | ||||||
|  |         if result is NotImplemented: | ||||||
|  |             return NotImplemented | ||||||
|  | 
 | ||||||
|  |         return result | ||||||
|  | 
 | ||||||
|  |     method.__name__ = "__%s__" % (name,) | ||||||
|  |     method.__doc__ = "Return a %s b.  Computed by attrs." % ( | ||||||
|  |         _operation_names[name], | ||||||
|  |     ) | ||||||
|  | 
 | ||||||
|  |     return method | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def _is_comparable_to(self, other): | ||||||
|  |     """ | ||||||
|  |     Check whether `other` is comparable to `self`. | ||||||
|  |     """ | ||||||
|  |     for func in self._requirements: | ||||||
|  |         if not func(self, other): | ||||||
|  |             return False | ||||||
|  |     return True | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def _check_same_type(self, other): | ||||||
|  |     """ | ||||||
|  |     Return True if *self* and *other* are of the same type, False otherwise. | ||||||
|  |     """ | ||||||
|  |     return other.value.__class__ is self.value.__class__ | ||||||
							
								
								
									
										242
									
								
								lib/spack/external/attr/_compat.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										242
									
								
								lib/spack/external/attr/_compat.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,242 @@ | |||||||
|  | from __future__ import absolute_import, division, print_function | ||||||
|  | 
 | ||||||
|  | import platform | ||||||
|  | import sys | ||||||
|  | import types | ||||||
|  | import warnings | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | PY2 = sys.version_info[0] == 2 | ||||||
|  | PYPY = platform.python_implementation() == "PyPy" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | if PYPY or sys.version_info[:2] >= (3, 6): | ||||||
|  |     ordered_dict = dict | ||||||
|  | else: | ||||||
|  |     from collections import OrderedDict | ||||||
|  | 
 | ||||||
|  |     ordered_dict = OrderedDict | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | if PY2: | ||||||
|  |     from collections import Mapping, Sequence | ||||||
|  | 
 | ||||||
|  |     from UserDict import IterableUserDict | ||||||
|  | 
 | ||||||
|  |     # We 'bundle' isclass instead of using inspect as importing inspect is | ||||||
|  |     # fairly expensive (order of 10-15 ms for a modern machine in 2016) | ||||||
|  |     def isclass(klass): | ||||||
|  |         return isinstance(klass, (type, types.ClassType)) | ||||||
|  | 
 | ||||||
|  |     def new_class(name, bases, kwds, exec_body): | ||||||
|  |         """ | ||||||
|  |         A minimal stub of types.new_class that we need for make_class. | ||||||
|  |         """ | ||||||
|  |         ns = {} | ||||||
|  |         exec_body(ns) | ||||||
|  | 
 | ||||||
|  |         return type(name, bases, ns) | ||||||
|  | 
 | ||||||
|  |     # TYPE is used in exceptions, repr(int) is different on Python 2 and 3. | ||||||
|  |     TYPE = "type" | ||||||
|  | 
 | ||||||
|  |     def iteritems(d): | ||||||
|  |         return d.iteritems() | ||||||
|  | 
 | ||||||
|  |     # Python 2 is bereft of a read-only dict proxy, so we make one! | ||||||
|  |     class ReadOnlyDict(IterableUserDict): | ||||||
|  |         """ | ||||||
|  |         Best-effort read-only dict wrapper. | ||||||
|  |         """ | ||||||
|  | 
 | ||||||
|  |         def __setitem__(self, key, val): | ||||||
|  |             # We gently pretend we're a Python 3 mappingproxy. | ||||||
|  |             raise TypeError( | ||||||
|  |                 "'mappingproxy' object does not support item assignment" | ||||||
|  |             ) | ||||||
|  | 
 | ||||||
|  |         def update(self, _): | ||||||
|  |             # We gently pretend we're a Python 3 mappingproxy. | ||||||
|  |             raise AttributeError( | ||||||
|  |                 "'mappingproxy' object has no attribute 'update'" | ||||||
|  |             ) | ||||||
|  | 
 | ||||||
|  |         def __delitem__(self, _): | ||||||
|  |             # We gently pretend we're a Python 3 mappingproxy. | ||||||
|  |             raise TypeError( | ||||||
|  |                 "'mappingproxy' object does not support item deletion" | ||||||
|  |             ) | ||||||
|  | 
 | ||||||
|  |         def clear(self): | ||||||
|  |             # We gently pretend we're a Python 3 mappingproxy. | ||||||
|  |             raise AttributeError( | ||||||
|  |                 "'mappingproxy' object has no attribute 'clear'" | ||||||
|  |             ) | ||||||
|  | 
 | ||||||
|  |         def pop(self, key, default=None): | ||||||
|  |             # We gently pretend we're a Python 3 mappingproxy. | ||||||
|  |             raise AttributeError( | ||||||
|  |                 "'mappingproxy' object has no attribute 'pop'" | ||||||
|  |             ) | ||||||
|  | 
 | ||||||
|  |         def popitem(self): | ||||||
|  |             # We gently pretend we're a Python 3 mappingproxy. | ||||||
|  |             raise AttributeError( | ||||||
|  |                 "'mappingproxy' object has no attribute 'popitem'" | ||||||
|  |             ) | ||||||
|  | 
 | ||||||
|  |         def setdefault(self, key, default=None): | ||||||
|  |             # We gently pretend we're a Python 3 mappingproxy. | ||||||
|  |             raise AttributeError( | ||||||
|  |                 "'mappingproxy' object has no attribute 'setdefault'" | ||||||
|  |             ) | ||||||
|  | 
 | ||||||
|  |         def __repr__(self): | ||||||
|  |             # Override to be identical to the Python 3 version. | ||||||
|  |             return "mappingproxy(" + repr(self.data) + ")" | ||||||
|  | 
 | ||||||
|  |     def metadata_proxy(d): | ||||||
|  |         res = ReadOnlyDict() | ||||||
|  |         res.data.update(d)  # We blocked update, so we have to do it like this. | ||||||
|  |         return res | ||||||
|  | 
 | ||||||
|  |     def just_warn(*args, **kw):  # pragma: no cover | ||||||
|  |         """ | ||||||
|  |         We only warn on Python 3 because we are not aware of any concrete | ||||||
|  |         consequences of not setting the cell on Python 2. | ||||||
|  |         """ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | else:  # Python 3 and later. | ||||||
|  |     from collections.abc import Mapping, Sequence  # noqa | ||||||
|  | 
 | ||||||
|  |     def just_warn(*args, **kw): | ||||||
|  |         """ | ||||||
|  |         We only warn on Python 3 because we are not aware of any concrete | ||||||
|  |         consequences of not setting the cell on Python 2. | ||||||
|  |         """ | ||||||
|  |         warnings.warn( | ||||||
|  |             "Running interpreter doesn't sufficiently support code object " | ||||||
|  |             "introspection.  Some features like bare super() or accessing " | ||||||
|  |             "__class__ will not work with slotted classes.", | ||||||
|  |             RuntimeWarning, | ||||||
|  |             stacklevel=2, | ||||||
|  |         ) | ||||||
|  | 
 | ||||||
|  |     def isclass(klass): | ||||||
|  |         return isinstance(klass, type) | ||||||
|  | 
 | ||||||
|  |     TYPE = "class" | ||||||
|  | 
 | ||||||
|  |     def iteritems(d): | ||||||
|  |         return d.items() | ||||||
|  | 
 | ||||||
|  |     new_class = types.new_class | ||||||
|  | 
 | ||||||
|  |     def metadata_proxy(d): | ||||||
|  |         return types.MappingProxyType(dict(d)) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def make_set_closure_cell(): | ||||||
|  |     """Return a function of two arguments (cell, value) which sets | ||||||
|  |     the value stored in the closure cell `cell` to `value`. | ||||||
|  |     """ | ||||||
|  |     # pypy makes this easy. (It also supports the logic below, but | ||||||
|  |     # why not do the easy/fast thing?) | ||||||
|  |     if PYPY: | ||||||
|  | 
 | ||||||
|  |         def set_closure_cell(cell, value): | ||||||
|  |             cell.__setstate__((value,)) | ||||||
|  | 
 | ||||||
|  |         return set_closure_cell | ||||||
|  | 
 | ||||||
|  |     # Otherwise gotta do it the hard way. | ||||||
|  | 
 | ||||||
|  |     # Create a function that will set its first cellvar to `value`. | ||||||
|  |     def set_first_cellvar_to(value): | ||||||
|  |         x = value | ||||||
|  |         return | ||||||
|  | 
 | ||||||
|  |         # This function will be eliminated as dead code, but | ||||||
|  |         # not before its reference to `x` forces `x` to be | ||||||
|  |         # represented as a closure cell rather than a local. | ||||||
|  |         def force_x_to_be_a_cell():  # pragma: no cover | ||||||
|  |             return x | ||||||
|  | 
 | ||||||
|  |     try: | ||||||
|  |         # Extract the code object and make sure our assumptions about | ||||||
|  |         # the closure behavior are correct. | ||||||
|  |         if PY2: | ||||||
|  |             co = set_first_cellvar_to.func_code | ||||||
|  |         else: | ||||||
|  |             co = set_first_cellvar_to.__code__ | ||||||
|  |         if co.co_cellvars != ("x",) or co.co_freevars != (): | ||||||
|  |             raise AssertionError  # pragma: no cover | ||||||
|  | 
 | ||||||
|  |         # Convert this code object to a code object that sets the | ||||||
|  |         # function's first _freevar_ (not cellvar) to the argument. | ||||||
|  |         if sys.version_info >= (3, 8): | ||||||
|  |             # CPython 3.8+ has an incompatible CodeType signature | ||||||
|  |             # (added a posonlyargcount argument) but also added | ||||||
|  |             # CodeType.replace() to do this without counting parameters. | ||||||
|  |             set_first_freevar_code = co.replace( | ||||||
|  |                 co_cellvars=co.co_freevars, co_freevars=co.co_cellvars | ||||||
|  |             ) | ||||||
|  |         else: | ||||||
|  |             args = [co.co_argcount] | ||||||
|  |             if not PY2: | ||||||
|  |                 args.append(co.co_kwonlyargcount) | ||||||
|  |             args.extend( | ||||||
|  |                 [ | ||||||
|  |                     co.co_nlocals, | ||||||
|  |                     co.co_stacksize, | ||||||
|  |                     co.co_flags, | ||||||
|  |                     co.co_code, | ||||||
|  |                     co.co_consts, | ||||||
|  |                     co.co_names, | ||||||
|  |                     co.co_varnames, | ||||||
|  |                     co.co_filename, | ||||||
|  |                     co.co_name, | ||||||
|  |                     co.co_firstlineno, | ||||||
|  |                     co.co_lnotab, | ||||||
|  |                     # These two arguments are reversed: | ||||||
|  |                     co.co_cellvars, | ||||||
|  |                     co.co_freevars, | ||||||
|  |                 ] | ||||||
|  |             ) | ||||||
|  |             set_first_freevar_code = types.CodeType(*args) | ||||||
|  | 
 | ||||||
|  |         def set_closure_cell(cell, value): | ||||||
|  |             # Create a function using the set_first_freevar_code, | ||||||
|  |             # whose first closure cell is `cell`. Calling it will | ||||||
|  |             # change the value of that cell. | ||||||
|  |             setter = types.FunctionType( | ||||||
|  |                 set_first_freevar_code, {}, "setter", (), (cell,) | ||||||
|  |             ) | ||||||
|  |             # And call it to set the cell. | ||||||
|  |             setter(value) | ||||||
|  | 
 | ||||||
|  |         # Make sure it works on this interpreter: | ||||||
|  |         def make_func_with_cell(): | ||||||
|  |             x = None | ||||||
|  | 
 | ||||||
|  |             def func(): | ||||||
|  |                 return x  # pragma: no cover | ||||||
|  | 
 | ||||||
|  |             return func | ||||||
|  | 
 | ||||||
|  |         if PY2: | ||||||
|  |             cell = make_func_with_cell().func_closure[0] | ||||||
|  |         else: | ||||||
|  |             cell = make_func_with_cell().__closure__[0] | ||||||
|  |         set_closure_cell(cell, 100) | ||||||
|  |         if cell.cell_contents != 100: | ||||||
|  |             raise AssertionError  # pragma: no cover | ||||||
|  | 
 | ||||||
|  |     except Exception: | ||||||
|  |         return just_warn | ||||||
|  |     else: | ||||||
|  |         return set_closure_cell | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | set_closure_cell = make_set_closure_cell() | ||||||
							
								
								
									
										23
									
								
								lib/spack/external/attr/_config.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								lib/spack/external/attr/_config.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,23 @@ | |||||||
|  | from __future__ import absolute_import, division, print_function | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | __all__ = ["set_run_validators", "get_run_validators"] | ||||||
|  | 
 | ||||||
|  | _run_validators = True | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def set_run_validators(run): | ||||||
|  |     """ | ||||||
|  |     Set whether or not validators are run.  By default, they are run. | ||||||
|  |     """ | ||||||
|  |     if not isinstance(run, bool): | ||||||
|  |         raise TypeError("'run' must be bool.") | ||||||
|  |     global _run_validators | ||||||
|  |     _run_validators = run | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def get_run_validators(): | ||||||
|  |     """ | ||||||
|  |     Return whether or not validators are run. | ||||||
|  |     """ | ||||||
|  |     return _run_validators | ||||||
							
								
								
									
										395
									
								
								lib/spack/external/attr/_funcs.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										395
									
								
								lib/spack/external/attr/_funcs.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,395 @@ | |||||||
|  | from __future__ import absolute_import, division, print_function | ||||||
|  | 
 | ||||||
|  | import copy | ||||||
|  | 
 | ||||||
|  | from ._compat import iteritems | ||||||
|  | from ._make import NOTHING, _obj_setattr, fields | ||||||
|  | from .exceptions import AttrsAttributeNotFoundError | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def asdict( | ||||||
|  |     inst, | ||||||
|  |     recurse=True, | ||||||
|  |     filter=None, | ||||||
|  |     dict_factory=dict, | ||||||
|  |     retain_collection_types=False, | ||||||
|  |     value_serializer=None, | ||||||
|  | ): | ||||||
|  |     """ | ||||||
|  |     Return the ``attrs`` attribute values of *inst* as a dict. | ||||||
|  | 
 | ||||||
|  |     Optionally recurse into other ``attrs``-decorated classes. | ||||||
|  | 
 | ||||||
|  |     :param inst: Instance of an ``attrs``-decorated class. | ||||||
|  |     :param bool recurse: Recurse into classes that are also | ||||||
|  |         ``attrs``-decorated. | ||||||
|  |     :param callable filter: A callable whose return code determines whether an | ||||||
|  |         attribute or element is included (``True``) or dropped (``False``).  Is | ||||||
|  |         called with the `attr.Attribute` as the first argument and the | ||||||
|  |         value as the second argument. | ||||||
|  |     :param callable dict_factory: A callable to produce dictionaries from.  For | ||||||
|  |         example, to produce ordered dictionaries instead of normal Python | ||||||
|  |         dictionaries, pass in ``collections.OrderedDict``. | ||||||
|  |     :param bool retain_collection_types: Do not convert to ``list`` when | ||||||
|  |         encountering an attribute whose type is ``tuple`` or ``set``.  Only | ||||||
|  |         meaningful if ``recurse`` is ``True``. | ||||||
|  |     :param Optional[callable] value_serializer: A hook that is called for every | ||||||
|  |         attribute or dict key/value.  It receives the current instance, field | ||||||
|  |         and value and must return the (updated) value.  The hook is run *after* | ||||||
|  |         the optional *filter* has been applied. | ||||||
|  | 
 | ||||||
|  |     :rtype: return type of *dict_factory* | ||||||
|  | 
 | ||||||
|  |     :raise attr.exceptions.NotAnAttrsClassError: If *cls* is not an ``attrs`` | ||||||
|  |         class. | ||||||
|  | 
 | ||||||
|  |     ..  versionadded:: 16.0.0 *dict_factory* | ||||||
|  |     ..  versionadded:: 16.1.0 *retain_collection_types* | ||||||
|  |     ..  versionadded:: 20.3.0 *value_serializer* | ||||||
|  |     """ | ||||||
|  |     attrs = fields(inst.__class__) | ||||||
|  |     rv = dict_factory() | ||||||
|  |     for a in attrs: | ||||||
|  |         v = getattr(inst, a.name) | ||||||
|  |         if filter is not None and not filter(a, v): | ||||||
|  |             continue | ||||||
|  | 
 | ||||||
|  |         if value_serializer is not None: | ||||||
|  |             v = value_serializer(inst, a, v) | ||||||
|  | 
 | ||||||
|  |         if recurse is True: | ||||||
|  |             if has(v.__class__): | ||||||
|  |                 rv[a.name] = asdict( | ||||||
|  |                     v, | ||||||
|  |                     True, | ||||||
|  |                     filter, | ||||||
|  |                     dict_factory, | ||||||
|  |                     retain_collection_types, | ||||||
|  |                     value_serializer, | ||||||
|  |                 ) | ||||||
|  |             elif isinstance(v, (tuple, list, set, frozenset)): | ||||||
|  |                 cf = v.__class__ if retain_collection_types is True else list | ||||||
|  |                 rv[a.name] = cf( | ||||||
|  |                     [ | ||||||
|  |                         _asdict_anything( | ||||||
|  |                             i, | ||||||
|  |                             filter, | ||||||
|  |                             dict_factory, | ||||||
|  |                             retain_collection_types, | ||||||
|  |                             value_serializer, | ||||||
|  |                         ) | ||||||
|  |                         for i in v | ||||||
|  |                     ] | ||||||
|  |                 ) | ||||||
|  |             elif isinstance(v, dict): | ||||||
|  |                 df = dict_factory | ||||||
|  |                 rv[a.name] = df( | ||||||
|  |                     ( | ||||||
|  |                         _asdict_anything( | ||||||
|  |                             kk, | ||||||
|  |                             filter, | ||||||
|  |                             df, | ||||||
|  |                             retain_collection_types, | ||||||
|  |                             value_serializer, | ||||||
|  |                         ), | ||||||
|  |                         _asdict_anything( | ||||||
|  |                             vv, | ||||||
|  |                             filter, | ||||||
|  |                             df, | ||||||
|  |                             retain_collection_types, | ||||||
|  |                             value_serializer, | ||||||
|  |                         ), | ||||||
|  |                     ) | ||||||
|  |                     for kk, vv in iteritems(v) | ||||||
|  |                 ) | ||||||
|  |             else: | ||||||
|  |                 rv[a.name] = v | ||||||
|  |         else: | ||||||
|  |             rv[a.name] = v | ||||||
|  |     return rv | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def _asdict_anything( | ||||||
|  |     val, | ||||||
|  |     filter, | ||||||
|  |     dict_factory, | ||||||
|  |     retain_collection_types, | ||||||
|  |     value_serializer, | ||||||
|  | ): | ||||||
|  |     """ | ||||||
|  |     ``asdict`` only works on attrs instances, this works on anything. | ||||||
|  |     """ | ||||||
|  |     if getattr(val.__class__, "__attrs_attrs__", None) is not None: | ||||||
|  |         # Attrs class. | ||||||
|  |         rv = asdict( | ||||||
|  |             val, | ||||||
|  |             True, | ||||||
|  |             filter, | ||||||
|  |             dict_factory, | ||||||
|  |             retain_collection_types, | ||||||
|  |             value_serializer, | ||||||
|  |         ) | ||||||
|  |     elif isinstance(val, (tuple, list, set, frozenset)): | ||||||
|  |         cf = val.__class__ if retain_collection_types is True else list | ||||||
|  |         rv = cf( | ||||||
|  |             [ | ||||||
|  |                 _asdict_anything( | ||||||
|  |                     i, | ||||||
|  |                     filter, | ||||||
|  |                     dict_factory, | ||||||
|  |                     retain_collection_types, | ||||||
|  |                     value_serializer, | ||||||
|  |                 ) | ||||||
|  |                 for i in val | ||||||
|  |             ] | ||||||
|  |         ) | ||||||
|  |     elif isinstance(val, dict): | ||||||
|  |         df = dict_factory | ||||||
|  |         rv = df( | ||||||
|  |             ( | ||||||
|  |                 _asdict_anything( | ||||||
|  |                     kk, filter, df, retain_collection_types, value_serializer | ||||||
|  |                 ), | ||||||
|  |                 _asdict_anything( | ||||||
|  |                     vv, filter, df, retain_collection_types, value_serializer | ||||||
|  |                 ), | ||||||
|  |             ) | ||||||
|  |             for kk, vv in iteritems(val) | ||||||
|  |         ) | ||||||
|  |     else: | ||||||
|  |         rv = val | ||||||
|  |         if value_serializer is not None: | ||||||
|  |             rv = value_serializer(None, None, rv) | ||||||
|  | 
 | ||||||
|  |     return rv | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def astuple( | ||||||
|  |     inst, | ||||||
|  |     recurse=True, | ||||||
|  |     filter=None, | ||||||
|  |     tuple_factory=tuple, | ||||||
|  |     retain_collection_types=False, | ||||||
|  | ): | ||||||
|  |     """ | ||||||
|  |     Return the ``attrs`` attribute values of *inst* as a tuple. | ||||||
|  | 
 | ||||||
|  |     Optionally recurse into other ``attrs``-decorated classes. | ||||||
|  | 
 | ||||||
|  |     :param inst: Instance of an ``attrs``-decorated class. | ||||||
|  |     :param bool recurse: Recurse into classes that are also | ||||||
|  |         ``attrs``-decorated. | ||||||
|  |     :param callable filter: A callable whose return code determines whether an | ||||||
|  |         attribute or element is included (``True``) or dropped (``False``).  Is | ||||||
|  |         called with the `attr.Attribute` as the first argument and the | ||||||
|  |         value as the second argument. | ||||||
|  |     :param callable tuple_factory: A callable to produce tuples from.  For | ||||||
|  |         example, to produce lists instead of tuples. | ||||||
|  |     :param bool retain_collection_types: Do not convert to ``list`` | ||||||
|  |         or ``dict`` when encountering an attribute which type is | ||||||
|  |         ``tuple``, ``dict`` or ``set``.  Only meaningful if ``recurse`` is | ||||||
|  |         ``True``. | ||||||
|  | 
 | ||||||
|  |     :rtype: return type of *tuple_factory* | ||||||
|  | 
 | ||||||
|  |     :raise attr.exceptions.NotAnAttrsClassError: If *cls* is not an ``attrs`` | ||||||
|  |         class. | ||||||
|  | 
 | ||||||
|  |     ..  versionadded:: 16.2.0 | ||||||
|  |     """ | ||||||
|  |     attrs = fields(inst.__class__) | ||||||
|  |     rv = [] | ||||||
|  |     retain = retain_collection_types  # Very long. :/ | ||||||
|  |     for a in attrs: | ||||||
|  |         v = getattr(inst, a.name) | ||||||
|  |         if filter is not None and not filter(a, v): | ||||||
|  |             continue | ||||||
|  |         if recurse is True: | ||||||
|  |             if has(v.__class__): | ||||||
|  |                 rv.append( | ||||||
|  |                     astuple( | ||||||
|  |                         v, | ||||||
|  |                         recurse=True, | ||||||
|  |                         filter=filter, | ||||||
|  |                         tuple_factory=tuple_factory, | ||||||
|  |                         retain_collection_types=retain, | ||||||
|  |                     ) | ||||||
|  |                 ) | ||||||
|  |             elif isinstance(v, (tuple, list, set, frozenset)): | ||||||
|  |                 cf = v.__class__ if retain is True else list | ||||||
|  |                 rv.append( | ||||||
|  |                     cf( | ||||||
|  |                         [ | ||||||
|  |                             astuple( | ||||||
|  |                                 j, | ||||||
|  |                                 recurse=True, | ||||||
|  |                                 filter=filter, | ||||||
|  |                                 tuple_factory=tuple_factory, | ||||||
|  |                                 retain_collection_types=retain, | ||||||
|  |                             ) | ||||||
|  |                             if has(j.__class__) | ||||||
|  |                             else j | ||||||
|  |                             for j in v | ||||||
|  |                         ] | ||||||
|  |                     ) | ||||||
|  |                 ) | ||||||
|  |             elif isinstance(v, dict): | ||||||
|  |                 df = v.__class__ if retain is True else dict | ||||||
|  |                 rv.append( | ||||||
|  |                     df( | ||||||
|  |                         ( | ||||||
|  |                             astuple( | ||||||
|  |                                 kk, | ||||||
|  |                                 tuple_factory=tuple_factory, | ||||||
|  |                                 retain_collection_types=retain, | ||||||
|  |                             ) | ||||||
|  |                             if has(kk.__class__) | ||||||
|  |                             else kk, | ||||||
|  |                             astuple( | ||||||
|  |                                 vv, | ||||||
|  |                                 tuple_factory=tuple_factory, | ||||||
|  |                                 retain_collection_types=retain, | ||||||
|  |                             ) | ||||||
|  |                             if has(vv.__class__) | ||||||
|  |                             else vv, | ||||||
|  |                         ) | ||||||
|  |                         for kk, vv in iteritems(v) | ||||||
|  |                     ) | ||||||
|  |                 ) | ||||||
|  |             else: | ||||||
|  |                 rv.append(v) | ||||||
|  |         else: | ||||||
|  |             rv.append(v) | ||||||
|  | 
 | ||||||
|  |     return rv if tuple_factory is list else tuple_factory(rv) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def has(cls): | ||||||
|  |     """ | ||||||
|  |     Check whether *cls* is a class with ``attrs`` attributes. | ||||||
|  | 
 | ||||||
|  |     :param type cls: Class to introspect. | ||||||
|  |     :raise TypeError: If *cls* is not a class. | ||||||
|  | 
 | ||||||
|  |     :rtype: bool | ||||||
|  |     """ | ||||||
|  |     return getattr(cls, "__attrs_attrs__", None) is not None | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def assoc(inst, **changes): | ||||||
|  |     """ | ||||||
|  |     Copy *inst* and apply *changes*. | ||||||
|  | 
 | ||||||
|  |     :param inst: Instance of a class with ``attrs`` attributes. | ||||||
|  |     :param changes: Keyword changes in the new copy. | ||||||
|  | 
 | ||||||
|  |     :return: A copy of inst with *changes* incorporated. | ||||||
|  | 
 | ||||||
|  |     :raise attr.exceptions.AttrsAttributeNotFoundError: If *attr_name* couldn't | ||||||
|  |         be found on *cls*. | ||||||
|  |     :raise attr.exceptions.NotAnAttrsClassError: If *cls* is not an ``attrs`` | ||||||
|  |         class. | ||||||
|  | 
 | ||||||
|  |     ..  deprecated:: 17.1.0 | ||||||
|  |         Use `evolve` instead. | ||||||
|  |     """ | ||||||
|  |     import warnings | ||||||
|  | 
 | ||||||
|  |     warnings.warn( | ||||||
|  |         "assoc is deprecated and will be removed after 2018/01.", | ||||||
|  |         DeprecationWarning, | ||||||
|  |         stacklevel=2, | ||||||
|  |     ) | ||||||
|  |     new = copy.copy(inst) | ||||||
|  |     attrs = fields(inst.__class__) | ||||||
|  |     for k, v in iteritems(changes): | ||||||
|  |         a = getattr(attrs, k, NOTHING) | ||||||
|  |         if a is NOTHING: | ||||||
|  |             raise AttrsAttributeNotFoundError( | ||||||
|  |                 "{k} is not an attrs attribute on {cl}.".format( | ||||||
|  |                     k=k, cl=new.__class__ | ||||||
|  |                 ) | ||||||
|  |             ) | ||||||
|  |         _obj_setattr(new, k, v) | ||||||
|  |     return new | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def evolve(inst, **changes): | ||||||
|  |     """ | ||||||
|  |     Create a new instance, based on *inst* with *changes* applied. | ||||||
|  | 
 | ||||||
|  |     :param inst: Instance of a class with ``attrs`` attributes. | ||||||
|  |     :param changes: Keyword changes in the new copy. | ||||||
|  | 
 | ||||||
|  |     :return: A copy of inst with *changes* incorporated. | ||||||
|  | 
 | ||||||
|  |     :raise TypeError: If *attr_name* couldn't be found in the class | ||||||
|  |         ``__init__``. | ||||||
|  |     :raise attr.exceptions.NotAnAttrsClassError: If *cls* is not an ``attrs`` | ||||||
|  |         class. | ||||||
|  | 
 | ||||||
|  |     ..  versionadded:: 17.1.0 | ||||||
|  |     """ | ||||||
|  |     cls = inst.__class__ | ||||||
|  |     attrs = fields(cls) | ||||||
|  |     for a in attrs: | ||||||
|  |         if not a.init: | ||||||
|  |             continue | ||||||
|  |         attr_name = a.name  # To deal with private attributes. | ||||||
|  |         init_name = attr_name if attr_name[0] != "_" else attr_name[1:] | ||||||
|  |         if init_name not in changes: | ||||||
|  |             changes[init_name] = getattr(inst, attr_name) | ||||||
|  | 
 | ||||||
|  |     return cls(**changes) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def resolve_types(cls, globalns=None, localns=None, attribs=None): | ||||||
|  |     """ | ||||||
|  |     Resolve any strings and forward annotations in type annotations. | ||||||
|  | 
 | ||||||
|  |     This is only required if you need concrete types in `Attribute`'s *type* | ||||||
|  |     field. In other words, you don't need to resolve your types if you only | ||||||
|  |     use them for static type checking. | ||||||
|  | 
 | ||||||
|  |     With no arguments, names will be looked up in the module in which the class | ||||||
|  |     was created. If this is not what you want, e.g. if the name only exists | ||||||
|  |     inside a method, you may pass *globalns* or *localns* to specify other | ||||||
|  |     dictionaries in which to look up these names. See the docs of | ||||||
|  |     `typing.get_type_hints` for more details. | ||||||
|  | 
 | ||||||
|  |     :param type cls: Class to resolve. | ||||||
|  |     :param Optional[dict] globalns: Dictionary containing global variables. | ||||||
|  |     :param Optional[dict] localns: Dictionary containing local variables. | ||||||
|  |     :param Optional[list] attribs: List of attribs for the given class. | ||||||
|  |         This is necessary when calling from inside a ``field_transformer`` | ||||||
|  |         since *cls* is not an ``attrs`` class yet. | ||||||
|  | 
 | ||||||
|  |     :raise TypeError: If *cls* is not a class. | ||||||
|  |     :raise attr.exceptions.NotAnAttrsClassError: If *cls* is not an ``attrs`` | ||||||
|  |         class and you didn't pass any attribs. | ||||||
|  |     :raise NameError: If types cannot be resolved because of missing variables. | ||||||
|  | 
 | ||||||
|  |     :returns: *cls* so you can use this function also as a class decorator. | ||||||
|  |         Please note that you have to apply it **after** `attr.s`. That means | ||||||
|  |         the decorator has to come in the line **before** `attr.s`. | ||||||
|  | 
 | ||||||
|  |     ..  versionadded:: 20.1.0 | ||||||
|  |     ..  versionadded:: 21.1.0 *attribs* | ||||||
|  | 
 | ||||||
|  |     """ | ||||||
|  |     try: | ||||||
|  |         # Since calling get_type_hints is expensive we cache whether we've | ||||||
|  |         # done it already. | ||||||
|  |         cls.__attrs_types_resolved__ | ||||||
|  |     except AttributeError: | ||||||
|  |         import typing | ||||||
|  | 
 | ||||||
|  |         hints = typing.get_type_hints(cls, globalns=globalns, localns=localns) | ||||||
|  |         for field in fields(cls) if attribs is None else attribs: | ||||||
|  |             if field.name in hints: | ||||||
|  |                 # Since fields have been frozen we must work around it. | ||||||
|  |                 _obj_setattr(field, "type", hints[field.name]) | ||||||
|  |         cls.__attrs_types_resolved__ = True | ||||||
|  | 
 | ||||||
|  |     # Return the class so you can use it as a decorator too. | ||||||
|  |     return cls | ||||||
							
								
								
									
										3052
									
								
								lib/spack/external/attr/_make.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3052
									
								
								lib/spack/external/attr/_make.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										158
									
								
								lib/spack/external/attr/_next_gen.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										158
									
								
								lib/spack/external/attr/_next_gen.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,158 @@ | |||||||
|  | """ | ||||||
|  | These are Python 3.6+-only and keyword-only APIs that call `attr.s` and | ||||||
|  | `attr.ib` with different default values. | ||||||
|  | """ | ||||||
|  | 
 | ||||||
|  | from functools import partial | ||||||
|  | 
 | ||||||
|  | from attr.exceptions import UnannotatedAttributeError | ||||||
|  | 
 | ||||||
|  | from . import setters | ||||||
|  | from ._make import NOTHING, _frozen_setattrs, attrib, attrs | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def define( | ||||||
|  |     maybe_cls=None, | ||||||
|  |     *, | ||||||
|  |     these=None, | ||||||
|  |     repr=None, | ||||||
|  |     hash=None, | ||||||
|  |     init=None, | ||||||
|  |     slots=True, | ||||||
|  |     frozen=False, | ||||||
|  |     weakref_slot=True, | ||||||
|  |     str=False, | ||||||
|  |     auto_attribs=None, | ||||||
|  |     kw_only=False, | ||||||
|  |     cache_hash=False, | ||||||
|  |     auto_exc=True, | ||||||
|  |     eq=None, | ||||||
|  |     order=False, | ||||||
|  |     auto_detect=True, | ||||||
|  |     getstate_setstate=None, | ||||||
|  |     on_setattr=None, | ||||||
|  |     field_transformer=None, | ||||||
|  | ): | ||||||
|  |     r""" | ||||||
|  |     The only behavioral differences are the handling of the *auto_attribs* | ||||||
|  |     option: | ||||||
|  | 
 | ||||||
|  |     :param Optional[bool] auto_attribs: If set to `True` or `False`, it behaves | ||||||
|  |        exactly like `attr.s`. If left `None`, `attr.s` will try to guess: | ||||||
|  | 
 | ||||||
|  |        1. If any attributes are annotated and no unannotated `attr.ib`\ s | ||||||
|  |           are found, it assumes *auto_attribs=True*. | ||||||
|  |        2. Otherwise it assumes *auto_attribs=False* and tries to collect | ||||||
|  |           `attr.ib`\ s. | ||||||
|  | 
 | ||||||
|  |     and that mutable classes (``frozen=False``) validate on ``__setattr__``. | ||||||
|  | 
 | ||||||
|  |     .. versionadded:: 20.1.0 | ||||||
|  |     """ | ||||||
|  | 
 | ||||||
|  |     def do_it(cls, auto_attribs): | ||||||
|  |         return attrs( | ||||||
|  |             maybe_cls=cls, | ||||||
|  |             these=these, | ||||||
|  |             repr=repr, | ||||||
|  |             hash=hash, | ||||||
|  |             init=init, | ||||||
|  |             slots=slots, | ||||||
|  |             frozen=frozen, | ||||||
|  |             weakref_slot=weakref_slot, | ||||||
|  |             str=str, | ||||||
|  |             auto_attribs=auto_attribs, | ||||||
|  |             kw_only=kw_only, | ||||||
|  |             cache_hash=cache_hash, | ||||||
|  |             auto_exc=auto_exc, | ||||||
|  |             eq=eq, | ||||||
|  |             order=order, | ||||||
|  |             auto_detect=auto_detect, | ||||||
|  |             collect_by_mro=True, | ||||||
|  |             getstate_setstate=getstate_setstate, | ||||||
|  |             on_setattr=on_setattr, | ||||||
|  |             field_transformer=field_transformer, | ||||||
|  |         ) | ||||||
|  | 
 | ||||||
|  |     def wrap(cls): | ||||||
|  |         """ | ||||||
|  |         Making this a wrapper ensures this code runs during class creation. | ||||||
|  | 
 | ||||||
|  |         We also ensure that frozen-ness of classes is inherited. | ||||||
|  |         """ | ||||||
|  |         nonlocal frozen, on_setattr | ||||||
|  | 
 | ||||||
|  |         had_on_setattr = on_setattr not in (None, setters.NO_OP) | ||||||
|  | 
 | ||||||
|  |         # By default, mutable classes validate on setattr. | ||||||
|  |         if frozen is False and on_setattr is None: | ||||||
|  |             on_setattr = setters.validate | ||||||
|  | 
 | ||||||
|  |         # However, if we subclass a frozen class, we inherit the immutability | ||||||
|  |         # and disable on_setattr. | ||||||
|  |         for base_cls in cls.__bases__: | ||||||
|  |             if base_cls.__setattr__ is _frozen_setattrs: | ||||||
|  |                 if had_on_setattr: | ||||||
|  |                     raise ValueError( | ||||||
|  |                         "Frozen classes can't use on_setattr " | ||||||
|  |                         "(frozen-ness was inherited)." | ||||||
|  |                     ) | ||||||
|  | 
 | ||||||
|  |                 on_setattr = setters.NO_OP | ||||||
|  |                 break | ||||||
|  | 
 | ||||||
|  |         if auto_attribs is not None: | ||||||
|  |             return do_it(cls, auto_attribs) | ||||||
|  | 
 | ||||||
|  |         try: | ||||||
|  |             return do_it(cls, True) | ||||||
|  |         except UnannotatedAttributeError: | ||||||
|  |             return do_it(cls, False) | ||||||
|  | 
 | ||||||
|  |     # maybe_cls's type depends on the usage of the decorator.  It's a class | ||||||
|  |     # if it's used as `@attrs` but ``None`` if used as `@attrs()`. | ||||||
|  |     if maybe_cls is None: | ||||||
|  |         return wrap | ||||||
|  |     else: | ||||||
|  |         return wrap(maybe_cls) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | mutable = define | ||||||
|  | frozen = partial(define, frozen=True, on_setattr=None) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def field( | ||||||
|  |     *, | ||||||
|  |     default=NOTHING, | ||||||
|  |     validator=None, | ||||||
|  |     repr=True, | ||||||
|  |     hash=None, | ||||||
|  |     init=True, | ||||||
|  |     metadata=None, | ||||||
|  |     converter=None, | ||||||
|  |     factory=None, | ||||||
|  |     kw_only=False, | ||||||
|  |     eq=None, | ||||||
|  |     order=None, | ||||||
|  |     on_setattr=None, | ||||||
|  | ): | ||||||
|  |     """ | ||||||
|  |     Identical to `attr.ib`, except keyword-only and with some arguments | ||||||
|  |     removed. | ||||||
|  | 
 | ||||||
|  |     .. versionadded:: 20.1.0 | ||||||
|  |     """ | ||||||
|  |     return attrib( | ||||||
|  |         default=default, | ||||||
|  |         validator=validator, | ||||||
|  |         repr=repr, | ||||||
|  |         hash=hash, | ||||||
|  |         init=init, | ||||||
|  |         metadata=metadata, | ||||||
|  |         converter=converter, | ||||||
|  |         factory=factory, | ||||||
|  |         kw_only=kw_only, | ||||||
|  |         eq=eq, | ||||||
|  |         order=order, | ||||||
|  |         on_setattr=on_setattr, | ||||||
|  |     ) | ||||||
							
								
								
									
										85
									
								
								lib/spack/external/attr/_version_info.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								lib/spack/external/attr/_version_info.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,85 @@ | |||||||
|  | from __future__ import absolute_import, division, print_function | ||||||
|  | 
 | ||||||
|  | from functools import total_ordering | ||||||
|  | 
 | ||||||
|  | from ._funcs import astuple | ||||||
|  | from ._make import attrib, attrs | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @total_ordering | ||||||
|  | @attrs(eq=False, order=False, slots=True, frozen=True) | ||||||
|  | class VersionInfo(object): | ||||||
|  |     """ | ||||||
|  |     A version object that can be compared to tuple of length 1--4: | ||||||
|  | 
 | ||||||
|  |     >>> attr.VersionInfo(19, 1, 0, "final")  <= (19, 2) | ||||||
|  |     True | ||||||
|  |     >>> attr.VersionInfo(19, 1, 0, "final") < (19, 1, 1) | ||||||
|  |     True | ||||||
|  |     >>> vi = attr.VersionInfo(19, 2, 0, "final") | ||||||
|  |     >>> vi < (19, 1, 1) | ||||||
|  |     False | ||||||
|  |     >>> vi < (19,) | ||||||
|  |     False | ||||||
|  |     >>> vi == (19, 2,) | ||||||
|  |     True | ||||||
|  |     >>> vi == (19, 2, 1) | ||||||
|  |     False | ||||||
|  | 
 | ||||||
|  |     .. versionadded:: 19.2 | ||||||
|  |     """ | ||||||
|  | 
 | ||||||
|  |     year = attrib(type=int) | ||||||
|  |     minor = attrib(type=int) | ||||||
|  |     micro = attrib(type=int) | ||||||
|  |     releaselevel = attrib(type=str) | ||||||
|  | 
 | ||||||
|  |     @classmethod | ||||||
|  |     def _from_version_string(cls, s): | ||||||
|  |         """ | ||||||
|  |         Parse *s* and return a _VersionInfo. | ||||||
|  |         """ | ||||||
|  |         v = s.split(".") | ||||||
|  |         if len(v) == 3: | ||||||
|  |             v.append("final") | ||||||
|  | 
 | ||||||
|  |         return cls( | ||||||
|  |             year=int(v[0]), minor=int(v[1]), micro=int(v[2]), releaselevel=v[3] | ||||||
|  |         ) | ||||||
|  | 
 | ||||||
|  |     def _ensure_tuple(self, other): | ||||||
|  |         """ | ||||||
|  |         Ensure *other* is a tuple of a valid length. | ||||||
|  | 
 | ||||||
|  |         Returns a possibly transformed *other* and ourselves as a tuple of | ||||||
|  |         the same length as *other*. | ||||||
|  |         """ | ||||||
|  | 
 | ||||||
|  |         if self.__class__ is other.__class__: | ||||||
|  |             other = astuple(other) | ||||||
|  | 
 | ||||||
|  |         if not isinstance(other, tuple): | ||||||
|  |             raise NotImplementedError | ||||||
|  | 
 | ||||||
|  |         if not (1 <= len(other) <= 4): | ||||||
|  |             raise NotImplementedError | ||||||
|  | 
 | ||||||
|  |         return astuple(self)[: len(other)], other | ||||||
|  | 
 | ||||||
|  |     def __eq__(self, other): | ||||||
|  |         try: | ||||||
|  |             us, them = self._ensure_tuple(other) | ||||||
|  |         except NotImplementedError: | ||||||
|  |             return NotImplemented | ||||||
|  | 
 | ||||||
|  |         return us == them | ||||||
|  | 
 | ||||||
|  |     def __lt__(self, other): | ||||||
|  |         try: | ||||||
|  |             us, them = self._ensure_tuple(other) | ||||||
|  |         except NotImplementedError: | ||||||
|  |             return NotImplemented | ||||||
|  | 
 | ||||||
|  |         # Since alphabetically "dev0" < "final" < "post1" < "post2", we don't | ||||||
|  |         # have to do anything special with releaselevel for now. | ||||||
|  |         return us < them | ||||||
							
								
								
									
										111
									
								
								lib/spack/external/attr/converters.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										111
									
								
								lib/spack/external/attr/converters.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,111 @@ | |||||||
|  | """ | ||||||
|  | Commonly useful converters. | ||||||
|  | """ | ||||||
|  | 
 | ||||||
|  | from __future__ import absolute_import, division, print_function | ||||||
|  | 
 | ||||||
|  | from ._compat import PY2 | ||||||
|  | from ._make import NOTHING, Factory, pipe | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | if not PY2: | ||||||
|  |     import inspect | ||||||
|  |     import typing | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | __all__ = [ | ||||||
|  |     "pipe", | ||||||
|  |     "optional", | ||||||
|  |     "default_if_none", | ||||||
|  | ] | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def optional(converter): | ||||||
|  |     """ | ||||||
|  |     A converter that allows an attribute to be optional. An optional attribute | ||||||
|  |     is one which can be set to ``None``. | ||||||
|  | 
 | ||||||
|  |     Type annotations will be inferred from the wrapped converter's, if it | ||||||
|  |     has any. | ||||||
|  | 
 | ||||||
|  |     :param callable converter: the converter that is used for non-``None`` | ||||||
|  |         values. | ||||||
|  | 
 | ||||||
|  |     .. versionadded:: 17.1.0 | ||||||
|  |     """ | ||||||
|  | 
 | ||||||
|  |     def optional_converter(val): | ||||||
|  |         if val is None: | ||||||
|  |             return None | ||||||
|  |         return converter(val) | ||||||
|  | 
 | ||||||
|  |     if not PY2: | ||||||
|  |         sig = None | ||||||
|  |         try: | ||||||
|  |             sig = inspect.signature(converter) | ||||||
|  |         except (ValueError, TypeError):  # inspect failed | ||||||
|  |             pass | ||||||
|  |         if sig: | ||||||
|  |             params = list(sig.parameters.values()) | ||||||
|  |             if params and params[0].annotation is not inspect.Parameter.empty: | ||||||
|  |                 optional_converter.__annotations__["val"] = typing.Optional[ | ||||||
|  |                     params[0].annotation | ||||||
|  |                 ] | ||||||
|  |             if sig.return_annotation is not inspect.Signature.empty: | ||||||
|  |                 optional_converter.__annotations__["return"] = typing.Optional[ | ||||||
|  |                     sig.return_annotation | ||||||
|  |                 ] | ||||||
|  | 
 | ||||||
|  |     return optional_converter | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def default_if_none(default=NOTHING, factory=None): | ||||||
|  |     """ | ||||||
|  |     A converter that allows to replace ``None`` values by *default* or the | ||||||
|  |     result of *factory*. | ||||||
|  | 
 | ||||||
|  |     :param default: Value to be used if ``None`` is passed. Passing an instance | ||||||
|  |        of `attr.Factory` is supported, however the ``takes_self`` option | ||||||
|  |        is *not*. | ||||||
|  |     :param callable factory: A callable that takes no parameters whose result | ||||||
|  |        is used if ``None`` is passed. | ||||||
|  | 
 | ||||||
|  |     :raises TypeError: If **neither** *default* or *factory* is passed. | ||||||
|  |     :raises TypeError: If **both** *default* and *factory* are passed. | ||||||
|  |     :raises ValueError: If an instance of `attr.Factory` is passed with | ||||||
|  |        ``takes_self=True``. | ||||||
|  | 
 | ||||||
|  |     .. versionadded:: 18.2.0 | ||||||
|  |     """ | ||||||
|  |     if default is NOTHING and factory is None: | ||||||
|  |         raise TypeError("Must pass either `default` or `factory`.") | ||||||
|  | 
 | ||||||
|  |     if default is not NOTHING and factory is not None: | ||||||
|  |         raise TypeError( | ||||||
|  |             "Must pass either `default` or `factory` but not both." | ||||||
|  |         ) | ||||||
|  | 
 | ||||||
|  |     if factory is not None: | ||||||
|  |         default = Factory(factory) | ||||||
|  | 
 | ||||||
|  |     if isinstance(default, Factory): | ||||||
|  |         if default.takes_self: | ||||||
|  |             raise ValueError( | ||||||
|  |                 "`takes_self` is not supported by default_if_none." | ||||||
|  |             ) | ||||||
|  | 
 | ||||||
|  |         def default_if_none_converter(val): | ||||||
|  |             if val is not None: | ||||||
|  |                 return val | ||||||
|  | 
 | ||||||
|  |             return default.factory() | ||||||
|  | 
 | ||||||
|  |     else: | ||||||
|  | 
 | ||||||
|  |         def default_if_none_converter(val): | ||||||
|  |             if val is not None: | ||||||
|  |                 return val | ||||||
|  | 
 | ||||||
|  |             return default | ||||||
|  | 
 | ||||||
|  |     return default_if_none_converter | ||||||
							
								
								
									
										92
									
								
								lib/spack/external/attr/exceptions.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								lib/spack/external/attr/exceptions.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,92 @@ | |||||||
|  | from __future__ import absolute_import, division, print_function | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class FrozenError(AttributeError): | ||||||
|  |     """ | ||||||
|  |     A frozen/immutable instance or attribute have been attempted to be | ||||||
|  |     modified. | ||||||
|  | 
 | ||||||
|  |     It mirrors the behavior of ``namedtuples`` by using the same error message | ||||||
|  |     and subclassing `AttributeError`. | ||||||
|  | 
 | ||||||
|  |     .. versionadded:: 20.1.0 | ||||||
|  |     """ | ||||||
|  | 
 | ||||||
|  |     msg = "can't set attribute" | ||||||
|  |     args = [msg] | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class FrozenInstanceError(FrozenError): | ||||||
|  |     """ | ||||||
|  |     A frozen instance has been attempted to be modified. | ||||||
|  | 
 | ||||||
|  |     .. versionadded:: 16.1.0 | ||||||
|  |     """ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class FrozenAttributeError(FrozenError): | ||||||
|  |     """ | ||||||
|  |     A frozen attribute has been attempted to be modified. | ||||||
|  | 
 | ||||||
|  |     .. versionadded:: 20.1.0 | ||||||
|  |     """ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class AttrsAttributeNotFoundError(ValueError): | ||||||
|  |     """ | ||||||
|  |     An ``attrs`` function couldn't find an attribute that the user asked for. | ||||||
|  | 
 | ||||||
|  |     .. versionadded:: 16.2.0 | ||||||
|  |     """ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class NotAnAttrsClassError(ValueError): | ||||||
|  |     """ | ||||||
|  |     A non-``attrs`` class has been passed into an ``attrs`` function. | ||||||
|  | 
 | ||||||
|  |     .. versionadded:: 16.2.0 | ||||||
|  |     """ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class DefaultAlreadySetError(RuntimeError): | ||||||
|  |     """ | ||||||
|  |     A default has been set using ``attr.ib()`` and is attempted to be reset | ||||||
|  |     using the decorator. | ||||||
|  | 
 | ||||||
|  |     .. versionadded:: 17.1.0 | ||||||
|  |     """ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class UnannotatedAttributeError(RuntimeError): | ||||||
|  |     """ | ||||||
|  |     A class with ``auto_attribs=True`` has an ``attr.ib()`` without a type | ||||||
|  |     annotation. | ||||||
|  | 
 | ||||||
|  |     .. versionadded:: 17.3.0 | ||||||
|  |     """ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class PythonTooOldError(RuntimeError): | ||||||
|  |     """ | ||||||
|  |     It was attempted to use an ``attrs`` feature that requires a newer Python | ||||||
|  |     version. | ||||||
|  | 
 | ||||||
|  |     .. versionadded:: 18.2.0 | ||||||
|  |     """ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class NotCallableError(TypeError): | ||||||
|  |     """ | ||||||
|  |     A ``attr.ib()`` requiring a callable has been set with a value | ||||||
|  |     that is not callable. | ||||||
|  | 
 | ||||||
|  |     .. versionadded:: 19.2.0 | ||||||
|  |     """ | ||||||
|  | 
 | ||||||
|  |     def __init__(self, msg, value): | ||||||
|  |         super(TypeError, self).__init__(msg, value) | ||||||
|  |         self.msg = msg | ||||||
|  |         self.value = value | ||||||
|  | 
 | ||||||
|  |     def __str__(self): | ||||||
|  |         return str(self.msg) | ||||||
							
								
								
									
										52
									
								
								lib/spack/external/attr/filters.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								lib/spack/external/attr/filters.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,52 @@ | |||||||
|  | """ | ||||||
|  | Commonly useful filters for `attr.asdict`. | ||||||
|  | """ | ||||||
|  | 
 | ||||||
|  | from __future__ import absolute_import, division, print_function | ||||||
|  | 
 | ||||||
|  | from ._compat import isclass | ||||||
|  | from ._make import Attribute | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def _split_what(what): | ||||||
|  |     """ | ||||||
|  |     Returns a tuple of `frozenset`s of classes and attributes. | ||||||
|  |     """ | ||||||
|  |     return ( | ||||||
|  |         frozenset(cls for cls in what if isclass(cls)), | ||||||
|  |         frozenset(cls for cls in what if isinstance(cls, Attribute)), | ||||||
|  |     ) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def include(*what): | ||||||
|  |     """ | ||||||
|  |     Whitelist *what*. | ||||||
|  | 
 | ||||||
|  |     :param what: What to whitelist. | ||||||
|  |     :type what: `list` of `type` or `attr.Attribute`\\ s | ||||||
|  | 
 | ||||||
|  |     :rtype: `callable` | ||||||
|  |     """ | ||||||
|  |     cls, attrs = _split_what(what) | ||||||
|  | 
 | ||||||
|  |     def include_(attribute, value): | ||||||
|  |         return value.__class__ in cls or attribute in attrs | ||||||
|  | 
 | ||||||
|  |     return include_ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def exclude(*what): | ||||||
|  |     """ | ||||||
|  |     Blacklist *what*. | ||||||
|  | 
 | ||||||
|  |     :param what: What to blacklist. | ||||||
|  |     :type what: `list` of classes or `attr.Attribute`\\ s. | ||||||
|  | 
 | ||||||
|  |     :rtype: `callable` | ||||||
|  |     """ | ||||||
|  |     cls, attrs = _split_what(what) | ||||||
|  | 
 | ||||||
|  |     def exclude_(attribute, value): | ||||||
|  |         return value.__class__ not in cls and attribute not in attrs | ||||||
|  | 
 | ||||||
|  |     return exclude_ | ||||||
							
								
								
									
										77
									
								
								lib/spack/external/attr/setters.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								lib/spack/external/attr/setters.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,77 @@ | |||||||
|  | """ | ||||||
|  | Commonly used hooks for on_setattr. | ||||||
|  | """ | ||||||
|  | 
 | ||||||
|  | from __future__ import absolute_import, division, print_function | ||||||
|  | 
 | ||||||
|  | from . import _config | ||||||
|  | from .exceptions import FrozenAttributeError | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def pipe(*setters): | ||||||
|  |     """ | ||||||
|  |     Run all *setters* and return the return value of the last one. | ||||||
|  | 
 | ||||||
|  |     .. versionadded:: 20.1.0 | ||||||
|  |     """ | ||||||
|  | 
 | ||||||
|  |     def wrapped_pipe(instance, attrib, new_value): | ||||||
|  |         rv = new_value | ||||||
|  | 
 | ||||||
|  |         for setter in setters: | ||||||
|  |             rv = setter(instance, attrib, rv) | ||||||
|  | 
 | ||||||
|  |         return rv | ||||||
|  | 
 | ||||||
|  |     return wrapped_pipe | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def frozen(_, __, ___): | ||||||
|  |     """ | ||||||
|  |     Prevent an attribute to be modified. | ||||||
|  | 
 | ||||||
|  |     .. versionadded:: 20.1.0 | ||||||
|  |     """ | ||||||
|  |     raise FrozenAttributeError() | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def validate(instance, attrib, new_value): | ||||||
|  |     """ | ||||||
|  |     Run *attrib*'s validator on *new_value* if it has one. | ||||||
|  | 
 | ||||||
|  |     .. versionadded:: 20.1.0 | ||||||
|  |     """ | ||||||
|  |     if _config._run_validators is False: | ||||||
|  |         return new_value | ||||||
|  | 
 | ||||||
|  |     v = attrib.validator | ||||||
|  |     if not v: | ||||||
|  |         return new_value | ||||||
|  | 
 | ||||||
|  |     v(instance, attrib, new_value) | ||||||
|  | 
 | ||||||
|  |     return new_value | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def convert(instance, attrib, new_value): | ||||||
|  |     """ | ||||||
|  |     Run *attrib*'s converter -- if it has one --  on *new_value* and return the | ||||||
|  |     result. | ||||||
|  | 
 | ||||||
|  |     .. versionadded:: 20.1.0 | ||||||
|  |     """ | ||||||
|  |     c = attrib.converter | ||||||
|  |     if c: | ||||||
|  |         return c(new_value) | ||||||
|  | 
 | ||||||
|  |     return new_value | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | NO_OP = object() | ||||||
|  | """ | ||||||
|  | Sentinel for disabling class-wide *on_setattr* hooks for certain attributes. | ||||||
|  | 
 | ||||||
|  | Does not work in `pipe` or within lists. | ||||||
|  | 
 | ||||||
|  | .. versionadded:: 20.1.0 | ||||||
|  | """ | ||||||
							
								
								
									
										379
									
								
								lib/spack/external/attr/validators.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										379
									
								
								lib/spack/external/attr/validators.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,379 @@ | |||||||
|  | """ | ||||||
|  | Commonly useful validators. | ||||||
|  | """ | ||||||
|  | 
 | ||||||
|  | from __future__ import absolute_import, division, print_function | ||||||
|  | 
 | ||||||
|  | import re | ||||||
|  | 
 | ||||||
|  | from ._make import _AndValidator, and_, attrib, attrs | ||||||
|  | from .exceptions import NotCallableError | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | __all__ = [ | ||||||
|  |     "and_", | ||||||
|  |     "deep_iterable", | ||||||
|  |     "deep_mapping", | ||||||
|  |     "in_", | ||||||
|  |     "instance_of", | ||||||
|  |     "is_callable", | ||||||
|  |     "matches_re", | ||||||
|  |     "optional", | ||||||
|  |     "provides", | ||||||
|  | ] | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @attrs(repr=False, slots=True, hash=True) | ||||||
|  | class _InstanceOfValidator(object): | ||||||
|  |     type = attrib() | ||||||
|  | 
 | ||||||
|  |     def __call__(self, inst, attr, value): | ||||||
|  |         """ | ||||||
|  |         We use a callable class to be able to change the ``__repr__``. | ||||||
|  |         """ | ||||||
|  |         if not isinstance(value, self.type): | ||||||
|  |             raise TypeError( | ||||||
|  |                 "'{name}' must be {type!r} (got {value!r} that is a " | ||||||
|  |                 "{actual!r}).".format( | ||||||
|  |                     name=attr.name, | ||||||
|  |                     type=self.type, | ||||||
|  |                     actual=value.__class__, | ||||||
|  |                     value=value, | ||||||
|  |                 ), | ||||||
|  |                 attr, | ||||||
|  |                 self.type, | ||||||
|  |                 value, | ||||||
|  |             ) | ||||||
|  | 
 | ||||||
|  |     def __repr__(self): | ||||||
|  |         return "<instance_of validator for type {type!r}>".format( | ||||||
|  |             type=self.type | ||||||
|  |         ) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def instance_of(type): | ||||||
|  |     """ | ||||||
|  |     A validator that raises a `TypeError` if the initializer is called | ||||||
|  |     with a wrong type for this particular attribute (checks are performed using | ||||||
|  |     `isinstance` therefore it's also valid to pass a tuple of types). | ||||||
|  | 
 | ||||||
|  |     :param type: The type to check for. | ||||||
|  |     :type type: type or tuple of types | ||||||
|  | 
 | ||||||
|  |     :raises TypeError: With a human readable error message, the attribute | ||||||
|  |         (of type `attr.Attribute`), the expected type, and the value it | ||||||
|  |         got. | ||||||
|  |     """ | ||||||
|  |     return _InstanceOfValidator(type) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @attrs(repr=False, frozen=True, slots=True) | ||||||
|  | class _MatchesReValidator(object): | ||||||
|  |     regex = attrib() | ||||||
|  |     flags = attrib() | ||||||
|  |     match_func = attrib() | ||||||
|  | 
 | ||||||
|  |     def __call__(self, inst, attr, value): | ||||||
|  |         """ | ||||||
|  |         We use a callable class to be able to change the ``__repr__``. | ||||||
|  |         """ | ||||||
|  |         if not self.match_func(value): | ||||||
|  |             raise ValueError( | ||||||
|  |                 "'{name}' must match regex {regex!r}" | ||||||
|  |                 " ({value!r} doesn't)".format( | ||||||
|  |                     name=attr.name, regex=self.regex.pattern, value=value | ||||||
|  |                 ), | ||||||
|  |                 attr, | ||||||
|  |                 self.regex, | ||||||
|  |                 value, | ||||||
|  |             ) | ||||||
|  | 
 | ||||||
|  |     def __repr__(self): | ||||||
|  |         return "<matches_re validator for pattern {regex!r}>".format( | ||||||
|  |             regex=self.regex | ||||||
|  |         ) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def matches_re(regex, flags=0, func=None): | ||||||
|  |     r""" | ||||||
|  |     A validator that raises `ValueError` if the initializer is called | ||||||
|  |     with a string that doesn't match *regex*. | ||||||
|  | 
 | ||||||
|  |     :param str regex: a regex string to match against | ||||||
|  |     :param int flags: flags that will be passed to the underlying re function | ||||||
|  |         (default 0) | ||||||
|  |     :param callable func: which underlying `re` function to call (options | ||||||
|  |         are `re.fullmatch`, `re.search`, `re.match`, default | ||||||
|  |         is ``None`` which means either `re.fullmatch` or an emulation of | ||||||
|  |         it on Python 2). For performance reasons, they won't be used directly | ||||||
|  |         but on a pre-`re.compile`\ ed pattern. | ||||||
|  | 
 | ||||||
|  |     .. versionadded:: 19.2.0 | ||||||
|  |     """ | ||||||
|  |     fullmatch = getattr(re, "fullmatch", None) | ||||||
|  |     valid_funcs = (fullmatch, None, re.search, re.match) | ||||||
|  |     if func not in valid_funcs: | ||||||
|  |         raise ValueError( | ||||||
|  |             "'func' must be one of %s." | ||||||
|  |             % ( | ||||||
|  |                 ", ".join( | ||||||
|  |                     sorted( | ||||||
|  |                         e and e.__name__ or "None" for e in set(valid_funcs) | ||||||
|  |                     ) | ||||||
|  |                 ), | ||||||
|  |             ) | ||||||
|  |         ) | ||||||
|  | 
 | ||||||
|  |     pattern = re.compile(regex, flags) | ||||||
|  |     if func is re.match: | ||||||
|  |         match_func = pattern.match | ||||||
|  |     elif func is re.search: | ||||||
|  |         match_func = pattern.search | ||||||
|  |     else: | ||||||
|  |         if fullmatch: | ||||||
|  |             match_func = pattern.fullmatch | ||||||
|  |         else: | ||||||
|  |             pattern = re.compile(r"(?:{})\Z".format(regex), flags) | ||||||
|  |             match_func = pattern.match | ||||||
|  | 
 | ||||||
|  |     return _MatchesReValidator(pattern, flags, match_func) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @attrs(repr=False, slots=True, hash=True) | ||||||
|  | class _ProvidesValidator(object): | ||||||
|  |     interface = attrib() | ||||||
|  | 
 | ||||||
|  |     def __call__(self, inst, attr, value): | ||||||
|  |         """ | ||||||
|  |         We use a callable class to be able to change the ``__repr__``. | ||||||
|  |         """ | ||||||
|  |         if not self.interface.providedBy(value): | ||||||
|  |             raise TypeError( | ||||||
|  |                 "'{name}' must provide {interface!r} which {value!r} " | ||||||
|  |                 "doesn't.".format( | ||||||
|  |                     name=attr.name, interface=self.interface, value=value | ||||||
|  |                 ), | ||||||
|  |                 attr, | ||||||
|  |                 self.interface, | ||||||
|  |                 value, | ||||||
|  |             ) | ||||||
|  | 
 | ||||||
|  |     def __repr__(self): | ||||||
|  |         return "<provides validator for interface {interface!r}>".format( | ||||||
|  |             interface=self.interface | ||||||
|  |         ) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def provides(interface): | ||||||
|  |     """ | ||||||
|  |     A validator that raises a `TypeError` if the initializer is called | ||||||
|  |     with an object that does not provide the requested *interface* (checks are | ||||||
|  |     performed using ``interface.providedBy(value)`` (see `zope.interface | ||||||
|  |     <https://zopeinterface.readthedocs.io/en/latest/>`_). | ||||||
|  | 
 | ||||||
|  |     :param interface: The interface to check for. | ||||||
|  |     :type interface: ``zope.interface.Interface`` | ||||||
|  | 
 | ||||||
|  |     :raises TypeError: With a human readable error message, the attribute | ||||||
|  |         (of type `attr.Attribute`), the expected interface, and the | ||||||
|  |         value it got. | ||||||
|  |     """ | ||||||
|  |     return _ProvidesValidator(interface) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @attrs(repr=False, slots=True, hash=True) | ||||||
|  | class _OptionalValidator(object): | ||||||
|  |     validator = attrib() | ||||||
|  | 
 | ||||||
|  |     def __call__(self, inst, attr, value): | ||||||
|  |         if value is None: | ||||||
|  |             return | ||||||
|  | 
 | ||||||
|  |         self.validator(inst, attr, value) | ||||||
|  | 
 | ||||||
|  |     def __repr__(self): | ||||||
|  |         return "<optional validator for {what} or None>".format( | ||||||
|  |             what=repr(self.validator) | ||||||
|  |         ) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def optional(validator): | ||||||
|  |     """ | ||||||
|  |     A validator that makes an attribute optional.  An optional attribute is one | ||||||
|  |     which can be set to ``None`` in addition to satisfying the requirements of | ||||||
|  |     the sub-validator. | ||||||
|  | 
 | ||||||
|  |     :param validator: A validator (or a list of validators) that is used for | ||||||
|  |         non-``None`` values. | ||||||
|  |     :type validator: callable or `list` of callables. | ||||||
|  | 
 | ||||||
|  |     .. versionadded:: 15.1.0 | ||||||
|  |     .. versionchanged:: 17.1.0 *validator* can be a list of validators. | ||||||
|  |     """ | ||||||
|  |     if isinstance(validator, list): | ||||||
|  |         return _OptionalValidator(_AndValidator(validator)) | ||||||
|  |     return _OptionalValidator(validator) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @attrs(repr=False, slots=True, hash=True) | ||||||
|  | class _InValidator(object): | ||||||
|  |     options = attrib() | ||||||
|  | 
 | ||||||
|  |     def __call__(self, inst, attr, value): | ||||||
|  |         try: | ||||||
|  |             in_options = value in self.options | ||||||
|  |         except TypeError:  # e.g. `1 in "abc"` | ||||||
|  |             in_options = False | ||||||
|  | 
 | ||||||
|  |         if not in_options: | ||||||
|  |             raise ValueError( | ||||||
|  |                 "'{name}' must be in {options!r} (got {value!r})".format( | ||||||
|  |                     name=attr.name, options=self.options, value=value | ||||||
|  |                 ) | ||||||
|  |             ) | ||||||
|  | 
 | ||||||
|  |     def __repr__(self): | ||||||
|  |         return "<in_ validator with options {options!r}>".format( | ||||||
|  |             options=self.options | ||||||
|  |         ) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def in_(options): | ||||||
|  |     """ | ||||||
|  |     A validator that raises a `ValueError` if the initializer is called | ||||||
|  |     with a value that does not belong in the options provided.  The check is | ||||||
|  |     performed using ``value in options``. | ||||||
|  | 
 | ||||||
|  |     :param options: Allowed options. | ||||||
|  |     :type options: list, tuple, `enum.Enum`, ... | ||||||
|  | 
 | ||||||
|  |     :raises ValueError: With a human readable error message, the attribute (of | ||||||
|  |        type `attr.Attribute`), the expected options, and the value it | ||||||
|  |        got. | ||||||
|  | 
 | ||||||
|  |     .. versionadded:: 17.1.0 | ||||||
|  |     """ | ||||||
|  |     return _InValidator(options) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @attrs(repr=False, slots=False, hash=True) | ||||||
|  | class _IsCallableValidator(object): | ||||||
|  |     def __call__(self, inst, attr, value): | ||||||
|  |         """ | ||||||
|  |         We use a callable class to be able to change the ``__repr__``. | ||||||
|  |         """ | ||||||
|  |         if not callable(value): | ||||||
|  |             message = ( | ||||||
|  |                 "'{name}' must be callable " | ||||||
|  |                 "(got {value!r} that is a {actual!r})." | ||||||
|  |             ) | ||||||
|  |             raise NotCallableError( | ||||||
|  |                 msg=message.format( | ||||||
|  |                     name=attr.name, value=value, actual=value.__class__ | ||||||
|  |                 ), | ||||||
|  |                 value=value, | ||||||
|  |             ) | ||||||
|  | 
 | ||||||
|  |     def __repr__(self): | ||||||
|  |         return "<is_callable validator>" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def is_callable(): | ||||||
|  |     """ | ||||||
|  |     A validator that raises a `attr.exceptions.NotCallableError` if the | ||||||
|  |     initializer is called with a value for this particular attribute | ||||||
|  |     that is not callable. | ||||||
|  | 
 | ||||||
|  |     .. versionadded:: 19.1.0 | ||||||
|  | 
 | ||||||
|  |     :raises `attr.exceptions.NotCallableError`: With a human readable error | ||||||
|  |         message containing the attribute (`attr.Attribute`) name, | ||||||
|  |         and the value it got. | ||||||
|  |     """ | ||||||
|  |     return _IsCallableValidator() | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @attrs(repr=False, slots=True, hash=True) | ||||||
|  | class _DeepIterable(object): | ||||||
|  |     member_validator = attrib(validator=is_callable()) | ||||||
|  |     iterable_validator = attrib( | ||||||
|  |         default=None, validator=optional(is_callable()) | ||||||
|  |     ) | ||||||
|  | 
 | ||||||
|  |     def __call__(self, inst, attr, value): | ||||||
|  |         """ | ||||||
|  |         We use a callable class to be able to change the ``__repr__``. | ||||||
|  |         """ | ||||||
|  |         if self.iterable_validator is not None: | ||||||
|  |             self.iterable_validator(inst, attr, value) | ||||||
|  | 
 | ||||||
|  |         for member in value: | ||||||
|  |             self.member_validator(inst, attr, member) | ||||||
|  | 
 | ||||||
|  |     def __repr__(self): | ||||||
|  |         iterable_identifier = ( | ||||||
|  |             "" | ||||||
|  |             if self.iterable_validator is None | ||||||
|  |             else " {iterable!r}".format(iterable=self.iterable_validator) | ||||||
|  |         ) | ||||||
|  |         return ( | ||||||
|  |             "<deep_iterable validator for{iterable_identifier}" | ||||||
|  |             " iterables of {member!r}>" | ||||||
|  |         ).format( | ||||||
|  |             iterable_identifier=iterable_identifier, | ||||||
|  |             member=self.member_validator, | ||||||
|  |         ) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def deep_iterable(member_validator, iterable_validator=None): | ||||||
|  |     """ | ||||||
|  |     A validator that performs deep validation of an iterable. | ||||||
|  | 
 | ||||||
|  |     :param member_validator: Validator to apply to iterable members | ||||||
|  |     :param iterable_validator: Validator to apply to iterable itself | ||||||
|  |         (optional) | ||||||
|  | 
 | ||||||
|  |     .. versionadded:: 19.1.0 | ||||||
|  | 
 | ||||||
|  |     :raises TypeError: if any sub-validators fail | ||||||
|  |     """ | ||||||
|  |     return _DeepIterable(member_validator, iterable_validator) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @attrs(repr=False, slots=True, hash=True) | ||||||
|  | class _DeepMapping(object): | ||||||
|  |     key_validator = attrib(validator=is_callable()) | ||||||
|  |     value_validator = attrib(validator=is_callable()) | ||||||
|  |     mapping_validator = attrib(default=None, validator=optional(is_callable())) | ||||||
|  | 
 | ||||||
|  |     def __call__(self, inst, attr, value): | ||||||
|  |         """ | ||||||
|  |         We use a callable class to be able to change the ``__repr__``. | ||||||
|  |         """ | ||||||
|  |         if self.mapping_validator is not None: | ||||||
|  |             self.mapping_validator(inst, attr, value) | ||||||
|  | 
 | ||||||
|  |         for key in value: | ||||||
|  |             self.key_validator(inst, attr, key) | ||||||
|  |             self.value_validator(inst, attr, value[key]) | ||||||
|  | 
 | ||||||
|  |     def __repr__(self): | ||||||
|  |         return ( | ||||||
|  |             "<deep_mapping validator for objects mapping {key!r} to {value!r}>" | ||||||
|  |         ).format(key=self.key_validator, value=self.value_validator) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def deep_mapping(key_validator, value_validator, mapping_validator=None): | ||||||
|  |     """ | ||||||
|  |     A validator that performs deep validation of a dictionary. | ||||||
|  | 
 | ||||||
|  |     :param key_validator: Validator to apply to dictionary keys | ||||||
|  |     :param value_validator: Validator to apply to dictionary values | ||||||
|  |     :param mapping_validator: Validator to apply to top-level mapping | ||||||
|  |         attribute (optional) | ||||||
|  | 
 | ||||||
|  |     .. versionadded:: 19.1.0 | ||||||
|  | 
 | ||||||
|  |     :raises TypeError: if any sub-validators fail | ||||||
|  |     """ | ||||||
|  |     return _DeepMapping(key_validator, value_validator, mapping_validator) | ||||||
		Reference in New Issue
	
	Block a user
	 Todd Gamblin
					Todd Gamblin