diff --git a/.gitattributes b/.gitattributes index f6e0b2c7ad5a6e7a9642e18fe0592ff0429916a1..4a86f35e0f043e9a55a836ca9d3619325339334d 100644 --- a/.gitattributes +++ b/.gitattributes @@ -180,3 +180,6 @@ my_container_sandbox/workspace/anaconda3/pkgs/certifi-2024.2.2-pyhd8ed1ab_0.cond my_container_sandbox/workspace/anaconda3/pkgs/sqlite-3.41.2-h5eee18b_0.conda filter=lfs diff=lfs merge=lfs -text my_container_sandbox/workspace/anaconda3/pkgs/brotlipy-0.7.0-py39h27cfd23_1003.conda filter=lfs diff=lfs merge=lfs -text my_container_sandbox/workspace/anaconda3/pkgs/xz-5.2.5-h7b6447c_0.conda filter=lfs diff=lfs merge=lfs -text +my_container_sandbox/workspace/anaconda3/lib/libnvvm.so.4 filter=lfs diff=lfs merge=lfs -text +my_container_sandbox/workspace/anaconda3/pkgs/xz-5.4.6-h5eee18b_0.conda filter=lfs diff=lfs merge=lfs -text +my_container_sandbox/workspace/anaconda3/pkgs/libgomp-9.3.0-h5101ec6_17.conda filter=lfs diff=lfs merge=lfs -text diff --git a/my_container_sandbox/workspace/anaconda3/lib/libnvvm.so.4 b/my_container_sandbox/workspace/anaconda3/lib/libnvvm.so.4 new file mode 100644 index 0000000000000000000000000000000000000000..f302c97afef1282496ab97b3548370dfac09fcb8 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/libnvvm.so.4 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f0c95d249f3d60d67dbd191174fe1d8b9f393b1887ae1a54b4988823c7e42a31 +size 26650200 diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/GitPython-3.1.27.dist-info/AUTHORS b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/GitPython-3.1.27.dist-info/AUTHORS new file mode 100644 index 0000000000000000000000000000000000000000..55d6818130a9031aed0cc8d58fd1a751f38dc3c6 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/GitPython-3.1.27.dist-info/AUTHORS @@ -0,0 +1,48 @@ +GitPython was originally written by Michael Trier. +GitPython 0.2 was partially (re)written by Sebastian Thiel, based on 0.1.6 and git-dulwich. + +Contributors are: + +-Michael Trier +-Alan Briolat +-Florian Apolloner +-David Aguilar +-Jelmer Vernooij +-Steve Frécinaux +-Kai Lautaportti +-Paul Sowden +-Sebastian Thiel +-Jonathan Chu +-Vincent Driessen +-Phil Elson +-Bernard `Guyzmo` Pratz +-Timothy B. Hartman +-Konstantin Popov +-Peter Jones +-Anson Mansfield +-Ken Odegard +-Alexis Horgix Chotard +-Piotr Babij +-Mikuláš Poul +-Charles Bouchard-Légaré +-Yaroslav Halchenko +-Tim Swast +-William Luc Ritchie +-David Host +-A. Jesse Jiryu Davis +-Steven Whitman +-Stefan Stancu +-César Izurieta +-Arthur Milchior +-Anil Khatri +-JJ Graham +-Ben Thayer +-Dries Kennes +-Pratik Anurag +-Harmon +-Liam Beguin +-Ram Rachum +-Alba Mendez +-Robert Westman +-Hugo van Kemenade +Portions derived from other open source works and are clearly marked. diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/GitPython-3.1.27.dist-info/INSTALLER b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/GitPython-3.1.27.dist-info/INSTALLER new file mode 100644 index 0000000000000000000000000000000000000000..a1b589e38a32041e49332e5e81c2d363dc418d68 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/GitPython-3.1.27.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/GitPython-3.1.27.dist-info/LICENSE b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/GitPython-3.1.27.dist-info/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..5a9a6f8d38374103fa5aa601b4dd4814b01f0727 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/GitPython-3.1.27.dist-info/LICENSE @@ -0,0 +1,30 @@ +Copyright (C) 2008, 2009 Michael Trier and contributors +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +* Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +* Neither the name of the GitPython project nor the names of +its contributors may be used to endorse or promote products derived +from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/GitPython-3.1.27.dist-info/METADATA b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/GitPython-3.1.27.dist-info/METADATA new file mode 100644 index 0000000000000000000000000000000000000000..8a04eba10c5539302cdc91e5118a5b8bab738a9f --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/GitPython-3.1.27.dist-info/METADATA @@ -0,0 +1,33 @@ +Metadata-Version: 2.1 +Name: GitPython +Version: 3.1.27 +Summary: GitPython is a python library used to interact with Git repositories +Home-page: https://github.com/gitpython-developers/GitPython +Author: Sebastian Thiel, Michael Trier +Author-email: byronimo@gmail.com, mtrier@gmail.com +License: BSD +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Environment :: Console +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: BSD License +Classifier: Operating System :: OS Independent +Classifier: Operating System :: POSIX +Classifier: Operating System :: Microsoft :: Windows +Classifier: Operating System :: MacOS :: MacOS X +Classifier: Typing :: Typed +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Requires-Python: >=3.7 +Description-Content-Type: text/markdown +License-File: LICENSE +License-File: AUTHORS +Requires-Dist: gitdb (<5,>=4.0.1) +Requires-Dist: typing-extensions (>=3.7.4.3) ; python_version < "3.8" + +GitPython is a python library used to interact with Git repositories + diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/GitPython-3.1.27.dist-info/RECORD b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/GitPython-3.1.27.dist-info/RECORD new file mode 100644 index 0000000000000000000000000000000000000000..a4993533b553aeacdd1d2c2d4523f7e2347292ca --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/GitPython-3.1.27.dist-info/RECORD @@ -0,0 +1,83 @@ +GitPython-3.1.27.dist-info/AUTHORS,sha256=vjnd09wZL3p1v8gB5lsk4nj-2nDyHcZEzY_MKrZQyco,1936 +GitPython-3.1.27.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +GitPython-3.1.27.dist-info/LICENSE,sha256=_WV__CzvY9JceMq3gI1BTdA6KC5jiTSR_RHDL5i-Z_s,1521 +GitPython-3.1.27.dist-info/METADATA,sha256=h9Z-ZVEP5r7UES4v0wOH-dyhekIRG0qBBg_7VX5zAFc,1289 +GitPython-3.1.27.dist-info/RECORD,, +GitPython-3.1.27.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +GitPython-3.1.27.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92 +GitPython-3.1.27.dist-info/top_level.txt,sha256=0hzDuIp8obv624V3GmbqsagBWkk8ohtGU-Bc1PmTT0o,4 +git/__init__.py,sha256=LIqmpO0UYXoia_6ymWif0fdDpVN1apyh-yuzD1Qmkog,2500 +git/__pycache__/__init__.cpython-38.pyc,, +git/__pycache__/cmd.cpython-38.pyc,, +git/__pycache__/compat.cpython-38.pyc,, +git/__pycache__/config.cpython-38.pyc,, +git/__pycache__/db.cpython-38.pyc,, +git/__pycache__/diff.cpython-38.pyc,, +git/__pycache__/exc.cpython-38.pyc,, +git/__pycache__/remote.cpython-38.pyc,, +git/__pycache__/types.cpython-38.pyc,, +git/__pycache__/util.cpython-38.pyc,, +git/cmd.py,sha256=8QI5KptzHzAEGzfMg2FtQrPaggMAzv_YKwF4-rGhJRI,51897 +git/compat.py,sha256=A__j0NDexK9vm-IP59CveY7V_Epef9Km4wH94nykvGs,2244 +git/config.py,sha256=ABfTzzFy82NkwTKHreMbJF78JC43dAR385LbrUhnc84,34506 +git/db.py,sha256=Ji8Zrdq5Gvo3Hm54gBB7DXFYJE0SgPmoHyAp_5RI3s0,2255 +git/diff.py,sha256=nzQ2ZtSFrvcpgTvKBKlheLLZGdLgmW3xbwjaZQtaJBQ,22587 +git/exc.py,sha256=rtiF2l2ZONIih_yF3DZ_WuDXAocdq0inhjQzGJq5T7o,6079 +git/index/__init__.py,sha256=43ovvVNocVRNiQd4fLqvUMuGGmwhBQ9SsiQ46vkvk1E,89 +git/index/__pycache__/__init__.cpython-38.pyc,, +git/index/__pycache__/base.cpython-38.pyc,, +git/index/__pycache__/fun.cpython-38.pyc,, +git/index/__pycache__/typ.cpython-38.pyc,, +git/index/__pycache__/util.cpython-38.pyc,, +git/index/base.py,sha256=-MV0W-PyJwCYxFb-Klbooaay3uDm-sr8xHAiK_4lXaU,57001 +git/index/fun.py,sha256=Ac9zLk2JAnayb4Gl9QpJ8S2CzNqWDfxFhZT2S9bhWX8,16431 +git/index/typ.py,sha256=8-yL3QhdHXkVaDHfUuk4Kmks1Comrq547Kg48m6H2gA,5516 +git/index/util.py,sha256=t3llCo90s1L_OgPYIqah5AuVU6043XKTaQrmJtUeYjU,3454 +git/objects/__init__.py,sha256=1uMoWicK_mgiQIaikCMsX7uiRWc9US4XUXCouSmH4Dk,703 +git/objects/__pycache__/__init__.cpython-38.pyc,, +git/objects/__pycache__/base.cpython-38.pyc,, +git/objects/__pycache__/blob.cpython-38.pyc,, +git/objects/__pycache__/commit.cpython-38.pyc,, +git/objects/__pycache__/fun.cpython-38.pyc,, +git/objects/__pycache__/tag.cpython-38.pyc,, +git/objects/__pycache__/tree.cpython-38.pyc,, +git/objects/__pycache__/util.cpython-38.pyc,, +git/objects/base.py,sha256=qLgh-OStkOke3yKgwq2ZNFTC45Qsl1UTSI1-fdjR8-w,7759 +git/objects/blob.py,sha256=nXCRt885vuNjI6VRw_fXOZSgQfD9PjXPg3XZIRZkIfM,987 +git/objects/commit.py,sha256=-dXHQvop5HXIqQjuMYIFMNLL2AY9y0a7Gw3ayG8OAHY,25869 +git/objects/fun.py,sha256=vSmm8p4_6ZMOh3Vtwbi65gP1vIFczXF2hXtgHclP-EY,8542 +git/objects/submodule/__init__.py,sha256=OsMeiex7cG6ev2f35IaJ5csH-eXchSoNKCt4HXUG5Ws,93 +git/objects/submodule/__pycache__/__init__.cpython-38.pyc,, +git/objects/submodule/__pycache__/base.cpython-38.pyc,, +git/objects/submodule/__pycache__/root.cpython-38.pyc,, +git/objects/submodule/__pycache__/util.cpython-38.pyc,, +git/objects/submodule/base.py,sha256=QOZfeU4mQVyGFLKGWS8YTRD8DtN_lVjhtPsw6N9Upqs,58774 +git/objects/submodule/root.py,sha256=cy7wRBLJwqNXGm6bK0tgEucYX7lx-KNQS-WTTlEXvig,18288 +git/objects/submodule/util.py,sha256=iX1EYGDhVrr1PG8729zQPm2GL47FkE9MPqPYC8C_h-o,3358 +git/objects/tag.py,sha256=mqlDG5UyScqHEnwDXRBPwbMcPrTZnhMiezpDM7DkEss,3764 +git/objects/tree.py,sha256=ly7fgePvItjB-B69AvdlFXrekH8MixOMauO31sCpg7E,14292 +git/objects/util.py,sha256=gx1jzp1oiqdlADrWu6oorIF3FwXJZtaprzxPlyY9u8I,22466 +git/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +git/refs/__init__.py,sha256=PMF97jMUcivbCCEJnl2zTs-YtECNFp8rL8GHK8AitXU,203 +git/refs/__pycache__/__init__.cpython-38.pyc,, +git/refs/__pycache__/head.cpython-38.pyc,, +git/refs/__pycache__/log.cpython-38.pyc,, +git/refs/__pycache__/reference.cpython-38.pyc,, +git/refs/__pycache__/remote.cpython-38.pyc,, +git/refs/__pycache__/symbolic.cpython-38.pyc,, +git/refs/__pycache__/tag.cpython-38.pyc,, +git/refs/head.py,sha256=UbIuWCb9WI87DZY6puX92YaHLDnh-D6DkONwDjyxcvM,9626 +git/refs/log.py,sha256=8ZTiE7KV4SVAlx14xR7xVG1uh_jFgsSNZ_6QSMh4vpA,12061 +git/refs/reference.py,sha256=28aB_lnYLKIXx2wvy_y87P0EDIuNiCsGLgBmV-29qP0,5405 +git/refs/remote.py,sha256=3iSjMHPlQCUA3QacJ-CHK60yihCmGeyVnuTh-zTq7qo,2556 +git/refs/symbolic.py,sha256=nBmwXAK48w-vmFq-tAl40XlemKsPxiu7aDnyctlWA5o,29739 +git/refs/tag.py,sha256=xboM_oFCFXakpZvvb-bn4GgLcsddPvNIuEK9E3gNuNs,4273 +git/remote.py,sha256=VohJ7s27AC0RCP8EgG-_oMjTE1nxOqnQTHSulhqglnY,41704 +git/repo/__init__.py,sha256=XMpdeowJRtTEd80jAcrKSQfMu2JZGMfPlpuIYHG2ZCk,80 +git/repo/__pycache__/__init__.cpython-38.pyc,, +git/repo/__pycache__/base.cpython-38.pyc,, +git/repo/__pycache__/fun.cpython-38.pyc,, +git/repo/base.py,sha256=mF3lmjtg81KQfst2RZad290fp-bwsEG28dEh7NYkmf0,51847 +git/repo/fun.py,sha256=yjsY_sna6XaUzB0ZANiIMwu97QMxWAWpWtoj4pynqg4,12713 +git/types.py,sha256=L9yBmFn6XUdV9BJgnKSwXPcYEPj9mACl7VuIi7FcNQ8,3072 +git/util.py,sha256=AAebYTIADbA46Iu5rsUqCvCPAM2w-PlbMp2-sm6Wdok,39531 diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/GitPython-3.1.27.dist-info/REQUESTED b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/GitPython-3.1.27.dist-info/REQUESTED new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/GitPython-3.1.27.dist-info/WHEEL b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/GitPython-3.1.27.dist-info/WHEEL new file mode 100644 index 0000000000000000000000000000000000000000..becc9a66ea739ba941d48a749e248761cc6e658a --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/GitPython-3.1.27.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.37.1) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/GitPython-3.1.27.dist-info/top_level.txt b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/GitPython-3.1.27.dist-info/top_level.txt new file mode 100644 index 0000000000000000000000000000000000000000..5664e303b5dc2e9ef8e14a0845d9486ec1920afd --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/GitPython-3.1.27.dist-info/top_level.txt @@ -0,0 +1 @@ +git diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/accelerate-0.11.0.dist-info/INSTALLER b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/accelerate-0.11.0.dist-info/INSTALLER new file mode 100644 index 0000000000000000000000000000000000000000..a1b589e38a32041e49332e5e81c2d363dc418d68 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/accelerate-0.11.0.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/accelerate-0.11.0.dist-info/LICENSE b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/accelerate-0.11.0.dist-info/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..261eeb9e9f8b2b4b0d119366dda99c6fd7d35c64 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/accelerate-0.11.0.dist-info/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/conda_package_handling-2.2.0.dist-info/AUTHORS.md b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/conda_package_handling-2.2.0.dist-info/AUTHORS.md new file mode 100644 index 0000000000000000000000000000000000000000..34009313a8fc489d088209577df126cde1244b98 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/conda_package_handling-2.2.0.dist-info/AUTHORS.md @@ -0,0 +1,24 @@ +All of the people who have made at least one contribution to conda-package-handling. +Authors are sorted alphabetically. + +* Alan Du +* Cheng H. Lee +* Chris Burr +* Christopher Barber +* Conda Bot +* Daniel Bast +* Daniel Holth +* Eli Uriegas +* Jannis Leidel +* John Lee +* Jonathan J. Helmus +* Ken Odegard +* Marius van Niekerk +* Matthew R. Becker +* Michael Sarahan +* Nehal J Wani +* Pure Software +* Ray Donnelly +* Tobias "Tobi" Koch +* Vadim Zayakin +* pre-commit-ci[bot] diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/conda_package_handling-2.2.0.dist-info/INSTALLER b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/conda_package_handling-2.2.0.dist-info/INSTALLER new file mode 100644 index 0000000000000000000000000000000000000000..f79e4cb9aaf0b2d9e8ba78861e2071317b2384b3 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/conda_package_handling-2.2.0.dist-info/INSTALLER @@ -0,0 +1 @@ +conda \ No newline at end of file diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/conda_package_handling-2.2.0.dist-info/LICENSE b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/conda_package_handling-2.2.0.dist-info/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..eb2f3f5caf1ffbd7a91b22c6a757ab1f31616621 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/conda_package_handling-2.2.0.dist-info/LICENSE @@ -0,0 +1,29 @@ +BSD 3-Clause License + +Copyright (c) 2019, Conda +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/conda_package_handling-2.2.0.dist-info/METADATA b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/conda_package_handling-2.2.0.dist-info/METADATA new file mode 100644 index 0000000000000000000000000000000000000000..84a33d4dbafe5cec7ea8e983c27416b84b8e70b5 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/conda_package_handling-2.2.0.dist-info/METADATA @@ -0,0 +1,42 @@ +Metadata-Version: 2.1 +Name: conda-package-handling +Version: 2.2.0 +Summary: Create and extract conda packages of various formats. +Home-page: https://github.com/conda/conda-package-handling +Author: Anaconda, Inc. +Author-email: conda@anaconda.com +Keywords: conda-package-handling +Classifier: Programming Language :: Python :: 3 +Requires-Python: >=3.7 +Description-Content-Type: text/markdown +License-File: LICENSE +License-File: AUTHORS.md +Requires-Dist: conda-package-streaming (>=0.9.0) +Provides-Extra: docs +Requires-Dist: furo ; extra == 'docs' +Requires-Dist: sphinx ; extra == 'docs' +Requires-Dist: sphinx-argparse ; extra == 'docs' +Requires-Dist: myst-parser ; extra == 'docs' +Requires-Dist: mdit-py-plugins (>=0.3.0) ; extra == 'docs' +Provides-Extra: test +Requires-Dist: mock ; extra == 'test' +Requires-Dist: pytest ; extra == 'test' +Requires-Dist: pytest-cov ; extra == 'test' +Requires-Dist: pytest-mock ; extra == 'test' + +# conda-package-handling + +[![pre-commit.ci status](https://results.pre-commit.ci/badge/github/conda/conda-package-handling/main.svg)](https://results.pre-commit.ci/latest/github/conda/conda-package-handling/main) + +Create and extract conda packages of various formats. + +`conda` and `conda-build` use `conda_package_handling.api` to create and extract +conda packages. This package also provides the `cph` command line tool to +extract, create, and convert between formats. + +See also +[conda-package-streaming](https://conda.github.io/conda-package-streaming), an +efficient library to read from new and old format .conda and .tar.bz2 conda +packages. + +Full documentation at [https://conda.github.io/conda-package-handling/](https://conda.github.io/conda-package-handling/) diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/conda_package_handling-2.2.0.dist-info/RECORD b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/conda_package_handling-2.2.0.dist-info/RECORD new file mode 100644 index 0000000000000000000000000000000000000000..097f61b69fa3f93b2e4bb06ef2f2a5c888678be7 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/conda_package_handling-2.2.0.dist-info/RECORD @@ -0,0 +1,33 @@ +../../../bin/cph,sha256=amSbVeIpmd6emwl52Plg8237KxV03oaiIyrlJiUprq4,508 +conda_package_handling-2.2.0.dist-info/AUTHORS.md,sha256=e1PalFDU00a-gtCZU_etkSjXHnlxkpBDiSJjUCCWcW0,460 +conda_package_handling-2.2.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +conda_package_handling-2.2.0.dist-info/LICENSE,sha256=t_7OW5ytYcamhC7Wd2bBOAaL6tOaKVupR0m8szIrXnU,1505 +conda_package_handling-2.2.0.dist-info/METADATA,sha256=a--HjXzY6tdey9RQ6WQryFRW2AItZKrXnEU_eSwsliU,1692 +conda_package_handling-2.2.0.dist-info/RECORD,, +conda_package_handling-2.2.0.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +conda_package_handling-2.2.0.dist-info/WHEEL,sha256=AtBG6SXL3KF_v0NxLf0ehyVOh0cold-JbJYXNGorC6Q,92 +conda_package_handling-2.2.0.dist-info/direct_url.json,sha256=Nvd-PiTlaGzGjht--TbZ0TmVoP4PCheazKelTLI465I,118 +conda_package_handling-2.2.0.dist-info/entry_points.txt,sha256=4gBd7ZOv9v6P3VIiI6veVwgXzKCu_fUiOqwqVb0VTno,56 +conda_package_handling-2.2.0.dist-info/top_level.txt,sha256=3290W3g8MbIyhMS6inC3oTzSzIweY5A2UKk__AZrnSY,23 +conda_package_handling/__init__.py,sha256=DKk-1b-rZsJFxFi1JoJ7TmEvIEQ0rf-C9HAZWwvjuM0,22 +conda_package_handling/__main__.py,sha256=a8OMmLES3Fl3A097Gn8VgCl6qR0b0zL6PON76sjnik8,60 +conda_package_handling/__pycache__/__init__.cpython-311.pyc,, +conda_package_handling/__pycache__/__main__.cpython-311.pyc,, +conda_package_handling/__pycache__/api.cpython-311.pyc,, +conda_package_handling/__pycache__/cli.cpython-311.pyc,, +conda_package_handling/__pycache__/conda_fmt.cpython-311.pyc,, +conda_package_handling/__pycache__/exceptions.cpython-311.pyc,, +conda_package_handling/__pycache__/interface.cpython-311.pyc,, +conda_package_handling/__pycache__/streaming.cpython-311.pyc,, +conda_package_handling/__pycache__/tarball.cpython-311.pyc,, +conda_package_handling/__pycache__/utils.cpython-311.pyc,, +conda_package_handling/__pycache__/validate.cpython-311.pyc,, +conda_package_handling/api.py,sha256=NzZji1JAN8s7L9Mjc5dzqkGmlLmrwMS5NtoaPyNvFuA,7772 +conda_package_handling/cli.py,sha256=Q0cQOjRRXlpZiexJ_E6o_hQuDa7Pc_6x4o3BzglwRts,5083 +conda_package_handling/conda_fmt.py,sha256=av1fRa8QDa5rCQjMCC089odh-OFMnPBtRC0yoH3SQPU,5187 +conda_package_handling/exceptions.py,sha256=Eg2_GsE2oJqpeHvg98YYO6tfHP8Wv0MrV7CS55xRau0,1893 +conda_package_handling/interface.py,sha256=X8nhmM-orw50Fw08OxVIkHOjk7GNI9LFZLVQmcHYo18,613 +conda_package_handling/streaming.py,sha256=RBD9-9FoLGyljQKHxY-KdPsJ8CpIOl1nic-pbd3d8YA,1412 +conda_package_handling/tarball.py,sha256=k2M_KQpOHvnIPT1RhV-cixciIJQbICA8nnGPKkz4HW4,2895 +conda_package_handling/utils.py,sha256=Mg3o4itddHZ-h_q-NerL3_Viw65Jj2_OyWKPf8iV4Ok,16707 +conda_package_handling/validate.py,sha256=48gkidkuUm1JbCxLTh2jbJ4TgMu9tAasltb-UO2R62k,3652 diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/conda_package_handling-2.2.0.dist-info/REQUESTED b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/conda_package_handling-2.2.0.dist-info/REQUESTED new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/conda_package_handling-2.2.0.dist-info/WHEEL b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/conda_package_handling-2.2.0.dist-info/WHEEL new file mode 100644 index 0000000000000000000000000000000000000000..d272f6ed555bf206d2a9572524bfa3c0b500fe8d --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/conda_package_handling-2.2.0.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.41.0) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/conda_package_handling-2.2.0.dist-info/direct_url.json b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/conda_package_handling-2.2.0.dist-info/direct_url.json new file mode 100644 index 0000000000000000000000000000000000000000..694c86b4716fbea89cbe2da8bcd83f1f339f161b --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/conda_package_handling-2.2.0.dist-info/direct_url.json @@ -0,0 +1 @@ +{"dir_info": {}, "url": "file:///home/conda/feedstock_root/build_artifacts/conda-package-handling_1691048088238/work"} \ No newline at end of file diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/conda_package_handling-2.2.0.dist-info/entry_points.txt b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/conda_package_handling-2.2.0.dist-info/entry_points.txt new file mode 100644 index 0000000000000000000000000000000000000000..9fdb1861f943c5c8c0b96afb0e2ea40f88f30649 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/conda_package_handling-2.2.0.dist-info/entry_points.txt @@ -0,0 +1,2 @@ +[console_scripts] +cph = conda_package_handling.cli:main diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/conda_package_handling-2.2.0.dist-info/top_level.txt b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/conda_package_handling-2.2.0.dist-info/top_level.txt new file mode 100644 index 0000000000000000000000000000000000000000..b18d594baf030474c9e1b3a2f0cc4b86c453686b --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/conda_package_handling-2.2.0.dist-info/top_level.txt @@ -0,0 +1 @@ +conda_package_handling diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/humanize/__init__.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/humanize/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..25c0ba19e0769f8b7bcabf7ecddcdc8534a4dcad --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/humanize/__init__.py @@ -0,0 +1,52 @@ +"""Main package for humanize.""" + +from humanize.filesize import naturalsize +from humanize.i18n import activate, deactivate, thousands_separator +from humanize.number import ( + apnumber, + clamp, + fractional, + intcomma, + intword, + metric, + ordinal, + scientific, +) +from humanize.time import ( + naturaldate, + naturalday, + naturaldelta, + naturaltime, + precisedelta, +) + +try: + # Python 3.8+ + import importlib.metadata as importlib_metadata +except ImportError: + # str: + """Format a number of bytes like a human readable filesize (e.g. 10 kB). + + By default, decimal suffixes (kB, MB) are used. + + Non-GNU modes are compatible with jinja2's `filesizeformat` filter. + + Examples: + ```pycon + >>> naturalsize(3000000) + '3.0 MB' + >>> naturalsize(300, False, True) + '300B' + >>> naturalsize(3000, False, True) + '2.9K' + >>> naturalsize(3000, False, True, "%.3f") + '2.930K' + >>> naturalsize(3000, True) + '2.9 KiB' + + ``` + Args: + value (int, float, str): Integer to convert. + binary (bool): If `True`, uses binary suffixes (KiB, MiB) with base + 210 instead of 103. + gnu (bool): If `True`, the binary argument is ignored and GNU-style + (`ls -sh` style) prefixes are used (K, M) with the 2**10 definition. + format (str): Custom formatter. + + Returns: + str: Human readable representation of a filesize. + """ + if gnu: + suffix = suffixes["gnu"] + elif binary: + suffix = suffixes["binary"] + else: + suffix = suffixes["decimal"] + + base = 1024 if (gnu or binary) else 1000 + bytes_ = float(value) + abs_bytes = abs(bytes_) + + if abs_bytes == 1 and not gnu: + return "%d Byte" % bytes_ + elif abs_bytes < base and not gnu: + return "%d Bytes" % bytes_ + elif abs_bytes < base and gnu: + return "%dB" % bytes_ + + for i, s in enumerate(suffix): + unit = base ** (i + 2) + if abs_bytes < unit and not gnu: + return (format + " %s") % ((base * bytes_ / unit), s) + elif abs_bytes < unit and gnu: + return (format + "%s") % ((base * bytes_ / unit), s) + if gnu: + return (format + "%s") % ((base * bytes_ / unit), s) + return (format + " %s") % ((base * bytes_ / unit), s) diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/humanize/i18n.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/humanize/i18n.py new file mode 100644 index 0000000000000000000000000000000000000000..6c95749d52131a213cdbe7a99aec94fe7d157a2a --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/humanize/i18n.py @@ -0,0 +1,174 @@ +"""Activate, get and deactivate translations.""" +from __future__ import annotations + +import gettext as gettext_module +import os.path +from threading import local + +__all__ = ["activate", "deactivate", "thousands_separator"] + +_TRANSLATIONS: dict[str | None, gettext_module.NullTranslations] = { + None: gettext_module.NullTranslations() +} +_CURRENT = local() + + +# Mapping of locale to thousands separator +_THOUSANDS_SEPARATOR = { + "fr_FR": " ", +} + + +def _get_default_locale_path() -> str | None: + try: + if __file__ is None: + return None + return os.path.join(os.path.dirname(__file__), "locale") + except NameError: + return None + + +def get_translation() -> gettext_module.NullTranslations: + try: + return _TRANSLATIONS[_CURRENT.locale] + except (AttributeError, KeyError): + return _TRANSLATIONS[None] + + +def activate(locale: str, path: str | None = None) -> gettext_module.NullTranslations: + """Activate internationalisation. + + Set `locale` as current locale. Search for locale in directory `path`. + + Args: + locale (str): Language name, e.g. `en_GB`. + path (str): Path to search for locales. + + Returns: + dict: Translations. + + Raises: + Exception: If humanize cannot find the locale folder. + """ + if path is None: + path = _get_default_locale_path() + + if path is None: + raise Exception( + "Humanize cannot determinate the default location of the 'locale' folder. " + "You need to pass the path explicitly." + ) + if locale not in _TRANSLATIONS: + translation = gettext_module.translation("humanize", path, [locale]) + _TRANSLATIONS[locale] = translation + _CURRENT.locale = locale + return _TRANSLATIONS[locale] + + +def deactivate() -> None: + """Deactivate internationalisation.""" + _CURRENT.locale = None + + +def _gettext(message: str) -> str: + """Get translation. + + Args: + message (str): Text to translate. + + Returns: + str: Translated text. + """ + return get_translation().gettext(message) + + +def _pgettext(msgctxt: str, message: str) -> str: + """Fetches a particular translation. + + It works with `msgctxt` .po modifiers and allows duplicate keys with different + translations. + + Args: + msgctxt (str): Context of the translation. + message (str): Text to translate. + + Returns: + str: Translated text. + """ + # This GNU gettext function was added in Python 3.8, so for older versions we + # reimplement it. It works by joining `msgctx` and `message` by '4' byte. + try: + # Python 3.8+ + return get_translation().pgettext(msgctxt, message) + except AttributeError: + # Python 3.7 and older + key = msgctxt + "\x04" + message + translation = get_translation().gettext(key) + return message if translation == key else translation + + +def _ngettext(message: str, plural: str, num: int) -> str: + """Plural version of _gettext. + + Args: + message (str): Singular text to translate. + plural (str): Plural text to translate. + num (int): The number (e.g. item count) to determine translation for the + respective grammatical number. + + Returns: + str: Translated text. + """ + return get_translation().ngettext(message, plural, num) + + +def _gettext_noop(message: str) -> str: + """Mark a string as a translation string without translating it. + + Example usage: + ```python + CONSTANTS = [_gettext_noop('first'), _gettext_noop('second')] + def num_name(n): + return _gettext(CONSTANTS[n]) + ``` + + Args: + message (str): Text to translate in the future. + + Returns: + str: Original text, unchanged. + """ + return message + + +def _ngettext_noop(singular: str, plural: str) -> tuple[str, str]: + """Mark two strings as pluralized translations without translating them. + + Example usage: + ```python + CONSTANTS = [ngettext_noop('first', 'firsts'), ngettext_noop('second', 'seconds')] + def num_name(n): + return _ngettext(*CONSTANTS[n]) + ``` + + Args: + singular (str): Singular text to translate in the future. + plural (str): Plural text to translate in the future. + + Returns: + tuple: Original text, unchanged. + """ + return singular, plural + + +def thousands_separator() -> str: + """Return the thousands separator for a locale, default to comma. + + Returns: + str: Thousands separator. + """ + try: + sep = _THOUSANDS_SEPARATOR[_CURRENT.locale] + except (AttributeError, KeyError): + sep = "," + return sep diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/humanize/number.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/humanize/number.py new file mode 100644 index 0000000000000000000000000000000000000000..77475e31c03a86b1c525d1bca7963aaafac1543e --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/humanize/number.py @@ -0,0 +1,516 @@ +#!/usr/bin/env python + +"""Humanizing functions for numbers.""" +from __future__ import annotations + +import math +import re +import sys +from fractions import Fraction +from typing import TYPE_CHECKING + +from .i18n import _gettext as _ +from .i18n import _ngettext +from .i18n import _ngettext_noop as NS_ +from .i18n import _pgettext as P_ +from .i18n import thousands_separator + +if TYPE_CHECKING: + if sys.version_info >= (3, 10): + from typing import TypeAlias + else: + from typing_extensions import TypeAlias + +# This type can be better defined by typing.SupportsInt, typing.SupportsFloat +# but that's a Python 3.8 only typing option. +NumberOrString: TypeAlias = "float | str" + + +def ordinal(value: NumberOrString, gender: str = "male") -> str: + """Converts an integer to its ordinal as a string. + + For example, 1 is "1st", 2 is "2nd", 3 is "3rd", etc. Works for any integer or + anything `int()` will turn into an integer. Anything else will return the output + of str(value). + + Examples: + ```pycon + >>> ordinal(1) + '1st' + >>> ordinal(1002) + '1002nd' + >>> ordinal(103) + '103rd' + >>> ordinal(4) + '4th' + >>> ordinal(12) + '12th' + >>> ordinal(101) + '101st' + >>> ordinal(111) + '111th' + >>> ordinal("something else") + 'something else' + >>> ordinal([1, 2, 3]) == "[1, 2, 3]" + True + + ``` + Args: + value (int, str, float): Integer to convert. + gender (str): Gender for translations. Accepts either "male" or "female". + + Returns: + str: Ordinal string. + """ + try: + value = int(value) + except (TypeError, ValueError): + return str(value) + if gender == "male": + t = ( + P_("0 (male)", "th"), + P_("1 (male)", "st"), + P_("2 (male)", "nd"), + P_("3 (male)", "rd"), + P_("4 (male)", "th"), + P_("5 (male)", "th"), + P_("6 (male)", "th"), + P_("7 (male)", "th"), + P_("8 (male)", "th"), + P_("9 (male)", "th"), + ) + else: + t = ( + P_("0 (female)", "th"), + P_("1 (female)", "st"), + P_("2 (female)", "nd"), + P_("3 (female)", "rd"), + P_("4 (female)", "th"), + P_("5 (female)", "th"), + P_("6 (female)", "th"), + P_("7 (female)", "th"), + P_("8 (female)", "th"), + P_("9 (female)", "th"), + ) + if value % 100 in (11, 12, 13): # special case + return f"{value}{t[0]}" + return f"{value}{t[value % 10]}" + + +def intcomma(value: NumberOrString, ndigits: int | None = None) -> str: + """Converts an integer to a string containing commas every three digits. + + For example, 3000 becomes "3,000" and 45000 becomes "45,000". To maintain some + compatibility with Django's `intcomma`, this function also accepts floats. + + Examples: + ```pycon + >>> intcomma(100) + '100' + >>> intcomma("1000") + '1,000' + >>> intcomma(1_000_000) + '1,000,000' + >>> intcomma(1_234_567.25) + '1,234,567.25' + >>> intcomma(1234.5454545, 2) + '1,234.55' + >>> intcomma(14308.40, 1) + '14,308.4' + >>> intcomma(None) + 'None' + + ``` + Args: + value (int, float, str): Integer or float to convert. + ndigits (int, None): Digits of precision for rounding after the decimal point. + + Returns: + str: String containing commas every three digits. + """ + sep = thousands_separator() + try: + if isinstance(value, str): + float(value.replace(sep, "")) + else: + float(value) + except (TypeError, ValueError): + return str(value) + + if ndigits is not None: + orig = "{0:.{1}f}".format(value, ndigits) + else: + orig = str(value) + + new = re.sub(r"^(-?\d+)(\d{3})", rf"\g<1>{sep}\g<2>", orig) + if orig == new: + return new + else: + return intcomma(new) + + +powers = [10**x for x in (3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 100)] +human_powers = ( + NS_("thousand", "thousand"), + NS_("million", "million"), + NS_("billion", "billion"), + NS_("trillion", "trillion"), + NS_("quadrillion", "quadrillion"), + NS_("quintillion", "quintillion"), + NS_("sextillion", "sextillion"), + NS_("septillion", "septillion"), + NS_("octillion", "octillion"), + NS_("nonillion", "nonillion"), + NS_("decillion", "decillion"), + NS_("googol", "googol"), +) + + +def intword(value: NumberOrString, format: str = "%.1f") -> str: + """Converts a large integer to a friendly text representation. + + Works best for numbers over 1 million. For example, 1_000_000 becomes "1.0 million", + 1200000 becomes "1.2 million" and "1_200_000_000" becomes "1.2 billion". Supports up + to decillion (33 digits) and googol (100 digits). + + Examples: + ```pycon + >>> intword("100") + '100' + >>> intword("12400") + '12.4 thousand' + >>> intword("1000000") + '1.0 million' + >>> intword(1_200_000_000) + '1.2 billion' + >>> intword(8100000000000000000000000000000000) + '8.1 decillion' + >>> intword(None) + 'None' + >>> intword("1234000", "%0.3f") + '1.234 million' + + ``` + Args: + value (int, float, str): Integer to convert. + format (str): To change the number of decimal or general format of the number + portion. + + Returns: + str: Friendly text representation as a string, unless the value passed could not + be coaxed into an `int`. + """ + try: + value = int(value) + except (TypeError, ValueError): + return str(value) + + if value < powers[0]: + return str(value) + for ordinal, power in enumerate(powers[1:], 1): + if value < power: + chopped = value / float(powers[ordinal - 1]) + if float(format % chopped) == float(10**3): + chopped = value / float(powers[ordinal]) + singular, plural = human_powers[ordinal] + return ( + " ".join([format, _ngettext(singular, plural, math.ceil(chopped))]) + ) % chopped + else: + singular, plural = human_powers[ordinal - 1] + return ( + " ".join([format, _ngettext(singular, plural, math.ceil(chopped))]) + ) % chopped + return str(value) + + +def apnumber(value: NumberOrString) -> str: + """Converts an integer to Associated Press style. + + Examples: + ```pycon + >>> apnumber(0) + 'zero' + >>> apnumber(5) + 'five' + >>> apnumber(10) + '10' + >>> apnumber("7") + 'seven' + >>> apnumber("foo") + 'foo' + >>> apnumber(None) + 'None' + + ``` + Args: + value (int, float, str): Integer to convert. + + Returns: + str: For numbers 0-9, the number spelled out. Otherwise, the number. This always + returns a string unless the value was not `int`-able, then `str(value)` + is returned. + """ + try: + value = int(value) + except (TypeError, ValueError): + return str(value) + if not 0 <= value < 10: + return str(value) + return ( + _("zero"), + _("one"), + _("two"), + _("three"), + _("four"), + _("five"), + _("six"), + _("seven"), + _("eight"), + _("nine"), + )[value] + + +def fractional(value: NumberOrString) -> str: + """Convert to fractional number. + + There will be some cases where one might not want to show ugly decimal places for + floats and decimals. + + This function returns a human-readable fractional number in form of fractions and + mixed fractions. + + Pass in a string, or a number or a float, and this function returns: + + * a string representation of a fraction + * or a whole number + * or a mixed fraction + * or the str output of the value, if it could not be converted + + Examples: + ```pycon + >>> fractional(0.3) + '3/10' + >>> fractional(1.3) + '1 3/10' + >>> fractional(float(1/3)) + '1/3' + >>> fractional(1) + '1' + >>> fractional("ten") + 'ten' + >>> fractional(None) + 'None' + + ``` + Args: + value (int, float, str): Integer to convert. + + Returns: + str: Fractional number as a string. + """ + try: + number = float(value) + except (TypeError, ValueError): + return str(value) + whole_number = int(number) + frac = Fraction(number - whole_number).limit_denominator(1000) + numerator = frac.numerator + denominator = frac.denominator + if whole_number and not numerator and denominator == 1: + # this means that an integer was passed in + # (or variants of that integer like 1.0000) + return f"{whole_number:.0f}" + elif not whole_number: + return f"{numerator:.0f}/{denominator:.0f}" + else: + return f"{whole_number:.0f} {numerator:.0f}/{denominator:.0f}" + + +def scientific(value: NumberOrString, precision: int = 2) -> str: + """Return number in string scientific notation z.wq x 10ⁿ. + + Examples: + ```pycon + >>> scientific(float(0.3)) + '3.00 x 10⁻¹' + >>> scientific(int(500)) + '5.00 x 10²' + >>> scientific(-1000) + '-1.00 x 10³' + >>> scientific(1000, 1) + '1.0 x 10³' + >>> scientific(1000, 3) + '1.000 x 10³' + >>> scientific("99") + '9.90 x 10¹' + >>> scientific("foo") + 'foo' + >>> scientific(None) + 'None' + + ``` + + Args: + value (int, float, str): Input number. + precision (int): Number of decimal for first part of the number. + + Returns: + str: Number in scientific notation z.wq x 10ⁿ. + """ + exponents = { + "0": "⁰", + "1": "¹", + "2": "²", + "3": "³", + "4": "⁴", + "5": "⁵", + "6": "⁶", + "7": "⁷", + "8": "⁸", + "9": "⁹", + "-": "⁻", + } + try: + value = float(value) + except (ValueError, TypeError): + return str(value) + fmt = "{:.%se}" % str(int(precision)) + n = fmt.format(value) + part1, part2 = n.split("e") + # Remove redundant leading '+' or '0's (preserving the last '0' for 10⁰). + part2 = re.sub(r"^\+?(\-?)0*(.+)$", r"\1\2", part2) + + new_part2 = [] + for char in part2: + new_part2.append(exponents[char]) + + final_str = part1 + " x 10" + "".join(new_part2) + + return final_str + + +def clamp( + value: float, + format: str = "{:}", + floor: float | None = None, + ceil: float | None = None, + floor_token: str = "<", + ceil_token: str = ">", +) -> str: + """Returns number with the specified format, clamped between floor and ceil. + + If the number is larger than ceil or smaller than floor, then the respective limit + will be returned, formatted and prepended with a token specifying as such. + + Examples: + ```pycon + >>> clamp(123.456) + '123.456' + >>> clamp(0.0001, floor=0.01) + '<0.01' + >>> clamp(0.99, format="{:.0%}", ceil=0.99) + '99%' + >>> clamp(0.999, format="{:.0%}", ceil=0.99) + '>99%' + >>> clamp(1, format=intword, floor=1e6, floor_token="under ") + 'under 1.0 million' + >>> clamp(None) is None + True + + ``` + + Args: + value (int, float): Input number. + format (str OR callable): Can either be a formatting string, or a callable + function that receives value and returns a string. + floor (int, float): Smallest value before clamping. + ceil (int, float): Largest value before clamping. + floor_token (str): If value is smaller than floor, token will be prepended + to output. + ceil_token (str): If value is larger than ceil, token will be prepended + to output. + + Returns: + str: Formatted number. The output is clamped between the indicated floor and + ceil. If the number is larger than ceil or smaller than floor, the output will + be prepended with a token indicating as such. + + """ + if value is None: + return None + + if floor is not None and value < floor: + value = floor + token = floor_token + elif ceil is not None and value > ceil: + value = ceil + token = ceil_token + else: + token = "" + + if isinstance(format, str): + return token + format.format(value) + elif callable(format): + return token + format(value) + else: + raise ValueError( + "Invalid format. Must be either a valid formatting string, or a function " + "that accepts value and returns a string." + ) + + +def metric(value: float, unit: str = "", precision: int = 3) -> str: + """Return a value with a metric SI unit-prefix appended. + + Examples: + ```pycon + >>> metric(1500, "V") + '1.50 kV' + >>> metric(2e8, "W") + '200 MW' + >>> metric(220e-6, "F") + '220 μF' + >>> metric(1e-14, precision=4) + '10.00 f' + + ``` + + The unit prefix is always chosen so that non-significant zero digits are required. + i.e. `123,000` will become `123k` instead of `0.123M` and `1,230,000` will become + `1.23M` instead of `1230K`. For numbers that are either too huge or too tiny to + represent without resorting to either leading or trailing zeroes, it falls back to + `scientific()`. + ```pycon + >>> metric(1e40) + '1.00 x 10⁴⁰' + + ``` + + Args: + value (int, float): Input number. + unit (str): Optional base unit. + precision (int): The number of digits the output should contain. + + Returns: + str: + """ + exponent = int(math.floor(math.log10(abs(value)))) + + if exponent >= 27 or exponent < -24: + return scientific(value, precision - 1) + unit + + value /= 10 ** (exponent // 3 * 3) + if exponent >= 3: + ordinal = "kMGTPEZY"[exponent // 3 - 1] + elif exponent < 0: + ordinal = "mμnpfazy"[(-exponent - 1) // 3] + else: + ordinal = "" + value_ = format(value, ".%if" % (precision - (exponent % 3) - 1)) + if not (unit or ordinal) or unit in ("°", "′", "″"): + space = "" + else: + space = " " + + return f"{value_}{space}{ordinal}{unit}" diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/humanize/py.typed b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/humanize/py.typed new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/humanize/time.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/humanize/time.py new file mode 100644 index 0000000000000000000000000000000000000000..755009030945f5a18073016144814fafa90e4b4b --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/humanize/time.py @@ -0,0 +1,580 @@ +#!/usr/bin/env python + +"""Time humanizing functions. + +These are largely borrowed from Django's `contrib.humanize`. +""" +from __future__ import annotations + +import collections.abc +import datetime as dt +import math +import typing +from enum import Enum +from functools import total_ordering + +from .i18n import _gettext as _ +from .i18n import _ngettext +from .number import intcomma + +__all__ = [ + "naturaldelta", + "naturaltime", + "naturalday", + "naturaldate", + "precisedelta", +] + + +@total_ordering +class Unit(Enum): + MICROSECONDS = 0 + MILLISECONDS = 1 + SECONDS = 2 + MINUTES = 3 + HOURS = 4 + DAYS = 5 + MONTHS = 6 + YEARS = 7 + + def __lt__(self, other: typing.Any) -> typing.Any: + if self.__class__ is other.__class__: + return self.value < other.value + return NotImplemented + + +def _now() -> dt.datetime: + return dt.datetime.now() + + +def _abs_timedelta(delta: dt.timedelta) -> dt.timedelta: + """Return an "absolute" value for a timedelta, always representing a time distance. + + Args: + delta (datetime.timedelta): Input timedelta. + + Returns: + datetime.timedelta: Absolute timedelta. + """ + if delta.days < 0: + now = _now() + return now - (now + delta) + return delta + + +def _date_and_delta( + value: typing.Any, *, now: dt.datetime | None = None +) -> tuple[typing.Any, typing.Any]: + """Turn a value into a date and a timedelta which represents how long ago it was. + + If that's not possible, return `(None, value)`. + """ + if not now: + now = _now() + if isinstance(value, dt.datetime): + date = value + delta = now - value + elif isinstance(value, dt.timedelta): + date = now - value + delta = value + else: + try: + value = int(value) + delta = dt.timedelta(seconds=value) + date = now - delta + except (ValueError, TypeError): + return None, value + return date, _abs_timedelta(delta) + + +def naturaldelta( + value: dt.timedelta | float, + months: bool = True, + minimum_unit: str = "seconds", +) -> str: + """Return a natural representation of a timedelta or number of seconds. + + This is similar to `naturaltime`, but does not add tense to the result. + + Args: + value (datetime.timedelta, int or float): A timedelta or a number of seconds. + months (bool): If `True`, then a number of months (based on 30.5 days) will be + used for fuzziness between years. + minimum_unit (str): The lowest unit that can be used. + + Returns: + str (str or `value`): A natural representation of the amount of time + elapsed unless `value` is not datetime.timedelta or cannot be + converted to int. In that case, a `value` is returned unchanged. + + Raises: + OverflowError: If `value` is too large to convert to datetime.timedelta. + + Examples + Compare two timestamps in a custom local timezone:: + + import datetime as dt + from dateutil.tz import gettz + + berlin = gettz("Europe/Berlin") + now = dt.datetime.now(tz=berlin) + later = now + dt.timedelta(minutes=30) + + assert naturaldelta(later - now) == "30 minutes" + """ + tmp = Unit[minimum_unit.upper()] + if tmp not in (Unit.SECONDS, Unit.MILLISECONDS, Unit.MICROSECONDS): + raise ValueError(f"Minimum unit '{minimum_unit}' not supported") + min_unit = tmp + + if isinstance(value, dt.timedelta): + delta = value + else: + try: + value = int(value) + delta = dt.timedelta(seconds=value) + except (ValueError, TypeError): + return str(value) + + use_months = months + + seconds = abs(delta.seconds) + days = abs(delta.days) + years = days // 365 + days = days % 365 + num_months = int(days // 30.5) + + if not years and days < 1: + if seconds == 0: + if min_unit == Unit.MICROSECONDS and delta.microseconds < 1000: + return ( + _ngettext("%d microsecond", "%d microseconds", delta.microseconds) + % delta.microseconds + ) + elif min_unit == Unit.MILLISECONDS or ( + min_unit == Unit.MICROSECONDS and 1000 <= delta.microseconds < 1_000_000 + ): + milliseconds = delta.microseconds / 1000 + return ( + _ngettext("%d millisecond", "%d milliseconds", int(milliseconds)) + % milliseconds + ) + return _("a moment") + elif seconds == 1: + return _("a second") + elif seconds < 60: + return _ngettext("%d second", "%d seconds", seconds) % seconds + elif 60 <= seconds < 120: + return _("a minute") + elif 120 <= seconds < 3600: + minutes = seconds // 60 + return _ngettext("%d minute", "%d minutes", minutes) % minutes + elif 3600 <= seconds < 3600 * 2: + return _("an hour") + elif 3600 < seconds: + hours = seconds // 3600 + return _ngettext("%d hour", "%d hours", hours) % hours + elif years == 0: + if days == 1: + return _("a day") + if not use_months: + return _ngettext("%d day", "%d days", days) % days + else: + if not num_months: + return _ngettext("%d day", "%d days", days) % days + elif num_months == 1: + return _("a month") + else: + return _ngettext("%d month", "%d months", num_months) % num_months + elif years == 1: + if not num_months and not days: + return _("a year") + elif not num_months: + return _ngettext("1 year, %d day", "1 year, %d days", days) % days + elif use_months: + if num_months == 1: + return _("1 year, 1 month") + else: + return ( + _ngettext("1 year, %d month", "1 year, %d months", num_months) + % num_months + ) + else: + return _ngettext("1 year, %d day", "1 year, %d days", days) % days + + return _ngettext("%d year", "%d years", years).replace("%d", "%s") % intcomma(years) + + +def naturaltime( + value: dt.datetime | float, + future: bool = False, + months: bool = True, + minimum_unit: str = "seconds", + when: dt.datetime | None = None, +) -> str: + """Return a natural representation of a time in a resolution that makes sense. + + This is more or less compatible with Django's `naturaltime` filter. + + Args: + value (datetime.datetime, int or float): A `datetime` or a number of seconds. + future (bool): Ignored for `datetime`s, where the tense is always figured out + based on the current time. For integers, the return value will be past tense + by default, unless future is `True`. + months (bool): If `True`, then a number of months (based on 30.5 days) will be + used for fuzziness between years. + minimum_unit (str): The lowest unit that can be used. + when (datetime.datetime): Point in time relative to which _value_ is + interpreted. Defaults to the current time in the local timezone. + + Returns: + str: A natural representation of the input in a resolution that makes sense. + """ + now = when or _now() + date, delta = _date_and_delta(value, now=now) + if date is None: + return str(value) + # determine tense by value only if datetime/timedelta were passed + if isinstance(value, (dt.datetime, dt.timedelta)): + future = date > now + + ago = _("%s from now") if future else _("%s ago") + delta = naturaldelta(delta, months, minimum_unit) + + if delta == _("a moment"): + return _("now") + + return str(ago % delta) + + +def naturalday(value: dt.date | dt.datetime, format: str = "%b %d") -> str: + """Return a natural day. + + For date values that are tomorrow, today or yesterday compared to + present day return representing string. Otherwise, return a string + formatted according to `format`. + + """ + try: + value = dt.date(value.year, value.month, value.day) + except AttributeError: + # Passed value wasn't date-ish + return str(value) + except (OverflowError, ValueError): + # Date arguments out of range + return str(value) + delta = value - dt.date.today() + if delta.days == 0: + return _("today") + elif delta.days == 1: + return _("tomorrow") + elif delta.days == -1: + return _("yesterday") + return value.strftime(format) + + +def naturaldate(value: dt.date | dt.datetime) -> str: + """Like `naturalday`, but append a year for dates more than ~five months away.""" + try: + value = dt.date(value.year, value.month, value.day) + except AttributeError: + # Passed value wasn't date-ish + return str(value) + except (OverflowError, ValueError): + # Date arguments out of range + return str(value) + delta = _abs_timedelta(value - dt.date.today()) + if delta.days >= 5 * 365 / 12: + return naturalday(value, "%b %d %Y") + return naturalday(value) + + +def _quotient_and_remainder( + value: float, + divisor: float, + unit: Unit, + minimum_unit: Unit, + suppress: collections.abc.Iterable[Unit], +) -> tuple[float, float]: + """Divide `value` by `divisor` returning the quotient and remainder. + + If `unit` is `minimum_unit`, makes the quotient a float number and the remainder + will be zero. The rational is that if `unit` is the unit of the quotient, we cannot + represent the remainder because it would require a unit smaller than the + `minimum_unit`. + + >>> from humanize.time import _quotient_and_remainder, Unit + >>> _quotient_and_remainder(36, 24, Unit.DAYS, Unit.DAYS, []) + (1.5, 0) + + If unit is in `suppress`, the quotient will be zero and the remainder will be the + initial value. The idea is that if we cannot use `unit`, we are forced to use a + lower unit so we cannot do the division. + + >>> _quotient_and_remainder(36, 24, Unit.DAYS, Unit.HOURS, [Unit.DAYS]) + (0, 36) + + In other case return quotient and remainder as `divmod` would do it. + + >>> _quotient_and_remainder(36, 24, Unit.DAYS, Unit.HOURS, []) + (1, 12) + + """ + if unit == minimum_unit: + return value / divisor, 0 + elif unit in suppress: + return 0, value + else: + return divmod(value, divisor) + + +def _carry( + value1: float, + value2: float, + ratio: float, + unit: Unit, + min_unit: Unit, + suppress: typing.Iterable[Unit], +) -> tuple[float, float]: + """Return a tuple with two values. + + If the unit is in `suppress`, multiply `value1` by `ratio` and add it to `value2` + (carry to right). The idea is that if we cannot represent `value1` we need to + represent it in a lower unit. + + >>> from humanize.time import _carry, Unit + >>> _carry(2, 6, 24, Unit.DAYS, Unit.SECONDS, [Unit.DAYS]) + (0, 54) + + If the unit is the minimum unit, `value2` is divided by `ratio` and added to + `value1` (carry to left). We assume that `value2` has a lower unit so we need to + carry it to `value1`. + + >>> _carry(2, 6, 24, Unit.DAYS, Unit.DAYS, []) + (2.25, 0) + + Otherwise, just return the same input: + + >>> _carry(2, 6, 24, Unit.DAYS, Unit.SECONDS, []) + (2, 6) + """ + if unit == min_unit: + return value1 + value2 / ratio, 0 + elif unit in suppress: + return 0, value2 + value1 * ratio + else: + return value1, value2 + + +def _suitable_minimum_unit(min_unit: Unit, suppress: typing.Iterable[Unit]) -> Unit: + """Return a minimum unit suitable that is not suppressed. + + If not suppressed, return the same unit: + + >>> from humanize.time import _suitable_minimum_unit, Unit + >>> _suitable_minimum_unit(Unit.HOURS, []).name + 'HOURS' + + But if suppressed, find a unit greather than the original one that is not + suppressed: + + >>> _suitable_minimum_unit(Unit.HOURS, [Unit.HOURS]).name + 'DAYS' + + >>> _suitable_minimum_unit(Unit.HOURS, [Unit.HOURS, Unit.DAYS]).name + 'MONTHS' + """ + if min_unit in suppress: + for unit in Unit: + if unit > min_unit and unit not in suppress: + return unit + + raise ValueError( + "Minimum unit is suppressed and no suitable replacement was found" + ) + + return min_unit + + +def _suppress_lower_units(min_unit: Unit, suppress: typing.Iterable[Unit]) -> set[Unit]: + """Extend suppressed units (if any) with all units lower than the minimum unit. + + >>> from humanize.time import _suppress_lower_units, Unit + >>> [x.name for x in sorted(_suppress_lower_units(Unit.SECONDS, [Unit.DAYS]))] + ['MICROSECONDS', 'MILLISECONDS', 'DAYS'] + """ + suppress = set(suppress) + for u in Unit: + if u == min_unit: + break + suppress.add(u) + + return suppress + + +def precisedelta( + value: dt.timedelta | int, + minimum_unit: str = "seconds", + suppress: typing.Iterable[str] = (), + format: str = "%0.2f", +) -> str: + """Return a precise representation of a timedelta. + + ```pycon + >>> import datetime as dt + >>> from humanize.time import precisedelta + + >>> delta = dt.timedelta(seconds=3633, days=2, microseconds=123000) + >>> precisedelta(delta) + '2 days, 1 hour and 33.12 seconds' + + ``` + + A custom `format` can be specified to control how the fractional part + is represented: + + ```pycon + >>> precisedelta(delta, format="%0.4f") + '2 days, 1 hour and 33.1230 seconds' + + ``` + + Instead, the `minimum_unit` can be changed to have a better resolution; + the function will still readjust the unit to use the greatest of the + units that does not lose precision. + + For example setting microseconds but still representing the date with milliseconds: + + ```pycon + >>> precisedelta(delta, minimum_unit="microseconds") + '2 days, 1 hour, 33 seconds and 123 milliseconds' + + ``` + + If desired, some units can be suppressed: you will not see them represented and the + time of the other units will be adjusted to keep representing the same timedelta: + + ```pycon + >>> precisedelta(delta, suppress=['days']) + '49 hours and 33.12 seconds' + + ``` + + Note that microseconds precision is lost if the seconds and all + the units below are suppressed: + + ```pycon + >>> delta = dt.timedelta(seconds=90, microseconds=100) + >>> precisedelta(delta, suppress=['seconds', 'milliseconds', 'microseconds']) + '1.50 minutes' + + ``` + + If the delta is too small to be represented with the minimum unit, + a value of zero will be returned: + + ```pycon + >>> delta = dt.timedelta(seconds=1) + >>> precisedelta(delta, minimum_unit="minutes") + '0.02 minutes' + + >>> delta = dt.timedelta(seconds=0.1) + >>> precisedelta(delta, minimum_unit="minutes") + '0 minutes' + + ``` + """ + date, delta = _date_and_delta(value) + if date is None: + return str(value) + + suppress_set = {Unit[s.upper()] for s in suppress} + + # Find a suitable minimum unit (it can be greater the one that the + # user gave us if it is suppressed). + min_unit = Unit[minimum_unit.upper()] + min_unit = _suitable_minimum_unit(min_unit, suppress_set) + del minimum_unit + + # Expand the suppressed units list/set to include all the units + # that are below the minimum unit + suppress_set = _suppress_lower_units(min_unit, suppress_set) + + # handy aliases + days = delta.days + secs = delta.seconds + usecs = delta.microseconds + + MICROSECONDS, MILLISECONDS, SECONDS, MINUTES, HOURS, DAYS, MONTHS, YEARS = list( + Unit + ) + + # Given DAYS compute YEARS and the remainder of DAYS as follows: + # if YEARS is the minimum unit, we cannot use DAYS so + # we will use a float for YEARS and 0 for DAYS: + # years, days = years/days, 0 + # + # if YEARS is suppressed, use DAYS: + # years, days = 0, days + # + # otherwise: + # years, days = divmod(years, days) + # + # The same applies for months, hours, minutes and milliseconds below + years, days = _quotient_and_remainder(days, 365, YEARS, min_unit, suppress_set) + months, days = _quotient_and_remainder(days, 30.5, MONTHS, min_unit, suppress_set) + + # If DAYS is not in suppress, we can represent the days but + # if it is a suppressed unit, we need to carry it to a lower unit, + # seconds in this case. + # + # The same applies for secs and usecs below + days, secs = _carry(days, secs, 24 * 3600, DAYS, min_unit, suppress_set) + + hours, secs = _quotient_and_remainder(secs, 3600, HOURS, min_unit, suppress_set) + minutes, secs = _quotient_and_remainder(secs, 60, MINUTES, min_unit, suppress_set) + + secs, usecs = _carry(secs, usecs, 1e6, SECONDS, min_unit, suppress_set) + + msecs, usecs = _quotient_and_remainder( + usecs, 1000, MILLISECONDS, min_unit, suppress_set + ) + + # if _unused != 0 we had lost some precision + usecs, _unused = _carry(usecs, 0, 1, MICROSECONDS, min_unit, suppress_set) + + fmts = [ + ("%d year", "%d years", years), + ("%d month", "%d months", months), + ("%d day", "%d days", days), + ("%d hour", "%d hours", hours), + ("%d minute", "%d minutes", minutes), + ("%d second", "%d seconds", secs), + ("%d millisecond", "%d milliseconds", msecs), + ("%d microsecond", "%d microseconds", usecs), + ] + + texts: list[str] = [] + for unit, fmt in zip(reversed(Unit), fmts): + singular_txt, plural_txt, fmt_value = fmt + if fmt_value > 0 or (not texts and unit == min_unit): + fmt_txt = _ngettext(singular_txt, plural_txt, fmt_value) + if unit == min_unit and math.modf(fmt_value)[0] > 0: + fmt_txt = fmt_txt.replace("%d", format) + elif unit == YEARS: + fmt_txt = fmt_txt.replace("%d", "%s") + texts.append(fmt_txt % intcomma(fmt_value)) + continue + + texts.append(fmt_txt % fmt_value) + + if unit == min_unit: + break + + if len(texts) == 1: + return texts[0] + + head = ", ".join(texts[:-1]) + tail = texts[-1] + + return _("%s and %s") % (head, tail) diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/kiwisolver/__init__.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/kiwisolver/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..cc69f4f6364a968abc5b94d3e4371dbce15d7aa0 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/kiwisolver/__init__.py @@ -0,0 +1,40 @@ +# -------------------------------------------------------------------------------------- +# Copyright (c) 2013-2022, Nucleic Development Team. +# +# Distributed under the terms of the Modified BSD License. +# +# The full license is in the file LICENSE, distributed with this software. +# -------------------------------------------------------------------------------------- +from ._cext import ( + BadRequiredStrength, + Constraint, + DuplicateConstraint, + DuplicateEditVariable, + Expression, + Solver, + Term, + UnknownConstraint, + UnknownEditVariable, + UnsatisfiableConstraint, + Variable, + __kiwi_version__, + __version__, + strength, +) + +__all__ = [ + "BadRequiredStrength", + "DuplicateConstraint", + "DuplicateEditVariable", + "UnknownConstraint", + "UnknownEditVariable", + "UnsatisfiableConstraint", + "strength", + "Variable", + "Term", + "Expression", + "Constraint", + "Solver", + "__version__", + "__kiwi_version__", +] diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/kiwisolver/_cext.pyi b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/kiwisolver/_cext.pyi new file mode 100644 index 0000000000000000000000000000000000000000..da6aaa34bdb8a6f2291613382c8c99ed9fce1045 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/kiwisolver/_cext.pyi @@ -0,0 +1,234 @@ +# -------------------------------------------------------------------------------------- +# Copyright (c) 2021, Nucleic Development Team. +# +# Distributed under the terms of the Modified BSD License. +# +# The full license is in the file LICENSE, distributed with this software. +# -------------------------------------------------------------------------------------- + +from typing import Any, Iterable, NoReturn, Tuple, type_check_only + +try: + from typing import Literal +except ImportError: + from typing_extensions import Literal # type: ignore + +__version__: str +__kiwi_version__: str + +# --- Exceptions + +class BadRequiredStrength(Exception): ... +class DuplicateConstraint(Exception): ... +class DuplicateEditVariable(Exception): ... +class UnknownConstraint(Exception): ... +class UnknownEditVariable(Exception): ... +class UnsatisfiableConstraint(Exception): ... + +# Types +@type_check_only +class Strength: + @property + def weak(self) -> float: ... + @property + def medium(self) -> float: ... + @property + def strong(self) -> float: ... + @property + def required(self) -> float: ... + def create( + self, + a: int | float, + b: int | float, + c: int | float, + weight: int | float = 1.0, + /, + ) -> float: ... + +# This is meant as a singleton and users should not access the Strength type. +strength: Strength + +class Variable: + """Variable to express a constraint in a solver.""" + + __hash__: None # type: ignore + def __init__(self, name: str = "", context: Any = None, /) -> None: ... + def name(self) -> str: + """Get the name of the variable.""" + ... + def setName(self, name: str, /) -> Any: + """Set the name of the variable.""" + ... + def value(self) -> float: + """Get the current value of the variable.""" + ... + def context(self) -> Any: + """Get the context object associated with the variable.""" + ... + def setContext(self, context: Any, /) -> Any: + """Set the context object associated with the variable.""" + ... + def __neg__(self) -> Term: ... + def __add__(self, other: float | Variable | Term | Expression) -> Expression: ... + def __radd__(self, other: float | Variable | Term | Expression) -> Expression: ... + def __sub__(self, other: float | Variable | Term | Expression) -> Expression: ... + def __rsub__(self, other: float | Variable | Term | Expression) -> Expression: ... + def __mul__(self, other: float) -> Term: ... + def __rmul__(self, other: float) -> Term: ... + def __truediv__(self, other: float) -> Term: ... + def __rtruediv__(self, other: float) -> Term: ... + def __eq__(self, other: float | Variable | Term | Expression) -> Constraint: ... # type: ignore + def __ge__(self, other: float | Variable | Term | Expression) -> Constraint: ... + def __le__(self, other: float | Variable | Term | Expression) -> Constraint: ... + def __ne__(self, other: Any) -> NoReturn: ... + def __gt__(self, other: Any) -> NoReturn: ... + def __lt__(self, other: Any) -> NoReturn: ... + +class Term: + """Product of a variable by a constant pre-factor.""" + + __hash__: None # type: ignore + def __init__( + self, variable: Variable, coefficient: int | float = 1.0, / # noqa + ) -> None: ... + def coefficient(self) -> float: + """Get the coefficient for the term.""" + ... + def variable(self) -> Variable: + """Get the variable for the term.""" + ... + def value(self) -> float: + """Get the value for the term.""" + ... + def __neg__(self) -> Term: ... + def __add__(self, other: float | Variable | Term | Expression) -> Expression: ... + def __radd__(self, other: float | Variable | Term | Expression) -> Expression: ... + def __sub__(self, other: float | Variable | Term | Expression) -> Expression: ... + def __rsub__(self, other: float | Variable | Term | Expression) -> Expression: ... + def __mul__(self, other: float) -> Term: ... + def __rmul__(self, other: float) -> Term: ... + def __truediv__(self, other: float) -> Term: ... + def __rtruediv__(self, other: float) -> Term: ... + def __eq__(self, other: float | Variable | Term | Expression) -> Constraint: ... # type: ignore + def __ge__(self, other: float | Variable | Term | Expression) -> Constraint: ... + def __le__(self, other: float | Variable | Term | Expression) -> Constraint: ... + def __ne__(self, other: Any) -> NoReturn: ... + def __gt__(self, other: Any) -> NoReturn: ... + def __lt__(self, other: Any) -> NoReturn: ... + +class Expression: + """Sum of terms and an additional constant.""" + + __hash__: None # type: ignore + def __init__( + self, terms: Iterable[Term], constant: int | float = 0.0, / # noqa + ) -> None: ... + def constant(self) -> float: + "" "Get the constant for the expression." "" + ... + def terms(self) -> Tuple[Term, ...]: + """Get the tuple of terms for the expression.""" + ... + def value(self) -> float: + """Get the value for the expression.""" + ... + def __neg__(self) -> Expression: ... + def __add__(self, other: float | Variable | Term | Expression) -> Expression: ... + def __radd__(self, other: float | Variable | Term | Expression) -> Expression: ... + def __sub__(self, other: float | Variable | Term | Expression) -> Expression: ... + def __rsub__(self, other: float | Variable | Term | Expression) -> Expression: ... + def __mul__(self, other: float) -> Expression: ... + def __rmul__(self, other: float) -> Expression: ... + def __truediv__(self, other: float) -> Expression: ... + def __rtruediv__(self, other: float) -> Expression: ... + def __eq__(self, other: float | Variable | Term | Expression) -> Constraint: ... # type: ignore + def __ge__(self, other: float | Variable | Term | Expression) -> Constraint: ... + def __le__(self, other: float | Variable | Term | Expression) -> Constraint: ... + def __ne__(self, other: Any) -> NoReturn: ... + def __gt__(self, other: Any) -> NoReturn: ... + def __lt__(self, other: Any) -> NoReturn: ... + +class Constraint: + def __init__( + self, + expression: Expression, + op: Literal["=="] | Literal["<="] | Literal[">="], + strength: float + | Literal["weak"] + | Literal["medium"] + | Literal["strong"] + | Literal["required"] = "required", + /, + ) -> None: ... + def expression(self) -> Expression: + """Get the expression object for the constraint.""" + ... + def op(self) -> Literal["=="] | Literal["<="] | Literal[">="]: + """Get the relational operator for the constraint.""" + ... + def strength(self) -> float: + """Get the strength for the constraint.""" + ... + def __or__( + self, + other: float + | Literal["weak"] + | Literal["medium"] + | Literal["strong"] + | Literal["required"], + ) -> Constraint: ... + def __ror__( + self, + other: float + | Literal["weak"] + | Literal["medium"] + | Literal["strong"] + | Literal["required"], + ) -> Constraint: ... + +class Solver: + """Kiwi solver class.""" + + def __init__(self) -> None: ... + def addConstraint(self, constraint: Constraint, /) -> None: + """Add a constraint to the solver.""" + ... + def removeConstraint(self, constraint: Constraint, /) -> None: + """Remove a constraint from the solver.""" + ... + def hasConstraint(self, constraint: Constraint, /) -> bool: + """Check whether the solver contains a constraint.""" + ... + def addEditVariable( + self, + variable: Variable, + strength: float + | Literal["weak"] + | Literal["medium"] + | Literal["strong"] + | Literal["required"], + /, + ) -> None: + """Add an edit variable to the solver.""" + ... + def removeEditVariable(self, variable: Variable, /) -> None: + """Remove an edit variable from the solver.""" + ... + def hasEditVariable(self, variable: Variable, /) -> bool: + """Check whether the solver contains an edit variable.""" + ... + def suggestValue(self, variable: Variable, value: int | float, /) -> None: + """Suggest a desired value for an edit variable.""" + ... + def updateVariables(self) -> None: + """Update the values of the solver variables.""" + ... + def reset(self) -> None: + """Reset the solver to the initial empty starting condition.""" + ... + def dump(self) -> None: + """Dump a representation of the solver internals to stdout.""" + ... + def dumps(self) -> str: + """Dump a representation of the solver internals to a string.""" + ... diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/kiwisolver/py.typed b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/kiwisolver/py.typed new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/libpasteurize/__init__.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/libpasteurize/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..4cb1cbcd6343fc4bc4d69954e412ea508984be2e --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/libpasteurize/__init__.py @@ -0,0 +1 @@ +# empty to make this a package diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/libpasteurize/main.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/libpasteurize/main.py new file mode 100644 index 0000000000000000000000000000000000000000..4179174b566596a19163931419219215c9bd4781 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/libpasteurize/main.py @@ -0,0 +1,204 @@ +""" +pasteurize: automatic conversion of Python 3 code to clean 2/3 code +=================================================================== + +``pasteurize`` attempts to convert existing Python 3 code into source-compatible +Python 2 and 3 code. + +Use it like this on Python 3 code: + + $ pasteurize --verbose mypython3script.py + +This removes any Py3-only syntax (e.g. new metaclasses) and adds these +import lines: + + from __future__ import absolute_import + from __future__ import division + from __future__ import print_function + from __future__ import unicode_literals + from future import standard_library + standard_library.install_hooks() + from builtins import * + +To write changes to the files, use the -w flag. + +It also adds any other wrappers needed for Py2/3 compatibility. + +Note that separate stages are not available (or needed) when converting from +Python 3 with ``pasteurize`` as they are when converting from Python 2 with +``futurize``. + +The --all-imports option forces adding all ``__future__`` imports, +``builtins`` imports, and standard library aliases, even if they don't +seem necessary for the current state of each module. (This can simplify +testing, and can reduce the need to think about Py2 compatibility when editing +the code further.) + +""" + +from __future__ import (absolute_import, print_function, unicode_literals) + +import sys +import logging +import optparse +from lib2to3.main import main, warn, StdoutRefactoringTool +from lib2to3 import refactor + +from future import __version__ +from libpasteurize.fixes import fix_names + + +def main(args=None): + """Main program. + + Returns a suggested exit status (0, 1, 2). + """ + # Set up option parser + parser = optparse.OptionParser(usage="pasteurize [options] file|dir ...") + parser.add_option("-V", "--version", action="store_true", + help="Report the version number of pasteurize") + parser.add_option("-a", "--all-imports", action="store_true", + help="Adds all __future__ and future imports to each module") + parser.add_option("-f", "--fix", action="append", default=[], + help="Each FIX specifies a transformation; default: all") + parser.add_option("-j", "--processes", action="store", default=1, + type="int", help="Run 2to3 concurrently") + parser.add_option("-x", "--nofix", action="append", default=[], + help="Prevent a fixer from being run.") + parser.add_option("-l", "--list-fixes", action="store_true", + help="List available transformations") + # parser.add_option("-p", "--print-function", action="store_true", + # help="Modify the grammar so that print() is a function") + parser.add_option("-v", "--verbose", action="store_true", + help="More verbose logging") + parser.add_option("--no-diffs", action="store_true", + help="Don't show diffs of the refactoring") + parser.add_option("-w", "--write", action="store_true", + help="Write back modified files") + parser.add_option("-n", "--nobackups", action="store_true", default=False, + help="Don't write backups for modified files.") + + # Parse command line arguments + refactor_stdin = False + flags = {} + options, args = parser.parse_args(args) + fixer_pkg = 'libpasteurize.fixes' + avail_fixes = fix_names + flags["print_function"] = True + + if not options.write and options.no_diffs: + warn("not writing files and not printing diffs; that's not very useful") + if not options.write and options.nobackups: + parser.error("Can't use -n without -w") + if options.version: + print(__version__) + return 0 + if options.list_fixes: + print("Available transformations for the -f/--fix option:") + for fixname in sorted(avail_fixes): + print(fixname) + if not args: + return 0 + if not args: + print("At least one file or directory argument required.", + file=sys.stderr) + print("Use --help to show usage.", file=sys.stderr) + return 2 + if "-" in args: + refactor_stdin = True + if options.write: + print("Can't write to stdin.", file=sys.stderr) + return 2 + + # Set up logging handler + level = logging.DEBUG if options.verbose else logging.INFO + logging.basicConfig(format='%(name)s: %(message)s', level=level) + + unwanted_fixes = set() + for fix in options.nofix: + if ".fix_" in fix: + unwanted_fixes.add(fix) + else: + # Infer the full module name for the fixer. + # First ensure that no names clash (e.g. + # lib2to3.fixes.fix_blah and libfuturize.fixes.fix_blah): + found = [f for f in avail_fixes + if f.endswith('fix_{0}'.format(fix))] + if len(found) > 1: + print("Ambiguous fixer name. Choose a fully qualified " + "module name instead from these:\n" + + "\n".join(" " + myf for myf in found), + file=sys.stderr) + return 2 + elif len(found) == 0: + print("Unknown fixer. Use --list-fixes or -l for a list.", + file=sys.stderr) + return 2 + unwanted_fixes.add(found[0]) + + extra_fixes = set() + if options.all_imports: + prefix = 'libpasteurize.fixes.' + extra_fixes.add(prefix + 'fix_add_all__future__imports') + extra_fixes.add(prefix + 'fix_add_future_standard_library_import') + extra_fixes.add(prefix + 'fix_add_all_future_builtins') + + explicit = set() + if options.fix: + all_present = False + for fix in options.fix: + if fix == 'all': + all_present = True + else: + if ".fix_" in fix: + explicit.add(fix) + else: + # Infer the full module name for the fixer. + # First ensure that no names clash (e.g. + # lib2to3.fixes.fix_blah and libpasteurize.fixes.fix_blah): + found = [f for f in avail_fixes + if f.endswith('fix_{0}'.format(fix))] + if len(found) > 1: + print("Ambiguous fixer name. Choose a fully qualified " + "module name instead from these:\n" + + "\n".join(" " + myf for myf in found), + file=sys.stderr) + return 2 + elif len(found) == 0: + print("Unknown fixer. Use --list-fixes or -l for a list.", + file=sys.stderr) + return 2 + explicit.add(found[0]) + if len(explicit & unwanted_fixes) > 0: + print("Conflicting usage: the following fixers have been " + "simultaneously requested and disallowed:\n" + + "\n".join(" " + myf for myf in (explicit & unwanted_fixes)), + file=sys.stderr) + return 2 + requested = avail_fixes.union(explicit) if all_present else explicit + else: + requested = avail_fixes.union(explicit) + + fixer_names = requested | extra_fixes - unwanted_fixes + + # Initialize the refactoring tool + rt = StdoutRefactoringTool(sorted(fixer_names), flags, set(), + options.nobackups, not options.no_diffs) + + # Refactor all files and directories passed as arguments + if not rt.errors: + if refactor_stdin: + rt.refactor_stdin() + else: + try: + rt.refactor(args, options.write, None, + options.processes) + except refactor.MultiprocessingUnsupported: + assert options.processes > 1 + print("Sorry, -j isn't " \ + "supported on this platform.", file=sys.stderr) + return 1 + rt.summarize() + + # Return error status (0 if rt.errors is zero) + return int(bool(rt.errors)) diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/markdown/__main__.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/markdown/__main__.py new file mode 100644 index 0000000000000000000000000000000000000000..018400824f07bacccd0f30cc0449920fb424bcdc --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/markdown/__main__.py @@ -0,0 +1,151 @@ +""" +Python Markdown + +A Python implementation of John Gruber's Markdown. + +Documentation: https://python-markdown.github.io/ +GitHub: https://github.com/Python-Markdown/markdown/ +PyPI: https://pypi.org/project/Markdown/ + +Started by Manfred Stienstra (http://www.dwerg.net/). +Maintained for a few years by Yuri Takhteyev (http://www.freewisdom.org). +Currently maintained by Waylan Limberg (https://github.com/waylan), +Dmitry Shachnev (https://github.com/mitya57) and Isaac Muse (https://github.com/facelessuser). + +Copyright 2007-2018 The Python Markdown Project (v. 1.7 and later) +Copyright 2004, 2005, 2006 Yuri Takhteyev (v. 0.2-1.6b) +Copyright 2004 Manfred Stienstra (the original version) + +License: BSD (see LICENSE.md for details). +""" + +import sys +import optparse +import codecs +import warnings +import markdown +try: + # We use `unsafe_load` because users may need to pass in actual Python + # objects. As this is only available from the CLI, the user has much + # worse problems if an attacker can use this as an attach vector. + from yaml import unsafe_load as yaml_load +except ImportError: # pragma: no cover + try: + # Fall back to PyYAML <5.1 + from yaml import load as yaml_load + except ImportError: + # Fall back to JSON + from json import load as yaml_load + +import logging +from logging import DEBUG, WARNING, CRITICAL + +logger = logging.getLogger('MARKDOWN') + + +def parse_options(args=None, values=None): + """ + Define and parse `optparse` options for command-line usage. + """ + usage = """%prog [options] [INPUTFILE] + (STDIN is assumed if no INPUTFILE is given)""" + desc = "A Python implementation of John Gruber's Markdown. " \ + "https://Python-Markdown.github.io/" + ver = "%%prog %s" % markdown.__version__ + + parser = optparse.OptionParser(usage=usage, description=desc, version=ver) + parser.add_option("-f", "--file", dest="filename", default=None, + help="Write output to OUTPUT_FILE. Defaults to STDOUT.", + metavar="OUTPUT_FILE") + parser.add_option("-e", "--encoding", dest="encoding", + help="Encoding for input and output files.",) + parser.add_option("-o", "--output_format", dest="output_format", + default='xhtml', metavar="OUTPUT_FORMAT", + help="Use output format 'xhtml' (default) or 'html'.") + parser.add_option("-n", "--no_lazy_ol", dest="lazy_ol", + action='store_false', default=True, + help="Observe number of first item of ordered lists.") + parser.add_option("-x", "--extension", action="append", dest="extensions", + help="Load extension EXTENSION.", metavar="EXTENSION") + parser.add_option("-c", "--extension_configs", + dest="configfile", default=None, + help="Read extension configurations from CONFIG_FILE. " + "CONFIG_FILE must be of JSON or YAML format. YAML " + "format requires that a python YAML library be " + "installed. The parsed JSON or YAML must result in a " + "python dictionary which would be accepted by the " + "'extension_configs' keyword on the markdown.Markdown " + "class. The extensions must also be loaded with the " + "`--extension` option.", + metavar="CONFIG_FILE") + parser.add_option("-q", "--quiet", default=CRITICAL, + action="store_const", const=CRITICAL+10, dest="verbose", + help="Suppress all warnings.") + parser.add_option("-v", "--verbose", + action="store_const", const=WARNING, dest="verbose", + help="Print all warnings.") + parser.add_option("--noisy", + action="store_const", const=DEBUG, dest="verbose", + help="Print debug messages.") + + (options, args) = parser.parse_args(args, values) + + if len(args) == 0: + input_file = None + else: + input_file = args[0] + + if not options.extensions: + options.extensions = [] + + extension_configs = {} + if options.configfile: + with codecs.open( + options.configfile, mode="r", encoding=options.encoding + ) as fp: + try: + extension_configs = yaml_load(fp) + except Exception as e: + message = "Failed parsing extension config file: %s" % \ + options.configfile + e.args = (message,) + e.args[1:] + raise + + opts = { + 'input': input_file, + 'output': options.filename, + 'extensions': options.extensions, + 'extension_configs': extension_configs, + 'encoding': options.encoding, + 'output_format': options.output_format, + 'lazy_ol': options.lazy_ol + } + + return opts, options.verbose + + +def run(): # pragma: no cover + """Run Markdown from the command line.""" + + # Parse options and adjust logging level if necessary + options, logging_level = parse_options() + if not options: + sys.exit(2) + logger.setLevel(logging_level) + console_handler = logging.StreamHandler() + logger.addHandler(console_handler) + if logging_level <= WARNING: + # Ensure deprecation warnings get displayed + warnings.filterwarnings('default') + logging.captureWarnings(True) + warn_logger = logging.getLogger('py.warnings') + warn_logger.addHandler(console_handler) + + # Run + markdown.markdownFromFile(**options) + + +if __name__ == '__main__': # pragma: no cover + # Support running module as a commandline command. + # `python -m markdown [options] [args]`. + run() diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/markdown/__meta__.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/markdown/__meta__.py new file mode 100644 index 0000000000000000000000000000000000000000..84884b602fb7d970637749606704fd6d2e9cf78e --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/markdown/__meta__.py @@ -0,0 +1,49 @@ +""" +Python Markdown + +A Python implementation of John Gruber's Markdown. + +Documentation: https://python-markdown.github.io/ +GitHub: https://github.com/Python-Markdown/markdown/ +PyPI: https://pypi.org/project/Markdown/ + +Started by Manfred Stienstra (http://www.dwerg.net/). +Maintained for a few years by Yuri Takhteyev (http://www.freewisdom.org). +Currently maintained by Waylan Limberg (https://github.com/waylan), +Dmitry Shachnev (https://github.com/mitya57) and Isaac Muse (https://github.com/facelessuser). + +Copyright 2007-2018 The Python Markdown Project (v. 1.7 and later) +Copyright 2004, 2005, 2006 Yuri Takhteyev (v. 0.2-1.6b) +Copyright 2004 Manfred Stienstra (the original version) + +License: BSD (see LICENSE.md for details). +""" + +# __version_info__ format: +# (major, minor, patch, dev/alpha/beta/rc/final, #) +# (1, 1, 2, 'dev', 0) => "1.1.2.dev0" +# (1, 1, 2, 'alpha', 1) => "1.1.2a1" +# (1, 2, 0, 'beta', 2) => "1.2b2" +# (1, 2, 0, 'rc', 4) => "1.2rc4" +# (1, 2, 0, 'final', 0) => "1.2" +__version_info__ = (3, 3, 7, 'final', 0) + + +def _get_version(version_info): + " Returns a PEP 440-compliant version number from version_info. " + assert len(version_info) == 5 + assert version_info[3] in ('dev', 'alpha', 'beta', 'rc', 'final') + + parts = 2 if version_info[2] == 0 else 3 + v = '.'.join(map(str, version_info[:parts])) + + if version_info[3] == 'dev': + v += '.dev' + str(version_info[4]) + elif version_info[3] != 'final': + mapping = {'alpha': 'a', 'beta': 'b', 'rc': 'rc'} + v += mapping[version_info[3]] + str(version_info[4]) + + return v + + +__version__ = _get_version(__version_info__) diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/markdown/blockparser.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/markdown/blockparser.py new file mode 100644 index 0000000000000000000000000000000000000000..39219fdf777fc9dde1f86e370ec84ff449441453 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/markdown/blockparser.py @@ -0,0 +1,125 @@ +""" +Python Markdown + +A Python implementation of John Gruber's Markdown. + +Documentation: https://python-markdown.github.io/ +GitHub: https://github.com/Python-Markdown/markdown/ +PyPI: https://pypi.org/project/Markdown/ + +Started by Manfred Stienstra (http://www.dwerg.net/). +Maintained for a few years by Yuri Takhteyev (http://www.freewisdom.org). +Currently maintained by Waylan Limberg (https://github.com/waylan), +Dmitry Shachnev (https://github.com/mitya57) and Isaac Muse (https://github.com/facelessuser). + +Copyright 2007-2018 The Python Markdown Project (v. 1.7 and later) +Copyright 2004, 2005, 2006 Yuri Takhteyev (v. 0.2-1.6b) +Copyright 2004 Manfred Stienstra (the original version) + +License: BSD (see LICENSE.md for details). +""" + +import xml.etree.ElementTree as etree +from . import util + + +class State(list): + """ Track the current and nested state of the parser. + + This utility class is used to track the state of the BlockParser and + support multiple levels if nesting. It's just a simple API wrapped around + a list. Each time a state is set, that state is appended to the end of the + list. Each time a state is reset, that state is removed from the end of + the list. + + Therefore, each time a state is set for a nested block, that state must be + reset when we back out of that level of nesting or the state could be + corrupted. + + While all the methods of a list object are available, only the three + defined below need be used. + + """ + + def set(self, state): + """ Set a new state. """ + self.append(state) + + def reset(self): + """ Step back one step in nested state. """ + self.pop() + + def isstate(self, state): + """ Test that top (current) level is of given state. """ + if len(self): + return self[-1] == state + else: + return False + + +class BlockParser: + """ Parse Markdown blocks into an ElementTree object. + + A wrapper class that stitches the various BlockProcessors together, + looping through them and creating an ElementTree object. + """ + + def __init__(self, md): + self.blockprocessors = util.Registry() + self.state = State() + self.md = md + + @property + @util.deprecated("Use 'md' instead.") + def markdown(self): + # TODO: remove this later + return self.md + + def parseDocument(self, lines): + """ Parse a markdown document into an ElementTree. + + Given a list of lines, an ElementTree object (not just a parent + Element) is created and the root element is passed to the parser + as the parent. The ElementTree object is returned. + + This should only be called on an entire document, not pieces. + + """ + # Create a ElementTree from the lines + self.root = etree.Element(self.md.doc_tag) + self.parseChunk(self.root, '\n'.join(lines)) + return etree.ElementTree(self.root) + + def parseChunk(self, parent, text): + """ Parse a chunk of markdown text and attach to given etree node. + + While the ``text`` argument is generally assumed to contain multiple + blocks which will be split on blank lines, it could contain only one + block. Generally, this method would be called by extensions when + block parsing is required. + + The ``parent`` etree Element passed in is altered in place. + Nothing is returned. + + """ + self.parseBlocks(parent, text.split('\n\n')) + + def parseBlocks(self, parent, blocks): + """ Process blocks of markdown text and attach to given etree node. + + Given a list of ``blocks``, each blockprocessor is stepped through + until there are no blocks left. While an extension could potentially + call this method directly, it's generally expected to be used + internally. + + This is a public method as an extension may need to add/alter + additional BlockProcessors which call this method to recursively + parse a nested block. + + """ + while blocks: + for processor in self.blockprocessors: + if processor.test(parent, blocks[0]): + if processor.run(parent, blocks) is not False: + # run returns True or None + break diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/markdown/blockprocessors.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/markdown/blockprocessors.py new file mode 100644 index 0000000000000000000000000000000000000000..3d0ff86ebbe6ae8dbc36d63a878781a4f11785f3 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/markdown/blockprocessors.py @@ -0,0 +1,623 @@ +""" +Python Markdown + +A Python implementation of John Gruber's Markdown. + +Documentation: https://python-markdown.github.io/ +GitHub: https://github.com/Python-Markdown/markdown/ +PyPI: https://pypi.org/project/Markdown/ + +Started by Manfred Stienstra (http://www.dwerg.net/). +Maintained for a few years by Yuri Takhteyev (http://www.freewisdom.org). +Currently maintained by Waylan Limberg (https://github.com/waylan), +Dmitry Shachnev (https://github.com/mitya57) and Isaac Muse (https://github.com/facelessuser). + +Copyright 2007-2018 The Python Markdown Project (v. 1.7 and later) +Copyright 2004, 2005, 2006 Yuri Takhteyev (v. 0.2-1.6b) +Copyright 2004 Manfred Stienstra (the original version) + +License: BSD (see LICENSE.md for details). + +CORE MARKDOWN BLOCKPARSER +=========================================================================== + +This parser handles basic parsing of Markdown blocks. It doesn't concern +itself with inline elements such as **bold** or *italics*, but rather just +catches blocks, lists, quotes, etc. + +The BlockParser is made up of a bunch of BlockProcessors, each handling a +different type of block. Extensions may add/replace/remove BlockProcessors +as they need to alter how markdown blocks are parsed. +""" + +import logging +import re +import xml.etree.ElementTree as etree +from . import util +from .blockparser import BlockParser + +logger = logging.getLogger('MARKDOWN') + + +def build_block_parser(md, **kwargs): + """ Build the default block parser used by Markdown. """ + parser = BlockParser(md) + parser.blockprocessors.register(EmptyBlockProcessor(parser), 'empty', 100) + parser.blockprocessors.register(ListIndentProcessor(parser), 'indent', 90) + parser.blockprocessors.register(CodeBlockProcessor(parser), 'code', 80) + parser.blockprocessors.register(HashHeaderProcessor(parser), 'hashheader', 70) + parser.blockprocessors.register(SetextHeaderProcessor(parser), 'setextheader', 60) + parser.blockprocessors.register(HRProcessor(parser), 'hr', 50) + parser.blockprocessors.register(OListProcessor(parser), 'olist', 40) + parser.blockprocessors.register(UListProcessor(parser), 'ulist', 30) + parser.blockprocessors.register(BlockQuoteProcessor(parser), 'quote', 20) + parser.blockprocessors.register(ReferenceProcessor(parser), 'reference', 15) + parser.blockprocessors.register(ParagraphProcessor(parser), 'paragraph', 10) + return parser + + +class BlockProcessor: + """ Base class for block processors. + + Each subclass will provide the methods below to work with the source and + tree. Each processor will need to define it's own ``test`` and ``run`` + methods. The ``test`` method should return True or False, to indicate + whether the current block should be processed by this processor. If the + test passes, the parser will call the processors ``run`` method. + + """ + + def __init__(self, parser): + self.parser = parser + self.tab_length = parser.md.tab_length + + def lastChild(self, parent): + """ Return the last child of an etree element. """ + if len(parent): + return parent[-1] + else: + return None + + def detab(self, text, length=None): + """ Remove a tab from the front of each line of the given text. """ + if length is None: + length = self.tab_length + newtext = [] + lines = text.split('\n') + for line in lines: + if line.startswith(' ' * length): + newtext.append(line[length:]) + elif not line.strip(): + newtext.append('') + else: + break + return '\n'.join(newtext), '\n'.join(lines[len(newtext):]) + + def looseDetab(self, text, level=1): + """ Remove a tab from front of lines but allowing dedented lines. """ + lines = text.split('\n') + for i in range(len(lines)): + if lines[i].startswith(' '*self.tab_length*level): + lines[i] = lines[i][self.tab_length*level:] + return '\n'.join(lines) + + def test(self, parent, block): + """ Test for block type. Must be overridden by subclasses. + + As the parser loops through processors, it will call the ``test`` + method on each to determine if the given block of text is of that + type. This method must return a boolean ``True`` or ``False``. The + actual method of testing is left to the needs of that particular + block type. It could be as simple as ``block.startswith(some_string)`` + or a complex regular expression. As the block type may be different + depending on the parent of the block (i.e. inside a list), the parent + etree element is also provided and may be used as part of the test. + + Keywords: + + * ``parent``: A etree element which will be the parent of the block. + * ``block``: A block of text from the source which has been split at + blank lines. + """ + pass # pragma: no cover + + def run(self, parent, blocks): + """ Run processor. Must be overridden by subclasses. + + When the parser determines the appropriate type of a block, the parser + will call the corresponding processor's ``run`` method. This method + should parse the individual lines of the block and append them to + the etree. + + Note that both the ``parent`` and ``etree`` keywords are pointers + to instances of the objects which should be edited in place. Each + processor must make changes to the existing objects as there is no + mechanism to return new/different objects to replace them. + + This means that this method should be adding SubElements or adding text + to the parent, and should remove (``pop``) or add (``insert``) items to + the list of blocks. + + Keywords: + + * ``parent``: A etree element which is the parent of the current block. + * ``blocks``: A list of all remaining blocks of the document. + """ + pass # pragma: no cover + + +class ListIndentProcessor(BlockProcessor): + """ Process children of list items. + + Example: + * a list item + process this part + + or this part + + """ + + ITEM_TYPES = ['li'] + LIST_TYPES = ['ul', 'ol'] + + def __init__(self, *args): + super().__init__(*args) + self.INDENT_RE = re.compile(r'^(([ ]{%s})+)' % self.tab_length) + + def test(self, parent, block): + return block.startswith(' '*self.tab_length) and \ + not self.parser.state.isstate('detabbed') and \ + (parent.tag in self.ITEM_TYPES or + (len(parent) and parent[-1] is not None and + (parent[-1].tag in self.LIST_TYPES))) + + def run(self, parent, blocks): + block = blocks.pop(0) + level, sibling = self.get_level(parent, block) + block = self.looseDetab(block, level) + + self.parser.state.set('detabbed') + if parent.tag in self.ITEM_TYPES: + # It's possible that this parent has a 'ul' or 'ol' child list + # with a member. If that is the case, then that should be the + # parent. This is intended to catch the edge case of an indented + # list whose first member was parsed previous to this point + # see OListProcessor + if len(parent) and parent[-1].tag in self.LIST_TYPES: + self.parser.parseBlocks(parent[-1], [block]) + else: + # The parent is already a li. Just parse the child block. + self.parser.parseBlocks(parent, [block]) + elif sibling.tag in self.ITEM_TYPES: + # The sibling is a li. Use it as parent. + self.parser.parseBlocks(sibling, [block]) + elif len(sibling) and sibling[-1].tag in self.ITEM_TYPES: + # The parent is a list (``ol`` or ``ul``) which has children. + # Assume the last child li is the parent of this block. + if sibling[-1].text: + # If the parent li has text, that text needs to be moved to a p + # The p must be 'inserted' at beginning of list in the event + # that other children already exist i.e.; a nested sublist. + p = etree.Element('p') + p.text = sibling[-1].text + sibling[-1].text = '' + sibling[-1].insert(0, p) + self.parser.parseChunk(sibling[-1], block) + else: + self.create_item(sibling, block) + self.parser.state.reset() + + def create_item(self, parent, block): + """ Create a new li and parse the block with it as the parent. """ + li = etree.SubElement(parent, 'li') + self.parser.parseBlocks(li, [block]) + + def get_level(self, parent, block): + """ Get level of indent based on list level. """ + # Get indent level + m = self.INDENT_RE.match(block) + if m: + indent_level = len(m.group(1))/self.tab_length + else: + indent_level = 0 + if self.parser.state.isstate('list'): + # We're in a tightlist - so we already are at correct parent. + level = 1 + else: + # We're in a looselist - so we need to find parent. + level = 0 + # Step through children of tree to find matching indent level. + while indent_level > level: + child = self.lastChild(parent) + if (child is not None and + (child.tag in self.LIST_TYPES or child.tag in self.ITEM_TYPES)): + if child.tag in self.LIST_TYPES: + level += 1 + parent = child + else: + # No more child levels. If we're short of indent_level, + # we have a code block. So we stop here. + break + return level, parent + + +class CodeBlockProcessor(BlockProcessor): + """ Process code blocks. """ + + def test(self, parent, block): + return block.startswith(' '*self.tab_length) + + def run(self, parent, blocks): + sibling = self.lastChild(parent) + block = blocks.pop(0) + theRest = '' + if (sibling is not None and sibling.tag == "pre" and + len(sibling) and sibling[0].tag == "code"): + # The previous block was a code block. As blank lines do not start + # new code blocks, append this block to the previous, adding back + # linebreaks removed from the split into a list. + code = sibling[0] + block, theRest = self.detab(block) + code.text = util.AtomicString( + '{}\n{}\n'.format(code.text, util.code_escape(block.rstrip())) + ) + else: + # This is a new codeblock. Create the elements and insert text. + pre = etree.SubElement(parent, 'pre') + code = etree.SubElement(pre, 'code') + block, theRest = self.detab(block) + code.text = util.AtomicString('%s\n' % util.code_escape(block.rstrip())) + if theRest: + # This block contained unindented line(s) after the first indented + # line. Insert these lines as the first block of the master blocks + # list for future processing. + blocks.insert(0, theRest) + + +class BlockQuoteProcessor(BlockProcessor): + + RE = re.compile(r'(^|\n)[ ]{0,3}>[ ]?(.*)') + + def test(self, parent, block): + return bool(self.RE.search(block)) and not util.nearing_recursion_limit() + + def run(self, parent, blocks): + block = blocks.pop(0) + m = self.RE.search(block) + if m: + before = block[:m.start()] # Lines before blockquote + # Pass lines before blockquote in recursively for parsing first. + self.parser.parseBlocks(parent, [before]) + # Remove ``> `` from beginning of each line. + block = '\n'.join( + [self.clean(line) for line in block[m.start():].split('\n')] + ) + sibling = self.lastChild(parent) + if sibling is not None and sibling.tag == "blockquote": + # Previous block was a blockquote so set that as this blocks parent + quote = sibling + else: + # This is a new blockquote. Create a new parent element. + quote = etree.SubElement(parent, 'blockquote') + # Recursively parse block with blockquote as parent. + # change parser state so blockquotes embedded in lists use p tags + self.parser.state.set('blockquote') + self.parser.parseChunk(quote, block) + self.parser.state.reset() + + def clean(self, line): + """ Remove ``>`` from beginning of a line. """ + m = self.RE.match(line) + if line.strip() == ">": + return "" + elif m: + return m.group(2) + else: + return line + + +class OListProcessor(BlockProcessor): + """ Process ordered list blocks. """ + + TAG = 'ol' + # The integer (python string) with which the lists starts (default=1) + # Eg: If list is initialized as) + # 3. Item + # The ol tag will get starts="3" attribute + STARTSWITH = '1' + # Lazy ol - ignore startswith + LAZY_OL = True + # List of allowed sibling tags. + SIBLING_TAGS = ['ol', 'ul'] + + def __init__(self, parser): + super().__init__(parser) + # Detect an item (``1. item``). ``group(1)`` contains contents of item. + self.RE = re.compile(r'^[ ]{0,%d}\d+\.[ ]+(.*)' % (self.tab_length - 1)) + # Detect items on secondary lines. they can be of either list type. + self.CHILD_RE = re.compile(r'^[ ]{0,%d}((\d+\.)|[*+-])[ ]+(.*)' % + (self.tab_length - 1)) + # Detect indented (nested) items of either type + self.INDENT_RE = re.compile(r'^[ ]{%d,%d}((\d+\.)|[*+-])[ ]+.*' % + (self.tab_length, self.tab_length * 2 - 1)) + + def test(self, parent, block): + return bool(self.RE.match(block)) + + def run(self, parent, blocks): + # Check fr multiple items in one block. + items = self.get_items(blocks.pop(0)) + sibling = self.lastChild(parent) + + if sibling is not None and sibling.tag in self.SIBLING_TAGS: + # Previous block was a list item, so set that as parent + lst = sibling + # make sure previous item is in a p- if the item has text, + # then it isn't in a p + if lst[-1].text: + # since it's possible there are other children for this + # sibling, we can't just SubElement the p, we need to + # insert it as the first item. + p = etree.Element('p') + p.text = lst[-1].text + lst[-1].text = '' + lst[-1].insert(0, p) + # if the last item has a tail, then the tail needs to be put in a p + # likely only when a header is not followed by a blank line + lch = self.lastChild(lst[-1]) + if lch is not None and lch.tail: + p = etree.SubElement(lst[-1], 'p') + p.text = lch.tail.lstrip() + lch.tail = '' + + # parse first block differently as it gets wrapped in a p. + li = etree.SubElement(lst, 'li') + self.parser.state.set('looselist') + firstitem = items.pop(0) + self.parser.parseBlocks(li, [firstitem]) + self.parser.state.reset() + elif parent.tag in ['ol', 'ul']: + # this catches the edge case of a multi-item indented list whose + # first item is in a blank parent-list item: + # * * subitem1 + # * subitem2 + # see also ListIndentProcessor + lst = parent + else: + # This is a new list so create parent with appropriate tag. + lst = etree.SubElement(parent, self.TAG) + # Check if a custom start integer is set + if not self.LAZY_OL and self.STARTSWITH != '1': + lst.attrib['start'] = self.STARTSWITH + + self.parser.state.set('list') + # Loop through items in block, recursively parsing each with the + # appropriate parent. + for item in items: + if item.startswith(' '*self.tab_length): + # Item is indented. Parse with last item as parent + self.parser.parseBlocks(lst[-1], [item]) + else: + # New item. Create li and parse with it as parent + li = etree.SubElement(lst, 'li') + self.parser.parseBlocks(li, [item]) + self.parser.state.reset() + + def get_items(self, block): + """ Break a block into list items. """ + items = [] + for line in block.split('\n'): + m = self.CHILD_RE.match(line) + if m: + # This is a new list item + # Check first item for the start index + if not items and self.TAG == 'ol': + # Detect the integer value of first list item + INTEGER_RE = re.compile(r'(\d+)') + self.STARTSWITH = INTEGER_RE.match(m.group(1)).group() + # Append to the list + items.append(m.group(3)) + elif self.INDENT_RE.match(line): + # This is an indented (possibly nested) item. + if items[-1].startswith(' '*self.tab_length): + # Previous item was indented. Append to that item. + items[-1] = '{}\n{}'.format(items[-1], line) + else: + items.append(line) + else: + # This is another line of previous item. Append to that item. + items[-1] = '{}\n{}'.format(items[-1], line) + return items + + +class UListProcessor(OListProcessor): + """ Process unordered list blocks. """ + + TAG = 'ul' + + def __init__(self, parser): + super().__init__(parser) + # Detect an item (``1. item``). ``group(1)`` contains contents of item. + self.RE = re.compile(r'^[ ]{0,%d}[*+-][ ]+(.*)' % (self.tab_length - 1)) + + +class HashHeaderProcessor(BlockProcessor): + """ Process Hash Headers. """ + + # Detect a header at start of any line in block + RE = re.compile(r'(?:^|\n)(?P#{1,6})(?P
(?:\\.|[^\\])*?)#*(?:\n|$)') + + def test(self, parent, block): + return bool(self.RE.search(block)) + + def run(self, parent, blocks): + block = blocks.pop(0) + m = self.RE.search(block) + if m: + before = block[:m.start()] # All lines before header + after = block[m.end():] # All lines after header + if before: + # As the header was not the first line of the block and the + # lines before the header must be parsed first, + # recursively parse this lines as a block. + self.parser.parseBlocks(parent, [before]) + # Create header using named groups from RE + h = etree.SubElement(parent, 'h%d' % len(m.group('level'))) + h.text = m.group('header').strip() + if after: + # Insert remaining lines as first block for future parsing. + blocks.insert(0, after) + else: # pragma: no cover + # This should never happen, but just in case... + logger.warn("We've got a problem header: %r" % block) + + +class SetextHeaderProcessor(BlockProcessor): + """ Process Setext-style Headers. """ + + # Detect Setext-style header. Must be first 2 lines of block. + RE = re.compile(r'^.*?\n[=-]+[ ]*(\n|$)', re.MULTILINE) + + def test(self, parent, block): + return bool(self.RE.match(block)) + + def run(self, parent, blocks): + lines = blocks.pop(0).split('\n') + # Determine level. ``=`` is 1 and ``-`` is 2. + if lines[1].startswith('='): + level = 1 + else: + level = 2 + h = etree.SubElement(parent, 'h%d' % level) + h.text = lines[0].strip() + if len(lines) > 2: + # Block contains additional lines. Add to master blocks for later. + blocks.insert(0, '\n'.join(lines[2:])) + + +class HRProcessor(BlockProcessor): + """ Process Horizontal Rules. """ + + # Python's re module doesn't officially support atomic grouping. However you can fake it. + # See https://stackoverflow.com/a/13577411/866026 + RE = r'^[ ]{0,3}(?=(?P(-+[ ]{0,2}){3,}|(_+[ ]{0,2}){3,}|(\*+[ ]{0,2}){3,}))(?P=atomicgroup)[ ]*$' + # Detect hr on any line of a block. + SEARCH_RE = re.compile(RE, re.MULTILINE) + + def test(self, parent, block): + m = self.SEARCH_RE.search(block) + if m: + # Save match object on class instance so we can use it later. + self.match = m + return True + return False + + def run(self, parent, blocks): + block = blocks.pop(0) + match = self.match + # Check for lines in block before hr. + prelines = block[:match.start()].rstrip('\n') + if prelines: + # Recursively parse lines before hr so they get parsed first. + self.parser.parseBlocks(parent, [prelines]) + # create hr + etree.SubElement(parent, 'hr') + # check for lines in block after hr. + postlines = block[match.end():].lstrip('\n') + if postlines: + # Add lines after hr to master blocks for later parsing. + blocks.insert(0, postlines) + + +class EmptyBlockProcessor(BlockProcessor): + """ Process blocks that are empty or start with an empty line. """ + + def test(self, parent, block): + return not block or block.startswith('\n') + + def run(self, parent, blocks): + block = blocks.pop(0) + filler = '\n\n' + if block: + # Starts with empty line + # Only replace a single line. + filler = '\n' + # Save the rest for later. + theRest = block[1:] + if theRest: + # Add remaining lines to master blocks for later. + blocks.insert(0, theRest) + sibling = self.lastChild(parent) + if (sibling is not None and sibling.tag == 'pre' and + len(sibling) and sibling[0].tag == 'code'): + # Last block is a codeblock. Append to preserve whitespace. + sibling[0].text = util.AtomicString( + '{}{}'.format(sibling[0].text, filler) + ) + + +class ReferenceProcessor(BlockProcessor): + """ Process link references. """ + RE = re.compile( + r'^[ ]{0,3}\[([^\[\]]*)\]:[ ]*\n?[ ]*([^\s]+)[ ]*(?:\n[ ]*)?((["\'])(.*)\4[ ]*|\((.*)\)[ ]*)?$', re.MULTILINE + ) + + def test(self, parent, block): + return True + + def run(self, parent, blocks): + block = blocks.pop(0) + m = self.RE.search(block) + if m: + id = m.group(1).strip().lower() + link = m.group(2).lstrip('<').rstrip('>') + title = m.group(5) or m.group(6) + self.parser.md.references[id] = (link, title) + if block[m.end():].strip(): + # Add any content after match back to blocks as separate block + blocks.insert(0, block[m.end():].lstrip('\n')) + if block[:m.start()].strip(): + # Add any content before match back to blocks as separate block + blocks.insert(0, block[:m.start()].rstrip('\n')) + return True + # No match. Restore block. + blocks.insert(0, block) + return False + + +class ParagraphProcessor(BlockProcessor): + """ Process Paragraph blocks. """ + + def test(self, parent, block): + return True + + def run(self, parent, blocks): + block = blocks.pop(0) + if block.strip(): + # Not a blank block. Add to parent, otherwise throw it away. + if self.parser.state.isstate('list'): + # The parent is a tight-list. + # + # Check for any children. This will likely only happen in a + # tight-list when a header isn't followed by a blank line. + # For example: + # + # * # Header + # Line 2 of list item - not part of header. + sibling = self.lastChild(parent) + if sibling is not None: + # Insetrt after sibling. + if sibling.tail: + sibling.tail = '{}\n{}'.format(sibling.tail, block) + else: + sibling.tail = '\n%s' % block + else: + # Append to parent.text + if parent.text: + parent.text = '{}\n{}'.format(parent.text, block) + else: + parent.text = block.lstrip() + else: + # Create a regular paragraph + p = etree.SubElement(parent, 'p') + p.text = block.lstrip() diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/markdown/core.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/markdown/core.py new file mode 100644 index 0000000000000000000000000000000000000000..d8c819607b558f5c9f9e5ca0e590674d5cbebd98 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/markdown/core.py @@ -0,0 +1,407 @@ +""" +Python Markdown + +A Python implementation of John Gruber's Markdown. + +Documentation: https://python-markdown.github.io/ +GitHub: https://github.com/Python-Markdown/markdown/ +PyPI: https://pypi.org/project/Markdown/ + +Started by Manfred Stienstra (http://www.dwerg.net/). +Maintained for a few years by Yuri Takhteyev (http://www.freewisdom.org). +Currently maintained by Waylan Limberg (https://github.com/waylan), +Dmitry Shachnev (https://github.com/mitya57) and Isaac Muse (https://github.com/facelessuser). + +Copyright 2007-2018 The Python Markdown Project (v. 1.7 and later) +Copyright 2004, 2005, 2006 Yuri Takhteyev (v. 0.2-1.6b) +Copyright 2004 Manfred Stienstra (the original version) + +License: BSD (see LICENSE.md for details). +""" + +import codecs +import sys +import logging +import importlib +from . import util +from .preprocessors import build_preprocessors +from .blockprocessors import build_block_parser +from .treeprocessors import build_treeprocessors +from .inlinepatterns import build_inlinepatterns +from .postprocessors import build_postprocessors +from .extensions import Extension +from .serializers import to_html_string, to_xhtml_string + +__all__ = ['Markdown', 'markdown', 'markdownFromFile'] + + +logger = logging.getLogger('MARKDOWN') + + +class Markdown: + """Convert Markdown to HTML.""" + + doc_tag = "div" # Element used to wrap document - later removed + + output_formats = { + 'html': to_html_string, + 'xhtml': to_xhtml_string, + } + + def __init__(self, **kwargs): + """ + Creates a new Markdown instance. + + Keyword arguments: + + * extensions: A list of extensions. + If an item is an instance of a subclass of `markdown.extension.Extension`, the instance will be used + as-is. If an item is of type string, first an entry point will be loaded. If that fails, the string is + assumed to use Python dot notation (`path.to.module:ClassName`) to load a markdown.Extension subclass. If + no class is specified, then a `makeExtension` function is called within the specified module. + * extension_configs: Configuration settings for extensions. + * output_format: Format of output. Supported formats are: + * "xhtml": Outputs XHTML style tags. Default. + * "html": Outputs HTML style tags. + * tab_length: Length of tabs in the source. Default: 4 + + """ + + self.tab_length = kwargs.get('tab_length', 4) + + self.ESCAPED_CHARS = ['\\', '`', '*', '_', '{', '}', '[', ']', + '(', ')', '>', '#', '+', '-', '.', '!'] + + self.block_level_elements = [ + # Elements which are invalid to wrap in a `

` tag. + # See https://w3c.github.io/html/grouping-content.html#the-p-element + 'address', 'article', 'aside', 'blockquote', 'details', 'div', 'dl', + 'fieldset', 'figcaption', 'figure', 'footer', 'form', 'h1', 'h2', 'h3', + 'h4', 'h5', 'h6', 'header', 'hgroup', 'hr', 'main', 'menu', 'nav', 'ol', + 'p', 'pre', 'section', 'table', 'ul', + # Other elements which Markdown should not be mucking up the contents of. + 'canvas', 'colgroup', 'dd', 'body', 'dt', 'group', 'iframe', 'li', 'legend', + 'math', 'map', 'noscript', 'output', 'object', 'option', 'progress', 'script', + 'style', 'summary', 'tbody', 'td', 'textarea', 'tfoot', 'th', 'thead', 'tr', 'video' + ] + + self.registeredExtensions = [] + self.docType = "" + self.stripTopLevelTags = True + + self.build_parser() + + self.references = {} + self.htmlStash = util.HtmlStash() + self.registerExtensions(extensions=kwargs.get('extensions', []), + configs=kwargs.get('extension_configs', {})) + self.set_output_format(kwargs.get('output_format', 'xhtml')) + self.reset() + + def build_parser(self): + """ Build the parser from the various parts. """ + self.preprocessors = build_preprocessors(self) + self.parser = build_block_parser(self) + self.inlinePatterns = build_inlinepatterns(self) + self.treeprocessors = build_treeprocessors(self) + self.postprocessors = build_postprocessors(self) + return self + + def registerExtensions(self, extensions, configs): + """ + Register extensions with this instance of Markdown. + + Keyword arguments: + + * extensions: A list of extensions, which can either + be strings or objects. + * configs: A dictionary mapping extension names to config options. + + """ + for ext in extensions: + if isinstance(ext, str): + ext = self.build_extension(ext, configs.get(ext, {})) + if isinstance(ext, Extension): + ext._extendMarkdown(self) + logger.debug( + 'Successfully loaded extension "%s.%s".' + % (ext.__class__.__module__, ext.__class__.__name__) + ) + elif ext is not None: + raise TypeError( + 'Extension "{}.{}" must be of type: "{}.{}"'.format( + ext.__class__.__module__, ext.__class__.__name__, + Extension.__module__, Extension.__name__ + ) + ) + return self + + def build_extension(self, ext_name, configs): + """ + Build extension from a string name, then return an instance. + + First attempt to load an entry point. The string name must be registered as an entry point in the + `markdown.extensions` group which points to a subclass of the `markdown.extensions.Extension` class. + If multiple distributions have registered the same name, the first one found is returned. + + If no entry point is found, assume dot notation (`path.to.module:ClassName`). Load the specified class and + return an instance. If no class is specified, import the module and call a `makeExtension` function and return + the Extension instance returned by that function. + """ + configs = dict(configs) + + entry_points = [ep for ep in util.INSTALLED_EXTENSIONS if ep.name == ext_name] + if entry_points: + ext = entry_points[0].load() + return ext(**configs) + + # Get class name (if provided): `path.to.module:ClassName` + ext_name, class_name = ext_name.split(':', 1) if ':' in ext_name else (ext_name, '') + + try: + module = importlib.import_module(ext_name) + logger.debug( + 'Successfully imported extension module "%s".' % ext_name + ) + except ImportError as e: + message = 'Failed loading extension "%s".' % ext_name + e.args = (message,) + e.args[1:] + raise + + if class_name: + # Load given class name from module. + return getattr(module, class_name)(**configs) + else: + # Expect makeExtension() function to return a class. + try: + return module.makeExtension(**configs) + except AttributeError as e: + message = e.args[0] + message = "Failed to initiate extension " \ + "'%s': %s" % (ext_name, message) + e.args = (message,) + e.args[1:] + raise + + def registerExtension(self, extension): + """ This gets called by the extension """ + self.registeredExtensions.append(extension) + return self + + def reset(self): + """ + Resets all state variables so that we can start with a new text. + """ + self.htmlStash.reset() + self.references.clear() + + for extension in self.registeredExtensions: + if hasattr(extension, 'reset'): + extension.reset() + + return self + + def set_output_format(self, format): + """ Set the output format for the class instance. """ + self.output_format = format.lower().rstrip('145') # ignore num + try: + self.serializer = self.output_formats[self.output_format] + except KeyError as e: + valid_formats = list(self.output_formats.keys()) + valid_formats.sort() + message = 'Invalid Output Format: "%s". Use one of %s.' \ + % (self.output_format, + '"' + '", "'.join(valid_formats) + '"') + e.args = (message,) + e.args[1:] + raise + return self + + def is_block_level(self, tag): + """Check if the tag is a block level HTML tag.""" + if isinstance(tag, str): + return tag.lower().rstrip('/') in self.block_level_elements + # Some ElementTree tags are not strings, so return False. + return False + + def convert(self, source): + """ + Convert markdown to serialized XHTML or HTML. + + Keyword arguments: + + * source: Source text as a Unicode string. + + Markdown processing takes place in five steps: + + 1. A bunch of "preprocessors" munge the input text. + 2. BlockParser() parses the high-level structural elements of the + pre-processed text into an ElementTree. + 3. A bunch of "treeprocessors" are run against the ElementTree. One + such treeprocessor runs InlinePatterns against the ElementTree, + detecting inline markup. + 4. Some post-processors are run against the text after the ElementTree + has been serialized into text. + 5. The output is written to a string. + + """ + + # Fixup the source text + if not source.strip(): + return '' # a blank unicode string + + try: + source = str(source) + except UnicodeDecodeError as e: # pragma: no cover + # Customise error message while maintaining original trackback + e.reason += '. -- Note: Markdown only accepts unicode input!' + raise + + # Split into lines and run the line preprocessors. + self.lines = source.split("\n") + for prep in self.preprocessors: + self.lines = prep.run(self.lines) + + # Parse the high-level elements. + root = self.parser.parseDocument(self.lines).getroot() + + # Run the tree-processors + for treeprocessor in self.treeprocessors: + newRoot = treeprocessor.run(root) + if newRoot is not None: + root = newRoot + + # Serialize _properly_. Strip top-level tags. + output = self.serializer(root) + if self.stripTopLevelTags: + try: + start = output.index( + '<%s>' % self.doc_tag) + len(self.doc_tag) + 2 + end = output.rindex('' % self.doc_tag) + output = output[start:end].strip() + except ValueError as e: # pragma: no cover + if output.strip().endswith('<%s />' % self.doc_tag): + # We have an empty document + output = '' + else: + # We have a serious problem + raise ValueError('Markdown failed to strip top-level ' + 'tags. Document=%r' % output.strip()) from e + + # Run the text post-processors + for pp in self.postprocessors: + output = pp.run(output) + + return output.strip() + + def convertFile(self, input=None, output=None, encoding=None): + """Converts a markdown file and returns the HTML as a unicode string. + + Decodes the file using the provided encoding (defaults to utf-8), + passes the file content to markdown, and outputs the html to either + the provided stream or the file with provided name, using the same + encoding as the source file. The 'xmlcharrefreplace' error handler is + used when encoding the output. + + **Note:** This is the only place that decoding and encoding of unicode + takes place in Python-Markdown. (All other code is unicode-in / + unicode-out.) + + Keyword arguments: + + * input: File object or path. Reads from stdin if `None`. + * output: File object or path. Writes to stdout if `None`. + * encoding: Encoding of input and output files. Defaults to utf-8. + + """ + + encoding = encoding or "utf-8" + + # Read the source + if input: + if isinstance(input, str): + input_file = codecs.open(input, mode="r", encoding=encoding) + else: + input_file = codecs.getreader(encoding)(input) + text = input_file.read() + input_file.close() + else: + text = sys.stdin.read() + if not isinstance(text, str): # pragma: no cover + text = text.decode(encoding) + + text = text.lstrip('\ufeff') # remove the byte-order mark + + # Convert + html = self.convert(text) + + # Write to file or stdout + if output: + if isinstance(output, str): + output_file = codecs.open(output, "w", + encoding=encoding, + errors="xmlcharrefreplace") + output_file.write(html) + output_file.close() + else: + writer = codecs.getwriter(encoding) + output_file = writer(output, errors="xmlcharrefreplace") + output_file.write(html) + # Don't close here. User may want to write more. + else: + # Encode manually and write bytes to stdout. + html = html.encode(encoding, "xmlcharrefreplace") + try: + # Write bytes directly to buffer (Python 3). + sys.stdout.buffer.write(html) + except AttributeError: # pragma: no cover + # Probably Python 2, which works with bytes by default. + sys.stdout.write(html) + + return self + + +""" +EXPORTED FUNCTIONS +============================================================================= + +Those are the two functions we really mean to export: markdown() and +markdownFromFile(). +""" + + +def markdown(text, **kwargs): + """Convert a markdown string to HTML and return HTML as a unicode string. + + This is a shortcut function for `Markdown` class to cover the most + basic use case. It initializes an instance of Markdown, loads the + necessary extensions and runs the parser on the given text. + + Keyword arguments: + + * text: Markdown formatted text as Unicode or ASCII string. + * Any arguments accepted by the Markdown class. + + Returns: An HTML document as a string. + + """ + md = Markdown(**kwargs) + return md.convert(text) + + +def markdownFromFile(**kwargs): + """Read markdown code from a file and write it to a file or a stream. + + This is a shortcut function which initializes an instance of Markdown, + and calls the convertFile method rather than convert. + + Keyword arguments: + + * input: a file name or readable object. + * output: a file name or writable object. + * encoding: Encoding of input and output. + * Any arguments accepted by the Markdown class. + + """ + md = Markdown(**kwargs) + md.convertFile(kwargs.get('input', None), + kwargs.get('output', None), + kwargs.get('encoding', None)) diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/markdown/inlinepatterns.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/markdown/inlinepatterns.py new file mode 100644 index 0000000000000000000000000000000000000000..eb74f495eb38f3304282187f091578e3a2d21d38 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/markdown/inlinepatterns.py @@ -0,0 +1,892 @@ +""" +Python Markdown + +A Python implementation of John Gruber's Markdown. + +Documentation: https://python-markdown.github.io/ +GitHub: https://github.com/Python-Markdown/markdown/ +PyPI: https://pypi.org/project/Markdown/ + +Started by Manfred Stienstra (http://www.dwerg.net/). +Maintained for a few years by Yuri Takhteyev (http://www.freewisdom.org). +Currently maintained by Waylan Limberg (https://github.com/waylan), +Dmitry Shachnev (https://github.com/mitya57) and Isaac Muse (https://github.com/facelessuser). + +Copyright 2007-2018 The Python Markdown Project (v. 1.7 and later) +Copyright 2004, 2005, 2006 Yuri Takhteyev (v. 0.2-1.6b) +Copyright 2004 Manfred Stienstra (the original version) + +License: BSD (see LICENSE.md for details). + +INLINE PATTERNS +============================================================================= + +Inline patterns such as *emphasis* are handled by means of auxiliary +objects, one per pattern. Pattern objects must be instances of classes +that extend markdown.Pattern. Each pattern object uses a single regular +expression and needs support the following methods: + + pattern.getCompiledRegExp() # returns a regular expression + + pattern.handleMatch(m) # takes a match object and returns + # an ElementTree element or just plain text + +All of python markdown's built-in patterns subclass from Pattern, +but you can add additional patterns that don't. + +Also note that all the regular expressions used by inline must +capture the whole block. For this reason, they all start with +'^(.*)' and end with '(.*)!'. In case with built-in expression +Pattern takes care of adding the "^(.*)" and "(.*)!". + +Finally, the order in which regular expressions are applied is very +important - e.g. if we first replace http://.../ links with tags +and _then_ try to replace inline html, we would end up with a mess. +So, we apply the expressions in the following order: + +* escape and backticks have to go before everything else, so + that we can preempt any markdown patterns by escaping them. + +* then we handle auto-links (must be done before inline html) + +* then we handle inline HTML. At this point we will simply + replace all inline HTML strings with a placeholder and add + the actual HTML to a hash. + +* then inline images (must be done before links) + +* then bracketed links, first regular then reference-style + +* finally we apply strong and emphasis +""" + +from . import util +from collections import namedtuple +import re +import xml.etree.ElementTree as etree +try: # pragma: no cover + from html import entities +except ImportError: # pragma: no cover + import htmlentitydefs as entities + + +def build_inlinepatterns(md, **kwargs): + """ Build the default set of inline patterns for Markdown. """ + inlinePatterns = util.Registry() + inlinePatterns.register(BacktickInlineProcessor(BACKTICK_RE), 'backtick', 190) + inlinePatterns.register(EscapeInlineProcessor(ESCAPE_RE, md), 'escape', 180) + inlinePatterns.register(ReferenceInlineProcessor(REFERENCE_RE, md), 'reference', 170) + inlinePatterns.register(LinkInlineProcessor(LINK_RE, md), 'link', 160) + inlinePatterns.register(ImageInlineProcessor(IMAGE_LINK_RE, md), 'image_link', 150) + inlinePatterns.register( + ImageReferenceInlineProcessor(IMAGE_REFERENCE_RE, md), 'image_reference', 140 + ) + inlinePatterns.register( + ShortReferenceInlineProcessor(REFERENCE_RE, md), 'short_reference', 130 + ) + inlinePatterns.register( + ShortImageReferenceInlineProcessor(IMAGE_REFERENCE_RE, md), 'short_image_ref', 125 + ) + inlinePatterns.register(AutolinkInlineProcessor(AUTOLINK_RE, md), 'autolink', 120) + inlinePatterns.register(AutomailInlineProcessor(AUTOMAIL_RE, md), 'automail', 110) + inlinePatterns.register(SubstituteTagInlineProcessor(LINE_BREAK_RE, 'br'), 'linebreak', 100) + inlinePatterns.register(HtmlInlineProcessor(HTML_RE, md), 'html', 90) + inlinePatterns.register(HtmlInlineProcessor(ENTITY_RE, md), 'entity', 80) + inlinePatterns.register(SimpleTextInlineProcessor(NOT_STRONG_RE), 'not_strong', 70) + inlinePatterns.register(AsteriskProcessor(r'\*'), 'em_strong', 60) + inlinePatterns.register(UnderscoreProcessor(r'_'), 'em_strong2', 50) + return inlinePatterns + + +""" +The actual regular expressions for patterns +----------------------------------------------------------------------------- +""" + +NOIMG = r'(?) or [text](url "title") +LINK_RE = NOIMG + r'\[' + +# ![alttxt](http://x.com/) or ![alttxt]() +IMAGE_LINK_RE = r'\!\[' + +# [Google][3] +REFERENCE_RE = LINK_RE + +# ![alt text][2] +IMAGE_REFERENCE_RE = IMAGE_LINK_RE + +# stand-alone * or _ +NOT_STRONG_RE = r'((^|\s)(\*|_)(\s|$))' + +# +AUTOLINK_RE = r'<((?:[Ff]|[Hh][Tt])[Tt][Pp][Ss]?://[^<>]*)>' + +# +AUTOMAIL_RE = r'<([^<> !]+@[^@<> ]+)>' + +# <...> +HTML_RE = r'(<(\/?[a-zA-Z][^<>@ ]*( [^<>]*)?|!--(?:(?!).)*--)>)' + +# "&" (decimal) or "&" (hex) or "&" (named) +ENTITY_RE = r'(&(?:\#[0-9]+|\#x[0-9a-fA-F]+|[a-zA-Z0-9]+);)' + +# two spaces at end of line +LINE_BREAK_RE = r' \n' + + +def dequote(string): + """Remove quotes from around a string.""" + if ((string.startswith('"') and string.endswith('"')) or + (string.startswith("'") and string.endswith("'"))): + return string[1:-1] + else: + return string + + +class EmStrongItem(namedtuple('EmStrongItem', ['pattern', 'builder', 'tags'])): + """Emphasis/strong pattern item.""" + + +""" +The pattern classes +----------------------------------------------------------------------------- +""" + + +class Pattern: # pragma: no cover + """Base class that inline patterns subclass. """ + + ANCESTOR_EXCLUDES = tuple() + + def __init__(self, pattern, md=None): + """ + Create an instant of an inline pattern. + + Keyword arguments: + + * pattern: A regular expression that matches a pattern + + """ + self.pattern = pattern + self.compiled_re = re.compile(r"^(.*?)%s(.*)$" % pattern, + re.DOTALL | re.UNICODE) + + self.md = md + + @property + @util.deprecated("Use 'md' instead.") + def markdown(self): + # TODO: remove this later + return self.md + + def getCompiledRegExp(self): + """ Return a compiled regular expression. """ + return self.compiled_re + + def handleMatch(self, m): + """Return a ElementTree element from the given match. + + Subclasses should override this method. + + Keyword arguments: + + * m: A re match object containing a match of the pattern. + + """ + pass # pragma: no cover + + def type(self): + """ Return class name, to define pattern type """ + return self.__class__.__name__ + + def unescape(self, text): + """ Return unescaped text given text with an inline placeholder. """ + try: + stash = self.md.treeprocessors['inline'].stashed_nodes + except KeyError: # pragma: no cover + return text + + def get_stash(m): + id = m.group(1) + if id in stash: + value = stash.get(id) + if isinstance(value, str): + return value + else: + # An etree Element - return text content only + return ''.join(value.itertext()) + return util.INLINE_PLACEHOLDER_RE.sub(get_stash, text) + + +class InlineProcessor(Pattern): + """ + Base class that inline patterns subclass. + + This is the newer style inline processor that uses a more + efficient and flexible search approach. + """ + + def __init__(self, pattern, md=None): + """ + Create an instant of an inline pattern. + + Keyword arguments: + + * pattern: A regular expression that matches a pattern + + """ + self.pattern = pattern + self.compiled_re = re.compile(pattern, re.DOTALL | re.UNICODE) + + # Api for Markdown to pass safe_mode into instance + self.safe_mode = False + self.md = md + + def handleMatch(self, m, data): + """Return a ElementTree element from the given match and the + start and end index of the matched text. + + If `start` and/or `end` are returned as `None`, it will be + assumed that the processor did not find a valid region of text. + + Subclasses should override this method. + + Keyword arguments: + + * m: A re match object containing a match of the pattern. + * data: The buffer current under analysis + + Returns: + + * el: The ElementTree element, text or None. + * start: The start of the region that has been matched or None. + * end: The end of the region that has been matched or None. + + """ + pass # pragma: no cover + + +class SimpleTextPattern(Pattern): # pragma: no cover + """ Return a simple text of group(2) of a Pattern. """ + def handleMatch(self, m): + return m.group(2) + + +class SimpleTextInlineProcessor(InlineProcessor): + """ Return a simple text of group(1) of a Pattern. """ + def handleMatch(self, m, data): + return m.group(1), m.start(0), m.end(0) + + +class EscapeInlineProcessor(InlineProcessor): + """ Return an escaped character. """ + + def handleMatch(self, m, data): + char = m.group(1) + if char in self.md.ESCAPED_CHARS: + return '{}{}{}'.format(util.STX, ord(char), util.ETX), m.start(0), m.end(0) + else: + return None, m.start(0), m.end(0) + + +class SimpleTagPattern(Pattern): # pragma: no cover + """ + Return element of type `tag` with a text attribute of group(3) + of a Pattern. + + """ + def __init__(self, pattern, tag): + Pattern.__init__(self, pattern) + self.tag = tag + + def handleMatch(self, m): + el = etree.Element(self.tag) + el.text = m.group(3) + return el + + +class SimpleTagInlineProcessor(InlineProcessor): + """ + Return element of type `tag` with a text attribute of group(2) + of a Pattern. + + """ + def __init__(self, pattern, tag): + InlineProcessor.__init__(self, pattern) + self.tag = tag + + def handleMatch(self, m, data): # pragma: no cover + el = etree.Element(self.tag) + el.text = m.group(2) + return el, m.start(0), m.end(0) + + +class SubstituteTagPattern(SimpleTagPattern): # pragma: no cover + """ Return an element of type `tag` with no children. """ + def handleMatch(self, m): + return etree.Element(self.tag) + + +class SubstituteTagInlineProcessor(SimpleTagInlineProcessor): + """ Return an element of type `tag` with no children. """ + def handleMatch(self, m, data): + return etree.Element(self.tag), m.start(0), m.end(0) + + +class BacktickInlineProcessor(InlineProcessor): + """ Return a `` element containing the matching text. """ + def __init__(self, pattern): + InlineProcessor.__init__(self, pattern) + self.ESCAPED_BSLASH = '{}{}{}'.format(util.STX, ord('\\'), util.ETX) + self.tag = 'code' + + def handleMatch(self, m, data): + if m.group(3): + el = etree.Element(self.tag) + el.text = util.AtomicString(util.code_escape(m.group(3).strip())) + return el, m.start(0), m.end(0) + else: + return m.group(1).replace('\\\\', self.ESCAPED_BSLASH), m.start(0), m.end(0) + + +class DoubleTagPattern(SimpleTagPattern): # pragma: no cover + """Return a ElementTree element nested in tag2 nested in tag1. + + Useful for strong emphasis etc. + + """ + def handleMatch(self, m): + tag1, tag2 = self.tag.split(",") + el1 = etree.Element(tag1) + el2 = etree.SubElement(el1, tag2) + el2.text = m.group(3) + if len(m.groups()) == 5: + el2.tail = m.group(4) + return el1 + + +class DoubleTagInlineProcessor(SimpleTagInlineProcessor): + """Return a ElementTree element nested in tag2 nested in tag1. + + Useful for strong emphasis etc. + + """ + def handleMatch(self, m, data): # pragma: no cover + tag1, tag2 = self.tag.split(",") + el1 = etree.Element(tag1) + el2 = etree.SubElement(el1, tag2) + el2.text = m.group(2) + if len(m.groups()) == 3: + el2.tail = m.group(3) + return el1, m.start(0), m.end(0) + + +class HtmlInlineProcessor(InlineProcessor): + """ Store raw inline html and return a placeholder. """ + def handleMatch(self, m, data): + rawhtml = self.unescape(m.group(1)) + place_holder = self.md.htmlStash.store(rawhtml) + return place_holder, m.start(0), m.end(0) + + def unescape(self, text): + """ Return unescaped text given text with an inline placeholder. """ + try: + stash = self.md.treeprocessors['inline'].stashed_nodes + except KeyError: # pragma: no cover + return text + + def get_stash(m): + id = m.group(1) + value = stash.get(id) + if value is not None: + try: + return self.md.serializer(value) + except Exception: + return r'\%s' % value + + return util.INLINE_PLACEHOLDER_RE.sub(get_stash, text) + + +class AsteriskProcessor(InlineProcessor): + """Emphasis processor for handling strong and em matches inside asterisks.""" + + PATTERNS = [ + EmStrongItem(re.compile(EM_STRONG_RE, re.DOTALL | re.UNICODE), 'double', 'strong,em'), + EmStrongItem(re.compile(STRONG_EM_RE, re.DOTALL | re.UNICODE), 'double', 'em,strong'), + EmStrongItem(re.compile(STRONG_EM3_RE, re.DOTALL | re.UNICODE), 'double2', 'strong,em'), + EmStrongItem(re.compile(STRONG_RE, re.DOTALL | re.UNICODE), 'single', 'strong'), + EmStrongItem(re.compile(EMPHASIS_RE, re.DOTALL | re.UNICODE), 'single', 'em') + ] + + def build_single(self, m, tag, idx): + """Return single tag.""" + el1 = etree.Element(tag) + text = m.group(2) + self.parse_sub_patterns(text, el1, None, idx) + return el1 + + def build_double(self, m, tags, idx): + """Return double tag.""" + + tag1, tag2 = tags.split(",") + el1 = etree.Element(tag1) + el2 = etree.Element(tag2) + text = m.group(2) + self.parse_sub_patterns(text, el2, None, idx) + el1.append(el2) + if len(m.groups()) == 3: + text = m.group(3) + self.parse_sub_patterns(text, el1, el2, idx) + return el1 + + def build_double2(self, m, tags, idx): + """Return double tags (variant 2): `text text`.""" + + tag1, tag2 = tags.split(",") + el1 = etree.Element(tag1) + el2 = etree.Element(tag2) + text = m.group(2) + self.parse_sub_patterns(text, el1, None, idx) + text = m.group(3) + el1.append(el2) + self.parse_sub_patterns(text, el2, None, idx) + return el1 + + def parse_sub_patterns(self, data, parent, last, idx): + """ + Parses sub patterns. + + `data` (`str`): + text to evaluate. + + `parent` (`etree.Element`): + Parent to attach text and sub elements to. + + `last` (`etree.Element`): + Last appended child to parent. Can also be None if parent has no children. + + `idx` (`int`): + Current pattern index that was used to evaluate the parent. + + """ + + offset = 0 + pos = 0 + + length = len(data) + while pos < length: + # Find the start of potential emphasis or strong tokens + if self.compiled_re.match(data, pos): + matched = False + # See if the we can match an emphasis/strong pattern + for index, item in enumerate(self.PATTERNS): + # Only evaluate patterns that are after what was used on the parent + if index <= idx: + continue + m = item.pattern.match(data, pos) + if m: + # Append child nodes to parent + # Text nodes should be appended to the last + # child if present, and if not, it should + # be added as the parent's text node. + text = data[offset:m.start(0)] + if text: + if last is not None: + last.tail = text + else: + parent.text = text + el = self.build_element(m, item.builder, item.tags, index) + parent.append(el) + last = el + # Move our position past the matched hunk + offset = pos = m.end(0) + matched = True + if not matched: + # We matched nothing, move on to the next character + pos += 1 + else: + # Increment position as no potential emphasis start was found. + pos += 1 + + # Append any leftover text as a text node. + text = data[offset:] + if text: + if last is not None: + last.tail = text + else: + parent.text = text + + def build_element(self, m, builder, tags, index): + """Element builder.""" + + if builder == 'double2': + return self.build_double2(m, tags, index) + elif builder == 'double': + return self.build_double(m, tags, index) + else: + return self.build_single(m, tags, index) + + def handleMatch(self, m, data): + """Parse patterns.""" + + el = None + start = None + end = None + + for index, item in enumerate(self.PATTERNS): + m1 = item.pattern.match(data, m.start(0)) + if m1: + start = m1.start(0) + end = m1.end(0) + el = self.build_element(m1, item.builder, item.tags, index) + break + return el, start, end + + +class UnderscoreProcessor(AsteriskProcessor): + """Emphasis processor for handling strong and em matches inside underscores.""" + + PATTERNS = [ + EmStrongItem(re.compile(EM_STRONG2_RE, re.DOTALL | re.UNICODE), 'double', 'strong,em'), + EmStrongItem(re.compile(STRONG_EM2_RE, re.DOTALL | re.UNICODE), 'double', 'em,strong'), + EmStrongItem(re.compile(SMART_STRONG_EM_RE, re.DOTALL | re.UNICODE), 'double2', 'strong,em'), + EmStrongItem(re.compile(SMART_STRONG_RE, re.DOTALL | re.UNICODE), 'single', 'strong'), + EmStrongItem(re.compile(SMART_EMPHASIS_RE, re.DOTALL | re.UNICODE), 'single', 'em') + ] + + +class LinkInlineProcessor(InlineProcessor): + """ Return a link element from the given match. """ + RE_LINK = re.compile(r'''\(\s*(?:(<[^<>]*>)\s*(?:('[^']*'|"[^"]*")\s*)?\))?''', re.DOTALL | re.UNICODE) + RE_TITLE_CLEAN = re.compile(r'\s') + + def handleMatch(self, m, data): + text, index, handled = self.getText(data, m.end(0)) + + if not handled: + return None, None, None + + href, title, index, handled = self.getLink(data, index) + if not handled: + return None, None, None + + el = etree.Element("a") + el.text = text + + el.set("href", href) + + if title is not None: + el.set("title", title) + + return el, m.start(0), index + + def getLink(self, data, index): + """Parse data between `()` of `[Text]()` allowing recursive `()`. """ + + href = '' + title = None + handled = False + + m = self.RE_LINK.match(data, pos=index) + if m and m.group(1): + # Matches [Text]( "title") + href = m.group(1)[1:-1].strip() + if m.group(2): + title = m.group(2)[1:-1] + index = m.end(0) + handled = True + elif m: + # Track bracket nesting and index in string + bracket_count = 1 + backtrack_count = 1 + start_index = m.end() + index = start_index + last_bracket = -1 + + # Primary (first found) quote tracking. + quote = None + start_quote = -1 + exit_quote = -1 + ignore_matches = False + + # Secondary (second found) quote tracking. + alt_quote = None + start_alt_quote = -1 + exit_alt_quote = -1 + + # Track last character + last = '' + + for pos in range(index, len(data)): + c = data[pos] + if c == '(': + # Count nested ( + # Don't increment the bracket count if we are sure we're in a title. + if not ignore_matches: + bracket_count += 1 + elif backtrack_count > 0: + backtrack_count -= 1 + elif c == ')': + # Match nested ) to ( + # Don't decrement if we are sure we are in a title that is unclosed. + if ((exit_quote != -1 and quote == last) or (exit_alt_quote != -1 and alt_quote == last)): + bracket_count = 0 + elif not ignore_matches: + bracket_count -= 1 + elif backtrack_count > 0: + backtrack_count -= 1 + # We've found our backup end location if the title doesn't resolve. + if backtrack_count == 0: + last_bracket = index + 1 + + elif c in ("'", '"'): + # Quote has started + if not quote: + # We'll assume we are now in a title. + # Brackets are quoted, so no need to match them (except for the final one). + ignore_matches = True + backtrack_count = bracket_count + bracket_count = 1 + start_quote = index + 1 + quote = c + # Secondary quote (in case the first doesn't resolve): [text](link'"title") + elif c != quote and not alt_quote: + start_alt_quote = index + 1 + alt_quote = c + # Update primary quote match + elif c == quote: + exit_quote = index + 1 + # Update secondary quote match + elif alt_quote and c == alt_quote: + exit_alt_quote = index + 1 + + index += 1 + + # Link is closed, so let's break out of the loop + if bracket_count == 0: + # Get the title if we closed a title string right before link closed + if exit_quote >= 0 and quote == last: + href = data[start_index:start_quote - 1] + title = ''.join(data[start_quote:exit_quote - 1]) + elif exit_alt_quote >= 0 and alt_quote == last: + href = data[start_index:start_alt_quote - 1] + title = ''.join(data[start_alt_quote:exit_alt_quote - 1]) + else: + href = data[start_index:index - 1] + break + + if c != ' ': + last = c + + # We have a scenario: [test](link"notitle) + # When we enter a string, we stop tracking bracket resolution in the main counter, + # but we do keep a backup counter up until we discover where we might resolve all brackets + # if the title string fails to resolve. + if bracket_count != 0 and backtrack_count == 0: + href = data[start_index:last_bracket - 1] + index = last_bracket + bracket_count = 0 + + handled = bracket_count == 0 + + if title is not None: + title = self.RE_TITLE_CLEAN.sub(' ', dequote(self.unescape(title.strip()))) + + href = self.unescape(href).strip() + + return href, title, index, handled + + def getText(self, data, index): + """Parse the content between `[]` of the start of an image or link + resolving nested square brackets. + + """ + bracket_count = 1 + text = [] + for pos in range(index, len(data)): + c = data[pos] + if c == ']': + bracket_count -= 1 + elif c == '[': + bracket_count += 1 + index += 1 + if bracket_count == 0: + break + text.append(c) + return ''.join(text), index, bracket_count == 0 + + +class ImageInlineProcessor(LinkInlineProcessor): + """ Return a img element from the given match. """ + + def handleMatch(self, m, data): + text, index, handled = self.getText(data, m.end(0)) + if not handled: + return None, None, None + + src, title, index, handled = self.getLink(data, index) + if not handled: + return None, None, None + + el = etree.Element("img") + + el.set("src", src) + + if title is not None: + el.set("title", title) + + el.set('alt', self.unescape(text)) + return el, m.start(0), index + + +class ReferenceInlineProcessor(LinkInlineProcessor): + """ Match to a stored reference and return link element. """ + NEWLINE_CLEANUP_RE = re.compile(r'\s+', re.MULTILINE) + + RE_LINK = re.compile(r'\s?\[([^\]]*)\]', re.DOTALL | re.UNICODE) + + def handleMatch(self, m, data): + text, index, handled = self.getText(data, m.end(0)) + if not handled: + return None, None, None + + id, end, handled = self.evalId(data, index, text) + if not handled: + return None, None, None + + # Clean up linebreaks in id + id = self.NEWLINE_CLEANUP_RE.sub(' ', id) + if id not in self.md.references: # ignore undefined refs + return None, m.start(0), end + + href, title = self.md.references[id] + + return self.makeTag(href, title, text), m.start(0), end + + def evalId(self, data, index, text): + """ + Evaluate the id portion of [ref][id]. + + If [ref][] use [ref]. + """ + m = self.RE_LINK.match(data, pos=index) + if not m: + return None, index, False + else: + id = m.group(1).lower() + end = m.end(0) + if not id: + id = text.lower() + return id, end, True + + def makeTag(self, href, title, text): + el = etree.Element('a') + + el.set('href', href) + if title: + el.set('title', title) + + el.text = text + return el + + +class ShortReferenceInlineProcessor(ReferenceInlineProcessor): + """Short form of reference: [google]. """ + def evalId(self, data, index, text): + """Evaluate the id from of [ref] """ + + return text.lower(), index, True + + +class ImageReferenceInlineProcessor(ReferenceInlineProcessor): + """ Match to a stored reference and return img element. """ + def makeTag(self, href, title, text): + el = etree.Element("img") + el.set("src", href) + if title: + el.set("title", title) + el.set("alt", self.unescape(text)) + return el + + +class ShortImageReferenceInlineProcessor(ImageReferenceInlineProcessor): + """ Short form of inage reference: ![ref]. """ + def evalId(self, data, index, text): + """Evaluate the id from of [ref] """ + + return text.lower(), index, True + + +class AutolinkInlineProcessor(InlineProcessor): + """ Return a link Element given an autolink (``). """ + def handleMatch(self, m, data): + el = etree.Element("a") + el.set('href', self.unescape(m.group(1))) + el.text = util.AtomicString(m.group(1)) + return el, m.start(0), m.end(0) + + +class AutomailInlineProcessor(InlineProcessor): + """ + Return a mailto link Element given an automail link (``). + """ + def handleMatch(self, m, data): + el = etree.Element('a') + email = self.unescape(m.group(1)) + if email.startswith("mailto:"): + email = email[len("mailto:"):] + + def codepoint2name(code): + """Return entity definition by code, or the code if not defined.""" + entity = entities.codepoint2name.get(code) + if entity: + return "{}{};".format(util.AMP_SUBSTITUTE, entity) + else: + return "%s#%d;" % (util.AMP_SUBSTITUTE, code) + + letters = [codepoint2name(ord(letter)) for letter in email] + el.text = util.AtomicString(''.join(letters)) + + mailto = "mailto:" + email + mailto = "".join([util.AMP_SUBSTITUTE + '#%d;' % + ord(letter) for letter in mailto]) + el.set('href', mailto) + return el, m.start(0), m.end(0) diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/markdown/postprocessors.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/markdown/postprocessors.py new file mode 100644 index 0000000000000000000000000000000000000000..f4fb92477d58c451259a7069f805d841213efd4f --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/markdown/postprocessors.py @@ -0,0 +1,134 @@ +""" +Python Markdown + +A Python implementation of John Gruber's Markdown. + +Documentation: https://python-markdown.github.io/ +GitHub: https://github.com/Python-Markdown/markdown/ +PyPI: https://pypi.org/project/Markdown/ + +Started by Manfred Stienstra (http://www.dwerg.net/). +Maintained for a few years by Yuri Takhteyev (http://www.freewisdom.org). +Currently maintained by Waylan Limberg (https://github.com/waylan), +Dmitry Shachnev (https://github.com/mitya57) and Isaac Muse (https://github.com/facelessuser). + +Copyright 2007-2018 The Python Markdown Project (v. 1.7 and later) +Copyright 2004, 2005, 2006 Yuri Takhteyev (v. 0.2-1.6b) +Copyright 2004 Manfred Stienstra (the original version) + +License: BSD (see LICENSE.md for details). + +POST-PROCESSORS +============================================================================= + +Markdown also allows post-processors, which are similar to preprocessors in +that they need to implement a "run" method. However, they are run after core +processing. + +""" + +from collections import OrderedDict +from . import util +import re + + +def build_postprocessors(md, **kwargs): + """ Build the default postprocessors for Markdown. """ + postprocessors = util.Registry() + postprocessors.register(RawHtmlPostprocessor(md), 'raw_html', 30) + postprocessors.register(AndSubstitutePostprocessor(), 'amp_substitute', 20) + postprocessors.register(UnescapePostprocessor(), 'unescape', 10) + return postprocessors + + +class Postprocessor(util.Processor): + """ + Postprocessors are run after the ElementTree it converted back into text. + + Each Postprocessor implements a "run" method that takes a pointer to a + text string, modifies it as necessary and returns a text string. + + Postprocessors must extend markdown.Postprocessor. + + """ + + def run(self, text): + """ + Subclasses of Postprocessor should implement a `run` method, which + takes the html document as a single text string and returns a + (possibly modified) string. + + """ + pass # pragma: no cover + + +class RawHtmlPostprocessor(Postprocessor): + """ Restore raw html to the document. """ + + BLOCK_LEVEL_REGEX = re.compile(r'^\<\/?([^ >]+)') + + def run(self, text): + """ Iterate over html stash and restore html. """ + replacements = OrderedDict() + for i in range(self.md.htmlStash.html_counter): + html = self.stash_to_string(self.md.htmlStash.rawHtmlBlocks[i]) + if self.isblocklevel(html): + replacements["

{}

".format( + self.md.htmlStash.get_placeholder(i))] = html + replacements[self.md.htmlStash.get_placeholder(i)] = html + + def substitute_match(m): + key = m.group(0) + + if key not in replacements: + if key[3:-4] in replacements: + return f'

{ replacements[key[3:-4]] }

' + else: + return key + + return replacements[key] + + if replacements: + base_placeholder = util.HTML_PLACEHOLDER % r'([0-9]+)' + pattern = re.compile(f'

{ base_placeholder }

|{ base_placeholder }') + processed_text = pattern.sub(substitute_match, text) + else: + return text + + if processed_text == text: + return processed_text + else: + return self.run(processed_text) + + def isblocklevel(self, html): + m = self.BLOCK_LEVEL_REGEX.match(html) + if m: + if m.group(1)[0] in ('!', '?', '@', '%'): + # Comment, php etc... + return True + return self.md.is_block_level(m.group(1)) + return False + + def stash_to_string(self, text): + """ Convert a stashed object to a string. """ + return str(text) + + +class AndSubstitutePostprocessor(Postprocessor): + """ Restore valid entities """ + + def run(self, text): + text = text.replace(util.AMP_SUBSTITUTE, "&") + return text + + +class UnescapePostprocessor(Postprocessor): + """ Restore escaped chars """ + + RE = re.compile(r'{}(\d+){}'.format(util.STX, util.ETX)) + + def unescape(self, m): + return chr(int(m.group(1))) + + def run(self, text): + return self.RE.sub(self.unescape, text) diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/markdown/preprocessors.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/markdown/preprocessors.py new file mode 100644 index 0000000000000000000000000000000000000000..e1023c59aea5306fc457e65bf265b4e93ecc79f1 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/markdown/preprocessors.py @@ -0,0 +1,82 @@ +""" +Python Markdown + +A Python implementation of John Gruber's Markdown. + +Documentation: https://python-markdown.github.io/ +GitHub: https://github.com/Python-Markdown/markdown/ +PyPI: https://pypi.org/project/Markdown/ + +Started by Manfred Stienstra (http://www.dwerg.net/). +Maintained for a few years by Yuri Takhteyev (http://www.freewisdom.org). +Currently maintained by Waylan Limberg (https://github.com/waylan), +Dmitry Shachnev (https://github.com/mitya57) and Isaac Muse (https://github.com/facelessuser). + +Copyright 2007-2018 The Python Markdown Project (v. 1.7 and later) +Copyright 2004, 2005, 2006 Yuri Takhteyev (v. 0.2-1.6b) +Copyright 2004 Manfred Stienstra (the original version) + +License: BSD (see LICENSE.md for details). + +PRE-PROCESSORS +============================================================================= + +Preprocessors work on source text before we start doing anything too +complicated. +""" + +from . import util +from .htmlparser import HTMLExtractor +import re + + +def build_preprocessors(md, **kwargs): + """ Build the default set of preprocessors used by Markdown. """ + preprocessors = util.Registry() + preprocessors.register(NormalizeWhitespace(md), 'normalize_whitespace', 30) + preprocessors.register(HtmlBlockPreprocessor(md), 'html_block', 20) + return preprocessors + + +class Preprocessor(util.Processor): + """ + Preprocessors are run after the text is broken into lines. + + Each preprocessor implements a "run" method that takes a pointer to a + list of lines of the document, modifies it as necessary and returns + either the same pointer or a pointer to a new list. + + Preprocessors must extend markdown.Preprocessor. + + """ + def run(self, lines): + """ + Each subclass of Preprocessor should override the `run` method, which + takes the document as a list of strings split by newlines and returns + the (possibly modified) list of lines. + + """ + pass # pragma: no cover + + +class NormalizeWhitespace(Preprocessor): + """ Normalize whitespace for consistent parsing. """ + + def run(self, lines): + source = '\n'.join(lines) + source = source.replace(util.STX, "").replace(util.ETX, "") + source = source.replace("\r\n", "\n").replace("\r", "\n") + "\n\n" + source = source.expandtabs(self.md.tab_length) + source = re.sub(r'(?<=\n) +\n', '\n', source) + return source.split('\n') + + +class HtmlBlockPreprocessor(Preprocessor): + """Remove html blocks from the text and store them for later retrieval.""" + + def run(self, lines): + source = '\n'.join(lines) + parser = HTMLExtractor(self.md) + parser.feed(source) + parser.close() + return ''.join(parser.cleandoc).split('\n') diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/markdown/serializers.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/markdown/serializers.py new file mode 100644 index 0000000000000000000000000000000000000000..59bab18dfeb214c8ea00d91dfb4c1390050784a2 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/markdown/serializers.py @@ -0,0 +1,189 @@ +# markdown/searializers.py +# +# Add x/html serialization to Elementree +# Taken from ElementTree 1.3 preview with slight modifications +# +# Copyright (c) 1999-2007 by Fredrik Lundh. All rights reserved. +# +# fredrik@pythonware.com +# https://www.pythonware.com/ +# +# -------------------------------------------------------------------- +# The ElementTree toolkit is +# +# Copyright (c) 1999-2007 by Fredrik Lundh +# +# By obtaining, using, and/or copying this software and/or its +# associated documentation, you agree that you have read, understood, +# and will comply with the following terms and conditions: +# +# Permission to use, copy, modify, and distribute this software and +# its associated documentation for any purpose and without fee is +# hereby granted, provided that the above copyright notice appears in +# all copies, and that both that copyright notice and this permission +# notice appear in supporting documentation, and that the name of +# Secret Labs AB or the author not be used in advertising or publicity +# pertaining to distribution of the software without specific, written +# prior permission. +# +# SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD +# TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- +# ABILITY AND FITNESS. IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR +# BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY +# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS +# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +# OF THIS SOFTWARE. +# -------------------------------------------------------------------- + + +from xml.etree.ElementTree import ProcessingInstruction +from xml.etree.ElementTree import Comment, ElementTree, QName +import re + +__all__ = ['to_html_string', 'to_xhtml_string'] + +HTML_EMPTY = ("area", "base", "basefont", "br", "col", "frame", "hr", + "img", "input", "isindex", "link", "meta", "param") +RE_AMP = re.compile(r'&(?!(?:\#[0-9]+|\#x[0-9a-f]+|[0-9a-z]+);)', re.I) + +try: + HTML_EMPTY = set(HTML_EMPTY) +except NameError: # pragma: no cover + pass + + +def _raise_serialization_error(text): # pragma: no cover + raise TypeError( + "cannot serialize {!r} (type {})".format(text, type(text).__name__) + ) + + +def _escape_cdata(text): + # escape character data + try: + # it's worth avoiding do-nothing calls for strings that are + # shorter than 500 character, or so. assume that's, by far, + # the most common case in most applications. + if "&" in text: + # Only replace & when not part of an entity + text = RE_AMP.sub('&', text) + if "<" in text: + text = text.replace("<", "<") + if ">" in text: + text = text.replace(">", ">") + return text + except (TypeError, AttributeError): # pragma: no cover + _raise_serialization_error(text) + + +def _escape_attrib(text): + # escape attribute value + try: + if "&" in text: + # Only replace & when not part of an entity + text = RE_AMP.sub('&', text) + if "<" in text: + text = text.replace("<", "<") + if ">" in text: + text = text.replace(">", ">") + if "\"" in text: + text = text.replace("\"", """) + if "\n" in text: + text = text.replace("\n", " ") + return text + except (TypeError, AttributeError): # pragma: no cover + _raise_serialization_error(text) + + +def _escape_attrib_html(text): + # escape attribute value + try: + if "&" in text: + # Only replace & when not part of an entity + text = RE_AMP.sub('&', text) + if "<" in text: + text = text.replace("<", "<") + if ">" in text: + text = text.replace(">", ">") + if "\"" in text: + text = text.replace("\"", """) + return text + except (TypeError, AttributeError): # pragma: no cover + _raise_serialization_error(text) + + +def _serialize_html(write, elem, format): + tag = elem.tag + text = elem.text + if tag is Comment: + write("" % _escape_cdata(text)) + elif tag is ProcessingInstruction: + write("" % _escape_cdata(text)) + elif tag is None: + if text: + write(_escape_cdata(text)) + for e in elem: + _serialize_html(write, e, format) + else: + namespace_uri = None + if isinstance(tag, QName): + # QNAME objects store their data as a string: `{uri}tag` + if tag.text[:1] == "{": + namespace_uri, tag = tag.text[1:].split("}", 1) + else: + raise ValueError('QName objects must define a tag.') + write("<" + tag) + items = elem.items() + if items: + items = sorted(items) # lexical order + for k, v in items: + if isinstance(k, QName): + # Assume a text only QName + k = k.text + if isinstance(v, QName): + # Assume a text only QName + v = v.text + else: + v = _escape_attrib_html(v) + if k == v and format == 'html': + # handle boolean attributes + write(" %s" % v) + else: + write(' {}="{}"'.format(k, v)) + if namespace_uri: + write(' xmlns="%s"' % (_escape_attrib(namespace_uri))) + if format == "xhtml" and tag.lower() in HTML_EMPTY: + write(" />") + else: + write(">") + if text: + if tag.lower() in ["script", "style"]: + write(text) + else: + write(_escape_cdata(text)) + for e in elem: + _serialize_html(write, e, format) + if tag.lower() not in HTML_EMPTY: + write("") + if elem.tail: + write(_escape_cdata(elem.tail)) + + +def _write_html(root, format="html"): + assert root is not None + data = [] + write = data.append + _serialize_html(write, root, format) + return "".join(data) + + +# -------------------------------------------------------------------- +# public functions + +def to_html_string(element): + return _write_html(ElementTree(element).getroot(), format="html") + + +def to_xhtml_string(element): + return _write_html(ElementTree(element).getroot(), format="xhtml") diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/markdown/test_tools.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/markdown/test_tools.py new file mode 100644 index 0000000000000000000000000000000000000000..2ce0e74f7df46285d70fa71aa37fa725fc6748f2 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/markdown/test_tools.py @@ -0,0 +1,220 @@ +""" +Python Markdown + +A Python implementation of John Gruber's Markdown. + +Documentation: https://python-markdown.github.io/ +GitHub: https://github.com/Python-Markdown/markdown/ +PyPI: https://pypi.org/project/Markdown/ + +Started by Manfred Stienstra (http://www.dwerg.net/). +Maintained for a few years by Yuri Takhteyev (http://www.freewisdom.org). +Currently maintained by Waylan Limberg (https://github.com/waylan), +Dmitry Shachnev (https://github.com/mitya57) and Isaac Muse (https://github.com/facelessuser). + +Copyright 2007-2018 The Python Markdown Project (v. 1.7 and later) +Copyright 2004, 2005, 2006 Yuri Takhteyev (v. 0.2-1.6b) +Copyright 2004 Manfred Stienstra (the original version) + +License: BSD (see LICENSE.md for details). +""" + +import os +import sys +import unittest +import textwrap +from . import markdown, Markdown, util + +try: + import tidylib +except ImportError: + tidylib = None + +__all__ = ['TestCase', 'LegacyTestCase', 'Kwargs'] + + +class TestCase(unittest.TestCase): + """ + A unittest.TestCase subclass with helpers for testing Markdown output. + + Define `default_kwargs` as a dict of keywords to pass to Markdown for each + test. The defaults can be overridden on individual tests. + + The `assertMarkdownRenders` method accepts the source text, the expected + output, and any keywords to pass to Markdown. The `default_kwargs` are used + except where overridden by `kwargs`. The output and expected output are passed + to `TestCase.assertMultiLineEqual`. An AssertionError is raised with a diff + if the actual output does not equal the expected output. + + The `dedent` method is available to dedent triple-quoted strings if + necessary. + + In all other respects, behaves as unittest.TestCase. + """ + + default_kwargs = {} + + def assertMarkdownRenders(self, source, expected, expected_attrs=None, **kwargs): + """ + Test that source Markdown text renders to expected output with given keywords. + + `expected_attrs` accepts a dict. Each key should be the name of an attribute + on the `Markdown` instance and the value should be the expected value after + the source text is parsed by Markdown. After the expected output is tested, + the expected value for each attribute is compared against the actual + attribute of the `Markdown` instance using `TestCase.assertEqual`. + """ + + expected_attrs = expected_attrs or {} + kws = self.default_kwargs.copy() + kws.update(kwargs) + md = Markdown(**kws) + output = md.convert(source) + self.assertMultiLineEqual(output, expected) + for key, value in expected_attrs.items(): + self.assertEqual(getattr(md, key), value) + + def dedent(self, text): + """ + Dedent text. + """ + + # TODO: If/when actual output ends with a newline, then use: + # return textwrap.dedent(text.strip('/n')) + return textwrap.dedent(text).strip() + + +class recursionlimit: + """ + A context manager which temporarily modifies the Python recursion limit. + + The testing framework, coverage, etc. may add an arbitrary number of levels to the depth. To maintain consistency + in the tests, the current stack depth is determined when called, then added to the provided limit. + + Example usage: + + with recursionlimit(20): + # test code here + + See https://stackoverflow.com/a/50120316/866026 + """ + + def __init__(self, limit): + self.limit = util._get_stack_depth() + limit + self.old_limit = sys.getrecursionlimit() + + def __enter__(self): + sys.setrecursionlimit(self.limit) + + def __exit__(self, type, value, tb): + sys.setrecursionlimit(self.old_limit) + + +######################### +# Legacy Test Framework # +######################### + + +class Kwargs(dict): + """ A dict like class for holding keyword arguments. """ + pass + + +def _normalize_whitespace(text): + """ Normalize whitespace for a string of html using tidylib. """ + output, errors = tidylib.tidy_fragment(text, options={ + 'drop_empty_paras': 0, + 'fix_backslash': 0, + 'fix_bad_comments': 0, + 'fix_uri': 0, + 'join_styles': 0, + 'lower_literals': 0, + 'merge_divs': 0, + 'output_xhtml': 1, + 'quote_ampersand': 0, + 'newline': 'LF' + }) + return output + + +class LegacyTestMeta(type): + def __new__(cls, name, bases, dct): + + def generate_test(infile, outfile, normalize, kwargs): + def test(self): + with open(infile, encoding="utf-8") as f: + input = f.read() + with open(outfile, encoding="utf-8") as f: + # Normalize line endings + # (on Windows, git may have altered line endings). + expected = f.read().replace("\r\n", "\n") + output = markdown(input, **kwargs) + if tidylib and normalize: + try: + expected = _normalize_whitespace(expected) + output = _normalize_whitespace(output) + except OSError: + self.skipTest("Tidylib's c library not available.") + elif normalize: + self.skipTest('Tidylib not available.') + self.assertMultiLineEqual(output, expected) + return test + + location = dct.get('location', '') + exclude = dct.get('exclude', []) + normalize = dct.get('normalize', False) + input_ext = dct.get('input_ext', '.txt') + output_ext = dct.get('output_ext', '.html') + kwargs = dct.get('default_kwargs', Kwargs()) + + if os.path.isdir(location): + for file in os.listdir(location): + infile = os.path.join(location, file) + if os.path.isfile(infile): + tname, ext = os.path.splitext(file) + if ext == input_ext: + outfile = os.path.join(location, tname + output_ext) + tname = tname.replace(' ', '_').replace('-', '_') + kws = kwargs.copy() + if tname in dct: + kws.update(dct[tname]) + test_name = 'test_%s' % tname + if tname not in exclude: + dct[test_name] = generate_test(infile, outfile, normalize, kws) + else: + dct[test_name] = unittest.skip('Excluded')(lambda: None) + + return type.__new__(cls, name, bases, dct) + + +class LegacyTestCase(unittest.TestCase, metaclass=LegacyTestMeta): + """ + A `unittest.TestCase` subclass for running Markdown's legacy file-based tests. + + A subclass should define various properties which point to a directory of + text-based test files and define various behaviors/defaults for those tests. + The following properties are supported: + + location: A path to the directory of test files. An absolute path is preferred. + exclude: A list of tests to exclude. Each test name should comprise the filename + without an extension. + normalize: A boolean value indicating if the HTML should be normalized. + Default: `False`. + input_ext: A string containing the file extension of input files. Default: `.txt`. + ouput_ext: A string containing the file extension of expected output files. + Default: `html`. + default_kwargs: A `Kwargs` instance which stores the default set of keyword + arguments for all test files in the directory. + + In addition, properties can be defined for each individual set of test files within + the directory. The property should be given the name of the file without the file + extension. Any spaces and dashes in the filename should be replaced with + underscores. The value of the property should be a `Kwargs` instance which + contains the keyword arguments that should be passed to `Markdown` for that + test file. The keyword arguments will "update" the `default_kwargs`. + + When the class instance is created, it will walk the given directory and create + a separate unitttest for each set of test files using the naming scheme: + `test_filename`. One unittest will be run for each set of input and output files. + """ + pass diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/markdown/treeprocessors.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/markdown/treeprocessors.py new file mode 100644 index 0000000000000000000000000000000000000000..a475fdeb4aeb89addc94615b798e678729e4ad72 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/markdown/treeprocessors.py @@ -0,0 +1,436 @@ +""" +Python Markdown + +A Python implementation of John Gruber's Markdown. + +Documentation: https://python-markdown.github.io/ +GitHub: https://github.com/Python-Markdown/markdown/ +PyPI: https://pypi.org/project/Markdown/ + +Started by Manfred Stienstra (http://www.dwerg.net/). +Maintained for a few years by Yuri Takhteyev (http://www.freewisdom.org). +Currently maintained by Waylan Limberg (https://github.com/waylan), +Dmitry Shachnev (https://github.com/mitya57) and Isaac Muse (https://github.com/facelessuser). + +Copyright 2007-2018 The Python Markdown Project (v. 1.7 and later) +Copyright 2004, 2005, 2006 Yuri Takhteyev (v. 0.2-1.6b) +Copyright 2004 Manfred Stienstra (the original version) + +License: BSD (see LICENSE.md for details). +""" + +import xml.etree.ElementTree as etree +from . import util +from . import inlinepatterns + + +def build_treeprocessors(md, **kwargs): + """ Build the default treeprocessors for Markdown. """ + treeprocessors = util.Registry() + treeprocessors.register(InlineProcessor(md), 'inline', 20) + treeprocessors.register(PrettifyTreeprocessor(md), 'prettify', 10) + return treeprocessors + + +def isString(s): + """ Check if it's string """ + if not isinstance(s, util.AtomicString): + return isinstance(s, str) + return False + + +class Treeprocessor(util.Processor): + """ + Treeprocessors are run on the ElementTree object before serialization. + + Each Treeprocessor implements a "run" method that takes a pointer to an + ElementTree, modifies it as necessary and returns an ElementTree + object. + + Treeprocessors must extend markdown.Treeprocessor. + + """ + def run(self, root): + """ + Subclasses of Treeprocessor should implement a `run` method, which + takes a root ElementTree. This method can return another ElementTree + object, and the existing root ElementTree will be replaced, or it can + modify the current tree and return None. + """ + pass # pragma: no cover + + +class InlineProcessor(Treeprocessor): + """ + A Treeprocessor that traverses a tree, applying inline patterns. + """ + + def __init__(self, md): + self.__placeholder_prefix = util.INLINE_PLACEHOLDER_PREFIX + self.__placeholder_suffix = util.ETX + self.__placeholder_length = 4 + len(self.__placeholder_prefix) \ + + len(self.__placeholder_suffix) + self.__placeholder_re = util.INLINE_PLACEHOLDER_RE + self.md = md + self.inlinePatterns = md.inlinePatterns + self.ancestors = [] + + @property + @util.deprecated("Use 'md' instead.") + def markdown(self): + # TODO: remove this later + return self.md + + def __makePlaceholder(self, type): + """ Generate a placeholder """ + id = "%04d" % len(self.stashed_nodes) + hash = util.INLINE_PLACEHOLDER % id + return hash, id + + def __findPlaceholder(self, data, index): + """ + Extract id from data string, start from index + + Keyword arguments: + + * data: string + * index: index, from which we start search + + Returns: placeholder id and string index, after the found placeholder. + + """ + m = self.__placeholder_re.search(data, index) + if m: + return m.group(1), m.end() + else: + return None, index + 1 + + def __stashNode(self, node, type): + """ Add node to stash """ + placeholder, id = self.__makePlaceholder(type) + self.stashed_nodes[id] = node + return placeholder + + def __handleInline(self, data, patternIndex=0): + """ + Process string with inline patterns and replace it + with placeholders + + Keyword arguments: + + * data: A line of Markdown text + * patternIndex: The index of the inlinePattern to start with + + Returns: String with placeholders. + + """ + if not isinstance(data, util.AtomicString): + startIndex = 0 + count = len(self.inlinePatterns) + while patternIndex < count: + data, matched, startIndex = self.__applyPattern( + self.inlinePatterns[patternIndex], data, patternIndex, startIndex + ) + if not matched: + patternIndex += 1 + return data + + def __processElementText(self, node, subnode, isText=True): + """ + Process placeholders in Element.text or Element.tail + of Elements popped from self.stashed_nodes. + + Keywords arguments: + + * node: parent node + * subnode: processing node + * isText: bool variable, True - it's text, False - it's tail + + Returns: None + + """ + if isText: + text = subnode.text + subnode.text = None + else: + text = subnode.tail + subnode.tail = None + + childResult = self.__processPlaceholders(text, subnode, isText) + + if not isText and node is not subnode: + pos = list(node).index(subnode) + 1 + else: + pos = 0 + + childResult.reverse() + for newChild in childResult: + node.insert(pos, newChild[0]) + + def __processPlaceholders(self, data, parent, isText=True): + """ + Process string with placeholders and generate ElementTree tree. + + Keyword arguments: + + * data: string with placeholders instead of ElementTree elements. + * parent: Element, which contains processing inline data + + Returns: list with ElementTree elements with applied inline patterns. + + """ + def linkText(text): + if text: + if result: + if result[-1][0].tail: + result[-1][0].tail += text + else: + result[-1][0].tail = text + elif not isText: + if parent.tail: + parent.tail += text + else: + parent.tail = text + else: + if parent.text: + parent.text += text + else: + parent.text = text + result = [] + strartIndex = 0 + while data: + index = data.find(self.__placeholder_prefix, strartIndex) + if index != -1: + id, phEndIndex = self.__findPlaceholder(data, index) + + if id in self.stashed_nodes: + node = self.stashed_nodes.get(id) + + if index > 0: + text = data[strartIndex:index] + linkText(text) + + if not isString(node): # it's Element + for child in [node] + list(node): + if child.tail: + if child.tail.strip(): + self.__processElementText( + node, child, False + ) + if child.text: + if child.text.strip(): + self.__processElementText(child, child) + else: # it's just a string + linkText(node) + strartIndex = phEndIndex + continue + + strartIndex = phEndIndex + result.append((node, self.ancestors[:])) + + else: # wrong placeholder + end = index + len(self.__placeholder_prefix) + linkText(data[strartIndex:end]) + strartIndex = end + else: + text = data[strartIndex:] + if isinstance(data, util.AtomicString): + # We don't want to loose the AtomicString + text = util.AtomicString(text) + linkText(text) + data = "" + + return result + + def __applyPattern(self, pattern, data, patternIndex, startIndex=0): + """ + Check if the line fits the pattern, create the necessary + elements, add it to stashed_nodes. + + Keyword arguments: + + * data: the text to be processed + * pattern: the pattern to be checked + * patternIndex: index of current pattern + * startIndex: string index, from which we start searching + + Returns: String with placeholders instead of ElementTree elements. + + """ + new_style = isinstance(pattern, inlinepatterns.InlineProcessor) + + for exclude in pattern.ANCESTOR_EXCLUDES: + if exclude.lower() in self.ancestors: + return data, False, 0 + + if new_style: + match = None + # Since handleMatch may reject our first match, + # we iterate over the buffer looking for matches + # until we can't find any more. + for match in pattern.getCompiledRegExp().finditer(data, startIndex): + node, start, end = pattern.handleMatch(match, data) + if start is None or end is None: + startIndex += match.end(0) + match = None + continue + break + else: # pragma: no cover + match = pattern.getCompiledRegExp().match(data[startIndex:]) + leftData = data[:startIndex] + + if not match: + return data, False, 0 + + if not new_style: # pragma: no cover + node = pattern.handleMatch(match) + start = match.start(0) + end = match.end(0) + + if node is None: + return data, True, end + + if not isString(node): + if not isinstance(node.text, util.AtomicString): + # We need to process current node too + for child in [node] + list(node): + if not isString(node): + if child.text: + self.ancestors.append(child.tag.lower()) + child.text = self.__handleInline( + child.text, patternIndex + 1 + ) + self.ancestors.pop() + if child.tail: + child.tail = self.__handleInline( + child.tail, patternIndex + ) + + placeholder = self.__stashNode(node, pattern.type()) + + if new_style: + return "{}{}{}".format(data[:start], + placeholder, data[end:]), True, 0 + else: # pragma: no cover + return "{}{}{}{}".format(leftData, + match.group(1), + placeholder, match.groups()[-1]), True, 0 + + def __build_ancestors(self, parent, parents): + """Build the ancestor list.""" + ancestors = [] + while parent is not None: + if parent is not None: + ancestors.append(parent.tag.lower()) + parent = self.parent_map.get(parent) + ancestors.reverse() + parents.extend(ancestors) + + def run(self, tree, ancestors=None): + """Apply inline patterns to a parsed Markdown tree. + + Iterate over ElementTree, find elements with inline tag, apply inline + patterns and append newly created Elements to tree. If you don't + want to process your data with inline patterns, instead of normal + string, use subclass AtomicString: + + node.text = markdown.AtomicString("This will not be processed.") + + Arguments: + + * tree: ElementTree object, representing Markdown tree. + * ancestors: List of parent tag names that precede the tree node (if needed). + + Returns: ElementTree object with applied inline patterns. + + """ + self.stashed_nodes = {} + + # Ensure a valid parent list, but copy passed in lists + # to ensure we don't have the user accidentally change it on us. + tree_parents = [] if ancestors is None else ancestors[:] + + self.parent_map = {c: p for p in tree.iter() for c in p} + stack = [(tree, tree_parents)] + + while stack: + currElement, parents = stack.pop() + + self.ancestors = parents + self.__build_ancestors(currElement, self.ancestors) + + insertQueue = [] + for child in currElement: + if child.text and not isinstance( + child.text, util.AtomicString + ): + self.ancestors.append(child.tag.lower()) + text = child.text + child.text = None + lst = self.__processPlaceholders( + self.__handleInline(text), child + ) + for item in lst: + self.parent_map[item[0]] = child + stack += lst + insertQueue.append((child, lst)) + self.ancestors.pop() + if child.tail: + tail = self.__handleInline(child.tail) + dumby = etree.Element('d') + child.tail = None + tailResult = self.__processPlaceholders(tail, dumby, False) + if dumby.tail: + child.tail = dumby.tail + pos = list(currElement).index(child) + 1 + tailResult.reverse() + for newChild in tailResult: + self.parent_map[newChild[0]] = currElement + currElement.insert(pos, newChild[0]) + if len(child): + self.parent_map[child] = currElement + stack.append((child, self.ancestors[:])) + + for element, lst in insertQueue: + for i, obj in enumerate(lst): + newChild = obj[0] + element.insert(i, newChild) + return tree + + +class PrettifyTreeprocessor(Treeprocessor): + """ Add linebreaks to the html document. """ + + def _prettifyETree(self, elem): + """ Recursively add linebreaks to ElementTree children. """ + + i = "\n" + if self.md.is_block_level(elem.tag) and elem.tag not in ['code', 'pre']: + if (not elem.text or not elem.text.strip()) \ + and len(elem) and self.md.is_block_level(elem[0].tag): + elem.text = i + for e in elem: + if self.md.is_block_level(e.tag): + self._prettifyETree(e) + if not elem.tail or not elem.tail.strip(): + elem.tail = i + if not elem.tail or not elem.tail.strip(): + elem.tail = i + + def run(self, root): + """ Add linebreaks to ElementTree root object. """ + + self._prettifyETree(root) + # Do
's separately as they are often in the middle of + # inline content and missed by _prettifyETree. + brs = root.iter('br') + for br in brs: + if not br.tail or not br.tail.strip(): + br.tail = '\n' + else: + br.tail = '\n%s' % br.tail + # Clean up extra empty lines at end of code blocks. + pres = root.iter('pre') + for pre in pres: + if len(pre) and pre[0].tag == 'code': + pre[0].text = util.AtomicString(pre[0].text.rstrip() + '\n') diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/nisext/__init__.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/nisext/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..644503e3f7eda3395c6dcfc2b47022a2db506481 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/nisext/__init__.py @@ -0,0 +1,7 @@ +# init for sext package +""" Setuptools extensions + +nibabel uses these routines, and houses them, and installs them. nipy-proper +and dipy use them. +""" + diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/nisext/py3builder.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/nisext/py3builder.py new file mode 100644 index 0000000000000000000000000000000000000000..7bcaf2348c62264d161f92e75a3874708238a82f --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/nisext/py3builder.py @@ -0,0 +1,38 @@ +""" distutils utilities for porting to python 3 within 2-compatible tree """ + + +try: + from distutils.command.build_py import build_py_2to3 +except ImportError: + # 2.x - no parsing of code + from distutils.command.build_py import build_py +else: # Python 3 + # Command to also apply 2to3 to doctests + from distutils import log + class build_py(build_py_2to3): + def run_2to3(self, files): + # Add doctest parsing; this stuff copied from distutils.utils in + # python 3.2 source + if not files: + return + fixer_names, options, explicit = (self.fixer_names, + self.options, + self.explicit) + # Make this class local, to delay import of 2to3 + from lib2to3.refactor import RefactoringTool, get_fixers_from_package + class DistutilsRefactoringTool(RefactoringTool): + def log_error(self, msg, *args, **kw): + log.error(msg, *args) + + def log_message(self, msg, *args): + log.info(msg, *args) + + def log_debug(self, msg, *args): + log.debug(msg, *args) + + if fixer_names is None: + fixer_names = get_fixers_from_package('lib2to3.fixes') + r = DistutilsRefactoringTool(fixer_names, options=options) + r.refactor(files, write=True) + # Then doctests + r.refactor(files, write=True, doctests_only=True) diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/nisext/sexts.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/nisext/sexts.py new file mode 100644 index 0000000000000000000000000000000000000000..37a8adcc7c7690a637792231d6a493dce02c8a63 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/nisext/sexts.py @@ -0,0 +1,289 @@ +""" Distutils / setuptools helpers """ + +import os +from os.path import join as pjoin, split as psplit, splitext + +from configparser import ConfigParser + +from distutils.version import LooseVersion +from distutils.command.build_py import build_py +from distutils.command.install_scripts import install_scripts + +from distutils import log + + +def get_comrec_build(pkg_dir, build_cmd=build_py): + """ Return extended build command class for recording commit + + The extended command tries to run git to find the current commit, getting + the empty string if it fails. It then writes the commit hash into a file + in the `pkg_dir` path, named ``COMMIT_INFO.txt``. + + In due course this information can be used by the package after it is + installed, to tell you what commit it was installed from if known. + + To make use of this system, you need a package with a COMMIT_INFO.txt file - + e.g. ``myproject/COMMIT_INFO.txt`` - that might well look like this:: + + # This is an ini file that may contain information about the code state + [commit hash] + # The line below may contain a valid hash if it has been substituted during 'git archive' + archive_subst_hash=$Format:%h$ + # This line may be modified by the install process + install_hash= + + The COMMIT_INFO file above is also designed to be used with git substitution + - so you probably also want a ``.gitattributes`` file in the root directory + of your working tree that contains something like this:: + + myproject/COMMIT_INFO.txt export-subst + + That will cause the ``COMMIT_INFO.txt`` file to get filled in by ``git + archive`` - useful in case someone makes such an archive - for example with + via the github 'download source' button. + + Although all the above will work as is, you might consider having something + like a ``get_info()`` function in your package to display the commit + information at the terminal. See the ``pkg_info.py`` module in the nipy + package for an example. + """ + class MyBuildPy(build_cmd): + """ Subclass to write commit data into installation tree """ + def run(self): + build_cmd.run(self) + import subprocess + proc = subprocess.Popen('git rev-parse --short HEAD', + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + shell=True) + repo_commit, _ = proc.communicate() + # Fix for python 3 + repo_commit = str(repo_commit) + # We write the installation commit even if it's empty + cfg_parser = ConfigParser() + cfg_parser.read(pjoin(pkg_dir, 'COMMIT_INFO.txt')) + cfg_parser.set('commit hash', 'install_hash', repo_commit) + out_pth = pjoin(self.build_lib, pkg_dir, 'COMMIT_INFO.txt') + cfg_parser.write(open(out_pth, 'wt')) + return MyBuildPy + + +def _add_append_key(in_dict, key, value): + """ Helper for appending dependencies to setuptools args """ + # If in_dict[key] does not exist, create it + # If in_dict[key] is a string, make it len 1 list of strings + # Append value to in_dict[key] list + if key not in in_dict: + in_dict[key] = [] + elif isinstance(in_dict[key], str): + in_dict[key] = [in_dict[key]] + in_dict[key].append(value) + + +# Dependency checks +def package_check(pkg_name, version=None, + optional=False, + checker=LooseVersion, + version_getter=None, + messages=None, + setuptools_args=None + ): + """ Check if package `pkg_name` is present and has good enough version + + Has two modes of operation. If `setuptools_args` is None (the default), + raise an error for missing non-optional dependencies and log warnings for + missing optional dependencies. If `setuptools_args` is a dict, then fill + ``install_requires`` key value with any missing non-optional dependencies, + and the ``extras_requires`` key value with optional dependencies. + + This allows us to work with and without setuptools. It also means we can + check for packages that have not been installed with setuptools to avoid + installing them again. + + Parameters + ---------- + pkg_name : str + name of package as imported into python + version : {None, str}, optional + minimum version of the package that we require. If None, we don't + check the version. Default is None + optional : bool or str, optional + If ``bool(optional)`` is False, raise error for absent package or wrong + version; otherwise warn. If ``setuptools_args`` is not None, and + ``bool(optional)`` is not False, then `optional` should be a string + giving the feature name for the ``extras_require`` argument to setup. + checker : callable, optional + callable with which to return comparable thing from version + string. Default is ``distutils.version.LooseVersion`` + version_getter : {None, callable}: + Callable that takes `pkg_name` as argument, and returns the + package version string - as in:: + + ``version = version_getter(pkg_name)`` + + If None, equivalent to:: + + mod = __import__(pkg_name); version = mod.__version__`` + messages : None or dict, optional + dictionary giving output messages + setuptools_args : None or dict + If None, raise errors / warnings for missing non-optional / optional + dependencies. If dict fill key values ``install_requires`` and + ``extras_require`` for non-optional and optional dependencies. + """ + setuptools_mode = not setuptools_args is None + optional_tf = bool(optional) + if version_getter is None: + def version_getter(pkg_name): + mod = __import__(pkg_name) + return mod.__version__ + if messages is None: + messages = {} + msgs = { + 'missing': 'Cannot import package "%s" - is it installed?', + 'missing opt': 'Missing optional package "%s"', + 'opt suffix': '; you may get run-time errors', + 'version too old': 'You have version %s of package "%s"' + ' but we need version >= %s', } + msgs.update(messages) + status, have_version = _package_status(pkg_name, + version, + version_getter, + checker) + if status == 'satisfied': + return + if not setuptools_mode: + if status == 'missing': + if not optional_tf: + raise RuntimeError(msgs['missing'] % pkg_name) + log.warn(msgs['missing opt'] % pkg_name + + msgs['opt suffix']) + return + elif status == 'no-version': + raise RuntimeError(f'Cannot find version for {pkg_name}') + assert status == 'low-version' + if not optional_tf: + raise RuntimeError(msgs['version too old'] % (have_version, + pkg_name, + version)) + log.warn(msgs['version too old'] % (have_version, + pkg_name, + version) + + msgs['opt suffix']) + return + # setuptools mode + if optional_tf and not isinstance(optional, str): + raise RuntimeError('Not-False optional arg should be string') + dependency = pkg_name + if version: + dependency += '>=' + version + if optional_tf: + if not 'extras_require' in setuptools_args: + setuptools_args['extras_require'] = {} + _add_append_key(setuptools_args['extras_require'], + optional, + dependency) + return + _add_append_key(setuptools_args, 'install_requires', dependency) + return + + +def _package_status(pkg_name, version, version_getter, checker): + try: + __import__(pkg_name) + except ImportError: + return 'missing', None + if not version: + return 'satisfied', None + try: + have_version = version_getter(pkg_name) + except AttributeError: + return 'no-version', None + if checker(have_version) < checker(version): + return 'low-version', have_version + return 'satisfied', have_version + + +BAT_TEMPLATE = \ +r"""@echo off +REM wrapper to use shebang first line of {FNAME} +set mypath=%~dp0 +set pyscript="%mypath%{FNAME}" +set /p line1=<%pyscript% +if "%line1:~0,2%" == "#!" (goto :goodstart) +echo First line of %pyscript% does not start with "#!" +exit /b 1 +:goodstart +set py_exe=%line1:~2% +call "%py_exe%" %pyscript% %* +""" + +class install_scripts_bat(install_scripts): + """ Make scripts executable on Windows + + Scripts are bare file names without extension on Unix, fitting (for example) + Debian rules. They identify as python scripts with the usual ``#!`` first + line. Unix recognizes and uses this first "shebang" line, but Windows does + not. So, on Windows only we add a ``.bat`` wrapper of name + ``bare_script_name.bat`` to call ``bare_script_name`` using the python + interpreter from the #! first line of the script. + + Notes + ----- + See discussion at + https://matthew-brett.github.io/pydagogue/installing_scripts.html and + example at git://github.com/matthew-brett/myscripter.git for more + background. + """ + def run(self): + install_scripts.run(self) + if not os.name == "nt": + return + for filepath in self.get_outputs(): + # If we can find an executable name in the #! top line of the script + # file, make .bat wrapper for script. + with open(filepath, 'rt') as fobj: + first_line = fobj.readline() + if not (first_line.startswith('#!') and + 'python' in first_line.lower()): + log.info("No #!python executable found, skipping .bat " + "wrapper") + continue + pth, fname = psplit(filepath) + froot, ext = splitext(fname) + bat_file = pjoin(pth, froot + '.bat') + bat_contents = BAT_TEMPLATE.replace('{FNAME}', fname) + log.info(f"Making {bat_file} wrapper for {filepath}") + if self.dry_run: + continue + with open(bat_file, 'wt') as fobj: + fobj.write(bat_contents) + + +class Bunch(object): + def __init__(self, vars): + for key, name in vars.items(): + if key.startswith('__'): + continue + self.__dict__[key] = name + + +def read_vars_from(ver_file): + """ Read variables from Python text file + + Parameters + ---------- + ver_file : str + Filename of file to read + + Returns + ------- + info_vars : Bunch instance + Bunch object where variables read from `ver_file` appear as + attributes + """ + # Use exec for compabibility with Python 3 + ns = {} + with open(ver_file, 'rt') as fobj: + exec(fobj.read(), ns) + return Bunch(ns) diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/nisext/testers.py b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/nisext/testers.py new file mode 100644 index 0000000000000000000000000000000000000000..df26c7af39e516e099df9d77171399a2c705cf29 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/nisext/testers.py @@ -0,0 +1,533 @@ +""" Test package information in various install settings + +The routines here install the package from source directories, zips or eggs, and +check these installations by running tests, checking version information, +looking for files that were not copied over. + +The typical use for this module is as a Makefile target. For example, here are +the Makefile targets from nibabel:: + + # Check for files not installed + check-files: + $(PYTHON) -c 'from nisext.testers import check_files; check_files("nibabel")' + + # Print out info for possible install methods + check-version-info: + $(PYTHON) -c 'from nisext.testers import info_from_here; info_from_here("nibabel")' + + # Run tests from installed code + installed-tests: + $(PYTHON) -c 'from nisext.testers import tests_installed; tests_installed("nibabel")' + + # Run tests from installed code + sdist-tests: + $(PYTHON) -c 'from nisext.testers import sdist_tests; sdist_tests("nibabel")' + + # Run tests from binary egg + bdist-egg-tests: + $(PYTHON) -c 'from nisext.testers import bdist_egg_tests; bdist_egg_tests("nibabel")' + +""" + + +import os +import sys +from os.path import join as pjoin, abspath +from glob import glob +import shutil +import tempfile +import zipfile +import re +from subprocess import Popen, PIPE + +NEEDS_SHELL = os.name != 'nt' +PYTHON=sys.executable +HAVE_PUTENV = hasattr(os, 'putenv') + +PY_LIB_SDIR = 'pylib' + +def back_tick(cmd, ret_err=False, as_str=True): + """ Run command `cmd`, return stdout, or stdout, stderr if `ret_err` + + Roughly equivalent to ``check_output`` in Python 2.7 + + Parameters + ---------- + cmd : str + command to execute + ret_err : bool, optional + If True, return stderr in addition to stdout. If False, just return + stdout + as_str : bool, optional + Whether to decode outputs to unicode string on exit. + + Returns + ------- + out : str or tuple + If `ret_err` is False, return stripped string containing stdout from + `cmd`. If `ret_err` is True, return tuple of (stdout, stderr) where + ``stdout`` is the stripped stdout, and ``stderr`` is the stripped + stderr. + + Raises + ------ + RuntimeError + if command returns non-zero exit code. + """ + proc = Popen(cmd, stdout=PIPE, stderr=PIPE, shell=NEEDS_SHELL) + out, err = proc.communicate() + retcode = proc.returncode + if retcode is None: + proc.terminate() + raise RuntimeError(cmd + ' process did not terminate') + if retcode != 0: + raise RuntimeError(cmd + ' process returned code %d' % retcode) + out = out.strip() + if as_str: + out = out.decode('latin-1') + if not ret_err: + return out + err = err.strip() + if as_str: + err = err.decode('latin-1') + return out, err + + +def run_mod_cmd(mod_name, pkg_path, cmd, script_dir=None, print_location=True): + """ Run command in own process in anonymous path + + Parameters + ---------- + mod_name : str + Name of module to import - e.g. 'nibabel' + pkg_path : str + directory containing `mod_name` package. Typically that will be the + directory containing the e.g. 'nibabel' directory. + cmd : str + Python command to execute + script_dir : None or str, optional + script directory to prepend to PATH + print_location : bool, optional + Whether to print the location of the imported `mod_name` + + Returns + ------- + stdout : str + stdout as str + stderr : str + stderr as str + """ + if script_dir is None: + paths_add = '' + else: + if not HAVE_PUTENV: + raise RuntimeError('We cannot set environment variables') + # Need to add the python path for the scripts to pick up our package in + # their environment, because the scripts will get called via the shell + # (via `cmd`). Consider that PYTHONPATH may not be set. Because the + # command might run scripts via the shell, prepend script_dir to the + # system path also. + paths_add = \ +r""" +os.environ['PATH'] = r'"{script_dir}"' + os.path.pathsep + os.environ['PATH'] +PYTHONPATH = os.environ.get('PYTHONPATH') +if PYTHONPATH is None: + os.environ['PYTHONPATH'] = r'"{pkg_path}"' +else: + os.environ['PYTHONPATH'] = r'"{pkg_path}"' + os.path.pathsep + PYTHONPATH +""".format(**locals()) + if print_location: + p_loc = f'print({mod_name}.__file__);' + else: + p_loc = '' + cwd = os.getcwd() + tmpdir = tempfile.mkdtemp() + try: + os.chdir(tmpdir) + with open('script.py', 'wt') as fobj: + fobj.write( +r""" +import os +import sys +sys.path.insert(0, r"{pkg_path}") +{paths_add} +import {mod_name} +{p_loc} +{cmd}""".format(**locals())) + res = back_tick(f'{PYTHON} script.py', ret_err=True) + finally: + os.chdir(cwd) + shutil.rmtree(tmpdir) + return res + + +def zip_extract_all(fname, path=None): + """ Extract all members from zipfile + + Deals with situation where the directory is stored in the zipfile as a name, + as well as files that have to go into this directory. + """ + zf = zipfile.ZipFile(fname) + members = zf.namelist() + # Remove members that are just bare directories + members = [m for m in members if not m.endswith('/')] + for zipinfo in members: + zf.extract(zipinfo, path, None) + + +def install_from_to(from_dir, to_dir, py_lib_sdir=PY_LIB_SDIR, bin_sdir='bin'): + """ Install package in `from_dir` to standard location in `to_dir` + + Parameters + ---------- + from_dir : str + path containing files to install with ``python setup.py ...`` + to_dir : str + prefix path to which files will be installed, as in ``python setup.py + install --prefix=to_dir`` + py_lib_sdir : str, optional + subdirectory within `to_dir` to which library code will be installed + bin_sdir : str, optional + subdirectory within `to_dir` to which scripts will be installed + """ + site_pkgs_path = os.path.join(to_dir, py_lib_sdir) + py_lib_locs = (f' --install-purelib={site_pkgs_path} ' + f'--install-platlib={site_pkgs_path}') + pwd = os.path.abspath(os.getcwd()) + cmd = f'{PYTHON} setup.py --quiet install --prefix={to_dir} {py_lib_locs}' + try: + os.chdir(from_dir) + back_tick(cmd) + finally: + os.chdir(pwd) + + +def install_from_zip(zip_fname, install_path, pkg_finder=None, + py_lib_sdir=PY_LIB_SDIR, + script_sdir='bin'): + """ Install package from zip file `zip_fname` + + Parameters + ---------- + zip_fname : str + filename of zip file containing package code + install_path : str + output prefix at which to install package + pkg_finder : None or callable, optional + If None, assume zip contains ``setup.py`` at the top level. Otherwise, + find directory containing ``setup.py`` with ``pth = + pkg_finder(unzip_path)`` where ``unzip_path`` is the path to which we + have unzipped the zip file contents. + py_lib_sdir : str, optional + subdirectory to which to write the library code from the package. Thus + if package called ``nibabel``, the written code will be in + ``//nibabel + script_sdir : str, optional + subdirectory to which we write the installed scripts. Thus scripts will + be written to ``/ + """ + unzip_path = tempfile.mkdtemp() + try: + # Zip may unpack module into current directory + zip_extract_all(zip_fname, unzip_path) + if pkg_finder is None: + from_path = unzip_path + else: + from_path = pkg_finder(unzip_path) + install_from_to(from_path, install_path, py_lib_sdir, script_sdir) + finally: + shutil.rmtree(unzip_path) + + +def contexts_print_info(mod_name, repo_path, install_path): + """ Print result of get_info from different installation routes + + Runs installation from: + + * git archive zip file + * with setup.py install from repository directory + * just running code from repository directory + + and prints out result of get_info in each case. There will be many files + written into `install_path` that you may want to clean up somehow. + + Parameters + ---------- + mod_name : str + package name that will be installed, and tested + repo_path : str + path to location of git repository + install_path : str + path into which to install temporary installations + """ + site_pkgs_path = os.path.join(install_path, PY_LIB_SDIR) + # first test archive + pwd = os.path.abspath(os.getcwd()) + out_fname = pjoin(install_path, 'test.zip') + try: + os.chdir(repo_path) + back_tick(f'git archive --format zip -o {out_fname} HEAD') + finally: + os.chdir(pwd) + install_from_zip(out_fname, install_path, None) + cmd_str = f'print({mod_name}.get_info())' + print(run_mod_cmd(mod_name, site_pkgs_path, cmd_str)[0]) + # now test install into a directory from the repository + install_from_to(repo_path, install_path, PY_LIB_SDIR) + print(run_mod_cmd(mod_name, site_pkgs_path, cmd_str)[0]) + # test from development tree + print(run_mod_cmd(mod_name, repo_path, cmd_str)[0]) + return + + +def info_from_here(mod_name): + """ Run info context checks starting in working directory + + Runs checks from current working directory, installing temporary + installations into a new temporary directory + + Parameters + ---------- + mod_name : str + package name that will be installed, and tested + """ + repo_path = os.path.abspath(os.getcwd()) + install_path = tempfile.mkdtemp() + try: + contexts_print_info(mod_name, repo_path, install_path) + finally: + shutil.rmtree(install_path) + + +def tests_installed(mod_name, source_path=None): + """ Install from `source_path` into temporary directory; run tests + + Parameters + ---------- + mod_name : str + name of module - e.g. 'nibabel' + source_path : None or str + Path from which to install. If None, defaults to working directory + """ + if source_path is None: + source_path = os.path.abspath(os.getcwd()) + install_path = tempfile.mkdtemp() + site_pkgs_path = pjoin(install_path, PY_LIB_SDIR) + scripts_path = pjoin(install_path, 'bin') + try: + install_from_to(source_path, install_path, PY_LIB_SDIR, 'bin') + stdout, stderr = run_mod_cmd(mod_name, + site_pkgs_path, + mod_name + '.test()', + scripts_path) + finally: + shutil.rmtree(install_path) + print(stdout) + print(stderr) + +# Tell nose this is not a test +tests_installed.__test__ = False + + +def check_installed_files(repo_mod_path, install_mod_path): + """ Check files in `repo_mod_path` are installed at `install_mod_path` + + At the moment, all this does is check that all the ``*.py`` files in + `repo_mod_path` are installed at `install_mod_path`. + + Parameters + ---------- + repo_mod_path : str + repository path containing package files, e.g. /nibabel> + install_mod_path : str + path at which package has been installed. This is the path where the + root package ``__init__.py`` lives. + + Return + ------ + uninstalled : list + list of files that should have been installed, but have not been + installed + """ + return missing_from(repo_mod_path, install_mod_path, filter=r"\.py$") + + +def missing_from(path0, path1, filter=None): + """ Return filenames present in `path0` but not in `path1` + + Parameters + ---------- + path0 : str + path which contains all files of interest + path1 : str + path which should contain all files of interest + filter : None or str or regexp, optional + A successful result from ``filter.search(fname)`` means the file is of + interest. None means all files are of interest + + Returns + ------- + path1_missing : list + list of all files missing from `path1` that are in `path0` at the same + relative path. + """ + if not filter is None: + filter = re.compile(filter) + uninstalled = [] + # Walk directory tree to get py files + for dirpath, dirnames, filenames in os.walk(path0): + out_dirpath = dirpath.replace(path0, path1) + for fname in filenames: + if not filter is None and filter.search(fname) is None: + continue + equiv_fname = os.path.join(out_dirpath, fname) + if not os.path.isfile(equiv_fname): + uninstalled.append(pjoin(dirpath, fname)) + return uninstalled + + +def check_files(mod_name, repo_path=None, scripts_sdir='bin'): + """ Print library and script files not picked up during install + """ + if repo_path is None: + repo_path = abspath(os.getcwd()) + install_path = tempfile.mkdtemp() + repo_mod_path = pjoin(repo_path, mod_name) + installed_mod_path = pjoin(install_path, PY_LIB_SDIR, mod_name) + repo_bin = pjoin(repo_path, 'bin') + installed_bin = pjoin(install_path, 'bin') + try: + zip_fname = make_dist(repo_path, + install_path, + 'sdist --formats=zip', + '*.zip') + pf = get_sdist_finder(mod_name) + install_from_zip(zip_fname, install_path, pf, PY_LIB_SDIR, scripts_sdir) + lib_misses = missing_from(repo_mod_path, installed_mod_path, r"\.py$") + script_misses = missing_from(repo_bin, installed_bin) + finally: + shutil.rmtree(install_path) + if lib_misses: + print("Missed library files: ", ', '.join(lib_misses)) + else: + print("You got all the library files") + if script_misses: + print("Missed script files: ", ', '.join(script_misses)) + else: + print("You got all the script files") + return len(lib_misses) > 0 or len(script_misses) > 0 + + +def get_sdist_finder(mod_name): + """ Return function finding sdist source directory for `mod_name` + """ + def pf(pth): + pkg_dirs = glob(pjoin(pth, mod_name + '-*')) + if len(pkg_dirs) != 1: + raise OSError('There must be one and only one package dir') + return pkg_dirs[0] + return pf + + +def sdist_tests(mod_name, repo_path=None, label='fast', doctests=True): + """ Make sdist zip, install from it, and run tests """ + if repo_path is None: + repo_path = abspath(os.getcwd()) + install_path = tempfile.mkdtemp() + try: + zip_fname = make_dist(repo_path, + install_path, + 'sdist --formats=zip', + '*.zip') + pf = get_sdist_finder(mod_name) + install_from_zip(zip_fname, install_path, pf, PY_LIB_SDIR, 'bin') + site_pkgs_path = pjoin(install_path, PY_LIB_SDIR) + script_path = pjoin(install_path, 'bin') + cmd = f"{mod_name}.test(label='{label}', doctests={doctests})" + stdout, stderr = run_mod_cmd(mod_name, + site_pkgs_path, + cmd, + script_path) + finally: + shutil.rmtree(install_path) + print(stdout) + print(stderr) + +sdist_tests.__test__ = False + + +def bdist_egg_tests(mod_name, repo_path=None, label='fast', doctests=True): + """ Make bdist_egg, unzip it, and run tests from result + + We've got a problem here, because the egg does not contain the scripts, and + so, if we are testing the scripts with ``mod.test()``, we won't pick up the + scripts from the repository we are testing. + + So, you might need to add a label to the script tests, and use the `label` + parameter to indicate these should be skipped. As in: + + bdist_egg_tests('nibabel', None, label='not script_test') + """ + if repo_path is None: + repo_path = abspath(os.getcwd()) + install_path = tempfile.mkdtemp() + scripts_path = pjoin(install_path, 'bin') + try: + zip_fname = make_dist(repo_path, + install_path, + 'bdist_egg', + '*.egg') + zip_extract_all(zip_fname, install_path) + cmd = f"{mod_name}.test(label='{label}', doctests={doctests})" + stdout, stderr = run_mod_cmd(mod_name, + install_path, + cmd, + scripts_path) + finally: + shutil.rmtree(install_path) + print(stdout) + print(stderr) + +bdist_egg_tests.__test__ = False + + +def make_dist(repo_path, out_dir, setup_params, zipglob): + """ Create distutils distribution file + + Parameters + ---------- + repo_path : str + path to repository containing code and ``setup.py`` + out_dir : str + path to which to write new distribution file + setup_params: str + parameters to pass to ``setup.py`` to create distribution. + zipglob : str + glob identifying expected output file. + + Returns + ------- + out_fname : str + filename of generated distribution file + + Examples + -------- + Make, return a zipped sdist:: + + make_dist('/path/to/repo', '/tmp/path', 'sdist --formats=zip', '*.zip') + + Make, return a binary egg:: + + make_dist('/path/to/repo', '/tmp/path', 'bdist_egg', '*.egg') + """ + pwd = os.path.abspath(os.getcwd()) + try: + os.chdir(repo_path) + back_tick(f'{PYTHON} setup.py {setup_params} --dist-dir={out_dir}') + zips = glob(pjoin(out_dir, zipglob)) + if len(zips) != 1: + raise OSError(f"There must be one and only one {zipglob} " + f"file, but I found \"{': '.join(zips)}\"") + finally: + os.chdir(pwd) + return zips[0] diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/oauthlib-3.2.0.dist-info/METADATA b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/oauthlib-3.2.0.dist-info/METADATA new file mode 100644 index 0000000000000000000000000000000000000000..efa7496396ec5ba6f6a8baa554882e350f9724f4 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/oauthlib-3.2.0.dist-info/METADATA @@ -0,0 +1,181 @@ +Metadata-Version: 2.1 +Name: oauthlib +Version: 3.2.0 +Summary: A generic, spec-compliant, thorough implementation of the OAuth request-signing logic +Home-page: https://github.com/oauthlib/oauthlib +Author: The OAuthlib Community +Author-email: idan@gazit.me +Maintainer: Ib Lundgren +Maintainer-email: ib.lundgren@gmail.com +License: BSD +Platform: any +Classifier: Development Status :: 5 - Production/Stable +Classifier: Environment :: Web Environment +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved +Classifier: License :: OSI Approved :: BSD License +Classifier: Operating System :: MacOS +Classifier: Operating System :: POSIX +Classifier: Operating System :: POSIX :: Linux +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3 :: Only +Classifier: Programming Language :: Python :: Implementation +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Requires-Python: >=3.6 +Description-Content-Type: text/x-rst +License-File: LICENSE +Provides-Extra: rsa +Requires-Dist: cryptography (>=3.0.0) ; extra == 'rsa' +Provides-Extra: signals +Requires-Dist: blinker (>=1.4.0) ; extra == 'signals' +Provides-Extra: signedtoken +Requires-Dist: cryptography (>=3.0.0) ; extra == 'signedtoken' +Requires-Dist: pyjwt (<3,>=2.0.0) ; extra == 'signedtoken' + +OAuthLib - Python Framework for OAuth1 & OAuth2 +=============================================== + +*A generic, spec-compliant, thorough implementation of the OAuth request-signing +logic for Python 3.6+.* + +.. image:: https://travis-ci.org/oauthlib/oauthlib.svg?branch=master + :target: https://travis-ci.org/oauthlib/oauthlib + :alt: Travis +.. image:: https://coveralls.io/repos/oauthlib/oauthlib/badge.svg?branch=master + :target: https://coveralls.io/r/oauthlib/oauthlib + :alt: Coveralls +.. image:: https://img.shields.io/pypi/pyversions/oauthlib.svg + :target: https://pypi.org/project/oauthlib/ + :alt: Download from PyPI +.. image:: https://img.shields.io/pypi/l/oauthlib.svg + :target: https://pypi.org/project/oauthlib/ + :alt: License +.. image:: https://app.fossa.io/api/projects/git%2Bgithub.com%2Foauthlib%2Foauthlib.svg?type=shield + :target: https://app.fossa.io/projects/git%2Bgithub.com%2Foauthlib%2Foauthlib?ref=badge_shield + :alt: FOSSA Status +.. image:: https://img.shields.io/readthedocs/oauthlib.svg + :target: https://oauthlib.readthedocs.io/en/latest/index.html + :alt: Read the Docs +.. image:: https://badges.gitter.im/oauthlib/oauthlib.svg + :target: https://gitter.im/oauthlib/Lobby + :alt: Chat on Gitter + + +.. image:: https://raw.githubusercontent.com/oauthlib/oauthlib/8d71b161fd145d11c40d55c9ab66ac134a303253/docs/logo/oauthlib-banner-700x192.png + :target: https://github.com/oauthlib/oauthlib/ + :alt: OAuth + Python = OAuthlib Python Framework + + +OAuth often seems complicated and difficult-to-implement. There are several +prominent libraries for handling OAuth requests, but they all suffer from one or +both of the following: + +1. They predate the `OAuth 1.0 spec`_, AKA RFC 5849. +2. They predate the `OAuth 2.0 spec`_, AKA RFC 6749. +3. They assume the usage of a specific HTTP request library. + +.. _`OAuth 1.0 spec`: https://tools.ietf.org/html/rfc5849 +.. _`OAuth 2.0 spec`: https://tools.ietf.org/html/rfc6749 + +OAuthLib is a framework which implements the logic of OAuth1 or OAuth2 without +assuming a specific HTTP request object or web framework. Use it to graft OAuth +client support onto your favorite HTTP library, or provide support onto your +favourite web framework. If you're a maintainer of such a library, write a thin +veneer on top of OAuthLib and get OAuth support for very little effort. + + +Documentation +-------------- + +Full documentation is available on `Read the Docs`_. All contributions are very +welcome! The documentation is still quite sparse, please open an issue for what +you'd like to know, or discuss it in our `Gitter community`_, or even better, send a +pull request! + +.. _`Gitter community`: https://gitter.im/oauthlib/Lobby +.. _`Read the Docs`: https://oauthlib.readthedocs.io/en/latest/index.html + +Interested in making OAuth requests? +------------------------------------ + +Then you might be more interested in using `requests`_ which has OAuthLib +powered OAuth support provided by the `requests-oauthlib`_ library. + +.. _`requests`: https://github.com/requests/requests +.. _`requests-oauthlib`: https://github.com/requests/requests-oauthlib + +Which web frameworks are supported? +----------------------------------- + +The following packages provide OAuth support using OAuthLib. + +- For Django there is `django-oauth-toolkit`_, which includes `Django REST framework`_ support. +- For Flask there is `flask-oauthlib`_ and `Flask-Dance`_. +- For Pyramid there is `pyramid-oauthlib`_. +- For Bottle there is `bottle-oauthlib`_. + +If you have written an OAuthLib package that supports your favorite framework, +please open a Pull Request, updating the documentation. + +.. _`django-oauth-toolkit`: https://github.com/evonove/django-oauth-toolkit +.. _`flask-oauthlib`: https://github.com/lepture/flask-oauthlib +.. _`Django REST framework`: http://django-rest-framework.org +.. _`Flask-Dance`: https://github.com/singingwolfboy/flask-dance +.. _`pyramid-oauthlib`: https://github.com/tilgovi/pyramid-oauthlib +.. _`bottle-oauthlib`: https://github.com/thomsonreuters/bottle-oauthlib + +Using OAuthLib? Please get in touch! +------------------------------------ +Patching OAuth support onto an http request framework? Creating an OAuth +provider extension for a web framework? Simply using OAuthLib to Get Things Done +or to learn? + +No matter which we'd love to hear from you in our `Gitter community`_ or if you have +anything in particular you would like to have, change or comment on don't +hesitate for a second to send a pull request or open an issue. We might be quite +busy and therefore slow to reply but we love feedback! + +Chances are you have run into something annoying that you wish there was +documentation for, if you wish to gain eternal fame and glory, and a drink if we +have the pleasure to run into eachother, please send a docs pull request =) + +.. _`Gitter community`: https://gitter.im/oauthlib/Lobby + +License +------- + +OAuthLib is yours to use and abuse according to the terms of the BSD license. +Check the LICENSE file for full details. + +Credits +------- + +OAuthLib has been started and maintained several years by Idan Gazit and other +amazing `AUTHORS`_. Thanks to their wonderful work, the open-source `community`_ +creation has been possible and the project can stay active and reactive to users +requests. + + +.. _`AUTHORS`: https://github.com/oauthlib/oauthlib/blob/master/AUTHORS +.. _`community`: https://github.com/oauthlib/ + +Changelog +--------- + +*OAuthLib is in active development, with the core of both OAuth1 and OAuth2 +completed, for providers as well as clients.* See `supported features`_ for +details. + +.. _`supported features`: https://oauthlib.readthedocs.io/en/latest/feature_matrix.html + +For a full changelog see ``CHANGELOG.rst``. + + diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/oauthlib-3.2.0.dist-info/RECORD b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/oauthlib-3.2.0.dist-info/RECORD new file mode 100644 index 0000000000000000000000000000000000000000..22f1776364df549cd666d85eb81121affb43b03d --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/oauthlib-3.2.0.dist-info/RECORD @@ -0,0 +1,143 @@ +oauthlib-3.2.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +oauthlib-3.2.0.dist-info/LICENSE,sha256=PR4S2KxSwLbBSK9tKR9yQAuHIO0WwKxKiYaLbRSxyTk,1530 +oauthlib-3.2.0.dist-info/METADATA,sha256=4BfXhM-eajiPmT96iyP4bykMyHf_Xz2pfggvcOyrNv0,7447 +oauthlib-3.2.0.dist-info/RECORD,, +oauthlib-3.2.0.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +oauthlib-3.2.0.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92 +oauthlib-3.2.0.dist-info/top_level.txt,sha256=gz2py0fFs1AhG1O7KpHPcIXOgXOwdIiCaSnmLkiR12Q,9 +oauthlib/__init__.py,sha256=mhqqb9kZLISCLzTMXwHwdDnS3q_7-NQciRNsQr_1q5M,686 +oauthlib/__pycache__/__init__.cpython-38.pyc,, +oauthlib/__pycache__/common.cpython-38.pyc,, +oauthlib/__pycache__/signals.cpython-38.pyc,, +oauthlib/__pycache__/uri_validate.cpython-38.pyc,, +oauthlib/common.py,sha256=FimXHIfgk-XVgzu3lq6-wv3Jsq7hzGgsurwGvTm3t3A,13422 +oauthlib/oauth1/__init__.py,sha256=U_6yHcB8jdYPbcas4CBel7tE_YYCN5S1300U3zVlWlE,1187 +oauthlib/oauth1/__pycache__/__init__.cpython-38.pyc,, +oauthlib/oauth1/rfc5849/__init__.py,sha256=-5sJHDG3JRZQRJYlCjkj3CP2jZgqEg0OY5pVIxE4mxE,16744 +oauthlib/oauth1/rfc5849/__pycache__/__init__.cpython-38.pyc,, +oauthlib/oauth1/rfc5849/__pycache__/errors.cpython-38.pyc,, +oauthlib/oauth1/rfc5849/__pycache__/parameters.cpython-38.pyc,, +oauthlib/oauth1/rfc5849/__pycache__/request_validator.cpython-38.pyc,, +oauthlib/oauth1/rfc5849/__pycache__/signature.cpython-38.pyc,, +oauthlib/oauth1/rfc5849/__pycache__/utils.cpython-38.pyc,, +oauthlib/oauth1/rfc5849/endpoints/__init__.py,sha256=SeIECziJ-Sv_NCGnowG3P9UnX_VdFNldRqRywEaJvxY,327 +oauthlib/oauth1/rfc5849/endpoints/__pycache__/__init__.cpython-38.pyc,, +oauthlib/oauth1/rfc5849/endpoints/__pycache__/access_token.cpython-38.pyc,, +oauthlib/oauth1/rfc5849/endpoints/__pycache__/authorization.cpython-38.pyc,, +oauthlib/oauth1/rfc5849/endpoints/__pycache__/base.cpython-38.pyc,, +oauthlib/oauth1/rfc5849/endpoints/__pycache__/pre_configured.cpython-38.pyc,, +oauthlib/oauth1/rfc5849/endpoints/__pycache__/request_token.cpython-38.pyc,, +oauthlib/oauth1/rfc5849/endpoints/__pycache__/resource.cpython-38.pyc,, +oauthlib/oauth1/rfc5849/endpoints/__pycache__/signature_only.cpython-38.pyc,, +oauthlib/oauth1/rfc5849/endpoints/access_token.py,sha256=CRgLV5DqDiwVvbo8MiHySbTEKrxETJV29-VGu-2kQ7Y,9347 +oauthlib/oauth1/rfc5849/endpoints/authorization.py,sha256=zbU7TzO6nB6853UIqtTkhxUV-JTHOdOc-CvdQsIQKWk,6724 +oauthlib/oauth1/rfc5849/endpoints/base.py,sha256=pBOS1MqIrJVxydTD6jnzZcGZRh_NMbRmT1c_c2ISKVs,11643 +oauthlib/oauth1/rfc5849/endpoints/pre_configured.py,sha256=Ie5oBUq_JTsXQdvfWhcMRjhH3OOxS_mRHbKBQ9TpsGg,543 +oauthlib/oauth1/rfc5849/endpoints/request_token.py,sha256=Nz-d7ShVB5Hlh9cAKTp-KHeHH_t5f7khvtCVT8avM9Q,9293 +oauthlib/oauth1/rfc5849/endpoints/resource.py,sha256=rmzBuF0FyrLTpaAehFx0wkj0laAoe7XTdbbeRTrUCZQ,7376 +oauthlib/oauth1/rfc5849/endpoints/signature_only.py,sha256=MX5zV66v4-wrR4cu7OmOd_GF3L8ysM60HmEiHtRR0l8,3327 +oauthlib/oauth1/rfc5849/errors.py,sha256=WPvKVjPlgkCYp6TXvcwC8VETkhsZBzphKCkTJKDPNfM,2474 +oauthlib/oauth1/rfc5849/parameters.py,sha256=Abnxpix_Yy7P3A3vbkrV2bkFxtnR5TRTTKdOu9MKydo,4802 +oauthlib/oauth1/rfc5849/request_validator.py,sha256=x1c8EdFxdvSvilHQ_ZavkiSDjPy6gkYb0gMhXqLr7cw,30988 +oauthlib/oauth1/rfc5849/signature.py,sha256=FBrizlpvzlHjsJbT3AMmYOyBD_OnpOeEdSxXCg-1iAY,32024 +oauthlib/oauth1/rfc5849/utils.py,sha256=IapG_jM6iMe4e0DYWWds1jp-wce2Lf_cuhFrtCP_2ls,2613 +oauthlib/oauth2/__init__.py,sha256=uPkdHF2NEpIM6Ybz-jPPEKU5e56eHptaOz2NPwppyys,1597 +oauthlib/oauth2/__pycache__/__init__.cpython-38.pyc,, +oauthlib/oauth2/rfc6749/__init__.py,sha256=sJcxfdG6HTloXzhkG8-PTJTVQWoCeNtnw6ODNCJNw58,404 +oauthlib/oauth2/rfc6749/__pycache__/__init__.cpython-38.pyc,, +oauthlib/oauth2/rfc6749/__pycache__/errors.cpython-38.pyc,, +oauthlib/oauth2/rfc6749/__pycache__/parameters.cpython-38.pyc,, +oauthlib/oauth2/rfc6749/__pycache__/request_validator.cpython-38.pyc,, +oauthlib/oauth2/rfc6749/__pycache__/tokens.cpython-38.pyc,, +oauthlib/oauth2/rfc6749/__pycache__/utils.cpython-38.pyc,, +oauthlib/oauth2/rfc6749/clients/__init__.py,sha256=TuYtiErfo0_Ej0816tIv5rBsrwA9BjYz3tu_ZM0X364,504 +oauthlib/oauth2/rfc6749/clients/__pycache__/__init__.cpython-38.pyc,, +oauthlib/oauth2/rfc6749/clients/__pycache__/backend_application.cpython-38.pyc,, +oauthlib/oauth2/rfc6749/clients/__pycache__/base.cpython-38.pyc,, +oauthlib/oauth2/rfc6749/clients/__pycache__/legacy_application.cpython-38.pyc,, +oauthlib/oauth2/rfc6749/clients/__pycache__/mobile_application.cpython-38.pyc,, +oauthlib/oauth2/rfc6749/clients/__pycache__/service_application.cpython-38.pyc,, +oauthlib/oauth2/rfc6749/clients/__pycache__/web_application.cpython-38.pyc,, +oauthlib/oauth2/rfc6749/clients/backend_application.py,sha256=CAhmHPY3vJ1-McjrMQ4TgJXXqx2Ls9PLfuPWUV0JEtY,3223 +oauthlib/oauth2/rfc6749/clients/base.py,sha256=q1_tKeEE-3KBUxUrIneMXabiBK9T9iGr9aXaowdPB6E,26575 +oauthlib/oauth2/rfc6749/clients/legacy_application.py,sha256=FVDcZNyJK-uSSAPJUQMM3Ud_-EAzJJ8pZ5rr937c7NY,4031 +oauthlib/oauth2/rfc6749/clients/mobile_application.py,sha256=nuM6Gp7jZtY6xP85j1hQUp1nvW_6MpM_dK3wJntKxb4,8877 +oauthlib/oauth2/rfc6749/clients/service_application.py,sha256=fBxB-eY6kG1NKrl5jGfFCJFAJt_PJP8opUdRKY7sojA,7810 +oauthlib/oauth2/rfc6749/clients/web_application.py,sha256=2wtPArVJipR0n3kSCDca-V2SQuVPl4PhGWl57LiOxDo,12086 +oauthlib/oauth2/rfc6749/endpoints/__init__.py,sha256=RL_txhULl35A74dbvlJ7nvqwp3GMCSCpg_4TvjoO-Xk,553 +oauthlib/oauth2/rfc6749/endpoints/__pycache__/__init__.cpython-38.pyc,, +oauthlib/oauth2/rfc6749/endpoints/__pycache__/authorization.cpython-38.pyc,, +oauthlib/oauth2/rfc6749/endpoints/__pycache__/base.cpython-38.pyc,, +oauthlib/oauth2/rfc6749/endpoints/__pycache__/introspect.cpython-38.pyc,, +oauthlib/oauth2/rfc6749/endpoints/__pycache__/metadata.cpython-38.pyc,, +oauthlib/oauth2/rfc6749/endpoints/__pycache__/pre_configured.cpython-38.pyc,, +oauthlib/oauth2/rfc6749/endpoints/__pycache__/resource.cpython-38.pyc,, +oauthlib/oauth2/rfc6749/endpoints/__pycache__/revocation.cpython-38.pyc,, +oauthlib/oauth2/rfc6749/endpoints/__pycache__/token.cpython-38.pyc,, +oauthlib/oauth2/rfc6749/endpoints/authorization.py,sha256=2N2Cb_TQtpUPcqDIclsJnZERtaMKmH9uSgGoMZLFnUI,4584 +oauthlib/oauth2/rfc6749/endpoints/base.py,sha256=fUhCGaftD5bm5PstA6L2CqUNb9kHDpUj4_BsvLRbi4w,4130 +oauthlib/oauth2/rfc6749/endpoints/introspect.py,sha256=SGVI0jI1KmstheTNxMWfngNWCtvdkNTi-H_o3MRQvHE,4983 +oauthlib/oauth2/rfc6749/endpoints/metadata.py,sha256=ySOnnACtwTCjXmojYwZA_EC3EU7OMBlJ117x9P9xxuM,10516 +oauthlib/oauth2/rfc6749/endpoints/pre_configured.py,sha256=ChhORao78XGGlnikJsLb6d_FZvKaLGBUM-te-84NeJ8,11954 +oauthlib/oauth2/rfc6749/endpoints/resource.py,sha256=vpXoovgpmByY-IuW0PDccS5IJGFoFiLVjLLUpGFmXX4,3248 +oauthlib/oauth2/rfc6749/endpoints/revocation.py,sha256=hH3F2G3-QmqCQ1tE4yN2AQfaQ2lEB46YkO5-n1ophGE,5212 +oauthlib/oauth2/rfc6749/endpoints/token.py,sha256=iJDlaSkVR8U6s1_T9fiyVnLgfCgOWsq9PFDcmzL74H4,4595 +oauthlib/oauth2/rfc6749/errors.py,sha256=5EE4Qs3ru34d33wqaFo-WGOofLLYK1jTov9sqG92CW0,12947 +oauthlib/oauth2/rfc6749/grant_types/__init__.py,sha256=im_XwEWmw3dhmzcdfyhkN38xZopBhL3cRShmmCtqQs0,368 +oauthlib/oauth2/rfc6749/grant_types/__pycache__/__init__.cpython-38.pyc,, +oauthlib/oauth2/rfc6749/grant_types/__pycache__/authorization_code.cpython-38.pyc,, +oauthlib/oauth2/rfc6749/grant_types/__pycache__/base.cpython-38.pyc,, +oauthlib/oauth2/rfc6749/grant_types/__pycache__/client_credentials.cpython-38.pyc,, +oauthlib/oauth2/rfc6749/grant_types/__pycache__/implicit.cpython-38.pyc,, +oauthlib/oauth2/rfc6749/grant_types/__pycache__/refresh_token.cpython-38.pyc,, +oauthlib/oauth2/rfc6749/grant_types/__pycache__/resource_owner_password_credentials.cpython-38.pyc,, +oauthlib/oauth2/rfc6749/grant_types/authorization_code.py,sha256=R2cXCtdGfDkKseYu-raoZkOpc7lnMa2oVRBs-C3jGKs,26858 +oauthlib/oauth2/rfc6749/grant_types/base.py,sha256=BMcu0_Ks0khfp0B0w2t8CgT6hx9YDjUtkIx95fHf8MM,10213 +oauthlib/oauth2/rfc6749/grant_types/client_credentials.py,sha256=Wr0CpWDVmHrIfOBPTYp9RxnISTfYdp5SjSaRAu77vUY,5079 +oauthlib/oauth2/rfc6749/grant_types/implicit.py,sha256=hYAEYOwToxo3eNpGRC9SyJue93tu37jZVL7MYiaErDs,16852 +oauthlib/oauth2/rfc6749/grant_types/refresh_token.py,sha256=OW0mI-sUPfiTD2UaiZEv8kdpp6QGVSRJEvopJyuRELw,5832 +oauthlib/oauth2/rfc6749/grant_types/resource_owner_password_credentials.py,sha256=9FsDbrSNNylWKkEvgdafJDzlNncTRCOhIZODo-f4ZIM,8516 +oauthlib/oauth2/rfc6749/parameters.py,sha256=WYiyVkEfKS66fXpyczcard3bDaMHy0h1H5l2PUtUY_c,19016 +oauthlib/oauth2/rfc6749/request_validator.py,sha256=CduQ-_Utp1_LrHNDhrC_zx6KMrNFVAVNB8e5_vVziWw,28814 +oauthlib/oauth2/rfc6749/tokens.py,sha256=H6QOIMNGXFEhDeBfOdK2I_UparP5KRrz55SZQJ4WpVY,11097 +oauthlib/oauth2/rfc6749/utils.py,sha256=EKlU_U-FcYkdd8PvXo1irtHTqBXF7gKqdFKBadteZ64,2207 +oauthlib/oauth2/rfc8628/__init__.py,sha256=yfG2QHuDxrp7_9HNKPEeXYXA_qBVZqiRrhI7q2cG4NM,232 +oauthlib/oauth2/rfc8628/__pycache__/__init__.cpython-38.pyc,, +oauthlib/oauth2/rfc8628/clients/__init__.py,sha256=indCdGycy9cekvLOBxYbCwtyezEVhl3uKZzoShml-aY,201 +oauthlib/oauth2/rfc8628/clients/__pycache__/__init__.cpython-38.pyc,, +oauthlib/oauth2/rfc8628/clients/__pycache__/device.cpython-38.pyc,, +oauthlib/oauth2/rfc8628/clients/device.py,sha256=DjDTy51Vxyl28u5sQGB2UsPzr-VAFNO52okuOtw5BcQ,3878 +oauthlib/openid/__init__.py,sha256=qZQCKCdQt40myte_nxSYrWvzf1VVADqRl8om0-t6LzE,162 +oauthlib/openid/__pycache__/__init__.cpython-38.pyc,, +oauthlib/openid/connect/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +oauthlib/openid/connect/__pycache__/__init__.cpython-38.pyc,, +oauthlib/openid/connect/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +oauthlib/openid/connect/core/__pycache__/__init__.cpython-38.pyc,, +oauthlib/openid/connect/core/__pycache__/exceptions.cpython-38.pyc,, +oauthlib/openid/connect/core/__pycache__/request_validator.cpython-38.pyc,, +oauthlib/openid/connect/core/__pycache__/tokens.cpython-38.pyc,, +oauthlib/openid/connect/core/endpoints/__init__.py,sha256=nQ6mGniUaM9X1ENG0tZlPgWgbLdlFESWGK-5_e8mp5Y,229 +oauthlib/openid/connect/core/endpoints/__pycache__/__init__.cpython-38.pyc,, +oauthlib/openid/connect/core/endpoints/__pycache__/pre_configured.cpython-38.pyc,, +oauthlib/openid/connect/core/endpoints/__pycache__/userinfo.cpython-38.pyc,, +oauthlib/openid/connect/core/endpoints/pre_configured.py,sha256=p4Bq4HHUTvCBYXlTHr3PXktABKjHFGC3yBmwxWifzKc,5426 +oauthlib/openid/connect/core/endpoints/userinfo.py,sha256=gTO5BHp4evBqI9CcQKQzJNFs1rx8QJLlBtfo7S67s0I,3847 +oauthlib/openid/connect/core/exceptions.py,sha256=uMMjE7VMc16jyL7TIhpbCx48_MsHD2C_atoMIemBKVA,4790 +oauthlib/openid/connect/core/grant_types/__init__.py,sha256=geSZh6OFlupoC2tg9Bqqsnd31nu1-EheWNobzu86ZqU,426 +oauthlib/openid/connect/core/grant_types/__pycache__/__init__.cpython-38.pyc,, +oauthlib/openid/connect/core/grant_types/__pycache__/authorization_code.cpython-38.pyc,, +oauthlib/openid/connect/core/grant_types/__pycache__/base.cpython-38.pyc,, +oauthlib/openid/connect/core/grant_types/__pycache__/dispatchers.cpython-38.pyc,, +oauthlib/openid/connect/core/grant_types/__pycache__/hybrid.cpython-38.pyc,, +oauthlib/openid/connect/core/grant_types/__pycache__/implicit.cpython-38.pyc,, +oauthlib/openid/connect/core/grant_types/__pycache__/refresh_token.cpython-38.pyc,, +oauthlib/openid/connect/core/grant_types/authorization_code.py,sha256=WOlS5RlSjIk2VNNmC5O4svxfTeUJiXpL3o5Mqn5EULk,1441 +oauthlib/openid/connect/core/grant_types/base.py,sha256=StMSoCD-lrv-01GZMLKdLMvTlAg-VkQ0lw4jdhVOEms,15386 +oauthlib/openid/connect/core/grant_types/dispatchers.py,sha256=kgYI3SpTZd796N_bnkqdaTDis_WmwhzkcMS9Avw_1zM,3979 +oauthlib/openid/connect/core/grant_types/hybrid.py,sha256=PHWBazxe3qpJq02rpU93jaK7URxI_r1zl0Ee4ibcaPA,2742 +oauthlib/openid/connect/core/grant_types/implicit.py,sha256=UICxnDNoePZfTUbL5QCBWA231o8XIQEnxocSrPp9gzw,1971 +oauthlib/openid/connect/core/grant_types/refresh_token.py,sha256=8X0i1EHLgBIrlqP10rwJ5lXWO3f8iupmfn2E6DlLmnw,1035 +oauthlib/openid/connect/core/request_validator.py,sha256=-lo1BnAhMWVkCj2Qhpn22LbV6CDmx4Nh4tCOntCg9tQ,13767 +oauthlib/openid/connect/core/tokens.py,sha256=uiHwpFiVhaQDFdKizV74AcBPuEiHxZQ9mtZ8n5KfvFU,1596 +oauthlib/signals.py,sha256=_PKDXWqKW6X3IbQUxGqW4eJ5Yi3p8jdOqXPAKfI956E,1489 +oauthlib/uri_validate.py,sha256=XLEO1mSoXK5j9kYA12JxnTktWhsJH40mPJ9m8q7jDYw,6107 diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/oauthlib-3.2.0.dist-info/WHEEL b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/oauthlib-3.2.0.dist-info/WHEEL new file mode 100644 index 0000000000000000000000000000000000000000..becc9a66ea739ba941d48a749e248761cc6e658a --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/oauthlib-3.2.0.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.37.1) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/oauthlib-3.2.0.dist-info/top_level.txt b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/oauthlib-3.2.0.dist-info/top_level.txt new file mode 100644 index 0000000000000000000000000000000000000000..b5f3f0e3450f1ffb7a28cd40aed368a56254cacb --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/oauthlib-3.2.0.dist-info/top_level.txt @@ -0,0 +1 @@ +oauthlib diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/omegaconf-2.2.3.dist-info/INSTALLER b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/omegaconf-2.2.3.dist-info/INSTALLER new file mode 100644 index 0000000000000000000000000000000000000000..a1b589e38a32041e49332e5e81c2d363dc418d68 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/omegaconf-2.2.3.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/omegaconf-2.2.3.dist-info/LICENSE b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/omegaconf-2.2.3.dist-info/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..eb208dada03bbd9975633d6f42eb036c09e33125 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/omegaconf-2.2.3.dist-info/LICENSE @@ -0,0 +1,29 @@ +BSD 3-Clause License + +Copyright (c) 2018, Omry Yadan +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/omegaconf-2.2.3.dist-info/REQUESTED b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/omegaconf-2.2.3.dist-info/REQUESTED new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/omegaconf-2.2.3.dist-info/WHEEL b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/omegaconf-2.2.3.dist-info/WHEEL new file mode 100644 index 0000000000000000000000000000000000000000..becc9a66ea739ba941d48a749e248761cc6e658a --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/omegaconf-2.2.3.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.37.1) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/python_dateutil-2.9.0.post0.dist-info/INSTALLER b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/python_dateutil-2.9.0.post0.dist-info/INSTALLER new file mode 100644 index 0000000000000000000000000000000000000000..a1b589e38a32041e49332e5e81c2d363dc418d68 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/python_dateutil-2.9.0.post0.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/python_dateutil-2.9.0.post0.dist-info/LICENSE b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/python_dateutil-2.9.0.post0.dist-info/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..1e65815cf0b3132689485874a93034ede7206bf4 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/python_dateutil-2.9.0.post0.dist-info/LICENSE @@ -0,0 +1,54 @@ +Copyright 2017- Paul Ganssle +Copyright 2017- dateutil contributors (see AUTHORS file) + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +The above license applies to all contributions after 2017-12-01, as well as +all contributions that have been re-licensed (see AUTHORS file for the list of +contributors who have re-licensed their code). +-------------------------------------------------------------------------------- +dateutil - Extensions to the standard Python datetime module. + +Copyright (c) 2003-2011 - Gustavo Niemeyer +Copyright (c) 2012-2014 - Tomi Pieviläinen +Copyright (c) 2014-2016 - Yaron de Leeuw +Copyright (c) 2015- - Paul Ganssle +Copyright (c) 2015- - dateutil contributors (see AUTHORS file) + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The above BSD License Applies to all code, even that also covered by Apache 2.0. \ No newline at end of file diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/python_dateutil-2.9.0.post0.dist-info/METADATA b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/python_dateutil-2.9.0.post0.dist-info/METADATA new file mode 100644 index 0000000000000000000000000000000000000000..577f2bf2b7749e1b123b8225d610b1b257e430cc --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/python_dateutil-2.9.0.post0.dist-info/METADATA @@ -0,0 +1,204 @@ +Metadata-Version: 2.1 +Name: python-dateutil +Version: 2.9.0.post0 +Summary: Extensions to the standard Python datetime module +Home-page: https://github.com/dateutil/dateutil +Author: Gustavo Niemeyer +Author-email: gustavo@niemeyer.net +Maintainer: Paul Ganssle +Maintainer-email: dateutil@python.org +License: Dual License +Project-URL: Documentation, https://dateutil.readthedocs.io/en/stable/ +Project-URL: Source, https://github.com/dateutil/dateutil +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: BSD License +Classifier: License :: OSI Approved :: Apache Software License +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 2 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.3 +Classifier: Programming Language :: Python :: 3.4 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 +Classifier: Topic :: Software Development :: Libraries +Requires-Python: !=3.0.*,!=3.1.*,!=3.2.*,>=2.7 +Description-Content-Type: text/x-rst +License-File: LICENSE +Requires-Dist: six >=1.5 + +dateutil - powerful extensions to datetime +========================================== + +|pypi| |support| |licence| + +|gitter| |readthedocs| + +|travis| |appveyor| |pipelines| |coverage| + +.. |pypi| image:: https://img.shields.io/pypi/v/python-dateutil.svg?style=flat-square + :target: https://pypi.org/project/python-dateutil/ + :alt: pypi version + +.. |support| image:: https://img.shields.io/pypi/pyversions/python-dateutil.svg?style=flat-square + :target: https://pypi.org/project/python-dateutil/ + :alt: supported Python version + +.. |travis| image:: https://img.shields.io/travis/dateutil/dateutil/master.svg?style=flat-square&label=Travis%20Build + :target: https://travis-ci.org/dateutil/dateutil + :alt: travis build status + +.. |appveyor| image:: https://img.shields.io/appveyor/ci/dateutil/dateutil/master.svg?style=flat-square&logo=appveyor + :target: https://ci.appveyor.com/project/dateutil/dateutil + :alt: appveyor build status + +.. |pipelines| image:: https://dev.azure.com/pythondateutilazure/dateutil/_apis/build/status/dateutil.dateutil?branchName=master + :target: https://dev.azure.com/pythondateutilazure/dateutil/_build/latest?definitionId=1&branchName=master + :alt: azure pipelines build status + +.. |coverage| image:: https://codecov.io/gh/dateutil/dateutil/branch/master/graphs/badge.svg?branch=master + :target: https://codecov.io/gh/dateutil/dateutil?branch=master + :alt: Code coverage + +.. |gitter| image:: https://badges.gitter.im/dateutil/dateutil.svg + :alt: Join the chat at https://gitter.im/dateutil/dateutil + :target: https://gitter.im/dateutil/dateutil + +.. |licence| image:: https://img.shields.io/pypi/l/python-dateutil.svg?style=flat-square + :target: https://pypi.org/project/python-dateutil/ + :alt: licence + +.. |readthedocs| image:: https://img.shields.io/readthedocs/dateutil/latest.svg?style=flat-square&label=Read%20the%20Docs + :alt: Read the documentation at https://dateutil.readthedocs.io/en/latest/ + :target: https://dateutil.readthedocs.io/en/latest/ + +The `dateutil` module provides powerful extensions to +the standard `datetime` module, available in Python. + +Installation +============ +`dateutil` can be installed from PyPI using `pip` (note that the package name is +different from the importable name):: + + pip install python-dateutil + +Download +======== +dateutil is available on PyPI +https://pypi.org/project/python-dateutil/ + +The documentation is hosted at: +https://dateutil.readthedocs.io/en/stable/ + +Code +==== +The code and issue tracker are hosted on GitHub: +https://github.com/dateutil/dateutil/ + +Features +======== + +* Computing of relative deltas (next month, next year, + next Monday, last week of month, etc); +* Computing of relative deltas between two given + date and/or datetime objects; +* Computing of dates based on very flexible recurrence rules, + using a superset of the `iCalendar `_ + specification. Parsing of RFC strings is supported as well. +* Generic parsing of dates in almost any string format; +* Timezone (tzinfo) implementations for tzfile(5) format + files (/etc/localtime, /usr/share/zoneinfo, etc), TZ + environment string (in all known formats), iCalendar + format files, given ranges (with help from relative deltas), + local machine timezone, fixed offset timezone, UTC timezone, + and Windows registry-based time zones. +* Internal up-to-date world timezone information based on + Olson's database. +* Computing of Easter Sunday dates for any given year, + using Western, Orthodox or Julian algorithms; +* A comprehensive test suite. + +Quick example +============= +Here's a snapshot, just to give an idea about the power of the +package. For more examples, look at the documentation. + +Suppose you want to know how much time is left, in +years/months/days/etc, before the next easter happening on a +year with a Friday 13th in August, and you want to get today's +date out of the "date" unix system command. Here is the code: + +.. code-block:: python3 + + >>> from dateutil.relativedelta import * + >>> from dateutil.easter import * + >>> from dateutil.rrule import * + >>> from dateutil.parser import * + >>> from datetime import * + >>> now = parse("Sat Oct 11 17:13:46 UTC 2003") + >>> today = now.date() + >>> year = rrule(YEARLY,dtstart=now,bymonth=8,bymonthday=13,byweekday=FR)[0].year + >>> rdelta = relativedelta(easter(year), today) + >>> print("Today is: %s" % today) + Today is: 2003-10-11 + >>> print("Year with next Aug 13th on a Friday is: %s" % year) + Year with next Aug 13th on a Friday is: 2004 + >>> print("How far is the Easter of that year: %s" % rdelta) + How far is the Easter of that year: relativedelta(months=+6) + >>> print("And the Easter of that year is: %s" % (today+rdelta)) + And the Easter of that year is: 2004-04-11 + +Being exactly 6 months ahead was **really** a coincidence :) + +Contributing +============ + +We welcome many types of contributions - bug reports, pull requests (code, infrastructure or documentation fixes). For more information about how to contribute to the project, see the ``CONTRIBUTING.md`` file in the repository. + + +Author +====== +The dateutil module was written by Gustavo Niemeyer +in 2003. + +It is maintained by: + +* Gustavo Niemeyer 2003-2011 +* Tomi Pieviläinen 2012-2014 +* Yaron de Leeuw 2014-2016 +* Paul Ganssle 2015- + +Starting with version 2.4.1 and running until 2.8.2, all source and binary +distributions will be signed by a PGP key that has, at the very least, been +signed by the key which made the previous release. A table of release signing +keys can be found below: + +=========== ============================ +Releases Signing key fingerprint +=========== ============================ +2.4.1-2.8.2 `6B49 ACBA DCF6 BD1C A206 67AB CD54 FCE3 D964 BEFB`_ +=========== ============================ + +New releases *may* have signed tags, but binary and source distributions +uploaded to PyPI will no longer have GPG signatures attached. + +Contact +======= +Our mailing list is available at `dateutil@python.org `_. As it is hosted by the PSF, it is subject to the `PSF code of +conduct `_. + +License +======= + +All contributions after December 1, 2017 released under dual license - either `Apache 2.0 License `_ or the `BSD 3-Clause License `_. Contributions before December 1, 2017 - except those those explicitly relicensed - are released only under the BSD 3-Clause License. + + +.. _6B49 ACBA DCF6 BD1C A206 67AB CD54 FCE3 D964 BEFB: + https://pgp.mit.edu/pks/lookup?op=vindex&search=0xCD54FCE3D964BEFB diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/python_dateutil-2.9.0.post0.dist-info/RECORD b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/python_dateutil-2.9.0.post0.dist-info/RECORD new file mode 100644 index 0000000000000000000000000000000000000000..63e5b75d9fcf3719ffa1375f2182777153dad932 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/python_dateutil-2.9.0.post0.dist-info/RECORD @@ -0,0 +1,44 @@ +dateutil/__init__.py,sha256=Mqam67WO9IkTmUFyI66vS6IoSXTp9G388DadH2LCMLY,620 +dateutil/__pycache__/__init__.cpython-38.pyc,, +dateutil/__pycache__/_common.cpython-38.pyc,, +dateutil/__pycache__/_version.cpython-38.pyc,, +dateutil/__pycache__/easter.cpython-38.pyc,, +dateutil/__pycache__/relativedelta.cpython-38.pyc,, +dateutil/__pycache__/rrule.cpython-38.pyc,, +dateutil/__pycache__/tzwin.cpython-38.pyc,, +dateutil/__pycache__/utils.cpython-38.pyc,, +dateutil/_common.py,sha256=77w0yytkrxlYbSn--lDVPUMabUXRR9I3lBv_vQRUqUY,932 +dateutil/_version.py,sha256=BV031OxDDAmy58neUg5yyqLkLaqIw7ibK9As3jiMib0,166 +dateutil/easter.py,sha256=dyBi-lKvimH1u_k6p7Z0JJK72QhqVtVBsqByvpEPKvc,2678 +dateutil/parser/__init__.py,sha256=wWk6GFuxTpjoggCGtgkceJoti4pVjl4_fHQXpNOaSYg,1766 +dateutil/parser/__pycache__/__init__.cpython-38.pyc,, +dateutil/parser/__pycache__/_parser.cpython-38.pyc,, +dateutil/parser/__pycache__/isoparser.cpython-38.pyc,, +dateutil/parser/_parser.py,sha256=7klDdyicksQB_Xgl-3UAmBwzCYor1AIZqklIcT6dH_8,58796 +dateutil/parser/isoparser.py,sha256=8Fy999bnCd1frSdOYuOraWfJTtd5W7qQ51NwNuH_hXM,13233 +dateutil/relativedelta.py,sha256=IY_mglMjoZbYfrvloTY2ce02aiVjPIkiZfqgNTZRfuA,24903 +dateutil/rrule.py,sha256=KJzKlaCd1jEbu4A38ZltslaoAUh9nSbdbOFdjp70Kew,66557 +dateutil/tz/__init__.py,sha256=F-Mz13v6jYseklQf9Te9J6nzcLDmq47gORa61K35_FA,444 +dateutil/tz/__pycache__/__init__.cpython-38.pyc,, +dateutil/tz/__pycache__/_common.cpython-38.pyc,, +dateutil/tz/__pycache__/_factories.cpython-38.pyc,, +dateutil/tz/__pycache__/tz.cpython-38.pyc,, +dateutil/tz/__pycache__/win.cpython-38.pyc,, +dateutil/tz/_common.py,sha256=cgzDTANsOXvEc86cYF77EsliuSab8Puwpsl5-bX3_S4,12977 +dateutil/tz/_factories.py,sha256=unb6XQNXrPMveksTCU-Ag8jmVZs4SojoPUcAHpWnrvU,2569 +dateutil/tz/tz.py,sha256=EUnEdMfeThXiY6l4sh9yBabZ63_POzy01zSsh9thn1o,62855 +dateutil/tz/win.py,sha256=xJszWgSwE1xPx_HJj4ZkepyukC_hNy016WMcXhbRaB8,12935 +dateutil/tzwin.py,sha256=7Ar4vdQCnnM0mKR3MUjbIKsZrBVfHgdwsJZc_mGYRew,59 +dateutil/utils.py,sha256=dKCchEw8eObi0loGTx91unBxm_7UGlU3v_FjFMdqwYM,1965 +dateutil/zoneinfo/__init__.py,sha256=KYg0pthCMjcp5MXSEiBJn3nMjZeNZav7rlJw5-tz1S4,5889 +dateutil/zoneinfo/__pycache__/__init__.cpython-38.pyc,, +dateutil/zoneinfo/__pycache__/rebuild.cpython-38.pyc,, +dateutil/zoneinfo/dateutil-zoneinfo.tar.gz,sha256=0-pS57bpaN4NiE3xKIGTWW-pW4A9tPkqGCeac5gARHU,156400 +dateutil/zoneinfo/rebuild.py,sha256=MiqYzCIHvNbMH-LdRYLv-4T0EIA7hDKt5GLR0IRTLdI,2392 +python_dateutil-2.9.0.post0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +python_dateutil-2.9.0.post0.dist-info/LICENSE,sha256=ugD1Gg2SgjtaHN4n2LW50jIeZ-2NqbwWPv-W1eF-V34,2889 +python_dateutil-2.9.0.post0.dist-info/METADATA,sha256=qdQ22jIr6AgzL5jYgyWZjofLaTpniplp_rTPrXKabpM,8354 +python_dateutil-2.9.0.post0.dist-info/RECORD,, +python_dateutil-2.9.0.post0.dist-info/WHEEL,sha256=-G_t0oGuE7UD0DrSpVZnq1hHMBV9DD2XkS5v7XpmTnk,110 +python_dateutil-2.9.0.post0.dist-info/top_level.txt,sha256=4tjdWkhRZvF7LA_BYe_L9gB2w_p2a-z5y6ArjaRkot8,9 +python_dateutil-2.9.0.post0.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1 diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/python_dateutil-2.9.0.post0.dist-info/WHEEL b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/python_dateutil-2.9.0.post0.dist-info/WHEEL new file mode 100644 index 0000000000000000000000000000000000000000..4724c45738f6ac125bb3a21787855562e6870440 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/python_dateutil-2.9.0.post0.dist-info/WHEEL @@ -0,0 +1,6 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.42.0) +Root-Is-Purelib: true +Tag: py2-none-any +Tag: py3-none-any + diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/python_dateutil-2.9.0.post0.dist-info/top_level.txt b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/python_dateutil-2.9.0.post0.dist-info/top_level.txt new file mode 100644 index 0000000000000000000000000000000000000000..66501480ba5b63f98ee9a59c1f99e5e6917da6d9 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/python_dateutil-2.9.0.post0.dist-info/top_level.txt @@ -0,0 +1 @@ +dateutil diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/python_dateutil-2.9.0.post0.dist-info/zip-safe b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/python_dateutil-2.9.0.post0.dist-info/zip-safe new file mode 100644 index 0000000000000000000000000000000000000000..8b137891791fe96927ad78e64b0aad7bded08bdc --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/python_dateutil-2.9.0.post0.dist-info/zip-safe @@ -0,0 +1 @@ + diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/regex-2022.6.2.dist-info/INSTALLER b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/regex-2022.6.2.dist-info/INSTALLER new file mode 100644 index 0000000000000000000000000000000000000000..a1b589e38a32041e49332e5e81c2d363dc418d68 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/regex-2022.6.2.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/regex-2022.6.2.dist-info/LICENSE.txt b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/regex-2022.6.2.dist-info/LICENSE.txt new file mode 100644 index 0000000000000000000000000000000000000000..99c19cf844141395a87c34325da3a537f1e95815 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/regex-2022.6.2.dist-info/LICENSE.txt @@ -0,0 +1,208 @@ +This work was derived from the 're' module of CPython 2.6 and CPython 3.1, +copyright (c) 1998-2001 by Secret Labs AB and licensed under CNRI's Python 1.6 +license. + +All additions and alterations are licensed under the Apache 2.0 License. + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2020 Matthew Barnett + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/regex-2022.6.2.dist-info/METADATA b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/regex-2022.6.2.dist-info/METADATA new file mode 100644 index 0000000000000000000000000000000000000000..4e05f39ac19914b52a3bd90418b0747bd10a956b --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/regex-2022.6.2.dist-info/METADATA @@ -0,0 +1,1095 @@ +Metadata-Version: 2.1 +Name: regex +Version: 2022.6.2 +Summary: Alternative regular expression module, to replace re. +Home-page: https://github.com/mrabarnett/mrab-regex +Author: Matthew Barnett +Author-email: regex@mrabarnett.plus.com +License: Apache Software License +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: Apache Software License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Topic :: Scientific/Engineering :: Information Analysis +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Classifier: Topic :: Text Processing +Classifier: Topic :: Text Processing :: General +Requires-Python: >=3.6 +Description-Content-Type: text/x-rst +License-File: LICENSE.txt + +Introduction +------------ + +This regex implementation is backwards-compatible with the standard 're' module, but offers additional functionality. + +Note +---- + +The re module's behaviour with zero-width matches changed in Python 3.7, and this module will follow that behaviour when compiled for Python 3.7. + +Python 2 +-------- + +Python 2 is no longer supported. The last release that supported Python 2 was 2021.11.10. + +PyPy +---- + +This module is targeted at CPython. It expects that all codepoints are the same width, so it won't behave properly with PyPy outside U+0000..U+007F because PyPy stores strings as UTF-8. + +Old vs new behaviour +-------------------- + +In order to be compatible with the re module, this module has 2 behaviours: + +* **Version 0** behaviour (old behaviour, compatible with the re module): + + Please note that the re module's behaviour may change over time, and I'll endeavour to match that behaviour in version 0. + + * Indicated by the ``VERSION0`` or ``V0`` flag, or ``(?V0)`` in the pattern. + + * Zero-width matches are not handled correctly in the re module before Python 3.7. The behaviour in those earlier versions is: + + * ``.split`` won't split a string at a zero-width match. + + * ``.sub`` will advance by one character after a zero-width match. + + * Inline flags apply to the entire pattern, and they can't be turned off. + + * Only simple sets are supported. + + * Case-insensitive matches in Unicode use simple case-folding by default. + +* **Version 1** behaviour (new behaviour, possibly different from the re module): + + * Indicated by the ``VERSION1`` or ``V1`` flag, or ``(?V1)`` in the pattern. + + * Zero-width matches are handled correctly. + + * Inline flags apply to the end of the group or pattern, and they can be turned off. + + * Nested sets and set operations are supported. + + * Case-insensitive matches in Unicode use full case-folding by default. + +If no version is specified, the regex module will default to ``regex.DEFAULT_VERSION``. + +Case-insensitive matches in Unicode +----------------------------------- + +The regex module supports both simple and full case-folding for case-insensitive matches in Unicode. Use of full case-folding can be turned on using the ``FULLCASE`` or ``F`` flag, or ``(?f)`` in the pattern. Please note that this flag affects how the ``IGNORECASE`` flag works; the ``FULLCASE`` flag itself does not turn on case-insensitive matching. + +In the version 0 behaviour, the flag is off by default. + +In the version 1 behaviour, the flag is on by default. + +Nested sets and set operations +------------------------------ + +It's not possible to support both simple sets, as used in the re module, and nested sets at the same time because of a difference in the meaning of an unescaped ``"["`` in a set. + +For example, the pattern ``[[a-z]--[aeiou]]`` is treated in the version 0 behaviour (simple sets, compatible with the re module) as: + +* Set containing "[" and the letters "a" to "z" + +* Literal "--" + +* Set containing letters "a", "e", "i", "o", "u" + +* Literal "]" + +but in the version 1 behaviour (nested sets, enhanced behaviour) as: + +* Set which is: + + * Set containing the letters "a" to "z" + +* but excluding: + + * Set containing the letters "a", "e", "i", "o", "u" + +Version 0 behaviour: only simple sets are supported. + +Version 1 behaviour: nested sets and set operations are supported. + +Flags +----- + +There are 2 kinds of flag: scoped and global. Scoped flags can apply to only part of a pattern and can be turned on or off; global flags apply to the entire pattern and can only be turned on. + +The scoped flags are: ``ASCII``, ``FULLCASE``, ``IGNORECASE``, ``LOCALE``, ``MULTILINE``, ``DOTALL``, ``UNICODE``, ``VERBOSE``, ``WORD``. + +The global flags are: ``BESTMATCH``, ``ENHANCEMATCH``, ``POSIX``, ``REVERSE``, ``VERSION0``, ``VERSION1``. + +If neither the ``ASCII``, ``LOCALE`` nor ``UNICODE`` flag is specified, it will default to ``UNICODE`` if the regex pattern is a Unicode string and ``ASCII`` if it's a bytestring. + +The ``ENHANCEMATCH`` flag makes fuzzy matching attempt to improve the fit of the next match that it finds. + +The ``BESTMATCH`` flag makes fuzzy matching search for the best match instead of the next match. + +Notes on named capture groups +----------------------------- + +All capture groups have a group number, starting from 1. + +Groups with the same group name will have the same group number, and groups with a different group name will have a different group number. + +The same name can be used by more than one group, with later captures 'overwriting' earlier captures. All of the captures of the group will be available from the ``captures`` method of the match object. + +Group numbers will be reused across different branches of a branch reset, eg. ``(?|(first)|(second))`` has only group 1. If capture groups have different group names then they will, of course, have different group numbers, eg. ``(?|(?Pfirst)|(?Psecond))`` has group 1 ("foo") and group 2 ("bar"). + +In the regex ``(\s+)(?|(?P[A-Z]+)|(\w+) (?P[0-9]+)`` there are 2 groups: + +* ``(\s+)`` is group 1. + +* ``(?P[A-Z]+)`` is group 2, also called "foo". + +* ``(\w+)`` is group 2 because of the branch reset. + +* ``(?P[0-9]+)`` is group 2 because it's called "foo". + +If you want to prevent ``(\w+)`` from being group 2, you need to name it (different name, different group number). + +Multithreading +-------------- + +The regex module releases the GIL during matching on instances of the built-in (immutable) string classes, enabling other Python threads to run concurrently. It is also possible to force the regex module to release the GIL during matching by calling the matching methods with the keyword argument ``concurrent=True``. The behaviour is undefined if the string changes during matching, so use it *only* when it is guaranteed that that won't happen. + +Unicode +------- + +This module supports Unicode 14.0.0. + +Full Unicode case-folding is supported. + +Additional features +------------------- + +The issue numbers relate to the Python bug tracker, except where listed as "Hg issue". + +Added support for lookaround in conditional pattern (`Hg issue 163 `_) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The test of a conditional pattern can now be a lookaround. + +Examples: + +.. sourcecode:: python + + >>> regex.match(r'(?(?=\d)\d+|\w+)', '123abc') + + >>> regex.match(r'(?(?=\d)\d+|\w+)', 'abc123') + + +This is not quite the same as putting a lookaround in the first branch of a pair of alternatives. + +Examples: + +.. sourcecode:: python + + >>> print(regex.match(r'(?:(?=\d)\d+\b|\w+)', '123abc')) + + >>> print(regex.match(r'(?(?=\d)\d+\b|\w+)', '123abc')) + None + +In the first example, the lookaround matched, but the remainder of the first branch failed to match, and so the second branch was attempted, whereas in the second example, the lookaround matched, and the first branch failed to match, but the second branch was **not** attempted. + +Added POSIX matching (leftmost longest) (`Hg issue 150 `_) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The POSIX standard for regex is to return the leftmost longest match. This can be turned on using the ``POSIX`` flag (``(?p)``). + +Examples: + +.. sourcecode:: python + + >>> # Normal matching. + >>> regex.search(r'Mr|Mrs', 'Mrs') + + >>> regex.search(r'one(self)?(selfsufficient)?', 'oneselfsufficient') + + >>> # POSIX matching. + >>> regex.search(r'(?p)Mr|Mrs', 'Mrs') + + >>> regex.search(r'(?p)one(self)?(selfsufficient)?', 'oneselfsufficient') + + +Note that it will take longer to find matches because when it finds a match at a certain position, it won't return that immediately, but will keep looking to see if there's another longer match there. + +Added ``(?(DEFINE)...)`` (`Hg issue 152 `_) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +If there's no group called "DEFINE", then ... will be ignored, but any group definitions within it will be available. + +Examples: + +.. sourcecode:: python + + >>> regex.search(r'(?(DEFINE)(?P\d+)(?P\w+))(?&quant) (?&item)', '5 elephants') + + +Added ``(*PRUNE)``, ``(*SKIP)`` and ``(*FAIL)`` (`Hg issue 153 `_) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +``(*PRUNE)`` discards the backtracking info up to that point. When used in an atomic group or a lookaround, it won't affect the enclosing pattern. + +``(*SKIP)`` is similar to ``(*PRUNE)``, except that it also sets where in the text the next attempt to match will start. When used in an atomic group or a lookaround, it won't affect the enclosing pattern. + +``(*FAIL)`` causes immediate backtracking. ``(*F)`` is a permitted abbreviation. + +Added ``\K`` (`Hg issue 151 `_) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Keeps the part of the entire match after the position where ``\K`` occurred; the part before it is discarded. + +It does not affect what capture groups return. + +Examples: + +.. sourcecode:: python + + >>> m = regex.search(r'(\w\w\K\w\w\w)', 'abcdef') + >>> m[0] + 'cde' + >>> m[1] + 'abcde' + >>> + >>> m = regex.search(r'(?r)(\w\w\K\w\w\w)', 'abcdef') + >>> m[0] + 'bc' + >>> m[1] + 'bcdef' + +Added capture subscripting for ``expandf`` and ``subf``/``subfn`` (`Hg issue 133 `_) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +You can now use subscripting to get the captures of a repeated capture group. + +Examples: + +.. sourcecode:: python + + >>> m = regex.match(r"(\w)+", "abc") + >>> m.expandf("{1}") + 'c' + >>> m.expandf("{1[0]} {1[1]} {1[2]}") + 'a b c' + >>> m.expandf("{1[-1]} {1[-2]} {1[-3]}") + 'c b a' + >>> + >>> m = regex.match(r"(?P\w)+", "abc") + >>> m.expandf("{letter}") + 'c' + >>> m.expandf("{letter[0]} {letter[1]} {letter[2]}") + 'a b c' + >>> m.expandf("{letter[-1]} {letter[-2]} {letter[-3]}") + 'c b a' + +Added support for referring to a group by number using ``(?P=...)``. +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +This is in addition to the existing ``\g<...>``. + +Fixed the handling of locale-sensitive regexes. +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The ``LOCALE`` flag is intended for legacy code and has limited support. You're still recommended to use Unicode instead. + +Added partial matches (`Hg issue 102 `_) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +A partial match is one that matches up to the end of string, but that string has been truncated and you want to know whether a complete match could be possible if the string had not been truncated. + +Partial matches are supported by ``match``, ``search``, ``fullmatch`` and ``finditer`` with the ``partial`` keyword argument. + +Match objects have a ``partial`` attribute, which is ``True`` if it's a partial match. + +For example, if you wanted a user to enter a 4-digit number and check it character by character as it was being entered: + +.. sourcecode:: python + + >>> pattern = regex.compile(r'\d{4}') + + >>> # Initially, nothing has been entered: + >>> print(pattern.fullmatch('', partial=True)) + + + >>> # An empty string is OK, but it's only a partial match. + >>> # The user enters a letter: + >>> print(pattern.fullmatch('a', partial=True)) + None + >>> # It'll never match. + + >>> # The user deletes that and enters a digit: + >>> print(pattern.fullmatch('1', partial=True)) + + >>> # It matches this far, but it's only a partial match. + + >>> # The user enters 2 more digits: + >>> print(pattern.fullmatch('123', partial=True)) + + >>> # It matches this far, but it's only a partial match. + + >>> # The user enters another digit: + >>> print(pattern.fullmatch('1234', partial=True)) + + >>> # It's a complete match. + + >>> # If the user enters another digit: + >>> print(pattern.fullmatch('12345', partial=True)) + None + >>> # It's no longer a match. + + >>> # This is a partial match: + >>> pattern.match('123', partial=True).partial + True + + >>> # This is a complete match: + >>> pattern.match('1233', partial=True).partial + False + +``*`` operator not working correctly with sub() (`Hg issue 106 `_) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Sometimes it's not clear how zero-width matches should be handled. For example, should ``.*`` match 0 characters directly after matching >0 characters? + +Examples: + +.. sourcecode:: python + + # Python 3.7 and later + >>> regex.sub('.*', 'x', 'test') + 'xx' + >>> regex.sub('.*?', '|', 'test') + '|||||||||' + + # Python 3.6 and earlier + >>> regex.sub('(?V0).*', 'x', 'test') + 'x' + >>> regex.sub('(?V1).*', 'x', 'test') + 'xx' + >>> regex.sub('(?V0).*?', '|', 'test') + '|t|e|s|t|' + >>> regex.sub('(?V1).*?', '|', 'test') + '|||||||||' + +Added ``capturesdict`` (`Hg issue 86 `_) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +``capturesdict`` is a combination of ``groupdict`` and ``captures``: + +``groupdict`` returns a dict of the named groups and the last capture of those groups. + +``captures`` returns a list of all the captures of a group + +``capturesdict`` returns a dict of the named groups and lists of all the captures of those groups. + +Examples: + +.. sourcecode:: python + + >>> m = regex.match(r"(?:(?P\w+) (?P\d+)\n)+", "one 1\ntwo 2\nthree 3\n") + >>> m.groupdict() + {'word': 'three', 'digits': '3'} + >>> m.captures("word") + ['one', 'two', 'three'] + >>> m.captures("digits") + ['1', '2', '3'] + >>> m.capturesdict() + {'word': ['one', 'two', 'three'], 'digits': ['1', '2', '3']} + +Allow duplicate names of groups (`Hg issue 87 `_) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Group names can now be duplicated. + +Examples: + +.. sourcecode:: python + + >>> # With optional groups: + >>> + >>> # Both groups capture, the second capture 'overwriting' the first. + >>> m = regex.match(r"(?P\w+)? or (?P\w+)?", "first or second") + >>> m.group("item") + 'second' + >>> m.captures("item") + ['first', 'second'] + >>> # Only the second group captures. + >>> m = regex.match(r"(?P\w+)? or (?P\w+)?", " or second") + >>> m.group("item") + 'second' + >>> m.captures("item") + ['second'] + >>> # Only the first group captures. + >>> m = regex.match(r"(?P\w+)? or (?P\w+)?", "first or ") + >>> m.group("item") + 'first' + >>> m.captures("item") + ['first'] + >>> + >>> # With mandatory groups: + >>> + >>> # Both groups capture, the second capture 'overwriting' the first. + >>> m = regex.match(r"(?P\w*) or (?P\w*)?", "first or second") + >>> m.group("item") + 'second' + >>> m.captures("item") + ['first', 'second'] + >>> # Again, both groups capture, the second capture 'overwriting' the first. + >>> m = regex.match(r"(?P\w*) or (?P\w*)", " or second") + >>> m.group("item") + 'second' + >>> m.captures("item") + ['', 'second'] + >>> # And yet again, both groups capture, the second capture 'overwriting' the first. + >>> m = regex.match(r"(?P\w*) or (?P\w*)", "first or ") + >>> m.group("item") + '' + >>> m.captures("item") + ['first', ''] + +Added ``fullmatch`` (`issue #16203 `_) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +``fullmatch`` behaves like ``match``, except that it must match all of the string. + +Examples: + +.. sourcecode:: python + + >>> print(regex.fullmatch(r"abc", "abc").span()) + (0, 3) + >>> print(regex.fullmatch(r"abc", "abcx")) + None + >>> print(regex.fullmatch(r"abc", "abcx", endpos=3).span()) + (0, 3) + >>> print(regex.fullmatch(r"abc", "xabcy", pos=1, endpos=4).span()) + (1, 4) + >>> + >>> regex.match(r"a.*?", "abcd").group(0) + 'a' + >>> regex.fullmatch(r"a.*?", "abcd").group(0) + 'abcd' + +Added ``subf`` and ``subfn`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +``subf`` and ``subfn`` are alternatives to ``sub`` and ``subn`` respectively. When passed a replacement string, they treat it as a format string. + +Examples: + +.. sourcecode:: python + + >>> regex.subf(r"(\w+) (\w+)", "{0} => {2} {1}", "foo bar") + 'foo bar => bar foo' + >>> regex.subf(r"(?P\w+) (?P\w+)", "{word2} {word1}", "foo bar") + 'bar foo' + +Added ``expandf`` to match object +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +``expandf`` is an alternative to ``expand``. When passed a replacement string, it treats it as a format string. + +Examples: + +.. sourcecode:: python + + >>> m = regex.match(r"(\w+) (\w+)", "foo bar") + >>> m.expandf("{0} => {2} {1}") + 'foo bar => bar foo' + >>> + >>> m = regex.match(r"(?P\w+) (?P\w+)", "foo bar") + >>> m.expandf("{word2} {word1}") + 'bar foo' + +Detach searched string +^^^^^^^^^^^^^^^^^^^^^^ + +A match object contains a reference to the string that was searched, via its ``string`` attribute. The ``detach_string`` method will 'detach' that string, making it available for garbage collection, which might save valuable memory if that string is very large. + +Example: + +.. sourcecode:: python + + >>> m = regex.search(r"\w+", "Hello world") + >>> print(m.group()) + Hello + >>> print(m.string) + Hello world + >>> m.detach_string() + >>> print(m.group()) + Hello + >>> print(m.string) + None + +Recursive patterns (`Hg issue 27 `_) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Recursive and repeated patterns are supported. + +``(?R)`` or ``(?0)`` tries to match the entire regex recursively. ``(?1)``, ``(?2)``, etc, try to match the relevant capture group. + +``(?&name)`` tries to match the named capture group. + +Examples: + +.. sourcecode:: python + + >>> regex.match(r"(Tarzan|Jane) loves (?1)", "Tarzan loves Jane").groups() + ('Tarzan',) + >>> regex.match(r"(Tarzan|Jane) loves (?1)", "Jane loves Tarzan").groups() + ('Jane',) + + >>> m = regex.search(r"(\w)(?:(?R)|(\w?))\1", "kayak") + >>> m.group(0, 1, 2) + ('kayak', 'k', None) + +The first two examples show how the subpattern within the capture group is reused, but is _not_ itself a capture group. In other words, ``"(Tarzan|Jane) loves (?1)"`` is equivalent to ``"(Tarzan|Jane) loves (?:Tarzan|Jane)"``. + +It's possible to backtrack into a recursed or repeated group. + +You can't call a group if there is more than one group with that group name or group number (``"ambiguous group reference"``). + +The alternative forms ``(?P>name)`` and ``(?P&name)`` are also supported. + +Full Unicode case-folding is supported. +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +In version 1 behaviour, the regex module uses full case-folding when performing case-insensitive matches in Unicode. + +Examples (in Python 3): + +.. sourcecode:: python + + >>> regex.match(r"(?iV1)strasse", "stra\N{LATIN SMALL LETTER SHARP S}e").span() + (0, 6) + >>> regex.match(r"(?iV1)stra\N{LATIN SMALL LETTER SHARP S}e", "STRASSE").span() + (0, 7) + +In version 0 behaviour, it uses simple case-folding for backward compatibility with the re module. + +Approximate "fuzzy" matching (`Hg issue 12 `_, `Hg issue 41 `_, `Hg issue 109 `_) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Regex usually attempts an exact match, but sometimes an approximate, or "fuzzy", match is needed, for those cases where the text being searched may contain errors in the form of inserted, deleted or substituted characters. + +A fuzzy regex specifies which types of errors are permitted, and, optionally, either the minimum and maximum or only the maximum permitted number of each type. (You cannot specify only a minimum.) + +The 3 types of error are: + +* Insertion, indicated by "i" + +* Deletion, indicated by "d" + +* Substitution, indicated by "s" + +In addition, "e" indicates any type of error. + +The fuzziness of a regex item is specified between "{" and "}" after the item. + +Examples: + +* ``foo`` match "foo" exactly + +* ``(?:foo){i}`` match "foo", permitting insertions + +* ``(?:foo){d}`` match "foo", permitting deletions + +* ``(?:foo){s}`` match "foo", permitting substitutions + +* ``(?:foo){i,s}`` match "foo", permitting insertions and substitutions + +* ``(?:foo){e}`` match "foo", permitting errors + +If a certain type of error is specified, then any type not specified will **not** be permitted. + +In the following examples I'll omit the item and write only the fuzziness: + +* ``{d<=3}`` permit at most 3 deletions, but no other types + +* ``{i<=1,s<=2}`` permit at most 1 insertion and at most 2 substitutions, but no deletions + +* ``{1<=e<=3}`` permit at least 1 and at most 3 errors + +* ``{i<=2,d<=2,e<=3}`` permit at most 2 insertions, at most 2 deletions, at most 3 errors in total, but no substitutions + +It's also possible to state the costs of each type of error and the maximum permitted total cost. + +Examples: + +* ``{2i+2d+1s<=4}`` each insertion costs 2, each deletion costs 2, each substitution costs 1, the total cost must not exceed 4 + +* ``{i<=1,d<=1,s<=1,2i+2d+1s<=4}`` at most 1 insertion, at most 1 deletion, at most 1 substitution; each insertion costs 2, each deletion costs 2, each substitution costs 1, the total cost must not exceed 4 + +You can also use "<" instead of "<=" if you want an exclusive minimum or maximum. + +You can add a test to perform on a character that's substituted or inserted. + +Examples: + +* ``{s<=2:[a-z]}`` at most 2 substitutions, which must be in the character set ``[a-z]``. + +* ``{s<=2,i<=3:\d}`` at most 2 substitutions, at most 3 insertions, which must be digits. + +By default, fuzzy matching searches for the first match that meets the given constraints. The ``ENHANCEMATCH`` flag (``(?e)`` in the pattern) will cause it to attempt to improve the fit (i.e. reduce the number of errors) of the match that it has found. + +The ``BESTMATCH`` flag (``(?b)`` in the pattern) will make it search for the best match instead. + +Further examples to note: + +* ``regex.search("(dog){e}", "cat and dog")[1]`` returns ``"cat"`` because that matches ``"dog"`` with 3 errors (an unlimited number of errors is permitted). + +* ``regex.search("(dog){e<=1}", "cat and dog")[1]`` returns ``" dog"`` (with a leading space) because that matches ``"dog"`` with 1 error, which is within the limit. + +* ``regex.search("(?e)(dog){e<=1}", "cat and dog")[1]`` returns ``"dog"`` (without a leading space) because the fuzzy search matches ``" dog"`` with 1 error, which is within the limit, and the ``(?e)`` then it attempts a better fit. + +In the first two examples there are perfect matches later in the string, but in neither case is it the first possible match. + +The match object has an attribute ``fuzzy_counts`` which gives the total number of substitutions, insertions and deletions. + +.. sourcecode:: python + + >>> # A 'raw' fuzzy match: + >>> regex.fullmatch(r"(?:cats|cat){e<=1}", "cat").fuzzy_counts + (0, 0, 1) + >>> # 0 substitutions, 0 insertions, 1 deletion. + + >>> # A better match might be possible if the ENHANCEMATCH flag used: + >>> regex.fullmatch(r"(?e)(?:cats|cat){e<=1}", "cat").fuzzy_counts + (0, 0, 0) + >>> # 0 substitutions, 0 insertions, 0 deletions. + +The match object also has an attribute ``fuzzy_changes`` which gives a tuple of the positions of the substitutions, insertions and deletions. + +.. sourcecode:: python + + >>> m = regex.search('(fuu){i<=2,d<=2,e<=5}', 'anaconda foo bar') + >>> m + + >>> m.fuzzy_changes + ([], [7, 8], [10, 11]) + +What this means is that if the matched part of the string had been: + +.. sourcecode:: python + + 'anacondfuuoo bar' + +it would've been an exact match. + +However, there were insertions at positions 7 and 8: + +.. sourcecode:: python + + 'anaconda fuuoo bar' + ^^ + +and deletions at positions 10 and 11: + +.. sourcecode:: python + + 'anaconda f~~oo bar' + ^^ + +So the actual string was: + +.. sourcecode:: python + + 'anaconda foo bar' + +Named lists (`Hg issue 11 `_) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +``\L`` + +There are occasions where you may want to include a list (actually, a set) of options in a regex. + +One way is to build the pattern like this: + +.. sourcecode:: python + + >>> p = regex.compile(r"first|second|third|fourth|fifth") + +but if the list is large, parsing the resulting regex can take considerable time, and care must also be taken that the strings are properly escaped and properly ordered, for example, "cats" before "cat". + +The new alternative is to use a named list: + +.. sourcecode:: python + + >>> option_set = ["first", "second", "third", "fourth", "fifth"] + >>> p = regex.compile(r"\L", options=option_set) + +The order of the items is irrelevant, they are treated as a set. The named lists are available as the ``.named_lists`` attribute of the pattern object : + +.. sourcecode:: python + + >>> print(p.named_lists) + {'options': frozenset({'fifth', 'first', 'fourth', 'second', 'third'})} + +If there are any unused keyword arguments, ``ValueError`` will be raised unless you tell it otherwise: + +.. sourcecode:: python + + >>> option_set = ["first", "second", "third", "fourth", "fifth"] + >>> p = regex.compile(r"\L", options=option_set, other_options=[]) + Traceback (most recent call last): + File "", line 1, in + File "C:\Python37\lib\site-packages\regex\regex.py", line 348, in compile + return _compile(pattern, flags, ignore_unused, kwargs) + File "C:\Python37\lib\site-packages\regex\regex.py", line 585, in _compile + raise ValueError('unused keyword argument {!a}'.format(any_one)) + ValueError: unused keyword argument 'other_options' + >>> p = regex.compile(r"\L", options=option_set, other_options=[], ignore_unused=True) + >>> + +Start and end of word +^^^^^^^^^^^^^^^^^^^^^ + +``\m`` matches at the start of a word. + +``\M`` matches at the end of a word. + +Compare with ``\b``, which matches at the start or end of a word. + +Unicode line separators +^^^^^^^^^^^^^^^^^^^^^^^ + +Normally the only line separator is ``\n`` (``\x0A``), but if the ``WORD`` flag is turned on then the line separators are ``\x0D\x0A``, ``\x0A``, ``\x0B``, ``\x0C`` and ``\x0D``, plus ``\x85``, ``\u2028`` and ``\u2029`` when working with Unicode. + +This affects the regex dot ``"."``, which, with the ``DOTALL`` flag turned off, matches any character except a line separator. It also affects the line anchors ``^`` and ``$`` (in multiline mode). + +Set operators +^^^^^^^^^^^^^ + +**Version 1 behaviour only** + +Set operators have been added, and a set ``[...]`` can include nested sets. + +The operators, in order of increasing precedence, are: + +* ``||`` for union ("x||y" means "x or y") + +* ``~~`` (double tilde) for symmetric difference ("x~~y" means "x or y, but not both") + +* ``&&`` for intersection ("x&&y" means "x and y") + +* ``--`` (double dash) for difference ("x--y" means "x but not y") + +Implicit union, ie, simple juxtaposition like in ``[ab]``, has the highest precedence. Thus, ``[ab&&cd]`` is the same as ``[[a||b]&&[c||d]]``. + +Examples: + +* ``[ab]`` # Set containing 'a' and 'b' + +* ``[a-z]`` # Set containing 'a' .. 'z' + +* ``[[a-z]--[qw]]`` # Set containing 'a' .. 'z', but not 'q' or 'w' + +* ``[a-z--qw]`` # Same as above + +* ``[\p{L}--QW]`` # Set containing all letters except 'Q' and 'W' + +* ``[\p{N}--[0-9]]`` # Set containing all numbers except '0' .. '9' + +* ``[\p{ASCII}&&\p{Letter}]`` # Set containing all characters which are ASCII and letter + +regex.escape (`issue #2650 `_) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +regex.escape has an additional keyword parameter ``special_only``. When True, only 'special' regex characters, such as '?', are escaped. + +Examples: + +.. sourcecode:: python + + >>> regex.escape("foo!?", special_only=False) + 'foo\\!\\?' + >>> regex.escape("foo!?", special_only=True) + 'foo!\\?' + +regex.escape (`Hg issue 249 `_) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +regex.escape has an additional keyword parameter ``literal_spaces``. When True, spaces are not escaped. + +Examples: + +.. sourcecode:: python + + >>> regex.escape("foo bar!?", literal_spaces=False) + 'foo\\ bar!\\?' + >>> regex.escape("foo bar!?", literal_spaces=True) + 'foo bar!\\?' + +Repeated captures (`issue #7132 `_) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +A match object has additional methods which return information on all the successful matches of a repeated capture group. These methods are: + +* ``matchobject.captures([group1, ...])`` + + * Returns a list of the strings matched in a group or groups. Compare with ``matchobject.group([group1, ...])``. + +* ``matchobject.starts([group])`` + + * Returns a list of the start positions. Compare with ``matchobject.start([group])``. + +* ``matchobject.ends([group])`` + + * Returns a list of the end positions. Compare with ``matchobject.end([group])``. + +* ``matchobject.spans([group])`` + + * Returns a list of the spans. Compare with ``matchobject.span([group])``. + +Examples: + +.. sourcecode:: python + + >>> m = regex.search(r"(\w{3})+", "123456789") + >>> m.group(1) + '789' + >>> m.captures(1) + ['123', '456', '789'] + >>> m.start(1) + 6 + >>> m.starts(1) + [0, 3, 6] + >>> m.end(1) + 9 + >>> m.ends(1) + [3, 6, 9] + >>> m.span(1) + (6, 9) + >>> m.spans(1) + [(0, 3), (3, 6), (6, 9)] + +Atomic grouping (`issue #433030 `_) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +``(?>...)`` + +If the following pattern subsequently fails, then the subpattern as a whole will fail. + +Possessive quantifiers. +^^^^^^^^^^^^^^^^^^^^^^^ + +``(?:...)?+`` ; ``(?:...)*+`` ; ``(?:...)++`` ; ``(?:...){min,max}+`` + +The subpattern is matched up to 'max' times. If the following pattern subsequently fails, then all of the repeated subpatterns will fail as a whole. For example, ``(?:...)++`` is equivalent to ``(?>(?:...)+)``. + +Scoped flags (`issue #433028 `_) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +``(?flags-flags:...)`` + +The flags will apply only to the subpattern. Flags can be turned on or off. + +Definition of 'word' character (`issue #1693050 `_) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The definition of a 'word' character has been expanded for Unicode. It now conforms to the Unicode specification at ``http://www.unicode.org/reports/tr29/``. + +Variable-length lookbehind +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +A lookbehind can match a variable-length string. + +Flags argument for regex.split, regex.sub and regex.subn (`issue #3482 `_) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +``regex.split``, ``regex.sub`` and ``regex.subn`` support a 'flags' argument. + +Pos and endpos arguments for regex.sub and regex.subn +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +``regex.sub`` and ``regex.subn`` support 'pos' and 'endpos' arguments. + +'Overlapped' argument for regex.findall and regex.finditer +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +``regex.findall`` and ``regex.finditer`` support an 'overlapped' flag which permits overlapped matches. + +Splititer +^^^^^^^^^ + +``regex.splititer`` has been added. It's a generator equivalent of ``regex.split``. + +Subscripting for groups +^^^^^^^^^^^^^^^^^^^^^^^ + +A match object accepts access to the captured groups via subscripting and slicing: + +.. sourcecode:: python + + >>> m = regex.search(r"(?P.*?)(?P\d+)(?P.*)", "pqr123stu") + >>> print(m["before"]) + pqr + >>> print(len(m)) + 4 + >>> print(m[:]) + ('pqr123stu', 'pqr', '123', 'stu') + +Named groups +^^^^^^^^^^^^ + +Groups can be named with ``(?...)`` as well as the current ``(?P...)``. + +Group references +^^^^^^^^^^^^^^^^ + +Groups can be referenced within a pattern with ``\g``. This also allows there to be more than 99 groups. + +Named characters +^^^^^^^^^^^^^^^^ + +``\N{name}`` + +Named characters are supported. (Note: only those known by Python's Unicode database are supported.) + +Unicode codepoint properties, including scripts and blocks +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +``\p{property=value}``; ``\P{property=value}``; ``\p{value}`` ; ``\P{value}`` + +Many Unicode properties are supported, including blocks and scripts. ``\p{property=value}`` or ``\p{property:value}`` matches a character whose property ``property`` has value ``value``. The inverse of ``\p{property=value}`` is ``\P{property=value}`` or ``\p{^property=value}``. + +If the short form ``\p{value}`` is used, the properties are checked in the order: ``General_Category``, ``Script``, ``Block``, binary property: + +* ``Latin``, the 'Latin' script (``Script=Latin``). + +* ``BasicLatin``, the 'BasicLatin' block (``Block=BasicLatin``). + +* ``Alphabetic``, the 'Alphabetic' binary property (``Alphabetic=Yes``). + +A short form starting with ``Is`` indicates a script or binary property: + +* ``IsLatin``, the 'Latin' script (``Script=Latin``). + +* ``IsAlphabetic``, the 'Alphabetic' binary property (``Alphabetic=Yes``). + +A short form starting with ``In`` indicates a block property: + +* ``InBasicLatin``, the 'BasicLatin' block (``Block=BasicLatin``). + +POSIX character classes +^^^^^^^^^^^^^^^^^^^^^^^ + +``[[:alpha:]]``; ``[[:^alpha:]]`` + +POSIX character classes are supported. These are normally treated as an alternative form of ``\p{...}``. + +The exceptions are ``alnum``, ``digit``, ``punct`` and ``xdigit``, whose definitions are different from those of Unicode. + +``[[:alnum:]]`` is equivalent to ``\p{posix_alnum}``. + +``[[:digit:]]`` is equivalent to ``\p{posix_digit}``. + +``[[:punct:]]`` is equivalent to ``\p{posix_punct}``. + +``[[:xdigit:]]`` is equivalent to ``\p{posix_xdigit}``. + +Search anchor +^^^^^^^^^^^^^ + +``\G`` + +A search anchor has been added. It matches at the position where each search started/continued and can be used for contiguous matches or in negative variable-length lookbehinds to limit how far back the lookbehind goes: + +.. sourcecode:: python + + >>> regex.findall(r"\w{2}", "abcd ef") + ['ab', 'cd', 'ef'] + >>> regex.findall(r"\G\w{2}", "abcd ef") + ['ab', 'cd'] + +* The search starts at position 0 and matches 2 letters 'ab'. + +* The search continues at position 2 and matches 2 letters 'cd'. + +* The search continues at position 4 and fails to match any letters. + +* The anchor stops the search start position from being advanced, so there are no more results. + +Reverse searching +^^^^^^^^^^^^^^^^^ + +Searches can now work backwards: + +.. sourcecode:: python + + >>> regex.findall(r".", "abc") + ['a', 'b', 'c'] + >>> regex.findall(r"(?r).", "abc") + ['c', 'b', 'a'] + +Note: the result of a reverse search is not necessarily the reverse of a forward search: + +.. sourcecode:: python + + >>> regex.findall(r"..", "abcde") + ['ab', 'cd'] + >>> regex.findall(r"(?r)..", "abcde") + ['de', 'bc'] + +Matching a single grapheme +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +``\X`` + +The grapheme matcher is supported. It now conforms to the Unicode specification at ``http://www.unicode.org/reports/tr29/``. + +Branch reset +^^^^^^^^^^^^ + +``(?|...|...)`` + +Capture group numbers will be reused across the alternatives, but groups with different names will have different group numbers. + +Examples: + +.. sourcecode:: python + + >>> regex.match(r"(?|(first)|(second))", "first").groups() + ('first',) + >>> regex.match(r"(?|(first)|(second))", "second").groups() + ('second',) + +Note that there is only one group. + +Default Unicode word boundary +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The ``WORD`` flag changes the definition of a 'word boundary' to that of a default Unicode word boundary. This applies to ``\b`` and ``\B``. + +Timeout (Python 3) +^^^^^^^^^^^^^^^^^^ + +The matching methods and functions support timeouts. The timeout (in seconds) applies to the entire operation: + +.. sourcecode:: python + + >>> from time import sleep + >>> + >>> def fast_replace(m): + ... return 'X' + ... + >>> def slow_replace(m): + ... sleep(0.5) + ... return 'X' + ... + >>> regex.sub(r'[a-z]', fast_replace, 'abcde', timeout=2) + 'XXXXX' + >>> regex.sub(r'[a-z]', slow_replace, 'abcde', timeout=2) + Traceback (most recent call last): + File "", line 1, in + File "C:\Python37\lib\site-packages\regex\regex.py", line 276, in sub + endpos, concurrent, timeout) + TimeoutError: regex timed out diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/regex-2022.6.2.dist-info/RECORD b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/regex-2022.6.2.dist-info/RECORD new file mode 100644 index 0000000000000000000000000000000000000000..1546be2e5c57e3992cc5003c1a7242f02d700589 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/regex-2022.6.2.dist-info/RECORD @@ -0,0 +1,16 @@ +regex-2022.6.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +regex-2022.6.2.dist-info/LICENSE.txt,sha256=v_Ve9M3MjBTOJZ-OirYOJkQYRA1jNfTcE4Jz-9UGFE0,11584 +regex-2022.6.2.dist-info/METADATA,sha256=ch3wQ7Rq5i2BRNWiO0G8GGDOHoTUiQF88NS9LotFov8,39260 +regex-2022.6.2.dist-info/RECORD,, +regex-2022.6.2.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +regex-2022.6.2.dist-info/WHEEL,sha256=-ijGDuALlPxm3HbhKntps0QzHsi-DPlXqgerYTTJkFE,148 +regex-2022.6.2.dist-info/top_level.txt,sha256=aQmiDMhNTF26cCK4_7D-qaVvhbxClG0wyCTnEhkzYBs,6 +regex/__init__.py,sha256=9slNQEb4SCZ9LncNzcQvqmkyxXlcOAF7QwAwigxWjsw,65 +regex/__pycache__/__init__.cpython-38.pyc,, +regex/__pycache__/_regex_core.cpython-38.pyc,, +regex/__pycache__/regex.cpython-38.pyc,, +regex/__pycache__/test_regex.cpython-38.pyc,, +regex/_regex.cpython-38-x86_64-linux-gnu.so,sha256=V6AHYf-J1t3jdtKugXfXRwE_XgwTlA8bIu1XQjGyXdI,2471112 +regex/_regex_core.py,sha256=8LW3zNBvWiX28ctbEQB4bNH1nOZ62k3aofxYc5CFNvo,141150 +regex/regex.py,sha256=pwntQhYA2aLuK25kMbadT8P-_u3komZdIlw-7ANgEqs,32645 +regex/test_regex.py,sha256=cX6BZoucKI6l-Q5hKohXKs8UmB85VxbM9r92zmzAk0Q,218253 diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/regex-2022.6.2.dist-info/REQUESTED b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/regex-2022.6.2.dist-info/REQUESTED new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/regex-2022.6.2.dist-info/WHEEL b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/regex-2022.6.2.dist-info/WHEEL new file mode 100644 index 0000000000000000000000000000000000000000..3a48d3480384503bea53d4a7c55a666ace0eb5fc --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/regex-2022.6.2.dist-info/WHEEL @@ -0,0 +1,6 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.37.1) +Root-Is-Purelib: false +Tag: cp38-cp38-manylinux_2_17_x86_64 +Tag: cp38-cp38-manylinux2014_x86_64 + diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/regex-2022.6.2.dist-info/top_level.txt b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/regex-2022.6.2.dist-info/top_level.txt new file mode 100644 index 0000000000000000000000000000000000000000..4f9256d62325c75de027d1cd48f1ff520117413e --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/regex-2022.6.2.dist-info/top_level.txt @@ -0,0 +1 @@ +regex diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/wcwidth-0.2.13.dist-info/INSTALLER b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/wcwidth-0.2.13.dist-info/INSTALLER new file mode 100644 index 0000000000000000000000000000000000000000..a1b589e38a32041e49332e5e81c2d363dc418d68 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/wcwidth-0.2.13.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/wcwidth-0.2.13.dist-info/LICENSE b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/wcwidth-0.2.13.dist-info/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..a44c0757243a785b0b73c21a38c45f44a4a2c32f --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/wcwidth-0.2.13.dist-info/LICENSE @@ -0,0 +1,27 @@ +The MIT License (MIT) + +Copyright (c) 2014 Jeff Quast + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +Markus Kuhn -- 2007-05-26 (Unicode 5.0) + +Permission to use, copy, modify, and distribute this software +for any purpose and without fee is hereby granted. The author +disclaims all warranties with regard to this software. diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/wcwidth-0.2.13.dist-info/RECORD b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/wcwidth-0.2.13.dist-info/RECORD new file mode 100644 index 0000000000000000000000000000000000000000..18eae3bfddb630b823e7dfdd12e635aecbfbee52 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/wcwidth-0.2.13.dist-info/RECORD @@ -0,0 +1,19 @@ +wcwidth-0.2.13.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +wcwidth-0.2.13.dist-info/LICENSE,sha256=cLmKlaIUTrcK-AF_qMbZXOJH5AhnQ26LxknhN_4T0ho,1322 +wcwidth-0.2.13.dist-info/METADATA,sha256=wBs2ALubn0kTdhEFDXc1gZBU_zf4rlfNgv1YS02jzLQ,14992 +wcwidth-0.2.13.dist-info/RECORD,, +wcwidth-0.2.13.dist-info/WHEEL,sha256=iYlv5fX357PQyRT2o6tw1bN-YcKFFHKqB_LwHO5wP-g,110 +wcwidth-0.2.13.dist-info/top_level.txt,sha256=LLjS8SFiXXuLEcD2BNdFdGhpKWe5opHtvn7KNj9AIRI,8 +wcwidth-0.2.13.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1 +wcwidth/__init__.py,sha256=ecZx3UVoktZuAvatG6NetByVFgENkKl9htmk0ZasTmA,1076 +wcwidth/__pycache__/__init__.cpython-38.pyc,, +wcwidth/__pycache__/table_vs16.cpython-38.pyc,, +wcwidth/__pycache__/table_wide.cpython-38.pyc,, +wcwidth/__pycache__/table_zero.cpython-38.pyc,, +wcwidth/__pycache__/unicode_versions.cpython-38.pyc,, +wcwidth/__pycache__/wcwidth.cpython-38.pyc,, +wcwidth/table_vs16.py,sha256=hPbuoFxmxrGfuBaeoheMTAGmgB2a4EudhxYsYokLf6o,6857 +wcwidth/table_wide.py,sha256=vUHjEOuRw1WGyUcIw2L9GymZsYvC2I3dc858mlYyTYM,100896 +wcwidth/table_zero.py,sha256=4ZeihLZDH8obgrwA6ct-vu2lxc4t_DsfyiB9p9Ovxbo,359450 +wcwidth/unicode_versions.py,sha256=7nShgeRYrvZFkGpREdr-PkUeXnuM-WxeOmGYj6QNaaE,851 +wcwidth/wcwidth.py,sha256=TLzyH1ahdEDDPOIMcqVO4U0gyKwSyZdzAsSgEPuVFGY,14512 diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/wcwidth-0.2.13.dist-info/WHEEL b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/wcwidth-0.2.13.dist-info/WHEEL new file mode 100644 index 0000000000000000000000000000000000000000..c34f1162ef9a50c355df1261ef6194ffc1b39975 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/wcwidth-0.2.13.dist-info/WHEEL @@ -0,0 +1,6 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.41.2) +Root-Is-Purelib: true +Tag: py2-none-any +Tag: py3-none-any + diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/wcwidth-0.2.13.dist-info/top_level.txt b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/wcwidth-0.2.13.dist-info/top_level.txt new file mode 100644 index 0000000000000000000000000000000000000000..723a22ca00a76ffd3df5b5513c78c751654f075c --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/wcwidth-0.2.13.dist-info/top_level.txt @@ -0,0 +1 @@ +wcwidth diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/wcwidth-0.2.13.dist-info/zip-safe b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/wcwidth-0.2.13.dist-info/zip-safe new file mode 100644 index 0000000000000000000000000000000000000000..8b137891791fe96927ad78e64b0aad7bded08bdc --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/wcwidth-0.2.13.dist-info/zip-safe @@ -0,0 +1 @@ + diff --git a/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/zstandard-0.19.0.dist-info/direct_url.json b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/zstandard-0.19.0.dist-info/direct_url.json new file mode 100644 index 0000000000000000000000000000000000000000..df8da4ed8c7d2f8bbe898d80f5931b06385da3b4 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/zstandard-0.19.0.dist-info/direct_url.json @@ -0,0 +1 @@ +{"dir_info": {}, "url": "file:///croot/zstandard_1677013143055/work"} \ No newline at end of file diff --git a/my_container_sandbox/workspace/anaconda3/pkgs/libgomp-9.3.0-h5101ec6_17.conda b/my_container_sandbox/workspace/anaconda3/pkgs/libgomp-9.3.0-h5101ec6_17.conda new file mode 100644 index 0000000000000000000000000000000000000000..172dfab1859652695b21806eb0c84bb77c46531b --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/pkgs/libgomp-9.3.0-h5101ec6_17.conda @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b53f7b4d5a1a3a3d61ad86b043f91a0ca9ee16b77194021383185d34eb592e56 +size 318078 diff --git a/my_container_sandbox/workspace/anaconda3/pkgs/xz-5.4.6-h5eee18b_0.conda b/my_container_sandbox/workspace/anaconda3/pkgs/xz-5.4.6-h5eee18b_0.conda new file mode 100644 index 0000000000000000000000000000000000000000..447078d7a35bffea5a90cff942cb620129d1b523 --- /dev/null +++ b/my_container_sandbox/workspace/anaconda3/pkgs/xz-5.4.6-h5eee18b_0.conda @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a0b4228fcb688b4b376c82c00cbf04ee3867a6edab1fdcad4907d005d980c26a +size 666300 diff --git a/my_container_sandbox/workspace/difftumor/tumor_mask_access/unet_synt_liver_tumors.pt b/my_container_sandbox/workspace/difftumor/tumor_mask_access/unet_synt_liver_tumors.pt new file mode 100644 index 0000000000000000000000000000000000000000..e14fbf5437736a7f77067c3ffcddc8be5db657a3 --- /dev/null +++ b/my_container_sandbox/workspace/difftumor/tumor_mask_access/unet_synt_liver_tumors.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9b9c5ce10508151e0cb36ec0082b635e03eb86f65022c4f454708da7bdb25445 +size 19260008 diff --git a/tmp_inputs_32_24/case00007.nii.gz b/tmp_inputs_32_24/case00007.nii.gz new file mode 100644 index 0000000000000000000000000000000000000000..a8c7fdb833b1211a5967e71015065bd52be7ee3a --- /dev/null +++ b/tmp_inputs_32_24/case00007.nii.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:453716882149fec5014bdc3a2e7dd0bcdd00c49da99942e5ce955f85aa00b0c2 +size 33253044 diff --git a/tmp_inputs_32_6/case00003.nii.gz b/tmp_inputs_32_6/case00003.nii.gz new file mode 100644 index 0000000000000000000000000000000000000000..c7a6edb23a51f941e922764833d91064e9fd3b6e --- /dev/null +++ b/tmp_inputs_32_6/case00003.nii.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:df371ea9b56b33616ba5f5f10a1d8fae88331dfa89de261b5d78708810d3f814 +size 32840542