externals: add functools32 for new jsonschema
				
					
				
			Updating `jsonschema` to 3.2.0 requires `functools32`, just for Python 2.
This commit is contained in:
		| @@ -46,8 +46,8 @@ PackageName: distro | |||||||
| PackageHomePage: https://pypi.python.org/pypi/distro | PackageHomePage: https://pypi.python.org/pypi/distro | ||||||
| PackageLicenseDeclared: Apache-2.0 | PackageLicenseDeclared: Apache-2.0 | ||||||
|  |  | ||||||
| PackageName: functools | PackageName: functools32 | ||||||
| PackageHomePage: https://github.com/python/cpython/blob/2.7/Lib/functools.py | PackageHomePage: https://github.com/MiCHiLU/python-functools32 | ||||||
| PackageLicenseDeclared: Python-2.0 | PackageLicenseDeclared: Python-2.0 | ||||||
|  |  | ||||||
| PackageName: jinja2 | PackageName: jinja2 | ||||||
|   | |||||||
							
								
								
									
										6
									
								
								lib/spack/external/__init__.py
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								lib/spack/external/__init__.py
									
									
									
									
										vendored
									
									
								
							| @@ -40,6 +40,12 @@ | |||||||
| * Version: 1.6.0 (64946a1e2a9ff529047070657728600e006c99ff) | * Version: 1.6.0 (64946a1e2a9ff529047070657728600e006c99ff) | ||||||
| * Note: Last version supporting Python 2.7 | * Note: Last version supporting Python 2.7 | ||||||
| 
 | 
 | ||||||
|  | functools32 | ||||||
|  | ----------- | ||||||
|  | * Homepage: https://github.com/MiCHiLU/python-functools32 | ||||||
|  | * Usage: Needed by jsonschema when using Python 2.7. | ||||||
|  | * Version: 3.2.3-2 | ||||||
|  | 
 | ||||||
| jinja2 | jinja2 | ||||||
| ------ | ------ | ||||||
| 
 | 
 | ||||||
|   | |||||||
							
								
								
									
										289
									
								
								lib/spack/external/py2/functools32/LICENSE
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										289
									
								
								lib/spack/external/py2/functools32/LICENSE
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,289 @@ | |||||||
|  | A. HISTORY OF THE SOFTWARE | ||||||
|  | ========================== | ||||||
|  |  | ||||||
|  | Python was created in the early 1990s by Guido van Rossum at Stichting | ||||||
|  | Mathematisch Centrum (CWI, see http://www.cwi.nl) in the Netherlands | ||||||
|  | as a successor of a language called ABC.  Guido remains Python's | ||||||
|  | principal author, although it includes many contributions from others. | ||||||
|  |  | ||||||
|  | In 1995, Guido continued his work on Python at the Corporation for | ||||||
|  | National Research Initiatives (CNRI, see http://www.cnri.reston.va.us) | ||||||
|  | in Reston, Virginia where he released several versions of the | ||||||
|  | software. | ||||||
|  |  | ||||||
|  | In May 2000, Guido and the Python core development team moved to | ||||||
|  | BeOpen.com to form the BeOpen PythonLabs team.  In October of the same | ||||||
|  | year, the PythonLabs team moved to Digital Creations (now Zope | ||||||
|  | Corporation, see http://www.zope.com).  In 2001, the Python Software | ||||||
|  | Foundation (PSF, see http://www.python.org/psf/) was formed, a | ||||||
|  | non-profit organization created specifically to own Python-related | ||||||
|  | Intellectual Property.  Zope Corporation is a sponsoring member of | ||||||
|  | the PSF. | ||||||
|  |  | ||||||
|  | All Python releases are Open Source (see http://www.opensource.org for | ||||||
|  | the Open Source Definition).  Historically, most, but not all, Python | ||||||
|  | releases have also been GPL-compatible; the table below summarizes | ||||||
|  | the various releases. | ||||||
|  |  | ||||||
|  |     Release         Derived     Year        Owner       GPL- | ||||||
|  |                     from                                compatible? (1) | ||||||
|  |  | ||||||
|  |     0.9.0 thru 1.2              1991-1995   CWI         yes | ||||||
|  |     1.3 thru 1.5.2  1.2         1995-1999   CNRI        yes | ||||||
|  |     1.6             1.5.2       2000        CNRI        no | ||||||
|  |     2.0             1.6         2000        BeOpen.com  no | ||||||
|  |     1.6.1           1.6         2001        CNRI        yes (2) | ||||||
|  |     2.1             2.0+1.6.1   2001        PSF         no | ||||||
|  |     2.0.1           2.0+1.6.1   2001        PSF         yes | ||||||
|  |     2.1.1           2.1+2.0.1   2001        PSF         yes | ||||||
|  |     2.2             2.1.1       2001        PSF         yes | ||||||
|  |     2.1.2           2.1.1       2002        PSF         yes | ||||||
|  |     2.1.3           2.1.2       2002        PSF         yes | ||||||
|  |     2.2.1           2.2         2002        PSF         yes | ||||||
|  |     2.2.2           2.2.1       2002        PSF         yes | ||||||
|  |     2.2.3           2.2.2       2003        PSF         yes | ||||||
|  |     2.3             2.2.2       2002-2003   PSF         yes | ||||||
|  |     2.3.1           2.3         2002-2003   PSF         yes | ||||||
|  |     2.3.2           2.3.1       2002-2003   PSF         yes | ||||||
|  |     2.3.3           2.3.2       2002-2003   PSF         yes | ||||||
|  |     2.3.4           2.3.3       2004        PSF         yes | ||||||
|  |     2.3.5           2.3.4       2005        PSF         yes | ||||||
|  |     2.4             2.3         2004        PSF         yes | ||||||
|  |     2.4.1           2.4         2005        PSF         yes | ||||||
|  |     2.4.2           2.4.1       2005        PSF         yes | ||||||
|  |     2.4.3           2.4.2       2006        PSF         yes | ||||||
|  |     2.4.4           2.4.3       2006        PSF         yes | ||||||
|  |     2.5             2.4         2006        PSF         yes | ||||||
|  |     2.5.1           2.5         2007        PSF         yes | ||||||
|  |     2.5.2           2.5.1       2008        PSF         yes | ||||||
|  |     2.5.3           2.5.2       2008        PSF         yes | ||||||
|  |     2.6             2.5         2008        PSF         yes | ||||||
|  |     2.6.1           2.6         2008        PSF         yes | ||||||
|  |     2.6.2           2.6.1       2009        PSF         yes | ||||||
|  |     2.6.3           2.6.2       2009        PSF         yes | ||||||
|  |     2.6.4           2.6.3       2009        PSF         yes | ||||||
|  |     2.6.5           2.6.4       2010        PSF         yes | ||||||
|  |     3.0             2.6         2008        PSF         yes | ||||||
|  |     3.0.1           3.0         2009        PSF         yes | ||||||
|  |     3.1             3.0.1       2009        PSF         yes | ||||||
|  |     3.1.1           3.1         2009        PSF         yes | ||||||
|  |     3.1.2           3.1.1       2010        PSF         yes | ||||||
|  |     3.1.3           3.1.2       2010        PSF         yes | ||||||
|  |     3.1.4           3.1.3       2011        PSF         yes | ||||||
|  |     3.2             3.1         2011        PSF         yes | ||||||
|  |     3.2.1           3.2         2011        PSF         yes | ||||||
|  |     3.2.2           3.2.1       2011        PSF         yes | ||||||
|  |     3.2.3           3.2.2       2012        PSF         yes | ||||||
|  |  | ||||||
|  | Footnotes: | ||||||
|  |  | ||||||
|  | (1) GPL-compatible doesn't mean that we're distributing Python under | ||||||
|  |     the GPL.  All Python licenses, unlike the GPL, let you distribute | ||||||
|  |     a modified version without making your changes open source.  The | ||||||
|  |     GPL-compatible licenses make it possible to combine Python with | ||||||
|  |     other software that is released under the GPL; the others don't. | ||||||
|  |  | ||||||
|  | (2) According to Richard Stallman, 1.6.1 is not GPL-compatible, | ||||||
|  |     because its license has a choice of law clause.  According to | ||||||
|  |     CNRI, however, Stallman's lawyer has told CNRI's lawyer that 1.6.1 | ||||||
|  |     is "not incompatible" with the GPL. | ||||||
|  |  | ||||||
|  | Thanks to the many outside volunteers who have worked under Guido's | ||||||
|  | direction to make these releases possible. | ||||||
|  |  | ||||||
|  |  | ||||||
|  | B. TERMS AND CONDITIONS FOR ACCESSING OR OTHERWISE USING PYTHON | ||||||
|  | =============================================================== | ||||||
|  |  | ||||||
|  | PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 | ||||||
|  | -------------------------------------------- | ||||||
|  |  | ||||||
|  | 1. This LICENSE AGREEMENT is between the Python Software Foundation | ||||||
|  | ("PSF"), and the Individual or Organization ("Licensee") accessing and | ||||||
|  | otherwise using this software ("Python") in source or binary form and | ||||||
|  | its associated documentation. | ||||||
|  |  | ||||||
|  | 2. Subject to the terms and conditions of this License Agreement, PSF hereby | ||||||
|  | grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce, | ||||||
|  | analyze, test, perform and/or display publicly, prepare derivative works, | ||||||
|  | distribute, and otherwise use Python alone or in any derivative version, | ||||||
|  | provided, however, that PSF's License Agreement and PSF's notice of copyright, | ||||||
|  | i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, | ||||||
|  | 2011, 2012 Python Software Foundation; All Rights Reserved" are retained in Python | ||||||
|  | alone or in any derivative version prepared by Licensee. | ||||||
|  |  | ||||||
|  | 3. In the event Licensee prepares a derivative work that is based on | ||||||
|  | or incorporates Python or any part thereof, and wants to make | ||||||
|  | the derivative work available to others as provided herein, then | ||||||
|  | Licensee hereby agrees to include in any such work a brief summary of | ||||||
|  | the changes made to Python. | ||||||
|  |  | ||||||
|  | 4. PSF is making Python available to Licensee on an "AS IS" | ||||||
|  | basis.  PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR | ||||||
|  | IMPLIED.  BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND | ||||||
|  | DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS | ||||||
|  | FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT | ||||||
|  | INFRINGE ANY THIRD PARTY RIGHTS. | ||||||
|  |  | ||||||
|  | 5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON | ||||||
|  | FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS | ||||||
|  | A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON, | ||||||
|  | OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. | ||||||
|  |  | ||||||
|  | 6. This License Agreement will automatically terminate upon a material | ||||||
|  | breach of its terms and conditions. | ||||||
|  |  | ||||||
|  | 7. Nothing in this License Agreement shall be deemed to create any | ||||||
|  | relationship of agency, partnership, or joint venture between PSF and | ||||||
|  | Licensee.  This License Agreement does not grant permission to use PSF | ||||||
|  | trademarks or trade name in a trademark sense to endorse or promote | ||||||
|  | products or services of Licensee, or any third party. | ||||||
|  |  | ||||||
|  | 8. By copying, installing or otherwise using Python, Licensee | ||||||
|  | agrees to be bound by the terms and conditions of this License | ||||||
|  | Agreement. | ||||||
|  |  | ||||||
|  |  | ||||||
|  | BEOPEN.COM LICENSE AGREEMENT FOR PYTHON 2.0 | ||||||
|  | ------------------------------------------- | ||||||
|  |  | ||||||
|  | BEOPEN PYTHON OPEN SOURCE LICENSE AGREEMENT VERSION 1 | ||||||
|  |  | ||||||
|  | 1. This LICENSE AGREEMENT is between BeOpen.com ("BeOpen"), having an | ||||||
|  | office at 160 Saratoga Avenue, Santa Clara, CA 95051, and the | ||||||
|  | Individual or Organization ("Licensee") accessing and otherwise using | ||||||
|  | this software in source or binary form and its associated | ||||||
|  | documentation ("the Software"). | ||||||
|  |  | ||||||
|  | 2. Subject to the terms and conditions of this BeOpen Python License | ||||||
|  | Agreement, BeOpen hereby grants Licensee a non-exclusive, | ||||||
|  | royalty-free, world-wide license to reproduce, analyze, test, perform | ||||||
|  | and/or display publicly, prepare derivative works, distribute, and | ||||||
|  | otherwise use the Software alone or in any derivative version, | ||||||
|  | provided, however, that the BeOpen Python License is retained in the | ||||||
|  | Software, alone or in any derivative version prepared by Licensee. | ||||||
|  |  | ||||||
|  | 3. BeOpen is making the Software available to Licensee on an "AS IS" | ||||||
|  | basis.  BEOPEN MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR | ||||||
|  | IMPLIED.  BY WAY OF EXAMPLE, BUT NOT LIMITATION, BEOPEN MAKES NO AND | ||||||
|  | DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS | ||||||
|  | FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE WILL NOT | ||||||
|  | INFRINGE ANY THIRD PARTY RIGHTS. | ||||||
|  |  | ||||||
|  | 4. BEOPEN SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF THE | ||||||
|  | SOFTWARE FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS | ||||||
|  | AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THE SOFTWARE, OR ANY | ||||||
|  | DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. | ||||||
|  |  | ||||||
|  | 5. This License Agreement will automatically terminate upon a material | ||||||
|  | breach of its terms and conditions. | ||||||
|  |  | ||||||
|  | 6. This License Agreement shall be governed by and interpreted in all | ||||||
|  | respects by the law of the State of California, excluding conflict of | ||||||
|  | law provisions.  Nothing in this License Agreement shall be deemed to | ||||||
|  | create any relationship of agency, partnership, or joint venture | ||||||
|  | between BeOpen and Licensee.  This License Agreement does not grant | ||||||
|  | permission to use BeOpen trademarks or trade names in a trademark | ||||||
|  | sense to endorse or promote products or services of Licensee, or any | ||||||
|  | third party.  As an exception, the "BeOpen Python" logos available at | ||||||
|  | http://www.pythonlabs.com/logos.html may be used according to the | ||||||
|  | permissions granted on that web page. | ||||||
|  |  | ||||||
|  | 7. By copying, installing or otherwise using the software, Licensee | ||||||
|  | agrees to be bound by the terms and conditions of this License | ||||||
|  | Agreement. | ||||||
|  |  | ||||||
|  |  | ||||||
|  | CNRI LICENSE AGREEMENT FOR PYTHON 1.6.1 | ||||||
|  | --------------------------------------- | ||||||
|  |  | ||||||
|  | 1. This LICENSE AGREEMENT is between the Corporation for National | ||||||
|  | Research Initiatives, having an office at 1895 Preston White Drive, | ||||||
|  | Reston, VA 20191 ("CNRI"), and the Individual or Organization | ||||||
|  | ("Licensee") accessing and otherwise using Python 1.6.1 software in | ||||||
|  | source or binary form and its associated documentation. | ||||||
|  |  | ||||||
|  | 2. Subject to the terms and conditions of this License Agreement, CNRI | ||||||
|  | hereby grants Licensee a nonexclusive, royalty-free, world-wide | ||||||
|  | license to reproduce, analyze, test, perform and/or display publicly, | ||||||
|  | prepare derivative works, distribute, and otherwise use Python 1.6.1 | ||||||
|  | alone or in any derivative version, provided, however, that CNRI's | ||||||
|  | License Agreement and CNRI's notice of copyright, i.e., "Copyright (c) | ||||||
|  | 1995-2001 Corporation for National Research Initiatives; All Rights | ||||||
|  | Reserved" are retained in Python 1.6.1 alone or in any derivative | ||||||
|  | version prepared by Licensee.  Alternately, in lieu of CNRI's License | ||||||
|  | Agreement, Licensee may substitute the following text (omitting the | ||||||
|  | quotes): "Python 1.6.1 is made available subject to the terms and | ||||||
|  | conditions in CNRI's License Agreement.  This Agreement together with | ||||||
|  | Python 1.6.1 may be located on the Internet using the following | ||||||
|  | unique, persistent identifier (known as a handle): 1895.22/1013.  This | ||||||
|  | Agreement may also be obtained from a proxy server on the Internet | ||||||
|  | using the following URL: http://hdl.handle.net/1895.22/1013". | ||||||
|  |  | ||||||
|  | 3. In the event Licensee prepares a derivative work that is based on | ||||||
|  | or incorporates Python 1.6.1 or any part thereof, and wants to make | ||||||
|  | the derivative work available to others as provided herein, then | ||||||
|  | Licensee hereby agrees to include in any such work a brief summary of | ||||||
|  | the changes made to Python 1.6.1. | ||||||
|  |  | ||||||
|  | 4. CNRI is making Python 1.6.1 available to Licensee on an "AS IS" | ||||||
|  | basis.  CNRI MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR | ||||||
|  | IMPLIED.  BY WAY OF EXAMPLE, BUT NOT LIMITATION, CNRI MAKES NO AND | ||||||
|  | DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS | ||||||
|  | FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 1.6.1 WILL NOT | ||||||
|  | INFRINGE ANY THIRD PARTY RIGHTS. | ||||||
|  |  | ||||||
|  | 5. CNRI SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON | ||||||
|  | 1.6.1 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS | ||||||
|  | A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 1.6.1, | ||||||
|  | OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. | ||||||
|  |  | ||||||
|  | 6. This License Agreement will automatically terminate upon a material | ||||||
|  | breach of its terms and conditions. | ||||||
|  |  | ||||||
|  | 7. This License Agreement shall be governed by the federal | ||||||
|  | intellectual property law of the United States, including without | ||||||
|  | limitation the federal copyright law, and, to the extent such | ||||||
|  | U.S. federal law does not apply, by the law of the Commonwealth of | ||||||
|  | Virginia, excluding Virginia's conflict of law provisions. | ||||||
|  | Notwithstanding the foregoing, with regard to derivative works based | ||||||
|  | on Python 1.6.1 that incorporate non-separable material that was | ||||||
|  | previously distributed under the GNU General Public License (GPL), the | ||||||
|  | law of the Commonwealth of Virginia shall govern this License | ||||||
|  | Agreement only as to issues arising under or with respect to | ||||||
|  | Paragraphs 4, 5, and 7 of this License Agreement.  Nothing in this | ||||||
|  | License Agreement shall be deemed to create any relationship of | ||||||
|  | agency, partnership, or joint venture between CNRI and Licensee.  This | ||||||
|  | License Agreement does not grant permission to use CNRI trademarks or | ||||||
|  | trade name in a trademark sense to endorse or promote products or | ||||||
|  | services of Licensee, or any third party. | ||||||
|  |  | ||||||
|  | 8. By clicking on the "ACCEPT" button where indicated, or by copying, | ||||||
|  | installing or otherwise using Python 1.6.1, Licensee agrees to be | ||||||
|  | bound by the terms and conditions of this License Agreement. | ||||||
|  |  | ||||||
|  |         ACCEPT | ||||||
|  |  | ||||||
|  |  | ||||||
|  | CWI LICENSE AGREEMENT FOR PYTHON 0.9.0 THROUGH 1.2 | ||||||
|  | -------------------------------------------------- | ||||||
|  |  | ||||||
|  | Copyright (c) 1991 - 1995, Stichting Mathematisch Centrum Amsterdam, | ||||||
|  | The Netherlands.  All rights reserved. | ||||||
|  |  | ||||||
|  | Permission to use, copy, modify, and distribute this software and its | ||||||
|  | documentation for any purpose and without fee is hereby granted, | ||||||
|  | provided that the above copyright notice appear in all copies and that | ||||||
|  | both that copyright notice and this permission notice appear in | ||||||
|  | supporting documentation, and that the name of Stichting Mathematisch | ||||||
|  | Centrum or CWI not be used in advertising or publicity pertaining to | ||||||
|  | distribution of the software without specific, written prior | ||||||
|  | permission. | ||||||
|  |  | ||||||
|  | STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO | ||||||
|  | THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND | ||||||
|  | FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE | ||||||
|  | FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||||||
|  | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||||||
|  | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT | ||||||
|  | OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||||||
							
								
								
									
										1
									
								
								lib/spack/external/py2/functools32/__init__.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								lib/spack/external/py2/functools32/__init__.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | from .functools32 import * | ||||||
							
								
								
									
										158
									
								
								lib/spack/external/py2/functools32/_dummy_thread32.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										158
									
								
								lib/spack/external/py2/functools32/_dummy_thread32.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,158 @@ | |||||||
|  | """Drop-in replacement for the thread module. | ||||||
|  | 
 | ||||||
|  | Meant to be used as a brain-dead substitute so that threaded code does | ||||||
|  | not need to be rewritten for when the thread module is not present. | ||||||
|  | 
 | ||||||
|  | Suggested usage is:: | ||||||
|  | 
 | ||||||
|  |     try: | ||||||
|  |         try: | ||||||
|  |             import _thread  # Python >= 3 | ||||||
|  |         except: | ||||||
|  |             import thread as _thread  # Python < 3 | ||||||
|  |     except ImportError: | ||||||
|  |         import _dummy_thread as _thread | ||||||
|  | 
 | ||||||
|  | """ | ||||||
|  | # Exports only things specified by thread documentation; | ||||||
|  | # skipping obsolete synonyms allocate(), start_new(), exit_thread(). | ||||||
|  | __all__ = ['error', 'start_new_thread', 'exit', 'get_ident', 'allocate_lock', | ||||||
|  |            'interrupt_main', 'LockType'] | ||||||
|  | 
 | ||||||
|  | # A dummy value | ||||||
|  | TIMEOUT_MAX = 2**31 | ||||||
|  | 
 | ||||||
|  | # NOTE: this module can be imported early in the extension building process, | ||||||
|  | # and so top level imports of other modules should be avoided.  Instead, all | ||||||
|  | # imports are done when needed on a function-by-function basis.  Since threads | ||||||
|  | # are disabled, the import lock should not be an issue anyway (??). | ||||||
|  | 
 | ||||||
|  | class error(Exception): | ||||||
|  |     """Dummy implementation of _thread.error.""" | ||||||
|  | 
 | ||||||
|  |     def __init__(self, *args): | ||||||
|  |         self.args = args | ||||||
|  | 
 | ||||||
|  | def start_new_thread(function, args, kwargs={}): | ||||||
|  |     """Dummy implementation of _thread.start_new_thread(). | ||||||
|  | 
 | ||||||
|  |     Compatibility is maintained by making sure that ``args`` is a | ||||||
|  |     tuple and ``kwargs`` is a dictionary.  If an exception is raised | ||||||
|  |     and it is SystemExit (which can be done by _thread.exit()) it is | ||||||
|  |     caught and nothing is done; all other exceptions are printed out | ||||||
|  |     by using traceback.print_exc(). | ||||||
|  | 
 | ||||||
|  |     If the executed function calls interrupt_main the KeyboardInterrupt will be | ||||||
|  |     raised when the function returns. | ||||||
|  | 
 | ||||||
|  |     """ | ||||||
|  |     if type(args) != type(tuple()): | ||||||
|  |         raise TypeError("2nd arg must be a tuple") | ||||||
|  |     if type(kwargs) != type(dict()): | ||||||
|  |         raise TypeError("3rd arg must be a dict") | ||||||
|  |     global _main | ||||||
|  |     _main = False | ||||||
|  |     try: | ||||||
|  |         function(*args, **kwargs) | ||||||
|  |     except SystemExit: | ||||||
|  |         pass | ||||||
|  |     except: | ||||||
|  |         import traceback | ||||||
|  |         traceback.print_exc() | ||||||
|  |     _main = True | ||||||
|  |     global _interrupt | ||||||
|  |     if _interrupt: | ||||||
|  |         _interrupt = False | ||||||
|  |         raise KeyboardInterrupt | ||||||
|  | 
 | ||||||
|  | def exit(): | ||||||
|  |     """Dummy implementation of _thread.exit().""" | ||||||
|  |     raise SystemExit | ||||||
|  | 
 | ||||||
|  | def get_ident(): | ||||||
|  |     """Dummy implementation of _thread.get_ident(). | ||||||
|  | 
 | ||||||
|  |     Since this module should only be used when _threadmodule is not | ||||||
|  |     available, it is safe to assume that the current process is the | ||||||
|  |     only thread.  Thus a constant can be safely returned. | ||||||
|  |     """ | ||||||
|  |     return -1 | ||||||
|  | 
 | ||||||
|  | def allocate_lock(): | ||||||
|  |     """Dummy implementation of _thread.allocate_lock().""" | ||||||
|  |     return LockType() | ||||||
|  | 
 | ||||||
|  | def stack_size(size=None): | ||||||
|  |     """Dummy implementation of _thread.stack_size().""" | ||||||
|  |     if size is not None: | ||||||
|  |         raise error("setting thread stack size not supported") | ||||||
|  |     return 0 | ||||||
|  | 
 | ||||||
|  | class LockType(object): | ||||||
|  |     """Class implementing dummy implementation of _thread.LockType. | ||||||
|  | 
 | ||||||
|  |     Compatibility is maintained by maintaining self.locked_status | ||||||
|  |     which is a boolean that stores the state of the lock.  Pickling of | ||||||
|  |     the lock, though, should not be done since if the _thread module is | ||||||
|  |     then used with an unpickled ``lock()`` from here problems could | ||||||
|  |     occur from this class not having atomic methods. | ||||||
|  | 
 | ||||||
|  |     """ | ||||||
|  | 
 | ||||||
|  |     def __init__(self): | ||||||
|  |         self.locked_status = False | ||||||
|  | 
 | ||||||
|  |     def acquire(self, waitflag=None, timeout=-1): | ||||||
|  |         """Dummy implementation of acquire(). | ||||||
|  | 
 | ||||||
|  |         For blocking calls, self.locked_status is automatically set to | ||||||
|  |         True and returned appropriately based on value of | ||||||
|  |         ``waitflag``.  If it is non-blocking, then the value is | ||||||
|  |         actually checked and not set if it is already acquired.  This | ||||||
|  |         is all done so that threading.Condition's assert statements | ||||||
|  |         aren't triggered and throw a little fit. | ||||||
|  | 
 | ||||||
|  |         """ | ||||||
|  |         if waitflag is None or waitflag: | ||||||
|  |             self.locked_status = True | ||||||
|  |             return True | ||||||
|  |         else: | ||||||
|  |             if not self.locked_status: | ||||||
|  |                 self.locked_status = True | ||||||
|  |                 return True | ||||||
|  |             else: | ||||||
|  |                 if timeout > 0: | ||||||
|  |                     import time | ||||||
|  |                     time.sleep(timeout) | ||||||
|  |                 return False | ||||||
|  | 
 | ||||||
|  |     __enter__ = acquire | ||||||
|  | 
 | ||||||
|  |     def __exit__(self, typ, val, tb): | ||||||
|  |         self.release() | ||||||
|  | 
 | ||||||
|  |     def release(self): | ||||||
|  |         """Release the dummy lock.""" | ||||||
|  |         # XXX Perhaps shouldn't actually bother to test?  Could lead | ||||||
|  |         #     to problems for complex, threaded code. | ||||||
|  |         if not self.locked_status: | ||||||
|  |             raise error | ||||||
|  |         self.locked_status = False | ||||||
|  |         return True | ||||||
|  | 
 | ||||||
|  |     def locked(self): | ||||||
|  |         return self.locked_status | ||||||
|  | 
 | ||||||
|  | # Used to signal that interrupt_main was called in a "thread" | ||||||
|  | _interrupt = False | ||||||
|  | # True when not executing in a "thread" | ||||||
|  | _main = True | ||||||
|  | 
 | ||||||
|  | def interrupt_main(): | ||||||
|  |     """Set _interrupt flag to True to have start_new_thread raise | ||||||
|  |     KeyboardInterrupt upon exiting.""" | ||||||
|  |     if _main: | ||||||
|  |         raise KeyboardInterrupt | ||||||
|  |     else: | ||||||
|  |         global _interrupt | ||||||
|  |         _interrupt = True | ||||||
							
								
								
									
										423
									
								
								lib/spack/external/py2/functools32/functools32.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										423
									
								
								lib/spack/external/py2/functools32/functools32.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,423 @@ | |||||||
|  | """functools.py - Tools for working with functions and callable objects | ||||||
|  | """ | ||||||
|  | # Python module wrapper for _functools C module | ||||||
|  | # to allow utilities written in Python to be added | ||||||
|  | # to the functools module. | ||||||
|  | # Written by Nick Coghlan <ncoghlan at gmail.com> | ||||||
|  | # and Raymond Hettinger <python at rcn.com> | ||||||
|  | #   Copyright (C) 2006-2010 Python Software Foundation. | ||||||
|  | # See C source code for _functools credits/copyright | ||||||
|  | 
 | ||||||
|  | __all__ = ['update_wrapper', 'wraps', 'WRAPPER_ASSIGNMENTS', 'WRAPPER_UPDATES', | ||||||
|  |            'total_ordering', 'cmp_to_key', 'lru_cache', 'reduce', 'partial'] | ||||||
|  | 
 | ||||||
|  | from _functools import partial, reduce | ||||||
|  | from collections import MutableMapping, namedtuple | ||||||
|  | from .reprlib32 import recursive_repr as _recursive_repr | ||||||
|  | from weakref import proxy as _proxy | ||||||
|  | import sys as _sys | ||||||
|  | try: | ||||||
|  |     from thread import allocate_lock as Lock | ||||||
|  | except ImportError: | ||||||
|  |     from ._dummy_thread32 import allocate_lock as Lock | ||||||
|  | 
 | ||||||
|  | ################################################################################ | ||||||
|  | ### OrderedDict | ||||||
|  | ################################################################################ | ||||||
|  | 
 | ||||||
|  | class _Link(object): | ||||||
|  |     __slots__ = 'prev', 'next', 'key', '__weakref__' | ||||||
|  | 
 | ||||||
|  | class OrderedDict(dict): | ||||||
|  |     'Dictionary that remembers insertion order' | ||||||
|  |     # An inherited dict maps keys to values. | ||||||
|  |     # The inherited dict provides __getitem__, __len__, __contains__, and get. | ||||||
|  |     # The remaining methods are order-aware. | ||||||
|  |     # Big-O running times for all methods are the same as regular dictionaries. | ||||||
|  | 
 | ||||||
|  |     # The internal self.__map dict maps keys to links in a doubly linked list. | ||||||
|  |     # The circular doubly linked list starts and ends with a sentinel element. | ||||||
|  |     # The sentinel element never gets deleted (this simplifies the algorithm). | ||||||
|  |     # The sentinel is in self.__hardroot with a weakref proxy in self.__root. | ||||||
|  |     # The prev links are weakref proxies (to prevent circular references). | ||||||
|  |     # Individual links are kept alive by the hard reference in self.__map. | ||||||
|  |     # Those hard references disappear when a key is deleted from an OrderedDict. | ||||||
|  | 
 | ||||||
|  |     def __init__(self, *args, **kwds): | ||||||
|  |         '''Initialize an ordered dictionary.  The signature is the same as | ||||||
|  |         regular dictionaries, but keyword arguments are not recommended because | ||||||
|  |         their insertion order is arbitrary. | ||||||
|  | 
 | ||||||
|  |         ''' | ||||||
|  |         if len(args) > 1: | ||||||
|  |             raise TypeError('expected at most 1 arguments, got %d' % len(args)) | ||||||
|  |         try: | ||||||
|  |             self.__root | ||||||
|  |         except AttributeError: | ||||||
|  |             self.__hardroot = _Link() | ||||||
|  |             self.__root = root = _proxy(self.__hardroot) | ||||||
|  |             root.prev = root.next = root | ||||||
|  |             self.__map = {} | ||||||
|  |         self.__update(*args, **kwds) | ||||||
|  | 
 | ||||||
|  |     def __setitem__(self, key, value, | ||||||
|  |                     dict_setitem=dict.__setitem__, proxy=_proxy, Link=_Link): | ||||||
|  |         'od.__setitem__(i, y) <==> od[i]=y' | ||||||
|  |         # Setting a new item creates a new link at the end of the linked list, | ||||||
|  |         # and the inherited dictionary is updated with the new key/value pair. | ||||||
|  |         if key not in self: | ||||||
|  |             self.__map[key] = link = Link() | ||||||
|  |             root = self.__root | ||||||
|  |             last = root.prev | ||||||
|  |             link.prev, link.next, link.key = last, root, key | ||||||
|  |             last.next = link | ||||||
|  |             root.prev = proxy(link) | ||||||
|  |         dict_setitem(self, key, value) | ||||||
|  | 
 | ||||||
|  |     def __delitem__(self, key, dict_delitem=dict.__delitem__): | ||||||
|  |         'od.__delitem__(y) <==> del od[y]' | ||||||
|  |         # Deleting an existing item uses self.__map to find the link which gets | ||||||
|  |         # removed by updating the links in the predecessor and successor nodes. | ||||||
|  |         dict_delitem(self, key) | ||||||
|  |         link = self.__map.pop(key) | ||||||
|  |         link_prev = link.prev | ||||||
|  |         link_next = link.next | ||||||
|  |         link_prev.next = link_next | ||||||
|  |         link_next.prev = link_prev | ||||||
|  | 
 | ||||||
|  |     def __iter__(self): | ||||||
|  |         'od.__iter__() <==> iter(od)' | ||||||
|  |         # Traverse the linked list in order. | ||||||
|  |         root = self.__root | ||||||
|  |         curr = root.next | ||||||
|  |         while curr is not root: | ||||||
|  |             yield curr.key | ||||||
|  |             curr = curr.next | ||||||
|  | 
 | ||||||
|  |     def __reversed__(self): | ||||||
|  |         'od.__reversed__() <==> reversed(od)' | ||||||
|  |         # Traverse the linked list in reverse order. | ||||||
|  |         root = self.__root | ||||||
|  |         curr = root.prev | ||||||
|  |         while curr is not root: | ||||||
|  |             yield curr.key | ||||||
|  |             curr = curr.prev | ||||||
|  | 
 | ||||||
|  |     def clear(self): | ||||||
|  |         'od.clear() -> None.  Remove all items from od.' | ||||||
|  |         root = self.__root | ||||||
|  |         root.prev = root.next = root | ||||||
|  |         self.__map.clear() | ||||||
|  |         dict.clear(self) | ||||||
|  | 
 | ||||||
|  |     def popitem(self, last=True): | ||||||
|  |         '''od.popitem() -> (k, v), return and remove a (key, value) pair. | ||||||
|  |         Pairs are returned in LIFO order if last is true or FIFO order if false. | ||||||
|  | 
 | ||||||
|  |         ''' | ||||||
|  |         if not self: | ||||||
|  |             raise KeyError('dictionary is empty') | ||||||
|  |         root = self.__root | ||||||
|  |         if last: | ||||||
|  |             link = root.prev | ||||||
|  |             link_prev = link.prev | ||||||
|  |             link_prev.next = root | ||||||
|  |             root.prev = link_prev | ||||||
|  |         else: | ||||||
|  |             link = root.next | ||||||
|  |             link_next = link.next | ||||||
|  |             root.next = link_next | ||||||
|  |             link_next.prev = root | ||||||
|  |         key = link.key | ||||||
|  |         del self.__map[key] | ||||||
|  |         value = dict.pop(self, key) | ||||||
|  |         return key, value | ||||||
|  | 
 | ||||||
|  |     def move_to_end(self, key, last=True): | ||||||
|  |         '''Move an existing element to the end (or beginning if last==False). | ||||||
|  | 
 | ||||||
|  |         Raises KeyError if the element does not exist. | ||||||
|  |         When last=True, acts like a fast version of self[key]=self.pop(key). | ||||||
|  | 
 | ||||||
|  |         ''' | ||||||
|  |         link = self.__map[key] | ||||||
|  |         link_prev = link.prev | ||||||
|  |         link_next = link.next | ||||||
|  |         link_prev.next = link_next | ||||||
|  |         link_next.prev = link_prev | ||||||
|  |         root = self.__root | ||||||
|  |         if last: | ||||||
|  |             last = root.prev | ||||||
|  |             link.prev = last | ||||||
|  |             link.next = root | ||||||
|  |             last.next = root.prev = link | ||||||
|  |         else: | ||||||
|  |             first = root.next | ||||||
|  |             link.prev = root | ||||||
|  |             link.next = first | ||||||
|  |             root.next = first.prev = link | ||||||
|  | 
 | ||||||
|  |     def __sizeof__(self): | ||||||
|  |         sizeof = _sys.getsizeof | ||||||
|  |         n = len(self) + 1                       # number of links including root | ||||||
|  |         size = sizeof(self.__dict__)            # instance dictionary | ||||||
|  |         size += sizeof(self.__map) * 2          # internal dict and inherited dict | ||||||
|  |         size += sizeof(self.__hardroot) * n     # link objects | ||||||
|  |         size += sizeof(self.__root) * n         # proxy objects | ||||||
|  |         return size | ||||||
|  | 
 | ||||||
|  |     update = __update = MutableMapping.update | ||||||
|  |     keys = MutableMapping.keys | ||||||
|  |     values = MutableMapping.values | ||||||
|  |     items = MutableMapping.items | ||||||
|  |     __ne__ = MutableMapping.__ne__ | ||||||
|  | 
 | ||||||
|  |     __marker = object() | ||||||
|  | 
 | ||||||
|  |     def pop(self, key, default=__marker): | ||||||
|  |         '''od.pop(k[,d]) -> v, remove specified key and return the corresponding | ||||||
|  |         value.  If key is not found, d is returned if given, otherwise KeyError | ||||||
|  |         is raised. | ||||||
|  | 
 | ||||||
|  |         ''' | ||||||
|  |         if key in self: | ||||||
|  |             result = self[key] | ||||||
|  |             del self[key] | ||||||
|  |             return result | ||||||
|  |         if default is self.__marker: | ||||||
|  |             raise KeyError(key) | ||||||
|  |         return default | ||||||
|  | 
 | ||||||
|  |     def setdefault(self, key, default=None): | ||||||
|  |         'od.setdefault(k[,d]) -> od.get(k,d), also set od[k]=d if k not in od' | ||||||
|  |         if key in self: | ||||||
|  |             return self[key] | ||||||
|  |         self[key] = default | ||||||
|  |         return default | ||||||
|  | 
 | ||||||
|  |     @_recursive_repr() | ||||||
|  |     def __repr__(self): | ||||||
|  |         'od.__repr__() <==> repr(od)' | ||||||
|  |         if not self: | ||||||
|  |             return '%s()' % (self.__class__.__name__,) | ||||||
|  |         return '%s(%r)' % (self.__class__.__name__, list(self.items())) | ||||||
|  | 
 | ||||||
|  |     def __reduce__(self): | ||||||
|  |         'Return state information for pickling' | ||||||
|  |         items = [[k, self[k]] for k in self] | ||||||
|  |         inst_dict = vars(self).copy() | ||||||
|  |         for k in vars(OrderedDict()): | ||||||
|  |             inst_dict.pop(k, None) | ||||||
|  |         if inst_dict: | ||||||
|  |             return (self.__class__, (items,), inst_dict) | ||||||
|  |         return self.__class__, (items,) | ||||||
|  | 
 | ||||||
|  |     def copy(self): | ||||||
|  |         'od.copy() -> a shallow copy of od' | ||||||
|  |         return self.__class__(self) | ||||||
|  | 
 | ||||||
|  |     @classmethod | ||||||
|  |     def fromkeys(cls, iterable, value=None): | ||||||
|  |         '''OD.fromkeys(S[, v]) -> New ordered dictionary with keys from S. | ||||||
|  |         If not specified, the value defaults to None. | ||||||
|  | 
 | ||||||
|  |         ''' | ||||||
|  |         self = cls() | ||||||
|  |         for key in iterable: | ||||||
|  |             self[key] = value | ||||||
|  |         return self | ||||||
|  | 
 | ||||||
|  |     def __eq__(self, other): | ||||||
|  |         '''od.__eq__(y) <==> od==y.  Comparison to another OD is order-sensitive | ||||||
|  |         while comparison to a regular mapping is order-insensitive. | ||||||
|  | 
 | ||||||
|  |         ''' | ||||||
|  |         if isinstance(other, OrderedDict): | ||||||
|  |             return len(self)==len(other) and \ | ||||||
|  |                    all(p==q for p, q in zip(self.items(), other.items())) | ||||||
|  |         return dict.__eq__(self, other) | ||||||
|  | 
 | ||||||
|  | # update_wrapper() and wraps() are tools to help write | ||||||
|  | # wrapper functions that can handle naive introspection | ||||||
|  | 
 | ||||||
|  | WRAPPER_ASSIGNMENTS = ('__module__', '__name__', '__doc__') | ||||||
|  | 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) | ||||||
|  |     """ | ||||||
|  |     wrapper.__wrapped__ = wrapped | ||||||
|  |     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, {})) | ||||||
|  |     # Return the wrapper so this can be used as a decorator via partial() | ||||||
|  |     return wrapper | ||||||
|  | 
 | ||||||
|  | def wraps(wrapped, | ||||||
|  |           assigned = WRAPPER_ASSIGNMENTS, | ||||||
|  |           updated = WRAPPER_UPDATES): | ||||||
|  |     """Decorator factory to apply update_wrapper() to a wrapper function | ||||||
|  | 
 | ||||||
|  |        Returns a decorator that invokes update_wrapper() with the decorated | ||||||
|  |        function as the wrapper argument and the arguments to wraps() as the | ||||||
|  |        remaining arguments. Default arguments are as for update_wrapper(). | ||||||
|  |        This is a convenience function to simplify applying partial() to | ||||||
|  |        update_wrapper(). | ||||||
|  |     """ | ||||||
|  |     return partial(update_wrapper, wrapped=wrapped, | ||||||
|  |                    assigned=assigned, updated=updated) | ||||||
|  | 
 | ||||||
|  | def total_ordering(cls): | ||||||
|  |     """Class decorator that fills in missing ordering methods""" | ||||||
|  |     convert = { | ||||||
|  |         '__lt__': [('__gt__', lambda self, other: not (self < other or self == other)), | ||||||
|  |                    ('__le__', lambda self, other: self < other or self == other), | ||||||
|  |                    ('__ge__', lambda self, other: not self < other)], | ||||||
|  |         '__le__': [('__ge__', lambda self, other: not self <= other or self == other), | ||||||
|  |                    ('__lt__', lambda self, other: self <= other and not self == other), | ||||||
|  |                    ('__gt__', lambda self, other: not self <= other)], | ||||||
|  |         '__gt__': [('__lt__', lambda self, other: not (self > other or self == other)), | ||||||
|  |                    ('__ge__', lambda self, other: self > other or self == other), | ||||||
|  |                    ('__le__', lambda self, other: not self > other)], | ||||||
|  |         '__ge__': [('__le__', lambda self, other: (not self >= other) or self == other), | ||||||
|  |                    ('__gt__', lambda self, other: self >= other and not self == other), | ||||||
|  |                    ('__lt__', lambda self, other: not self >= other)] | ||||||
|  |     } | ||||||
|  |     roots = set(dir(cls)) & set(convert) | ||||||
|  |     if not roots: | ||||||
|  |         raise ValueError('must define at least one ordering operation: < > <= >=') | ||||||
|  |     root = max(roots)       # prefer __lt__ to __le__ to __gt__ to __ge__ | ||||||
|  |     for opname, opfunc in convert[root]: | ||||||
|  |         if opname not in roots: | ||||||
|  |             opfunc.__name__ = opname | ||||||
|  |             opfunc.__doc__ = getattr(int, opname).__doc__ | ||||||
|  |             setattr(cls, opname, opfunc) | ||||||
|  |     return cls | ||||||
|  | 
 | ||||||
|  | def cmp_to_key(mycmp): | ||||||
|  |     """Convert a cmp= function into a key= function""" | ||||||
|  |     class K(object): | ||||||
|  |         __slots__ = ['obj'] | ||||||
|  |         def __init__(self, obj): | ||||||
|  |             self.obj = obj | ||||||
|  |         def __lt__(self, other): | ||||||
|  |             return mycmp(self.obj, other.obj) < 0 | ||||||
|  |         def __gt__(self, other): | ||||||
|  |             return mycmp(self.obj, other.obj) > 0 | ||||||
|  |         def __eq__(self, other): | ||||||
|  |             return mycmp(self.obj, other.obj) == 0 | ||||||
|  |         def __le__(self, other): | ||||||
|  |             return mycmp(self.obj, other.obj) <= 0 | ||||||
|  |         def __ge__(self, other): | ||||||
|  |             return mycmp(self.obj, other.obj) >= 0 | ||||||
|  |         def __ne__(self, other): | ||||||
|  |             return mycmp(self.obj, other.obj) != 0 | ||||||
|  |         __hash__ = None | ||||||
|  |     return K | ||||||
|  | 
 | ||||||
|  | _CacheInfo = namedtuple("CacheInfo", "hits misses maxsize currsize") | ||||||
|  | 
 | ||||||
|  | def lru_cache(maxsize=100): | ||||||
|  |     """Least-recently-used cache decorator. | ||||||
|  | 
 | ||||||
|  |     If *maxsize* is set to None, the LRU features are disabled and the cache | ||||||
|  |     can grow without bound. | ||||||
|  | 
 | ||||||
|  |     Arguments to the cached function must be hashable. | ||||||
|  | 
 | ||||||
|  |     View the cache statistics named tuple (hits, misses, maxsize, currsize) with | ||||||
|  |     f.cache_info().  Clear the cache and statistics with f.cache_clear(). | ||||||
|  |     Access the underlying function with f.__wrapped__. | ||||||
|  | 
 | ||||||
|  |     See:  http://en.wikipedia.org/wiki/Cache_algorithms#Least_Recently_Used | ||||||
|  | 
 | ||||||
|  |     """ | ||||||
|  |     # Users should only access the lru_cache through its public API: | ||||||
|  |     #       cache_info, cache_clear, and f.__wrapped__ | ||||||
|  |     # The internals of the lru_cache are encapsulated for thread safety and | ||||||
|  |     # to allow the implementation to change (including a possible C version). | ||||||
|  | 
 | ||||||
|  |     def decorating_function(user_function, | ||||||
|  |                 tuple=tuple, sorted=sorted, len=len, KeyError=KeyError): | ||||||
|  | 
 | ||||||
|  |         hits, misses = [0], [0] | ||||||
|  |         kwd_mark = (object(),)          # separates positional and keyword args | ||||||
|  |         lock = Lock()                   # needed because OrderedDict isn't threadsafe | ||||||
|  | 
 | ||||||
|  |         if maxsize is None: | ||||||
|  |             cache = dict()              # simple cache without ordering or size limit | ||||||
|  | 
 | ||||||
|  |             @wraps(user_function) | ||||||
|  |             def wrapper(*args, **kwds): | ||||||
|  |                 key = args | ||||||
|  |                 if kwds: | ||||||
|  |                     key += kwd_mark + tuple(sorted(kwds.items())) | ||||||
|  |                 try: | ||||||
|  |                     result = cache[key] | ||||||
|  |                     hits[0] += 1 | ||||||
|  |                     return result | ||||||
|  |                 except KeyError: | ||||||
|  |                     pass | ||||||
|  |                 result = user_function(*args, **kwds) | ||||||
|  |                 cache[key] = result | ||||||
|  |                 misses[0] += 1 | ||||||
|  |                 return result | ||||||
|  |         else: | ||||||
|  |             cache = OrderedDict()           # ordered least recent to most recent | ||||||
|  |             cache_popitem = cache.popitem | ||||||
|  |             cache_renew = cache.move_to_end | ||||||
|  | 
 | ||||||
|  |             @wraps(user_function) | ||||||
|  |             def wrapper(*args, **kwds): | ||||||
|  |                 key = args | ||||||
|  |                 if kwds: | ||||||
|  |                     key += kwd_mark + tuple(sorted(kwds.items())) | ||||||
|  |                 with lock: | ||||||
|  |                     try: | ||||||
|  |                         result = cache[key] | ||||||
|  |                         cache_renew(key)    # record recent use of this key | ||||||
|  |                         hits[0] += 1 | ||||||
|  |                         return result | ||||||
|  |                     except KeyError: | ||||||
|  |                         pass | ||||||
|  |                 result = user_function(*args, **kwds) | ||||||
|  |                 with lock: | ||||||
|  |                     cache[key] = result     # record recent use of this key | ||||||
|  |                     misses[0] += 1 | ||||||
|  |                     if len(cache) > maxsize: | ||||||
|  |                         cache_popitem(0)    # purge least recently used cache entry | ||||||
|  |                 return result | ||||||
|  | 
 | ||||||
|  |         def cache_info(): | ||||||
|  |             """Report cache statistics""" | ||||||
|  |             with lock: | ||||||
|  |                 return _CacheInfo(hits[0], misses[0], maxsize, len(cache)) | ||||||
|  | 
 | ||||||
|  |         def cache_clear(): | ||||||
|  |             """Clear the cache and cache statistics""" | ||||||
|  |             with lock: | ||||||
|  |                 cache.clear() | ||||||
|  |                 hits[0] = misses[0] = 0 | ||||||
|  | 
 | ||||||
|  |         wrapper.cache_info = cache_info | ||||||
|  |         wrapper.cache_clear = cache_clear | ||||||
|  |         return wrapper | ||||||
|  | 
 | ||||||
|  |     return decorating_function | ||||||
							
								
								
									
										157
									
								
								lib/spack/external/py2/functools32/reprlib32.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										157
									
								
								lib/spack/external/py2/functools32/reprlib32.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,157 @@ | |||||||
|  | """Redo the builtin repr() (representation) but with limits on most sizes.""" | ||||||
|  | 
 | ||||||
|  | __all__ = ["Repr", "repr", "recursive_repr"] | ||||||
|  | 
 | ||||||
|  | import __builtin__ as builtins | ||||||
|  | from itertools import islice | ||||||
|  | try: | ||||||
|  |     from thread import get_ident | ||||||
|  | except ImportError: | ||||||
|  |     from _dummy_thread32 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 Repr: | ||||||
|  | 
 | ||||||
|  |     def __init__(self): | ||||||
|  |         self.maxlevel = 6 | ||||||
|  |         self.maxtuple = 6 | ||||||
|  |         self.maxlist = 6 | ||||||
|  |         self.maxarray = 5 | ||||||
|  |         self.maxdict = 4 | ||||||
|  |         self.maxset = 6 | ||||||
|  |         self.maxfrozenset = 6 | ||||||
|  |         self.maxdeque = 6 | ||||||
|  |         self.maxstring = 30 | ||||||
|  |         self.maxlong = 40 | ||||||
|  |         self.maxother = 30 | ||||||
|  | 
 | ||||||
|  |     def repr(self, x): | ||||||
|  |         return self.repr1(x, self.maxlevel) | ||||||
|  | 
 | ||||||
|  |     def repr1(self, x, level): | ||||||
|  |         typename = type(x).__name__ | ||||||
|  |         if ' ' in typename: | ||||||
|  |             parts = typename.split() | ||||||
|  |             typename = '_'.join(parts) | ||||||
|  |         if hasattr(self, 'repr_' + typename): | ||||||
|  |             return getattr(self, 'repr_' + typename)(x, level) | ||||||
|  |         else: | ||||||
|  |             return self.repr_instance(x, level) | ||||||
|  | 
 | ||||||
|  |     def _repr_iterable(self, x, level, left, right, maxiter, trail=''): | ||||||
|  |         n = len(x) | ||||||
|  |         if level <= 0 and n: | ||||||
|  |             s = '...' | ||||||
|  |         else: | ||||||
|  |             newlevel = level - 1 | ||||||
|  |             repr1 = self.repr1 | ||||||
|  |             pieces = [repr1(elem, newlevel) for elem in islice(x, maxiter)] | ||||||
|  |             if n > maxiter:  pieces.append('...') | ||||||
|  |             s = ', '.join(pieces) | ||||||
|  |             if n == 1 and trail:  right = trail + right | ||||||
|  |         return '%s%s%s' % (left, s, right) | ||||||
|  | 
 | ||||||
|  |     def repr_tuple(self, x, level): | ||||||
|  |         return self._repr_iterable(x, level, '(', ')', self.maxtuple, ',') | ||||||
|  | 
 | ||||||
|  |     def repr_list(self, x, level): | ||||||
|  |         return self._repr_iterable(x, level, '[', ']', self.maxlist) | ||||||
|  | 
 | ||||||
|  |     def repr_array(self, x, level): | ||||||
|  |         header = "array('%s', [" % x.typecode | ||||||
|  |         return self._repr_iterable(x, level, header, '])', self.maxarray) | ||||||
|  | 
 | ||||||
|  |     def repr_set(self, x, level): | ||||||
|  |         x = _possibly_sorted(x) | ||||||
|  |         return self._repr_iterable(x, level, 'set([', '])', self.maxset) | ||||||
|  | 
 | ||||||
|  |     def repr_frozenset(self, x, level): | ||||||
|  |         x = _possibly_sorted(x) | ||||||
|  |         return self._repr_iterable(x, level, 'frozenset([', '])', | ||||||
|  |                                    self.maxfrozenset) | ||||||
|  | 
 | ||||||
|  |     def repr_deque(self, x, level): | ||||||
|  |         return self._repr_iterable(x, level, 'deque([', '])', self.maxdeque) | ||||||
|  | 
 | ||||||
|  |     def repr_dict(self, x, level): | ||||||
|  |         n = len(x) | ||||||
|  |         if n == 0: return '{}' | ||||||
|  |         if level <= 0: return '{...}' | ||||||
|  |         newlevel = level - 1 | ||||||
|  |         repr1 = self.repr1 | ||||||
|  |         pieces = [] | ||||||
|  |         for key in islice(_possibly_sorted(x), self.maxdict): | ||||||
|  |             keyrepr = repr1(key, newlevel) | ||||||
|  |             valrepr = repr1(x[key], newlevel) | ||||||
|  |             pieces.append('%s: %s' % (keyrepr, valrepr)) | ||||||
|  |         if n > self.maxdict: pieces.append('...') | ||||||
|  |         s = ', '.join(pieces) | ||||||
|  |         return '{%s}' % (s,) | ||||||
|  | 
 | ||||||
|  |     def repr_str(self, x, level): | ||||||
|  |         s = builtins.repr(x[:self.maxstring]) | ||||||
|  |         if len(s) > self.maxstring: | ||||||
|  |             i = max(0, (self.maxstring-3)//2) | ||||||
|  |             j = max(0, self.maxstring-3-i) | ||||||
|  |             s = builtins.repr(x[:i] + x[len(x)-j:]) | ||||||
|  |             s = s[:i] + '...' + s[len(s)-j:] | ||||||
|  |         return s | ||||||
|  | 
 | ||||||
|  |     def repr_int(self, x, level): | ||||||
|  |         s = builtins.repr(x) # XXX Hope this isn't too slow... | ||||||
|  |         if len(s) > self.maxlong: | ||||||
|  |             i = max(0, (self.maxlong-3)//2) | ||||||
|  |             j = max(0, self.maxlong-3-i) | ||||||
|  |             s = s[:i] + '...' + s[len(s)-j:] | ||||||
|  |         return s | ||||||
|  | 
 | ||||||
|  |     def repr_instance(self, x, level): | ||||||
|  |         try: | ||||||
|  |             s = builtins.repr(x) | ||||||
|  |             # Bugs in x.__repr__() can cause arbitrary | ||||||
|  |             # exceptions -- then make up something | ||||||
|  |         except Exception: | ||||||
|  |             return '<%s instance at %x>' % (x.__class__.__name__, id(x)) | ||||||
|  |         if len(s) > self.maxother: | ||||||
|  |             i = max(0, (self.maxother-3)//2) | ||||||
|  |             j = max(0, self.maxother-3-i) | ||||||
|  |             s = s[:i] + '...' + s[len(s)-j:] | ||||||
|  |         return s | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def _possibly_sorted(x): | ||||||
|  |     # Since not all sequences of items can be sorted and comparison | ||||||
|  |     # functions may raise arbitrary exceptions, return an unsorted | ||||||
|  |     # sequence in that case. | ||||||
|  |     try: | ||||||
|  |         return sorted(x) | ||||||
|  |     except Exception: | ||||||
|  |         return list(x) | ||||||
|  | 
 | ||||||
|  | aRepr = Repr() | ||||||
|  | repr = aRepr.repr | ||||||
		Reference in New Issue
	
	Block a user
	 Todd Gamblin
					Todd Gamblin