Delete Pytorch
Browse filesThis view is limited to 50 files because it contains too many changes.
See raw diff
- Pytorch/.nonadmin +0 -0
- Pytorch/DLLs/_asyncio.pyd +0 -0
- Pytorch/DLLs/_bz2.pyd +0 -0
- Pytorch/DLLs/_ctypes.pyd +0 -0
- Pytorch/DLLs/_ctypes_test.pyd +0 -0
- Pytorch/DLLs/_decimal.pyd +0 -0
- Pytorch/DLLs/_elementtree.pyd +0 -0
- Pytorch/DLLs/_hashlib.pyd +0 -0
- Pytorch/DLLs/_lzma.pyd +0 -0
- Pytorch/DLLs/_msi.pyd +0 -0
- Pytorch/DLLs/_multiprocessing.pyd +0 -0
- Pytorch/DLLs/_overlapped.pyd +0 -0
- Pytorch/DLLs/_queue.pyd +0 -0
- Pytorch/DLLs/_socket.pyd +0 -0
- Pytorch/DLLs/_sqlite3.pyd +0 -0
- Pytorch/DLLs/_ssl.pyd +0 -0
- Pytorch/DLLs/_testbuffer.pyd +0 -0
- Pytorch/DLLs/_testcapi.pyd +0 -0
- Pytorch/DLLs/_testconsole.pyd +0 -0
- Pytorch/DLLs/_testimportmultiple.pyd +0 -0
- Pytorch/DLLs/_testinternalcapi.pyd +0 -0
- Pytorch/DLLs/_testmultiphase.pyd +0 -0
- Pytorch/DLLs/_tkinter.pyd +0 -0
- Pytorch/DLLs/_uuid.pyd +0 -0
- Pytorch/DLLs/_zoneinfo.pyd +0 -0
- Pytorch/DLLs/py.ico +0 -0
- Pytorch/DLLs/pyc.ico +0 -0
- Pytorch/DLLs/pyexpat.pyd +0 -0
- Pytorch/DLLs/select.pyd +0 -0
- Pytorch/DLLs/unicodedata.pyd +0 -3
- Pytorch/DLLs/winsound.pyd +0 -0
- Pytorch/DLLs/xxlimited.pyd +0 -0
- Pytorch/DLLs/xxlimited_35.pyd +0 -0
- Pytorch/LICENSE_PYTHON.txt +0 -279
- Pytorch/Lib/abc.py +0 -188
- Pytorch/Lib/aifc.py +0 -947
- Pytorch/Lib/antigravity.py +0 -17
- Pytorch/Lib/argparse.py +0 -0
- Pytorch/Lib/ast.py +0 -1709
- Pytorch/Lib/asynchat.py +0 -315
- Pytorch/Lib/asyncio/__init__.py +0 -43
- Pytorch/Lib/asyncio/__main__.py +0 -125
- Pytorch/Lib/asyncio/__pycache__/__init__.cpython-310.pyc +0 -0
- Pytorch/Lib/asyncio/__pycache__/__main__.cpython-310.pyc +0 -0
- Pytorch/Lib/asyncio/__pycache__/base_events.cpython-310.pyc +0 -0
- Pytorch/Lib/asyncio/__pycache__/base_futures.cpython-310.pyc +0 -0
- Pytorch/Lib/asyncio/__pycache__/base_subprocess.cpython-310.pyc +0 -0
- Pytorch/Lib/asyncio/__pycache__/base_tasks.cpython-310.pyc +0 -0
- Pytorch/Lib/asyncio/__pycache__/constants.cpython-310.pyc +0 -0
- Pytorch/Lib/asyncio/__pycache__/coroutines.cpython-310.pyc +0 -0
Pytorch/.nonadmin
DELETED
|
File without changes
|
Pytorch/DLLs/_asyncio.pyd
DELETED
|
Binary file (66.8 kB)
|
|
|
Pytorch/DLLs/_bz2.pyd
DELETED
|
Binary file (35.6 kB)
|
|
|
Pytorch/DLLs/_ctypes.pyd
DELETED
|
Binary file (129 kB)
|
|
|
Pytorch/DLLs/_ctypes_test.pyd
DELETED
|
Binary file (35.1 kB)
|
|
|
Pytorch/DLLs/_decimal.pyd
DELETED
|
Binary file (268 kB)
|
|
|
Pytorch/DLLs/_elementtree.pyd
DELETED
|
Binary file (140 kB)
|
|
|
Pytorch/DLLs/_hashlib.pyd
DELETED
|
Binary file (61.2 kB)
|
|
|
Pytorch/DLLs/_lzma.pyd
DELETED
|
Binary file (47.4 kB)
|
|
|
Pytorch/DLLs/_msi.pyd
DELETED
|
Binary file (44.8 kB)
|
|
|
Pytorch/DLLs/_multiprocessing.pyd
DELETED
|
Binary file (34.1 kB)
|
|
|
Pytorch/DLLs/_overlapped.pyd
DELETED
|
Binary file (53 kB)
|
|
|
Pytorch/DLLs/_queue.pyd
DELETED
|
Binary file (32 kB)
|
|
|
Pytorch/DLLs/_socket.pyd
DELETED
|
Binary file (80.7 kB)
|
|
|
Pytorch/DLLs/_sqlite3.pyd
DELETED
|
Binary file (88.9 kB)
|
|
|
Pytorch/DLLs/_ssl.pyd
DELETED
|
Binary file (182 kB)
|
|
|
Pytorch/DLLs/_testbuffer.pyd
DELETED
|
Binary file (53.5 kB)
|
|
|
Pytorch/DLLs/_testcapi.pyd
DELETED
|
Binary file (134 kB)
|
|
|
Pytorch/DLLs/_testconsole.pyd
DELETED
|
Binary file (25.9 kB)
|
|
|
Pytorch/DLLs/_testimportmultiple.pyd
DELETED
|
Binary file (24.9 kB)
|
|
|
Pytorch/DLLs/_testinternalcapi.pyd
DELETED
|
Binary file (32.5 kB)
|
|
|
Pytorch/DLLs/_testmultiphase.pyd
DELETED
|
Binary file (37.1 kB)
|
|
|
Pytorch/DLLs/_tkinter.pyd
DELETED
|
Binary file (66.8 kB)
|
|
|
Pytorch/DLLs/_uuid.pyd
DELETED
|
Binary file (24.8 kB)
|
|
|
Pytorch/DLLs/_zoneinfo.pyd
DELETED
|
Binary file (44.8 kB)
|
|
|
Pytorch/DLLs/py.ico
DELETED
|
Binary file (75.8 kB)
|
|
|
Pytorch/DLLs/pyc.ico
DELETED
|
Binary file (78.4 kB)
|
|
|
Pytorch/DLLs/pyexpat.pyd
DELETED
|
Binary file (202 kB)
|
|
|
Pytorch/DLLs/select.pyd
DELETED
|
Binary file (30.5 kB)
|
|
|
Pytorch/DLLs/unicodedata.pyd
DELETED
|
@@ -1,3 +0,0 @@
|
|
| 1 |
-
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:dc0b7e48b8d7319f515877b98e086b8a85b24a47c0cc8b1d8a127d72d94272bc
|
| 3 |
-
size 1121560
|
|
|
|
|
|
|
|
|
|
|
|
Pytorch/DLLs/winsound.pyd
DELETED
|
Binary file (31 kB)
|
|
|
Pytorch/DLLs/xxlimited.pyd
DELETED
|
Binary file (25.4 kB)
|
|
|
Pytorch/DLLs/xxlimited_35.pyd
DELETED
|
Binary file (25.4 kB)
|
|
|
Pytorch/LICENSE_PYTHON.txt
DELETED
|
@@ -1,279 +0,0 @@
|
|
| 1 |
-
A. HISTORY OF THE SOFTWARE
|
| 2 |
-
==========================
|
| 3 |
-
|
| 4 |
-
Python was created in the early 1990s by Guido van Rossum at Stichting
|
| 5 |
-
Mathematisch Centrum (CWI, see https://www.cwi.nl) in the Netherlands
|
| 6 |
-
as a successor of a language called ABC. Guido remains Python's
|
| 7 |
-
principal author, although it includes many contributions from others.
|
| 8 |
-
|
| 9 |
-
In 1995, Guido continued his work on Python at the Corporation for
|
| 10 |
-
National Research Initiatives (CNRI, see https://www.cnri.reston.va.us)
|
| 11 |
-
in Reston, Virginia where he released several versions of the
|
| 12 |
-
software.
|
| 13 |
-
|
| 14 |
-
In May 2000, Guido and the Python core development team moved to
|
| 15 |
-
BeOpen.com to form the BeOpen PythonLabs team. In October of the same
|
| 16 |
-
year, the PythonLabs team moved to Digital Creations, which became
|
| 17 |
-
Zope Corporation. In 2001, the Python Software Foundation (PSF, see
|
| 18 |
-
https://www.python.org/psf/) was formed, a non-profit organization
|
| 19 |
-
created specifically to own Python-related Intellectual Property.
|
| 20 |
-
Zope Corporation was a sponsoring member of the PSF.
|
| 21 |
-
|
| 22 |
-
All Python releases are Open Source (see https://opensource.org for
|
| 23 |
-
the Open Source Definition). Historically, most, but not all, Python
|
| 24 |
-
releases have also been GPL-compatible; the table below summarizes
|
| 25 |
-
the various releases.
|
| 26 |
-
|
| 27 |
-
Release Derived Year Owner GPL-
|
| 28 |
-
from compatible? (1)
|
| 29 |
-
|
| 30 |
-
0.9.0 thru 1.2 1991-1995 CWI yes
|
| 31 |
-
1.3 thru 1.5.2 1.2 1995-1999 CNRI yes
|
| 32 |
-
1.6 1.5.2 2000 CNRI no
|
| 33 |
-
2.0 1.6 2000 BeOpen.com no
|
| 34 |
-
1.6.1 1.6 2001 CNRI yes (2)
|
| 35 |
-
2.1 2.0+1.6.1 2001 PSF no
|
| 36 |
-
2.0.1 2.0+1.6.1 2001 PSF yes
|
| 37 |
-
2.1.1 2.1+2.0.1 2001 PSF yes
|
| 38 |
-
2.1.2 2.1.1 2002 PSF yes
|
| 39 |
-
2.1.3 2.1.2 2002 PSF yes
|
| 40 |
-
2.2 and above 2.1.1 2001-now PSF yes
|
| 41 |
-
|
| 42 |
-
Footnotes:
|
| 43 |
-
|
| 44 |
-
(1) GPL-compatible doesn't mean that we're distributing Python under
|
| 45 |
-
the GPL. All Python licenses, unlike the GPL, let you distribute
|
| 46 |
-
a modified version without making your changes open source. The
|
| 47 |
-
GPL-compatible licenses make it possible to combine Python with
|
| 48 |
-
other software that is released under the GPL; the others don't.
|
| 49 |
-
|
| 50 |
-
(2) According to Richard Stallman, 1.6.1 is not GPL-compatible,
|
| 51 |
-
because its license has a choice of law clause. According to
|
| 52 |
-
CNRI, however, Stallman's lawyer has told CNRI's lawyer that 1.6.1
|
| 53 |
-
is "not incompatible" with the GPL.
|
| 54 |
-
|
| 55 |
-
Thanks to the many outside volunteers who have worked under Guido's
|
| 56 |
-
direction to make these releases possible.
|
| 57 |
-
|
| 58 |
-
|
| 59 |
-
B. TERMS AND CONDITIONS FOR ACCESSING OR OTHERWISE USING PYTHON
|
| 60 |
-
===============================================================
|
| 61 |
-
|
| 62 |
-
Python software and documentation are licensed under the
|
| 63 |
-
Python Software Foundation License Version 2.
|
| 64 |
-
|
| 65 |
-
Starting with Python 3.8.6, examples, recipes, and other code in
|
| 66 |
-
the documentation are dual licensed under the PSF License Version 2
|
| 67 |
-
and the Zero-Clause BSD license.
|
| 68 |
-
|
| 69 |
-
Some software incorporated into Python is under different licenses.
|
| 70 |
-
The licenses are listed with code falling under that license.
|
| 71 |
-
|
| 72 |
-
|
| 73 |
-
PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
|
| 74 |
-
--------------------------------------------
|
| 75 |
-
|
| 76 |
-
1. This LICENSE AGREEMENT is between the Python Software Foundation
|
| 77 |
-
("PSF"), and the Individual or Organization ("Licensee") accessing and
|
| 78 |
-
otherwise using this software ("Python") in source or binary form and
|
| 79 |
-
its associated documentation.
|
| 80 |
-
|
| 81 |
-
2. Subject to the terms and conditions of this License Agreement, PSF hereby
|
| 82 |
-
grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce,
|
| 83 |
-
analyze, test, perform and/or display publicly, prepare derivative works,
|
| 84 |
-
distribute, and otherwise use Python alone or in any derivative version,
|
| 85 |
-
provided, however, that PSF's License Agreement and PSF's notice of copyright,
|
| 86 |
-
i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
| 87 |
-
2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023 Python Software Foundation;
|
| 88 |
-
All Rights Reserved" are retained in Python alone or in any derivative version
|
| 89 |
-
prepared by Licensee.
|
| 90 |
-
|
| 91 |
-
3. In the event Licensee prepares a derivative work that is based on
|
| 92 |
-
or incorporates Python or any part thereof, and wants to make
|
| 93 |
-
the derivative work available to others as provided herein, then
|
| 94 |
-
Licensee hereby agrees to include in any such work a brief summary of
|
| 95 |
-
the changes made to Python.
|
| 96 |
-
|
| 97 |
-
4. PSF is making Python available to Licensee on an "AS IS"
|
| 98 |
-
basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
|
| 99 |
-
IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND
|
| 100 |
-
DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
|
| 101 |
-
FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT
|
| 102 |
-
INFRINGE ANY THIRD PARTY RIGHTS.
|
| 103 |
-
|
| 104 |
-
5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
|
| 105 |
-
FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
|
| 106 |
-
A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON,
|
| 107 |
-
OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
|
| 108 |
-
|
| 109 |
-
6. This License Agreement will automatically terminate upon a material
|
| 110 |
-
breach of its terms and conditions.
|
| 111 |
-
|
| 112 |
-
7. Nothing in this License Agreement shall be deemed to create any
|
| 113 |
-
relationship of agency, partnership, or joint venture between PSF and
|
| 114 |
-
Licensee. This License Agreement does not grant permission to use PSF
|
| 115 |
-
trademarks or trade name in a trademark sense to endorse or promote
|
| 116 |
-
products or services of Licensee, or any third party.
|
| 117 |
-
|
| 118 |
-
8. By copying, installing or otherwise using Python, Licensee
|
| 119 |
-
agrees to be bound by the terms and conditions of this License
|
| 120 |
-
Agreement.
|
| 121 |
-
|
| 122 |
-
|
| 123 |
-
BEOPEN.COM LICENSE AGREEMENT FOR PYTHON 2.0
|
| 124 |
-
-------------------------------------------
|
| 125 |
-
|
| 126 |
-
BEOPEN PYTHON OPEN SOURCE LICENSE AGREEMENT VERSION 1
|
| 127 |
-
|
| 128 |
-
1. This LICENSE AGREEMENT is between BeOpen.com ("BeOpen"), having an
|
| 129 |
-
office at 160 Saratoga Avenue, Santa Clara, CA 95051, and the
|
| 130 |
-
Individual or Organization ("Licensee") accessing and otherwise using
|
| 131 |
-
this software in source or binary form and its associated
|
| 132 |
-
documentation ("the Software").
|
| 133 |
-
|
| 134 |
-
2. Subject to the terms and conditions of this BeOpen Python License
|
| 135 |
-
Agreement, BeOpen hereby grants Licensee a non-exclusive,
|
| 136 |
-
royalty-free, world-wide license to reproduce, analyze, test, perform
|
| 137 |
-
and/or display publicly, prepare derivative works, distribute, and
|
| 138 |
-
otherwise use the Software alone or in any derivative version,
|
| 139 |
-
provided, however, that the BeOpen Python License is retained in the
|
| 140 |
-
Software, alone or in any derivative version prepared by Licensee.
|
| 141 |
-
|
| 142 |
-
3. BeOpen is making the Software available to Licensee on an "AS IS"
|
| 143 |
-
basis. BEOPEN MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
|
| 144 |
-
IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, BEOPEN MAKES NO AND
|
| 145 |
-
DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
|
| 146 |
-
FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE WILL NOT
|
| 147 |
-
INFRINGE ANY THIRD PARTY RIGHTS.
|
| 148 |
-
|
| 149 |
-
4. BEOPEN SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF THE
|
| 150 |
-
SOFTWARE FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS
|
| 151 |
-
AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THE SOFTWARE, OR ANY
|
| 152 |
-
DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
|
| 153 |
-
|
| 154 |
-
5. This License Agreement will automatically terminate upon a material
|
| 155 |
-
breach of its terms and conditions.
|
| 156 |
-
|
| 157 |
-
6. This License Agreement shall be governed by and interpreted in all
|
| 158 |
-
respects by the law of the State of California, excluding conflict of
|
| 159 |
-
law provisions. Nothing in this License Agreement shall be deemed to
|
| 160 |
-
create any relationship of agency, partnership, or joint venture
|
| 161 |
-
between BeOpen and Licensee. This License Agreement does not grant
|
| 162 |
-
permission to use BeOpen trademarks or trade names in a trademark
|
| 163 |
-
sense to endorse or promote products or services of Licensee, or any
|
| 164 |
-
third party. As an exception, the "BeOpen Python" logos available at
|
| 165 |
-
http://www.pythonlabs.com/logos.html may be used according to the
|
| 166 |
-
permissions granted on that web page.
|
| 167 |
-
|
| 168 |
-
7. By copying, installing or otherwise using the software, Licensee
|
| 169 |
-
agrees to be bound by the terms and conditions of this License
|
| 170 |
-
Agreement.
|
| 171 |
-
|
| 172 |
-
|
| 173 |
-
CNRI LICENSE AGREEMENT FOR PYTHON 1.6.1
|
| 174 |
-
---------------------------------------
|
| 175 |
-
|
| 176 |
-
1. This LICENSE AGREEMENT is between the Corporation for National
|
| 177 |
-
Research Initiatives, having an office at 1895 Preston White Drive,
|
| 178 |
-
Reston, VA 20191 ("CNRI"), and the Individual or Organization
|
| 179 |
-
("Licensee") accessing and otherwise using Python 1.6.1 software in
|
| 180 |
-
source or binary form and its associated documentation.
|
| 181 |
-
|
| 182 |
-
2. Subject to the terms and conditions of this License Agreement, CNRI
|
| 183 |
-
hereby grants Licensee a nonexclusive, royalty-free, world-wide
|
| 184 |
-
license to reproduce, analyze, test, perform and/or display publicly,
|
| 185 |
-
prepare derivative works, distribute, and otherwise use Python 1.6.1
|
| 186 |
-
alone or in any derivative version, provided, however, that CNRI's
|
| 187 |
-
License Agreement and CNRI's notice of copyright, i.e., "Copyright (c)
|
| 188 |
-
1995-2001 Corporation for National Research Initiatives; All Rights
|
| 189 |
-
Reserved" are retained in Python 1.6.1 alone or in any derivative
|
| 190 |
-
version prepared by Licensee. Alternately, in lieu of CNRI's License
|
| 191 |
-
Agreement, Licensee may substitute the following text (omitting the
|
| 192 |
-
quotes): "Python 1.6.1 is made available subject to the terms and
|
| 193 |
-
conditions in CNRI's License Agreement. This Agreement together with
|
| 194 |
-
Python 1.6.1 may be located on the internet using the following
|
| 195 |
-
unique, persistent identifier (known as a handle): 1895.22/1013. This
|
| 196 |
-
Agreement may also be obtained from a proxy server on the internet
|
| 197 |
-
using the following URL: http://hdl.handle.net/1895.22/1013".
|
| 198 |
-
|
| 199 |
-
3. In the event Licensee prepares a derivative work that is based on
|
| 200 |
-
or incorporates Python 1.6.1 or any part thereof, and wants to make
|
| 201 |
-
the derivative work available to others as provided herein, then
|
| 202 |
-
Licensee hereby agrees to include in any such work a brief summary of
|
| 203 |
-
the changes made to Python 1.6.1.
|
| 204 |
-
|
| 205 |
-
4. CNRI is making Python 1.6.1 available to Licensee on an "AS IS"
|
| 206 |
-
basis. CNRI MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
|
| 207 |
-
IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, CNRI MAKES NO AND
|
| 208 |
-
DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
|
| 209 |
-
FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 1.6.1 WILL NOT
|
| 210 |
-
INFRINGE ANY THIRD PARTY RIGHTS.
|
| 211 |
-
|
| 212 |
-
5. CNRI SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
|
| 213 |
-
1.6.1 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
|
| 214 |
-
A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 1.6.1,
|
| 215 |
-
OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
|
| 216 |
-
|
| 217 |
-
6. This License Agreement will automatically terminate upon a material
|
| 218 |
-
breach of its terms and conditions.
|
| 219 |
-
|
| 220 |
-
7. This License Agreement shall be governed by the federal
|
| 221 |
-
intellectual property law of the United States, including without
|
| 222 |
-
limitation the federal copyright law, and, to the extent such
|
| 223 |
-
U.S. federal law does not apply, by the law of the Commonwealth of
|
| 224 |
-
Virginia, excluding Virginia's conflict of law provisions.
|
| 225 |
-
Notwithstanding the foregoing, with regard to derivative works based
|
| 226 |
-
on Python 1.6.1 that incorporate non-separable material that was
|
| 227 |
-
previously distributed under the GNU General Public License (GPL), the
|
| 228 |
-
law of the Commonwealth of Virginia shall govern this License
|
| 229 |
-
Agreement only as to issues arising under or with respect to
|
| 230 |
-
Paragraphs 4, 5, and 7 of this License Agreement. Nothing in this
|
| 231 |
-
License Agreement shall be deemed to create any relationship of
|
| 232 |
-
agency, partnership, or joint venture between CNRI and Licensee. This
|
| 233 |
-
License Agreement does not grant permission to use CNRI trademarks or
|
| 234 |
-
trade name in a trademark sense to endorse or promote products or
|
| 235 |
-
services of Licensee, or any third party.
|
| 236 |
-
|
| 237 |
-
8. By clicking on the "ACCEPT" button where indicated, or by copying,
|
| 238 |
-
installing or otherwise using Python 1.6.1, Licensee agrees to be
|
| 239 |
-
bound by the terms and conditions of this License Agreement.
|
| 240 |
-
|
| 241 |
-
ACCEPT
|
| 242 |
-
|
| 243 |
-
|
| 244 |
-
CWI LICENSE AGREEMENT FOR PYTHON 0.9.0 THROUGH 1.2
|
| 245 |
-
--------------------------------------------------
|
| 246 |
-
|
| 247 |
-
Copyright (c) 1991 - 1995, Stichting Mathematisch Centrum Amsterdam,
|
| 248 |
-
The Netherlands. All rights reserved.
|
| 249 |
-
|
| 250 |
-
Permission to use, copy, modify, and distribute this software and its
|
| 251 |
-
documentation for any purpose and without fee is hereby granted,
|
| 252 |
-
provided that the above copyright notice appear in all copies and that
|
| 253 |
-
both that copyright notice and this permission notice appear in
|
| 254 |
-
supporting documentation, and that the name of Stichting Mathematisch
|
| 255 |
-
Centrum or CWI not be used in advertising or publicity pertaining to
|
| 256 |
-
distribution of the software without specific, written prior
|
| 257 |
-
permission.
|
| 258 |
-
|
| 259 |
-
STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
|
| 260 |
-
THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
| 261 |
-
FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
|
| 262 |
-
FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
| 263 |
-
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
| 264 |
-
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
| 265 |
-
OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
| 266 |
-
|
| 267 |
-
ZERO-CLAUSE BSD LICENSE FOR CODE IN THE PYTHON DOCUMENTATION
|
| 268 |
-
----------------------------------------------------------------------
|
| 269 |
-
|
| 270 |
-
Permission to use, copy, modify, and/or distribute this software for any
|
| 271 |
-
purpose with or without fee is hereby granted.
|
| 272 |
-
|
| 273 |
-
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
| 274 |
-
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
| 275 |
-
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
| 276 |
-
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
| 277 |
-
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
| 278 |
-
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
| 279 |
-
PERFORMANCE OF THIS SOFTWARE.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Pytorch/Lib/abc.py
DELETED
|
@@ -1,188 +0,0 @@
|
|
| 1 |
-
# Copyright 2007 Google, Inc. All Rights Reserved.
|
| 2 |
-
# Licensed to PSF under a Contributor Agreement.
|
| 3 |
-
|
| 4 |
-
"""Abstract Base Classes (ABCs) according to PEP 3119."""
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
def abstractmethod(funcobj):
|
| 8 |
-
"""A decorator indicating abstract methods.
|
| 9 |
-
|
| 10 |
-
Requires that the metaclass is ABCMeta or derived from it. A
|
| 11 |
-
class that has a metaclass derived from ABCMeta cannot be
|
| 12 |
-
instantiated unless all of its abstract methods are overridden.
|
| 13 |
-
The abstract methods can be called using any of the normal
|
| 14 |
-
'super' call mechanisms. abstractmethod() may be used to declare
|
| 15 |
-
abstract methods for properties and descriptors.
|
| 16 |
-
|
| 17 |
-
Usage:
|
| 18 |
-
|
| 19 |
-
class C(metaclass=ABCMeta):
|
| 20 |
-
@abstractmethod
|
| 21 |
-
def my_abstract_method(self, ...):
|
| 22 |
-
...
|
| 23 |
-
"""
|
| 24 |
-
funcobj.__isabstractmethod__ = True
|
| 25 |
-
return funcobj
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
class abstractclassmethod(classmethod):
|
| 29 |
-
"""A decorator indicating abstract classmethods.
|
| 30 |
-
|
| 31 |
-
Deprecated, use 'classmethod' with 'abstractmethod' instead:
|
| 32 |
-
|
| 33 |
-
class C(ABC):
|
| 34 |
-
@classmethod
|
| 35 |
-
@abstractmethod
|
| 36 |
-
def my_abstract_classmethod(cls, ...):
|
| 37 |
-
...
|
| 38 |
-
|
| 39 |
-
"""
|
| 40 |
-
|
| 41 |
-
__isabstractmethod__ = True
|
| 42 |
-
|
| 43 |
-
def __init__(self, callable):
|
| 44 |
-
callable.__isabstractmethod__ = True
|
| 45 |
-
super().__init__(callable)
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
class abstractstaticmethod(staticmethod):
|
| 49 |
-
"""A decorator indicating abstract staticmethods.
|
| 50 |
-
|
| 51 |
-
Deprecated, use 'staticmethod' with 'abstractmethod' instead:
|
| 52 |
-
|
| 53 |
-
class C(ABC):
|
| 54 |
-
@staticmethod
|
| 55 |
-
@abstractmethod
|
| 56 |
-
def my_abstract_staticmethod(...):
|
| 57 |
-
...
|
| 58 |
-
|
| 59 |
-
"""
|
| 60 |
-
|
| 61 |
-
__isabstractmethod__ = True
|
| 62 |
-
|
| 63 |
-
def __init__(self, callable):
|
| 64 |
-
callable.__isabstractmethod__ = True
|
| 65 |
-
super().__init__(callable)
|
| 66 |
-
|
| 67 |
-
|
| 68 |
-
class abstractproperty(property):
|
| 69 |
-
"""A decorator indicating abstract properties.
|
| 70 |
-
|
| 71 |
-
Deprecated, use 'property' with 'abstractmethod' instead:
|
| 72 |
-
|
| 73 |
-
class C(ABC):
|
| 74 |
-
@property
|
| 75 |
-
@abstractmethod
|
| 76 |
-
def my_abstract_property(self):
|
| 77 |
-
...
|
| 78 |
-
|
| 79 |
-
"""
|
| 80 |
-
|
| 81 |
-
__isabstractmethod__ = True
|
| 82 |
-
|
| 83 |
-
|
| 84 |
-
try:
|
| 85 |
-
from _abc import (get_cache_token, _abc_init, _abc_register,
|
| 86 |
-
_abc_instancecheck, _abc_subclasscheck, _get_dump,
|
| 87 |
-
_reset_registry, _reset_caches)
|
| 88 |
-
except ImportError:
|
| 89 |
-
from _py_abc import ABCMeta, get_cache_token
|
| 90 |
-
ABCMeta.__module__ = 'abc'
|
| 91 |
-
else:
|
| 92 |
-
class ABCMeta(type):
|
| 93 |
-
"""Metaclass for defining Abstract Base Classes (ABCs).
|
| 94 |
-
|
| 95 |
-
Use this metaclass to create an ABC. An ABC can be subclassed
|
| 96 |
-
directly, and then acts as a mix-in class. You can also register
|
| 97 |
-
unrelated concrete classes (even built-in classes) and unrelated
|
| 98 |
-
ABCs as 'virtual subclasses' -- these and their descendants will
|
| 99 |
-
be considered subclasses of the registering ABC by the built-in
|
| 100 |
-
issubclass() function, but the registering ABC won't show up in
|
| 101 |
-
their MRO (Method Resolution Order) nor will method
|
| 102 |
-
implementations defined by the registering ABC be callable (not
|
| 103 |
-
even via super()).
|
| 104 |
-
"""
|
| 105 |
-
def __new__(mcls, name, bases, namespace, **kwargs):
|
| 106 |
-
cls = super().__new__(mcls, name, bases, namespace, **kwargs)
|
| 107 |
-
_abc_init(cls)
|
| 108 |
-
return cls
|
| 109 |
-
|
| 110 |
-
def register(cls, subclass):
|
| 111 |
-
"""Register a virtual subclass of an ABC.
|
| 112 |
-
|
| 113 |
-
Returns the subclass, to allow usage as a class decorator.
|
| 114 |
-
"""
|
| 115 |
-
return _abc_register(cls, subclass)
|
| 116 |
-
|
| 117 |
-
def __instancecheck__(cls, instance):
|
| 118 |
-
"""Override for isinstance(instance, cls)."""
|
| 119 |
-
return _abc_instancecheck(cls, instance)
|
| 120 |
-
|
| 121 |
-
def __subclasscheck__(cls, subclass):
|
| 122 |
-
"""Override for issubclass(subclass, cls)."""
|
| 123 |
-
return _abc_subclasscheck(cls, subclass)
|
| 124 |
-
|
| 125 |
-
def _dump_registry(cls, file=None):
|
| 126 |
-
"""Debug helper to print the ABC registry."""
|
| 127 |
-
print(f"Class: {cls.__module__}.{cls.__qualname__}", file=file)
|
| 128 |
-
print(f"Inv. counter: {get_cache_token()}", file=file)
|
| 129 |
-
(_abc_registry, _abc_cache, _abc_negative_cache,
|
| 130 |
-
_abc_negative_cache_version) = _get_dump(cls)
|
| 131 |
-
print(f"_abc_registry: {_abc_registry!r}", file=file)
|
| 132 |
-
print(f"_abc_cache: {_abc_cache!r}", file=file)
|
| 133 |
-
print(f"_abc_negative_cache: {_abc_negative_cache!r}", file=file)
|
| 134 |
-
print(f"_abc_negative_cache_version: {_abc_negative_cache_version!r}",
|
| 135 |
-
file=file)
|
| 136 |
-
|
| 137 |
-
def _abc_registry_clear(cls):
|
| 138 |
-
"""Clear the registry (for debugging or testing)."""
|
| 139 |
-
_reset_registry(cls)
|
| 140 |
-
|
| 141 |
-
def _abc_caches_clear(cls):
|
| 142 |
-
"""Clear the caches (for debugging or testing)."""
|
| 143 |
-
_reset_caches(cls)
|
| 144 |
-
|
| 145 |
-
|
| 146 |
-
def update_abstractmethods(cls):
|
| 147 |
-
"""Recalculate the set of abstract methods of an abstract class.
|
| 148 |
-
|
| 149 |
-
If a class has had one of its abstract methods implemented after the
|
| 150 |
-
class was created, the method will not be considered implemented until
|
| 151 |
-
this function is called. Alternatively, if a new abstract method has been
|
| 152 |
-
added to the class, it will only be considered an abstract method of the
|
| 153 |
-
class after this function is called.
|
| 154 |
-
|
| 155 |
-
This function should be called before any use is made of the class,
|
| 156 |
-
usually in class decorators that add methods to the subject class.
|
| 157 |
-
|
| 158 |
-
Returns cls, to allow usage as a class decorator.
|
| 159 |
-
|
| 160 |
-
If cls is not an instance of ABCMeta, does nothing.
|
| 161 |
-
"""
|
| 162 |
-
if not hasattr(cls, '__abstractmethods__'):
|
| 163 |
-
# We check for __abstractmethods__ here because cls might by a C
|
| 164 |
-
# implementation or a python implementation (especially during
|
| 165 |
-
# testing), and we want to handle both cases.
|
| 166 |
-
return cls
|
| 167 |
-
|
| 168 |
-
abstracts = set()
|
| 169 |
-
# Check the existing abstract methods of the parents, keep only the ones
|
| 170 |
-
# that are not implemented.
|
| 171 |
-
for scls in cls.__bases__:
|
| 172 |
-
for name in getattr(scls, '__abstractmethods__', ()):
|
| 173 |
-
value = getattr(cls, name, None)
|
| 174 |
-
if getattr(value, "__isabstractmethod__", False):
|
| 175 |
-
abstracts.add(name)
|
| 176 |
-
# Also add any other newly added abstract methods.
|
| 177 |
-
for name, value in cls.__dict__.items():
|
| 178 |
-
if getattr(value, "__isabstractmethod__", False):
|
| 179 |
-
abstracts.add(name)
|
| 180 |
-
cls.__abstractmethods__ = frozenset(abstracts)
|
| 181 |
-
return cls
|
| 182 |
-
|
| 183 |
-
|
| 184 |
-
class ABC(metaclass=ABCMeta):
|
| 185 |
-
"""Helper class that provides a standard way to create an ABC using
|
| 186 |
-
inheritance.
|
| 187 |
-
"""
|
| 188 |
-
__slots__ = ()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Pytorch/Lib/aifc.py
DELETED
|
@@ -1,947 +0,0 @@
|
|
| 1 |
-
"""Stuff to parse AIFF-C and AIFF files.
|
| 2 |
-
|
| 3 |
-
Unless explicitly stated otherwise, the description below is true
|
| 4 |
-
both for AIFF-C files and AIFF files.
|
| 5 |
-
|
| 6 |
-
An AIFF-C file has the following structure.
|
| 7 |
-
|
| 8 |
-
+-----------------+
|
| 9 |
-
| FORM |
|
| 10 |
-
+-----------------+
|
| 11 |
-
| <size> |
|
| 12 |
-
+----+------------+
|
| 13 |
-
| | AIFC |
|
| 14 |
-
| +------------+
|
| 15 |
-
| | <chunks> |
|
| 16 |
-
| | . |
|
| 17 |
-
| | . |
|
| 18 |
-
| | . |
|
| 19 |
-
+----+------------+
|
| 20 |
-
|
| 21 |
-
An AIFF file has the string "AIFF" instead of "AIFC".
|
| 22 |
-
|
| 23 |
-
A chunk consists of an identifier (4 bytes) followed by a size (4 bytes,
|
| 24 |
-
big endian order), followed by the data. The size field does not include
|
| 25 |
-
the size of the 8 byte header.
|
| 26 |
-
|
| 27 |
-
The following chunk types are recognized.
|
| 28 |
-
|
| 29 |
-
FVER
|
| 30 |
-
<version number of AIFF-C defining document> (AIFF-C only).
|
| 31 |
-
MARK
|
| 32 |
-
<# of markers> (2 bytes)
|
| 33 |
-
list of markers:
|
| 34 |
-
<marker ID> (2 bytes, must be > 0)
|
| 35 |
-
<position> (4 bytes)
|
| 36 |
-
<marker name> ("pstring")
|
| 37 |
-
COMM
|
| 38 |
-
<# of channels> (2 bytes)
|
| 39 |
-
<# of sound frames> (4 bytes)
|
| 40 |
-
<size of the samples> (2 bytes)
|
| 41 |
-
<sampling frequency> (10 bytes, IEEE 80-bit extended
|
| 42 |
-
floating point)
|
| 43 |
-
in AIFF-C files only:
|
| 44 |
-
<compression type> (4 bytes)
|
| 45 |
-
<human-readable version of compression type> ("pstring")
|
| 46 |
-
SSND
|
| 47 |
-
<offset> (4 bytes, not used by this program)
|
| 48 |
-
<blocksize> (4 bytes, not used by this program)
|
| 49 |
-
<sound data>
|
| 50 |
-
|
| 51 |
-
A pstring consists of 1 byte length, a string of characters, and 0 or 1
|
| 52 |
-
byte pad to make the total length even.
|
| 53 |
-
|
| 54 |
-
Usage.
|
| 55 |
-
|
| 56 |
-
Reading AIFF files:
|
| 57 |
-
f = aifc.open(file, 'r')
|
| 58 |
-
where file is either the name of a file or an open file pointer.
|
| 59 |
-
The open file pointer must have methods read(), seek(), and close().
|
| 60 |
-
In some types of audio files, if the setpos() method is not used,
|
| 61 |
-
the seek() method is not necessary.
|
| 62 |
-
|
| 63 |
-
This returns an instance of a class with the following public methods:
|
| 64 |
-
getnchannels() -- returns number of audio channels (1 for
|
| 65 |
-
mono, 2 for stereo)
|
| 66 |
-
getsampwidth() -- returns sample width in bytes
|
| 67 |
-
getframerate() -- returns sampling frequency
|
| 68 |
-
getnframes() -- returns number of audio frames
|
| 69 |
-
getcomptype() -- returns compression type ('NONE' for AIFF files)
|
| 70 |
-
getcompname() -- returns human-readable version of
|
| 71 |
-
compression type ('not compressed' for AIFF files)
|
| 72 |
-
getparams() -- returns a namedtuple consisting of all of the
|
| 73 |
-
above in the above order
|
| 74 |
-
getmarkers() -- get the list of marks in the audio file or None
|
| 75 |
-
if there are no marks
|
| 76 |
-
getmark(id) -- get mark with the specified id (raises an error
|
| 77 |
-
if the mark does not exist)
|
| 78 |
-
readframes(n) -- returns at most n frames of audio
|
| 79 |
-
rewind() -- rewind to the beginning of the audio stream
|
| 80 |
-
setpos(pos) -- seek to the specified position
|
| 81 |
-
tell() -- return the current position
|
| 82 |
-
close() -- close the instance (make it unusable)
|
| 83 |
-
The position returned by tell(), the position given to setpos() and
|
| 84 |
-
the position of marks are all compatible and have nothing to do with
|
| 85 |
-
the actual position in the file.
|
| 86 |
-
The close() method is called automatically when the class instance
|
| 87 |
-
is destroyed.
|
| 88 |
-
|
| 89 |
-
Writing AIFF files:
|
| 90 |
-
f = aifc.open(file, 'w')
|
| 91 |
-
where file is either the name of a file or an open file pointer.
|
| 92 |
-
The open file pointer must have methods write(), tell(), seek(), and
|
| 93 |
-
close().
|
| 94 |
-
|
| 95 |
-
This returns an instance of a class with the following public methods:
|
| 96 |
-
aiff() -- create an AIFF file (AIFF-C default)
|
| 97 |
-
aifc() -- create an AIFF-C file
|
| 98 |
-
setnchannels(n) -- set the number of channels
|
| 99 |
-
setsampwidth(n) -- set the sample width
|
| 100 |
-
setframerate(n) -- set the frame rate
|
| 101 |
-
setnframes(n) -- set the number of frames
|
| 102 |
-
setcomptype(type, name)
|
| 103 |
-
-- set the compression type and the
|
| 104 |
-
human-readable compression type
|
| 105 |
-
setparams(tuple)
|
| 106 |
-
-- set all parameters at once
|
| 107 |
-
setmark(id, pos, name)
|
| 108 |
-
-- add specified mark to the list of marks
|
| 109 |
-
tell() -- return current position in output file (useful
|
| 110 |
-
in combination with setmark())
|
| 111 |
-
writeframesraw(data)
|
| 112 |
-
-- write audio frames without pathing up the
|
| 113 |
-
file header
|
| 114 |
-
writeframes(data)
|
| 115 |
-
-- write audio frames and patch up the file header
|
| 116 |
-
close() -- patch up the file header and close the
|
| 117 |
-
output file
|
| 118 |
-
You should set the parameters before the first writeframesraw or
|
| 119 |
-
writeframes. The total number of frames does not need to be set,
|
| 120 |
-
but when it is set to the correct value, the header does not have to
|
| 121 |
-
be patched up.
|
| 122 |
-
It is best to first set all parameters, perhaps possibly the
|
| 123 |
-
compression type, and then write audio frames using writeframesraw.
|
| 124 |
-
When all frames have been written, either call writeframes(b'') or
|
| 125 |
-
close() to patch up the sizes in the header.
|
| 126 |
-
Marks can be added anytime. If there are any marks, you must call
|
| 127 |
-
close() after all frames have been written.
|
| 128 |
-
The close() method is called automatically when the class instance
|
| 129 |
-
is destroyed.
|
| 130 |
-
|
| 131 |
-
When a file is opened with the extension '.aiff', an AIFF file is
|
| 132 |
-
written, otherwise an AIFF-C file is written. This default can be
|
| 133 |
-
changed by calling aiff() or aifc() before the first writeframes or
|
| 134 |
-
writeframesraw.
|
| 135 |
-
"""
|
| 136 |
-
|
| 137 |
-
import struct
|
| 138 |
-
import builtins
|
| 139 |
-
import warnings
|
| 140 |
-
|
| 141 |
-
__all__ = ["Error", "open"]
|
| 142 |
-
|
| 143 |
-
class Error(Exception):
|
| 144 |
-
pass
|
| 145 |
-
|
| 146 |
-
_AIFC_version = 0xA2805140 # Version 1 of AIFF-C
|
| 147 |
-
|
| 148 |
-
def _read_long(file):
|
| 149 |
-
try:
|
| 150 |
-
return struct.unpack('>l', file.read(4))[0]
|
| 151 |
-
except struct.error:
|
| 152 |
-
raise EOFError from None
|
| 153 |
-
|
| 154 |
-
def _read_ulong(file):
|
| 155 |
-
try:
|
| 156 |
-
return struct.unpack('>L', file.read(4))[0]
|
| 157 |
-
except struct.error:
|
| 158 |
-
raise EOFError from None
|
| 159 |
-
|
| 160 |
-
def _read_short(file):
|
| 161 |
-
try:
|
| 162 |
-
return struct.unpack('>h', file.read(2))[0]
|
| 163 |
-
except struct.error:
|
| 164 |
-
raise EOFError from None
|
| 165 |
-
|
| 166 |
-
def _read_ushort(file):
|
| 167 |
-
try:
|
| 168 |
-
return struct.unpack('>H', file.read(2))[0]
|
| 169 |
-
except struct.error:
|
| 170 |
-
raise EOFError from None
|
| 171 |
-
|
| 172 |
-
def _read_string(file):
|
| 173 |
-
length = ord(file.read(1))
|
| 174 |
-
if length == 0:
|
| 175 |
-
data = b''
|
| 176 |
-
else:
|
| 177 |
-
data = file.read(length)
|
| 178 |
-
if length & 1 == 0:
|
| 179 |
-
dummy = file.read(1)
|
| 180 |
-
return data
|
| 181 |
-
|
| 182 |
-
_HUGE_VAL = 1.79769313486231e+308 # See <limits.h>
|
| 183 |
-
|
| 184 |
-
def _read_float(f): # 10 bytes
|
| 185 |
-
expon = _read_short(f) # 2 bytes
|
| 186 |
-
sign = 1
|
| 187 |
-
if expon < 0:
|
| 188 |
-
sign = -1
|
| 189 |
-
expon = expon + 0x8000
|
| 190 |
-
himant = _read_ulong(f) # 4 bytes
|
| 191 |
-
lomant = _read_ulong(f) # 4 bytes
|
| 192 |
-
if expon == himant == lomant == 0:
|
| 193 |
-
f = 0.0
|
| 194 |
-
elif expon == 0x7FFF:
|
| 195 |
-
f = _HUGE_VAL
|
| 196 |
-
else:
|
| 197 |
-
expon = expon - 16383
|
| 198 |
-
f = (himant * 0x100000000 + lomant) * pow(2.0, expon - 63)
|
| 199 |
-
return sign * f
|
| 200 |
-
|
| 201 |
-
def _write_short(f, x):
|
| 202 |
-
f.write(struct.pack('>h', x))
|
| 203 |
-
|
| 204 |
-
def _write_ushort(f, x):
|
| 205 |
-
f.write(struct.pack('>H', x))
|
| 206 |
-
|
| 207 |
-
def _write_long(f, x):
|
| 208 |
-
f.write(struct.pack('>l', x))
|
| 209 |
-
|
| 210 |
-
def _write_ulong(f, x):
|
| 211 |
-
f.write(struct.pack('>L', x))
|
| 212 |
-
|
| 213 |
-
def _write_string(f, s):
|
| 214 |
-
if len(s) > 255:
|
| 215 |
-
raise ValueError("string exceeds maximum pstring length")
|
| 216 |
-
f.write(struct.pack('B', len(s)))
|
| 217 |
-
f.write(s)
|
| 218 |
-
if len(s) & 1 == 0:
|
| 219 |
-
f.write(b'\x00')
|
| 220 |
-
|
| 221 |
-
def _write_float(f, x):
|
| 222 |
-
import math
|
| 223 |
-
if x < 0:
|
| 224 |
-
sign = 0x8000
|
| 225 |
-
x = x * -1
|
| 226 |
-
else:
|
| 227 |
-
sign = 0
|
| 228 |
-
if x == 0:
|
| 229 |
-
expon = 0
|
| 230 |
-
himant = 0
|
| 231 |
-
lomant = 0
|
| 232 |
-
else:
|
| 233 |
-
fmant, expon = math.frexp(x)
|
| 234 |
-
if expon > 16384 or fmant >= 1 or fmant != fmant: # Infinity or NaN
|
| 235 |
-
expon = sign|0x7FFF
|
| 236 |
-
himant = 0
|
| 237 |
-
lomant = 0
|
| 238 |
-
else: # Finite
|
| 239 |
-
expon = expon + 16382
|
| 240 |
-
if expon < 0: # denormalized
|
| 241 |
-
fmant = math.ldexp(fmant, expon)
|
| 242 |
-
expon = 0
|
| 243 |
-
expon = expon | sign
|
| 244 |
-
fmant = math.ldexp(fmant, 32)
|
| 245 |
-
fsmant = math.floor(fmant)
|
| 246 |
-
himant = int(fsmant)
|
| 247 |
-
fmant = math.ldexp(fmant - fsmant, 32)
|
| 248 |
-
fsmant = math.floor(fmant)
|
| 249 |
-
lomant = int(fsmant)
|
| 250 |
-
_write_ushort(f, expon)
|
| 251 |
-
_write_ulong(f, himant)
|
| 252 |
-
_write_ulong(f, lomant)
|
| 253 |
-
|
| 254 |
-
from chunk import Chunk
|
| 255 |
-
from collections import namedtuple
|
| 256 |
-
|
| 257 |
-
_aifc_params = namedtuple('_aifc_params',
|
| 258 |
-
'nchannels sampwidth framerate nframes comptype compname')
|
| 259 |
-
|
| 260 |
-
_aifc_params.nchannels.__doc__ = 'Number of audio channels (1 for mono, 2 for stereo)'
|
| 261 |
-
_aifc_params.sampwidth.__doc__ = 'Sample width in bytes'
|
| 262 |
-
_aifc_params.framerate.__doc__ = 'Sampling frequency'
|
| 263 |
-
_aifc_params.nframes.__doc__ = 'Number of audio frames'
|
| 264 |
-
_aifc_params.comptype.__doc__ = 'Compression type ("NONE" for AIFF files)'
|
| 265 |
-
_aifc_params.compname.__doc__ = ("""\
|
| 266 |
-
A human-readable version of the compression type
|
| 267 |
-
('not compressed' for AIFF files)""")
|
| 268 |
-
|
| 269 |
-
|
| 270 |
-
class Aifc_read:
|
| 271 |
-
# Variables used in this class:
|
| 272 |
-
#
|
| 273 |
-
# These variables are available to the user though appropriate
|
| 274 |
-
# methods of this class:
|
| 275 |
-
# _file -- the open file with methods read(), close(), and seek()
|
| 276 |
-
# set through the __init__() method
|
| 277 |
-
# _nchannels -- the number of audio channels
|
| 278 |
-
# available through the getnchannels() method
|
| 279 |
-
# _nframes -- the number of audio frames
|
| 280 |
-
# available through the getnframes() method
|
| 281 |
-
# _sampwidth -- the number of bytes per audio sample
|
| 282 |
-
# available through the getsampwidth() method
|
| 283 |
-
# _framerate -- the sampling frequency
|
| 284 |
-
# available through the getframerate() method
|
| 285 |
-
# _comptype -- the AIFF-C compression type ('NONE' if AIFF)
|
| 286 |
-
# available through the getcomptype() method
|
| 287 |
-
# _compname -- the human-readable AIFF-C compression type
|
| 288 |
-
# available through the getcomptype() method
|
| 289 |
-
# _markers -- the marks in the audio file
|
| 290 |
-
# available through the getmarkers() and getmark()
|
| 291 |
-
# methods
|
| 292 |
-
# _soundpos -- the position in the audio stream
|
| 293 |
-
# available through the tell() method, set through the
|
| 294 |
-
# setpos() method
|
| 295 |
-
#
|
| 296 |
-
# These variables are used internally only:
|
| 297 |
-
# _version -- the AIFF-C version number
|
| 298 |
-
# _decomp -- the decompressor from builtin module cl
|
| 299 |
-
# _comm_chunk_read -- 1 iff the COMM chunk has been read
|
| 300 |
-
# _aifc -- 1 iff reading an AIFF-C file
|
| 301 |
-
# _ssnd_seek_needed -- 1 iff positioned correctly in audio
|
| 302 |
-
# file for readframes()
|
| 303 |
-
# _ssnd_chunk -- instantiation of a chunk class for the SSND chunk
|
| 304 |
-
# _framesize -- size of one frame in the file
|
| 305 |
-
|
| 306 |
-
_file = None # Set here since __del__ checks it
|
| 307 |
-
|
| 308 |
-
def initfp(self, file):
|
| 309 |
-
self._version = 0
|
| 310 |
-
self._convert = None
|
| 311 |
-
self._markers = []
|
| 312 |
-
self._soundpos = 0
|
| 313 |
-
self._file = file
|
| 314 |
-
chunk = Chunk(file)
|
| 315 |
-
if chunk.getname() != b'FORM':
|
| 316 |
-
raise Error('file does not start with FORM id')
|
| 317 |
-
formdata = chunk.read(4)
|
| 318 |
-
if formdata == b'AIFF':
|
| 319 |
-
self._aifc = 0
|
| 320 |
-
elif formdata == b'AIFC':
|
| 321 |
-
self._aifc = 1
|
| 322 |
-
else:
|
| 323 |
-
raise Error('not an AIFF or AIFF-C file')
|
| 324 |
-
self._comm_chunk_read = 0
|
| 325 |
-
self._ssnd_chunk = None
|
| 326 |
-
while 1:
|
| 327 |
-
self._ssnd_seek_needed = 1
|
| 328 |
-
try:
|
| 329 |
-
chunk = Chunk(self._file)
|
| 330 |
-
except EOFError:
|
| 331 |
-
break
|
| 332 |
-
chunkname = chunk.getname()
|
| 333 |
-
if chunkname == b'COMM':
|
| 334 |
-
self._read_comm_chunk(chunk)
|
| 335 |
-
self._comm_chunk_read = 1
|
| 336 |
-
elif chunkname == b'SSND':
|
| 337 |
-
self._ssnd_chunk = chunk
|
| 338 |
-
dummy = chunk.read(8)
|
| 339 |
-
self._ssnd_seek_needed = 0
|
| 340 |
-
elif chunkname == b'FVER':
|
| 341 |
-
self._version = _read_ulong(chunk)
|
| 342 |
-
elif chunkname == b'MARK':
|
| 343 |
-
self._readmark(chunk)
|
| 344 |
-
chunk.skip()
|
| 345 |
-
if not self._comm_chunk_read or not self._ssnd_chunk:
|
| 346 |
-
raise Error('COMM chunk and/or SSND chunk missing')
|
| 347 |
-
|
| 348 |
-
def __init__(self, f):
|
| 349 |
-
if isinstance(f, str):
|
| 350 |
-
file_object = builtins.open(f, 'rb')
|
| 351 |
-
try:
|
| 352 |
-
self.initfp(file_object)
|
| 353 |
-
except:
|
| 354 |
-
file_object.close()
|
| 355 |
-
raise
|
| 356 |
-
else:
|
| 357 |
-
# assume it is an open file object already
|
| 358 |
-
self.initfp(f)
|
| 359 |
-
|
| 360 |
-
def __enter__(self):
|
| 361 |
-
return self
|
| 362 |
-
|
| 363 |
-
def __exit__(self, *args):
|
| 364 |
-
self.close()
|
| 365 |
-
|
| 366 |
-
#
|
| 367 |
-
# User visible methods.
|
| 368 |
-
#
|
| 369 |
-
def getfp(self):
|
| 370 |
-
return self._file
|
| 371 |
-
|
| 372 |
-
def rewind(self):
|
| 373 |
-
self._ssnd_seek_needed = 1
|
| 374 |
-
self._soundpos = 0
|
| 375 |
-
|
| 376 |
-
def close(self):
|
| 377 |
-
file = self._file
|
| 378 |
-
if file is not None:
|
| 379 |
-
self._file = None
|
| 380 |
-
file.close()
|
| 381 |
-
|
| 382 |
-
def tell(self):
|
| 383 |
-
return self._soundpos
|
| 384 |
-
|
| 385 |
-
def getnchannels(self):
|
| 386 |
-
return self._nchannels
|
| 387 |
-
|
| 388 |
-
def getnframes(self):
|
| 389 |
-
return self._nframes
|
| 390 |
-
|
| 391 |
-
def getsampwidth(self):
|
| 392 |
-
return self._sampwidth
|
| 393 |
-
|
| 394 |
-
def getframerate(self):
|
| 395 |
-
return self._framerate
|
| 396 |
-
|
| 397 |
-
def getcomptype(self):
|
| 398 |
-
return self._comptype
|
| 399 |
-
|
| 400 |
-
def getcompname(self):
|
| 401 |
-
return self._compname
|
| 402 |
-
|
| 403 |
-
## def getversion(self):
|
| 404 |
-
## return self._version
|
| 405 |
-
|
| 406 |
-
def getparams(self):
|
| 407 |
-
return _aifc_params(self.getnchannels(), self.getsampwidth(),
|
| 408 |
-
self.getframerate(), self.getnframes(),
|
| 409 |
-
self.getcomptype(), self.getcompname())
|
| 410 |
-
|
| 411 |
-
def getmarkers(self):
|
| 412 |
-
if len(self._markers) == 0:
|
| 413 |
-
return None
|
| 414 |
-
return self._markers
|
| 415 |
-
|
| 416 |
-
def getmark(self, id):
|
| 417 |
-
for marker in self._markers:
|
| 418 |
-
if id == marker[0]:
|
| 419 |
-
return marker
|
| 420 |
-
raise Error('marker {0!r} does not exist'.format(id))
|
| 421 |
-
|
| 422 |
-
def setpos(self, pos):
|
| 423 |
-
if pos < 0 or pos > self._nframes:
|
| 424 |
-
raise Error('position not in range')
|
| 425 |
-
self._soundpos = pos
|
| 426 |
-
self._ssnd_seek_needed = 1
|
| 427 |
-
|
| 428 |
-
def readframes(self, nframes):
|
| 429 |
-
if self._ssnd_seek_needed:
|
| 430 |
-
self._ssnd_chunk.seek(0)
|
| 431 |
-
dummy = self._ssnd_chunk.read(8)
|
| 432 |
-
pos = self._soundpos * self._framesize
|
| 433 |
-
if pos:
|
| 434 |
-
self._ssnd_chunk.seek(pos + 8)
|
| 435 |
-
self._ssnd_seek_needed = 0
|
| 436 |
-
if nframes == 0:
|
| 437 |
-
return b''
|
| 438 |
-
data = self._ssnd_chunk.read(nframes * self._framesize)
|
| 439 |
-
if self._convert and data:
|
| 440 |
-
data = self._convert(data)
|
| 441 |
-
self._soundpos = self._soundpos + len(data) // (self._nchannels
|
| 442 |
-
* self._sampwidth)
|
| 443 |
-
return data
|
| 444 |
-
|
| 445 |
-
#
|
| 446 |
-
# Internal methods.
|
| 447 |
-
#
|
| 448 |
-
|
| 449 |
-
def _alaw2lin(self, data):
|
| 450 |
-
import audioop
|
| 451 |
-
return audioop.alaw2lin(data, 2)
|
| 452 |
-
|
| 453 |
-
def _ulaw2lin(self, data):
|
| 454 |
-
import audioop
|
| 455 |
-
return audioop.ulaw2lin(data, 2)
|
| 456 |
-
|
| 457 |
-
def _adpcm2lin(self, data):
|
| 458 |
-
import audioop
|
| 459 |
-
if not hasattr(self, '_adpcmstate'):
|
| 460 |
-
# first time
|
| 461 |
-
self._adpcmstate = None
|
| 462 |
-
data, self._adpcmstate = audioop.adpcm2lin(data, 2, self._adpcmstate)
|
| 463 |
-
return data
|
| 464 |
-
|
| 465 |
-
def _read_comm_chunk(self, chunk):
|
| 466 |
-
self._nchannels = _read_short(chunk)
|
| 467 |
-
self._nframes = _read_long(chunk)
|
| 468 |
-
self._sampwidth = (_read_short(chunk) + 7) // 8
|
| 469 |
-
self._framerate = int(_read_float(chunk))
|
| 470 |
-
if self._sampwidth <= 0:
|
| 471 |
-
raise Error('bad sample width')
|
| 472 |
-
if self._nchannels <= 0:
|
| 473 |
-
raise Error('bad # of channels')
|
| 474 |
-
self._framesize = self._nchannels * self._sampwidth
|
| 475 |
-
if self._aifc:
|
| 476 |
-
#DEBUG: SGI's soundeditor produces a bad size :-(
|
| 477 |
-
kludge = 0
|
| 478 |
-
if chunk.chunksize == 18:
|
| 479 |
-
kludge = 1
|
| 480 |
-
warnings.warn('Warning: bad COMM chunk size')
|
| 481 |
-
chunk.chunksize = 23
|
| 482 |
-
#DEBUG end
|
| 483 |
-
self._comptype = chunk.read(4)
|
| 484 |
-
#DEBUG start
|
| 485 |
-
if kludge:
|
| 486 |
-
length = ord(chunk.file.read(1))
|
| 487 |
-
if length & 1 == 0:
|
| 488 |
-
length = length + 1
|
| 489 |
-
chunk.chunksize = chunk.chunksize + length
|
| 490 |
-
chunk.file.seek(-1, 1)
|
| 491 |
-
#DEBUG end
|
| 492 |
-
self._compname = _read_string(chunk)
|
| 493 |
-
if self._comptype != b'NONE':
|
| 494 |
-
if self._comptype == b'G722':
|
| 495 |
-
self._convert = self._adpcm2lin
|
| 496 |
-
elif self._comptype in (b'ulaw', b'ULAW'):
|
| 497 |
-
self._convert = self._ulaw2lin
|
| 498 |
-
elif self._comptype in (b'alaw', b'ALAW'):
|
| 499 |
-
self._convert = self._alaw2lin
|
| 500 |
-
else:
|
| 501 |
-
raise Error('unsupported compression type')
|
| 502 |
-
self._sampwidth = 2
|
| 503 |
-
else:
|
| 504 |
-
self._comptype = b'NONE'
|
| 505 |
-
self._compname = b'not compressed'
|
| 506 |
-
|
| 507 |
-
def _readmark(self, chunk):
|
| 508 |
-
nmarkers = _read_short(chunk)
|
| 509 |
-
# Some files appear to contain invalid counts.
|
| 510 |
-
# Cope with this by testing for EOF.
|
| 511 |
-
try:
|
| 512 |
-
for i in range(nmarkers):
|
| 513 |
-
id = _read_short(chunk)
|
| 514 |
-
pos = _read_long(chunk)
|
| 515 |
-
name = _read_string(chunk)
|
| 516 |
-
if pos or name:
|
| 517 |
-
# some files appear to have
|
| 518 |
-
# dummy markers consisting of
|
| 519 |
-
# a position 0 and name ''
|
| 520 |
-
self._markers.append((id, pos, name))
|
| 521 |
-
except EOFError:
|
| 522 |
-
w = ('Warning: MARK chunk contains only %s marker%s instead of %s' %
|
| 523 |
-
(len(self._markers), '' if len(self._markers) == 1 else 's',
|
| 524 |
-
nmarkers))
|
| 525 |
-
warnings.warn(w)
|
| 526 |
-
|
| 527 |
-
class Aifc_write:
|
| 528 |
-
# Variables used in this class:
|
| 529 |
-
#
|
| 530 |
-
# These variables are user settable through appropriate methods
|
| 531 |
-
# of this class:
|
| 532 |
-
# _file -- the open file with methods write(), close(), tell(), seek()
|
| 533 |
-
# set through the __init__() method
|
| 534 |
-
# _comptype -- the AIFF-C compression type ('NONE' in AIFF)
|
| 535 |
-
# set through the setcomptype() or setparams() method
|
| 536 |
-
# _compname -- the human-readable AIFF-C compression type
|
| 537 |
-
# set through the setcomptype() or setparams() method
|
| 538 |
-
# _nchannels -- the number of audio channels
|
| 539 |
-
# set through the setnchannels() or setparams() method
|
| 540 |
-
# _sampwidth -- the number of bytes per audio sample
|
| 541 |
-
# set through the setsampwidth() or setparams() method
|
| 542 |
-
# _framerate -- the sampling frequency
|
| 543 |
-
# set through the setframerate() or setparams() method
|
| 544 |
-
# _nframes -- the number of audio frames written to the header
|
| 545 |
-
# set through the setnframes() or setparams() method
|
| 546 |
-
# _aifc -- whether we're writing an AIFF-C file or an AIFF file
|
| 547 |
-
# set through the aifc() method, reset through the
|
| 548 |
-
# aiff() method
|
| 549 |
-
#
|
| 550 |
-
# These variables are used internally only:
|
| 551 |
-
# _version -- the AIFF-C version number
|
| 552 |
-
# _comp -- the compressor from builtin module cl
|
| 553 |
-
# _nframeswritten -- the number of audio frames actually written
|
| 554 |
-
# _datalength -- the size of the audio samples written to the header
|
| 555 |
-
# _datawritten -- the size of the audio samples actually written
|
| 556 |
-
|
| 557 |
-
_file = None # Set here since __del__ checks it
|
| 558 |
-
|
| 559 |
-
def __init__(self, f):
|
| 560 |
-
if isinstance(f, str):
|
| 561 |
-
file_object = builtins.open(f, 'wb')
|
| 562 |
-
try:
|
| 563 |
-
self.initfp(file_object)
|
| 564 |
-
except:
|
| 565 |
-
file_object.close()
|
| 566 |
-
raise
|
| 567 |
-
|
| 568 |
-
# treat .aiff file extensions as non-compressed audio
|
| 569 |
-
if f.endswith('.aiff'):
|
| 570 |
-
self._aifc = 0
|
| 571 |
-
else:
|
| 572 |
-
# assume it is an open file object already
|
| 573 |
-
self.initfp(f)
|
| 574 |
-
|
| 575 |
-
def initfp(self, file):
|
| 576 |
-
self._file = file
|
| 577 |
-
self._version = _AIFC_version
|
| 578 |
-
self._comptype = b'NONE'
|
| 579 |
-
self._compname = b'not compressed'
|
| 580 |
-
self._convert = None
|
| 581 |
-
self._nchannels = 0
|
| 582 |
-
self._sampwidth = 0
|
| 583 |
-
self._framerate = 0
|
| 584 |
-
self._nframes = 0
|
| 585 |
-
self._nframeswritten = 0
|
| 586 |
-
self._datawritten = 0
|
| 587 |
-
self._datalength = 0
|
| 588 |
-
self._markers = []
|
| 589 |
-
self._marklength = 0
|
| 590 |
-
self._aifc = 1 # AIFF-C is default
|
| 591 |
-
|
| 592 |
-
def __del__(self):
|
| 593 |
-
self.close()
|
| 594 |
-
|
| 595 |
-
def __enter__(self):
|
| 596 |
-
return self
|
| 597 |
-
|
| 598 |
-
def __exit__(self, *args):
|
| 599 |
-
self.close()
|
| 600 |
-
|
| 601 |
-
#
|
| 602 |
-
# User visible methods.
|
| 603 |
-
#
|
| 604 |
-
def aiff(self):
|
| 605 |
-
if self._nframeswritten:
|
| 606 |
-
raise Error('cannot change parameters after starting to write')
|
| 607 |
-
self._aifc = 0
|
| 608 |
-
|
| 609 |
-
def aifc(self):
|
| 610 |
-
if self._nframeswritten:
|
| 611 |
-
raise Error('cannot change parameters after starting to write')
|
| 612 |
-
self._aifc = 1
|
| 613 |
-
|
| 614 |
-
def setnchannels(self, nchannels):
|
| 615 |
-
if self._nframeswritten:
|
| 616 |
-
raise Error('cannot change parameters after starting to write')
|
| 617 |
-
if nchannels < 1:
|
| 618 |
-
raise Error('bad # of channels')
|
| 619 |
-
self._nchannels = nchannels
|
| 620 |
-
|
| 621 |
-
def getnchannels(self):
|
| 622 |
-
if not self._nchannels:
|
| 623 |
-
raise Error('number of channels not set')
|
| 624 |
-
return self._nchannels
|
| 625 |
-
|
| 626 |
-
def setsampwidth(self, sampwidth):
|
| 627 |
-
if self._nframeswritten:
|
| 628 |
-
raise Error('cannot change parameters after starting to write')
|
| 629 |
-
if sampwidth < 1 or sampwidth > 4:
|
| 630 |
-
raise Error('bad sample width')
|
| 631 |
-
self._sampwidth = sampwidth
|
| 632 |
-
|
| 633 |
-
def getsampwidth(self):
|
| 634 |
-
if not self._sampwidth:
|
| 635 |
-
raise Error('sample width not set')
|
| 636 |
-
return self._sampwidth
|
| 637 |
-
|
| 638 |
-
def setframerate(self, framerate):
|
| 639 |
-
if self._nframeswritten:
|
| 640 |
-
raise Error('cannot change parameters after starting to write')
|
| 641 |
-
if framerate <= 0:
|
| 642 |
-
raise Error('bad frame rate')
|
| 643 |
-
self._framerate = framerate
|
| 644 |
-
|
| 645 |
-
def getframerate(self):
|
| 646 |
-
if not self._framerate:
|
| 647 |
-
raise Error('frame rate not set')
|
| 648 |
-
return self._framerate
|
| 649 |
-
|
| 650 |
-
def setnframes(self, nframes):
|
| 651 |
-
if self._nframeswritten:
|
| 652 |
-
raise Error('cannot change parameters after starting to write')
|
| 653 |
-
self._nframes = nframes
|
| 654 |
-
|
| 655 |
-
def getnframes(self):
|
| 656 |
-
return self._nframeswritten
|
| 657 |
-
|
| 658 |
-
def setcomptype(self, comptype, compname):
|
| 659 |
-
if self._nframeswritten:
|
| 660 |
-
raise Error('cannot change parameters after starting to write')
|
| 661 |
-
if comptype not in (b'NONE', b'ulaw', b'ULAW',
|
| 662 |
-
b'alaw', b'ALAW', b'G722'):
|
| 663 |
-
raise Error('unsupported compression type')
|
| 664 |
-
self._comptype = comptype
|
| 665 |
-
self._compname = compname
|
| 666 |
-
|
| 667 |
-
def getcomptype(self):
|
| 668 |
-
return self._comptype
|
| 669 |
-
|
| 670 |
-
def getcompname(self):
|
| 671 |
-
return self._compname
|
| 672 |
-
|
| 673 |
-
## def setversion(self, version):
|
| 674 |
-
## if self._nframeswritten:
|
| 675 |
-
## raise Error, 'cannot change parameters after starting to write'
|
| 676 |
-
## self._version = version
|
| 677 |
-
|
| 678 |
-
def setparams(self, params):
|
| 679 |
-
nchannels, sampwidth, framerate, nframes, comptype, compname = params
|
| 680 |
-
if self._nframeswritten:
|
| 681 |
-
raise Error('cannot change parameters after starting to write')
|
| 682 |
-
if comptype not in (b'NONE', b'ulaw', b'ULAW',
|
| 683 |
-
b'alaw', b'ALAW', b'G722'):
|
| 684 |
-
raise Error('unsupported compression type')
|
| 685 |
-
self.setnchannels(nchannels)
|
| 686 |
-
self.setsampwidth(sampwidth)
|
| 687 |
-
self.setframerate(framerate)
|
| 688 |
-
self.setnframes(nframes)
|
| 689 |
-
self.setcomptype(comptype, compname)
|
| 690 |
-
|
| 691 |
-
def getparams(self):
|
| 692 |
-
if not self._nchannels or not self._sampwidth or not self._framerate:
|
| 693 |
-
raise Error('not all parameters set')
|
| 694 |
-
return _aifc_params(self._nchannels, self._sampwidth, self._framerate,
|
| 695 |
-
self._nframes, self._comptype, self._compname)
|
| 696 |
-
|
| 697 |
-
def setmark(self, id, pos, name):
|
| 698 |
-
if id <= 0:
|
| 699 |
-
raise Error('marker ID must be > 0')
|
| 700 |
-
if pos < 0:
|
| 701 |
-
raise Error('marker position must be >= 0')
|
| 702 |
-
if not isinstance(name, bytes):
|
| 703 |
-
raise Error('marker name must be bytes')
|
| 704 |
-
for i in range(len(self._markers)):
|
| 705 |
-
if id == self._markers[i][0]:
|
| 706 |
-
self._markers[i] = id, pos, name
|
| 707 |
-
return
|
| 708 |
-
self._markers.append((id, pos, name))
|
| 709 |
-
|
| 710 |
-
def getmark(self, id):
|
| 711 |
-
for marker in self._markers:
|
| 712 |
-
if id == marker[0]:
|
| 713 |
-
return marker
|
| 714 |
-
raise Error('marker {0!r} does not exist'.format(id))
|
| 715 |
-
|
| 716 |
-
def getmarkers(self):
|
| 717 |
-
if len(self._markers) == 0:
|
| 718 |
-
return None
|
| 719 |
-
return self._markers
|
| 720 |
-
|
| 721 |
-
def tell(self):
|
| 722 |
-
return self._nframeswritten
|
| 723 |
-
|
| 724 |
-
def writeframesraw(self, data):
|
| 725 |
-
if not isinstance(data, (bytes, bytearray)):
|
| 726 |
-
data = memoryview(data).cast('B')
|
| 727 |
-
self._ensure_header_written(len(data))
|
| 728 |
-
nframes = len(data) // (self._sampwidth * self._nchannels)
|
| 729 |
-
if self._convert:
|
| 730 |
-
data = self._convert(data)
|
| 731 |
-
self._file.write(data)
|
| 732 |
-
self._nframeswritten = self._nframeswritten + nframes
|
| 733 |
-
self._datawritten = self._datawritten + len(data)
|
| 734 |
-
|
| 735 |
-
def writeframes(self, data):
|
| 736 |
-
self.writeframesraw(data)
|
| 737 |
-
if self._nframeswritten != self._nframes or \
|
| 738 |
-
self._datalength != self._datawritten:
|
| 739 |
-
self._patchheader()
|
| 740 |
-
|
| 741 |
-
def close(self):
|
| 742 |
-
if self._file is None:
|
| 743 |
-
return
|
| 744 |
-
try:
|
| 745 |
-
self._ensure_header_written(0)
|
| 746 |
-
if self._datawritten & 1:
|
| 747 |
-
# quick pad to even size
|
| 748 |
-
self._file.write(b'\x00')
|
| 749 |
-
self._datawritten = self._datawritten + 1
|
| 750 |
-
self._writemarkers()
|
| 751 |
-
if self._nframeswritten != self._nframes or \
|
| 752 |
-
self._datalength != self._datawritten or \
|
| 753 |
-
self._marklength:
|
| 754 |
-
self._patchheader()
|
| 755 |
-
finally:
|
| 756 |
-
# Prevent ref cycles
|
| 757 |
-
self._convert = None
|
| 758 |
-
f = self._file
|
| 759 |
-
self._file = None
|
| 760 |
-
f.close()
|
| 761 |
-
|
| 762 |
-
#
|
| 763 |
-
# Internal methods.
|
| 764 |
-
#
|
| 765 |
-
|
| 766 |
-
def _lin2alaw(self, data):
|
| 767 |
-
import audioop
|
| 768 |
-
return audioop.lin2alaw(data, 2)
|
| 769 |
-
|
| 770 |
-
def _lin2ulaw(self, data):
|
| 771 |
-
import audioop
|
| 772 |
-
return audioop.lin2ulaw(data, 2)
|
| 773 |
-
|
| 774 |
-
def _lin2adpcm(self, data):
|
| 775 |
-
import audioop
|
| 776 |
-
if not hasattr(self, '_adpcmstate'):
|
| 777 |
-
self._adpcmstate = None
|
| 778 |
-
data, self._adpcmstate = audioop.lin2adpcm(data, 2, self._adpcmstate)
|
| 779 |
-
return data
|
| 780 |
-
|
| 781 |
-
def _ensure_header_written(self, datasize):
|
| 782 |
-
if not self._nframeswritten:
|
| 783 |
-
if self._comptype in (b'ULAW', b'ulaw', b'ALAW', b'alaw', b'G722'):
|
| 784 |
-
if not self._sampwidth:
|
| 785 |
-
self._sampwidth = 2
|
| 786 |
-
if self._sampwidth != 2:
|
| 787 |
-
raise Error('sample width must be 2 when compressing '
|
| 788 |
-
'with ulaw/ULAW, alaw/ALAW or G7.22 (ADPCM)')
|
| 789 |
-
if not self._nchannels:
|
| 790 |
-
raise Error('# channels not specified')
|
| 791 |
-
if not self._sampwidth:
|
| 792 |
-
raise Error('sample width not specified')
|
| 793 |
-
if not self._framerate:
|
| 794 |
-
raise Error('sampling rate not specified')
|
| 795 |
-
self._write_header(datasize)
|
| 796 |
-
|
| 797 |
-
def _init_compression(self):
|
| 798 |
-
if self._comptype == b'G722':
|
| 799 |
-
self._convert = self._lin2adpcm
|
| 800 |
-
elif self._comptype in (b'ulaw', b'ULAW'):
|
| 801 |
-
self._convert = self._lin2ulaw
|
| 802 |
-
elif self._comptype in (b'alaw', b'ALAW'):
|
| 803 |
-
self._convert = self._lin2alaw
|
| 804 |
-
|
| 805 |
-
def _write_header(self, initlength):
|
| 806 |
-
if self._aifc and self._comptype != b'NONE':
|
| 807 |
-
self._init_compression()
|
| 808 |
-
self._file.write(b'FORM')
|
| 809 |
-
if not self._nframes:
|
| 810 |
-
self._nframes = initlength // (self._nchannels * self._sampwidth)
|
| 811 |
-
self._datalength = self._nframes * self._nchannels * self._sampwidth
|
| 812 |
-
if self._datalength & 1:
|
| 813 |
-
self._datalength = self._datalength + 1
|
| 814 |
-
if self._aifc:
|
| 815 |
-
if self._comptype in (b'ulaw', b'ULAW', b'alaw', b'ALAW'):
|
| 816 |
-
self._datalength = self._datalength // 2
|
| 817 |
-
if self._datalength & 1:
|
| 818 |
-
self._datalength = self._datalength + 1
|
| 819 |
-
elif self._comptype == b'G722':
|
| 820 |
-
self._datalength = (self._datalength + 3) // 4
|
| 821 |
-
if self._datalength & 1:
|
| 822 |
-
self._datalength = self._datalength + 1
|
| 823 |
-
try:
|
| 824 |
-
self._form_length_pos = self._file.tell()
|
| 825 |
-
except (AttributeError, OSError):
|
| 826 |
-
self._form_length_pos = None
|
| 827 |
-
commlength = self._write_form_length(self._datalength)
|
| 828 |
-
if self._aifc:
|
| 829 |
-
self._file.write(b'AIFC')
|
| 830 |
-
self._file.write(b'FVER')
|
| 831 |
-
_write_ulong(self._file, 4)
|
| 832 |
-
_write_ulong(self._file, self._version)
|
| 833 |
-
else:
|
| 834 |
-
self._file.write(b'AIFF')
|
| 835 |
-
self._file.write(b'COMM')
|
| 836 |
-
_write_ulong(self._file, commlength)
|
| 837 |
-
_write_short(self._file, self._nchannels)
|
| 838 |
-
if self._form_length_pos is not None:
|
| 839 |
-
self._nframes_pos = self._file.tell()
|
| 840 |
-
_write_ulong(self._file, self._nframes)
|
| 841 |
-
if self._comptype in (b'ULAW', b'ulaw', b'ALAW', b'alaw', b'G722'):
|
| 842 |
-
_write_short(self._file, 8)
|
| 843 |
-
else:
|
| 844 |
-
_write_short(self._file, self._sampwidth * 8)
|
| 845 |
-
_write_float(self._file, self._framerate)
|
| 846 |
-
if self._aifc:
|
| 847 |
-
self._file.write(self._comptype)
|
| 848 |
-
_write_string(self._file, self._compname)
|
| 849 |
-
self._file.write(b'SSND')
|
| 850 |
-
if self._form_length_pos is not None:
|
| 851 |
-
self._ssnd_length_pos = self._file.tell()
|
| 852 |
-
_write_ulong(self._file, self._datalength + 8)
|
| 853 |
-
_write_ulong(self._file, 0)
|
| 854 |
-
_write_ulong(self._file, 0)
|
| 855 |
-
|
| 856 |
-
def _write_form_length(self, datalength):
|
| 857 |
-
if self._aifc:
|
| 858 |
-
commlength = 18 + 5 + len(self._compname)
|
| 859 |
-
if commlength & 1:
|
| 860 |
-
commlength = commlength + 1
|
| 861 |
-
verslength = 12
|
| 862 |
-
else:
|
| 863 |
-
commlength = 18
|
| 864 |
-
verslength = 0
|
| 865 |
-
_write_ulong(self._file, 4 + verslength + self._marklength + \
|
| 866 |
-
8 + commlength + 16 + datalength)
|
| 867 |
-
return commlength
|
| 868 |
-
|
| 869 |
-
def _patchheader(self):
|
| 870 |
-
curpos = self._file.tell()
|
| 871 |
-
if self._datawritten & 1:
|
| 872 |
-
datalength = self._datawritten + 1
|
| 873 |
-
self._file.write(b'\x00')
|
| 874 |
-
else:
|
| 875 |
-
datalength = self._datawritten
|
| 876 |
-
if datalength == self._datalength and \
|
| 877 |
-
self._nframes == self._nframeswritten and \
|
| 878 |
-
self._marklength == 0:
|
| 879 |
-
self._file.seek(curpos, 0)
|
| 880 |
-
return
|
| 881 |
-
self._file.seek(self._form_length_pos, 0)
|
| 882 |
-
dummy = self._write_form_length(datalength)
|
| 883 |
-
self._file.seek(self._nframes_pos, 0)
|
| 884 |
-
_write_ulong(self._file, self._nframeswritten)
|
| 885 |
-
self._file.seek(self._ssnd_length_pos, 0)
|
| 886 |
-
_write_ulong(self._file, datalength + 8)
|
| 887 |
-
self._file.seek(curpos, 0)
|
| 888 |
-
self._nframes = self._nframeswritten
|
| 889 |
-
self._datalength = datalength
|
| 890 |
-
|
| 891 |
-
def _writemarkers(self):
|
| 892 |
-
if len(self._markers) == 0:
|
| 893 |
-
return
|
| 894 |
-
self._file.write(b'MARK')
|
| 895 |
-
length = 2
|
| 896 |
-
for marker in self._markers:
|
| 897 |
-
id, pos, name = marker
|
| 898 |
-
length = length + len(name) + 1 + 6
|
| 899 |
-
if len(name) & 1 == 0:
|
| 900 |
-
length = length + 1
|
| 901 |
-
_write_ulong(self._file, length)
|
| 902 |
-
self._marklength = length + 8
|
| 903 |
-
_write_short(self._file, len(self._markers))
|
| 904 |
-
for marker in self._markers:
|
| 905 |
-
id, pos, name = marker
|
| 906 |
-
_write_short(self._file, id)
|
| 907 |
-
_write_ulong(self._file, pos)
|
| 908 |
-
_write_string(self._file, name)
|
| 909 |
-
|
| 910 |
-
def open(f, mode=None):
|
| 911 |
-
if mode is None:
|
| 912 |
-
if hasattr(f, 'mode'):
|
| 913 |
-
mode = f.mode
|
| 914 |
-
else:
|
| 915 |
-
mode = 'rb'
|
| 916 |
-
if mode in ('r', 'rb'):
|
| 917 |
-
return Aifc_read(f)
|
| 918 |
-
elif mode in ('w', 'wb'):
|
| 919 |
-
return Aifc_write(f)
|
| 920 |
-
else:
|
| 921 |
-
raise Error("mode must be 'r', 'rb', 'w', or 'wb'")
|
| 922 |
-
|
| 923 |
-
|
| 924 |
-
if __name__ == '__main__':
|
| 925 |
-
import sys
|
| 926 |
-
if not sys.argv[1:]:
|
| 927 |
-
sys.argv.append('/usr/demos/data/audio/bach.aiff')
|
| 928 |
-
fn = sys.argv[1]
|
| 929 |
-
with open(fn, 'r') as f:
|
| 930 |
-
print("Reading", fn)
|
| 931 |
-
print("nchannels =", f.getnchannels())
|
| 932 |
-
print("nframes =", f.getnframes())
|
| 933 |
-
print("sampwidth =", f.getsampwidth())
|
| 934 |
-
print("framerate =", f.getframerate())
|
| 935 |
-
print("comptype =", f.getcomptype())
|
| 936 |
-
print("compname =", f.getcompname())
|
| 937 |
-
if sys.argv[2:]:
|
| 938 |
-
gn = sys.argv[2]
|
| 939 |
-
print("Writing", gn)
|
| 940 |
-
with open(gn, 'w') as g:
|
| 941 |
-
g.setparams(f.getparams())
|
| 942 |
-
while 1:
|
| 943 |
-
data = f.readframes(1024)
|
| 944 |
-
if not data:
|
| 945 |
-
break
|
| 946 |
-
g.writeframes(data)
|
| 947 |
-
print("Done.")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Pytorch/Lib/antigravity.py
DELETED
|
@@ -1,17 +0,0 @@
|
|
| 1 |
-
|
| 2 |
-
import webbrowser
|
| 3 |
-
import hashlib
|
| 4 |
-
|
| 5 |
-
webbrowser.open("https://xkcd.com/353/")
|
| 6 |
-
|
| 7 |
-
def geohash(latitude, longitude, datedow):
|
| 8 |
-
'''Compute geohash() using the Munroe algorithm.
|
| 9 |
-
|
| 10 |
-
>>> geohash(37.421542, -122.085589, b'2005-05-26-10458.68')
|
| 11 |
-
37.857713 -122.544543
|
| 12 |
-
|
| 13 |
-
'''
|
| 14 |
-
# https://xkcd.com/426/
|
| 15 |
-
h = hashlib.md5(datedow, usedforsecurity=False).hexdigest()
|
| 16 |
-
p, q = [('%f' % float.fromhex('0.' + x)) for x in (h[:16], h[16:32])]
|
| 17 |
-
print('%d%s %d%s' % (latitude, p[1:], longitude, q[1:]))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Pytorch/Lib/argparse.py
DELETED
|
The diff for this file is too large to render.
See raw diff
|
|
|
Pytorch/Lib/ast.py
DELETED
|
@@ -1,1709 +0,0 @@
|
|
| 1 |
-
"""
|
| 2 |
-
ast
|
| 3 |
-
~~~
|
| 4 |
-
|
| 5 |
-
The `ast` module helps Python applications to process trees of the Python
|
| 6 |
-
abstract syntax grammar. The abstract syntax itself might change with
|
| 7 |
-
each Python release; this module helps to find out programmatically what
|
| 8 |
-
the current grammar looks like and allows modifications of it.
|
| 9 |
-
|
| 10 |
-
An abstract syntax tree can be generated by passing `ast.PyCF_ONLY_AST` as
|
| 11 |
-
a flag to the `compile()` builtin function or by using the `parse()`
|
| 12 |
-
function from this module. The result will be a tree of objects whose
|
| 13 |
-
classes all inherit from `ast.AST`.
|
| 14 |
-
|
| 15 |
-
A modified abstract syntax tree can be compiled into a Python code object
|
| 16 |
-
using the built-in `compile()` function.
|
| 17 |
-
|
| 18 |
-
Additionally various helper functions are provided that make working with
|
| 19 |
-
the trees simpler. The main intention of the helper functions and this
|
| 20 |
-
module in general is to provide an easy to use interface for libraries
|
| 21 |
-
that work tightly with the python syntax (template engines for example).
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
:copyright: Copyright 2008 by Armin Ronacher.
|
| 25 |
-
:license: Python License.
|
| 26 |
-
"""
|
| 27 |
-
import sys
|
| 28 |
-
from _ast import *
|
| 29 |
-
from contextlib import contextmanager, nullcontext
|
| 30 |
-
from enum import IntEnum, auto
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
def parse(source, filename='<unknown>', mode='exec', *,
|
| 34 |
-
type_comments=False, feature_version=None):
|
| 35 |
-
"""
|
| 36 |
-
Parse the source into an AST node.
|
| 37 |
-
Equivalent to compile(source, filename, mode, PyCF_ONLY_AST).
|
| 38 |
-
Pass type_comments=True to get back type comments where the syntax allows.
|
| 39 |
-
"""
|
| 40 |
-
flags = PyCF_ONLY_AST
|
| 41 |
-
if type_comments:
|
| 42 |
-
flags |= PyCF_TYPE_COMMENTS
|
| 43 |
-
if isinstance(feature_version, tuple):
|
| 44 |
-
major, minor = feature_version # Should be a 2-tuple.
|
| 45 |
-
assert major == 3
|
| 46 |
-
feature_version = minor
|
| 47 |
-
elif feature_version is None:
|
| 48 |
-
feature_version = -1
|
| 49 |
-
# Else it should be an int giving the minor version for 3.x.
|
| 50 |
-
return compile(source, filename, mode, flags,
|
| 51 |
-
_feature_version=feature_version)
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
def literal_eval(node_or_string):
|
| 55 |
-
"""
|
| 56 |
-
Evaluate an expression node or a string containing only a Python
|
| 57 |
-
expression. The string or node provided may only consist of the following
|
| 58 |
-
Python literal structures: strings, bytes, numbers, tuples, lists, dicts,
|
| 59 |
-
sets, booleans, and None.
|
| 60 |
-
|
| 61 |
-
Caution: A complex expression can overflow the C stack and cause a crash.
|
| 62 |
-
"""
|
| 63 |
-
if isinstance(node_or_string, str):
|
| 64 |
-
node_or_string = parse(node_or_string.lstrip(" \t"), mode='eval')
|
| 65 |
-
if isinstance(node_or_string, Expression):
|
| 66 |
-
node_or_string = node_or_string.body
|
| 67 |
-
def _raise_malformed_node(node):
|
| 68 |
-
msg = "malformed node or string"
|
| 69 |
-
if lno := getattr(node, 'lineno', None):
|
| 70 |
-
msg += f' on line {lno}'
|
| 71 |
-
raise ValueError(msg + f': {node!r}')
|
| 72 |
-
def _convert_num(node):
|
| 73 |
-
if not isinstance(node, Constant) or type(node.value) not in (int, float, complex):
|
| 74 |
-
_raise_malformed_node(node)
|
| 75 |
-
return node.value
|
| 76 |
-
def _convert_signed_num(node):
|
| 77 |
-
if isinstance(node, UnaryOp) and isinstance(node.op, (UAdd, USub)):
|
| 78 |
-
operand = _convert_num(node.operand)
|
| 79 |
-
if isinstance(node.op, UAdd):
|
| 80 |
-
return + operand
|
| 81 |
-
else:
|
| 82 |
-
return - operand
|
| 83 |
-
return _convert_num(node)
|
| 84 |
-
def _convert(node):
|
| 85 |
-
if isinstance(node, Constant):
|
| 86 |
-
return node.value
|
| 87 |
-
elif isinstance(node, Tuple):
|
| 88 |
-
return tuple(map(_convert, node.elts))
|
| 89 |
-
elif isinstance(node, List):
|
| 90 |
-
return list(map(_convert, node.elts))
|
| 91 |
-
elif isinstance(node, Set):
|
| 92 |
-
return set(map(_convert, node.elts))
|
| 93 |
-
elif (isinstance(node, Call) and isinstance(node.func, Name) and
|
| 94 |
-
node.func.id == 'set' and node.args == node.keywords == []):
|
| 95 |
-
return set()
|
| 96 |
-
elif isinstance(node, Dict):
|
| 97 |
-
if len(node.keys) != len(node.values):
|
| 98 |
-
_raise_malformed_node(node)
|
| 99 |
-
return dict(zip(map(_convert, node.keys),
|
| 100 |
-
map(_convert, node.values)))
|
| 101 |
-
elif isinstance(node, BinOp) and isinstance(node.op, (Add, Sub)):
|
| 102 |
-
left = _convert_signed_num(node.left)
|
| 103 |
-
right = _convert_num(node.right)
|
| 104 |
-
if isinstance(left, (int, float)) and isinstance(right, complex):
|
| 105 |
-
if isinstance(node.op, Add):
|
| 106 |
-
return left + right
|
| 107 |
-
else:
|
| 108 |
-
return left - right
|
| 109 |
-
return _convert_signed_num(node)
|
| 110 |
-
return _convert(node_or_string)
|
| 111 |
-
|
| 112 |
-
|
| 113 |
-
def dump(node, annotate_fields=True, include_attributes=False, *, indent=None):
|
| 114 |
-
"""
|
| 115 |
-
Return a formatted dump of the tree in node. This is mainly useful for
|
| 116 |
-
debugging purposes. If annotate_fields is true (by default),
|
| 117 |
-
the returned string will show the names and the values for fields.
|
| 118 |
-
If annotate_fields is false, the result string will be more compact by
|
| 119 |
-
omitting unambiguous field names. Attributes such as line
|
| 120 |
-
numbers and column offsets are not dumped by default. If this is wanted,
|
| 121 |
-
include_attributes can be set to true. If indent is a non-negative
|
| 122 |
-
integer or string, then the tree will be pretty-printed with that indent
|
| 123 |
-
level. None (the default) selects the single line representation.
|
| 124 |
-
"""
|
| 125 |
-
def _format(node, level=0):
|
| 126 |
-
if indent is not None:
|
| 127 |
-
level += 1
|
| 128 |
-
prefix = '\n' + indent * level
|
| 129 |
-
sep = ',\n' + indent * level
|
| 130 |
-
else:
|
| 131 |
-
prefix = ''
|
| 132 |
-
sep = ', '
|
| 133 |
-
if isinstance(node, AST):
|
| 134 |
-
cls = type(node)
|
| 135 |
-
args = []
|
| 136 |
-
allsimple = True
|
| 137 |
-
keywords = annotate_fields
|
| 138 |
-
for name in node._fields:
|
| 139 |
-
try:
|
| 140 |
-
value = getattr(node, name)
|
| 141 |
-
except AttributeError:
|
| 142 |
-
keywords = True
|
| 143 |
-
continue
|
| 144 |
-
if value is None and getattr(cls, name, ...) is None:
|
| 145 |
-
keywords = True
|
| 146 |
-
continue
|
| 147 |
-
value, simple = _format(value, level)
|
| 148 |
-
allsimple = allsimple and simple
|
| 149 |
-
if keywords:
|
| 150 |
-
args.append('%s=%s' % (name, value))
|
| 151 |
-
else:
|
| 152 |
-
args.append(value)
|
| 153 |
-
if include_attributes and node._attributes:
|
| 154 |
-
for name in node._attributes:
|
| 155 |
-
try:
|
| 156 |
-
value = getattr(node, name)
|
| 157 |
-
except AttributeError:
|
| 158 |
-
continue
|
| 159 |
-
if value is None and getattr(cls, name, ...) is None:
|
| 160 |
-
continue
|
| 161 |
-
value, simple = _format(value, level)
|
| 162 |
-
allsimple = allsimple and simple
|
| 163 |
-
args.append('%s=%s' % (name, value))
|
| 164 |
-
if allsimple and len(args) <= 3:
|
| 165 |
-
return '%s(%s)' % (node.__class__.__name__, ', '.join(args)), not args
|
| 166 |
-
return '%s(%s%s)' % (node.__class__.__name__, prefix, sep.join(args)), False
|
| 167 |
-
elif isinstance(node, list):
|
| 168 |
-
if not node:
|
| 169 |
-
return '[]', True
|
| 170 |
-
return '[%s%s]' % (prefix, sep.join(_format(x, level)[0] for x in node)), False
|
| 171 |
-
return repr(node), True
|
| 172 |
-
|
| 173 |
-
if not isinstance(node, AST):
|
| 174 |
-
raise TypeError('expected AST, got %r' % node.__class__.__name__)
|
| 175 |
-
if indent is not None and not isinstance(indent, str):
|
| 176 |
-
indent = ' ' * indent
|
| 177 |
-
return _format(node)[0]
|
| 178 |
-
|
| 179 |
-
|
| 180 |
-
def copy_location(new_node, old_node):
|
| 181 |
-
"""
|
| 182 |
-
Copy source location (`lineno`, `col_offset`, `end_lineno`, and `end_col_offset`
|
| 183 |
-
attributes) from *old_node* to *new_node* if possible, and return *new_node*.
|
| 184 |
-
"""
|
| 185 |
-
for attr in 'lineno', 'col_offset', 'end_lineno', 'end_col_offset':
|
| 186 |
-
if attr in old_node._attributes and attr in new_node._attributes:
|
| 187 |
-
value = getattr(old_node, attr, None)
|
| 188 |
-
# end_lineno and end_col_offset are optional attributes, and they
|
| 189 |
-
# should be copied whether the value is None or not.
|
| 190 |
-
if value is not None or (
|
| 191 |
-
hasattr(old_node, attr) and attr.startswith("end_")
|
| 192 |
-
):
|
| 193 |
-
setattr(new_node, attr, value)
|
| 194 |
-
return new_node
|
| 195 |
-
|
| 196 |
-
|
| 197 |
-
def fix_missing_locations(node):
|
| 198 |
-
"""
|
| 199 |
-
When you compile a node tree with compile(), the compiler expects lineno and
|
| 200 |
-
col_offset attributes for every node that supports them. This is rather
|
| 201 |
-
tedious to fill in for generated nodes, so this helper adds these attributes
|
| 202 |
-
recursively where not already set, by setting them to the values of the
|
| 203 |
-
parent node. It works recursively starting at *node*.
|
| 204 |
-
"""
|
| 205 |
-
def _fix(node, lineno, col_offset, end_lineno, end_col_offset):
|
| 206 |
-
if 'lineno' in node._attributes:
|
| 207 |
-
if not hasattr(node, 'lineno'):
|
| 208 |
-
node.lineno = lineno
|
| 209 |
-
else:
|
| 210 |
-
lineno = node.lineno
|
| 211 |
-
if 'end_lineno' in node._attributes:
|
| 212 |
-
if getattr(node, 'end_lineno', None) is None:
|
| 213 |
-
node.end_lineno = end_lineno
|
| 214 |
-
else:
|
| 215 |
-
end_lineno = node.end_lineno
|
| 216 |
-
if 'col_offset' in node._attributes:
|
| 217 |
-
if not hasattr(node, 'col_offset'):
|
| 218 |
-
node.col_offset = col_offset
|
| 219 |
-
else:
|
| 220 |
-
col_offset = node.col_offset
|
| 221 |
-
if 'end_col_offset' in node._attributes:
|
| 222 |
-
if getattr(node, 'end_col_offset', None) is None:
|
| 223 |
-
node.end_col_offset = end_col_offset
|
| 224 |
-
else:
|
| 225 |
-
end_col_offset = node.end_col_offset
|
| 226 |
-
for child in iter_child_nodes(node):
|
| 227 |
-
_fix(child, lineno, col_offset, end_lineno, end_col_offset)
|
| 228 |
-
_fix(node, 1, 0, 1, 0)
|
| 229 |
-
return node
|
| 230 |
-
|
| 231 |
-
|
| 232 |
-
def increment_lineno(node, n=1):
|
| 233 |
-
"""
|
| 234 |
-
Increment the line number and end line number of each node in the tree
|
| 235 |
-
starting at *node* by *n*. This is useful to "move code" to a different
|
| 236 |
-
location in a file.
|
| 237 |
-
"""
|
| 238 |
-
for child in walk(node):
|
| 239 |
-
# TypeIgnore is a special case where lineno is not an attribute
|
| 240 |
-
# but rather a field of the node itself.
|
| 241 |
-
if isinstance(child, TypeIgnore):
|
| 242 |
-
child.lineno = getattr(child, 'lineno', 0) + n
|
| 243 |
-
continue
|
| 244 |
-
|
| 245 |
-
if 'lineno' in child._attributes:
|
| 246 |
-
child.lineno = getattr(child, 'lineno', 0) + n
|
| 247 |
-
if (
|
| 248 |
-
"end_lineno" in child._attributes
|
| 249 |
-
and (end_lineno := getattr(child, "end_lineno", 0)) is not None
|
| 250 |
-
):
|
| 251 |
-
child.end_lineno = end_lineno + n
|
| 252 |
-
return node
|
| 253 |
-
|
| 254 |
-
|
| 255 |
-
def iter_fields(node):
|
| 256 |
-
"""
|
| 257 |
-
Yield a tuple of ``(fieldname, value)`` for each field in ``node._fields``
|
| 258 |
-
that is present on *node*.
|
| 259 |
-
"""
|
| 260 |
-
for field in node._fields:
|
| 261 |
-
try:
|
| 262 |
-
yield field, getattr(node, field)
|
| 263 |
-
except AttributeError:
|
| 264 |
-
pass
|
| 265 |
-
|
| 266 |
-
|
| 267 |
-
def iter_child_nodes(node):
|
| 268 |
-
"""
|
| 269 |
-
Yield all direct child nodes of *node*, that is, all fields that are nodes
|
| 270 |
-
and all items of fields that are lists of nodes.
|
| 271 |
-
"""
|
| 272 |
-
for name, field in iter_fields(node):
|
| 273 |
-
if isinstance(field, AST):
|
| 274 |
-
yield field
|
| 275 |
-
elif isinstance(field, list):
|
| 276 |
-
for item in field:
|
| 277 |
-
if isinstance(item, AST):
|
| 278 |
-
yield item
|
| 279 |
-
|
| 280 |
-
|
| 281 |
-
def get_docstring(node, clean=True):
|
| 282 |
-
"""
|
| 283 |
-
Return the docstring for the given node or None if no docstring can
|
| 284 |
-
be found. If the node provided does not have docstrings a TypeError
|
| 285 |
-
will be raised.
|
| 286 |
-
|
| 287 |
-
If *clean* is `True`, all tabs are expanded to spaces and any whitespace
|
| 288 |
-
that can be uniformly removed from the second line onwards is removed.
|
| 289 |
-
"""
|
| 290 |
-
if not isinstance(node, (AsyncFunctionDef, FunctionDef, ClassDef, Module)):
|
| 291 |
-
raise TypeError("%r can't have docstrings" % node.__class__.__name__)
|
| 292 |
-
if not(node.body and isinstance(node.body[0], Expr)):
|
| 293 |
-
return None
|
| 294 |
-
node = node.body[0].value
|
| 295 |
-
if isinstance(node, Str):
|
| 296 |
-
text = node.s
|
| 297 |
-
elif isinstance(node, Constant) and isinstance(node.value, str):
|
| 298 |
-
text = node.value
|
| 299 |
-
else:
|
| 300 |
-
return None
|
| 301 |
-
if clean:
|
| 302 |
-
import inspect
|
| 303 |
-
text = inspect.cleandoc(text)
|
| 304 |
-
return text
|
| 305 |
-
|
| 306 |
-
|
| 307 |
-
def _splitlines_no_ff(source):
|
| 308 |
-
"""Split a string into lines ignoring form feed and other chars.
|
| 309 |
-
|
| 310 |
-
This mimics how the Python parser splits source code.
|
| 311 |
-
"""
|
| 312 |
-
idx = 0
|
| 313 |
-
lines = []
|
| 314 |
-
next_line = ''
|
| 315 |
-
while idx < len(source):
|
| 316 |
-
c = source[idx]
|
| 317 |
-
next_line += c
|
| 318 |
-
idx += 1
|
| 319 |
-
# Keep \r\n together
|
| 320 |
-
if c == '\r' and idx < len(source) and source[idx] == '\n':
|
| 321 |
-
next_line += '\n'
|
| 322 |
-
idx += 1
|
| 323 |
-
if c in '\r\n':
|
| 324 |
-
lines.append(next_line)
|
| 325 |
-
next_line = ''
|
| 326 |
-
|
| 327 |
-
if next_line:
|
| 328 |
-
lines.append(next_line)
|
| 329 |
-
return lines
|
| 330 |
-
|
| 331 |
-
|
| 332 |
-
def _pad_whitespace(source):
|
| 333 |
-
r"""Replace all chars except '\f\t' in a line with spaces."""
|
| 334 |
-
result = ''
|
| 335 |
-
for c in source:
|
| 336 |
-
if c in '\f\t':
|
| 337 |
-
result += c
|
| 338 |
-
else:
|
| 339 |
-
result += ' '
|
| 340 |
-
return result
|
| 341 |
-
|
| 342 |
-
|
| 343 |
-
def get_source_segment(source, node, *, padded=False):
|
| 344 |
-
"""Get source code segment of the *source* that generated *node*.
|
| 345 |
-
|
| 346 |
-
If some location information (`lineno`, `end_lineno`, `col_offset`,
|
| 347 |
-
or `end_col_offset`) is missing, return None.
|
| 348 |
-
|
| 349 |
-
If *padded* is `True`, the first line of a multi-line statement will
|
| 350 |
-
be padded with spaces to match its original position.
|
| 351 |
-
"""
|
| 352 |
-
try:
|
| 353 |
-
if node.end_lineno is None or node.end_col_offset is None:
|
| 354 |
-
return None
|
| 355 |
-
lineno = node.lineno - 1
|
| 356 |
-
end_lineno = node.end_lineno - 1
|
| 357 |
-
col_offset = node.col_offset
|
| 358 |
-
end_col_offset = node.end_col_offset
|
| 359 |
-
except AttributeError:
|
| 360 |
-
return None
|
| 361 |
-
|
| 362 |
-
lines = _splitlines_no_ff(source)
|
| 363 |
-
if end_lineno == lineno:
|
| 364 |
-
return lines[lineno].encode()[col_offset:end_col_offset].decode()
|
| 365 |
-
|
| 366 |
-
if padded:
|
| 367 |
-
padding = _pad_whitespace(lines[lineno].encode()[:col_offset].decode())
|
| 368 |
-
else:
|
| 369 |
-
padding = ''
|
| 370 |
-
|
| 371 |
-
first = padding + lines[lineno].encode()[col_offset:].decode()
|
| 372 |
-
last = lines[end_lineno].encode()[:end_col_offset].decode()
|
| 373 |
-
lines = lines[lineno+1:end_lineno]
|
| 374 |
-
|
| 375 |
-
lines.insert(0, first)
|
| 376 |
-
lines.append(last)
|
| 377 |
-
return ''.join(lines)
|
| 378 |
-
|
| 379 |
-
|
| 380 |
-
def walk(node):
|
| 381 |
-
"""
|
| 382 |
-
Recursively yield all descendant nodes in the tree starting at *node*
|
| 383 |
-
(including *node* itself), in no specified order. This is useful if you
|
| 384 |
-
only want to modify nodes in place and don't care about the context.
|
| 385 |
-
"""
|
| 386 |
-
from collections import deque
|
| 387 |
-
todo = deque([node])
|
| 388 |
-
while todo:
|
| 389 |
-
node = todo.popleft()
|
| 390 |
-
todo.extend(iter_child_nodes(node))
|
| 391 |
-
yield node
|
| 392 |
-
|
| 393 |
-
|
| 394 |
-
class NodeVisitor(object):
|
| 395 |
-
"""
|
| 396 |
-
A node visitor base class that walks the abstract syntax tree and calls a
|
| 397 |
-
visitor function for every node found. This function may return a value
|
| 398 |
-
which is forwarded by the `visit` method.
|
| 399 |
-
|
| 400 |
-
This class is meant to be subclassed, with the subclass adding visitor
|
| 401 |
-
methods.
|
| 402 |
-
|
| 403 |
-
Per default the visitor functions for the nodes are ``'visit_'`` +
|
| 404 |
-
class name of the node. So a `TryFinally` node visit function would
|
| 405 |
-
be `visit_TryFinally`. This behavior can be changed by overriding
|
| 406 |
-
the `visit` method. If no visitor function exists for a node
|
| 407 |
-
(return value `None`) the `generic_visit` visitor is used instead.
|
| 408 |
-
|
| 409 |
-
Don't use the `NodeVisitor` if you want to apply changes to nodes during
|
| 410 |
-
traversing. For this a special visitor exists (`NodeTransformer`) that
|
| 411 |
-
allows modifications.
|
| 412 |
-
"""
|
| 413 |
-
|
| 414 |
-
def visit(self, node):
|
| 415 |
-
"""Visit a node."""
|
| 416 |
-
method = 'visit_' + node.__class__.__name__
|
| 417 |
-
visitor = getattr(self, method, self.generic_visit)
|
| 418 |
-
return visitor(node)
|
| 419 |
-
|
| 420 |
-
def generic_visit(self, node):
|
| 421 |
-
"""Called if no explicit visitor function exists for a node."""
|
| 422 |
-
for field, value in iter_fields(node):
|
| 423 |
-
if isinstance(value, list):
|
| 424 |
-
for item in value:
|
| 425 |
-
if isinstance(item, AST):
|
| 426 |
-
self.visit(item)
|
| 427 |
-
elif isinstance(value, AST):
|
| 428 |
-
self.visit(value)
|
| 429 |
-
|
| 430 |
-
def visit_Constant(self, node):
|
| 431 |
-
value = node.value
|
| 432 |
-
type_name = _const_node_type_names.get(type(value))
|
| 433 |
-
if type_name is None:
|
| 434 |
-
for cls, name in _const_node_type_names.items():
|
| 435 |
-
if isinstance(value, cls):
|
| 436 |
-
type_name = name
|
| 437 |
-
break
|
| 438 |
-
if type_name is not None:
|
| 439 |
-
method = 'visit_' + type_name
|
| 440 |
-
try:
|
| 441 |
-
visitor = getattr(self, method)
|
| 442 |
-
except AttributeError:
|
| 443 |
-
pass
|
| 444 |
-
else:
|
| 445 |
-
import warnings
|
| 446 |
-
warnings.warn(f"{method} is deprecated; add visit_Constant",
|
| 447 |
-
DeprecationWarning, 2)
|
| 448 |
-
return visitor(node)
|
| 449 |
-
return self.generic_visit(node)
|
| 450 |
-
|
| 451 |
-
|
| 452 |
-
class NodeTransformer(NodeVisitor):
|
| 453 |
-
"""
|
| 454 |
-
A :class:`NodeVisitor` subclass that walks the abstract syntax tree and
|
| 455 |
-
allows modification of nodes.
|
| 456 |
-
|
| 457 |
-
The `NodeTransformer` will walk the AST and use the return value of the
|
| 458 |
-
visitor methods to replace or remove the old node. If the return value of
|
| 459 |
-
the visitor method is ``None``, the node will be removed from its location,
|
| 460 |
-
otherwise it is replaced with the return value. The return value may be the
|
| 461 |
-
original node in which case no replacement takes place.
|
| 462 |
-
|
| 463 |
-
Here is an example transformer that rewrites all occurrences of name lookups
|
| 464 |
-
(``foo``) to ``data['foo']``::
|
| 465 |
-
|
| 466 |
-
class RewriteName(NodeTransformer):
|
| 467 |
-
|
| 468 |
-
def visit_Name(self, node):
|
| 469 |
-
return Subscript(
|
| 470 |
-
value=Name(id='data', ctx=Load()),
|
| 471 |
-
slice=Constant(value=node.id),
|
| 472 |
-
ctx=node.ctx
|
| 473 |
-
)
|
| 474 |
-
|
| 475 |
-
Keep in mind that if the node you're operating on has child nodes you must
|
| 476 |
-
either transform the child nodes yourself or call the :meth:`generic_visit`
|
| 477 |
-
method for the node first.
|
| 478 |
-
|
| 479 |
-
For nodes that were part of a collection of statements (that applies to all
|
| 480 |
-
statement nodes), the visitor may also return a list of nodes rather than
|
| 481 |
-
just a single node.
|
| 482 |
-
|
| 483 |
-
Usually you use the transformer like this::
|
| 484 |
-
|
| 485 |
-
node = YourTransformer().visit(node)
|
| 486 |
-
"""
|
| 487 |
-
|
| 488 |
-
def generic_visit(self, node):
|
| 489 |
-
for field, old_value in iter_fields(node):
|
| 490 |
-
if isinstance(old_value, list):
|
| 491 |
-
new_values = []
|
| 492 |
-
for value in old_value:
|
| 493 |
-
if isinstance(value, AST):
|
| 494 |
-
value = self.visit(value)
|
| 495 |
-
if value is None:
|
| 496 |
-
continue
|
| 497 |
-
elif not isinstance(value, AST):
|
| 498 |
-
new_values.extend(value)
|
| 499 |
-
continue
|
| 500 |
-
new_values.append(value)
|
| 501 |
-
old_value[:] = new_values
|
| 502 |
-
elif isinstance(old_value, AST):
|
| 503 |
-
new_node = self.visit(old_value)
|
| 504 |
-
if new_node is None:
|
| 505 |
-
delattr(node, field)
|
| 506 |
-
else:
|
| 507 |
-
setattr(node, field, new_node)
|
| 508 |
-
return node
|
| 509 |
-
|
| 510 |
-
|
| 511 |
-
# If the ast module is loaded more than once, only add deprecated methods once
|
| 512 |
-
if not hasattr(Constant, 'n'):
|
| 513 |
-
# The following code is for backward compatibility.
|
| 514 |
-
# It will be removed in future.
|
| 515 |
-
|
| 516 |
-
def _getter(self):
|
| 517 |
-
"""Deprecated. Use value instead."""
|
| 518 |
-
return self.value
|
| 519 |
-
|
| 520 |
-
def _setter(self, value):
|
| 521 |
-
self.value = value
|
| 522 |
-
|
| 523 |
-
Constant.n = property(_getter, _setter)
|
| 524 |
-
Constant.s = property(_getter, _setter)
|
| 525 |
-
|
| 526 |
-
class _ABC(type):
|
| 527 |
-
|
| 528 |
-
def __init__(cls, *args):
|
| 529 |
-
cls.__doc__ = """Deprecated AST node class. Use ast.Constant instead"""
|
| 530 |
-
|
| 531 |
-
def __instancecheck__(cls, inst):
|
| 532 |
-
if not isinstance(inst, Constant):
|
| 533 |
-
return False
|
| 534 |
-
if cls in _const_types:
|
| 535 |
-
try:
|
| 536 |
-
value = inst.value
|
| 537 |
-
except AttributeError:
|
| 538 |
-
return False
|
| 539 |
-
else:
|
| 540 |
-
return (
|
| 541 |
-
isinstance(value, _const_types[cls]) and
|
| 542 |
-
not isinstance(value, _const_types_not.get(cls, ()))
|
| 543 |
-
)
|
| 544 |
-
return type.__instancecheck__(cls, inst)
|
| 545 |
-
|
| 546 |
-
def _new(cls, *args, **kwargs):
|
| 547 |
-
for key in kwargs:
|
| 548 |
-
if key not in cls._fields:
|
| 549 |
-
# arbitrary keyword arguments are accepted
|
| 550 |
-
continue
|
| 551 |
-
pos = cls._fields.index(key)
|
| 552 |
-
if pos < len(args):
|
| 553 |
-
raise TypeError(f"{cls.__name__} got multiple values for argument {key!r}")
|
| 554 |
-
if cls in _const_types:
|
| 555 |
-
return Constant(*args, **kwargs)
|
| 556 |
-
return Constant.__new__(cls, *args, **kwargs)
|
| 557 |
-
|
| 558 |
-
class Num(Constant, metaclass=_ABC):
|
| 559 |
-
_fields = ('n',)
|
| 560 |
-
__new__ = _new
|
| 561 |
-
|
| 562 |
-
class Str(Constant, metaclass=_ABC):
|
| 563 |
-
_fields = ('s',)
|
| 564 |
-
__new__ = _new
|
| 565 |
-
|
| 566 |
-
class Bytes(Constant, metaclass=_ABC):
|
| 567 |
-
_fields = ('s',)
|
| 568 |
-
__new__ = _new
|
| 569 |
-
|
| 570 |
-
class NameConstant(Constant, metaclass=_ABC):
|
| 571 |
-
__new__ = _new
|
| 572 |
-
|
| 573 |
-
class Ellipsis(Constant, metaclass=_ABC):
|
| 574 |
-
_fields = ()
|
| 575 |
-
|
| 576 |
-
def __new__(cls, *args, **kwargs):
|
| 577 |
-
if cls is Ellipsis:
|
| 578 |
-
return Constant(..., *args, **kwargs)
|
| 579 |
-
return Constant.__new__(cls, *args, **kwargs)
|
| 580 |
-
|
| 581 |
-
_const_types = {
|
| 582 |
-
Num: (int, float, complex),
|
| 583 |
-
Str: (str,),
|
| 584 |
-
Bytes: (bytes,),
|
| 585 |
-
NameConstant: (type(None), bool),
|
| 586 |
-
Ellipsis: (type(...),),
|
| 587 |
-
}
|
| 588 |
-
_const_types_not = {
|
| 589 |
-
Num: (bool,),
|
| 590 |
-
}
|
| 591 |
-
|
| 592 |
-
_const_node_type_names = {
|
| 593 |
-
bool: 'NameConstant', # should be before int
|
| 594 |
-
type(None): 'NameConstant',
|
| 595 |
-
int: 'Num',
|
| 596 |
-
float: 'Num',
|
| 597 |
-
complex: 'Num',
|
| 598 |
-
str: 'Str',
|
| 599 |
-
bytes: 'Bytes',
|
| 600 |
-
type(...): 'Ellipsis',
|
| 601 |
-
}
|
| 602 |
-
|
| 603 |
-
class slice(AST):
|
| 604 |
-
"""Deprecated AST node class."""
|
| 605 |
-
|
| 606 |
-
class Index(slice):
|
| 607 |
-
"""Deprecated AST node class. Use the index value directly instead."""
|
| 608 |
-
def __new__(cls, value, **kwargs):
|
| 609 |
-
return value
|
| 610 |
-
|
| 611 |
-
class ExtSlice(slice):
|
| 612 |
-
"""Deprecated AST node class. Use ast.Tuple instead."""
|
| 613 |
-
def __new__(cls, dims=(), **kwargs):
|
| 614 |
-
return Tuple(list(dims), Load(), **kwargs)
|
| 615 |
-
|
| 616 |
-
# If the ast module is loaded more than once, only add deprecated methods once
|
| 617 |
-
if not hasattr(Tuple, 'dims'):
|
| 618 |
-
# The following code is for backward compatibility.
|
| 619 |
-
# It will be removed in future.
|
| 620 |
-
|
| 621 |
-
def _dims_getter(self):
|
| 622 |
-
"""Deprecated. Use elts instead."""
|
| 623 |
-
return self.elts
|
| 624 |
-
|
| 625 |
-
def _dims_setter(self, value):
|
| 626 |
-
self.elts = value
|
| 627 |
-
|
| 628 |
-
Tuple.dims = property(_dims_getter, _dims_setter)
|
| 629 |
-
|
| 630 |
-
class Suite(mod):
|
| 631 |
-
"""Deprecated AST node class. Unused in Python 3."""
|
| 632 |
-
|
| 633 |
-
class AugLoad(expr_context):
|
| 634 |
-
"""Deprecated AST node class. Unused in Python 3."""
|
| 635 |
-
|
| 636 |
-
class AugStore(expr_context):
|
| 637 |
-
"""Deprecated AST node class. Unused in Python 3."""
|
| 638 |
-
|
| 639 |
-
class Param(expr_context):
|
| 640 |
-
"""Deprecated AST node class. Unused in Python 3."""
|
| 641 |
-
|
| 642 |
-
|
| 643 |
-
# Large float and imaginary literals get turned into infinities in the AST.
|
| 644 |
-
# We unparse those infinities to INFSTR.
|
| 645 |
-
_INFSTR = "1e" + repr(sys.float_info.max_10_exp + 1)
|
| 646 |
-
|
| 647 |
-
class _Precedence(IntEnum):
|
| 648 |
-
"""Precedence table that originated from python grammar."""
|
| 649 |
-
|
| 650 |
-
TUPLE = auto()
|
| 651 |
-
YIELD = auto() # 'yield', 'yield from'
|
| 652 |
-
TEST = auto() # 'if'-'else', 'lambda'
|
| 653 |
-
OR = auto() # 'or'
|
| 654 |
-
AND = auto() # 'and'
|
| 655 |
-
NOT = auto() # 'not'
|
| 656 |
-
CMP = auto() # '<', '>', '==', '>=', '<=', '!=',
|
| 657 |
-
# 'in', 'not in', 'is', 'is not'
|
| 658 |
-
EXPR = auto()
|
| 659 |
-
BOR = EXPR # '|'
|
| 660 |
-
BXOR = auto() # '^'
|
| 661 |
-
BAND = auto() # '&'
|
| 662 |
-
SHIFT = auto() # '<<', '>>'
|
| 663 |
-
ARITH = auto() # '+', '-'
|
| 664 |
-
TERM = auto() # '*', '@', '/', '%', '//'
|
| 665 |
-
FACTOR = auto() # unary '+', '-', '~'
|
| 666 |
-
POWER = auto() # '**'
|
| 667 |
-
AWAIT = auto() # 'await'
|
| 668 |
-
ATOM = auto()
|
| 669 |
-
|
| 670 |
-
def next(self):
|
| 671 |
-
try:
|
| 672 |
-
return self.__class__(self + 1)
|
| 673 |
-
except ValueError:
|
| 674 |
-
return self
|
| 675 |
-
|
| 676 |
-
|
| 677 |
-
_SINGLE_QUOTES = ("'", '"')
|
| 678 |
-
_MULTI_QUOTES = ('"""', "'''")
|
| 679 |
-
_ALL_QUOTES = (*_SINGLE_QUOTES, *_MULTI_QUOTES)
|
| 680 |
-
|
| 681 |
-
class _Unparser(NodeVisitor):
|
| 682 |
-
"""Methods in this class recursively traverse an AST and
|
| 683 |
-
output source code for the abstract syntax; original formatting
|
| 684 |
-
is disregarded."""
|
| 685 |
-
|
| 686 |
-
def __init__(self, *, _avoid_backslashes=False):
|
| 687 |
-
self._source = []
|
| 688 |
-
self._buffer = []
|
| 689 |
-
self._precedences = {}
|
| 690 |
-
self._type_ignores = {}
|
| 691 |
-
self._indent = 0
|
| 692 |
-
self._avoid_backslashes = _avoid_backslashes
|
| 693 |
-
|
| 694 |
-
def interleave(self, inter, f, seq):
|
| 695 |
-
"""Call f on each item in seq, calling inter() in between."""
|
| 696 |
-
seq = iter(seq)
|
| 697 |
-
try:
|
| 698 |
-
f(next(seq))
|
| 699 |
-
except StopIteration:
|
| 700 |
-
pass
|
| 701 |
-
else:
|
| 702 |
-
for x in seq:
|
| 703 |
-
inter()
|
| 704 |
-
f(x)
|
| 705 |
-
|
| 706 |
-
def items_view(self, traverser, items):
|
| 707 |
-
"""Traverse and separate the given *items* with a comma and append it to
|
| 708 |
-
the buffer. If *items* is a single item sequence, a trailing comma
|
| 709 |
-
will be added."""
|
| 710 |
-
if len(items) == 1:
|
| 711 |
-
traverser(items[0])
|
| 712 |
-
self.write(",")
|
| 713 |
-
else:
|
| 714 |
-
self.interleave(lambda: self.write(", "), traverser, items)
|
| 715 |
-
|
| 716 |
-
def maybe_newline(self):
|
| 717 |
-
"""Adds a newline if it isn't the start of generated source"""
|
| 718 |
-
if self._source:
|
| 719 |
-
self.write("\n")
|
| 720 |
-
|
| 721 |
-
def fill(self, text=""):
|
| 722 |
-
"""Indent a piece of text and append it, according to the current
|
| 723 |
-
indentation level"""
|
| 724 |
-
self.maybe_newline()
|
| 725 |
-
self.write(" " * self._indent + text)
|
| 726 |
-
|
| 727 |
-
def write(self, text):
|
| 728 |
-
"""Append a piece of text"""
|
| 729 |
-
self._source.append(text)
|
| 730 |
-
|
| 731 |
-
def buffer_writer(self, text):
|
| 732 |
-
self._buffer.append(text)
|
| 733 |
-
|
| 734 |
-
@property
|
| 735 |
-
def buffer(self):
|
| 736 |
-
value = "".join(self._buffer)
|
| 737 |
-
self._buffer.clear()
|
| 738 |
-
return value
|
| 739 |
-
|
| 740 |
-
@contextmanager
|
| 741 |
-
def block(self, *, extra = None):
|
| 742 |
-
"""A context manager for preparing the source for blocks. It adds
|
| 743 |
-
the character':', increases the indentation on enter and decreases
|
| 744 |
-
the indentation on exit. If *extra* is given, it will be directly
|
| 745 |
-
appended after the colon character.
|
| 746 |
-
"""
|
| 747 |
-
self.write(":")
|
| 748 |
-
if extra:
|
| 749 |
-
self.write(extra)
|
| 750 |
-
self._indent += 1
|
| 751 |
-
yield
|
| 752 |
-
self._indent -= 1
|
| 753 |
-
|
| 754 |
-
@contextmanager
|
| 755 |
-
def delimit(self, start, end):
|
| 756 |
-
"""A context manager for preparing the source for expressions. It adds
|
| 757 |
-
*start* to the buffer and enters, after exit it adds *end*."""
|
| 758 |
-
|
| 759 |
-
self.write(start)
|
| 760 |
-
yield
|
| 761 |
-
self.write(end)
|
| 762 |
-
|
| 763 |
-
def delimit_if(self, start, end, condition):
|
| 764 |
-
if condition:
|
| 765 |
-
return self.delimit(start, end)
|
| 766 |
-
else:
|
| 767 |
-
return nullcontext()
|
| 768 |
-
|
| 769 |
-
def require_parens(self, precedence, node):
|
| 770 |
-
"""Shortcut to adding precedence related parens"""
|
| 771 |
-
return self.delimit_if("(", ")", self.get_precedence(node) > precedence)
|
| 772 |
-
|
| 773 |
-
def get_precedence(self, node):
|
| 774 |
-
return self._precedences.get(node, _Precedence.TEST)
|
| 775 |
-
|
| 776 |
-
def set_precedence(self, precedence, *nodes):
|
| 777 |
-
for node in nodes:
|
| 778 |
-
self._precedences[node] = precedence
|
| 779 |
-
|
| 780 |
-
def get_raw_docstring(self, node):
|
| 781 |
-
"""If a docstring node is found in the body of the *node* parameter,
|
| 782 |
-
return that docstring node, None otherwise.
|
| 783 |
-
|
| 784 |
-
Logic mirrored from ``_PyAST_GetDocString``."""
|
| 785 |
-
if not isinstance(
|
| 786 |
-
node, (AsyncFunctionDef, FunctionDef, ClassDef, Module)
|
| 787 |
-
) or len(node.body) < 1:
|
| 788 |
-
return None
|
| 789 |
-
node = node.body[0]
|
| 790 |
-
if not isinstance(node, Expr):
|
| 791 |
-
return None
|
| 792 |
-
node = node.value
|
| 793 |
-
if isinstance(node, Constant) and isinstance(node.value, str):
|
| 794 |
-
return node
|
| 795 |
-
|
| 796 |
-
def get_type_comment(self, node):
|
| 797 |
-
comment = self._type_ignores.get(node.lineno) or node.type_comment
|
| 798 |
-
if comment is not None:
|
| 799 |
-
return f" # type: {comment}"
|
| 800 |
-
|
| 801 |
-
def traverse(self, node):
|
| 802 |
-
if isinstance(node, list):
|
| 803 |
-
for item in node:
|
| 804 |
-
self.traverse(item)
|
| 805 |
-
else:
|
| 806 |
-
super().visit(node)
|
| 807 |
-
|
| 808 |
-
# Note: as visit() resets the output text, do NOT rely on
|
| 809 |
-
# NodeVisitor.generic_visit to handle any nodes (as it calls back in to
|
| 810 |
-
# the subclass visit() method, which resets self._source to an empty list)
|
| 811 |
-
def visit(self, node):
|
| 812 |
-
"""Outputs a source code string that, if converted back to an ast
|
| 813 |
-
(using ast.parse) will generate an AST equivalent to *node*"""
|
| 814 |
-
self._source = []
|
| 815 |
-
self.traverse(node)
|
| 816 |
-
return "".join(self._source)
|
| 817 |
-
|
| 818 |
-
def _write_docstring_and_traverse_body(self, node):
|
| 819 |
-
if (docstring := self.get_raw_docstring(node)):
|
| 820 |
-
self._write_docstring(docstring)
|
| 821 |
-
self.traverse(node.body[1:])
|
| 822 |
-
else:
|
| 823 |
-
self.traverse(node.body)
|
| 824 |
-
|
| 825 |
-
def visit_Module(self, node):
|
| 826 |
-
self._type_ignores = {
|
| 827 |
-
ignore.lineno: f"ignore{ignore.tag}"
|
| 828 |
-
for ignore in node.type_ignores
|
| 829 |
-
}
|
| 830 |
-
self._write_docstring_and_traverse_body(node)
|
| 831 |
-
self._type_ignores.clear()
|
| 832 |
-
|
| 833 |
-
def visit_FunctionType(self, node):
|
| 834 |
-
with self.delimit("(", ")"):
|
| 835 |
-
self.interleave(
|
| 836 |
-
lambda: self.write(", "), self.traverse, node.argtypes
|
| 837 |
-
)
|
| 838 |
-
|
| 839 |
-
self.write(" -> ")
|
| 840 |
-
self.traverse(node.returns)
|
| 841 |
-
|
| 842 |
-
def visit_Expr(self, node):
|
| 843 |
-
self.fill()
|
| 844 |
-
self.set_precedence(_Precedence.YIELD, node.value)
|
| 845 |
-
self.traverse(node.value)
|
| 846 |
-
|
| 847 |
-
def visit_NamedExpr(self, node):
|
| 848 |
-
with self.require_parens(_Precedence.TUPLE, node):
|
| 849 |
-
self.set_precedence(_Precedence.ATOM, node.target, node.value)
|
| 850 |
-
self.traverse(node.target)
|
| 851 |
-
self.write(" := ")
|
| 852 |
-
self.traverse(node.value)
|
| 853 |
-
|
| 854 |
-
def visit_Import(self, node):
|
| 855 |
-
self.fill("import ")
|
| 856 |
-
self.interleave(lambda: self.write(", "), self.traverse, node.names)
|
| 857 |
-
|
| 858 |
-
def visit_ImportFrom(self, node):
|
| 859 |
-
self.fill("from ")
|
| 860 |
-
self.write("." * (node.level or 0))
|
| 861 |
-
if node.module:
|
| 862 |
-
self.write(node.module)
|
| 863 |
-
self.write(" import ")
|
| 864 |
-
self.interleave(lambda: self.write(", "), self.traverse, node.names)
|
| 865 |
-
|
| 866 |
-
def visit_Assign(self, node):
|
| 867 |
-
self.fill()
|
| 868 |
-
for target in node.targets:
|
| 869 |
-
self.traverse(target)
|
| 870 |
-
self.write(" = ")
|
| 871 |
-
self.traverse(node.value)
|
| 872 |
-
if type_comment := self.get_type_comment(node):
|
| 873 |
-
self.write(type_comment)
|
| 874 |
-
|
| 875 |
-
def visit_AugAssign(self, node):
|
| 876 |
-
self.fill()
|
| 877 |
-
self.traverse(node.target)
|
| 878 |
-
self.write(" " + self.binop[node.op.__class__.__name__] + "= ")
|
| 879 |
-
self.traverse(node.value)
|
| 880 |
-
|
| 881 |
-
def visit_AnnAssign(self, node):
|
| 882 |
-
self.fill()
|
| 883 |
-
with self.delimit_if("(", ")", not node.simple and isinstance(node.target, Name)):
|
| 884 |
-
self.traverse(node.target)
|
| 885 |
-
self.write(": ")
|
| 886 |
-
self.traverse(node.annotation)
|
| 887 |
-
if node.value:
|
| 888 |
-
self.write(" = ")
|
| 889 |
-
self.traverse(node.value)
|
| 890 |
-
|
| 891 |
-
def visit_Return(self, node):
|
| 892 |
-
self.fill("return")
|
| 893 |
-
if node.value:
|
| 894 |
-
self.write(" ")
|
| 895 |
-
self.traverse(node.value)
|
| 896 |
-
|
| 897 |
-
def visit_Pass(self, node):
|
| 898 |
-
self.fill("pass")
|
| 899 |
-
|
| 900 |
-
def visit_Break(self, node):
|
| 901 |
-
self.fill("break")
|
| 902 |
-
|
| 903 |
-
def visit_Continue(self, node):
|
| 904 |
-
self.fill("continue")
|
| 905 |
-
|
| 906 |
-
def visit_Delete(self, node):
|
| 907 |
-
self.fill("del ")
|
| 908 |
-
self.interleave(lambda: self.write(", "), self.traverse, node.targets)
|
| 909 |
-
|
| 910 |
-
def visit_Assert(self, node):
|
| 911 |
-
self.fill("assert ")
|
| 912 |
-
self.traverse(node.test)
|
| 913 |
-
if node.msg:
|
| 914 |
-
self.write(", ")
|
| 915 |
-
self.traverse(node.msg)
|
| 916 |
-
|
| 917 |
-
def visit_Global(self, node):
|
| 918 |
-
self.fill("global ")
|
| 919 |
-
self.interleave(lambda: self.write(", "), self.write, node.names)
|
| 920 |
-
|
| 921 |
-
def visit_Nonlocal(self, node):
|
| 922 |
-
self.fill("nonlocal ")
|
| 923 |
-
self.interleave(lambda: self.write(", "), self.write, node.names)
|
| 924 |
-
|
| 925 |
-
def visit_Await(self, node):
|
| 926 |
-
with self.require_parens(_Precedence.AWAIT, node):
|
| 927 |
-
self.write("await")
|
| 928 |
-
if node.value:
|
| 929 |
-
self.write(" ")
|
| 930 |
-
self.set_precedence(_Precedence.ATOM, node.value)
|
| 931 |
-
self.traverse(node.value)
|
| 932 |
-
|
| 933 |
-
def visit_Yield(self, node):
|
| 934 |
-
with self.require_parens(_Precedence.YIELD, node):
|
| 935 |
-
self.write("yield")
|
| 936 |
-
if node.value:
|
| 937 |
-
self.write(" ")
|
| 938 |
-
self.set_precedence(_Precedence.ATOM, node.value)
|
| 939 |
-
self.traverse(node.value)
|
| 940 |
-
|
| 941 |
-
def visit_YieldFrom(self, node):
|
| 942 |
-
with self.require_parens(_Precedence.YIELD, node):
|
| 943 |
-
self.write("yield from ")
|
| 944 |
-
if not node.value:
|
| 945 |
-
raise ValueError("Node can't be used without a value attribute.")
|
| 946 |
-
self.set_precedence(_Precedence.ATOM, node.value)
|
| 947 |
-
self.traverse(node.value)
|
| 948 |
-
|
| 949 |
-
def visit_Raise(self, node):
|
| 950 |
-
self.fill("raise")
|
| 951 |
-
if not node.exc:
|
| 952 |
-
if node.cause:
|
| 953 |
-
raise ValueError(f"Node can't use cause without an exception.")
|
| 954 |
-
return
|
| 955 |
-
self.write(" ")
|
| 956 |
-
self.traverse(node.exc)
|
| 957 |
-
if node.cause:
|
| 958 |
-
self.write(" from ")
|
| 959 |
-
self.traverse(node.cause)
|
| 960 |
-
|
| 961 |
-
def visit_Try(self, node):
|
| 962 |
-
self.fill("try")
|
| 963 |
-
with self.block():
|
| 964 |
-
self.traverse(node.body)
|
| 965 |
-
for ex in node.handlers:
|
| 966 |
-
self.traverse(ex)
|
| 967 |
-
if node.orelse:
|
| 968 |
-
self.fill("else")
|
| 969 |
-
with self.block():
|
| 970 |
-
self.traverse(node.orelse)
|
| 971 |
-
if node.finalbody:
|
| 972 |
-
self.fill("finally")
|
| 973 |
-
with self.block():
|
| 974 |
-
self.traverse(node.finalbody)
|
| 975 |
-
|
| 976 |
-
def visit_ExceptHandler(self, node):
|
| 977 |
-
self.fill("except")
|
| 978 |
-
if node.type:
|
| 979 |
-
self.write(" ")
|
| 980 |
-
self.traverse(node.type)
|
| 981 |
-
if node.name:
|
| 982 |
-
self.write(" as ")
|
| 983 |
-
self.write(node.name)
|
| 984 |
-
with self.block():
|
| 985 |
-
self.traverse(node.body)
|
| 986 |
-
|
| 987 |
-
def visit_ClassDef(self, node):
|
| 988 |
-
self.maybe_newline()
|
| 989 |
-
for deco in node.decorator_list:
|
| 990 |
-
self.fill("@")
|
| 991 |
-
self.traverse(deco)
|
| 992 |
-
self.fill("class " + node.name)
|
| 993 |
-
with self.delimit_if("(", ")", condition = node.bases or node.keywords):
|
| 994 |
-
comma = False
|
| 995 |
-
for e in node.bases:
|
| 996 |
-
if comma:
|
| 997 |
-
self.write(", ")
|
| 998 |
-
else:
|
| 999 |
-
comma = True
|
| 1000 |
-
self.traverse(e)
|
| 1001 |
-
for e in node.keywords:
|
| 1002 |
-
if comma:
|
| 1003 |
-
self.write(", ")
|
| 1004 |
-
else:
|
| 1005 |
-
comma = True
|
| 1006 |
-
self.traverse(e)
|
| 1007 |
-
|
| 1008 |
-
with self.block():
|
| 1009 |
-
self._write_docstring_and_traverse_body(node)
|
| 1010 |
-
|
| 1011 |
-
def visit_FunctionDef(self, node):
|
| 1012 |
-
self._function_helper(node, "def")
|
| 1013 |
-
|
| 1014 |
-
def visit_AsyncFunctionDef(self, node):
|
| 1015 |
-
self._function_helper(node, "async def")
|
| 1016 |
-
|
| 1017 |
-
def _function_helper(self, node, fill_suffix):
|
| 1018 |
-
self.maybe_newline()
|
| 1019 |
-
for deco in node.decorator_list:
|
| 1020 |
-
self.fill("@")
|
| 1021 |
-
self.traverse(deco)
|
| 1022 |
-
def_str = fill_suffix + " " + node.name
|
| 1023 |
-
self.fill(def_str)
|
| 1024 |
-
with self.delimit("(", ")"):
|
| 1025 |
-
self.traverse(node.args)
|
| 1026 |
-
if node.returns:
|
| 1027 |
-
self.write(" -> ")
|
| 1028 |
-
self.traverse(node.returns)
|
| 1029 |
-
with self.block(extra=self.get_type_comment(node)):
|
| 1030 |
-
self._write_docstring_and_traverse_body(node)
|
| 1031 |
-
|
| 1032 |
-
def visit_For(self, node):
|
| 1033 |
-
self._for_helper("for ", node)
|
| 1034 |
-
|
| 1035 |
-
def visit_AsyncFor(self, node):
|
| 1036 |
-
self._for_helper("async for ", node)
|
| 1037 |
-
|
| 1038 |
-
def _for_helper(self, fill, node):
|
| 1039 |
-
self.fill(fill)
|
| 1040 |
-
self.traverse(node.target)
|
| 1041 |
-
self.write(" in ")
|
| 1042 |
-
self.traverse(node.iter)
|
| 1043 |
-
with self.block(extra=self.get_type_comment(node)):
|
| 1044 |
-
self.traverse(node.body)
|
| 1045 |
-
if node.orelse:
|
| 1046 |
-
self.fill("else")
|
| 1047 |
-
with self.block():
|
| 1048 |
-
self.traverse(node.orelse)
|
| 1049 |
-
|
| 1050 |
-
def visit_If(self, node):
|
| 1051 |
-
self.fill("if ")
|
| 1052 |
-
self.traverse(node.test)
|
| 1053 |
-
with self.block():
|
| 1054 |
-
self.traverse(node.body)
|
| 1055 |
-
# collapse nested ifs into equivalent elifs.
|
| 1056 |
-
while node.orelse and len(node.orelse) == 1 and isinstance(node.orelse[0], If):
|
| 1057 |
-
node = node.orelse[0]
|
| 1058 |
-
self.fill("elif ")
|
| 1059 |
-
self.traverse(node.test)
|
| 1060 |
-
with self.block():
|
| 1061 |
-
self.traverse(node.body)
|
| 1062 |
-
# final else
|
| 1063 |
-
if node.orelse:
|
| 1064 |
-
self.fill("else")
|
| 1065 |
-
with self.block():
|
| 1066 |
-
self.traverse(node.orelse)
|
| 1067 |
-
|
| 1068 |
-
def visit_While(self, node):
|
| 1069 |
-
self.fill("while ")
|
| 1070 |
-
self.traverse(node.test)
|
| 1071 |
-
with self.block():
|
| 1072 |
-
self.traverse(node.body)
|
| 1073 |
-
if node.orelse:
|
| 1074 |
-
self.fill("else")
|
| 1075 |
-
with self.block():
|
| 1076 |
-
self.traverse(node.orelse)
|
| 1077 |
-
|
| 1078 |
-
def visit_With(self, node):
|
| 1079 |
-
self.fill("with ")
|
| 1080 |
-
self.interleave(lambda: self.write(", "), self.traverse, node.items)
|
| 1081 |
-
with self.block(extra=self.get_type_comment(node)):
|
| 1082 |
-
self.traverse(node.body)
|
| 1083 |
-
|
| 1084 |
-
def visit_AsyncWith(self, node):
|
| 1085 |
-
self.fill("async with ")
|
| 1086 |
-
self.interleave(lambda: self.write(", "), self.traverse, node.items)
|
| 1087 |
-
with self.block(extra=self.get_type_comment(node)):
|
| 1088 |
-
self.traverse(node.body)
|
| 1089 |
-
|
| 1090 |
-
def _str_literal_helper(
|
| 1091 |
-
self, string, *, quote_types=_ALL_QUOTES, escape_special_whitespace=False
|
| 1092 |
-
):
|
| 1093 |
-
"""Helper for writing string literals, minimizing escapes.
|
| 1094 |
-
Returns the tuple (string literal to write, possible quote types).
|
| 1095 |
-
"""
|
| 1096 |
-
def escape_char(c):
|
| 1097 |
-
# \n and \t are non-printable, but we only escape them if
|
| 1098 |
-
# escape_special_whitespace is True
|
| 1099 |
-
if not escape_special_whitespace and c in "\n\t":
|
| 1100 |
-
return c
|
| 1101 |
-
# Always escape backslashes and other non-printable characters
|
| 1102 |
-
if c == "\\" or not c.isprintable():
|
| 1103 |
-
return c.encode("unicode_escape").decode("ascii")
|
| 1104 |
-
return c
|
| 1105 |
-
|
| 1106 |
-
escaped_string = "".join(map(escape_char, string))
|
| 1107 |
-
possible_quotes = quote_types
|
| 1108 |
-
if "\n" in escaped_string:
|
| 1109 |
-
possible_quotes = [q for q in possible_quotes if q in _MULTI_QUOTES]
|
| 1110 |
-
possible_quotes = [q for q in possible_quotes if q not in escaped_string]
|
| 1111 |
-
if not possible_quotes:
|
| 1112 |
-
# If there aren't any possible_quotes, fallback to using repr
|
| 1113 |
-
# on the original string. Try to use a quote from quote_types,
|
| 1114 |
-
# e.g., so that we use triple quotes for docstrings.
|
| 1115 |
-
string = repr(string)
|
| 1116 |
-
quote = next((q for q in quote_types if string[0] in q), string[0])
|
| 1117 |
-
return string[1:-1], [quote]
|
| 1118 |
-
if escaped_string:
|
| 1119 |
-
# Sort so that we prefer '''"''' over """\""""
|
| 1120 |
-
possible_quotes.sort(key=lambda q: q[0] == escaped_string[-1])
|
| 1121 |
-
# If we're using triple quotes and we'd need to escape a final
|
| 1122 |
-
# quote, escape it
|
| 1123 |
-
if possible_quotes[0][0] == escaped_string[-1]:
|
| 1124 |
-
assert len(possible_quotes[0]) == 3
|
| 1125 |
-
escaped_string = escaped_string[:-1] + "\\" + escaped_string[-1]
|
| 1126 |
-
return escaped_string, possible_quotes
|
| 1127 |
-
|
| 1128 |
-
def _write_str_avoiding_backslashes(self, string, *, quote_types=_ALL_QUOTES):
|
| 1129 |
-
"""Write string literal value with a best effort attempt to avoid backslashes."""
|
| 1130 |
-
string, quote_types = self._str_literal_helper(string, quote_types=quote_types)
|
| 1131 |
-
quote_type = quote_types[0]
|
| 1132 |
-
self.write(f"{quote_type}{string}{quote_type}")
|
| 1133 |
-
|
| 1134 |
-
def visit_JoinedStr(self, node):
|
| 1135 |
-
self.write("f")
|
| 1136 |
-
if self._avoid_backslashes:
|
| 1137 |
-
self._fstring_JoinedStr(node, self.buffer_writer)
|
| 1138 |
-
self._write_str_avoiding_backslashes(self.buffer)
|
| 1139 |
-
return
|
| 1140 |
-
|
| 1141 |
-
# If we don't need to avoid backslashes globally (i.e., we only need
|
| 1142 |
-
# to avoid them inside FormattedValues), it's cosmetically preferred
|
| 1143 |
-
# to use escaped whitespace. That is, it's preferred to use backslashes
|
| 1144 |
-
# for cases like: f"{x}\n". To accomplish this, we keep track of what
|
| 1145 |
-
# in our buffer corresponds to FormattedValues and what corresponds to
|
| 1146 |
-
# Constant parts of the f-string, and allow escapes accordingly.
|
| 1147 |
-
buffer = []
|
| 1148 |
-
for value in node.values:
|
| 1149 |
-
meth = getattr(self, "_fstring_" + type(value).__name__)
|
| 1150 |
-
meth(value, self.buffer_writer)
|
| 1151 |
-
buffer.append((self.buffer, isinstance(value, Constant)))
|
| 1152 |
-
new_buffer = []
|
| 1153 |
-
quote_types = _ALL_QUOTES
|
| 1154 |
-
for value, is_constant in buffer:
|
| 1155 |
-
# Repeatedly narrow down the list of possible quote_types
|
| 1156 |
-
value, quote_types = self._str_literal_helper(
|
| 1157 |
-
value, quote_types=quote_types,
|
| 1158 |
-
escape_special_whitespace=is_constant
|
| 1159 |
-
)
|
| 1160 |
-
new_buffer.append(value)
|
| 1161 |
-
value = "".join(new_buffer)
|
| 1162 |
-
quote_type = quote_types[0]
|
| 1163 |
-
self.write(f"{quote_type}{value}{quote_type}")
|
| 1164 |
-
|
| 1165 |
-
def visit_FormattedValue(self, node):
|
| 1166 |
-
self.write("f")
|
| 1167 |
-
self._fstring_FormattedValue(node, self.buffer_writer)
|
| 1168 |
-
self._write_str_avoiding_backslashes(self.buffer)
|
| 1169 |
-
|
| 1170 |
-
def _fstring_JoinedStr(self, node, write):
|
| 1171 |
-
for value in node.values:
|
| 1172 |
-
meth = getattr(self, "_fstring_" + type(value).__name__)
|
| 1173 |
-
meth(value, write)
|
| 1174 |
-
|
| 1175 |
-
def _fstring_Constant(self, node, write):
|
| 1176 |
-
if not isinstance(node.value, str):
|
| 1177 |
-
raise ValueError("Constants inside JoinedStr should be a string.")
|
| 1178 |
-
value = node.value.replace("{", "{{").replace("}", "}}")
|
| 1179 |
-
write(value)
|
| 1180 |
-
|
| 1181 |
-
def _fstring_FormattedValue(self, node, write):
|
| 1182 |
-
write("{")
|
| 1183 |
-
unparser = type(self)(_avoid_backslashes=True)
|
| 1184 |
-
unparser.set_precedence(_Precedence.TEST.next(), node.value)
|
| 1185 |
-
expr = unparser.visit(node.value)
|
| 1186 |
-
if expr.startswith("{"):
|
| 1187 |
-
write(" ") # Separate pair of opening brackets as "{ {"
|
| 1188 |
-
if "\\" in expr:
|
| 1189 |
-
raise ValueError("Unable to avoid backslash in f-string expression part")
|
| 1190 |
-
write(expr)
|
| 1191 |
-
if node.conversion != -1:
|
| 1192 |
-
conversion = chr(node.conversion)
|
| 1193 |
-
if conversion not in "sra":
|
| 1194 |
-
raise ValueError("Unknown f-string conversion.")
|
| 1195 |
-
write(f"!{conversion}")
|
| 1196 |
-
if node.format_spec:
|
| 1197 |
-
write(":")
|
| 1198 |
-
meth = getattr(self, "_fstring_" + type(node.format_spec).__name__)
|
| 1199 |
-
meth(node.format_spec, write)
|
| 1200 |
-
write("}")
|
| 1201 |
-
|
| 1202 |
-
def visit_Name(self, node):
|
| 1203 |
-
self.write(node.id)
|
| 1204 |
-
|
| 1205 |
-
def _write_docstring(self, node):
|
| 1206 |
-
self.fill()
|
| 1207 |
-
if node.kind == "u":
|
| 1208 |
-
self.write("u")
|
| 1209 |
-
self._write_str_avoiding_backslashes(node.value, quote_types=_MULTI_QUOTES)
|
| 1210 |
-
|
| 1211 |
-
def _write_constant(self, value):
|
| 1212 |
-
if isinstance(value, (float, complex)):
|
| 1213 |
-
# Substitute overflowing decimal literal for AST infinities,
|
| 1214 |
-
# and inf - inf for NaNs.
|
| 1215 |
-
self.write(
|
| 1216 |
-
repr(value)
|
| 1217 |
-
.replace("inf", _INFSTR)
|
| 1218 |
-
.replace("nan", f"({_INFSTR}-{_INFSTR})")
|
| 1219 |
-
)
|
| 1220 |
-
elif self._avoid_backslashes and isinstance(value, str):
|
| 1221 |
-
self._write_str_avoiding_backslashes(value)
|
| 1222 |
-
else:
|
| 1223 |
-
self.write(repr(value))
|
| 1224 |
-
|
| 1225 |
-
def visit_Constant(self, node):
|
| 1226 |
-
value = node.value
|
| 1227 |
-
if isinstance(value, tuple):
|
| 1228 |
-
with self.delimit("(", ")"):
|
| 1229 |
-
self.items_view(self._write_constant, value)
|
| 1230 |
-
elif value is ...:
|
| 1231 |
-
self.write("...")
|
| 1232 |
-
else:
|
| 1233 |
-
if node.kind == "u":
|
| 1234 |
-
self.write("u")
|
| 1235 |
-
self._write_constant(node.value)
|
| 1236 |
-
|
| 1237 |
-
def visit_List(self, node):
|
| 1238 |
-
with self.delimit("[", "]"):
|
| 1239 |
-
self.interleave(lambda: self.write(", "), self.traverse, node.elts)
|
| 1240 |
-
|
| 1241 |
-
def visit_ListComp(self, node):
|
| 1242 |
-
with self.delimit("[", "]"):
|
| 1243 |
-
self.traverse(node.elt)
|
| 1244 |
-
for gen in node.generators:
|
| 1245 |
-
self.traverse(gen)
|
| 1246 |
-
|
| 1247 |
-
def visit_GeneratorExp(self, node):
|
| 1248 |
-
with self.delimit("(", ")"):
|
| 1249 |
-
self.traverse(node.elt)
|
| 1250 |
-
for gen in node.generators:
|
| 1251 |
-
self.traverse(gen)
|
| 1252 |
-
|
| 1253 |
-
def visit_SetComp(self, node):
|
| 1254 |
-
with self.delimit("{", "}"):
|
| 1255 |
-
self.traverse(node.elt)
|
| 1256 |
-
for gen in node.generators:
|
| 1257 |
-
self.traverse(gen)
|
| 1258 |
-
|
| 1259 |
-
def visit_DictComp(self, node):
|
| 1260 |
-
with self.delimit("{", "}"):
|
| 1261 |
-
self.traverse(node.key)
|
| 1262 |
-
self.write(": ")
|
| 1263 |
-
self.traverse(node.value)
|
| 1264 |
-
for gen in node.generators:
|
| 1265 |
-
self.traverse(gen)
|
| 1266 |
-
|
| 1267 |
-
def visit_comprehension(self, node):
|
| 1268 |
-
if node.is_async:
|
| 1269 |
-
self.write(" async for ")
|
| 1270 |
-
else:
|
| 1271 |
-
self.write(" for ")
|
| 1272 |
-
self.set_precedence(_Precedence.TUPLE, node.target)
|
| 1273 |
-
self.traverse(node.target)
|
| 1274 |
-
self.write(" in ")
|
| 1275 |
-
self.set_precedence(_Precedence.TEST.next(), node.iter, *node.ifs)
|
| 1276 |
-
self.traverse(node.iter)
|
| 1277 |
-
for if_clause in node.ifs:
|
| 1278 |
-
self.write(" if ")
|
| 1279 |
-
self.traverse(if_clause)
|
| 1280 |
-
|
| 1281 |
-
def visit_IfExp(self, node):
|
| 1282 |
-
with self.require_parens(_Precedence.TEST, node):
|
| 1283 |
-
self.set_precedence(_Precedence.TEST.next(), node.body, node.test)
|
| 1284 |
-
self.traverse(node.body)
|
| 1285 |
-
self.write(" if ")
|
| 1286 |
-
self.traverse(node.test)
|
| 1287 |
-
self.write(" else ")
|
| 1288 |
-
self.set_precedence(_Precedence.TEST, node.orelse)
|
| 1289 |
-
self.traverse(node.orelse)
|
| 1290 |
-
|
| 1291 |
-
def visit_Set(self, node):
|
| 1292 |
-
if node.elts:
|
| 1293 |
-
with self.delimit("{", "}"):
|
| 1294 |
-
self.interleave(lambda: self.write(", "), self.traverse, node.elts)
|
| 1295 |
-
else:
|
| 1296 |
-
# `{}` would be interpreted as a dictionary literal, and
|
| 1297 |
-
# `set` might be shadowed. Thus:
|
| 1298 |
-
self.write('{*()}')
|
| 1299 |
-
|
| 1300 |
-
def visit_Dict(self, node):
|
| 1301 |
-
def write_key_value_pair(k, v):
|
| 1302 |
-
self.traverse(k)
|
| 1303 |
-
self.write(": ")
|
| 1304 |
-
self.traverse(v)
|
| 1305 |
-
|
| 1306 |
-
def write_item(item):
|
| 1307 |
-
k, v = item
|
| 1308 |
-
if k is None:
|
| 1309 |
-
# for dictionary unpacking operator in dicts {**{'y': 2}}
|
| 1310 |
-
# see PEP 448 for details
|
| 1311 |
-
self.write("**")
|
| 1312 |
-
self.set_precedence(_Precedence.EXPR, v)
|
| 1313 |
-
self.traverse(v)
|
| 1314 |
-
else:
|
| 1315 |
-
write_key_value_pair(k, v)
|
| 1316 |
-
|
| 1317 |
-
with self.delimit("{", "}"):
|
| 1318 |
-
self.interleave(
|
| 1319 |
-
lambda: self.write(", "), write_item, zip(node.keys, node.values)
|
| 1320 |
-
)
|
| 1321 |
-
|
| 1322 |
-
def visit_Tuple(self, node):
|
| 1323 |
-
with self.delimit("(", ")"):
|
| 1324 |
-
self.items_view(self.traverse, node.elts)
|
| 1325 |
-
|
| 1326 |
-
unop = {"Invert": "~", "Not": "not", "UAdd": "+", "USub": "-"}
|
| 1327 |
-
unop_precedence = {
|
| 1328 |
-
"not": _Precedence.NOT,
|
| 1329 |
-
"~": _Precedence.FACTOR,
|
| 1330 |
-
"+": _Precedence.FACTOR,
|
| 1331 |
-
"-": _Precedence.FACTOR,
|
| 1332 |
-
}
|
| 1333 |
-
|
| 1334 |
-
def visit_UnaryOp(self, node):
|
| 1335 |
-
operator = self.unop[node.op.__class__.__name__]
|
| 1336 |
-
operator_precedence = self.unop_precedence[operator]
|
| 1337 |
-
with self.require_parens(operator_precedence, node):
|
| 1338 |
-
self.write(operator)
|
| 1339 |
-
# factor prefixes (+, -, ~) shouldn't be seperated
|
| 1340 |
-
# from the value they belong, (e.g: +1 instead of + 1)
|
| 1341 |
-
if operator_precedence is not _Precedence.FACTOR:
|
| 1342 |
-
self.write(" ")
|
| 1343 |
-
self.set_precedence(operator_precedence, node.operand)
|
| 1344 |
-
self.traverse(node.operand)
|
| 1345 |
-
|
| 1346 |
-
binop = {
|
| 1347 |
-
"Add": "+",
|
| 1348 |
-
"Sub": "-",
|
| 1349 |
-
"Mult": "*",
|
| 1350 |
-
"MatMult": "@",
|
| 1351 |
-
"Div": "/",
|
| 1352 |
-
"Mod": "%",
|
| 1353 |
-
"LShift": "<<",
|
| 1354 |
-
"RShift": ">>",
|
| 1355 |
-
"BitOr": "|",
|
| 1356 |
-
"BitXor": "^",
|
| 1357 |
-
"BitAnd": "&",
|
| 1358 |
-
"FloorDiv": "//",
|
| 1359 |
-
"Pow": "**",
|
| 1360 |
-
}
|
| 1361 |
-
|
| 1362 |
-
binop_precedence = {
|
| 1363 |
-
"+": _Precedence.ARITH,
|
| 1364 |
-
"-": _Precedence.ARITH,
|
| 1365 |
-
"*": _Precedence.TERM,
|
| 1366 |
-
"@": _Precedence.TERM,
|
| 1367 |
-
"/": _Precedence.TERM,
|
| 1368 |
-
"%": _Precedence.TERM,
|
| 1369 |
-
"<<": _Precedence.SHIFT,
|
| 1370 |
-
">>": _Precedence.SHIFT,
|
| 1371 |
-
"|": _Precedence.BOR,
|
| 1372 |
-
"^": _Precedence.BXOR,
|
| 1373 |
-
"&": _Precedence.BAND,
|
| 1374 |
-
"//": _Precedence.TERM,
|
| 1375 |
-
"**": _Precedence.POWER,
|
| 1376 |
-
}
|
| 1377 |
-
|
| 1378 |
-
binop_rassoc = frozenset(("**",))
|
| 1379 |
-
def visit_BinOp(self, node):
|
| 1380 |
-
operator = self.binop[node.op.__class__.__name__]
|
| 1381 |
-
operator_precedence = self.binop_precedence[operator]
|
| 1382 |
-
with self.require_parens(operator_precedence, node):
|
| 1383 |
-
if operator in self.binop_rassoc:
|
| 1384 |
-
left_precedence = operator_precedence.next()
|
| 1385 |
-
right_precedence = operator_precedence
|
| 1386 |
-
else:
|
| 1387 |
-
left_precedence = operator_precedence
|
| 1388 |
-
right_precedence = operator_precedence.next()
|
| 1389 |
-
|
| 1390 |
-
self.set_precedence(left_precedence, node.left)
|
| 1391 |
-
self.traverse(node.left)
|
| 1392 |
-
self.write(f" {operator} ")
|
| 1393 |
-
self.set_precedence(right_precedence, node.right)
|
| 1394 |
-
self.traverse(node.right)
|
| 1395 |
-
|
| 1396 |
-
cmpops = {
|
| 1397 |
-
"Eq": "==",
|
| 1398 |
-
"NotEq": "!=",
|
| 1399 |
-
"Lt": "<",
|
| 1400 |
-
"LtE": "<=",
|
| 1401 |
-
"Gt": ">",
|
| 1402 |
-
"GtE": ">=",
|
| 1403 |
-
"Is": "is",
|
| 1404 |
-
"IsNot": "is not",
|
| 1405 |
-
"In": "in",
|
| 1406 |
-
"NotIn": "not in",
|
| 1407 |
-
}
|
| 1408 |
-
|
| 1409 |
-
def visit_Compare(self, node):
|
| 1410 |
-
with self.require_parens(_Precedence.CMP, node):
|
| 1411 |
-
self.set_precedence(_Precedence.CMP.next(), node.left, *node.comparators)
|
| 1412 |
-
self.traverse(node.left)
|
| 1413 |
-
for o, e in zip(node.ops, node.comparators):
|
| 1414 |
-
self.write(" " + self.cmpops[o.__class__.__name__] + " ")
|
| 1415 |
-
self.traverse(e)
|
| 1416 |
-
|
| 1417 |
-
boolops = {"And": "and", "Or": "or"}
|
| 1418 |
-
boolop_precedence = {"and": _Precedence.AND, "or": _Precedence.OR}
|
| 1419 |
-
|
| 1420 |
-
def visit_BoolOp(self, node):
|
| 1421 |
-
operator = self.boolops[node.op.__class__.__name__]
|
| 1422 |
-
operator_precedence = self.boolop_precedence[operator]
|
| 1423 |
-
|
| 1424 |
-
def increasing_level_traverse(node):
|
| 1425 |
-
nonlocal operator_precedence
|
| 1426 |
-
operator_precedence = operator_precedence.next()
|
| 1427 |
-
self.set_precedence(operator_precedence, node)
|
| 1428 |
-
self.traverse(node)
|
| 1429 |
-
|
| 1430 |
-
with self.require_parens(operator_precedence, node):
|
| 1431 |
-
s = f" {operator} "
|
| 1432 |
-
self.interleave(lambda: self.write(s), increasing_level_traverse, node.values)
|
| 1433 |
-
|
| 1434 |
-
def visit_Attribute(self, node):
|
| 1435 |
-
self.set_precedence(_Precedence.ATOM, node.value)
|
| 1436 |
-
self.traverse(node.value)
|
| 1437 |
-
# Special case: 3.__abs__() is a syntax error, so if node.value
|
| 1438 |
-
# is an integer literal then we need to either parenthesize
|
| 1439 |
-
# it or add an extra space to get 3 .__abs__().
|
| 1440 |
-
if isinstance(node.value, Constant) and isinstance(node.value.value, int):
|
| 1441 |
-
self.write(" ")
|
| 1442 |
-
self.write(".")
|
| 1443 |
-
self.write(node.attr)
|
| 1444 |
-
|
| 1445 |
-
def visit_Call(self, node):
|
| 1446 |
-
self.set_precedence(_Precedence.ATOM, node.func)
|
| 1447 |
-
self.traverse(node.func)
|
| 1448 |
-
with self.delimit("(", ")"):
|
| 1449 |
-
comma = False
|
| 1450 |
-
for e in node.args:
|
| 1451 |
-
if comma:
|
| 1452 |
-
self.write(", ")
|
| 1453 |
-
else:
|
| 1454 |
-
comma = True
|
| 1455 |
-
self.traverse(e)
|
| 1456 |
-
for e in node.keywords:
|
| 1457 |
-
if comma:
|
| 1458 |
-
self.write(", ")
|
| 1459 |
-
else:
|
| 1460 |
-
comma = True
|
| 1461 |
-
self.traverse(e)
|
| 1462 |
-
|
| 1463 |
-
def visit_Subscript(self, node):
|
| 1464 |
-
def is_simple_tuple(slice_value):
|
| 1465 |
-
# when unparsing a non-empty tuple, the parentheses can be safely
|
| 1466 |
-
# omitted if there aren't any elements that explicitly requires
|
| 1467 |
-
# parentheses (such as starred expressions).
|
| 1468 |
-
return (
|
| 1469 |
-
isinstance(slice_value, Tuple)
|
| 1470 |
-
and slice_value.elts
|
| 1471 |
-
and not any(isinstance(elt, Starred) for elt in slice_value.elts)
|
| 1472 |
-
)
|
| 1473 |
-
|
| 1474 |
-
self.set_precedence(_Precedence.ATOM, node.value)
|
| 1475 |
-
self.traverse(node.value)
|
| 1476 |
-
with self.delimit("[", "]"):
|
| 1477 |
-
if is_simple_tuple(node.slice):
|
| 1478 |
-
self.items_view(self.traverse, node.slice.elts)
|
| 1479 |
-
else:
|
| 1480 |
-
self.traverse(node.slice)
|
| 1481 |
-
|
| 1482 |
-
def visit_Starred(self, node):
|
| 1483 |
-
self.write("*")
|
| 1484 |
-
self.set_precedence(_Precedence.EXPR, node.value)
|
| 1485 |
-
self.traverse(node.value)
|
| 1486 |
-
|
| 1487 |
-
def visit_Ellipsis(self, node):
|
| 1488 |
-
self.write("...")
|
| 1489 |
-
|
| 1490 |
-
def visit_Slice(self, node):
|
| 1491 |
-
if node.lower:
|
| 1492 |
-
self.traverse(node.lower)
|
| 1493 |
-
self.write(":")
|
| 1494 |
-
if node.upper:
|
| 1495 |
-
self.traverse(node.upper)
|
| 1496 |
-
if node.step:
|
| 1497 |
-
self.write(":")
|
| 1498 |
-
self.traverse(node.step)
|
| 1499 |
-
|
| 1500 |
-
def visit_Match(self, node):
|
| 1501 |
-
self.fill("match ")
|
| 1502 |
-
self.traverse(node.subject)
|
| 1503 |
-
with self.block():
|
| 1504 |
-
for case in node.cases:
|
| 1505 |
-
self.traverse(case)
|
| 1506 |
-
|
| 1507 |
-
def visit_arg(self, node):
|
| 1508 |
-
self.write(node.arg)
|
| 1509 |
-
if node.annotation:
|
| 1510 |
-
self.write(": ")
|
| 1511 |
-
self.traverse(node.annotation)
|
| 1512 |
-
|
| 1513 |
-
def visit_arguments(self, node):
|
| 1514 |
-
first = True
|
| 1515 |
-
# normal arguments
|
| 1516 |
-
all_args = node.posonlyargs + node.args
|
| 1517 |
-
defaults = [None] * (len(all_args) - len(node.defaults)) + node.defaults
|
| 1518 |
-
for index, elements in enumerate(zip(all_args, defaults), 1):
|
| 1519 |
-
a, d = elements
|
| 1520 |
-
if first:
|
| 1521 |
-
first = False
|
| 1522 |
-
else:
|
| 1523 |
-
self.write(", ")
|
| 1524 |
-
self.traverse(a)
|
| 1525 |
-
if d:
|
| 1526 |
-
self.write("=")
|
| 1527 |
-
self.traverse(d)
|
| 1528 |
-
if index == len(node.posonlyargs):
|
| 1529 |
-
self.write(", /")
|
| 1530 |
-
|
| 1531 |
-
# varargs, or bare '*' if no varargs but keyword-only arguments present
|
| 1532 |
-
if node.vararg or node.kwonlyargs:
|
| 1533 |
-
if first:
|
| 1534 |
-
first = False
|
| 1535 |
-
else:
|
| 1536 |
-
self.write(", ")
|
| 1537 |
-
self.write("*")
|
| 1538 |
-
if node.vararg:
|
| 1539 |
-
self.write(node.vararg.arg)
|
| 1540 |
-
if node.vararg.annotation:
|
| 1541 |
-
self.write(": ")
|
| 1542 |
-
self.traverse(node.vararg.annotation)
|
| 1543 |
-
|
| 1544 |
-
# keyword-only arguments
|
| 1545 |
-
if node.kwonlyargs:
|
| 1546 |
-
for a, d in zip(node.kwonlyargs, node.kw_defaults):
|
| 1547 |
-
self.write(", ")
|
| 1548 |
-
self.traverse(a)
|
| 1549 |
-
if d:
|
| 1550 |
-
self.write("=")
|
| 1551 |
-
self.traverse(d)
|
| 1552 |
-
|
| 1553 |
-
# kwargs
|
| 1554 |
-
if node.kwarg:
|
| 1555 |
-
if first:
|
| 1556 |
-
first = False
|
| 1557 |
-
else:
|
| 1558 |
-
self.write(", ")
|
| 1559 |
-
self.write("**" + node.kwarg.arg)
|
| 1560 |
-
if node.kwarg.annotation:
|
| 1561 |
-
self.write(": ")
|
| 1562 |
-
self.traverse(node.kwarg.annotation)
|
| 1563 |
-
|
| 1564 |
-
def visit_keyword(self, node):
|
| 1565 |
-
if node.arg is None:
|
| 1566 |
-
self.write("**")
|
| 1567 |
-
else:
|
| 1568 |
-
self.write(node.arg)
|
| 1569 |
-
self.write("=")
|
| 1570 |
-
self.traverse(node.value)
|
| 1571 |
-
|
| 1572 |
-
def visit_Lambda(self, node):
|
| 1573 |
-
with self.require_parens(_Precedence.TEST, node):
|
| 1574 |
-
self.write("lambda ")
|
| 1575 |
-
self.traverse(node.args)
|
| 1576 |
-
self.write(": ")
|
| 1577 |
-
self.set_precedence(_Precedence.TEST, node.body)
|
| 1578 |
-
self.traverse(node.body)
|
| 1579 |
-
|
| 1580 |
-
def visit_alias(self, node):
|
| 1581 |
-
self.write(node.name)
|
| 1582 |
-
if node.asname:
|
| 1583 |
-
self.write(" as " + node.asname)
|
| 1584 |
-
|
| 1585 |
-
def visit_withitem(self, node):
|
| 1586 |
-
self.traverse(node.context_expr)
|
| 1587 |
-
if node.optional_vars:
|
| 1588 |
-
self.write(" as ")
|
| 1589 |
-
self.traverse(node.optional_vars)
|
| 1590 |
-
|
| 1591 |
-
def visit_match_case(self, node):
|
| 1592 |
-
self.fill("case ")
|
| 1593 |
-
self.traverse(node.pattern)
|
| 1594 |
-
if node.guard:
|
| 1595 |
-
self.write(" if ")
|
| 1596 |
-
self.traverse(node.guard)
|
| 1597 |
-
with self.block():
|
| 1598 |
-
self.traverse(node.body)
|
| 1599 |
-
|
| 1600 |
-
def visit_MatchValue(self, node):
|
| 1601 |
-
self.traverse(node.value)
|
| 1602 |
-
|
| 1603 |
-
def visit_MatchSingleton(self, node):
|
| 1604 |
-
self._write_constant(node.value)
|
| 1605 |
-
|
| 1606 |
-
def visit_MatchSequence(self, node):
|
| 1607 |
-
with self.delimit("[", "]"):
|
| 1608 |
-
self.interleave(
|
| 1609 |
-
lambda: self.write(", "), self.traverse, node.patterns
|
| 1610 |
-
)
|
| 1611 |
-
|
| 1612 |
-
def visit_MatchStar(self, node):
|
| 1613 |
-
name = node.name
|
| 1614 |
-
if name is None:
|
| 1615 |
-
name = "_"
|
| 1616 |
-
self.write(f"*{name}")
|
| 1617 |
-
|
| 1618 |
-
def visit_MatchMapping(self, node):
|
| 1619 |
-
def write_key_pattern_pair(pair):
|
| 1620 |
-
k, p = pair
|
| 1621 |
-
self.traverse(k)
|
| 1622 |
-
self.write(": ")
|
| 1623 |
-
self.traverse(p)
|
| 1624 |
-
|
| 1625 |
-
with self.delimit("{", "}"):
|
| 1626 |
-
keys = node.keys
|
| 1627 |
-
self.interleave(
|
| 1628 |
-
lambda: self.write(", "),
|
| 1629 |
-
write_key_pattern_pair,
|
| 1630 |
-
zip(keys, node.patterns, strict=True),
|
| 1631 |
-
)
|
| 1632 |
-
rest = node.rest
|
| 1633 |
-
if rest is not None:
|
| 1634 |
-
if keys:
|
| 1635 |
-
self.write(", ")
|
| 1636 |
-
self.write(f"**{rest}")
|
| 1637 |
-
|
| 1638 |
-
def visit_MatchClass(self, node):
|
| 1639 |
-
self.set_precedence(_Precedence.ATOM, node.cls)
|
| 1640 |
-
self.traverse(node.cls)
|
| 1641 |
-
with self.delimit("(", ")"):
|
| 1642 |
-
patterns = node.patterns
|
| 1643 |
-
self.interleave(
|
| 1644 |
-
lambda: self.write(", "), self.traverse, patterns
|
| 1645 |
-
)
|
| 1646 |
-
attrs = node.kwd_attrs
|
| 1647 |
-
if attrs:
|
| 1648 |
-
def write_attr_pattern(pair):
|
| 1649 |
-
attr, pattern = pair
|
| 1650 |
-
self.write(f"{attr}=")
|
| 1651 |
-
self.traverse(pattern)
|
| 1652 |
-
|
| 1653 |
-
if patterns:
|
| 1654 |
-
self.write(", ")
|
| 1655 |
-
self.interleave(
|
| 1656 |
-
lambda: self.write(", "),
|
| 1657 |
-
write_attr_pattern,
|
| 1658 |
-
zip(attrs, node.kwd_patterns, strict=True),
|
| 1659 |
-
)
|
| 1660 |
-
|
| 1661 |
-
def visit_MatchAs(self, node):
|
| 1662 |
-
name = node.name
|
| 1663 |
-
pattern = node.pattern
|
| 1664 |
-
if name is None:
|
| 1665 |
-
self.write("_")
|
| 1666 |
-
elif pattern is None:
|
| 1667 |
-
self.write(node.name)
|
| 1668 |
-
else:
|
| 1669 |
-
with self.require_parens(_Precedence.TEST, node):
|
| 1670 |
-
self.set_precedence(_Precedence.BOR, node.pattern)
|
| 1671 |
-
self.traverse(node.pattern)
|
| 1672 |
-
self.write(f" as {node.name}")
|
| 1673 |
-
|
| 1674 |
-
def visit_MatchOr(self, node):
|
| 1675 |
-
with self.require_parens(_Precedence.BOR, node):
|
| 1676 |
-
self.set_precedence(_Precedence.BOR.next(), *node.patterns)
|
| 1677 |
-
self.interleave(lambda: self.write(" | "), self.traverse, node.patterns)
|
| 1678 |
-
|
| 1679 |
-
def unparse(ast_obj):
|
| 1680 |
-
unparser = _Unparser()
|
| 1681 |
-
return unparser.visit(ast_obj)
|
| 1682 |
-
|
| 1683 |
-
|
| 1684 |
-
def main():
|
| 1685 |
-
import argparse
|
| 1686 |
-
|
| 1687 |
-
parser = argparse.ArgumentParser(prog='python -m ast')
|
| 1688 |
-
parser.add_argument('infile', type=argparse.FileType(mode='rb'), nargs='?',
|
| 1689 |
-
default='-',
|
| 1690 |
-
help='the file to parse; defaults to stdin')
|
| 1691 |
-
parser.add_argument('-m', '--mode', default='exec',
|
| 1692 |
-
choices=('exec', 'single', 'eval', 'func_type'),
|
| 1693 |
-
help='specify what kind of code must be parsed')
|
| 1694 |
-
parser.add_argument('--no-type-comments', default=True, action='store_false',
|
| 1695 |
-
help="don't add information about type comments")
|
| 1696 |
-
parser.add_argument('-a', '--include-attributes', action='store_true',
|
| 1697 |
-
help='include attributes such as line numbers and '
|
| 1698 |
-
'column offsets')
|
| 1699 |
-
parser.add_argument('-i', '--indent', type=int, default=3,
|
| 1700 |
-
help='indentation of nodes (number of spaces)')
|
| 1701 |
-
args = parser.parse_args()
|
| 1702 |
-
|
| 1703 |
-
with args.infile as infile:
|
| 1704 |
-
source = infile.read()
|
| 1705 |
-
tree = parse(source, args.infile.name, args.mode, type_comments=args.no_type_comments)
|
| 1706 |
-
print(dump(tree, include_attributes=args.include_attributes, indent=args.indent))
|
| 1707 |
-
|
| 1708 |
-
if __name__ == '__main__':
|
| 1709 |
-
main()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Pytorch/Lib/asynchat.py
DELETED
|
@@ -1,315 +0,0 @@
|
|
| 1 |
-
# -*- Mode: Python; tab-width: 4 -*-
|
| 2 |
-
# Id: asynchat.py,v 2.26 2000/09/07 22:29:26 rushing Exp
|
| 3 |
-
# Author: Sam Rushing <rushing@nightmare.com>
|
| 4 |
-
|
| 5 |
-
# ======================================================================
|
| 6 |
-
# Copyright 1996 by Sam Rushing
|
| 7 |
-
#
|
| 8 |
-
# All Rights Reserved
|
| 9 |
-
#
|
| 10 |
-
# Permission to use, copy, modify, and distribute this software and
|
| 11 |
-
# its documentation for any purpose and without fee is hereby
|
| 12 |
-
# granted, provided that the above copyright notice appear in all
|
| 13 |
-
# copies and that both that copyright notice and this permission
|
| 14 |
-
# notice appear in supporting documentation, and that the name of Sam
|
| 15 |
-
# Rushing not be used in advertising or publicity pertaining to
|
| 16 |
-
# distribution of the software without specific, written prior
|
| 17 |
-
# permission.
|
| 18 |
-
#
|
| 19 |
-
# SAM RUSHING DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
| 20 |
-
# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
|
| 21 |
-
# NO EVENT SHALL SAM RUSHING BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
| 22 |
-
# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
|
| 23 |
-
# OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
| 24 |
-
# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
| 25 |
-
# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
| 26 |
-
# ======================================================================
|
| 27 |
-
|
| 28 |
-
r"""A class supporting chat-style (command/response) protocols.
|
| 29 |
-
|
| 30 |
-
This class adds support for 'chat' style protocols - where one side
|
| 31 |
-
sends a 'command', and the other sends a response (examples would be
|
| 32 |
-
the common internet protocols - smtp, nntp, ftp, etc..).
|
| 33 |
-
|
| 34 |
-
The handle_read() method looks at the input stream for the current
|
| 35 |
-
'terminator' (usually '\r\n' for single-line responses, '\r\n.\r\n'
|
| 36 |
-
for multi-line output), calling self.found_terminator() on its
|
| 37 |
-
receipt.
|
| 38 |
-
|
| 39 |
-
for example:
|
| 40 |
-
Say you build an async nntp client using this class. At the start
|
| 41 |
-
of the connection, you'll have self.terminator set to '\r\n', in
|
| 42 |
-
order to process the single-line greeting. Just before issuing a
|
| 43 |
-
'LIST' command you'll set it to '\r\n.\r\n'. The output of the LIST
|
| 44 |
-
command will be accumulated (using your own 'collect_incoming_data'
|
| 45 |
-
method) up to the terminator, and then control will be returned to
|
| 46 |
-
you - by calling your self.found_terminator() method.
|
| 47 |
-
"""
|
| 48 |
-
import asyncore
|
| 49 |
-
from collections import deque
|
| 50 |
-
|
| 51 |
-
from warnings import warn
|
| 52 |
-
warn(
|
| 53 |
-
'The asynchat module is deprecated and will be removed in Python 3.12. '
|
| 54 |
-
'The recommended replacement is asyncio',
|
| 55 |
-
DeprecationWarning,
|
| 56 |
-
stacklevel=2)
|
| 57 |
-
|
| 58 |
-
|
| 59 |
-
|
| 60 |
-
class async_chat(asyncore.dispatcher):
|
| 61 |
-
"""This is an abstract class. You must derive from this class, and add
|
| 62 |
-
the two methods collect_incoming_data() and found_terminator()"""
|
| 63 |
-
|
| 64 |
-
# these are overridable defaults
|
| 65 |
-
|
| 66 |
-
ac_in_buffer_size = 65536
|
| 67 |
-
ac_out_buffer_size = 65536
|
| 68 |
-
|
| 69 |
-
# we don't want to enable the use of encoding by default, because that is a
|
| 70 |
-
# sign of an application bug that we don't want to pass silently
|
| 71 |
-
|
| 72 |
-
use_encoding = 0
|
| 73 |
-
encoding = 'latin-1'
|
| 74 |
-
|
| 75 |
-
def __init__(self, sock=None, map=None):
|
| 76 |
-
# for string terminator matching
|
| 77 |
-
self.ac_in_buffer = b''
|
| 78 |
-
|
| 79 |
-
# we use a list here rather than io.BytesIO for a few reasons...
|
| 80 |
-
# del lst[:] is faster than bio.truncate(0)
|
| 81 |
-
# lst = [] is faster than bio.truncate(0)
|
| 82 |
-
self.incoming = []
|
| 83 |
-
|
| 84 |
-
# we toss the use of the "simple producer" and replace it with
|
| 85 |
-
# a pure deque, which the original fifo was a wrapping of
|
| 86 |
-
self.producer_fifo = deque()
|
| 87 |
-
asyncore.dispatcher.__init__(self, sock, map)
|
| 88 |
-
|
| 89 |
-
def collect_incoming_data(self, data):
|
| 90 |
-
raise NotImplementedError("must be implemented in subclass")
|
| 91 |
-
|
| 92 |
-
def _collect_incoming_data(self, data):
|
| 93 |
-
self.incoming.append(data)
|
| 94 |
-
|
| 95 |
-
def _get_data(self):
|
| 96 |
-
d = b''.join(self.incoming)
|
| 97 |
-
del self.incoming[:]
|
| 98 |
-
return d
|
| 99 |
-
|
| 100 |
-
def found_terminator(self):
|
| 101 |
-
raise NotImplementedError("must be implemented in subclass")
|
| 102 |
-
|
| 103 |
-
def set_terminator(self, term):
|
| 104 |
-
"""Set the input delimiter.
|
| 105 |
-
|
| 106 |
-
Can be a fixed string of any length, an integer, or None.
|
| 107 |
-
"""
|
| 108 |
-
if isinstance(term, str) and self.use_encoding:
|
| 109 |
-
term = bytes(term, self.encoding)
|
| 110 |
-
elif isinstance(term, int) and term < 0:
|
| 111 |
-
raise ValueError('the number of received bytes must be positive')
|
| 112 |
-
self.terminator = term
|
| 113 |
-
|
| 114 |
-
def get_terminator(self):
|
| 115 |
-
return self.terminator
|
| 116 |
-
|
| 117 |
-
# grab some more data from the socket,
|
| 118 |
-
# throw it to the collector method,
|
| 119 |
-
# check for the terminator,
|
| 120 |
-
# if found, transition to the next state.
|
| 121 |
-
|
| 122 |
-
def handle_read(self):
|
| 123 |
-
|
| 124 |
-
try:
|
| 125 |
-
data = self.recv(self.ac_in_buffer_size)
|
| 126 |
-
except BlockingIOError:
|
| 127 |
-
return
|
| 128 |
-
except OSError:
|
| 129 |
-
self.handle_error()
|
| 130 |
-
return
|
| 131 |
-
|
| 132 |
-
if isinstance(data, str) and self.use_encoding:
|
| 133 |
-
data = bytes(str, self.encoding)
|
| 134 |
-
self.ac_in_buffer = self.ac_in_buffer + data
|
| 135 |
-
|
| 136 |
-
# Continue to search for self.terminator in self.ac_in_buffer,
|
| 137 |
-
# while calling self.collect_incoming_data. The while loop
|
| 138 |
-
# is necessary because we might read several data+terminator
|
| 139 |
-
# combos with a single recv(4096).
|
| 140 |
-
|
| 141 |
-
while self.ac_in_buffer:
|
| 142 |
-
lb = len(self.ac_in_buffer)
|
| 143 |
-
terminator = self.get_terminator()
|
| 144 |
-
if not terminator:
|
| 145 |
-
# no terminator, collect it all
|
| 146 |
-
self.collect_incoming_data(self.ac_in_buffer)
|
| 147 |
-
self.ac_in_buffer = b''
|
| 148 |
-
elif isinstance(terminator, int):
|
| 149 |
-
# numeric terminator
|
| 150 |
-
n = terminator
|
| 151 |
-
if lb < n:
|
| 152 |
-
self.collect_incoming_data(self.ac_in_buffer)
|
| 153 |
-
self.ac_in_buffer = b''
|
| 154 |
-
self.terminator = self.terminator - lb
|
| 155 |
-
else:
|
| 156 |
-
self.collect_incoming_data(self.ac_in_buffer[:n])
|
| 157 |
-
self.ac_in_buffer = self.ac_in_buffer[n:]
|
| 158 |
-
self.terminator = 0
|
| 159 |
-
self.found_terminator()
|
| 160 |
-
else:
|
| 161 |
-
# 3 cases:
|
| 162 |
-
# 1) end of buffer matches terminator exactly:
|
| 163 |
-
# collect data, transition
|
| 164 |
-
# 2) end of buffer matches some prefix:
|
| 165 |
-
# collect data to the prefix
|
| 166 |
-
# 3) end of buffer does not match any prefix:
|
| 167 |
-
# collect data
|
| 168 |
-
terminator_len = len(terminator)
|
| 169 |
-
index = self.ac_in_buffer.find(terminator)
|
| 170 |
-
if index != -1:
|
| 171 |
-
# we found the terminator
|
| 172 |
-
if index > 0:
|
| 173 |
-
# don't bother reporting the empty string
|
| 174 |
-
# (source of subtle bugs)
|
| 175 |
-
self.collect_incoming_data(self.ac_in_buffer[:index])
|
| 176 |
-
self.ac_in_buffer = self.ac_in_buffer[index+terminator_len:]
|
| 177 |
-
# This does the Right Thing if the terminator
|
| 178 |
-
# is changed here.
|
| 179 |
-
self.found_terminator()
|
| 180 |
-
else:
|
| 181 |
-
# check for a prefix of the terminator
|
| 182 |
-
index = find_prefix_at_end(self.ac_in_buffer, terminator)
|
| 183 |
-
if index:
|
| 184 |
-
if index != lb:
|
| 185 |
-
# we found a prefix, collect up to the prefix
|
| 186 |
-
self.collect_incoming_data(self.ac_in_buffer[:-index])
|
| 187 |
-
self.ac_in_buffer = self.ac_in_buffer[-index:]
|
| 188 |
-
break
|
| 189 |
-
else:
|
| 190 |
-
# no prefix, collect it all
|
| 191 |
-
self.collect_incoming_data(self.ac_in_buffer)
|
| 192 |
-
self.ac_in_buffer = b''
|
| 193 |
-
|
| 194 |
-
def handle_write(self):
|
| 195 |
-
self.initiate_send()
|
| 196 |
-
|
| 197 |
-
def handle_close(self):
|
| 198 |
-
self.close()
|
| 199 |
-
|
| 200 |
-
def push(self, data):
|
| 201 |
-
if not isinstance(data, (bytes, bytearray, memoryview)):
|
| 202 |
-
raise TypeError('data argument must be byte-ish (%r)',
|
| 203 |
-
type(data))
|
| 204 |
-
sabs = self.ac_out_buffer_size
|
| 205 |
-
if len(data) > sabs:
|
| 206 |
-
for i in range(0, len(data), sabs):
|
| 207 |
-
self.producer_fifo.append(data[i:i+sabs])
|
| 208 |
-
else:
|
| 209 |
-
self.producer_fifo.append(data)
|
| 210 |
-
self.initiate_send()
|
| 211 |
-
|
| 212 |
-
def push_with_producer(self, producer):
|
| 213 |
-
self.producer_fifo.append(producer)
|
| 214 |
-
self.initiate_send()
|
| 215 |
-
|
| 216 |
-
def readable(self):
|
| 217 |
-
"predicate for inclusion in the readable for select()"
|
| 218 |
-
# cannot use the old predicate, it violates the claim of the
|
| 219 |
-
# set_terminator method.
|
| 220 |
-
|
| 221 |
-
# return (len(self.ac_in_buffer) <= self.ac_in_buffer_size)
|
| 222 |
-
return 1
|
| 223 |
-
|
| 224 |
-
def writable(self):
|
| 225 |
-
"predicate for inclusion in the writable for select()"
|
| 226 |
-
return self.producer_fifo or (not self.connected)
|
| 227 |
-
|
| 228 |
-
def close_when_done(self):
|
| 229 |
-
"automatically close this channel once the outgoing queue is empty"
|
| 230 |
-
self.producer_fifo.append(None)
|
| 231 |
-
|
| 232 |
-
def initiate_send(self):
|
| 233 |
-
while self.producer_fifo and self.connected:
|
| 234 |
-
first = self.producer_fifo[0]
|
| 235 |
-
# handle empty string/buffer or None entry
|
| 236 |
-
if not first:
|
| 237 |
-
del self.producer_fifo[0]
|
| 238 |
-
if first is None:
|
| 239 |
-
self.handle_close()
|
| 240 |
-
return
|
| 241 |
-
|
| 242 |
-
# handle classic producer behavior
|
| 243 |
-
obs = self.ac_out_buffer_size
|
| 244 |
-
try:
|
| 245 |
-
data = first[:obs]
|
| 246 |
-
except TypeError:
|
| 247 |
-
data = first.more()
|
| 248 |
-
if data:
|
| 249 |
-
self.producer_fifo.appendleft(data)
|
| 250 |
-
else:
|
| 251 |
-
del self.producer_fifo[0]
|
| 252 |
-
continue
|
| 253 |
-
|
| 254 |
-
if isinstance(data, str) and self.use_encoding:
|
| 255 |
-
data = bytes(data, self.encoding)
|
| 256 |
-
|
| 257 |
-
# send the data
|
| 258 |
-
try:
|
| 259 |
-
num_sent = self.send(data)
|
| 260 |
-
except OSError:
|
| 261 |
-
self.handle_error()
|
| 262 |
-
return
|
| 263 |
-
|
| 264 |
-
if num_sent:
|
| 265 |
-
if num_sent < len(data) or obs < len(first):
|
| 266 |
-
self.producer_fifo[0] = first[num_sent:]
|
| 267 |
-
else:
|
| 268 |
-
del self.producer_fifo[0]
|
| 269 |
-
# we tried to send some actual data
|
| 270 |
-
return
|
| 271 |
-
|
| 272 |
-
def discard_buffers(self):
|
| 273 |
-
# Emergencies only!
|
| 274 |
-
self.ac_in_buffer = b''
|
| 275 |
-
del self.incoming[:]
|
| 276 |
-
self.producer_fifo.clear()
|
| 277 |
-
|
| 278 |
-
|
| 279 |
-
class simple_producer:
|
| 280 |
-
|
| 281 |
-
def __init__(self, data, buffer_size=512):
|
| 282 |
-
self.data = data
|
| 283 |
-
self.buffer_size = buffer_size
|
| 284 |
-
|
| 285 |
-
def more(self):
|
| 286 |
-
if len(self.data) > self.buffer_size:
|
| 287 |
-
result = self.data[:self.buffer_size]
|
| 288 |
-
self.data = self.data[self.buffer_size:]
|
| 289 |
-
return result
|
| 290 |
-
else:
|
| 291 |
-
result = self.data
|
| 292 |
-
self.data = b''
|
| 293 |
-
return result
|
| 294 |
-
|
| 295 |
-
|
| 296 |
-
# Given 'haystack', see if any prefix of 'needle' is at its end. This
|
| 297 |
-
# assumes an exact match has already been checked. Return the number of
|
| 298 |
-
# characters matched.
|
| 299 |
-
# for example:
|
| 300 |
-
# f_p_a_e("qwerty\r", "\r\n") => 1
|
| 301 |
-
# f_p_a_e("qwertydkjf", "\r\n") => 0
|
| 302 |
-
# f_p_a_e("qwerty\r\n", "\r\n") => <undefined>
|
| 303 |
-
|
| 304 |
-
# this could maybe be made faster with a computed regex?
|
| 305 |
-
# [answer: no; circa Python-2.0, Jan 2001]
|
| 306 |
-
# new python: 28961/s
|
| 307 |
-
# old python: 18307/s
|
| 308 |
-
# re: 12820/s
|
| 309 |
-
# regex: 14035/s
|
| 310 |
-
|
| 311 |
-
def find_prefix_at_end(haystack, needle):
|
| 312 |
-
l = len(needle) - 1
|
| 313 |
-
while l and not haystack.endswith(needle[:l]):
|
| 314 |
-
l -= 1
|
| 315 |
-
return l
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Pytorch/Lib/asyncio/__init__.py
DELETED
|
@@ -1,43 +0,0 @@
|
|
| 1 |
-
"""The asyncio package, tracking PEP 3156."""
|
| 2 |
-
|
| 3 |
-
# flake8: noqa
|
| 4 |
-
|
| 5 |
-
import sys
|
| 6 |
-
|
| 7 |
-
# This relies on each of the submodules having an __all__ variable.
|
| 8 |
-
from .base_events import *
|
| 9 |
-
from .coroutines import *
|
| 10 |
-
from .events import *
|
| 11 |
-
from .exceptions import *
|
| 12 |
-
from .futures import *
|
| 13 |
-
from .locks import *
|
| 14 |
-
from .protocols import *
|
| 15 |
-
from .runners import *
|
| 16 |
-
from .queues import *
|
| 17 |
-
from .streams import *
|
| 18 |
-
from .subprocess import *
|
| 19 |
-
from .tasks import *
|
| 20 |
-
from .threads import *
|
| 21 |
-
from .transports import *
|
| 22 |
-
|
| 23 |
-
__all__ = (base_events.__all__ +
|
| 24 |
-
coroutines.__all__ +
|
| 25 |
-
events.__all__ +
|
| 26 |
-
exceptions.__all__ +
|
| 27 |
-
futures.__all__ +
|
| 28 |
-
locks.__all__ +
|
| 29 |
-
protocols.__all__ +
|
| 30 |
-
runners.__all__ +
|
| 31 |
-
queues.__all__ +
|
| 32 |
-
streams.__all__ +
|
| 33 |
-
subprocess.__all__ +
|
| 34 |
-
tasks.__all__ +
|
| 35 |
-
threads.__all__ +
|
| 36 |
-
transports.__all__)
|
| 37 |
-
|
| 38 |
-
if sys.platform == 'win32': # pragma: no cover
|
| 39 |
-
from .windows_events import *
|
| 40 |
-
__all__ += windows_events.__all__
|
| 41 |
-
else:
|
| 42 |
-
from .unix_events import * # pragma: no cover
|
| 43 |
-
__all__ += unix_events.__all__
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Pytorch/Lib/asyncio/__main__.py
DELETED
|
@@ -1,125 +0,0 @@
|
|
| 1 |
-
import ast
|
| 2 |
-
import asyncio
|
| 3 |
-
import code
|
| 4 |
-
import concurrent.futures
|
| 5 |
-
import inspect
|
| 6 |
-
import sys
|
| 7 |
-
import threading
|
| 8 |
-
import types
|
| 9 |
-
import warnings
|
| 10 |
-
|
| 11 |
-
from . import futures
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
class AsyncIOInteractiveConsole(code.InteractiveConsole):
|
| 15 |
-
|
| 16 |
-
def __init__(self, locals, loop):
|
| 17 |
-
super().__init__(locals)
|
| 18 |
-
self.compile.compiler.flags |= ast.PyCF_ALLOW_TOP_LEVEL_AWAIT
|
| 19 |
-
|
| 20 |
-
self.loop = loop
|
| 21 |
-
|
| 22 |
-
def runcode(self, code):
|
| 23 |
-
future = concurrent.futures.Future()
|
| 24 |
-
|
| 25 |
-
def callback():
|
| 26 |
-
global repl_future
|
| 27 |
-
global repl_future_interrupted
|
| 28 |
-
|
| 29 |
-
repl_future = None
|
| 30 |
-
repl_future_interrupted = False
|
| 31 |
-
|
| 32 |
-
func = types.FunctionType(code, self.locals)
|
| 33 |
-
try:
|
| 34 |
-
coro = func()
|
| 35 |
-
except SystemExit:
|
| 36 |
-
raise
|
| 37 |
-
except KeyboardInterrupt as ex:
|
| 38 |
-
repl_future_interrupted = True
|
| 39 |
-
future.set_exception(ex)
|
| 40 |
-
return
|
| 41 |
-
except BaseException as ex:
|
| 42 |
-
future.set_exception(ex)
|
| 43 |
-
return
|
| 44 |
-
|
| 45 |
-
if not inspect.iscoroutine(coro):
|
| 46 |
-
future.set_result(coro)
|
| 47 |
-
return
|
| 48 |
-
|
| 49 |
-
try:
|
| 50 |
-
repl_future = self.loop.create_task(coro)
|
| 51 |
-
futures._chain_future(repl_future, future)
|
| 52 |
-
except BaseException as exc:
|
| 53 |
-
future.set_exception(exc)
|
| 54 |
-
|
| 55 |
-
loop.call_soon_threadsafe(callback)
|
| 56 |
-
|
| 57 |
-
try:
|
| 58 |
-
return future.result()
|
| 59 |
-
except SystemExit:
|
| 60 |
-
raise
|
| 61 |
-
except BaseException:
|
| 62 |
-
if repl_future_interrupted:
|
| 63 |
-
self.write("\nKeyboardInterrupt\n")
|
| 64 |
-
else:
|
| 65 |
-
self.showtraceback()
|
| 66 |
-
|
| 67 |
-
|
| 68 |
-
class REPLThread(threading.Thread):
|
| 69 |
-
|
| 70 |
-
def run(self):
|
| 71 |
-
try:
|
| 72 |
-
banner = (
|
| 73 |
-
f'asyncio REPL {sys.version} on {sys.platform}\n'
|
| 74 |
-
f'Use "await" directly instead of "asyncio.run()".\n'
|
| 75 |
-
f'Type "help", "copyright", "credits" or "license" '
|
| 76 |
-
f'for more information.\n'
|
| 77 |
-
f'{getattr(sys, "ps1", ">>> ")}import asyncio'
|
| 78 |
-
)
|
| 79 |
-
|
| 80 |
-
console.interact(
|
| 81 |
-
banner=banner,
|
| 82 |
-
exitmsg='exiting asyncio REPL...')
|
| 83 |
-
finally:
|
| 84 |
-
warnings.filterwarnings(
|
| 85 |
-
'ignore',
|
| 86 |
-
message=r'^coroutine .* was never awaited$',
|
| 87 |
-
category=RuntimeWarning)
|
| 88 |
-
|
| 89 |
-
loop.call_soon_threadsafe(loop.stop)
|
| 90 |
-
|
| 91 |
-
|
| 92 |
-
if __name__ == '__main__':
|
| 93 |
-
loop = asyncio.new_event_loop()
|
| 94 |
-
asyncio.set_event_loop(loop)
|
| 95 |
-
|
| 96 |
-
repl_locals = {'asyncio': asyncio}
|
| 97 |
-
for key in {'__name__', '__package__',
|
| 98 |
-
'__loader__', '__spec__',
|
| 99 |
-
'__builtins__', '__file__'}:
|
| 100 |
-
repl_locals[key] = locals()[key]
|
| 101 |
-
|
| 102 |
-
console = AsyncIOInteractiveConsole(repl_locals, loop)
|
| 103 |
-
|
| 104 |
-
repl_future = None
|
| 105 |
-
repl_future_interrupted = False
|
| 106 |
-
|
| 107 |
-
try:
|
| 108 |
-
import readline # NoQA
|
| 109 |
-
except ImportError:
|
| 110 |
-
pass
|
| 111 |
-
|
| 112 |
-
repl_thread = REPLThread()
|
| 113 |
-
repl_thread.daemon = True
|
| 114 |
-
repl_thread.start()
|
| 115 |
-
|
| 116 |
-
while True:
|
| 117 |
-
try:
|
| 118 |
-
loop.run_forever()
|
| 119 |
-
except KeyboardInterrupt:
|
| 120 |
-
if repl_future and not repl_future.done():
|
| 121 |
-
repl_future.cancel()
|
| 122 |
-
repl_future_interrupted = True
|
| 123 |
-
continue
|
| 124 |
-
else:
|
| 125 |
-
break
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Pytorch/Lib/asyncio/__pycache__/__init__.cpython-310.pyc
DELETED
|
Binary file (728 Bytes)
|
|
|
Pytorch/Lib/asyncio/__pycache__/__main__.cpython-310.pyc
DELETED
|
Binary file (3.16 kB)
|
|
|
Pytorch/Lib/asyncio/__pycache__/base_events.cpython-310.pyc
DELETED
|
Binary file (51.8 kB)
|
|
|
Pytorch/Lib/asyncio/__pycache__/base_futures.cpython-310.pyc
DELETED
|
Binary file (1.9 kB)
|
|
|
Pytorch/Lib/asyncio/__pycache__/base_subprocess.cpython-310.pyc
DELETED
|
Binary file (9.37 kB)
|
|
|
Pytorch/Lib/asyncio/__pycache__/base_tasks.cpython-310.pyc
DELETED
|
Binary file (1.97 kB)
|
|
|
Pytorch/Lib/asyncio/__pycache__/constants.cpython-310.pyc
DELETED
|
Binary file (570 Bytes)
|
|
|
Pytorch/Lib/asyncio/__pycache__/coroutines.cpython-310.pyc
DELETED
|
Binary file (6.61 kB)
|
|
|