prasb commited on
Commit
f83de80
·
verified ·
1 Parent(s): aa2967f

Add files using upload-large-folder tool

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .gitattributes +3 -0
  2. my_container_sandbox/workspace/anaconda3/lib/python3.8/lib-dynload/_codecs_jp.cpython-38-x86_64-linux-gnu.so +3 -0
  3. my_container_sandbox/workspace/anaconda3/lib/python3.8/lib-dynload/_decimal.cpython-38-x86_64-linux-gnu.so +3 -0
  4. my_container_sandbox/workspace/anaconda3/lib/python3.8/lib-dynload/readline.cpython-38-x86_64-linux-gnu.so +3 -0
  5. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/PyYAML-6.0.dist-info/INSTALLER +1 -0
  6. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/PyYAML-6.0.dist-info/LICENSE +20 -0
  7. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/PyYAML-6.0.dist-info/METADATA +46 -0
  8. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/PyYAML-6.0.dist-info/RECORD +44 -0
  9. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/PyYAML-6.0.dist-info/REQUESTED +0 -0
  10. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/PyYAML-6.0.dist-info/WHEEL +8 -0
  11. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/PyYAML-6.0.dist-info/top_level.txt +2 -0
  12. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/SimpleITK-2.1.1.2.dist-info/INSTALLER +1 -0
  13. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/SimpleITK-2.1.1.2.dist-info/METADATA +119 -0
  14. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/SimpleITK-2.1.1.2.dist-info/RECORD +18 -0
  15. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/SimpleITK-2.1.1.2.dist-info/REQUESTED +0 -0
  16. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/SimpleITK-2.1.1.2.dist-info/WHEEL +6 -0
  17. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/SimpleITK-2.1.1.2.dist-info/top_level.txt +1 -0
  18. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/click/__init__.py +73 -0
  19. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/click/_compat.py +626 -0
  20. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/click/_textwrap.py +49 -0
  21. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/click/_winconsole.py +279 -0
  22. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/click/core.py +0 -0
  23. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/click/decorators.py +497 -0
  24. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/click/exceptions.py +287 -0
  25. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/click/formatting.py +301 -0
  26. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/click/globals.py +68 -0
  27. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/click/parser.py +529 -0
  28. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/click/py.typed +0 -0
  29. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/click/shell_completion.py +580 -0
  30. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/click/termui.py +787 -0
  31. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/click/testing.py +479 -0
  32. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/click/types.py +1073 -0
  33. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/click/utils.py +580 -0
  34. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/fontTools/__init__.py +8 -0
  35. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/fontTools/__main__.py +34 -0
  36. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/fontTools/afmLib.py +430 -0
  37. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/fontTools/agl.py +0 -0
  38. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/fontTools/fontBuilder.py +958 -0
  39. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/fontTools/help.py +35 -0
  40. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/fontTools/tfmLib.py +460 -0
  41. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/fontTools/ttx.py +420 -0
  42. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/fontTools/unicode.py +47 -0
  43. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/fonttools-4.34.4.dist-info/INSTALLER +1 -0
  44. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/fonttools-4.34.4.dist-info/LICENSE +21 -0
  45. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/fonttools-4.34.4.dist-info/RECORD +567 -0
  46. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/fonttools-4.34.4.dist-info/REQUESTED +0 -0
  47. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/fonttools-4.34.4.dist-info/WHEEL +5 -0
  48. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/fonttools-4.34.4.dist-info/entry_points.txt +6 -0
  49. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/frozenlist/__init__.py +96 -0
  50. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/frozenlist/__init__.pyi +47 -0
.gitattributes CHANGED
@@ -223,3 +223,6 @@ my_container_sandbox/workspace/anaconda3/lib/python3.8/lib-dynload/select.cpytho
223
  my_container_sandbox/workspace/anaconda3/lib/libnpps.so filter=lfs diff=lfs merge=lfs -text
224
  my_container_sandbox/workspace/anaconda3/lib/python3.8/lib-dynload/audioop.cpython-38-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text
225
  my_container_sandbox/workspace/anaconda3/lib/python3.8/lib-dynload/_sha3.cpython-38-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text
 
 
 
 
223
  my_container_sandbox/workspace/anaconda3/lib/libnpps.so filter=lfs diff=lfs merge=lfs -text
224
  my_container_sandbox/workspace/anaconda3/lib/python3.8/lib-dynload/audioop.cpython-38-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text
225
  my_container_sandbox/workspace/anaconda3/lib/python3.8/lib-dynload/_sha3.cpython-38-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text
226
+ my_container_sandbox/workspace/anaconda3/lib/python3.8/lib-dynload/_codecs_jp.cpython-38-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text
227
+ my_container_sandbox/workspace/anaconda3/lib/python3.8/lib-dynload/_decimal.cpython-38-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text
228
+ my_container_sandbox/workspace/anaconda3/lib/python3.8/lib-dynload/readline.cpython-38-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text
my_container_sandbox/workspace/anaconda3/lib/python3.8/lib-dynload/_codecs_jp.cpython-38-x86_64-linux-gnu.so ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:afed7966a11edf7870e61b2624ef9a9b67b3668d725fc3c6690469513a8de55b
3
+ size 324800
my_container_sandbox/workspace/anaconda3/lib/python3.8/lib-dynload/_decimal.cpython-38-x86_64-linux-gnu.so ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:7262bad6fbdb5212a078fa84778d13ec4354aaa882b8192f57b5effdb1506200
3
+ size 1450816
my_container_sandbox/workspace/anaconda3/lib/python3.8/lib-dynload/readline.cpython-38-x86_64-linux-gnu.so ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:c86a4d71eb06fe15670233d0f02f65bdb7b6643da49a9e91080fe45aa2948c17
3
+ size 100272
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/PyYAML-6.0.dist-info/INSTALLER ADDED
@@ -0,0 +1 @@
 
 
1
+ pip
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/PyYAML-6.0.dist-info/LICENSE ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Copyright (c) 2017-2021 Ingy döt Net
2
+ Copyright (c) 2006-2016 Kirill Simonov
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
5
+ this software and associated documentation files (the "Software"), to deal in
6
+ the Software without restriction, including without limitation the rights to
7
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
8
+ of the Software, and to permit persons to whom the Software is furnished to do
9
+ so, subject to the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in all
12
+ copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ SOFTWARE.
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/PyYAML-6.0.dist-info/METADATA ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Metadata-Version: 2.1
2
+ Name: PyYAML
3
+ Version: 6.0
4
+ Summary: YAML parser and emitter for Python
5
+ Home-page: https://pyyaml.org/
6
+ Author: Kirill Simonov
7
+ Author-email: xi@resolvent.net
8
+ License: MIT
9
+ Download-URL: https://pypi.org/project/PyYAML/
10
+ Project-URL: Bug Tracker, https://github.com/yaml/pyyaml/issues
11
+ Project-URL: CI, https://github.com/yaml/pyyaml/actions
12
+ Project-URL: Documentation, https://pyyaml.org/wiki/PyYAMLDocumentation
13
+ Project-URL: Mailing lists, http://lists.sourceforge.net/lists/listinfo/yaml-core
14
+ Project-URL: Source Code, https://github.com/yaml/pyyaml
15
+ Platform: Any
16
+ Classifier: Development Status :: 5 - Production/Stable
17
+ Classifier: Intended Audience :: Developers
18
+ Classifier: License :: OSI Approved :: MIT License
19
+ Classifier: Operating System :: OS Independent
20
+ Classifier: Programming Language :: Cython
21
+ Classifier: Programming Language :: Python
22
+ Classifier: Programming Language :: Python :: 3
23
+ Classifier: Programming Language :: Python :: 3.6
24
+ Classifier: Programming Language :: Python :: 3.7
25
+ Classifier: Programming Language :: Python :: 3.8
26
+ Classifier: Programming Language :: Python :: 3.9
27
+ Classifier: Programming Language :: Python :: 3.10
28
+ Classifier: Programming Language :: Python :: Implementation :: CPython
29
+ Classifier: Programming Language :: Python :: Implementation :: PyPy
30
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
31
+ Classifier: Topic :: Text Processing :: Markup
32
+ Requires-Python: >=3.6
33
+ License-File: LICENSE
34
+
35
+ YAML is a data serialization format designed for human readability
36
+ and interaction with scripting languages. PyYAML is a YAML parser
37
+ and emitter for Python.
38
+
39
+ PyYAML features a complete YAML 1.1 parser, Unicode support, pickle
40
+ support, capable extension API, and sensible error messages. PyYAML
41
+ supports standard YAML tags and provides Python-specific tags that
42
+ allow to represent an arbitrary Python object.
43
+
44
+ PyYAML is applicable for a broad range of tasks from complex
45
+ configuration files to object serialization and persistence.
46
+
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/PyYAML-6.0.dist-info/RECORD ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ PyYAML-6.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
2
+ PyYAML-6.0.dist-info/LICENSE,sha256=jTko-dxEkP1jVwfLiOsmvXZBAqcoKVQwfT5RZ6V36KQ,1101
3
+ PyYAML-6.0.dist-info/METADATA,sha256=QmHx9kGp_0yezQCXYaft4eEFeJ6W4oyFfYwHDLP1kdg,2006
4
+ PyYAML-6.0.dist-info/RECORD,,
5
+ PyYAML-6.0.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
+ PyYAML-6.0.dist-info/WHEEL,sha256=RiwktpmF40OphKd3_aIG01PzIOQlJ7dpBn3cFSc9vak,217
7
+ PyYAML-6.0.dist-info/top_level.txt,sha256=rpj0IVMTisAjh_1vG3Ccf9v5jpCQwAz6cD1IVU5ZdhQ,11
8
+ _yaml/__init__.py,sha256=04Ae_5osxahpJHa3XBZUAf4wi6XX32gR8D6X6p64GEA,1402
9
+ _yaml/__pycache__/__init__.cpython-38.pyc,,
10
+ yaml/__init__.py,sha256=NDS7S8XgA72-hY6LRmGzUWTPvzGzjWVrWk-OGA-77AA,12309
11
+ yaml/__pycache__/__init__.cpython-38.pyc,,
12
+ yaml/__pycache__/composer.cpython-38.pyc,,
13
+ yaml/__pycache__/constructor.cpython-38.pyc,,
14
+ yaml/__pycache__/cyaml.cpython-38.pyc,,
15
+ yaml/__pycache__/dumper.cpython-38.pyc,,
16
+ yaml/__pycache__/emitter.cpython-38.pyc,,
17
+ yaml/__pycache__/error.cpython-38.pyc,,
18
+ yaml/__pycache__/events.cpython-38.pyc,,
19
+ yaml/__pycache__/loader.cpython-38.pyc,,
20
+ yaml/__pycache__/nodes.cpython-38.pyc,,
21
+ yaml/__pycache__/parser.cpython-38.pyc,,
22
+ yaml/__pycache__/reader.cpython-38.pyc,,
23
+ yaml/__pycache__/representer.cpython-38.pyc,,
24
+ yaml/__pycache__/resolver.cpython-38.pyc,,
25
+ yaml/__pycache__/scanner.cpython-38.pyc,,
26
+ yaml/__pycache__/serializer.cpython-38.pyc,,
27
+ yaml/__pycache__/tokens.cpython-38.pyc,,
28
+ yaml/_yaml.cpython-38-x86_64-linux-gnu.so,sha256=lMaKSmQZy3WNZSmmU0Wg5Y5ZAs-HR5vItyGVUIsp8Rg,2847784
29
+ yaml/composer.py,sha256=_Ko30Wr6eDWUeUpauUGT3Lcg9QPBnOPVlTnIMRGJ9FM,4883
30
+ yaml/constructor.py,sha256=kNgkfaeLUkwQYY_Q6Ff1Tz2XVw_pG1xVE9Ak7z-viLA,28639
31
+ yaml/cyaml.py,sha256=6ZrAG9fAYvdVe2FK_w0hmXoG7ZYsoYUwapG8CiC72H0,3851
32
+ yaml/dumper.py,sha256=PLctZlYwZLp7XmeUdwRuv4nYOZ2UBnDIUy8-lKfLF-o,2837
33
+ yaml/emitter.py,sha256=jghtaU7eFwg31bG0B7RZea_29Adi9CKmXq_QjgQpCkQ,43006
34
+ yaml/error.py,sha256=Ah9z-toHJUbE9j-M8YpxgSRM5CgLCcwVzJgLLRF2Fxo,2533
35
+ yaml/events.py,sha256=50_TksgQiE4up-lKo_V-nBy-tAIxkIPQxY5qDhKCeHw,2445
36
+ yaml/loader.py,sha256=UVa-zIqmkFSCIYq_PgSGm4NSJttHY2Rf_zQ4_b1fHN0,2061
37
+ yaml/nodes.py,sha256=gPKNj8pKCdh2d4gr3gIYINnPOaOxGhJAUiYhGRnPE84,1440
38
+ yaml/parser.py,sha256=ilWp5vvgoHFGzvOZDItFoGjD6D42nhlZrZyjAwa0oJo,25495
39
+ yaml/reader.py,sha256=0dmzirOiDG4Xo41RnuQS7K9rkY3xjHiVasfDMNTqCNw,6794
40
+ yaml/representer.py,sha256=IuWP-cAW9sHKEnS0gCqSa894k1Bg4cgTxaDwIcbRQ-Y,14190
41
+ yaml/resolver.py,sha256=9L-VYfm4mWHxUD1Vg4X7rjDRK_7VZd6b92wzq7Y2IKY,9004
42
+ yaml/scanner.py,sha256=YEM3iLZSaQwXcQRg2l2R4MdT0zGP2F9eHkKGKnHyWQY,51279
43
+ yaml/serializer.py,sha256=ChuFgmhU01hj4xgI8GaKv6vfM2Bujwa9i7d2FAHj7cA,4165
44
+ yaml/tokens.py,sha256=lTQIzSVw8Mg9wv459-TjiOQe6wVziqaRlqX2_89rp54,2573
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/PyYAML-6.0.dist-info/REQUESTED ADDED
File without changes
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/PyYAML-6.0.dist-info/WHEEL ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ Wheel-Version: 1.0
2
+ Generator: bdist_wheel (0.37.0)
3
+ Root-Is-Purelib: false
4
+ Tag: cp38-cp38-manylinux_2_5_x86_64
5
+ Tag: cp38-cp38-manylinux1_x86_64
6
+ Tag: cp38-cp38-manylinux_2_12_x86_64
7
+ Tag: cp38-cp38-manylinux2010_x86_64
8
+
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/PyYAML-6.0.dist-info/top_level.txt ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ _yaml
2
+ yaml
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/SimpleITK-2.1.1.2.dist-info/INSTALLER ADDED
@@ -0,0 +1 @@
 
 
1
+ pip
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/SimpleITK-2.1.1.2.dist-info/METADATA ADDED
@@ -0,0 +1,119 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Metadata-Version: 2.1
2
+ Name: SimpleITK
3
+ Version: 2.1.1.2
4
+ Summary: SimpleITK is a simplified interface to the Insight Toolkit (ITK) for image registration and segmentation
5
+ Home-page: http://simpleitk.org/
6
+ Author: Insight Software Consortium
7
+ Author-email: insight-users@itk.org
8
+ License: Apache
9
+ Project-URL: Bug Tracker, https://github.com/SimpleITK/SimpleITK/issues
10
+ Project-URL: Documentation, https://simpleitk.readthedocs.io/en/release/
11
+ Project-URL: Source Code, https://github.com/SimpleITK/SimpleITK
12
+ Keywords: SimpleITK ITK InsightToolkit segmentation registration
13
+ Platform: UNKNOWN
14
+ Classifier: License :: OSI Approved :: Apache Software License
15
+ Classifier: Programming Language :: Python
16
+ Classifier: Programming Language :: C++
17
+ Classifier: Development Status :: 5 - Production/Stable
18
+ Classifier: Intended Audience :: Education
19
+ Classifier: Intended Audience :: Healthcare Industry
20
+ Classifier: Intended Audience :: Science/Research
21
+ Classifier: Topic :: Scientific/Engineering
22
+ Classifier: Topic :: Scientific/Engineering :: Medical Science Apps.
23
+ Classifier: Topic :: Scientific/Engineering :: Information Analysis
24
+ Classifier: Topic :: Software Development :: Libraries
25
+ Classifier: Operating System :: Microsoft :: Windows
26
+ Classifier: Operating System :: POSIX
27
+ Classifier: Operating System :: Unix
28
+ Classifier: Operating System :: MacOS
29
+ Description-Content-Type: text/markdown
30
+
31
+ SimpleITK
32
+ =========
33
+
34
+ | | CircleCI | ReadTheDocs | AzurePipelines |
35
+ |:-------:|:---------:|:-------------:|:-------------:|
36
+ | release | [![CircleCI](https://circleci.com/gh/SimpleITK/SimpleITK/tree/release.svg?style=shield)](https://circleci.com/gh/SimpleITK/SimpleITK/tree/release) | [![ReadTheDoc](https://readthedocs.org/projects/simpleitk/badge/?version=release)](http://simpleitk.readthedocs.io/en/release/) | [![Build Status](https://dev.azure.com/SimpleITK-DevOps/SimpleITK/_apis/build/status/SimpleITK.SimpleITK?branchName=release)](https://dev.azure.com/SimpleITK-DevOps/SimpleITK/_build/latest?definitionId=2&branchName=release) |
37
+ | master | [![CircleCI](https://circleci.com/gh/SimpleITK/SimpleITK/tree/master.svg?style=shield)](https://circleci.com/gh/SimpleITK/SimpleITK/tree/master) | [![ReadTheDoc](https://readthedocs.org/projects/simpleitk/badge/?version=master)](http://simpleitk.readthedocs.io/en/master/) | [![Build Status](https://dev.azure.com/SimpleITK-DevOps/SimpleITK/_apis/build/status/SimpleITK.SimpleITK?branchName=master)](https://dev.azure.com/SimpleITK-DevOps/SimpleITK/_build/latest?definitionId=2&branchName=master) |
38
+
39
+
40
+ SimpleITK is an image analysis toolkit with a large number of components supporting general filtering operations, image segmentation and registration. It is built on top of the Insight Segmentation and Registration Toolkit [ITK](https://www.itk.org) with the intent of providing a simplified interface to ITK. SimpleITK itself is written in C++ but is available for a large number of programming languages. Currently these include:
41
+
42
+ * [Python](http://www.python.org)
43
+ * [R](https://www.r-project.org)
44
+ * [Java](http://www.java.com)
45
+ * [C#](http://msdn.microsoft.com/en-us/vcsharp/default.aspx)
46
+ * [Lua](http://www.lua.org)
47
+ * [TCL](https://www.tcl.tk/)
48
+ * [Ruby](https://www.ruby-lang.org/en/)
49
+
50
+
51
+ Wrapping of the C++ code is accomplished through [SWIG](http://www.swig.org), in principle, any language wrapped by SWIG should be applicable to SimpleITK.
52
+
53
+ Unlike ITK's support of n-dimensional spatio-temporal images, SimpleITK supports 2D, 3D and 4D images. The dimensionality refers to spatio-temporal dimensions, the voxels can be n-dimensional vectors.
54
+
55
+ SimpleITK is licensed under the [Apache License](http://www.opensource.org/licenses/apache2.0.php).
56
+
57
+ Acknowledgments
58
+ --------------
59
+ SimpleITK development has been supported by:
60
+
61
+ * The Intramural Research Program of the National Institutes of Health, National Institute of Allergy and Infectious Diseases.
62
+
63
+ * The US National Library of Medicine under the American Recovery and Reinvestment Act (ARRA) and under the Intramural Research Program of the U.S. National Institutes of Health.
64
+
65
+ * The Insight Software Consortium and the ITK user and developer communities.
66
+
67
+
68
+ License and Copyright
69
+ ---------------------
70
+
71
+ The SimpleITK project is part of the [Insight Software Consortium](https://www.insightsoftwareconsortium.org/)(ISC) a non-profit educational consortium dedicated to promoting and maintaining open-source, freely available software for bio-medical image analysis. The copyright is held by [NumFOCUS](https://numfocus.org/). The SimpleITK software is distributed under the [Apache License 2.0](https://github.com/SimpleITK/SimpleITK/blob/master/LICENSE).
72
+
73
+
74
+ How to Cite
75
+ --------
76
+
77
+ If you found SimpleITK useful in your research, support our efforts by citing
78
+ the relevant publication(s):
79
+
80
+ R. Beare, B. C. Lowekamp, Z. Yaniv, "Image Segmentation, Registration and
81
+ Characterization in R with SimpleITK", *J Stat Softw*, 86(8), https://doi.org/10.18637/jss.v086.i08, 2018.
82
+
83
+ Z. Yaniv, B. C. Lowekamp, H. J. Johnson, R. Beare, "SimpleITK Image-Analysis Notebooks: a Collaborative Environment for Education and Reproducible Research", *J Digit Imaging.*, 31(3): 290-303, https://doi.org/10.1007/s10278-017-0037-8, 2018.
84
+
85
+ B. C. Lowekamp, D. T. Chen, L. Ibáñez, D. Blezek, "The Design of SimpleITK", *Front. Neuroinform.*, 7:45. https://doi.org/10.3389/fninf.2013.00045, 2013.
86
+
87
+ Documentation
88
+ -------------
89
+ With massive libraries like SimpleITK, good documentation is a must. The documentation for SimpleITK is split up into multiple levels:
90
+ 1. [API Documentation](https://simpleitk.org/doxygen/latest/html/) - This contains class and function documentation. The descriptions for functions and classes are primarily borrowed from the original ITK C++ classes.
91
+ 2. [SimpleITK Documentation](http://simpleitk.readthedocs.io/en/master/) - This site contains high-level guides (fundamental SimpleITK concepts, common conventions, etc.), details with respect to the toolkit's binary distributions, instructions for building the toolkit, as well as SimpleITK examples in all supported programming languages. [This site replaced the
92
+ [SimpleITK Wiki](https://itk.org/Wiki/SimpleITK) which is mostly of interest for historical reasons.]
93
+ 3. [Juypyter Notebook Repository](http://insightsoftwareconsortium.github.io/SimpleITK-Notebooks/) - This repository contains a collection of Jupyter Notebooks illustrating the use of SimpleITK for educational and research activities. The notebooks demonstrate the use of SimpleITK for interactive image analysis using the Python and R programming languages. Recommended reading, if you are starting with SimpleITK.
94
+
95
+
96
+ Support
97
+ -------
98
+
99
+ SimpleITK provides access to most of the ITK components, but not all. If you are looking for something specific and can't find it, open an issue on GitHub or ask for support on the [forum](https://discourse.itk.org).
100
+
101
+ Report an Issue
102
+ ---------------
103
+
104
+ Help us improve SimpleITK by reporting issues you encounter. When you report an error, you allow us to address your specific problem, but more importantly you are helping all of the SimpleITK community.
105
+
106
+ **Thank you for helping making SimpleITK better!**
107
+
108
+ All issues are reported and managed on the [project's GitHub issue tracker](https://github.com/SimpleITK/SimpleITK/issues). When reporting an issue, please provide as much information as possible to enable us to reproduce the problem.
109
+
110
+ The following information will allow us to address your issue in a timely manner:
111
+ 1. Error message (copy & pasted) and focused description of the problem.
112
+ 2. Operating system, and version (e.g. OSX 10.11.6).
113
+ 3. Programming language, and version (e.g. Python 2.7.14, R 3.2.3).
114
+ 4. Version of SimpleITK (e.g. 1.1.0), just invoke the SimpleITK Version() function.
115
+ 5. How did you install SimpleITK, binary distribution (e.g. conda install -c simpleitk simpleitk), or built it from source (e.g. devtools::install_github("SimpleITK/SimpleITKRInstaller")).
116
+ 6. A minimal working example which causes the error.
117
+ 7. If your code requires input, possibly point to a minimal sized input image.
118
+
119
+
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/SimpleITK-2.1.1.2.dist-info/RECORD ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ SimpleITK-2.1.1.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
2
+ SimpleITK-2.1.1.2.dist-info/METADATA,sha256=TqEyR4KTBGwNTjrf4iBpPxU8sB-boL05nt7JKmdBFJQ,8065
3
+ SimpleITK-2.1.1.2.dist-info/RECORD,,
4
+ SimpleITK-2.1.1.2.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
+ SimpleITK-2.1.1.2.dist-info/WHEEL,sha256=VC8YzyxoGiXrzl8xKL9ftgvyZU-Uz6pGPrSATb2mDHw,148
6
+ SimpleITK-2.1.1.2.dist-info/top_level.txt,sha256=B1KR4Uq5HwDUTeXLYhuUE_Ryfnp5j8Tik9KptJj7Wr8,10
7
+ SimpleITK/SimpleITK.py,sha256=TWoLHw7FsHwNbn0f9DIpcsK8MBsT-_KZKBrELYIqYDk,1878079
8
+ SimpleITK/_SimpleITK.cpython-38-x86_64-linux-gnu.so,sha256=lPWMUfuz_9FTYum7joWHH6RBrHWzxHJbA1WQ-8y9SvI,246256112
9
+ SimpleITK/__init__.py,sha256=rcqfwADepv7hsdlUdAnvq6QvDdbh5amE9vd5GpUGiqo,846
10
+ SimpleITK/__pycache__/SimpleITK.cpython-38.pyc,,
11
+ SimpleITK/__pycache__/__init__.cpython-38.pyc,,
12
+ SimpleITK/__pycache__/_version.cpython-38.pyc,,
13
+ SimpleITK/__pycache__/extra.cpython-38.pyc,,
14
+ SimpleITK/_version.py,sha256=tUIfyR11gAIgaIVGlAm84Tq_a8UEnmJfx09IaOkneGw,1520
15
+ SimpleITK/docs/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
16
+ SimpleITK/docs/NOTICE,sha256=CR8SzcM7lSinW9xYMEDEoO_iT0LP4WckdQVYCaP3Y6o,174
17
+ SimpleITK/docs/Readme.md,sha256=v_FwrIFYVrDOBkT2-IPQzp_Koof3ECsLeTHxNdeGSqw,6689
18
+ SimpleITK/extra.py,sha256=FYlEeDulSFfR1GK2IfgqC6M-SmJiFLP7SbtKvVdWZ7E,15978
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/SimpleITK-2.1.1.2.dist-info/REQUESTED ADDED
File without changes
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/SimpleITK-2.1.1.2.dist-info/WHEEL ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ Wheel-Version: 1.0
2
+ Generator: bdist_wheel (0.37.1)
3
+ Root-Is-Purelib: false
4
+ Tag: cp38-cp38-manylinux_2_12_x86_64
5
+ Tag: cp38-cp38-manylinux2010_x86_64
6
+
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/SimpleITK-2.1.1.2.dist-info/top_level.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ SimpleITK
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/click/__init__.py ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Click is a simple Python module inspired by the stdlib optparse to make
3
+ writing command line scripts fun. Unlike other modules, it's based
4
+ around a simple API that does not come with too much magic and is
5
+ composable.
6
+ """
7
+ from .core import Argument as Argument
8
+ from .core import BaseCommand as BaseCommand
9
+ from .core import Command as Command
10
+ from .core import CommandCollection as CommandCollection
11
+ from .core import Context as Context
12
+ from .core import Group as Group
13
+ from .core import MultiCommand as MultiCommand
14
+ from .core import Option as Option
15
+ from .core import Parameter as Parameter
16
+ from .decorators import argument as argument
17
+ from .decorators import command as command
18
+ from .decorators import confirmation_option as confirmation_option
19
+ from .decorators import group as group
20
+ from .decorators import help_option as help_option
21
+ from .decorators import make_pass_decorator as make_pass_decorator
22
+ from .decorators import option as option
23
+ from .decorators import pass_context as pass_context
24
+ from .decorators import pass_obj as pass_obj
25
+ from .decorators import password_option as password_option
26
+ from .decorators import version_option as version_option
27
+ from .exceptions import Abort as Abort
28
+ from .exceptions import BadArgumentUsage as BadArgumentUsage
29
+ from .exceptions import BadOptionUsage as BadOptionUsage
30
+ from .exceptions import BadParameter as BadParameter
31
+ from .exceptions import ClickException as ClickException
32
+ from .exceptions import FileError as FileError
33
+ from .exceptions import MissingParameter as MissingParameter
34
+ from .exceptions import NoSuchOption as NoSuchOption
35
+ from .exceptions import UsageError as UsageError
36
+ from .formatting import HelpFormatter as HelpFormatter
37
+ from .formatting import wrap_text as wrap_text
38
+ from .globals import get_current_context as get_current_context
39
+ from .parser import OptionParser as OptionParser
40
+ from .termui import clear as clear
41
+ from .termui import confirm as confirm
42
+ from .termui import echo_via_pager as echo_via_pager
43
+ from .termui import edit as edit
44
+ from .termui import getchar as getchar
45
+ from .termui import launch as launch
46
+ from .termui import pause as pause
47
+ from .termui import progressbar as progressbar
48
+ from .termui import prompt as prompt
49
+ from .termui import secho as secho
50
+ from .termui import style as style
51
+ from .termui import unstyle as unstyle
52
+ from .types import BOOL as BOOL
53
+ from .types import Choice as Choice
54
+ from .types import DateTime as DateTime
55
+ from .types import File as File
56
+ from .types import FLOAT as FLOAT
57
+ from .types import FloatRange as FloatRange
58
+ from .types import INT as INT
59
+ from .types import IntRange as IntRange
60
+ from .types import ParamType as ParamType
61
+ from .types import Path as Path
62
+ from .types import STRING as STRING
63
+ from .types import Tuple as Tuple
64
+ from .types import UNPROCESSED as UNPROCESSED
65
+ from .types import UUID as UUID
66
+ from .utils import echo as echo
67
+ from .utils import format_filename as format_filename
68
+ from .utils import get_app_dir as get_app_dir
69
+ from .utils import get_binary_stream as get_binary_stream
70
+ from .utils import get_text_stream as get_text_stream
71
+ from .utils import open_file as open_file
72
+
73
+ __version__ = "8.1.3"
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/click/_compat.py ADDED
@@ -0,0 +1,626 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import codecs
2
+ import io
3
+ import os
4
+ import re
5
+ import sys
6
+ import typing as t
7
+ from weakref import WeakKeyDictionary
8
+
9
+ CYGWIN = sys.platform.startswith("cygwin")
10
+ MSYS2 = sys.platform.startswith("win") and ("GCC" in sys.version)
11
+ # Determine local App Engine environment, per Google's own suggestion
12
+ APP_ENGINE = "APPENGINE_RUNTIME" in os.environ and "Development/" in os.environ.get(
13
+ "SERVER_SOFTWARE", ""
14
+ )
15
+ WIN = sys.platform.startswith("win") and not APP_ENGINE and not MSYS2
16
+ auto_wrap_for_ansi: t.Optional[t.Callable[[t.TextIO], t.TextIO]] = None
17
+ _ansi_re = re.compile(r"\033\[[;?0-9]*[a-zA-Z]")
18
+
19
+
20
+ def get_filesystem_encoding() -> str:
21
+ return sys.getfilesystemencoding() or sys.getdefaultencoding()
22
+
23
+
24
+ def _make_text_stream(
25
+ stream: t.BinaryIO,
26
+ encoding: t.Optional[str],
27
+ errors: t.Optional[str],
28
+ force_readable: bool = False,
29
+ force_writable: bool = False,
30
+ ) -> t.TextIO:
31
+ if encoding is None:
32
+ encoding = get_best_encoding(stream)
33
+ if errors is None:
34
+ errors = "replace"
35
+ return _NonClosingTextIOWrapper(
36
+ stream,
37
+ encoding,
38
+ errors,
39
+ line_buffering=True,
40
+ force_readable=force_readable,
41
+ force_writable=force_writable,
42
+ )
43
+
44
+
45
+ def is_ascii_encoding(encoding: str) -> bool:
46
+ """Checks if a given encoding is ascii."""
47
+ try:
48
+ return codecs.lookup(encoding).name == "ascii"
49
+ except LookupError:
50
+ return False
51
+
52
+
53
+ def get_best_encoding(stream: t.IO) -> str:
54
+ """Returns the default stream encoding if not found."""
55
+ rv = getattr(stream, "encoding", None) or sys.getdefaultencoding()
56
+ if is_ascii_encoding(rv):
57
+ return "utf-8"
58
+ return rv
59
+
60
+
61
+ class _NonClosingTextIOWrapper(io.TextIOWrapper):
62
+ def __init__(
63
+ self,
64
+ stream: t.BinaryIO,
65
+ encoding: t.Optional[str],
66
+ errors: t.Optional[str],
67
+ force_readable: bool = False,
68
+ force_writable: bool = False,
69
+ **extra: t.Any,
70
+ ) -> None:
71
+ self._stream = stream = t.cast(
72
+ t.BinaryIO, _FixupStream(stream, force_readable, force_writable)
73
+ )
74
+ super().__init__(stream, encoding, errors, **extra)
75
+
76
+ def __del__(self) -> None:
77
+ try:
78
+ self.detach()
79
+ except Exception:
80
+ pass
81
+
82
+ def isatty(self) -> bool:
83
+ # https://bitbucket.org/pypy/pypy/issue/1803
84
+ return self._stream.isatty()
85
+
86
+
87
+ class _FixupStream:
88
+ """The new io interface needs more from streams than streams
89
+ traditionally implement. As such, this fix-up code is necessary in
90
+ some circumstances.
91
+
92
+ The forcing of readable and writable flags are there because some tools
93
+ put badly patched objects on sys (one such offender are certain version
94
+ of jupyter notebook).
95
+ """
96
+
97
+ def __init__(
98
+ self,
99
+ stream: t.BinaryIO,
100
+ force_readable: bool = False,
101
+ force_writable: bool = False,
102
+ ):
103
+ self._stream = stream
104
+ self._force_readable = force_readable
105
+ self._force_writable = force_writable
106
+
107
+ def __getattr__(self, name: str) -> t.Any:
108
+ return getattr(self._stream, name)
109
+
110
+ def read1(self, size: int) -> bytes:
111
+ f = getattr(self._stream, "read1", None)
112
+
113
+ if f is not None:
114
+ return t.cast(bytes, f(size))
115
+
116
+ return self._stream.read(size)
117
+
118
+ def readable(self) -> bool:
119
+ if self._force_readable:
120
+ return True
121
+ x = getattr(self._stream, "readable", None)
122
+ if x is not None:
123
+ return t.cast(bool, x())
124
+ try:
125
+ self._stream.read(0)
126
+ except Exception:
127
+ return False
128
+ return True
129
+
130
+ def writable(self) -> bool:
131
+ if self._force_writable:
132
+ return True
133
+ x = getattr(self._stream, "writable", None)
134
+ if x is not None:
135
+ return t.cast(bool, x())
136
+ try:
137
+ self._stream.write("") # type: ignore
138
+ except Exception:
139
+ try:
140
+ self._stream.write(b"")
141
+ except Exception:
142
+ return False
143
+ return True
144
+
145
+ def seekable(self) -> bool:
146
+ x = getattr(self._stream, "seekable", None)
147
+ if x is not None:
148
+ return t.cast(bool, x())
149
+ try:
150
+ self._stream.seek(self._stream.tell())
151
+ except Exception:
152
+ return False
153
+ return True
154
+
155
+
156
+ def _is_binary_reader(stream: t.IO, default: bool = False) -> bool:
157
+ try:
158
+ return isinstance(stream.read(0), bytes)
159
+ except Exception:
160
+ return default
161
+ # This happens in some cases where the stream was already
162
+ # closed. In this case, we assume the default.
163
+
164
+
165
+ def _is_binary_writer(stream: t.IO, default: bool = False) -> bool:
166
+ try:
167
+ stream.write(b"")
168
+ except Exception:
169
+ try:
170
+ stream.write("")
171
+ return False
172
+ except Exception:
173
+ pass
174
+ return default
175
+ return True
176
+
177
+
178
+ def _find_binary_reader(stream: t.IO) -> t.Optional[t.BinaryIO]:
179
+ # We need to figure out if the given stream is already binary.
180
+ # This can happen because the official docs recommend detaching
181
+ # the streams to get binary streams. Some code might do this, so
182
+ # we need to deal with this case explicitly.
183
+ if _is_binary_reader(stream, False):
184
+ return t.cast(t.BinaryIO, stream)
185
+
186
+ buf = getattr(stream, "buffer", None)
187
+
188
+ # Same situation here; this time we assume that the buffer is
189
+ # actually binary in case it's closed.
190
+ if buf is not None and _is_binary_reader(buf, True):
191
+ return t.cast(t.BinaryIO, buf)
192
+
193
+ return None
194
+
195
+
196
+ def _find_binary_writer(stream: t.IO) -> t.Optional[t.BinaryIO]:
197
+ # We need to figure out if the given stream is already binary.
198
+ # This can happen because the official docs recommend detaching
199
+ # the streams to get binary streams. Some code might do this, so
200
+ # we need to deal with this case explicitly.
201
+ if _is_binary_writer(stream, False):
202
+ return t.cast(t.BinaryIO, stream)
203
+
204
+ buf = getattr(stream, "buffer", None)
205
+
206
+ # Same situation here; this time we assume that the buffer is
207
+ # actually binary in case it's closed.
208
+ if buf is not None and _is_binary_writer(buf, True):
209
+ return t.cast(t.BinaryIO, buf)
210
+
211
+ return None
212
+
213
+
214
+ def _stream_is_misconfigured(stream: t.TextIO) -> bool:
215
+ """A stream is misconfigured if its encoding is ASCII."""
216
+ # If the stream does not have an encoding set, we assume it's set
217
+ # to ASCII. This appears to happen in certain unittest
218
+ # environments. It's not quite clear what the correct behavior is
219
+ # but this at least will force Click to recover somehow.
220
+ return is_ascii_encoding(getattr(stream, "encoding", None) or "ascii")
221
+
222
+
223
+ def _is_compat_stream_attr(stream: t.TextIO, attr: str, value: t.Optional[str]) -> bool:
224
+ """A stream attribute is compatible if it is equal to the
225
+ desired value or the desired value is unset and the attribute
226
+ has a value.
227
+ """
228
+ stream_value = getattr(stream, attr, None)
229
+ return stream_value == value or (value is None and stream_value is not None)
230
+
231
+
232
+ def _is_compatible_text_stream(
233
+ stream: t.TextIO, encoding: t.Optional[str], errors: t.Optional[str]
234
+ ) -> bool:
235
+ """Check if a stream's encoding and errors attributes are
236
+ compatible with the desired values.
237
+ """
238
+ return _is_compat_stream_attr(
239
+ stream, "encoding", encoding
240
+ ) and _is_compat_stream_attr(stream, "errors", errors)
241
+
242
+
243
+ def _force_correct_text_stream(
244
+ text_stream: t.IO,
245
+ encoding: t.Optional[str],
246
+ errors: t.Optional[str],
247
+ is_binary: t.Callable[[t.IO, bool], bool],
248
+ find_binary: t.Callable[[t.IO], t.Optional[t.BinaryIO]],
249
+ force_readable: bool = False,
250
+ force_writable: bool = False,
251
+ ) -> t.TextIO:
252
+ if is_binary(text_stream, False):
253
+ binary_reader = t.cast(t.BinaryIO, text_stream)
254
+ else:
255
+ text_stream = t.cast(t.TextIO, text_stream)
256
+ # If the stream looks compatible, and won't default to a
257
+ # misconfigured ascii encoding, return it as-is.
258
+ if _is_compatible_text_stream(text_stream, encoding, errors) and not (
259
+ encoding is None and _stream_is_misconfigured(text_stream)
260
+ ):
261
+ return text_stream
262
+
263
+ # Otherwise, get the underlying binary reader.
264
+ possible_binary_reader = find_binary(text_stream)
265
+
266
+ # If that's not possible, silently use the original reader
267
+ # and get mojibake instead of exceptions.
268
+ if possible_binary_reader is None:
269
+ return text_stream
270
+
271
+ binary_reader = possible_binary_reader
272
+
273
+ # Default errors to replace instead of strict in order to get
274
+ # something that works.
275
+ if errors is None:
276
+ errors = "replace"
277
+
278
+ # Wrap the binary stream in a text stream with the correct
279
+ # encoding parameters.
280
+ return _make_text_stream(
281
+ binary_reader,
282
+ encoding,
283
+ errors,
284
+ force_readable=force_readable,
285
+ force_writable=force_writable,
286
+ )
287
+
288
+
289
+ def _force_correct_text_reader(
290
+ text_reader: t.IO,
291
+ encoding: t.Optional[str],
292
+ errors: t.Optional[str],
293
+ force_readable: bool = False,
294
+ ) -> t.TextIO:
295
+ return _force_correct_text_stream(
296
+ text_reader,
297
+ encoding,
298
+ errors,
299
+ _is_binary_reader,
300
+ _find_binary_reader,
301
+ force_readable=force_readable,
302
+ )
303
+
304
+
305
+ def _force_correct_text_writer(
306
+ text_writer: t.IO,
307
+ encoding: t.Optional[str],
308
+ errors: t.Optional[str],
309
+ force_writable: bool = False,
310
+ ) -> t.TextIO:
311
+ return _force_correct_text_stream(
312
+ text_writer,
313
+ encoding,
314
+ errors,
315
+ _is_binary_writer,
316
+ _find_binary_writer,
317
+ force_writable=force_writable,
318
+ )
319
+
320
+
321
+ def get_binary_stdin() -> t.BinaryIO:
322
+ reader = _find_binary_reader(sys.stdin)
323
+ if reader is None:
324
+ raise RuntimeError("Was not able to determine binary stream for sys.stdin.")
325
+ return reader
326
+
327
+
328
+ def get_binary_stdout() -> t.BinaryIO:
329
+ writer = _find_binary_writer(sys.stdout)
330
+ if writer is None:
331
+ raise RuntimeError("Was not able to determine binary stream for sys.stdout.")
332
+ return writer
333
+
334
+
335
+ def get_binary_stderr() -> t.BinaryIO:
336
+ writer = _find_binary_writer(sys.stderr)
337
+ if writer is None:
338
+ raise RuntimeError("Was not able to determine binary stream for sys.stderr.")
339
+ return writer
340
+
341
+
342
+ def get_text_stdin(
343
+ encoding: t.Optional[str] = None, errors: t.Optional[str] = None
344
+ ) -> t.TextIO:
345
+ rv = _get_windows_console_stream(sys.stdin, encoding, errors)
346
+ if rv is not None:
347
+ return rv
348
+ return _force_correct_text_reader(sys.stdin, encoding, errors, force_readable=True)
349
+
350
+
351
+ def get_text_stdout(
352
+ encoding: t.Optional[str] = None, errors: t.Optional[str] = None
353
+ ) -> t.TextIO:
354
+ rv = _get_windows_console_stream(sys.stdout, encoding, errors)
355
+ if rv is not None:
356
+ return rv
357
+ return _force_correct_text_writer(sys.stdout, encoding, errors, force_writable=True)
358
+
359
+
360
+ def get_text_stderr(
361
+ encoding: t.Optional[str] = None, errors: t.Optional[str] = None
362
+ ) -> t.TextIO:
363
+ rv = _get_windows_console_stream(sys.stderr, encoding, errors)
364
+ if rv is not None:
365
+ return rv
366
+ return _force_correct_text_writer(sys.stderr, encoding, errors, force_writable=True)
367
+
368
+
369
+ def _wrap_io_open(
370
+ file: t.Union[str, os.PathLike, int],
371
+ mode: str,
372
+ encoding: t.Optional[str],
373
+ errors: t.Optional[str],
374
+ ) -> t.IO:
375
+ """Handles not passing ``encoding`` and ``errors`` in binary mode."""
376
+ if "b" in mode:
377
+ return open(file, mode)
378
+
379
+ return open(file, mode, encoding=encoding, errors=errors)
380
+
381
+
382
+ def open_stream(
383
+ filename: str,
384
+ mode: str = "r",
385
+ encoding: t.Optional[str] = None,
386
+ errors: t.Optional[str] = "strict",
387
+ atomic: bool = False,
388
+ ) -> t.Tuple[t.IO, bool]:
389
+ binary = "b" in mode
390
+
391
+ # Standard streams first. These are simple because they ignore the
392
+ # atomic flag. Use fsdecode to handle Path("-").
393
+ if os.fsdecode(filename) == "-":
394
+ if any(m in mode for m in ["w", "a", "x"]):
395
+ if binary:
396
+ return get_binary_stdout(), False
397
+ return get_text_stdout(encoding=encoding, errors=errors), False
398
+ if binary:
399
+ return get_binary_stdin(), False
400
+ return get_text_stdin(encoding=encoding, errors=errors), False
401
+
402
+ # Non-atomic writes directly go out through the regular open functions.
403
+ if not atomic:
404
+ return _wrap_io_open(filename, mode, encoding, errors), True
405
+
406
+ # Some usability stuff for atomic writes
407
+ if "a" in mode:
408
+ raise ValueError(
409
+ "Appending to an existing file is not supported, because that"
410
+ " would involve an expensive `copy`-operation to a temporary"
411
+ " file. Open the file in normal `w`-mode and copy explicitly"
412
+ " if that's what you're after."
413
+ )
414
+ if "x" in mode:
415
+ raise ValueError("Use the `overwrite`-parameter instead.")
416
+ if "w" not in mode:
417
+ raise ValueError("Atomic writes only make sense with `w`-mode.")
418
+
419
+ # Atomic writes are more complicated. They work by opening a file
420
+ # as a proxy in the same folder and then using the fdopen
421
+ # functionality to wrap it in a Python file. Then we wrap it in an
422
+ # atomic file that moves the file over on close.
423
+ import errno
424
+ import random
425
+
426
+ try:
427
+ perm: t.Optional[int] = os.stat(filename).st_mode
428
+ except OSError:
429
+ perm = None
430
+
431
+ flags = os.O_RDWR | os.O_CREAT | os.O_EXCL
432
+
433
+ if binary:
434
+ flags |= getattr(os, "O_BINARY", 0)
435
+
436
+ while True:
437
+ tmp_filename = os.path.join(
438
+ os.path.dirname(filename),
439
+ f".__atomic-write{random.randrange(1 << 32):08x}",
440
+ )
441
+ try:
442
+ fd = os.open(tmp_filename, flags, 0o666 if perm is None else perm)
443
+ break
444
+ except OSError as e:
445
+ if e.errno == errno.EEXIST or (
446
+ os.name == "nt"
447
+ and e.errno == errno.EACCES
448
+ and os.path.isdir(e.filename)
449
+ and os.access(e.filename, os.W_OK)
450
+ ):
451
+ continue
452
+ raise
453
+
454
+ if perm is not None:
455
+ os.chmod(tmp_filename, perm) # in case perm includes bits in umask
456
+
457
+ f = _wrap_io_open(fd, mode, encoding, errors)
458
+ af = _AtomicFile(f, tmp_filename, os.path.realpath(filename))
459
+ return t.cast(t.IO, af), True
460
+
461
+
462
+ class _AtomicFile:
463
+ def __init__(self, f: t.IO, tmp_filename: str, real_filename: str) -> None:
464
+ self._f = f
465
+ self._tmp_filename = tmp_filename
466
+ self._real_filename = real_filename
467
+ self.closed = False
468
+
469
+ @property
470
+ def name(self) -> str:
471
+ return self._real_filename
472
+
473
+ def close(self, delete: bool = False) -> None:
474
+ if self.closed:
475
+ return
476
+ self._f.close()
477
+ os.replace(self._tmp_filename, self._real_filename)
478
+ self.closed = True
479
+
480
+ def __getattr__(self, name: str) -> t.Any:
481
+ return getattr(self._f, name)
482
+
483
+ def __enter__(self) -> "_AtomicFile":
484
+ return self
485
+
486
+ def __exit__(self, exc_type, exc_value, tb): # type: ignore
487
+ self.close(delete=exc_type is not None)
488
+
489
+ def __repr__(self) -> str:
490
+ return repr(self._f)
491
+
492
+
493
+ def strip_ansi(value: str) -> str:
494
+ return _ansi_re.sub("", value)
495
+
496
+
497
+ def _is_jupyter_kernel_output(stream: t.IO) -> bool:
498
+ while isinstance(stream, (_FixupStream, _NonClosingTextIOWrapper)):
499
+ stream = stream._stream
500
+
501
+ return stream.__class__.__module__.startswith("ipykernel.")
502
+
503
+
504
+ def should_strip_ansi(
505
+ stream: t.Optional[t.IO] = None, color: t.Optional[bool] = None
506
+ ) -> bool:
507
+ if color is None:
508
+ if stream is None:
509
+ stream = sys.stdin
510
+ return not isatty(stream) and not _is_jupyter_kernel_output(stream)
511
+ return not color
512
+
513
+
514
+ # On Windows, wrap the output streams with colorama to support ANSI
515
+ # color codes.
516
+ # NOTE: double check is needed so mypy does not analyze this on Linux
517
+ if sys.platform.startswith("win") and WIN:
518
+ from ._winconsole import _get_windows_console_stream
519
+
520
+ def _get_argv_encoding() -> str:
521
+ import locale
522
+
523
+ return locale.getpreferredencoding()
524
+
525
+ _ansi_stream_wrappers: t.MutableMapping[t.TextIO, t.TextIO] = WeakKeyDictionary()
526
+
527
+ def auto_wrap_for_ansi(
528
+ stream: t.TextIO, color: t.Optional[bool] = None
529
+ ) -> t.TextIO:
530
+ """Support ANSI color and style codes on Windows by wrapping a
531
+ stream with colorama.
532
+ """
533
+ try:
534
+ cached = _ansi_stream_wrappers.get(stream)
535
+ except Exception:
536
+ cached = None
537
+
538
+ if cached is not None:
539
+ return cached
540
+
541
+ import colorama
542
+
543
+ strip = should_strip_ansi(stream, color)
544
+ ansi_wrapper = colorama.AnsiToWin32(stream, strip=strip)
545
+ rv = t.cast(t.TextIO, ansi_wrapper.stream)
546
+ _write = rv.write
547
+
548
+ def _safe_write(s):
549
+ try:
550
+ return _write(s)
551
+ except BaseException:
552
+ ansi_wrapper.reset_all()
553
+ raise
554
+
555
+ rv.write = _safe_write
556
+
557
+ try:
558
+ _ansi_stream_wrappers[stream] = rv
559
+ except Exception:
560
+ pass
561
+
562
+ return rv
563
+
564
+ else:
565
+
566
+ def _get_argv_encoding() -> str:
567
+ return getattr(sys.stdin, "encoding", None) or get_filesystem_encoding()
568
+
569
+ def _get_windows_console_stream(
570
+ f: t.TextIO, encoding: t.Optional[str], errors: t.Optional[str]
571
+ ) -> t.Optional[t.TextIO]:
572
+ return None
573
+
574
+
575
+ def term_len(x: str) -> int:
576
+ return len(strip_ansi(x))
577
+
578
+
579
+ def isatty(stream: t.IO) -> bool:
580
+ try:
581
+ return stream.isatty()
582
+ except Exception:
583
+ return False
584
+
585
+
586
+ def _make_cached_stream_func(
587
+ src_func: t.Callable[[], t.TextIO], wrapper_func: t.Callable[[], t.TextIO]
588
+ ) -> t.Callable[[], t.TextIO]:
589
+ cache: t.MutableMapping[t.TextIO, t.TextIO] = WeakKeyDictionary()
590
+
591
+ def func() -> t.TextIO:
592
+ stream = src_func()
593
+ try:
594
+ rv = cache.get(stream)
595
+ except Exception:
596
+ rv = None
597
+ if rv is not None:
598
+ return rv
599
+ rv = wrapper_func()
600
+ try:
601
+ cache[stream] = rv
602
+ except Exception:
603
+ pass
604
+ return rv
605
+
606
+ return func
607
+
608
+
609
+ _default_text_stdin = _make_cached_stream_func(lambda: sys.stdin, get_text_stdin)
610
+ _default_text_stdout = _make_cached_stream_func(lambda: sys.stdout, get_text_stdout)
611
+ _default_text_stderr = _make_cached_stream_func(lambda: sys.stderr, get_text_stderr)
612
+
613
+
614
+ binary_streams: t.Mapping[str, t.Callable[[], t.BinaryIO]] = {
615
+ "stdin": get_binary_stdin,
616
+ "stdout": get_binary_stdout,
617
+ "stderr": get_binary_stderr,
618
+ }
619
+
620
+ text_streams: t.Mapping[
621
+ str, t.Callable[[t.Optional[str], t.Optional[str]], t.TextIO]
622
+ ] = {
623
+ "stdin": get_text_stdin,
624
+ "stdout": get_text_stdout,
625
+ "stderr": get_text_stderr,
626
+ }
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/click/_textwrap.py ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import textwrap
2
+ import typing as t
3
+ from contextlib import contextmanager
4
+
5
+
6
+ class TextWrapper(textwrap.TextWrapper):
7
+ def _handle_long_word(
8
+ self,
9
+ reversed_chunks: t.List[str],
10
+ cur_line: t.List[str],
11
+ cur_len: int,
12
+ width: int,
13
+ ) -> None:
14
+ space_left = max(width - cur_len, 1)
15
+
16
+ if self.break_long_words:
17
+ last = reversed_chunks[-1]
18
+ cut = last[:space_left]
19
+ res = last[space_left:]
20
+ cur_line.append(cut)
21
+ reversed_chunks[-1] = res
22
+ elif not cur_line:
23
+ cur_line.append(reversed_chunks.pop())
24
+
25
+ @contextmanager
26
+ def extra_indent(self, indent: str) -> t.Iterator[None]:
27
+ old_initial_indent = self.initial_indent
28
+ old_subsequent_indent = self.subsequent_indent
29
+ self.initial_indent += indent
30
+ self.subsequent_indent += indent
31
+
32
+ try:
33
+ yield
34
+ finally:
35
+ self.initial_indent = old_initial_indent
36
+ self.subsequent_indent = old_subsequent_indent
37
+
38
+ def indent_only(self, text: str) -> str:
39
+ rv = []
40
+
41
+ for idx, line in enumerate(text.splitlines()):
42
+ indent = self.initial_indent
43
+
44
+ if idx > 0:
45
+ indent = self.subsequent_indent
46
+
47
+ rv.append(f"{indent}{line}")
48
+
49
+ return "\n".join(rv)
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/click/_winconsole.py ADDED
@@ -0,0 +1,279 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # This module is based on the excellent work by Adam Bartoš who
2
+ # provided a lot of what went into the implementation here in
3
+ # the discussion to issue1602 in the Python bug tracker.
4
+ #
5
+ # There are some general differences in regards to how this works
6
+ # compared to the original patches as we do not need to patch
7
+ # the entire interpreter but just work in our little world of
8
+ # echo and prompt.
9
+ import io
10
+ import sys
11
+ import time
12
+ import typing as t
13
+ from ctypes import byref
14
+ from ctypes import c_char
15
+ from ctypes import c_char_p
16
+ from ctypes import c_int
17
+ from ctypes import c_ssize_t
18
+ from ctypes import c_ulong
19
+ from ctypes import c_void_p
20
+ from ctypes import POINTER
21
+ from ctypes import py_object
22
+ from ctypes import Structure
23
+ from ctypes.wintypes import DWORD
24
+ from ctypes.wintypes import HANDLE
25
+ from ctypes.wintypes import LPCWSTR
26
+ from ctypes.wintypes import LPWSTR
27
+
28
+ from ._compat import _NonClosingTextIOWrapper
29
+
30
+ assert sys.platform == "win32"
31
+ import msvcrt # noqa: E402
32
+ from ctypes import windll # noqa: E402
33
+ from ctypes import WINFUNCTYPE # noqa: E402
34
+
35
+ c_ssize_p = POINTER(c_ssize_t)
36
+
37
+ kernel32 = windll.kernel32
38
+ GetStdHandle = kernel32.GetStdHandle
39
+ ReadConsoleW = kernel32.ReadConsoleW
40
+ WriteConsoleW = kernel32.WriteConsoleW
41
+ GetConsoleMode = kernel32.GetConsoleMode
42
+ GetLastError = kernel32.GetLastError
43
+ GetCommandLineW = WINFUNCTYPE(LPWSTR)(("GetCommandLineW", windll.kernel32))
44
+ CommandLineToArgvW = WINFUNCTYPE(POINTER(LPWSTR), LPCWSTR, POINTER(c_int))(
45
+ ("CommandLineToArgvW", windll.shell32)
46
+ )
47
+ LocalFree = WINFUNCTYPE(c_void_p, c_void_p)(("LocalFree", windll.kernel32))
48
+
49
+ STDIN_HANDLE = GetStdHandle(-10)
50
+ STDOUT_HANDLE = GetStdHandle(-11)
51
+ STDERR_HANDLE = GetStdHandle(-12)
52
+
53
+ PyBUF_SIMPLE = 0
54
+ PyBUF_WRITABLE = 1
55
+
56
+ ERROR_SUCCESS = 0
57
+ ERROR_NOT_ENOUGH_MEMORY = 8
58
+ ERROR_OPERATION_ABORTED = 995
59
+
60
+ STDIN_FILENO = 0
61
+ STDOUT_FILENO = 1
62
+ STDERR_FILENO = 2
63
+
64
+ EOF = b"\x1a"
65
+ MAX_BYTES_WRITTEN = 32767
66
+
67
+ try:
68
+ from ctypes import pythonapi
69
+ except ImportError:
70
+ # On PyPy we cannot get buffers so our ability to operate here is
71
+ # severely limited.
72
+ get_buffer = None
73
+ else:
74
+
75
+ class Py_buffer(Structure):
76
+ _fields_ = [
77
+ ("buf", c_void_p),
78
+ ("obj", py_object),
79
+ ("len", c_ssize_t),
80
+ ("itemsize", c_ssize_t),
81
+ ("readonly", c_int),
82
+ ("ndim", c_int),
83
+ ("format", c_char_p),
84
+ ("shape", c_ssize_p),
85
+ ("strides", c_ssize_p),
86
+ ("suboffsets", c_ssize_p),
87
+ ("internal", c_void_p),
88
+ ]
89
+
90
+ PyObject_GetBuffer = pythonapi.PyObject_GetBuffer
91
+ PyBuffer_Release = pythonapi.PyBuffer_Release
92
+
93
+ def get_buffer(obj, writable=False):
94
+ buf = Py_buffer()
95
+ flags = PyBUF_WRITABLE if writable else PyBUF_SIMPLE
96
+ PyObject_GetBuffer(py_object(obj), byref(buf), flags)
97
+
98
+ try:
99
+ buffer_type = c_char * buf.len
100
+ return buffer_type.from_address(buf.buf)
101
+ finally:
102
+ PyBuffer_Release(byref(buf))
103
+
104
+
105
+ class _WindowsConsoleRawIOBase(io.RawIOBase):
106
+ def __init__(self, handle):
107
+ self.handle = handle
108
+
109
+ def isatty(self):
110
+ super().isatty()
111
+ return True
112
+
113
+
114
+ class _WindowsConsoleReader(_WindowsConsoleRawIOBase):
115
+ def readable(self):
116
+ return True
117
+
118
+ def readinto(self, b):
119
+ bytes_to_be_read = len(b)
120
+ if not bytes_to_be_read:
121
+ return 0
122
+ elif bytes_to_be_read % 2:
123
+ raise ValueError(
124
+ "cannot read odd number of bytes from UTF-16-LE encoded console"
125
+ )
126
+
127
+ buffer = get_buffer(b, writable=True)
128
+ code_units_to_be_read = bytes_to_be_read // 2
129
+ code_units_read = c_ulong()
130
+
131
+ rv = ReadConsoleW(
132
+ HANDLE(self.handle),
133
+ buffer,
134
+ code_units_to_be_read,
135
+ byref(code_units_read),
136
+ None,
137
+ )
138
+ if GetLastError() == ERROR_OPERATION_ABORTED:
139
+ # wait for KeyboardInterrupt
140
+ time.sleep(0.1)
141
+ if not rv:
142
+ raise OSError(f"Windows error: {GetLastError()}")
143
+
144
+ if buffer[0] == EOF:
145
+ return 0
146
+ return 2 * code_units_read.value
147
+
148
+
149
+ class _WindowsConsoleWriter(_WindowsConsoleRawIOBase):
150
+ def writable(self):
151
+ return True
152
+
153
+ @staticmethod
154
+ def _get_error_message(errno):
155
+ if errno == ERROR_SUCCESS:
156
+ return "ERROR_SUCCESS"
157
+ elif errno == ERROR_NOT_ENOUGH_MEMORY:
158
+ return "ERROR_NOT_ENOUGH_MEMORY"
159
+ return f"Windows error {errno}"
160
+
161
+ def write(self, b):
162
+ bytes_to_be_written = len(b)
163
+ buf = get_buffer(b)
164
+ code_units_to_be_written = min(bytes_to_be_written, MAX_BYTES_WRITTEN) // 2
165
+ code_units_written = c_ulong()
166
+
167
+ WriteConsoleW(
168
+ HANDLE(self.handle),
169
+ buf,
170
+ code_units_to_be_written,
171
+ byref(code_units_written),
172
+ None,
173
+ )
174
+ bytes_written = 2 * code_units_written.value
175
+
176
+ if bytes_written == 0 and bytes_to_be_written > 0:
177
+ raise OSError(self._get_error_message(GetLastError()))
178
+ return bytes_written
179
+
180
+
181
+ class ConsoleStream:
182
+ def __init__(self, text_stream: t.TextIO, byte_stream: t.BinaryIO) -> None:
183
+ self._text_stream = text_stream
184
+ self.buffer = byte_stream
185
+
186
+ @property
187
+ def name(self) -> str:
188
+ return self.buffer.name
189
+
190
+ def write(self, x: t.AnyStr) -> int:
191
+ if isinstance(x, str):
192
+ return self._text_stream.write(x)
193
+ try:
194
+ self.flush()
195
+ except Exception:
196
+ pass
197
+ return self.buffer.write(x)
198
+
199
+ def writelines(self, lines: t.Iterable[t.AnyStr]) -> None:
200
+ for line in lines:
201
+ self.write(line)
202
+
203
+ def __getattr__(self, name: str) -> t.Any:
204
+ return getattr(self._text_stream, name)
205
+
206
+ def isatty(self) -> bool:
207
+ return self.buffer.isatty()
208
+
209
+ def __repr__(self):
210
+ return f"<ConsoleStream name={self.name!r} encoding={self.encoding!r}>"
211
+
212
+
213
+ def _get_text_stdin(buffer_stream: t.BinaryIO) -> t.TextIO:
214
+ text_stream = _NonClosingTextIOWrapper(
215
+ io.BufferedReader(_WindowsConsoleReader(STDIN_HANDLE)),
216
+ "utf-16-le",
217
+ "strict",
218
+ line_buffering=True,
219
+ )
220
+ return t.cast(t.TextIO, ConsoleStream(text_stream, buffer_stream))
221
+
222
+
223
+ def _get_text_stdout(buffer_stream: t.BinaryIO) -> t.TextIO:
224
+ text_stream = _NonClosingTextIOWrapper(
225
+ io.BufferedWriter(_WindowsConsoleWriter(STDOUT_HANDLE)),
226
+ "utf-16-le",
227
+ "strict",
228
+ line_buffering=True,
229
+ )
230
+ return t.cast(t.TextIO, ConsoleStream(text_stream, buffer_stream))
231
+
232
+
233
+ def _get_text_stderr(buffer_stream: t.BinaryIO) -> t.TextIO:
234
+ text_stream = _NonClosingTextIOWrapper(
235
+ io.BufferedWriter(_WindowsConsoleWriter(STDERR_HANDLE)),
236
+ "utf-16-le",
237
+ "strict",
238
+ line_buffering=True,
239
+ )
240
+ return t.cast(t.TextIO, ConsoleStream(text_stream, buffer_stream))
241
+
242
+
243
+ _stream_factories: t.Mapping[int, t.Callable[[t.BinaryIO], t.TextIO]] = {
244
+ 0: _get_text_stdin,
245
+ 1: _get_text_stdout,
246
+ 2: _get_text_stderr,
247
+ }
248
+
249
+
250
+ def _is_console(f: t.TextIO) -> bool:
251
+ if not hasattr(f, "fileno"):
252
+ return False
253
+
254
+ try:
255
+ fileno = f.fileno()
256
+ except (OSError, io.UnsupportedOperation):
257
+ return False
258
+
259
+ handle = msvcrt.get_osfhandle(fileno)
260
+ return bool(GetConsoleMode(handle, byref(DWORD())))
261
+
262
+
263
+ def _get_windows_console_stream(
264
+ f: t.TextIO, encoding: t.Optional[str], errors: t.Optional[str]
265
+ ) -> t.Optional[t.TextIO]:
266
+ if (
267
+ get_buffer is not None
268
+ and encoding in {"utf-16-le", None}
269
+ and errors in {"strict", None}
270
+ and _is_console(f)
271
+ ):
272
+ func = _stream_factories.get(f.fileno())
273
+ if func is not None:
274
+ b = getattr(f, "buffer", None)
275
+
276
+ if b is None:
277
+ return None
278
+
279
+ return func(b)
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/click/core.py ADDED
The diff for this file is too large to render. See raw diff
 
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/click/decorators.py ADDED
@@ -0,0 +1,497 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import inspect
2
+ import types
3
+ import typing as t
4
+ from functools import update_wrapper
5
+ from gettext import gettext as _
6
+
7
+ from .core import Argument
8
+ from .core import Command
9
+ from .core import Context
10
+ from .core import Group
11
+ from .core import Option
12
+ from .core import Parameter
13
+ from .globals import get_current_context
14
+ from .utils import echo
15
+
16
+ F = t.TypeVar("F", bound=t.Callable[..., t.Any])
17
+ FC = t.TypeVar("FC", bound=t.Union[t.Callable[..., t.Any], Command])
18
+
19
+
20
+ def pass_context(f: F) -> F:
21
+ """Marks a callback as wanting to receive the current context
22
+ object as first argument.
23
+ """
24
+
25
+ def new_func(*args, **kwargs): # type: ignore
26
+ return f(get_current_context(), *args, **kwargs)
27
+
28
+ return update_wrapper(t.cast(F, new_func), f)
29
+
30
+
31
+ def pass_obj(f: F) -> F:
32
+ """Similar to :func:`pass_context`, but only pass the object on the
33
+ context onwards (:attr:`Context.obj`). This is useful if that object
34
+ represents the state of a nested system.
35
+ """
36
+
37
+ def new_func(*args, **kwargs): # type: ignore
38
+ return f(get_current_context().obj, *args, **kwargs)
39
+
40
+ return update_wrapper(t.cast(F, new_func), f)
41
+
42
+
43
+ def make_pass_decorator(
44
+ object_type: t.Type, ensure: bool = False
45
+ ) -> "t.Callable[[F], F]":
46
+ """Given an object type this creates a decorator that will work
47
+ similar to :func:`pass_obj` but instead of passing the object of the
48
+ current context, it will find the innermost context of type
49
+ :func:`object_type`.
50
+
51
+ This generates a decorator that works roughly like this::
52
+
53
+ from functools import update_wrapper
54
+
55
+ def decorator(f):
56
+ @pass_context
57
+ def new_func(ctx, *args, **kwargs):
58
+ obj = ctx.find_object(object_type)
59
+ return ctx.invoke(f, obj, *args, **kwargs)
60
+ return update_wrapper(new_func, f)
61
+ return decorator
62
+
63
+ :param object_type: the type of the object to pass.
64
+ :param ensure: if set to `True`, a new object will be created and
65
+ remembered on the context if it's not there yet.
66
+ """
67
+
68
+ def decorator(f: F) -> F:
69
+ def new_func(*args, **kwargs): # type: ignore
70
+ ctx = get_current_context()
71
+
72
+ if ensure:
73
+ obj = ctx.ensure_object(object_type)
74
+ else:
75
+ obj = ctx.find_object(object_type)
76
+
77
+ if obj is None:
78
+ raise RuntimeError(
79
+ "Managed to invoke callback without a context"
80
+ f" object of type {object_type.__name__!r}"
81
+ " existing."
82
+ )
83
+
84
+ return ctx.invoke(f, obj, *args, **kwargs)
85
+
86
+ return update_wrapper(t.cast(F, new_func), f)
87
+
88
+ return decorator
89
+
90
+
91
+ def pass_meta_key(
92
+ key: str, *, doc_description: t.Optional[str] = None
93
+ ) -> "t.Callable[[F], F]":
94
+ """Create a decorator that passes a key from
95
+ :attr:`click.Context.meta` as the first argument to the decorated
96
+ function.
97
+
98
+ :param key: Key in ``Context.meta`` to pass.
99
+ :param doc_description: Description of the object being passed,
100
+ inserted into the decorator's docstring. Defaults to "the 'key'
101
+ key from Context.meta".
102
+
103
+ .. versionadded:: 8.0
104
+ """
105
+
106
+ def decorator(f: F) -> F:
107
+ def new_func(*args, **kwargs): # type: ignore
108
+ ctx = get_current_context()
109
+ obj = ctx.meta[key]
110
+ return ctx.invoke(f, obj, *args, **kwargs)
111
+
112
+ return update_wrapper(t.cast(F, new_func), f)
113
+
114
+ if doc_description is None:
115
+ doc_description = f"the {key!r} key from :attr:`click.Context.meta`"
116
+
117
+ decorator.__doc__ = (
118
+ f"Decorator that passes {doc_description} as the first argument"
119
+ " to the decorated function."
120
+ )
121
+ return decorator
122
+
123
+
124
+ CmdType = t.TypeVar("CmdType", bound=Command)
125
+
126
+
127
+ @t.overload
128
+ def command(
129
+ __func: t.Callable[..., t.Any],
130
+ ) -> Command:
131
+ ...
132
+
133
+
134
+ @t.overload
135
+ def command(
136
+ name: t.Optional[str] = None,
137
+ **attrs: t.Any,
138
+ ) -> t.Callable[..., Command]:
139
+ ...
140
+
141
+
142
+ @t.overload
143
+ def command(
144
+ name: t.Optional[str] = None,
145
+ cls: t.Type[CmdType] = ...,
146
+ **attrs: t.Any,
147
+ ) -> t.Callable[..., CmdType]:
148
+ ...
149
+
150
+
151
+ def command(
152
+ name: t.Union[str, t.Callable[..., t.Any], None] = None,
153
+ cls: t.Optional[t.Type[Command]] = None,
154
+ **attrs: t.Any,
155
+ ) -> t.Union[Command, t.Callable[..., Command]]:
156
+ r"""Creates a new :class:`Command` and uses the decorated function as
157
+ callback. This will also automatically attach all decorated
158
+ :func:`option`\s and :func:`argument`\s as parameters to the command.
159
+
160
+ The name of the command defaults to the name of the function with
161
+ underscores replaced by dashes. If you want to change that, you can
162
+ pass the intended name as the first argument.
163
+
164
+ All keyword arguments are forwarded to the underlying command class.
165
+ For the ``params`` argument, any decorated params are appended to
166
+ the end of the list.
167
+
168
+ Once decorated the function turns into a :class:`Command` instance
169
+ that can be invoked as a command line utility or be attached to a
170
+ command :class:`Group`.
171
+
172
+ :param name: the name of the command. This defaults to the function
173
+ name with underscores replaced by dashes.
174
+ :param cls: the command class to instantiate. This defaults to
175
+ :class:`Command`.
176
+
177
+ .. versionchanged:: 8.1
178
+ This decorator can be applied without parentheses.
179
+
180
+ .. versionchanged:: 8.1
181
+ The ``params`` argument can be used. Decorated params are
182
+ appended to the end of the list.
183
+ """
184
+
185
+ func: t.Optional[t.Callable[..., t.Any]] = None
186
+
187
+ if callable(name):
188
+ func = name
189
+ name = None
190
+ assert cls is None, "Use 'command(cls=cls)(callable)' to specify a class."
191
+ assert not attrs, "Use 'command(**kwargs)(callable)' to provide arguments."
192
+
193
+ if cls is None:
194
+ cls = Command
195
+
196
+ def decorator(f: t.Callable[..., t.Any]) -> Command:
197
+ if isinstance(f, Command):
198
+ raise TypeError("Attempted to convert a callback into a command twice.")
199
+
200
+ attr_params = attrs.pop("params", None)
201
+ params = attr_params if attr_params is not None else []
202
+
203
+ try:
204
+ decorator_params = f.__click_params__ # type: ignore
205
+ except AttributeError:
206
+ pass
207
+ else:
208
+ del f.__click_params__ # type: ignore
209
+ params.extend(reversed(decorator_params))
210
+
211
+ if attrs.get("help") is None:
212
+ attrs["help"] = f.__doc__
213
+
214
+ cmd = cls( # type: ignore[misc]
215
+ name=name or f.__name__.lower().replace("_", "-"), # type: ignore[arg-type]
216
+ callback=f,
217
+ params=params,
218
+ **attrs,
219
+ )
220
+ cmd.__doc__ = f.__doc__
221
+ return cmd
222
+
223
+ if func is not None:
224
+ return decorator(func)
225
+
226
+ return decorator
227
+
228
+
229
+ @t.overload
230
+ def group(
231
+ __func: t.Callable[..., t.Any],
232
+ ) -> Group:
233
+ ...
234
+
235
+
236
+ @t.overload
237
+ def group(
238
+ name: t.Optional[str] = None,
239
+ **attrs: t.Any,
240
+ ) -> t.Callable[[F], Group]:
241
+ ...
242
+
243
+
244
+ def group(
245
+ name: t.Union[str, t.Callable[..., t.Any], None] = None, **attrs: t.Any
246
+ ) -> t.Union[Group, t.Callable[[F], Group]]:
247
+ """Creates a new :class:`Group` with a function as callback. This
248
+ works otherwise the same as :func:`command` just that the `cls`
249
+ parameter is set to :class:`Group`.
250
+
251
+ .. versionchanged:: 8.1
252
+ This decorator can be applied without parentheses.
253
+ """
254
+ if attrs.get("cls") is None:
255
+ attrs["cls"] = Group
256
+
257
+ if callable(name):
258
+ grp: t.Callable[[F], Group] = t.cast(Group, command(**attrs))
259
+ return grp(name)
260
+
261
+ return t.cast(Group, command(name, **attrs))
262
+
263
+
264
+ def _param_memo(f: FC, param: Parameter) -> None:
265
+ if isinstance(f, Command):
266
+ f.params.append(param)
267
+ else:
268
+ if not hasattr(f, "__click_params__"):
269
+ f.__click_params__ = [] # type: ignore
270
+
271
+ f.__click_params__.append(param) # type: ignore
272
+
273
+
274
+ def argument(*param_decls: str, **attrs: t.Any) -> t.Callable[[FC], FC]:
275
+ """Attaches an argument to the command. All positional arguments are
276
+ passed as parameter declarations to :class:`Argument`; all keyword
277
+ arguments are forwarded unchanged (except ``cls``).
278
+ This is equivalent to creating an :class:`Argument` instance manually
279
+ and attaching it to the :attr:`Command.params` list.
280
+
281
+ :param cls: the argument class to instantiate. This defaults to
282
+ :class:`Argument`.
283
+ """
284
+
285
+ def decorator(f: FC) -> FC:
286
+ ArgumentClass = attrs.pop("cls", None) or Argument
287
+ _param_memo(f, ArgumentClass(param_decls, **attrs))
288
+ return f
289
+
290
+ return decorator
291
+
292
+
293
+ def option(*param_decls: str, **attrs: t.Any) -> t.Callable[[FC], FC]:
294
+ """Attaches an option to the command. All positional arguments are
295
+ passed as parameter declarations to :class:`Option`; all keyword
296
+ arguments are forwarded unchanged (except ``cls``).
297
+ This is equivalent to creating an :class:`Option` instance manually
298
+ and attaching it to the :attr:`Command.params` list.
299
+
300
+ :param cls: the option class to instantiate. This defaults to
301
+ :class:`Option`.
302
+ """
303
+
304
+ def decorator(f: FC) -> FC:
305
+ # Issue 926, copy attrs, so pre-defined options can re-use the same cls=
306
+ option_attrs = attrs.copy()
307
+ OptionClass = option_attrs.pop("cls", None) or Option
308
+ _param_memo(f, OptionClass(param_decls, **option_attrs))
309
+ return f
310
+
311
+ return decorator
312
+
313
+
314
+ def confirmation_option(*param_decls: str, **kwargs: t.Any) -> t.Callable[[FC], FC]:
315
+ """Add a ``--yes`` option which shows a prompt before continuing if
316
+ not passed. If the prompt is declined, the program will exit.
317
+
318
+ :param param_decls: One or more option names. Defaults to the single
319
+ value ``"--yes"``.
320
+ :param kwargs: Extra arguments are passed to :func:`option`.
321
+ """
322
+
323
+ def callback(ctx: Context, param: Parameter, value: bool) -> None:
324
+ if not value:
325
+ ctx.abort()
326
+
327
+ if not param_decls:
328
+ param_decls = ("--yes",)
329
+
330
+ kwargs.setdefault("is_flag", True)
331
+ kwargs.setdefault("callback", callback)
332
+ kwargs.setdefault("expose_value", False)
333
+ kwargs.setdefault("prompt", "Do you want to continue?")
334
+ kwargs.setdefault("help", "Confirm the action without prompting.")
335
+ return option(*param_decls, **kwargs)
336
+
337
+
338
+ def password_option(*param_decls: str, **kwargs: t.Any) -> t.Callable[[FC], FC]:
339
+ """Add a ``--password`` option which prompts for a password, hiding
340
+ input and asking to enter the value again for confirmation.
341
+
342
+ :param param_decls: One or more option names. Defaults to the single
343
+ value ``"--password"``.
344
+ :param kwargs: Extra arguments are passed to :func:`option`.
345
+ """
346
+ if not param_decls:
347
+ param_decls = ("--password",)
348
+
349
+ kwargs.setdefault("prompt", True)
350
+ kwargs.setdefault("confirmation_prompt", True)
351
+ kwargs.setdefault("hide_input", True)
352
+ return option(*param_decls, **kwargs)
353
+
354
+
355
+ def version_option(
356
+ version: t.Optional[str] = None,
357
+ *param_decls: str,
358
+ package_name: t.Optional[str] = None,
359
+ prog_name: t.Optional[str] = None,
360
+ message: t.Optional[str] = None,
361
+ **kwargs: t.Any,
362
+ ) -> t.Callable[[FC], FC]:
363
+ """Add a ``--version`` option which immediately prints the version
364
+ number and exits the program.
365
+
366
+ If ``version`` is not provided, Click will try to detect it using
367
+ :func:`importlib.metadata.version` to get the version for the
368
+ ``package_name``. On Python < 3.8, the ``importlib_metadata``
369
+ backport must be installed.
370
+
371
+ If ``package_name`` is not provided, Click will try to detect it by
372
+ inspecting the stack frames. This will be used to detect the
373
+ version, so it must match the name of the installed package.
374
+
375
+ :param version: The version number to show. If not provided, Click
376
+ will try to detect it.
377
+ :param param_decls: One or more option names. Defaults to the single
378
+ value ``"--version"``.
379
+ :param package_name: The package name to detect the version from. If
380
+ not provided, Click will try to detect it.
381
+ :param prog_name: The name of the CLI to show in the message. If not
382
+ provided, it will be detected from the command.
383
+ :param message: The message to show. The values ``%(prog)s``,
384
+ ``%(package)s``, and ``%(version)s`` are available. Defaults to
385
+ ``"%(prog)s, version %(version)s"``.
386
+ :param kwargs: Extra arguments are passed to :func:`option`.
387
+ :raise RuntimeError: ``version`` could not be detected.
388
+
389
+ .. versionchanged:: 8.0
390
+ Add the ``package_name`` parameter, and the ``%(package)s``
391
+ value for messages.
392
+
393
+ .. versionchanged:: 8.0
394
+ Use :mod:`importlib.metadata` instead of ``pkg_resources``. The
395
+ version is detected based on the package name, not the entry
396
+ point name. The Python package name must match the installed
397
+ package name, or be passed with ``package_name=``.
398
+ """
399
+ if message is None:
400
+ message = _("%(prog)s, version %(version)s")
401
+
402
+ if version is None and package_name is None:
403
+ frame = inspect.currentframe()
404
+ f_back = frame.f_back if frame is not None else None
405
+ f_globals = f_back.f_globals if f_back is not None else None
406
+ # break reference cycle
407
+ # https://docs.python.org/3/library/inspect.html#the-interpreter-stack
408
+ del frame
409
+
410
+ if f_globals is not None:
411
+ package_name = f_globals.get("__name__")
412
+
413
+ if package_name == "__main__":
414
+ package_name = f_globals.get("__package__")
415
+
416
+ if package_name:
417
+ package_name = package_name.partition(".")[0]
418
+
419
+ def callback(ctx: Context, param: Parameter, value: bool) -> None:
420
+ if not value or ctx.resilient_parsing:
421
+ return
422
+
423
+ nonlocal prog_name
424
+ nonlocal version
425
+
426
+ if prog_name is None:
427
+ prog_name = ctx.find_root().info_name
428
+
429
+ if version is None and package_name is not None:
430
+ metadata: t.Optional[types.ModuleType]
431
+
432
+ try:
433
+ from importlib import metadata # type: ignore
434
+ except ImportError:
435
+ # Python < 3.8
436
+ import importlib_metadata as metadata # type: ignore
437
+
438
+ try:
439
+ version = metadata.version(package_name) # type: ignore
440
+ except metadata.PackageNotFoundError: # type: ignore
441
+ raise RuntimeError(
442
+ f"{package_name!r} is not installed. Try passing"
443
+ " 'package_name' instead."
444
+ ) from None
445
+
446
+ if version is None:
447
+ raise RuntimeError(
448
+ f"Could not determine the version for {package_name!r} automatically."
449
+ )
450
+
451
+ echo(
452
+ t.cast(str, message)
453
+ % {"prog": prog_name, "package": package_name, "version": version},
454
+ color=ctx.color,
455
+ )
456
+ ctx.exit()
457
+
458
+ if not param_decls:
459
+ param_decls = ("--version",)
460
+
461
+ kwargs.setdefault("is_flag", True)
462
+ kwargs.setdefault("expose_value", False)
463
+ kwargs.setdefault("is_eager", True)
464
+ kwargs.setdefault("help", _("Show the version and exit."))
465
+ kwargs["callback"] = callback
466
+ return option(*param_decls, **kwargs)
467
+
468
+
469
+ def help_option(*param_decls: str, **kwargs: t.Any) -> t.Callable[[FC], FC]:
470
+ """Add a ``--help`` option which immediately prints the help page
471
+ and exits the program.
472
+
473
+ This is usually unnecessary, as the ``--help`` option is added to
474
+ each command automatically unless ``add_help_option=False`` is
475
+ passed.
476
+
477
+ :param param_decls: One or more option names. Defaults to the single
478
+ value ``"--help"``.
479
+ :param kwargs: Extra arguments are passed to :func:`option`.
480
+ """
481
+
482
+ def callback(ctx: Context, param: Parameter, value: bool) -> None:
483
+ if not value or ctx.resilient_parsing:
484
+ return
485
+
486
+ echo(ctx.get_help(), color=ctx.color)
487
+ ctx.exit()
488
+
489
+ if not param_decls:
490
+ param_decls = ("--help",)
491
+
492
+ kwargs.setdefault("is_flag", True)
493
+ kwargs.setdefault("expose_value", False)
494
+ kwargs.setdefault("is_eager", True)
495
+ kwargs.setdefault("help", _("Show this message and exit."))
496
+ kwargs["callback"] = callback
497
+ return option(*param_decls, **kwargs)
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/click/exceptions.py ADDED
@@ -0,0 +1,287 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import typing as t
3
+ from gettext import gettext as _
4
+ from gettext import ngettext
5
+
6
+ from ._compat import get_text_stderr
7
+ from .utils import echo
8
+
9
+ if t.TYPE_CHECKING:
10
+ from .core import Context
11
+ from .core import Parameter
12
+
13
+
14
+ def _join_param_hints(
15
+ param_hint: t.Optional[t.Union[t.Sequence[str], str]]
16
+ ) -> t.Optional[str]:
17
+ if param_hint is not None and not isinstance(param_hint, str):
18
+ return " / ".join(repr(x) for x in param_hint)
19
+
20
+ return param_hint
21
+
22
+
23
+ class ClickException(Exception):
24
+ """An exception that Click can handle and show to the user."""
25
+
26
+ #: The exit code for this exception.
27
+ exit_code = 1
28
+
29
+ def __init__(self, message: str) -> None:
30
+ super().__init__(message)
31
+ self.message = message
32
+
33
+ def format_message(self) -> str:
34
+ return self.message
35
+
36
+ def __str__(self) -> str:
37
+ return self.message
38
+
39
+ def show(self, file: t.Optional[t.IO] = None) -> None:
40
+ if file is None:
41
+ file = get_text_stderr()
42
+
43
+ echo(_("Error: {message}").format(message=self.format_message()), file=file)
44
+
45
+
46
+ class UsageError(ClickException):
47
+ """An internal exception that signals a usage error. This typically
48
+ aborts any further handling.
49
+
50
+ :param message: the error message to display.
51
+ :param ctx: optionally the context that caused this error. Click will
52
+ fill in the context automatically in some situations.
53
+ """
54
+
55
+ exit_code = 2
56
+
57
+ def __init__(self, message: str, ctx: t.Optional["Context"] = None) -> None:
58
+ super().__init__(message)
59
+ self.ctx = ctx
60
+ self.cmd = self.ctx.command if self.ctx else None
61
+
62
+ def show(self, file: t.Optional[t.IO] = None) -> None:
63
+ if file is None:
64
+ file = get_text_stderr()
65
+ color = None
66
+ hint = ""
67
+ if (
68
+ self.ctx is not None
69
+ and self.ctx.command.get_help_option(self.ctx) is not None
70
+ ):
71
+ hint = _("Try '{command} {option}' for help.").format(
72
+ command=self.ctx.command_path, option=self.ctx.help_option_names[0]
73
+ )
74
+ hint = f"{hint}\n"
75
+ if self.ctx is not None:
76
+ color = self.ctx.color
77
+ echo(f"{self.ctx.get_usage()}\n{hint}", file=file, color=color)
78
+ echo(
79
+ _("Error: {message}").format(message=self.format_message()),
80
+ file=file,
81
+ color=color,
82
+ )
83
+
84
+
85
+ class BadParameter(UsageError):
86
+ """An exception that formats out a standardized error message for a
87
+ bad parameter. This is useful when thrown from a callback or type as
88
+ Click will attach contextual information to it (for instance, which
89
+ parameter it is).
90
+
91
+ .. versionadded:: 2.0
92
+
93
+ :param param: the parameter object that caused this error. This can
94
+ be left out, and Click will attach this info itself
95
+ if possible.
96
+ :param param_hint: a string that shows up as parameter name. This
97
+ can be used as alternative to `param` in cases
98
+ where custom validation should happen. If it is
99
+ a string it's used as such, if it's a list then
100
+ each item is quoted and separated.
101
+ """
102
+
103
+ def __init__(
104
+ self,
105
+ message: str,
106
+ ctx: t.Optional["Context"] = None,
107
+ param: t.Optional["Parameter"] = None,
108
+ param_hint: t.Optional[str] = None,
109
+ ) -> None:
110
+ super().__init__(message, ctx)
111
+ self.param = param
112
+ self.param_hint = param_hint
113
+
114
+ def format_message(self) -> str:
115
+ if self.param_hint is not None:
116
+ param_hint = self.param_hint
117
+ elif self.param is not None:
118
+ param_hint = self.param.get_error_hint(self.ctx) # type: ignore
119
+ else:
120
+ return _("Invalid value: {message}").format(message=self.message)
121
+
122
+ return _("Invalid value for {param_hint}: {message}").format(
123
+ param_hint=_join_param_hints(param_hint), message=self.message
124
+ )
125
+
126
+
127
+ class MissingParameter(BadParameter):
128
+ """Raised if click required an option or argument but it was not
129
+ provided when invoking the script.
130
+
131
+ .. versionadded:: 4.0
132
+
133
+ :param param_type: a string that indicates the type of the parameter.
134
+ The default is to inherit the parameter type from
135
+ the given `param`. Valid values are ``'parameter'``,
136
+ ``'option'`` or ``'argument'``.
137
+ """
138
+
139
+ def __init__(
140
+ self,
141
+ message: t.Optional[str] = None,
142
+ ctx: t.Optional["Context"] = None,
143
+ param: t.Optional["Parameter"] = None,
144
+ param_hint: t.Optional[str] = None,
145
+ param_type: t.Optional[str] = None,
146
+ ) -> None:
147
+ super().__init__(message or "", ctx, param, param_hint)
148
+ self.param_type = param_type
149
+
150
+ def format_message(self) -> str:
151
+ if self.param_hint is not None:
152
+ param_hint: t.Optional[str] = self.param_hint
153
+ elif self.param is not None:
154
+ param_hint = self.param.get_error_hint(self.ctx) # type: ignore
155
+ else:
156
+ param_hint = None
157
+
158
+ param_hint = _join_param_hints(param_hint)
159
+ param_hint = f" {param_hint}" if param_hint else ""
160
+
161
+ param_type = self.param_type
162
+ if param_type is None and self.param is not None:
163
+ param_type = self.param.param_type_name
164
+
165
+ msg = self.message
166
+ if self.param is not None:
167
+ msg_extra = self.param.type.get_missing_message(self.param)
168
+ if msg_extra:
169
+ if msg:
170
+ msg += f". {msg_extra}"
171
+ else:
172
+ msg = msg_extra
173
+
174
+ msg = f" {msg}" if msg else ""
175
+
176
+ # Translate param_type for known types.
177
+ if param_type == "argument":
178
+ missing = _("Missing argument")
179
+ elif param_type == "option":
180
+ missing = _("Missing option")
181
+ elif param_type == "parameter":
182
+ missing = _("Missing parameter")
183
+ else:
184
+ missing = _("Missing {param_type}").format(param_type=param_type)
185
+
186
+ return f"{missing}{param_hint}.{msg}"
187
+
188
+ def __str__(self) -> str:
189
+ if not self.message:
190
+ param_name = self.param.name if self.param else None
191
+ return _("Missing parameter: {param_name}").format(param_name=param_name)
192
+ else:
193
+ return self.message
194
+
195
+
196
+ class NoSuchOption(UsageError):
197
+ """Raised if click attempted to handle an option that does not
198
+ exist.
199
+
200
+ .. versionadded:: 4.0
201
+ """
202
+
203
+ def __init__(
204
+ self,
205
+ option_name: str,
206
+ message: t.Optional[str] = None,
207
+ possibilities: t.Optional[t.Sequence[str]] = None,
208
+ ctx: t.Optional["Context"] = None,
209
+ ) -> None:
210
+ if message is None:
211
+ message = _("No such option: {name}").format(name=option_name)
212
+
213
+ super().__init__(message, ctx)
214
+ self.option_name = option_name
215
+ self.possibilities = possibilities
216
+
217
+ def format_message(self) -> str:
218
+ if not self.possibilities:
219
+ return self.message
220
+
221
+ possibility_str = ", ".join(sorted(self.possibilities))
222
+ suggest = ngettext(
223
+ "Did you mean {possibility}?",
224
+ "(Possible options: {possibilities})",
225
+ len(self.possibilities),
226
+ ).format(possibility=possibility_str, possibilities=possibility_str)
227
+ return f"{self.message} {suggest}"
228
+
229
+
230
+ class BadOptionUsage(UsageError):
231
+ """Raised if an option is generally supplied but the use of the option
232
+ was incorrect. This is for instance raised if the number of arguments
233
+ for an option is not correct.
234
+
235
+ .. versionadded:: 4.0
236
+
237
+ :param option_name: the name of the option being used incorrectly.
238
+ """
239
+
240
+ def __init__(
241
+ self, option_name: str, message: str, ctx: t.Optional["Context"] = None
242
+ ) -> None:
243
+ super().__init__(message, ctx)
244
+ self.option_name = option_name
245
+
246
+
247
+ class BadArgumentUsage(UsageError):
248
+ """Raised if an argument is generally supplied but the use of the argument
249
+ was incorrect. This is for instance raised if the number of values
250
+ for an argument is not correct.
251
+
252
+ .. versionadded:: 6.0
253
+ """
254
+
255
+
256
+ class FileError(ClickException):
257
+ """Raised if a file cannot be opened."""
258
+
259
+ def __init__(self, filename: str, hint: t.Optional[str] = None) -> None:
260
+ if hint is None:
261
+ hint = _("unknown error")
262
+
263
+ super().__init__(hint)
264
+ self.ui_filename = os.fsdecode(filename)
265
+ self.filename = filename
266
+
267
+ def format_message(self) -> str:
268
+ return _("Could not open file {filename!r}: {message}").format(
269
+ filename=self.ui_filename, message=self.message
270
+ )
271
+
272
+
273
+ class Abort(RuntimeError):
274
+ """An internal signalling exception that signals Click to abort."""
275
+
276
+
277
+ class Exit(RuntimeError):
278
+ """An exception that indicates that the application should exit with some
279
+ status code.
280
+
281
+ :param code: the status code to exit with.
282
+ """
283
+
284
+ __slots__ = ("exit_code",)
285
+
286
+ def __init__(self, code: int = 0) -> None:
287
+ self.exit_code = code
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/click/formatting.py ADDED
@@ -0,0 +1,301 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import typing as t
2
+ from contextlib import contextmanager
3
+ from gettext import gettext as _
4
+
5
+ from ._compat import term_len
6
+ from .parser import split_opt
7
+
8
+ # Can force a width. This is used by the test system
9
+ FORCED_WIDTH: t.Optional[int] = None
10
+
11
+
12
+ def measure_table(rows: t.Iterable[t.Tuple[str, str]]) -> t.Tuple[int, ...]:
13
+ widths: t.Dict[int, int] = {}
14
+
15
+ for row in rows:
16
+ for idx, col in enumerate(row):
17
+ widths[idx] = max(widths.get(idx, 0), term_len(col))
18
+
19
+ return tuple(y for x, y in sorted(widths.items()))
20
+
21
+
22
+ def iter_rows(
23
+ rows: t.Iterable[t.Tuple[str, str]], col_count: int
24
+ ) -> t.Iterator[t.Tuple[str, ...]]:
25
+ for row in rows:
26
+ yield row + ("",) * (col_count - len(row))
27
+
28
+
29
+ def wrap_text(
30
+ text: str,
31
+ width: int = 78,
32
+ initial_indent: str = "",
33
+ subsequent_indent: str = "",
34
+ preserve_paragraphs: bool = False,
35
+ ) -> str:
36
+ """A helper function that intelligently wraps text. By default, it
37
+ assumes that it operates on a single paragraph of text but if the
38
+ `preserve_paragraphs` parameter is provided it will intelligently
39
+ handle paragraphs (defined by two empty lines).
40
+
41
+ If paragraphs are handled, a paragraph can be prefixed with an empty
42
+ line containing the ``\\b`` character (``\\x08``) to indicate that
43
+ no rewrapping should happen in that block.
44
+
45
+ :param text: the text that should be rewrapped.
46
+ :param width: the maximum width for the text.
47
+ :param initial_indent: the initial indent that should be placed on the
48
+ first line as a string.
49
+ :param subsequent_indent: the indent string that should be placed on
50
+ each consecutive line.
51
+ :param preserve_paragraphs: if this flag is set then the wrapping will
52
+ intelligently handle paragraphs.
53
+ """
54
+ from ._textwrap import TextWrapper
55
+
56
+ text = text.expandtabs()
57
+ wrapper = TextWrapper(
58
+ width,
59
+ initial_indent=initial_indent,
60
+ subsequent_indent=subsequent_indent,
61
+ replace_whitespace=False,
62
+ )
63
+ if not preserve_paragraphs:
64
+ return wrapper.fill(text)
65
+
66
+ p: t.List[t.Tuple[int, bool, str]] = []
67
+ buf: t.List[str] = []
68
+ indent = None
69
+
70
+ def _flush_par() -> None:
71
+ if not buf:
72
+ return
73
+ if buf[0].strip() == "\b":
74
+ p.append((indent or 0, True, "\n".join(buf[1:])))
75
+ else:
76
+ p.append((indent or 0, False, " ".join(buf)))
77
+ del buf[:]
78
+
79
+ for line in text.splitlines():
80
+ if not line:
81
+ _flush_par()
82
+ indent = None
83
+ else:
84
+ if indent is None:
85
+ orig_len = term_len(line)
86
+ line = line.lstrip()
87
+ indent = orig_len - term_len(line)
88
+ buf.append(line)
89
+ _flush_par()
90
+
91
+ rv = []
92
+ for indent, raw, text in p:
93
+ with wrapper.extra_indent(" " * indent):
94
+ if raw:
95
+ rv.append(wrapper.indent_only(text))
96
+ else:
97
+ rv.append(wrapper.fill(text))
98
+
99
+ return "\n\n".join(rv)
100
+
101
+
102
+ class HelpFormatter:
103
+ """This class helps with formatting text-based help pages. It's
104
+ usually just needed for very special internal cases, but it's also
105
+ exposed so that developers can write their own fancy outputs.
106
+
107
+ At present, it always writes into memory.
108
+
109
+ :param indent_increment: the additional increment for each level.
110
+ :param width: the width for the text. This defaults to the terminal
111
+ width clamped to a maximum of 78.
112
+ """
113
+
114
+ def __init__(
115
+ self,
116
+ indent_increment: int = 2,
117
+ width: t.Optional[int] = None,
118
+ max_width: t.Optional[int] = None,
119
+ ) -> None:
120
+ import shutil
121
+
122
+ self.indent_increment = indent_increment
123
+ if max_width is None:
124
+ max_width = 80
125
+ if width is None:
126
+ width = FORCED_WIDTH
127
+ if width is None:
128
+ width = max(min(shutil.get_terminal_size().columns, max_width) - 2, 50)
129
+ self.width = width
130
+ self.current_indent = 0
131
+ self.buffer: t.List[str] = []
132
+
133
+ def write(self, string: str) -> None:
134
+ """Writes a unicode string into the internal buffer."""
135
+ self.buffer.append(string)
136
+
137
+ def indent(self) -> None:
138
+ """Increases the indentation."""
139
+ self.current_indent += self.indent_increment
140
+
141
+ def dedent(self) -> None:
142
+ """Decreases the indentation."""
143
+ self.current_indent -= self.indent_increment
144
+
145
+ def write_usage(
146
+ self, prog: str, args: str = "", prefix: t.Optional[str] = None
147
+ ) -> None:
148
+ """Writes a usage line into the buffer.
149
+
150
+ :param prog: the program name.
151
+ :param args: whitespace separated list of arguments.
152
+ :param prefix: The prefix for the first line. Defaults to
153
+ ``"Usage: "``.
154
+ """
155
+ if prefix is None:
156
+ prefix = f"{_('Usage:')} "
157
+
158
+ usage_prefix = f"{prefix:>{self.current_indent}}{prog} "
159
+ text_width = self.width - self.current_indent
160
+
161
+ if text_width >= (term_len(usage_prefix) + 20):
162
+ # The arguments will fit to the right of the prefix.
163
+ indent = " " * term_len(usage_prefix)
164
+ self.write(
165
+ wrap_text(
166
+ args,
167
+ text_width,
168
+ initial_indent=usage_prefix,
169
+ subsequent_indent=indent,
170
+ )
171
+ )
172
+ else:
173
+ # The prefix is too long, put the arguments on the next line.
174
+ self.write(usage_prefix)
175
+ self.write("\n")
176
+ indent = " " * (max(self.current_indent, term_len(prefix)) + 4)
177
+ self.write(
178
+ wrap_text(
179
+ args, text_width, initial_indent=indent, subsequent_indent=indent
180
+ )
181
+ )
182
+
183
+ self.write("\n")
184
+
185
+ def write_heading(self, heading: str) -> None:
186
+ """Writes a heading into the buffer."""
187
+ self.write(f"{'':>{self.current_indent}}{heading}:\n")
188
+
189
+ def write_paragraph(self) -> None:
190
+ """Writes a paragraph into the buffer."""
191
+ if self.buffer:
192
+ self.write("\n")
193
+
194
+ def write_text(self, text: str) -> None:
195
+ """Writes re-indented text into the buffer. This rewraps and
196
+ preserves paragraphs.
197
+ """
198
+ indent = " " * self.current_indent
199
+ self.write(
200
+ wrap_text(
201
+ text,
202
+ self.width,
203
+ initial_indent=indent,
204
+ subsequent_indent=indent,
205
+ preserve_paragraphs=True,
206
+ )
207
+ )
208
+ self.write("\n")
209
+
210
+ def write_dl(
211
+ self,
212
+ rows: t.Sequence[t.Tuple[str, str]],
213
+ col_max: int = 30,
214
+ col_spacing: int = 2,
215
+ ) -> None:
216
+ """Writes a definition list into the buffer. This is how options
217
+ and commands are usually formatted.
218
+
219
+ :param rows: a list of two item tuples for the terms and values.
220
+ :param col_max: the maximum width of the first column.
221
+ :param col_spacing: the number of spaces between the first and
222
+ second column.
223
+ """
224
+ rows = list(rows)
225
+ widths = measure_table(rows)
226
+ if len(widths) != 2:
227
+ raise TypeError("Expected two columns for definition list")
228
+
229
+ first_col = min(widths[0], col_max) + col_spacing
230
+
231
+ for first, second in iter_rows(rows, len(widths)):
232
+ self.write(f"{'':>{self.current_indent}}{first}")
233
+ if not second:
234
+ self.write("\n")
235
+ continue
236
+ if term_len(first) <= first_col - col_spacing:
237
+ self.write(" " * (first_col - term_len(first)))
238
+ else:
239
+ self.write("\n")
240
+ self.write(" " * (first_col + self.current_indent))
241
+
242
+ text_width = max(self.width - first_col - 2, 10)
243
+ wrapped_text = wrap_text(second, text_width, preserve_paragraphs=True)
244
+ lines = wrapped_text.splitlines()
245
+
246
+ if lines:
247
+ self.write(f"{lines[0]}\n")
248
+
249
+ for line in lines[1:]:
250
+ self.write(f"{'':>{first_col + self.current_indent}}{line}\n")
251
+ else:
252
+ self.write("\n")
253
+
254
+ @contextmanager
255
+ def section(self, name: str) -> t.Iterator[None]:
256
+ """Helpful context manager that writes a paragraph, a heading,
257
+ and the indents.
258
+
259
+ :param name: the section name that is written as heading.
260
+ """
261
+ self.write_paragraph()
262
+ self.write_heading(name)
263
+ self.indent()
264
+ try:
265
+ yield
266
+ finally:
267
+ self.dedent()
268
+
269
+ @contextmanager
270
+ def indentation(self) -> t.Iterator[None]:
271
+ """A context manager that increases the indentation."""
272
+ self.indent()
273
+ try:
274
+ yield
275
+ finally:
276
+ self.dedent()
277
+
278
+ def getvalue(self) -> str:
279
+ """Returns the buffer contents."""
280
+ return "".join(self.buffer)
281
+
282
+
283
+ def join_options(options: t.Sequence[str]) -> t.Tuple[str, bool]:
284
+ """Given a list of option strings this joins them in the most appropriate
285
+ way and returns them in the form ``(formatted_string,
286
+ any_prefix_is_slash)`` where the second item in the tuple is a flag that
287
+ indicates if any of the option prefixes was a slash.
288
+ """
289
+ rv = []
290
+ any_prefix_is_slash = False
291
+
292
+ for opt in options:
293
+ prefix = split_opt(opt)[0]
294
+
295
+ if prefix == "/":
296
+ any_prefix_is_slash = True
297
+
298
+ rv.append((len(prefix), opt))
299
+
300
+ rv.sort(key=lambda x: x[0])
301
+ return ", ".join(x[1] for x in rv), any_prefix_is_slash
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/click/globals.py ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import typing as t
2
+ from threading import local
3
+
4
+ if t.TYPE_CHECKING:
5
+ import typing_extensions as te
6
+ from .core import Context
7
+
8
+ _local = local()
9
+
10
+
11
+ @t.overload
12
+ def get_current_context(silent: "te.Literal[False]" = False) -> "Context":
13
+ ...
14
+
15
+
16
+ @t.overload
17
+ def get_current_context(silent: bool = ...) -> t.Optional["Context"]:
18
+ ...
19
+
20
+
21
+ def get_current_context(silent: bool = False) -> t.Optional["Context"]:
22
+ """Returns the current click context. This can be used as a way to
23
+ access the current context object from anywhere. This is a more implicit
24
+ alternative to the :func:`pass_context` decorator. This function is
25
+ primarily useful for helpers such as :func:`echo` which might be
26
+ interested in changing its behavior based on the current context.
27
+
28
+ To push the current context, :meth:`Context.scope` can be used.
29
+
30
+ .. versionadded:: 5.0
31
+
32
+ :param silent: if set to `True` the return value is `None` if no context
33
+ is available. The default behavior is to raise a
34
+ :exc:`RuntimeError`.
35
+ """
36
+ try:
37
+ return t.cast("Context", _local.stack[-1])
38
+ except (AttributeError, IndexError) as e:
39
+ if not silent:
40
+ raise RuntimeError("There is no active click context.") from e
41
+
42
+ return None
43
+
44
+
45
+ def push_context(ctx: "Context") -> None:
46
+ """Pushes a new context to the current stack."""
47
+ _local.__dict__.setdefault("stack", []).append(ctx)
48
+
49
+
50
+ def pop_context() -> None:
51
+ """Removes the top level from the stack."""
52
+ _local.stack.pop()
53
+
54
+
55
+ def resolve_color_default(color: t.Optional[bool] = None) -> t.Optional[bool]:
56
+ """Internal helper to get the default value of the color flag. If a
57
+ value is passed it's returned unchanged, otherwise it's looked up from
58
+ the current context.
59
+ """
60
+ if color is not None:
61
+ return color
62
+
63
+ ctx = get_current_context(silent=True)
64
+
65
+ if ctx is not None:
66
+ return ctx.color
67
+
68
+ return None
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/click/parser.py ADDED
@@ -0,0 +1,529 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ This module started out as largely a copy paste from the stdlib's
3
+ optparse module with the features removed that we do not need from
4
+ optparse because we implement them in Click on a higher level (for
5
+ instance type handling, help formatting and a lot more).
6
+
7
+ The plan is to remove more and more from here over time.
8
+
9
+ The reason this is a different module and not optparse from the stdlib
10
+ is that there are differences in 2.x and 3.x about the error messages
11
+ generated and optparse in the stdlib uses gettext for no good reason
12
+ and might cause us issues.
13
+
14
+ Click uses parts of optparse written by Gregory P. Ward and maintained
15
+ by the Python Software Foundation. This is limited to code in parser.py.
16
+
17
+ Copyright 2001-2006 Gregory P. Ward. All rights reserved.
18
+ Copyright 2002-2006 Python Software Foundation. All rights reserved.
19
+ """
20
+ # This code uses parts of optparse written by Gregory P. Ward and
21
+ # maintained by the Python Software Foundation.
22
+ # Copyright 2001-2006 Gregory P. Ward
23
+ # Copyright 2002-2006 Python Software Foundation
24
+ import typing as t
25
+ from collections import deque
26
+ from gettext import gettext as _
27
+ from gettext import ngettext
28
+
29
+ from .exceptions import BadArgumentUsage
30
+ from .exceptions import BadOptionUsage
31
+ from .exceptions import NoSuchOption
32
+ from .exceptions import UsageError
33
+
34
+ if t.TYPE_CHECKING:
35
+ import typing_extensions as te
36
+ from .core import Argument as CoreArgument
37
+ from .core import Context
38
+ from .core import Option as CoreOption
39
+ from .core import Parameter as CoreParameter
40
+
41
+ V = t.TypeVar("V")
42
+
43
+ # Sentinel value that indicates an option was passed as a flag without a
44
+ # value but is not a flag option. Option.consume_value uses this to
45
+ # prompt or use the flag_value.
46
+ _flag_needs_value = object()
47
+
48
+
49
+ def _unpack_args(
50
+ args: t.Sequence[str], nargs_spec: t.Sequence[int]
51
+ ) -> t.Tuple[t.Sequence[t.Union[str, t.Sequence[t.Optional[str]], None]], t.List[str]]:
52
+ """Given an iterable of arguments and an iterable of nargs specifications,
53
+ it returns a tuple with all the unpacked arguments at the first index
54
+ and all remaining arguments as the second.
55
+
56
+ The nargs specification is the number of arguments that should be consumed
57
+ or `-1` to indicate that this position should eat up all the remainders.
58
+
59
+ Missing items are filled with `None`.
60
+ """
61
+ args = deque(args)
62
+ nargs_spec = deque(nargs_spec)
63
+ rv: t.List[t.Union[str, t.Tuple[t.Optional[str], ...], None]] = []
64
+ spos: t.Optional[int] = None
65
+
66
+ def _fetch(c: "te.Deque[V]") -> t.Optional[V]:
67
+ try:
68
+ if spos is None:
69
+ return c.popleft()
70
+ else:
71
+ return c.pop()
72
+ except IndexError:
73
+ return None
74
+
75
+ while nargs_spec:
76
+ nargs = _fetch(nargs_spec)
77
+
78
+ if nargs is None:
79
+ continue
80
+
81
+ if nargs == 1:
82
+ rv.append(_fetch(args))
83
+ elif nargs > 1:
84
+ x = [_fetch(args) for _ in range(nargs)]
85
+
86
+ # If we're reversed, we're pulling in the arguments in reverse,
87
+ # so we need to turn them around.
88
+ if spos is not None:
89
+ x.reverse()
90
+
91
+ rv.append(tuple(x))
92
+ elif nargs < 0:
93
+ if spos is not None:
94
+ raise TypeError("Cannot have two nargs < 0")
95
+
96
+ spos = len(rv)
97
+ rv.append(None)
98
+
99
+ # spos is the position of the wildcard (star). If it's not `None`,
100
+ # we fill it with the remainder.
101
+ if spos is not None:
102
+ rv[spos] = tuple(args)
103
+ args = []
104
+ rv[spos + 1 :] = reversed(rv[spos + 1 :])
105
+
106
+ return tuple(rv), list(args)
107
+
108
+
109
+ def split_opt(opt: str) -> t.Tuple[str, str]:
110
+ first = opt[:1]
111
+ if first.isalnum():
112
+ return "", opt
113
+ if opt[1:2] == first:
114
+ return opt[:2], opt[2:]
115
+ return first, opt[1:]
116
+
117
+
118
+ def normalize_opt(opt: str, ctx: t.Optional["Context"]) -> str:
119
+ if ctx is None or ctx.token_normalize_func is None:
120
+ return opt
121
+ prefix, opt = split_opt(opt)
122
+ return f"{prefix}{ctx.token_normalize_func(opt)}"
123
+
124
+
125
+ def split_arg_string(string: str) -> t.List[str]:
126
+ """Split an argument string as with :func:`shlex.split`, but don't
127
+ fail if the string is incomplete. Ignores a missing closing quote or
128
+ incomplete escape sequence and uses the partial token as-is.
129
+
130
+ .. code-block:: python
131
+
132
+ split_arg_string("example 'my file")
133
+ ["example", "my file"]
134
+
135
+ split_arg_string("example my\\")
136
+ ["example", "my"]
137
+
138
+ :param string: String to split.
139
+ """
140
+ import shlex
141
+
142
+ lex = shlex.shlex(string, posix=True)
143
+ lex.whitespace_split = True
144
+ lex.commenters = ""
145
+ out = []
146
+
147
+ try:
148
+ for token in lex:
149
+ out.append(token)
150
+ except ValueError:
151
+ # Raised when end-of-string is reached in an invalid state. Use
152
+ # the partial token as-is. The quote or escape character is in
153
+ # lex.state, not lex.token.
154
+ out.append(lex.token)
155
+
156
+ return out
157
+
158
+
159
+ class Option:
160
+ def __init__(
161
+ self,
162
+ obj: "CoreOption",
163
+ opts: t.Sequence[str],
164
+ dest: t.Optional[str],
165
+ action: t.Optional[str] = None,
166
+ nargs: int = 1,
167
+ const: t.Optional[t.Any] = None,
168
+ ):
169
+ self._short_opts = []
170
+ self._long_opts = []
171
+ self.prefixes = set()
172
+
173
+ for opt in opts:
174
+ prefix, value = split_opt(opt)
175
+ if not prefix:
176
+ raise ValueError(f"Invalid start character for option ({opt})")
177
+ self.prefixes.add(prefix[0])
178
+ if len(prefix) == 1 and len(value) == 1:
179
+ self._short_opts.append(opt)
180
+ else:
181
+ self._long_opts.append(opt)
182
+ self.prefixes.add(prefix)
183
+
184
+ if action is None:
185
+ action = "store"
186
+
187
+ self.dest = dest
188
+ self.action = action
189
+ self.nargs = nargs
190
+ self.const = const
191
+ self.obj = obj
192
+
193
+ @property
194
+ def takes_value(self) -> bool:
195
+ return self.action in ("store", "append")
196
+
197
+ def process(self, value: str, state: "ParsingState") -> None:
198
+ if self.action == "store":
199
+ state.opts[self.dest] = value # type: ignore
200
+ elif self.action == "store_const":
201
+ state.opts[self.dest] = self.const # type: ignore
202
+ elif self.action == "append":
203
+ state.opts.setdefault(self.dest, []).append(value) # type: ignore
204
+ elif self.action == "append_const":
205
+ state.opts.setdefault(self.dest, []).append(self.const) # type: ignore
206
+ elif self.action == "count":
207
+ state.opts[self.dest] = state.opts.get(self.dest, 0) + 1 # type: ignore
208
+ else:
209
+ raise ValueError(f"unknown action '{self.action}'")
210
+ state.order.append(self.obj)
211
+
212
+
213
+ class Argument:
214
+ def __init__(self, obj: "CoreArgument", dest: t.Optional[str], nargs: int = 1):
215
+ self.dest = dest
216
+ self.nargs = nargs
217
+ self.obj = obj
218
+
219
+ def process(
220
+ self,
221
+ value: t.Union[t.Optional[str], t.Sequence[t.Optional[str]]],
222
+ state: "ParsingState",
223
+ ) -> None:
224
+ if self.nargs > 1:
225
+ assert value is not None
226
+ holes = sum(1 for x in value if x is None)
227
+ if holes == len(value):
228
+ value = None
229
+ elif holes != 0:
230
+ raise BadArgumentUsage(
231
+ _("Argument {name!r} takes {nargs} values.").format(
232
+ name=self.dest, nargs=self.nargs
233
+ )
234
+ )
235
+
236
+ if self.nargs == -1 and self.obj.envvar is not None and value == ():
237
+ # Replace empty tuple with None so that a value from the
238
+ # environment may be tried.
239
+ value = None
240
+
241
+ state.opts[self.dest] = value # type: ignore
242
+ state.order.append(self.obj)
243
+
244
+
245
+ class ParsingState:
246
+ def __init__(self, rargs: t.List[str]) -> None:
247
+ self.opts: t.Dict[str, t.Any] = {}
248
+ self.largs: t.List[str] = []
249
+ self.rargs = rargs
250
+ self.order: t.List["CoreParameter"] = []
251
+
252
+
253
+ class OptionParser:
254
+ """The option parser is an internal class that is ultimately used to
255
+ parse options and arguments. It's modelled after optparse and brings
256
+ a similar but vastly simplified API. It should generally not be used
257
+ directly as the high level Click classes wrap it for you.
258
+
259
+ It's not nearly as extensible as optparse or argparse as it does not
260
+ implement features that are implemented on a higher level (such as
261
+ types or defaults).
262
+
263
+ :param ctx: optionally the :class:`~click.Context` where this parser
264
+ should go with.
265
+ """
266
+
267
+ def __init__(self, ctx: t.Optional["Context"] = None) -> None:
268
+ #: The :class:`~click.Context` for this parser. This might be
269
+ #: `None` for some advanced use cases.
270
+ self.ctx = ctx
271
+ #: This controls how the parser deals with interspersed arguments.
272
+ #: If this is set to `False`, the parser will stop on the first
273
+ #: non-option. Click uses this to implement nested subcommands
274
+ #: safely.
275
+ self.allow_interspersed_args = True
276
+ #: This tells the parser how to deal with unknown options. By
277
+ #: default it will error out (which is sensible), but there is a
278
+ #: second mode where it will ignore it and continue processing
279
+ #: after shifting all the unknown options into the resulting args.
280
+ self.ignore_unknown_options = False
281
+
282
+ if ctx is not None:
283
+ self.allow_interspersed_args = ctx.allow_interspersed_args
284
+ self.ignore_unknown_options = ctx.ignore_unknown_options
285
+
286
+ self._short_opt: t.Dict[str, Option] = {}
287
+ self._long_opt: t.Dict[str, Option] = {}
288
+ self._opt_prefixes = {"-", "--"}
289
+ self._args: t.List[Argument] = []
290
+
291
+ def add_option(
292
+ self,
293
+ obj: "CoreOption",
294
+ opts: t.Sequence[str],
295
+ dest: t.Optional[str],
296
+ action: t.Optional[str] = None,
297
+ nargs: int = 1,
298
+ const: t.Optional[t.Any] = None,
299
+ ) -> None:
300
+ """Adds a new option named `dest` to the parser. The destination
301
+ is not inferred (unlike with optparse) and needs to be explicitly
302
+ provided. Action can be any of ``store``, ``store_const``,
303
+ ``append``, ``append_const`` or ``count``.
304
+
305
+ The `obj` can be used to identify the option in the order list
306
+ that is returned from the parser.
307
+ """
308
+ opts = [normalize_opt(opt, self.ctx) for opt in opts]
309
+ option = Option(obj, opts, dest, action=action, nargs=nargs, const=const)
310
+ self._opt_prefixes.update(option.prefixes)
311
+ for opt in option._short_opts:
312
+ self._short_opt[opt] = option
313
+ for opt in option._long_opts:
314
+ self._long_opt[opt] = option
315
+
316
+ def add_argument(
317
+ self, obj: "CoreArgument", dest: t.Optional[str], nargs: int = 1
318
+ ) -> None:
319
+ """Adds a positional argument named `dest` to the parser.
320
+
321
+ The `obj` can be used to identify the option in the order list
322
+ that is returned from the parser.
323
+ """
324
+ self._args.append(Argument(obj, dest=dest, nargs=nargs))
325
+
326
+ def parse_args(
327
+ self, args: t.List[str]
328
+ ) -> t.Tuple[t.Dict[str, t.Any], t.List[str], t.List["CoreParameter"]]:
329
+ """Parses positional arguments and returns ``(values, args, order)``
330
+ for the parsed options and arguments as well as the leftover
331
+ arguments if there are any. The order is a list of objects as they
332
+ appear on the command line. If arguments appear multiple times they
333
+ will be memorized multiple times as well.
334
+ """
335
+ state = ParsingState(args)
336
+ try:
337
+ self._process_args_for_options(state)
338
+ self._process_args_for_args(state)
339
+ except UsageError:
340
+ if self.ctx is None or not self.ctx.resilient_parsing:
341
+ raise
342
+ return state.opts, state.largs, state.order
343
+
344
+ def _process_args_for_args(self, state: ParsingState) -> None:
345
+ pargs, args = _unpack_args(
346
+ state.largs + state.rargs, [x.nargs for x in self._args]
347
+ )
348
+
349
+ for idx, arg in enumerate(self._args):
350
+ arg.process(pargs[idx], state)
351
+
352
+ state.largs = args
353
+ state.rargs = []
354
+
355
+ def _process_args_for_options(self, state: ParsingState) -> None:
356
+ while state.rargs:
357
+ arg = state.rargs.pop(0)
358
+ arglen = len(arg)
359
+ # Double dashes always handled explicitly regardless of what
360
+ # prefixes are valid.
361
+ if arg == "--":
362
+ return
363
+ elif arg[:1] in self._opt_prefixes and arglen > 1:
364
+ self._process_opts(arg, state)
365
+ elif self.allow_interspersed_args:
366
+ state.largs.append(arg)
367
+ else:
368
+ state.rargs.insert(0, arg)
369
+ return
370
+
371
+ # Say this is the original argument list:
372
+ # [arg0, arg1, ..., arg(i-1), arg(i), arg(i+1), ..., arg(N-1)]
373
+ # ^
374
+ # (we are about to process arg(i)).
375
+ #
376
+ # Then rargs is [arg(i), ..., arg(N-1)] and largs is a *subset* of
377
+ # [arg0, ..., arg(i-1)] (any options and their arguments will have
378
+ # been removed from largs).
379
+ #
380
+ # The while loop will usually consume 1 or more arguments per pass.
381
+ # If it consumes 1 (eg. arg is an option that takes no arguments),
382
+ # then after _process_arg() is done the situation is:
383
+ #
384
+ # largs = subset of [arg0, ..., arg(i)]
385
+ # rargs = [arg(i+1), ..., arg(N-1)]
386
+ #
387
+ # If allow_interspersed_args is false, largs will always be
388
+ # *empty* -- still a subset of [arg0, ..., arg(i-1)], but
389
+ # not a very interesting subset!
390
+
391
+ def _match_long_opt(
392
+ self, opt: str, explicit_value: t.Optional[str], state: ParsingState
393
+ ) -> None:
394
+ if opt not in self._long_opt:
395
+ from difflib import get_close_matches
396
+
397
+ possibilities = get_close_matches(opt, self._long_opt)
398
+ raise NoSuchOption(opt, possibilities=possibilities, ctx=self.ctx)
399
+
400
+ option = self._long_opt[opt]
401
+ if option.takes_value:
402
+ # At this point it's safe to modify rargs by injecting the
403
+ # explicit value, because no exception is raised in this
404
+ # branch. This means that the inserted value will be fully
405
+ # consumed.
406
+ if explicit_value is not None:
407
+ state.rargs.insert(0, explicit_value)
408
+
409
+ value = self._get_value_from_state(opt, option, state)
410
+
411
+ elif explicit_value is not None:
412
+ raise BadOptionUsage(
413
+ opt, _("Option {name!r} does not take a value.").format(name=opt)
414
+ )
415
+
416
+ else:
417
+ value = None
418
+
419
+ option.process(value, state)
420
+
421
+ def _match_short_opt(self, arg: str, state: ParsingState) -> None:
422
+ stop = False
423
+ i = 1
424
+ prefix = arg[0]
425
+ unknown_options = []
426
+
427
+ for ch in arg[1:]:
428
+ opt = normalize_opt(f"{prefix}{ch}", self.ctx)
429
+ option = self._short_opt.get(opt)
430
+ i += 1
431
+
432
+ if not option:
433
+ if self.ignore_unknown_options:
434
+ unknown_options.append(ch)
435
+ continue
436
+ raise NoSuchOption(opt, ctx=self.ctx)
437
+ if option.takes_value:
438
+ # Any characters left in arg? Pretend they're the
439
+ # next arg, and stop consuming characters of arg.
440
+ if i < len(arg):
441
+ state.rargs.insert(0, arg[i:])
442
+ stop = True
443
+
444
+ value = self._get_value_from_state(opt, option, state)
445
+
446
+ else:
447
+ value = None
448
+
449
+ option.process(value, state)
450
+
451
+ if stop:
452
+ break
453
+
454
+ # If we got any unknown options we re-combinate the string of the
455
+ # remaining options and re-attach the prefix, then report that
456
+ # to the state as new larg. This way there is basic combinatorics
457
+ # that can be achieved while still ignoring unknown arguments.
458
+ if self.ignore_unknown_options and unknown_options:
459
+ state.largs.append(f"{prefix}{''.join(unknown_options)}")
460
+
461
+ def _get_value_from_state(
462
+ self, option_name: str, option: Option, state: ParsingState
463
+ ) -> t.Any:
464
+ nargs = option.nargs
465
+
466
+ if len(state.rargs) < nargs:
467
+ if option.obj._flag_needs_value:
468
+ # Option allows omitting the value.
469
+ value = _flag_needs_value
470
+ else:
471
+ raise BadOptionUsage(
472
+ option_name,
473
+ ngettext(
474
+ "Option {name!r} requires an argument.",
475
+ "Option {name!r} requires {nargs} arguments.",
476
+ nargs,
477
+ ).format(name=option_name, nargs=nargs),
478
+ )
479
+ elif nargs == 1:
480
+ next_rarg = state.rargs[0]
481
+
482
+ if (
483
+ option.obj._flag_needs_value
484
+ and isinstance(next_rarg, str)
485
+ and next_rarg[:1] in self._opt_prefixes
486
+ and len(next_rarg) > 1
487
+ ):
488
+ # The next arg looks like the start of an option, don't
489
+ # use it as the value if omitting the value is allowed.
490
+ value = _flag_needs_value
491
+ else:
492
+ value = state.rargs.pop(0)
493
+ else:
494
+ value = tuple(state.rargs[:nargs])
495
+ del state.rargs[:nargs]
496
+
497
+ return value
498
+
499
+ def _process_opts(self, arg: str, state: ParsingState) -> None:
500
+ explicit_value = None
501
+ # Long option handling happens in two parts. The first part is
502
+ # supporting explicitly attached values. In any case, we will try
503
+ # to long match the option first.
504
+ if "=" in arg:
505
+ long_opt, explicit_value = arg.split("=", 1)
506
+ else:
507
+ long_opt = arg
508
+ norm_long_opt = normalize_opt(long_opt, self.ctx)
509
+
510
+ # At this point we will match the (assumed) long option through
511
+ # the long option matching code. Note that this allows options
512
+ # like "-foo" to be matched as long options.
513
+ try:
514
+ self._match_long_opt(norm_long_opt, explicit_value, state)
515
+ except NoSuchOption:
516
+ # At this point the long option matching failed, and we need
517
+ # to try with short options. However there is a special rule
518
+ # which says, that if we have a two character options prefix
519
+ # (applies to "--foo" for instance), we do not dispatch to the
520
+ # short option code and will instead raise the no option
521
+ # error.
522
+ if arg[:2] not in self._opt_prefixes:
523
+ self._match_short_opt(arg, state)
524
+ return
525
+
526
+ if not self.ignore_unknown_options:
527
+ raise
528
+
529
+ state.largs.append(arg)
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/click/py.typed ADDED
File without changes
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/click/shell_completion.py ADDED
@@ -0,0 +1,580 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import re
3
+ import typing as t
4
+ from gettext import gettext as _
5
+
6
+ from .core import Argument
7
+ from .core import BaseCommand
8
+ from .core import Context
9
+ from .core import MultiCommand
10
+ from .core import Option
11
+ from .core import Parameter
12
+ from .core import ParameterSource
13
+ from .parser import split_arg_string
14
+ from .utils import echo
15
+
16
+
17
+ def shell_complete(
18
+ cli: BaseCommand,
19
+ ctx_args: t.Dict[str, t.Any],
20
+ prog_name: str,
21
+ complete_var: str,
22
+ instruction: str,
23
+ ) -> int:
24
+ """Perform shell completion for the given CLI program.
25
+
26
+ :param cli: Command being called.
27
+ :param ctx_args: Extra arguments to pass to
28
+ ``cli.make_context``.
29
+ :param prog_name: Name of the executable in the shell.
30
+ :param complete_var: Name of the environment variable that holds
31
+ the completion instruction.
32
+ :param instruction: Value of ``complete_var`` with the completion
33
+ instruction and shell, in the form ``instruction_shell``.
34
+ :return: Status code to exit with.
35
+ """
36
+ shell, _, instruction = instruction.partition("_")
37
+ comp_cls = get_completion_class(shell)
38
+
39
+ if comp_cls is None:
40
+ return 1
41
+
42
+ comp = comp_cls(cli, ctx_args, prog_name, complete_var)
43
+
44
+ if instruction == "source":
45
+ echo(comp.source())
46
+ return 0
47
+
48
+ if instruction == "complete":
49
+ echo(comp.complete())
50
+ return 0
51
+
52
+ return 1
53
+
54
+
55
+ class CompletionItem:
56
+ """Represents a completion value and metadata about the value. The
57
+ default metadata is ``type`` to indicate special shell handling,
58
+ and ``help`` if a shell supports showing a help string next to the
59
+ value.
60
+
61
+ Arbitrary parameters can be passed when creating the object, and
62
+ accessed using ``item.attr``. If an attribute wasn't passed,
63
+ accessing it returns ``None``.
64
+
65
+ :param value: The completion suggestion.
66
+ :param type: Tells the shell script to provide special completion
67
+ support for the type. Click uses ``"dir"`` and ``"file"``.
68
+ :param help: String shown next to the value if supported.
69
+ :param kwargs: Arbitrary metadata. The built-in implementations
70
+ don't use this, but custom type completions paired with custom
71
+ shell support could use it.
72
+ """
73
+
74
+ __slots__ = ("value", "type", "help", "_info")
75
+
76
+ def __init__(
77
+ self,
78
+ value: t.Any,
79
+ type: str = "plain",
80
+ help: t.Optional[str] = None,
81
+ **kwargs: t.Any,
82
+ ) -> None:
83
+ self.value = value
84
+ self.type = type
85
+ self.help = help
86
+ self._info = kwargs
87
+
88
+ def __getattr__(self, name: str) -> t.Any:
89
+ return self._info.get(name)
90
+
91
+
92
+ # Only Bash >= 4.4 has the nosort option.
93
+ _SOURCE_BASH = """\
94
+ %(complete_func)s() {
95
+ local IFS=$'\\n'
96
+ local response
97
+
98
+ response=$(env COMP_WORDS="${COMP_WORDS[*]}" COMP_CWORD=$COMP_CWORD \
99
+ %(complete_var)s=bash_complete $1)
100
+
101
+ for completion in $response; do
102
+ IFS=',' read type value <<< "$completion"
103
+
104
+ if [[ $type == 'dir' ]]; then
105
+ COMPREPLY=()
106
+ compopt -o dirnames
107
+ elif [[ $type == 'file' ]]; then
108
+ COMPREPLY=()
109
+ compopt -o default
110
+ elif [[ $type == 'plain' ]]; then
111
+ COMPREPLY+=($value)
112
+ fi
113
+ done
114
+
115
+ return 0
116
+ }
117
+
118
+ %(complete_func)s_setup() {
119
+ complete -o nosort -F %(complete_func)s %(prog_name)s
120
+ }
121
+
122
+ %(complete_func)s_setup;
123
+ """
124
+
125
+ _SOURCE_ZSH = """\
126
+ #compdef %(prog_name)s
127
+
128
+ %(complete_func)s() {
129
+ local -a completions
130
+ local -a completions_with_descriptions
131
+ local -a response
132
+ (( ! $+commands[%(prog_name)s] )) && return 1
133
+
134
+ response=("${(@f)$(env COMP_WORDS="${words[*]}" COMP_CWORD=$((CURRENT-1)) \
135
+ %(complete_var)s=zsh_complete %(prog_name)s)}")
136
+
137
+ for type key descr in ${response}; do
138
+ if [[ "$type" == "plain" ]]; then
139
+ if [[ "$descr" == "_" ]]; then
140
+ completions+=("$key")
141
+ else
142
+ completions_with_descriptions+=("$key":"$descr")
143
+ fi
144
+ elif [[ "$type" == "dir" ]]; then
145
+ _path_files -/
146
+ elif [[ "$type" == "file" ]]; then
147
+ _path_files -f
148
+ fi
149
+ done
150
+
151
+ if [ -n "$completions_with_descriptions" ]; then
152
+ _describe -V unsorted completions_with_descriptions -U
153
+ fi
154
+
155
+ if [ -n "$completions" ]; then
156
+ compadd -U -V unsorted -a completions
157
+ fi
158
+ }
159
+
160
+ compdef %(complete_func)s %(prog_name)s;
161
+ """
162
+
163
+ _SOURCE_FISH = """\
164
+ function %(complete_func)s;
165
+ set -l response;
166
+
167
+ for value in (env %(complete_var)s=fish_complete COMP_WORDS=(commandline -cp) \
168
+ COMP_CWORD=(commandline -t) %(prog_name)s);
169
+ set response $response $value;
170
+ end;
171
+
172
+ for completion in $response;
173
+ set -l metadata (string split "," $completion);
174
+
175
+ if test $metadata[1] = "dir";
176
+ __fish_complete_directories $metadata[2];
177
+ else if test $metadata[1] = "file";
178
+ __fish_complete_path $metadata[2];
179
+ else if test $metadata[1] = "plain";
180
+ echo $metadata[2];
181
+ end;
182
+ end;
183
+ end;
184
+
185
+ complete --no-files --command %(prog_name)s --arguments \
186
+ "(%(complete_func)s)";
187
+ """
188
+
189
+
190
+ class ShellComplete:
191
+ """Base class for providing shell completion support. A subclass for
192
+ a given shell will override attributes and methods to implement the
193
+ completion instructions (``source`` and ``complete``).
194
+
195
+ :param cli: Command being called.
196
+ :param prog_name: Name of the executable in the shell.
197
+ :param complete_var: Name of the environment variable that holds
198
+ the completion instruction.
199
+
200
+ .. versionadded:: 8.0
201
+ """
202
+
203
+ name: t.ClassVar[str]
204
+ """Name to register the shell as with :func:`add_completion_class`.
205
+ This is used in completion instructions (``{name}_source`` and
206
+ ``{name}_complete``).
207
+ """
208
+
209
+ source_template: t.ClassVar[str]
210
+ """Completion script template formatted by :meth:`source`. This must
211
+ be provided by subclasses.
212
+ """
213
+
214
+ def __init__(
215
+ self,
216
+ cli: BaseCommand,
217
+ ctx_args: t.Dict[str, t.Any],
218
+ prog_name: str,
219
+ complete_var: str,
220
+ ) -> None:
221
+ self.cli = cli
222
+ self.ctx_args = ctx_args
223
+ self.prog_name = prog_name
224
+ self.complete_var = complete_var
225
+
226
+ @property
227
+ def func_name(self) -> str:
228
+ """The name of the shell function defined by the completion
229
+ script.
230
+ """
231
+ safe_name = re.sub(r"\W*", "", self.prog_name.replace("-", "_"), re.ASCII)
232
+ return f"_{safe_name}_completion"
233
+
234
+ def source_vars(self) -> t.Dict[str, t.Any]:
235
+ """Vars for formatting :attr:`source_template`.
236
+
237
+ By default this provides ``complete_func``, ``complete_var``,
238
+ and ``prog_name``.
239
+ """
240
+ return {
241
+ "complete_func": self.func_name,
242
+ "complete_var": self.complete_var,
243
+ "prog_name": self.prog_name,
244
+ }
245
+
246
+ def source(self) -> str:
247
+ """Produce the shell script that defines the completion
248
+ function. By default this ``%``-style formats
249
+ :attr:`source_template` with the dict returned by
250
+ :meth:`source_vars`.
251
+ """
252
+ return self.source_template % self.source_vars()
253
+
254
+ def get_completion_args(self) -> t.Tuple[t.List[str], str]:
255
+ """Use the env vars defined by the shell script to return a
256
+ tuple of ``args, incomplete``. This must be implemented by
257
+ subclasses.
258
+ """
259
+ raise NotImplementedError
260
+
261
+ def get_completions(
262
+ self, args: t.List[str], incomplete: str
263
+ ) -> t.List[CompletionItem]:
264
+ """Determine the context and last complete command or parameter
265
+ from the complete args. Call that object's ``shell_complete``
266
+ method to get the completions for the incomplete value.
267
+
268
+ :param args: List of complete args before the incomplete value.
269
+ :param incomplete: Value being completed. May be empty.
270
+ """
271
+ ctx = _resolve_context(self.cli, self.ctx_args, self.prog_name, args)
272
+ obj, incomplete = _resolve_incomplete(ctx, args, incomplete)
273
+ return obj.shell_complete(ctx, incomplete)
274
+
275
+ def format_completion(self, item: CompletionItem) -> str:
276
+ """Format a completion item into the form recognized by the
277
+ shell script. This must be implemented by subclasses.
278
+
279
+ :param item: Completion item to format.
280
+ """
281
+ raise NotImplementedError
282
+
283
+ def complete(self) -> str:
284
+ """Produce the completion data to send back to the shell.
285
+
286
+ By default this calls :meth:`get_completion_args`, gets the
287
+ completions, then calls :meth:`format_completion` for each
288
+ completion.
289
+ """
290
+ args, incomplete = self.get_completion_args()
291
+ completions = self.get_completions(args, incomplete)
292
+ out = [self.format_completion(item) for item in completions]
293
+ return "\n".join(out)
294
+
295
+
296
+ class BashComplete(ShellComplete):
297
+ """Shell completion for Bash."""
298
+
299
+ name = "bash"
300
+ source_template = _SOURCE_BASH
301
+
302
+ def _check_version(self) -> None:
303
+ import subprocess
304
+
305
+ output = subprocess.run(
306
+ ["bash", "-c", "echo ${BASH_VERSION}"], stdout=subprocess.PIPE
307
+ )
308
+ match = re.search(r"^(\d+)\.(\d+)\.\d+", output.stdout.decode())
309
+
310
+ if match is not None:
311
+ major, minor = match.groups()
312
+
313
+ if major < "4" or major == "4" and minor < "4":
314
+ raise RuntimeError(
315
+ _(
316
+ "Shell completion is not supported for Bash"
317
+ " versions older than 4.4."
318
+ )
319
+ )
320
+ else:
321
+ raise RuntimeError(
322
+ _("Couldn't detect Bash version, shell completion is not supported.")
323
+ )
324
+
325
+ def source(self) -> str:
326
+ self._check_version()
327
+ return super().source()
328
+
329
+ def get_completion_args(self) -> t.Tuple[t.List[str], str]:
330
+ cwords = split_arg_string(os.environ["COMP_WORDS"])
331
+ cword = int(os.environ["COMP_CWORD"])
332
+ args = cwords[1:cword]
333
+
334
+ try:
335
+ incomplete = cwords[cword]
336
+ except IndexError:
337
+ incomplete = ""
338
+
339
+ return args, incomplete
340
+
341
+ def format_completion(self, item: CompletionItem) -> str:
342
+ return f"{item.type},{item.value}"
343
+
344
+
345
+ class ZshComplete(ShellComplete):
346
+ """Shell completion for Zsh."""
347
+
348
+ name = "zsh"
349
+ source_template = _SOURCE_ZSH
350
+
351
+ def get_completion_args(self) -> t.Tuple[t.List[str], str]:
352
+ cwords = split_arg_string(os.environ["COMP_WORDS"])
353
+ cword = int(os.environ["COMP_CWORD"])
354
+ args = cwords[1:cword]
355
+
356
+ try:
357
+ incomplete = cwords[cword]
358
+ except IndexError:
359
+ incomplete = ""
360
+
361
+ return args, incomplete
362
+
363
+ def format_completion(self, item: CompletionItem) -> str:
364
+ return f"{item.type}\n{item.value}\n{item.help if item.help else '_'}"
365
+
366
+
367
+ class FishComplete(ShellComplete):
368
+ """Shell completion for Fish."""
369
+
370
+ name = "fish"
371
+ source_template = _SOURCE_FISH
372
+
373
+ def get_completion_args(self) -> t.Tuple[t.List[str], str]:
374
+ cwords = split_arg_string(os.environ["COMP_WORDS"])
375
+ incomplete = os.environ["COMP_CWORD"]
376
+ args = cwords[1:]
377
+
378
+ # Fish stores the partial word in both COMP_WORDS and
379
+ # COMP_CWORD, remove it from complete args.
380
+ if incomplete and args and args[-1] == incomplete:
381
+ args.pop()
382
+
383
+ return args, incomplete
384
+
385
+ def format_completion(self, item: CompletionItem) -> str:
386
+ if item.help:
387
+ return f"{item.type},{item.value}\t{item.help}"
388
+
389
+ return f"{item.type},{item.value}"
390
+
391
+
392
+ _available_shells: t.Dict[str, t.Type[ShellComplete]] = {
393
+ "bash": BashComplete,
394
+ "fish": FishComplete,
395
+ "zsh": ZshComplete,
396
+ }
397
+
398
+
399
+ def add_completion_class(
400
+ cls: t.Type[ShellComplete], name: t.Optional[str] = None
401
+ ) -> None:
402
+ """Register a :class:`ShellComplete` subclass under the given name.
403
+ The name will be provided by the completion instruction environment
404
+ variable during completion.
405
+
406
+ :param cls: The completion class that will handle completion for the
407
+ shell.
408
+ :param name: Name to register the class under. Defaults to the
409
+ class's ``name`` attribute.
410
+ """
411
+ if name is None:
412
+ name = cls.name
413
+
414
+ _available_shells[name] = cls
415
+
416
+
417
+ def get_completion_class(shell: str) -> t.Optional[t.Type[ShellComplete]]:
418
+ """Look up a registered :class:`ShellComplete` subclass by the name
419
+ provided by the completion instruction environment variable. If the
420
+ name isn't registered, returns ``None``.
421
+
422
+ :param shell: Name the class is registered under.
423
+ """
424
+ return _available_shells.get(shell)
425
+
426
+
427
+ def _is_incomplete_argument(ctx: Context, param: Parameter) -> bool:
428
+ """Determine if the given parameter is an argument that can still
429
+ accept values.
430
+
431
+ :param ctx: Invocation context for the command represented by the
432
+ parsed complete args.
433
+ :param param: Argument object being checked.
434
+ """
435
+ if not isinstance(param, Argument):
436
+ return False
437
+
438
+ assert param.name is not None
439
+ value = ctx.params[param.name]
440
+ return (
441
+ param.nargs == -1
442
+ or ctx.get_parameter_source(param.name) is not ParameterSource.COMMANDLINE
443
+ or (
444
+ param.nargs > 1
445
+ and isinstance(value, (tuple, list))
446
+ and len(value) < param.nargs
447
+ )
448
+ )
449
+
450
+
451
+ def _start_of_option(ctx: Context, value: str) -> bool:
452
+ """Check if the value looks like the start of an option."""
453
+ if not value:
454
+ return False
455
+
456
+ c = value[0]
457
+ return c in ctx._opt_prefixes
458
+
459
+
460
+ def _is_incomplete_option(ctx: Context, args: t.List[str], param: Parameter) -> bool:
461
+ """Determine if the given parameter is an option that needs a value.
462
+
463
+ :param args: List of complete args before the incomplete value.
464
+ :param param: Option object being checked.
465
+ """
466
+ if not isinstance(param, Option):
467
+ return False
468
+
469
+ if param.is_flag or param.count:
470
+ return False
471
+
472
+ last_option = None
473
+
474
+ for index, arg in enumerate(reversed(args)):
475
+ if index + 1 > param.nargs:
476
+ break
477
+
478
+ if _start_of_option(ctx, arg):
479
+ last_option = arg
480
+
481
+ return last_option is not None and last_option in param.opts
482
+
483
+
484
+ def _resolve_context(
485
+ cli: BaseCommand, ctx_args: t.Dict[str, t.Any], prog_name: str, args: t.List[str]
486
+ ) -> Context:
487
+ """Produce the context hierarchy starting with the command and
488
+ traversing the complete arguments. This only follows the commands,
489
+ it doesn't trigger input prompts or callbacks.
490
+
491
+ :param cli: Command being called.
492
+ :param prog_name: Name of the executable in the shell.
493
+ :param args: List of complete args before the incomplete value.
494
+ """
495
+ ctx_args["resilient_parsing"] = True
496
+ ctx = cli.make_context(prog_name, args.copy(), **ctx_args)
497
+ args = ctx.protected_args + ctx.args
498
+
499
+ while args:
500
+ command = ctx.command
501
+
502
+ if isinstance(command, MultiCommand):
503
+ if not command.chain:
504
+ name, cmd, args = command.resolve_command(ctx, args)
505
+
506
+ if cmd is None:
507
+ return ctx
508
+
509
+ ctx = cmd.make_context(name, args, parent=ctx, resilient_parsing=True)
510
+ args = ctx.protected_args + ctx.args
511
+ else:
512
+ while args:
513
+ name, cmd, args = command.resolve_command(ctx, args)
514
+
515
+ if cmd is None:
516
+ return ctx
517
+
518
+ sub_ctx = cmd.make_context(
519
+ name,
520
+ args,
521
+ parent=ctx,
522
+ allow_extra_args=True,
523
+ allow_interspersed_args=False,
524
+ resilient_parsing=True,
525
+ )
526
+ args = sub_ctx.args
527
+
528
+ ctx = sub_ctx
529
+ args = [*sub_ctx.protected_args, *sub_ctx.args]
530
+ else:
531
+ break
532
+
533
+ return ctx
534
+
535
+
536
+ def _resolve_incomplete(
537
+ ctx: Context, args: t.List[str], incomplete: str
538
+ ) -> t.Tuple[t.Union[BaseCommand, Parameter], str]:
539
+ """Find the Click object that will handle the completion of the
540
+ incomplete value. Return the object and the incomplete value.
541
+
542
+ :param ctx: Invocation context for the command represented by
543
+ the parsed complete args.
544
+ :param args: List of complete args before the incomplete value.
545
+ :param incomplete: Value being completed. May be empty.
546
+ """
547
+ # Different shells treat an "=" between a long option name and
548
+ # value differently. Might keep the value joined, return the "="
549
+ # as a separate item, or return the split name and value. Always
550
+ # split and discard the "=" to make completion easier.
551
+ if incomplete == "=":
552
+ incomplete = ""
553
+ elif "=" in incomplete and _start_of_option(ctx, incomplete):
554
+ name, _, incomplete = incomplete.partition("=")
555
+ args.append(name)
556
+
557
+ # The "--" marker tells Click to stop treating values as options
558
+ # even if they start with the option character. If it hasn't been
559
+ # given and the incomplete arg looks like an option, the current
560
+ # command will provide option name completions.
561
+ if "--" not in args and _start_of_option(ctx, incomplete):
562
+ return ctx.command, incomplete
563
+
564
+ params = ctx.command.get_params(ctx)
565
+
566
+ # If the last complete arg is an option name with an incomplete
567
+ # value, the option will provide value completions.
568
+ for param in params:
569
+ if _is_incomplete_option(ctx, args, param):
570
+ return param, incomplete
571
+
572
+ # It's not an option name or value. The first argument without a
573
+ # parsed value will provide value completions.
574
+ for param in params:
575
+ if _is_incomplete_argument(ctx, param):
576
+ return param, incomplete
577
+
578
+ # There were no unparsed arguments, the command may be a group that
579
+ # will provide command name completions.
580
+ return ctx.command, incomplete
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/click/termui.py ADDED
@@ -0,0 +1,787 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import inspect
2
+ import io
3
+ import itertools
4
+ import os
5
+ import sys
6
+ import typing as t
7
+ from gettext import gettext as _
8
+
9
+ from ._compat import isatty
10
+ from ._compat import strip_ansi
11
+ from ._compat import WIN
12
+ from .exceptions import Abort
13
+ from .exceptions import UsageError
14
+ from .globals import resolve_color_default
15
+ from .types import Choice
16
+ from .types import convert_type
17
+ from .types import ParamType
18
+ from .utils import echo
19
+ from .utils import LazyFile
20
+
21
+ if t.TYPE_CHECKING:
22
+ from ._termui_impl import ProgressBar
23
+
24
+ V = t.TypeVar("V")
25
+
26
+ # The prompt functions to use. The doc tools currently override these
27
+ # functions to customize how they work.
28
+ visible_prompt_func: t.Callable[[str], str] = input
29
+
30
+ _ansi_colors = {
31
+ "black": 30,
32
+ "red": 31,
33
+ "green": 32,
34
+ "yellow": 33,
35
+ "blue": 34,
36
+ "magenta": 35,
37
+ "cyan": 36,
38
+ "white": 37,
39
+ "reset": 39,
40
+ "bright_black": 90,
41
+ "bright_red": 91,
42
+ "bright_green": 92,
43
+ "bright_yellow": 93,
44
+ "bright_blue": 94,
45
+ "bright_magenta": 95,
46
+ "bright_cyan": 96,
47
+ "bright_white": 97,
48
+ }
49
+ _ansi_reset_all = "\033[0m"
50
+
51
+
52
+ def hidden_prompt_func(prompt: str) -> str:
53
+ import getpass
54
+
55
+ return getpass.getpass(prompt)
56
+
57
+
58
+ def _build_prompt(
59
+ text: str,
60
+ suffix: str,
61
+ show_default: bool = False,
62
+ default: t.Optional[t.Any] = None,
63
+ show_choices: bool = True,
64
+ type: t.Optional[ParamType] = None,
65
+ ) -> str:
66
+ prompt = text
67
+ if type is not None and show_choices and isinstance(type, Choice):
68
+ prompt += f" ({', '.join(map(str, type.choices))})"
69
+ if default is not None and show_default:
70
+ prompt = f"{prompt} [{_format_default(default)}]"
71
+ return f"{prompt}{suffix}"
72
+
73
+
74
+ def _format_default(default: t.Any) -> t.Any:
75
+ if isinstance(default, (io.IOBase, LazyFile)) and hasattr(default, "name"):
76
+ return default.name # type: ignore
77
+
78
+ return default
79
+
80
+
81
+ def prompt(
82
+ text: str,
83
+ default: t.Optional[t.Any] = None,
84
+ hide_input: bool = False,
85
+ confirmation_prompt: t.Union[bool, str] = False,
86
+ type: t.Optional[t.Union[ParamType, t.Any]] = None,
87
+ value_proc: t.Optional[t.Callable[[str], t.Any]] = None,
88
+ prompt_suffix: str = ": ",
89
+ show_default: bool = True,
90
+ err: bool = False,
91
+ show_choices: bool = True,
92
+ ) -> t.Any:
93
+ """Prompts a user for input. This is a convenience function that can
94
+ be used to prompt a user for input later.
95
+
96
+ If the user aborts the input by sending an interrupt signal, this
97
+ function will catch it and raise a :exc:`Abort` exception.
98
+
99
+ :param text: the text to show for the prompt.
100
+ :param default: the default value to use if no input happens. If this
101
+ is not given it will prompt until it's aborted.
102
+ :param hide_input: if this is set to true then the input value will
103
+ be hidden.
104
+ :param confirmation_prompt: Prompt a second time to confirm the
105
+ value. Can be set to a string instead of ``True`` to customize
106
+ the message.
107
+ :param type: the type to use to check the value against.
108
+ :param value_proc: if this parameter is provided it's a function that
109
+ is invoked instead of the type conversion to
110
+ convert a value.
111
+ :param prompt_suffix: a suffix that should be added to the prompt.
112
+ :param show_default: shows or hides the default value in the prompt.
113
+ :param err: if set to true the file defaults to ``stderr`` instead of
114
+ ``stdout``, the same as with echo.
115
+ :param show_choices: Show or hide choices if the passed type is a Choice.
116
+ For example if type is a Choice of either day or week,
117
+ show_choices is true and text is "Group by" then the
118
+ prompt will be "Group by (day, week): ".
119
+
120
+ .. versionadded:: 8.0
121
+ ``confirmation_prompt`` can be a custom string.
122
+
123
+ .. versionadded:: 7.0
124
+ Added the ``show_choices`` parameter.
125
+
126
+ .. versionadded:: 6.0
127
+ Added unicode support for cmd.exe on Windows.
128
+
129
+ .. versionadded:: 4.0
130
+ Added the `err` parameter.
131
+
132
+ """
133
+
134
+ def prompt_func(text: str) -> str:
135
+ f = hidden_prompt_func if hide_input else visible_prompt_func
136
+ try:
137
+ # Write the prompt separately so that we get nice
138
+ # coloring through colorama on Windows
139
+ echo(text.rstrip(" "), nl=False, err=err)
140
+ # Echo a space to stdout to work around an issue where
141
+ # readline causes backspace to clear the whole line.
142
+ return f(" ")
143
+ except (KeyboardInterrupt, EOFError):
144
+ # getpass doesn't print a newline if the user aborts input with ^C.
145
+ # Allegedly this behavior is inherited from getpass(3).
146
+ # A doc bug has been filed at https://bugs.python.org/issue24711
147
+ if hide_input:
148
+ echo(None, err=err)
149
+ raise Abort() from None
150
+
151
+ if value_proc is None:
152
+ value_proc = convert_type(type, default)
153
+
154
+ prompt = _build_prompt(
155
+ text, prompt_suffix, show_default, default, show_choices, type
156
+ )
157
+
158
+ if confirmation_prompt:
159
+ if confirmation_prompt is True:
160
+ confirmation_prompt = _("Repeat for confirmation")
161
+
162
+ confirmation_prompt = _build_prompt(confirmation_prompt, prompt_suffix)
163
+
164
+ while True:
165
+ while True:
166
+ value = prompt_func(prompt)
167
+ if value:
168
+ break
169
+ elif default is not None:
170
+ value = default
171
+ break
172
+ try:
173
+ result = value_proc(value)
174
+ except UsageError as e:
175
+ if hide_input:
176
+ echo(_("Error: The value you entered was invalid."), err=err)
177
+ else:
178
+ echo(_("Error: {e.message}").format(e=e), err=err) # noqa: B306
179
+ continue
180
+ if not confirmation_prompt:
181
+ return result
182
+ while True:
183
+ value2 = prompt_func(confirmation_prompt)
184
+ is_empty = not value and not value2
185
+ if value2 or is_empty:
186
+ break
187
+ if value == value2:
188
+ return result
189
+ echo(_("Error: The two entered values do not match."), err=err)
190
+
191
+
192
+ def confirm(
193
+ text: str,
194
+ default: t.Optional[bool] = False,
195
+ abort: bool = False,
196
+ prompt_suffix: str = ": ",
197
+ show_default: bool = True,
198
+ err: bool = False,
199
+ ) -> bool:
200
+ """Prompts for confirmation (yes/no question).
201
+
202
+ If the user aborts the input by sending a interrupt signal this
203
+ function will catch it and raise a :exc:`Abort` exception.
204
+
205
+ :param text: the question to ask.
206
+ :param default: The default value to use when no input is given. If
207
+ ``None``, repeat until input is given.
208
+ :param abort: if this is set to `True` a negative answer aborts the
209
+ exception by raising :exc:`Abort`.
210
+ :param prompt_suffix: a suffix that should be added to the prompt.
211
+ :param show_default: shows or hides the default value in the prompt.
212
+ :param err: if set to true the file defaults to ``stderr`` instead of
213
+ ``stdout``, the same as with echo.
214
+
215
+ .. versionchanged:: 8.0
216
+ Repeat until input is given if ``default`` is ``None``.
217
+
218
+ .. versionadded:: 4.0
219
+ Added the ``err`` parameter.
220
+ """
221
+ prompt = _build_prompt(
222
+ text,
223
+ prompt_suffix,
224
+ show_default,
225
+ "y/n" if default is None else ("Y/n" if default else "y/N"),
226
+ )
227
+
228
+ while True:
229
+ try:
230
+ # Write the prompt separately so that we get nice
231
+ # coloring through colorama on Windows
232
+ echo(prompt.rstrip(" "), nl=False, err=err)
233
+ # Echo a space to stdout to work around an issue where
234
+ # readline causes backspace to clear the whole line.
235
+ value = visible_prompt_func(" ").lower().strip()
236
+ except (KeyboardInterrupt, EOFError):
237
+ raise Abort() from None
238
+ if value in ("y", "yes"):
239
+ rv = True
240
+ elif value in ("n", "no"):
241
+ rv = False
242
+ elif default is not None and value == "":
243
+ rv = default
244
+ else:
245
+ echo(_("Error: invalid input"), err=err)
246
+ continue
247
+ break
248
+ if abort and not rv:
249
+ raise Abort()
250
+ return rv
251
+
252
+
253
+ def echo_via_pager(
254
+ text_or_generator: t.Union[t.Iterable[str], t.Callable[[], t.Iterable[str]], str],
255
+ color: t.Optional[bool] = None,
256
+ ) -> None:
257
+ """This function takes a text and shows it via an environment specific
258
+ pager on stdout.
259
+
260
+ .. versionchanged:: 3.0
261
+ Added the `color` flag.
262
+
263
+ :param text_or_generator: the text to page, or alternatively, a
264
+ generator emitting the text to page.
265
+ :param color: controls if the pager supports ANSI colors or not. The
266
+ default is autodetection.
267
+ """
268
+ color = resolve_color_default(color)
269
+
270
+ if inspect.isgeneratorfunction(text_or_generator):
271
+ i = t.cast(t.Callable[[], t.Iterable[str]], text_or_generator)()
272
+ elif isinstance(text_or_generator, str):
273
+ i = [text_or_generator]
274
+ else:
275
+ i = iter(t.cast(t.Iterable[str], text_or_generator))
276
+
277
+ # convert every element of i to a text type if necessary
278
+ text_generator = (el if isinstance(el, str) else str(el) for el in i)
279
+
280
+ from ._termui_impl import pager
281
+
282
+ return pager(itertools.chain(text_generator, "\n"), color)
283
+
284
+
285
+ def progressbar(
286
+ iterable: t.Optional[t.Iterable[V]] = None,
287
+ length: t.Optional[int] = None,
288
+ label: t.Optional[str] = None,
289
+ show_eta: bool = True,
290
+ show_percent: t.Optional[bool] = None,
291
+ show_pos: bool = False,
292
+ item_show_func: t.Optional[t.Callable[[t.Optional[V]], t.Optional[str]]] = None,
293
+ fill_char: str = "#",
294
+ empty_char: str = "-",
295
+ bar_template: str = "%(label)s [%(bar)s] %(info)s",
296
+ info_sep: str = " ",
297
+ width: int = 36,
298
+ file: t.Optional[t.TextIO] = None,
299
+ color: t.Optional[bool] = None,
300
+ update_min_steps: int = 1,
301
+ ) -> "ProgressBar[V]":
302
+ """This function creates an iterable context manager that can be used
303
+ to iterate over something while showing a progress bar. It will
304
+ either iterate over the `iterable` or `length` items (that are counted
305
+ up). While iteration happens, this function will print a rendered
306
+ progress bar to the given `file` (defaults to stdout) and will attempt
307
+ to calculate remaining time and more. By default, this progress bar
308
+ will not be rendered if the file is not a terminal.
309
+
310
+ The context manager creates the progress bar. When the context
311
+ manager is entered the progress bar is already created. With every
312
+ iteration over the progress bar, the iterable passed to the bar is
313
+ advanced and the bar is updated. When the context manager exits,
314
+ a newline is printed and the progress bar is finalized on screen.
315
+
316
+ Note: The progress bar is currently designed for use cases where the
317
+ total progress can be expected to take at least several seconds.
318
+ Because of this, the ProgressBar class object won't display
319
+ progress that is considered too fast, and progress where the time
320
+ between steps is less than a second.
321
+
322
+ No printing must happen or the progress bar will be unintentionally
323
+ destroyed.
324
+
325
+ Example usage::
326
+
327
+ with progressbar(items) as bar:
328
+ for item in bar:
329
+ do_something_with(item)
330
+
331
+ Alternatively, if no iterable is specified, one can manually update the
332
+ progress bar through the `update()` method instead of directly
333
+ iterating over the progress bar. The update method accepts the number
334
+ of steps to increment the bar with::
335
+
336
+ with progressbar(length=chunks.total_bytes) as bar:
337
+ for chunk in chunks:
338
+ process_chunk(chunk)
339
+ bar.update(chunks.bytes)
340
+
341
+ The ``update()`` method also takes an optional value specifying the
342
+ ``current_item`` at the new position. This is useful when used
343
+ together with ``item_show_func`` to customize the output for each
344
+ manual step::
345
+
346
+ with click.progressbar(
347
+ length=total_size,
348
+ label='Unzipping archive',
349
+ item_show_func=lambda a: a.filename
350
+ ) as bar:
351
+ for archive in zip_file:
352
+ archive.extract()
353
+ bar.update(archive.size, archive)
354
+
355
+ :param iterable: an iterable to iterate over. If not provided the length
356
+ is required.
357
+ :param length: the number of items to iterate over. By default the
358
+ progressbar will attempt to ask the iterator about its
359
+ length, which might or might not work. If an iterable is
360
+ also provided this parameter can be used to override the
361
+ length. If an iterable is not provided the progress bar
362
+ will iterate over a range of that length.
363
+ :param label: the label to show next to the progress bar.
364
+ :param show_eta: enables or disables the estimated time display. This is
365
+ automatically disabled if the length cannot be
366
+ determined.
367
+ :param show_percent: enables or disables the percentage display. The
368
+ default is `True` if the iterable has a length or
369
+ `False` if not.
370
+ :param show_pos: enables or disables the absolute position display. The
371
+ default is `False`.
372
+ :param item_show_func: A function called with the current item which
373
+ can return a string to show next to the progress bar. If the
374
+ function returns ``None`` nothing is shown. The current item can
375
+ be ``None``, such as when entering and exiting the bar.
376
+ :param fill_char: the character to use to show the filled part of the
377
+ progress bar.
378
+ :param empty_char: the character to use to show the non-filled part of
379
+ the progress bar.
380
+ :param bar_template: the format string to use as template for the bar.
381
+ The parameters in it are ``label`` for the label,
382
+ ``bar`` for the progress bar and ``info`` for the
383
+ info section.
384
+ :param info_sep: the separator between multiple info items (eta etc.)
385
+ :param width: the width of the progress bar in characters, 0 means full
386
+ terminal width
387
+ :param file: The file to write to. If this is not a terminal then
388
+ only the label is printed.
389
+ :param color: controls if the terminal supports ANSI colors or not. The
390
+ default is autodetection. This is only needed if ANSI
391
+ codes are included anywhere in the progress bar output
392
+ which is not the case by default.
393
+ :param update_min_steps: Render only when this many updates have
394
+ completed. This allows tuning for very fast iterators.
395
+
396
+ .. versionchanged:: 8.0
397
+ Output is shown even if execution time is less than 0.5 seconds.
398
+
399
+ .. versionchanged:: 8.0
400
+ ``item_show_func`` shows the current item, not the previous one.
401
+
402
+ .. versionchanged:: 8.0
403
+ Labels are echoed if the output is not a TTY. Reverts a change
404
+ in 7.0 that removed all output.
405
+
406
+ .. versionadded:: 8.0
407
+ Added the ``update_min_steps`` parameter.
408
+
409
+ .. versionchanged:: 4.0
410
+ Added the ``color`` parameter. Added the ``update`` method to
411
+ the object.
412
+
413
+ .. versionadded:: 2.0
414
+ """
415
+ from ._termui_impl import ProgressBar
416
+
417
+ color = resolve_color_default(color)
418
+ return ProgressBar(
419
+ iterable=iterable,
420
+ length=length,
421
+ show_eta=show_eta,
422
+ show_percent=show_percent,
423
+ show_pos=show_pos,
424
+ item_show_func=item_show_func,
425
+ fill_char=fill_char,
426
+ empty_char=empty_char,
427
+ bar_template=bar_template,
428
+ info_sep=info_sep,
429
+ file=file,
430
+ label=label,
431
+ width=width,
432
+ color=color,
433
+ update_min_steps=update_min_steps,
434
+ )
435
+
436
+
437
+ def clear() -> None:
438
+ """Clears the terminal screen. This will have the effect of clearing
439
+ the whole visible space of the terminal and moving the cursor to the
440
+ top left. This does not do anything if not connected to a terminal.
441
+
442
+ .. versionadded:: 2.0
443
+ """
444
+ if not isatty(sys.stdout):
445
+ return
446
+ if WIN:
447
+ os.system("cls")
448
+ else:
449
+ sys.stdout.write("\033[2J\033[1;1H")
450
+
451
+
452
+ def _interpret_color(
453
+ color: t.Union[int, t.Tuple[int, int, int], str], offset: int = 0
454
+ ) -> str:
455
+ if isinstance(color, int):
456
+ return f"{38 + offset};5;{color:d}"
457
+
458
+ if isinstance(color, (tuple, list)):
459
+ r, g, b = color
460
+ return f"{38 + offset};2;{r:d};{g:d};{b:d}"
461
+
462
+ return str(_ansi_colors[color] + offset)
463
+
464
+
465
+ def style(
466
+ text: t.Any,
467
+ fg: t.Optional[t.Union[int, t.Tuple[int, int, int], str]] = None,
468
+ bg: t.Optional[t.Union[int, t.Tuple[int, int, int], str]] = None,
469
+ bold: t.Optional[bool] = None,
470
+ dim: t.Optional[bool] = None,
471
+ underline: t.Optional[bool] = None,
472
+ overline: t.Optional[bool] = None,
473
+ italic: t.Optional[bool] = None,
474
+ blink: t.Optional[bool] = None,
475
+ reverse: t.Optional[bool] = None,
476
+ strikethrough: t.Optional[bool] = None,
477
+ reset: bool = True,
478
+ ) -> str:
479
+ """Styles a text with ANSI styles and returns the new string. By
480
+ default the styling is self contained which means that at the end
481
+ of the string a reset code is issued. This can be prevented by
482
+ passing ``reset=False``.
483
+
484
+ Examples::
485
+
486
+ click.echo(click.style('Hello World!', fg='green'))
487
+ click.echo(click.style('ATTENTION!', blink=True))
488
+ click.echo(click.style('Some things', reverse=True, fg='cyan'))
489
+ click.echo(click.style('More colors', fg=(255, 12, 128), bg=117))
490
+
491
+ Supported color names:
492
+
493
+ * ``black`` (might be a gray)
494
+ * ``red``
495
+ * ``green``
496
+ * ``yellow`` (might be an orange)
497
+ * ``blue``
498
+ * ``magenta``
499
+ * ``cyan``
500
+ * ``white`` (might be light gray)
501
+ * ``bright_black``
502
+ * ``bright_red``
503
+ * ``bright_green``
504
+ * ``bright_yellow``
505
+ * ``bright_blue``
506
+ * ``bright_magenta``
507
+ * ``bright_cyan``
508
+ * ``bright_white``
509
+ * ``reset`` (reset the color code only)
510
+
511
+ If the terminal supports it, color may also be specified as:
512
+
513
+ - An integer in the interval [0, 255]. The terminal must support
514
+ 8-bit/256-color mode.
515
+ - An RGB tuple of three integers in [0, 255]. The terminal must
516
+ support 24-bit/true-color mode.
517
+
518
+ See https://en.wikipedia.org/wiki/ANSI_color and
519
+ https://gist.github.com/XVilka/8346728 for more information.
520
+
521
+ :param text: the string to style with ansi codes.
522
+ :param fg: if provided this will become the foreground color.
523
+ :param bg: if provided this will become the background color.
524
+ :param bold: if provided this will enable or disable bold mode.
525
+ :param dim: if provided this will enable or disable dim mode. This is
526
+ badly supported.
527
+ :param underline: if provided this will enable or disable underline.
528
+ :param overline: if provided this will enable or disable overline.
529
+ :param italic: if provided this will enable or disable italic.
530
+ :param blink: if provided this will enable or disable blinking.
531
+ :param reverse: if provided this will enable or disable inverse
532
+ rendering (foreground becomes background and the
533
+ other way round).
534
+ :param strikethrough: if provided this will enable or disable
535
+ striking through text.
536
+ :param reset: by default a reset-all code is added at the end of the
537
+ string which means that styles do not carry over. This
538
+ can be disabled to compose styles.
539
+
540
+ .. versionchanged:: 8.0
541
+ A non-string ``message`` is converted to a string.
542
+
543
+ .. versionchanged:: 8.0
544
+ Added support for 256 and RGB color codes.
545
+
546
+ .. versionchanged:: 8.0
547
+ Added the ``strikethrough``, ``italic``, and ``overline``
548
+ parameters.
549
+
550
+ .. versionchanged:: 7.0
551
+ Added support for bright colors.
552
+
553
+ .. versionadded:: 2.0
554
+ """
555
+ if not isinstance(text, str):
556
+ text = str(text)
557
+
558
+ bits = []
559
+
560
+ if fg:
561
+ try:
562
+ bits.append(f"\033[{_interpret_color(fg)}m")
563
+ except KeyError:
564
+ raise TypeError(f"Unknown color {fg!r}") from None
565
+
566
+ if bg:
567
+ try:
568
+ bits.append(f"\033[{_interpret_color(bg, 10)}m")
569
+ except KeyError:
570
+ raise TypeError(f"Unknown color {bg!r}") from None
571
+
572
+ if bold is not None:
573
+ bits.append(f"\033[{1 if bold else 22}m")
574
+ if dim is not None:
575
+ bits.append(f"\033[{2 if dim else 22}m")
576
+ if underline is not None:
577
+ bits.append(f"\033[{4 if underline else 24}m")
578
+ if overline is not None:
579
+ bits.append(f"\033[{53 if overline else 55}m")
580
+ if italic is not None:
581
+ bits.append(f"\033[{3 if italic else 23}m")
582
+ if blink is not None:
583
+ bits.append(f"\033[{5 if blink else 25}m")
584
+ if reverse is not None:
585
+ bits.append(f"\033[{7 if reverse else 27}m")
586
+ if strikethrough is not None:
587
+ bits.append(f"\033[{9 if strikethrough else 29}m")
588
+ bits.append(text)
589
+ if reset:
590
+ bits.append(_ansi_reset_all)
591
+ return "".join(bits)
592
+
593
+
594
+ def unstyle(text: str) -> str:
595
+ """Removes ANSI styling information from a string. Usually it's not
596
+ necessary to use this function as Click's echo function will
597
+ automatically remove styling if necessary.
598
+
599
+ .. versionadded:: 2.0
600
+
601
+ :param text: the text to remove style information from.
602
+ """
603
+ return strip_ansi(text)
604
+
605
+
606
+ def secho(
607
+ message: t.Optional[t.Any] = None,
608
+ file: t.Optional[t.IO[t.AnyStr]] = None,
609
+ nl: bool = True,
610
+ err: bool = False,
611
+ color: t.Optional[bool] = None,
612
+ **styles: t.Any,
613
+ ) -> None:
614
+ """This function combines :func:`echo` and :func:`style` into one
615
+ call. As such the following two calls are the same::
616
+
617
+ click.secho('Hello World!', fg='green')
618
+ click.echo(click.style('Hello World!', fg='green'))
619
+
620
+ All keyword arguments are forwarded to the underlying functions
621
+ depending on which one they go with.
622
+
623
+ Non-string types will be converted to :class:`str`. However,
624
+ :class:`bytes` are passed directly to :meth:`echo` without applying
625
+ style. If you want to style bytes that represent text, call
626
+ :meth:`bytes.decode` first.
627
+
628
+ .. versionchanged:: 8.0
629
+ A non-string ``message`` is converted to a string. Bytes are
630
+ passed through without style applied.
631
+
632
+ .. versionadded:: 2.0
633
+ """
634
+ if message is not None and not isinstance(message, (bytes, bytearray)):
635
+ message = style(message, **styles)
636
+
637
+ return echo(message, file=file, nl=nl, err=err, color=color)
638
+
639
+
640
+ def edit(
641
+ text: t.Optional[t.AnyStr] = None,
642
+ editor: t.Optional[str] = None,
643
+ env: t.Optional[t.Mapping[str, str]] = None,
644
+ require_save: bool = True,
645
+ extension: str = ".txt",
646
+ filename: t.Optional[str] = None,
647
+ ) -> t.Optional[t.AnyStr]:
648
+ r"""Edits the given text in the defined editor. If an editor is given
649
+ (should be the full path to the executable but the regular operating
650
+ system search path is used for finding the executable) it overrides
651
+ the detected editor. Optionally, some environment variables can be
652
+ used. If the editor is closed without changes, `None` is returned. In
653
+ case a file is edited directly the return value is always `None` and
654
+ `require_save` and `extension` are ignored.
655
+
656
+ If the editor cannot be opened a :exc:`UsageError` is raised.
657
+
658
+ Note for Windows: to simplify cross-platform usage, the newlines are
659
+ automatically converted from POSIX to Windows and vice versa. As such,
660
+ the message here will have ``\n`` as newline markers.
661
+
662
+ :param text: the text to edit.
663
+ :param editor: optionally the editor to use. Defaults to automatic
664
+ detection.
665
+ :param env: environment variables to forward to the editor.
666
+ :param require_save: if this is true, then not saving in the editor
667
+ will make the return value become `None`.
668
+ :param extension: the extension to tell the editor about. This defaults
669
+ to `.txt` but changing this might change syntax
670
+ highlighting.
671
+ :param filename: if provided it will edit this file instead of the
672
+ provided text contents. It will not use a temporary
673
+ file as an indirection in that case.
674
+ """
675
+ from ._termui_impl import Editor
676
+
677
+ ed = Editor(editor=editor, env=env, require_save=require_save, extension=extension)
678
+
679
+ if filename is None:
680
+ return ed.edit(text)
681
+
682
+ ed.edit_file(filename)
683
+ return None
684
+
685
+
686
+ def launch(url: str, wait: bool = False, locate: bool = False) -> int:
687
+ """This function launches the given URL (or filename) in the default
688
+ viewer application for this file type. If this is an executable, it
689
+ might launch the executable in a new session. The return value is
690
+ the exit code of the launched application. Usually, ``0`` indicates
691
+ success.
692
+
693
+ Examples::
694
+
695
+ click.launch('https://click.palletsprojects.com/')
696
+ click.launch('/my/downloaded/file', locate=True)
697
+
698
+ .. versionadded:: 2.0
699
+
700
+ :param url: URL or filename of the thing to launch.
701
+ :param wait: Wait for the program to exit before returning. This
702
+ only works if the launched program blocks. In particular,
703
+ ``xdg-open`` on Linux does not block.
704
+ :param locate: if this is set to `True` then instead of launching the
705
+ application associated with the URL it will attempt to
706
+ launch a file manager with the file located. This
707
+ might have weird effects if the URL does not point to
708
+ the filesystem.
709
+ """
710
+ from ._termui_impl import open_url
711
+
712
+ return open_url(url, wait=wait, locate=locate)
713
+
714
+
715
+ # If this is provided, getchar() calls into this instead. This is used
716
+ # for unittesting purposes.
717
+ _getchar: t.Optional[t.Callable[[bool], str]] = None
718
+
719
+
720
+ def getchar(echo: bool = False) -> str:
721
+ """Fetches a single character from the terminal and returns it. This
722
+ will always return a unicode character and under certain rare
723
+ circumstances this might return more than one character. The
724
+ situations which more than one character is returned is when for
725
+ whatever reason multiple characters end up in the terminal buffer or
726
+ standard input was not actually a terminal.
727
+
728
+ Note that this will always read from the terminal, even if something
729
+ is piped into the standard input.
730
+
731
+ Note for Windows: in rare cases when typing non-ASCII characters, this
732
+ function might wait for a second character and then return both at once.
733
+ This is because certain Unicode characters look like special-key markers.
734
+
735
+ .. versionadded:: 2.0
736
+
737
+ :param echo: if set to `True`, the character read will also show up on
738
+ the terminal. The default is to not show it.
739
+ """
740
+ global _getchar
741
+
742
+ if _getchar is None:
743
+ from ._termui_impl import getchar as f
744
+
745
+ _getchar = f
746
+
747
+ return _getchar(echo)
748
+
749
+
750
+ def raw_terminal() -> t.ContextManager[int]:
751
+ from ._termui_impl import raw_terminal as f
752
+
753
+ return f()
754
+
755
+
756
+ def pause(info: t.Optional[str] = None, err: bool = False) -> None:
757
+ """This command stops execution and waits for the user to press any
758
+ key to continue. This is similar to the Windows batch "pause"
759
+ command. If the program is not run through a terminal, this command
760
+ will instead do nothing.
761
+
762
+ .. versionadded:: 2.0
763
+
764
+ .. versionadded:: 4.0
765
+ Added the `err` parameter.
766
+
767
+ :param info: The message to print before pausing. Defaults to
768
+ ``"Press any key to continue..."``.
769
+ :param err: if set to message goes to ``stderr`` instead of
770
+ ``stdout``, the same as with echo.
771
+ """
772
+ if not isatty(sys.stdin) or not isatty(sys.stdout):
773
+ return
774
+
775
+ if info is None:
776
+ info = _("Press any key to continue...")
777
+
778
+ try:
779
+ if info:
780
+ echo(info, nl=False, err=err)
781
+ try:
782
+ getchar()
783
+ except (KeyboardInterrupt, EOFError):
784
+ pass
785
+ finally:
786
+ if info:
787
+ echo(err=err)
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/click/testing.py ADDED
@@ -0,0 +1,479 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import contextlib
2
+ import io
3
+ import os
4
+ import shlex
5
+ import shutil
6
+ import sys
7
+ import tempfile
8
+ import typing as t
9
+ from types import TracebackType
10
+
11
+ from . import formatting
12
+ from . import termui
13
+ from . import utils
14
+ from ._compat import _find_binary_reader
15
+
16
+ if t.TYPE_CHECKING:
17
+ from .core import BaseCommand
18
+
19
+
20
+ class EchoingStdin:
21
+ def __init__(self, input: t.BinaryIO, output: t.BinaryIO) -> None:
22
+ self._input = input
23
+ self._output = output
24
+ self._paused = False
25
+
26
+ def __getattr__(self, x: str) -> t.Any:
27
+ return getattr(self._input, x)
28
+
29
+ def _echo(self, rv: bytes) -> bytes:
30
+ if not self._paused:
31
+ self._output.write(rv)
32
+
33
+ return rv
34
+
35
+ def read(self, n: int = -1) -> bytes:
36
+ return self._echo(self._input.read(n))
37
+
38
+ def read1(self, n: int = -1) -> bytes:
39
+ return self._echo(self._input.read1(n)) # type: ignore
40
+
41
+ def readline(self, n: int = -1) -> bytes:
42
+ return self._echo(self._input.readline(n))
43
+
44
+ def readlines(self) -> t.List[bytes]:
45
+ return [self._echo(x) for x in self._input.readlines()]
46
+
47
+ def __iter__(self) -> t.Iterator[bytes]:
48
+ return iter(self._echo(x) for x in self._input)
49
+
50
+ def __repr__(self) -> str:
51
+ return repr(self._input)
52
+
53
+
54
+ @contextlib.contextmanager
55
+ def _pause_echo(stream: t.Optional[EchoingStdin]) -> t.Iterator[None]:
56
+ if stream is None:
57
+ yield
58
+ else:
59
+ stream._paused = True
60
+ yield
61
+ stream._paused = False
62
+
63
+
64
+ class _NamedTextIOWrapper(io.TextIOWrapper):
65
+ def __init__(
66
+ self, buffer: t.BinaryIO, name: str, mode: str, **kwargs: t.Any
67
+ ) -> None:
68
+ super().__init__(buffer, **kwargs)
69
+ self._name = name
70
+ self._mode = mode
71
+
72
+ @property
73
+ def name(self) -> str:
74
+ return self._name
75
+
76
+ @property
77
+ def mode(self) -> str:
78
+ return self._mode
79
+
80
+
81
+ def make_input_stream(
82
+ input: t.Optional[t.Union[str, bytes, t.IO]], charset: str
83
+ ) -> t.BinaryIO:
84
+ # Is already an input stream.
85
+ if hasattr(input, "read"):
86
+ rv = _find_binary_reader(t.cast(t.IO, input))
87
+
88
+ if rv is not None:
89
+ return rv
90
+
91
+ raise TypeError("Could not find binary reader for input stream.")
92
+
93
+ if input is None:
94
+ input = b""
95
+ elif isinstance(input, str):
96
+ input = input.encode(charset)
97
+
98
+ return io.BytesIO(t.cast(bytes, input))
99
+
100
+
101
+ class Result:
102
+ """Holds the captured result of an invoked CLI script."""
103
+
104
+ def __init__(
105
+ self,
106
+ runner: "CliRunner",
107
+ stdout_bytes: bytes,
108
+ stderr_bytes: t.Optional[bytes],
109
+ return_value: t.Any,
110
+ exit_code: int,
111
+ exception: t.Optional[BaseException],
112
+ exc_info: t.Optional[
113
+ t.Tuple[t.Type[BaseException], BaseException, TracebackType]
114
+ ] = None,
115
+ ):
116
+ #: The runner that created the result
117
+ self.runner = runner
118
+ #: The standard output as bytes.
119
+ self.stdout_bytes = stdout_bytes
120
+ #: The standard error as bytes, or None if not available
121
+ self.stderr_bytes = stderr_bytes
122
+ #: The value returned from the invoked command.
123
+ #:
124
+ #: .. versionadded:: 8.0
125
+ self.return_value = return_value
126
+ #: The exit code as integer.
127
+ self.exit_code = exit_code
128
+ #: The exception that happened if one did.
129
+ self.exception = exception
130
+ #: The traceback
131
+ self.exc_info = exc_info
132
+
133
+ @property
134
+ def output(self) -> str:
135
+ """The (standard) output as unicode string."""
136
+ return self.stdout
137
+
138
+ @property
139
+ def stdout(self) -> str:
140
+ """The standard output as unicode string."""
141
+ return self.stdout_bytes.decode(self.runner.charset, "replace").replace(
142
+ "\r\n", "\n"
143
+ )
144
+
145
+ @property
146
+ def stderr(self) -> str:
147
+ """The standard error as unicode string."""
148
+ if self.stderr_bytes is None:
149
+ raise ValueError("stderr not separately captured")
150
+ return self.stderr_bytes.decode(self.runner.charset, "replace").replace(
151
+ "\r\n", "\n"
152
+ )
153
+
154
+ def __repr__(self) -> str:
155
+ exc_str = repr(self.exception) if self.exception else "okay"
156
+ return f"<{type(self).__name__} {exc_str}>"
157
+
158
+
159
+ class CliRunner:
160
+ """The CLI runner provides functionality to invoke a Click command line
161
+ script for unittesting purposes in a isolated environment. This only
162
+ works in single-threaded systems without any concurrency as it changes the
163
+ global interpreter state.
164
+
165
+ :param charset: the character set for the input and output data.
166
+ :param env: a dictionary with environment variables for overriding.
167
+ :param echo_stdin: if this is set to `True`, then reading from stdin writes
168
+ to stdout. This is useful for showing examples in
169
+ some circumstances. Note that regular prompts
170
+ will automatically echo the input.
171
+ :param mix_stderr: if this is set to `False`, then stdout and stderr are
172
+ preserved as independent streams. This is useful for
173
+ Unix-philosophy apps that have predictable stdout and
174
+ noisy stderr, such that each may be measured
175
+ independently
176
+ """
177
+
178
+ def __init__(
179
+ self,
180
+ charset: str = "utf-8",
181
+ env: t.Optional[t.Mapping[str, t.Optional[str]]] = None,
182
+ echo_stdin: bool = False,
183
+ mix_stderr: bool = True,
184
+ ) -> None:
185
+ self.charset = charset
186
+ self.env = env or {}
187
+ self.echo_stdin = echo_stdin
188
+ self.mix_stderr = mix_stderr
189
+
190
+ def get_default_prog_name(self, cli: "BaseCommand") -> str:
191
+ """Given a command object it will return the default program name
192
+ for it. The default is the `name` attribute or ``"root"`` if not
193
+ set.
194
+ """
195
+ return cli.name or "root"
196
+
197
+ def make_env(
198
+ self, overrides: t.Optional[t.Mapping[str, t.Optional[str]]] = None
199
+ ) -> t.Mapping[str, t.Optional[str]]:
200
+ """Returns the environment overrides for invoking a script."""
201
+ rv = dict(self.env)
202
+ if overrides:
203
+ rv.update(overrides)
204
+ return rv
205
+
206
+ @contextlib.contextmanager
207
+ def isolation(
208
+ self,
209
+ input: t.Optional[t.Union[str, bytes, t.IO]] = None,
210
+ env: t.Optional[t.Mapping[str, t.Optional[str]]] = None,
211
+ color: bool = False,
212
+ ) -> t.Iterator[t.Tuple[io.BytesIO, t.Optional[io.BytesIO]]]:
213
+ """A context manager that sets up the isolation for invoking of a
214
+ command line tool. This sets up stdin with the given input data
215
+ and `os.environ` with the overrides from the given dictionary.
216
+ This also rebinds some internals in Click to be mocked (like the
217
+ prompt functionality).
218
+
219
+ This is automatically done in the :meth:`invoke` method.
220
+
221
+ :param input: the input stream to put into sys.stdin.
222
+ :param env: the environment overrides as dictionary.
223
+ :param color: whether the output should contain color codes. The
224
+ application can still override this explicitly.
225
+
226
+ .. versionchanged:: 8.0
227
+ ``stderr`` is opened with ``errors="backslashreplace"``
228
+ instead of the default ``"strict"``.
229
+
230
+ .. versionchanged:: 4.0
231
+ Added the ``color`` parameter.
232
+ """
233
+ bytes_input = make_input_stream(input, self.charset)
234
+ echo_input = None
235
+
236
+ old_stdin = sys.stdin
237
+ old_stdout = sys.stdout
238
+ old_stderr = sys.stderr
239
+ old_forced_width = formatting.FORCED_WIDTH
240
+ formatting.FORCED_WIDTH = 80
241
+
242
+ env = self.make_env(env)
243
+
244
+ bytes_output = io.BytesIO()
245
+
246
+ if self.echo_stdin:
247
+ bytes_input = echo_input = t.cast(
248
+ t.BinaryIO, EchoingStdin(bytes_input, bytes_output)
249
+ )
250
+
251
+ sys.stdin = text_input = _NamedTextIOWrapper(
252
+ bytes_input, encoding=self.charset, name="<stdin>", mode="r"
253
+ )
254
+
255
+ if self.echo_stdin:
256
+ # Force unbuffered reads, otherwise TextIOWrapper reads a
257
+ # large chunk which is echoed early.
258
+ text_input._CHUNK_SIZE = 1 # type: ignore
259
+
260
+ sys.stdout = _NamedTextIOWrapper(
261
+ bytes_output, encoding=self.charset, name="<stdout>", mode="w"
262
+ )
263
+
264
+ bytes_error = None
265
+ if self.mix_stderr:
266
+ sys.stderr = sys.stdout
267
+ else:
268
+ bytes_error = io.BytesIO()
269
+ sys.stderr = _NamedTextIOWrapper(
270
+ bytes_error,
271
+ encoding=self.charset,
272
+ name="<stderr>",
273
+ mode="w",
274
+ errors="backslashreplace",
275
+ )
276
+
277
+ @_pause_echo(echo_input) # type: ignore
278
+ def visible_input(prompt: t.Optional[str] = None) -> str:
279
+ sys.stdout.write(prompt or "")
280
+ val = text_input.readline().rstrip("\r\n")
281
+ sys.stdout.write(f"{val}\n")
282
+ sys.stdout.flush()
283
+ return val
284
+
285
+ @_pause_echo(echo_input) # type: ignore
286
+ def hidden_input(prompt: t.Optional[str] = None) -> str:
287
+ sys.stdout.write(f"{prompt or ''}\n")
288
+ sys.stdout.flush()
289
+ return text_input.readline().rstrip("\r\n")
290
+
291
+ @_pause_echo(echo_input) # type: ignore
292
+ def _getchar(echo: bool) -> str:
293
+ char = sys.stdin.read(1)
294
+
295
+ if echo:
296
+ sys.stdout.write(char)
297
+
298
+ sys.stdout.flush()
299
+ return char
300
+
301
+ default_color = color
302
+
303
+ def should_strip_ansi(
304
+ stream: t.Optional[t.IO] = None, color: t.Optional[bool] = None
305
+ ) -> bool:
306
+ if color is None:
307
+ return not default_color
308
+ return not color
309
+
310
+ old_visible_prompt_func = termui.visible_prompt_func
311
+ old_hidden_prompt_func = termui.hidden_prompt_func
312
+ old__getchar_func = termui._getchar
313
+ old_should_strip_ansi = utils.should_strip_ansi # type: ignore
314
+ termui.visible_prompt_func = visible_input
315
+ termui.hidden_prompt_func = hidden_input
316
+ termui._getchar = _getchar
317
+ utils.should_strip_ansi = should_strip_ansi # type: ignore
318
+
319
+ old_env = {}
320
+ try:
321
+ for key, value in env.items():
322
+ old_env[key] = os.environ.get(key)
323
+ if value is None:
324
+ try:
325
+ del os.environ[key]
326
+ except Exception:
327
+ pass
328
+ else:
329
+ os.environ[key] = value
330
+ yield (bytes_output, bytes_error)
331
+ finally:
332
+ for key, value in old_env.items():
333
+ if value is None:
334
+ try:
335
+ del os.environ[key]
336
+ except Exception:
337
+ pass
338
+ else:
339
+ os.environ[key] = value
340
+ sys.stdout = old_stdout
341
+ sys.stderr = old_stderr
342
+ sys.stdin = old_stdin
343
+ termui.visible_prompt_func = old_visible_prompt_func
344
+ termui.hidden_prompt_func = old_hidden_prompt_func
345
+ termui._getchar = old__getchar_func
346
+ utils.should_strip_ansi = old_should_strip_ansi # type: ignore
347
+ formatting.FORCED_WIDTH = old_forced_width
348
+
349
+ def invoke(
350
+ self,
351
+ cli: "BaseCommand",
352
+ args: t.Optional[t.Union[str, t.Sequence[str]]] = None,
353
+ input: t.Optional[t.Union[str, bytes, t.IO]] = None,
354
+ env: t.Optional[t.Mapping[str, t.Optional[str]]] = None,
355
+ catch_exceptions: bool = True,
356
+ color: bool = False,
357
+ **extra: t.Any,
358
+ ) -> Result:
359
+ """Invokes a command in an isolated environment. The arguments are
360
+ forwarded directly to the command line script, the `extra` keyword
361
+ arguments are passed to the :meth:`~clickpkg.Command.main` function of
362
+ the command.
363
+
364
+ This returns a :class:`Result` object.
365
+
366
+ :param cli: the command to invoke
367
+ :param args: the arguments to invoke. It may be given as an iterable
368
+ or a string. When given as string it will be interpreted
369
+ as a Unix shell command. More details at
370
+ :func:`shlex.split`.
371
+ :param input: the input data for `sys.stdin`.
372
+ :param env: the environment overrides.
373
+ :param catch_exceptions: Whether to catch any other exceptions than
374
+ ``SystemExit``.
375
+ :param extra: the keyword arguments to pass to :meth:`main`.
376
+ :param color: whether the output should contain color codes. The
377
+ application can still override this explicitly.
378
+
379
+ .. versionchanged:: 8.0
380
+ The result object has the ``return_value`` attribute with
381
+ the value returned from the invoked command.
382
+
383
+ .. versionchanged:: 4.0
384
+ Added the ``color`` parameter.
385
+
386
+ .. versionchanged:: 3.0
387
+ Added the ``catch_exceptions`` parameter.
388
+
389
+ .. versionchanged:: 3.0
390
+ The result object has the ``exc_info`` attribute with the
391
+ traceback if available.
392
+ """
393
+ exc_info = None
394
+ with self.isolation(input=input, env=env, color=color) as outstreams:
395
+ return_value = None
396
+ exception: t.Optional[BaseException] = None
397
+ exit_code = 0
398
+
399
+ if isinstance(args, str):
400
+ args = shlex.split(args)
401
+
402
+ try:
403
+ prog_name = extra.pop("prog_name")
404
+ except KeyError:
405
+ prog_name = self.get_default_prog_name(cli)
406
+
407
+ try:
408
+ return_value = cli.main(args=args or (), prog_name=prog_name, **extra)
409
+ except SystemExit as e:
410
+ exc_info = sys.exc_info()
411
+ e_code = t.cast(t.Optional[t.Union[int, t.Any]], e.code)
412
+
413
+ if e_code is None:
414
+ e_code = 0
415
+
416
+ if e_code != 0:
417
+ exception = e
418
+
419
+ if not isinstance(e_code, int):
420
+ sys.stdout.write(str(e_code))
421
+ sys.stdout.write("\n")
422
+ e_code = 1
423
+
424
+ exit_code = e_code
425
+
426
+ except Exception as e:
427
+ if not catch_exceptions:
428
+ raise
429
+ exception = e
430
+ exit_code = 1
431
+ exc_info = sys.exc_info()
432
+ finally:
433
+ sys.stdout.flush()
434
+ stdout = outstreams[0].getvalue()
435
+ if self.mix_stderr:
436
+ stderr = None
437
+ else:
438
+ stderr = outstreams[1].getvalue() # type: ignore
439
+
440
+ return Result(
441
+ runner=self,
442
+ stdout_bytes=stdout,
443
+ stderr_bytes=stderr,
444
+ return_value=return_value,
445
+ exit_code=exit_code,
446
+ exception=exception,
447
+ exc_info=exc_info, # type: ignore
448
+ )
449
+
450
+ @contextlib.contextmanager
451
+ def isolated_filesystem(
452
+ self, temp_dir: t.Optional[t.Union[str, os.PathLike]] = None
453
+ ) -> t.Iterator[str]:
454
+ """A context manager that creates a temporary directory and
455
+ changes the current working directory to it. This isolates tests
456
+ that affect the contents of the CWD to prevent them from
457
+ interfering with each other.
458
+
459
+ :param temp_dir: Create the temporary directory under this
460
+ directory. If given, the created directory is not removed
461
+ when exiting.
462
+
463
+ .. versionchanged:: 8.0
464
+ Added the ``temp_dir`` parameter.
465
+ """
466
+ cwd = os.getcwd()
467
+ dt = tempfile.mkdtemp(dir=temp_dir) # type: ignore[type-var]
468
+ os.chdir(dt)
469
+
470
+ try:
471
+ yield t.cast(str, dt)
472
+ finally:
473
+ os.chdir(cwd)
474
+
475
+ if temp_dir is None:
476
+ try:
477
+ shutil.rmtree(dt)
478
+ except OSError: # noqa: B014
479
+ pass
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/click/types.py ADDED
@@ -0,0 +1,1073 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import stat
3
+ import typing as t
4
+ from datetime import datetime
5
+ from gettext import gettext as _
6
+ from gettext import ngettext
7
+
8
+ from ._compat import _get_argv_encoding
9
+ from ._compat import get_filesystem_encoding
10
+ from ._compat import open_stream
11
+ from .exceptions import BadParameter
12
+ from .utils import LazyFile
13
+ from .utils import safecall
14
+
15
+ if t.TYPE_CHECKING:
16
+ import typing_extensions as te
17
+ from .core import Context
18
+ from .core import Parameter
19
+ from .shell_completion import CompletionItem
20
+
21
+
22
+ class ParamType:
23
+ """Represents the type of a parameter. Validates and converts values
24
+ from the command line or Python into the correct type.
25
+
26
+ To implement a custom type, subclass and implement at least the
27
+ following:
28
+
29
+ - The :attr:`name` class attribute must be set.
30
+ - Calling an instance of the type with ``None`` must return
31
+ ``None``. This is already implemented by default.
32
+ - :meth:`convert` must convert string values to the correct type.
33
+ - :meth:`convert` must accept values that are already the correct
34
+ type.
35
+ - It must be able to convert a value if the ``ctx`` and ``param``
36
+ arguments are ``None``. This can occur when converting prompt
37
+ input.
38
+ """
39
+
40
+ is_composite: t.ClassVar[bool] = False
41
+ arity: t.ClassVar[int] = 1
42
+
43
+ #: the descriptive name of this type
44
+ name: str
45
+
46
+ #: if a list of this type is expected and the value is pulled from a
47
+ #: string environment variable, this is what splits it up. `None`
48
+ #: means any whitespace. For all parameters the general rule is that
49
+ #: whitespace splits them up. The exception are paths and files which
50
+ #: are split by ``os.path.pathsep`` by default (":" on Unix and ";" on
51
+ #: Windows).
52
+ envvar_list_splitter: t.ClassVar[t.Optional[str]] = None
53
+
54
+ def to_info_dict(self) -> t.Dict[str, t.Any]:
55
+ """Gather information that could be useful for a tool generating
56
+ user-facing documentation.
57
+
58
+ Use :meth:`click.Context.to_info_dict` to traverse the entire
59
+ CLI structure.
60
+
61
+ .. versionadded:: 8.0
62
+ """
63
+ # The class name without the "ParamType" suffix.
64
+ param_type = type(self).__name__.partition("ParamType")[0]
65
+ param_type = param_type.partition("ParameterType")[0]
66
+
67
+ # Custom subclasses might not remember to set a name.
68
+ if hasattr(self, "name"):
69
+ name = self.name
70
+ else:
71
+ name = param_type
72
+
73
+ return {"param_type": param_type, "name": name}
74
+
75
+ def __call__(
76
+ self,
77
+ value: t.Any,
78
+ param: t.Optional["Parameter"] = None,
79
+ ctx: t.Optional["Context"] = None,
80
+ ) -> t.Any:
81
+ if value is not None:
82
+ return self.convert(value, param, ctx)
83
+
84
+ def get_metavar(self, param: "Parameter") -> t.Optional[str]:
85
+ """Returns the metavar default for this param if it provides one."""
86
+
87
+ def get_missing_message(self, param: "Parameter") -> t.Optional[str]:
88
+ """Optionally might return extra information about a missing
89
+ parameter.
90
+
91
+ .. versionadded:: 2.0
92
+ """
93
+
94
+ def convert(
95
+ self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"]
96
+ ) -> t.Any:
97
+ """Convert the value to the correct type. This is not called if
98
+ the value is ``None`` (the missing value).
99
+
100
+ This must accept string values from the command line, as well as
101
+ values that are already the correct type. It may also convert
102
+ other compatible types.
103
+
104
+ The ``param`` and ``ctx`` arguments may be ``None`` in certain
105
+ situations, such as when converting prompt input.
106
+
107
+ If the value cannot be converted, call :meth:`fail` with a
108
+ descriptive message.
109
+
110
+ :param value: The value to convert.
111
+ :param param: The parameter that is using this type to convert
112
+ its value. May be ``None``.
113
+ :param ctx: The current context that arrived at this value. May
114
+ be ``None``.
115
+ """
116
+ return value
117
+
118
+ def split_envvar_value(self, rv: str) -> t.Sequence[str]:
119
+ """Given a value from an environment variable this splits it up
120
+ into small chunks depending on the defined envvar list splitter.
121
+
122
+ If the splitter is set to `None`, which means that whitespace splits,
123
+ then leading and trailing whitespace is ignored. Otherwise, leading
124
+ and trailing splitters usually lead to empty items being included.
125
+ """
126
+ return (rv or "").split(self.envvar_list_splitter)
127
+
128
+ def fail(
129
+ self,
130
+ message: str,
131
+ param: t.Optional["Parameter"] = None,
132
+ ctx: t.Optional["Context"] = None,
133
+ ) -> "t.NoReturn":
134
+ """Helper method to fail with an invalid value message."""
135
+ raise BadParameter(message, ctx=ctx, param=param)
136
+
137
+ def shell_complete(
138
+ self, ctx: "Context", param: "Parameter", incomplete: str
139
+ ) -> t.List["CompletionItem"]:
140
+ """Return a list of
141
+ :class:`~click.shell_completion.CompletionItem` objects for the
142
+ incomplete value. Most types do not provide completions, but
143
+ some do, and this allows custom types to provide custom
144
+ completions as well.
145
+
146
+ :param ctx: Invocation context for this command.
147
+ :param param: The parameter that is requesting completion.
148
+ :param incomplete: Value being completed. May be empty.
149
+
150
+ .. versionadded:: 8.0
151
+ """
152
+ return []
153
+
154
+
155
+ class CompositeParamType(ParamType):
156
+ is_composite = True
157
+
158
+ @property
159
+ def arity(self) -> int: # type: ignore
160
+ raise NotImplementedError()
161
+
162
+
163
+ class FuncParamType(ParamType):
164
+ def __init__(self, func: t.Callable[[t.Any], t.Any]) -> None:
165
+ self.name = func.__name__
166
+ self.func = func
167
+
168
+ def to_info_dict(self) -> t.Dict[str, t.Any]:
169
+ info_dict = super().to_info_dict()
170
+ info_dict["func"] = self.func
171
+ return info_dict
172
+
173
+ def convert(
174
+ self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"]
175
+ ) -> t.Any:
176
+ try:
177
+ return self.func(value)
178
+ except ValueError:
179
+ try:
180
+ value = str(value)
181
+ except UnicodeError:
182
+ value = value.decode("utf-8", "replace")
183
+
184
+ self.fail(value, param, ctx)
185
+
186
+
187
+ class UnprocessedParamType(ParamType):
188
+ name = "text"
189
+
190
+ def convert(
191
+ self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"]
192
+ ) -> t.Any:
193
+ return value
194
+
195
+ def __repr__(self) -> str:
196
+ return "UNPROCESSED"
197
+
198
+
199
+ class StringParamType(ParamType):
200
+ name = "text"
201
+
202
+ def convert(
203
+ self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"]
204
+ ) -> t.Any:
205
+ if isinstance(value, bytes):
206
+ enc = _get_argv_encoding()
207
+ try:
208
+ value = value.decode(enc)
209
+ except UnicodeError:
210
+ fs_enc = get_filesystem_encoding()
211
+ if fs_enc != enc:
212
+ try:
213
+ value = value.decode(fs_enc)
214
+ except UnicodeError:
215
+ value = value.decode("utf-8", "replace")
216
+ else:
217
+ value = value.decode("utf-8", "replace")
218
+ return value
219
+ return str(value)
220
+
221
+ def __repr__(self) -> str:
222
+ return "STRING"
223
+
224
+
225
+ class Choice(ParamType):
226
+ """The choice type allows a value to be checked against a fixed set
227
+ of supported values. All of these values have to be strings.
228
+
229
+ You should only pass a list or tuple of choices. Other iterables
230
+ (like generators) may lead to surprising results.
231
+
232
+ The resulting value will always be one of the originally passed choices
233
+ regardless of ``case_sensitive`` or any ``ctx.token_normalize_func``
234
+ being specified.
235
+
236
+ See :ref:`choice-opts` for an example.
237
+
238
+ :param case_sensitive: Set to false to make choices case
239
+ insensitive. Defaults to true.
240
+ """
241
+
242
+ name = "choice"
243
+
244
+ def __init__(self, choices: t.Sequence[str], case_sensitive: bool = True) -> None:
245
+ self.choices = choices
246
+ self.case_sensitive = case_sensitive
247
+
248
+ def to_info_dict(self) -> t.Dict[str, t.Any]:
249
+ info_dict = super().to_info_dict()
250
+ info_dict["choices"] = self.choices
251
+ info_dict["case_sensitive"] = self.case_sensitive
252
+ return info_dict
253
+
254
+ def get_metavar(self, param: "Parameter") -> str:
255
+ choices_str = "|".join(self.choices)
256
+
257
+ # Use curly braces to indicate a required argument.
258
+ if param.required and param.param_type_name == "argument":
259
+ return f"{{{choices_str}}}"
260
+
261
+ # Use square braces to indicate an option or optional argument.
262
+ return f"[{choices_str}]"
263
+
264
+ def get_missing_message(self, param: "Parameter") -> str:
265
+ return _("Choose from:\n\t{choices}").format(choices=",\n\t".join(self.choices))
266
+
267
+ def convert(
268
+ self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"]
269
+ ) -> t.Any:
270
+ # Match through normalization and case sensitivity
271
+ # first do token_normalize_func, then lowercase
272
+ # preserve original `value` to produce an accurate message in
273
+ # `self.fail`
274
+ normed_value = value
275
+ normed_choices = {choice: choice for choice in self.choices}
276
+
277
+ if ctx is not None and ctx.token_normalize_func is not None:
278
+ normed_value = ctx.token_normalize_func(value)
279
+ normed_choices = {
280
+ ctx.token_normalize_func(normed_choice): original
281
+ for normed_choice, original in normed_choices.items()
282
+ }
283
+
284
+ if not self.case_sensitive:
285
+ normed_value = normed_value.casefold()
286
+ normed_choices = {
287
+ normed_choice.casefold(): original
288
+ for normed_choice, original in normed_choices.items()
289
+ }
290
+
291
+ if normed_value in normed_choices:
292
+ return normed_choices[normed_value]
293
+
294
+ choices_str = ", ".join(map(repr, self.choices))
295
+ self.fail(
296
+ ngettext(
297
+ "{value!r} is not {choice}.",
298
+ "{value!r} is not one of {choices}.",
299
+ len(self.choices),
300
+ ).format(value=value, choice=choices_str, choices=choices_str),
301
+ param,
302
+ ctx,
303
+ )
304
+
305
+ def __repr__(self) -> str:
306
+ return f"Choice({list(self.choices)})"
307
+
308
+ def shell_complete(
309
+ self, ctx: "Context", param: "Parameter", incomplete: str
310
+ ) -> t.List["CompletionItem"]:
311
+ """Complete choices that start with the incomplete value.
312
+
313
+ :param ctx: Invocation context for this command.
314
+ :param param: The parameter that is requesting completion.
315
+ :param incomplete: Value being completed. May be empty.
316
+
317
+ .. versionadded:: 8.0
318
+ """
319
+ from click.shell_completion import CompletionItem
320
+
321
+ str_choices = map(str, self.choices)
322
+
323
+ if self.case_sensitive:
324
+ matched = (c for c in str_choices if c.startswith(incomplete))
325
+ else:
326
+ incomplete = incomplete.lower()
327
+ matched = (c for c in str_choices if c.lower().startswith(incomplete))
328
+
329
+ return [CompletionItem(c) for c in matched]
330
+
331
+
332
+ class DateTime(ParamType):
333
+ """The DateTime type converts date strings into `datetime` objects.
334
+
335
+ The format strings which are checked are configurable, but default to some
336
+ common (non-timezone aware) ISO 8601 formats.
337
+
338
+ When specifying *DateTime* formats, you should only pass a list or a tuple.
339
+ Other iterables, like generators, may lead to surprising results.
340
+
341
+ The format strings are processed using ``datetime.strptime``, and this
342
+ consequently defines the format strings which are allowed.
343
+
344
+ Parsing is tried using each format, in order, and the first format which
345
+ parses successfully is used.
346
+
347
+ :param formats: A list or tuple of date format strings, in the order in
348
+ which they should be tried. Defaults to
349
+ ``'%Y-%m-%d'``, ``'%Y-%m-%dT%H:%M:%S'``,
350
+ ``'%Y-%m-%d %H:%M:%S'``.
351
+ """
352
+
353
+ name = "datetime"
354
+
355
+ def __init__(self, formats: t.Optional[t.Sequence[str]] = None):
356
+ self.formats = formats or ["%Y-%m-%d", "%Y-%m-%dT%H:%M:%S", "%Y-%m-%d %H:%M:%S"]
357
+
358
+ def to_info_dict(self) -> t.Dict[str, t.Any]:
359
+ info_dict = super().to_info_dict()
360
+ info_dict["formats"] = self.formats
361
+ return info_dict
362
+
363
+ def get_metavar(self, param: "Parameter") -> str:
364
+ return f"[{'|'.join(self.formats)}]"
365
+
366
+ def _try_to_convert_date(self, value: t.Any, format: str) -> t.Optional[datetime]:
367
+ try:
368
+ return datetime.strptime(value, format)
369
+ except ValueError:
370
+ return None
371
+
372
+ def convert(
373
+ self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"]
374
+ ) -> t.Any:
375
+ if isinstance(value, datetime):
376
+ return value
377
+
378
+ for format in self.formats:
379
+ converted = self._try_to_convert_date(value, format)
380
+
381
+ if converted is not None:
382
+ return converted
383
+
384
+ formats_str = ", ".join(map(repr, self.formats))
385
+ self.fail(
386
+ ngettext(
387
+ "{value!r} does not match the format {format}.",
388
+ "{value!r} does not match the formats {formats}.",
389
+ len(self.formats),
390
+ ).format(value=value, format=formats_str, formats=formats_str),
391
+ param,
392
+ ctx,
393
+ )
394
+
395
+ def __repr__(self) -> str:
396
+ return "DateTime"
397
+
398
+
399
+ class _NumberParamTypeBase(ParamType):
400
+ _number_class: t.ClassVar[t.Type]
401
+
402
+ def convert(
403
+ self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"]
404
+ ) -> t.Any:
405
+ try:
406
+ return self._number_class(value)
407
+ except ValueError:
408
+ self.fail(
409
+ _("{value!r} is not a valid {number_type}.").format(
410
+ value=value, number_type=self.name
411
+ ),
412
+ param,
413
+ ctx,
414
+ )
415
+
416
+
417
+ class _NumberRangeBase(_NumberParamTypeBase):
418
+ def __init__(
419
+ self,
420
+ min: t.Optional[float] = None,
421
+ max: t.Optional[float] = None,
422
+ min_open: bool = False,
423
+ max_open: bool = False,
424
+ clamp: bool = False,
425
+ ) -> None:
426
+ self.min = min
427
+ self.max = max
428
+ self.min_open = min_open
429
+ self.max_open = max_open
430
+ self.clamp = clamp
431
+
432
+ def to_info_dict(self) -> t.Dict[str, t.Any]:
433
+ info_dict = super().to_info_dict()
434
+ info_dict.update(
435
+ min=self.min,
436
+ max=self.max,
437
+ min_open=self.min_open,
438
+ max_open=self.max_open,
439
+ clamp=self.clamp,
440
+ )
441
+ return info_dict
442
+
443
+ def convert(
444
+ self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"]
445
+ ) -> t.Any:
446
+ import operator
447
+
448
+ rv = super().convert(value, param, ctx)
449
+ lt_min: bool = self.min is not None and (
450
+ operator.le if self.min_open else operator.lt
451
+ )(rv, self.min)
452
+ gt_max: bool = self.max is not None and (
453
+ operator.ge if self.max_open else operator.gt
454
+ )(rv, self.max)
455
+
456
+ if self.clamp:
457
+ if lt_min:
458
+ return self._clamp(self.min, 1, self.min_open) # type: ignore
459
+
460
+ if gt_max:
461
+ return self._clamp(self.max, -1, self.max_open) # type: ignore
462
+
463
+ if lt_min or gt_max:
464
+ self.fail(
465
+ _("{value} is not in the range {range}.").format(
466
+ value=rv, range=self._describe_range()
467
+ ),
468
+ param,
469
+ ctx,
470
+ )
471
+
472
+ return rv
473
+
474
+ def _clamp(self, bound: float, dir: "te.Literal[1, -1]", open: bool) -> float:
475
+ """Find the valid value to clamp to bound in the given
476
+ direction.
477
+
478
+ :param bound: The boundary value.
479
+ :param dir: 1 or -1 indicating the direction to move.
480
+ :param open: If true, the range does not include the bound.
481
+ """
482
+ raise NotImplementedError
483
+
484
+ def _describe_range(self) -> str:
485
+ """Describe the range for use in help text."""
486
+ if self.min is None:
487
+ op = "<" if self.max_open else "<="
488
+ return f"x{op}{self.max}"
489
+
490
+ if self.max is None:
491
+ op = ">" if self.min_open else ">="
492
+ return f"x{op}{self.min}"
493
+
494
+ lop = "<" if self.min_open else "<="
495
+ rop = "<" if self.max_open else "<="
496
+ return f"{self.min}{lop}x{rop}{self.max}"
497
+
498
+ def __repr__(self) -> str:
499
+ clamp = " clamped" if self.clamp else ""
500
+ return f"<{type(self).__name__} {self._describe_range()}{clamp}>"
501
+
502
+
503
+ class IntParamType(_NumberParamTypeBase):
504
+ name = "integer"
505
+ _number_class = int
506
+
507
+ def __repr__(self) -> str:
508
+ return "INT"
509
+
510
+
511
+ class IntRange(_NumberRangeBase, IntParamType):
512
+ """Restrict an :data:`click.INT` value to a range of accepted
513
+ values. See :ref:`ranges`.
514
+
515
+ If ``min`` or ``max`` are not passed, any value is accepted in that
516
+ direction. If ``min_open`` or ``max_open`` are enabled, the
517
+ corresponding boundary is not included in the range.
518
+
519
+ If ``clamp`` is enabled, a value outside the range is clamped to the
520
+ boundary instead of failing.
521
+
522
+ .. versionchanged:: 8.0
523
+ Added the ``min_open`` and ``max_open`` parameters.
524
+ """
525
+
526
+ name = "integer range"
527
+
528
+ def _clamp( # type: ignore
529
+ self, bound: int, dir: "te.Literal[1, -1]", open: bool
530
+ ) -> int:
531
+ if not open:
532
+ return bound
533
+
534
+ return bound + dir
535
+
536
+
537
+ class FloatParamType(_NumberParamTypeBase):
538
+ name = "float"
539
+ _number_class = float
540
+
541
+ def __repr__(self) -> str:
542
+ return "FLOAT"
543
+
544
+
545
+ class FloatRange(_NumberRangeBase, FloatParamType):
546
+ """Restrict a :data:`click.FLOAT` value to a range of accepted
547
+ values. See :ref:`ranges`.
548
+
549
+ If ``min`` or ``max`` are not passed, any value is accepted in that
550
+ direction. If ``min_open`` or ``max_open`` are enabled, the
551
+ corresponding boundary is not included in the range.
552
+
553
+ If ``clamp`` is enabled, a value outside the range is clamped to the
554
+ boundary instead of failing. This is not supported if either
555
+ boundary is marked ``open``.
556
+
557
+ .. versionchanged:: 8.0
558
+ Added the ``min_open`` and ``max_open`` parameters.
559
+ """
560
+
561
+ name = "float range"
562
+
563
+ def __init__(
564
+ self,
565
+ min: t.Optional[float] = None,
566
+ max: t.Optional[float] = None,
567
+ min_open: bool = False,
568
+ max_open: bool = False,
569
+ clamp: bool = False,
570
+ ) -> None:
571
+ super().__init__(
572
+ min=min, max=max, min_open=min_open, max_open=max_open, clamp=clamp
573
+ )
574
+
575
+ if (min_open or max_open) and clamp:
576
+ raise TypeError("Clamping is not supported for open bounds.")
577
+
578
+ def _clamp(self, bound: float, dir: "te.Literal[1, -1]", open: bool) -> float:
579
+ if not open:
580
+ return bound
581
+
582
+ # Could use Python 3.9's math.nextafter here, but clamping an
583
+ # open float range doesn't seem to be particularly useful. It's
584
+ # left up to the user to write a callback to do it if needed.
585
+ raise RuntimeError("Clamping is not supported for open bounds.")
586
+
587
+
588
+ class BoolParamType(ParamType):
589
+ name = "boolean"
590
+
591
+ def convert(
592
+ self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"]
593
+ ) -> t.Any:
594
+ if value in {False, True}:
595
+ return bool(value)
596
+
597
+ norm = value.strip().lower()
598
+
599
+ if norm in {"1", "true", "t", "yes", "y", "on"}:
600
+ return True
601
+
602
+ if norm in {"0", "false", "f", "no", "n", "off"}:
603
+ return False
604
+
605
+ self.fail(
606
+ _("{value!r} is not a valid boolean.").format(value=value), param, ctx
607
+ )
608
+
609
+ def __repr__(self) -> str:
610
+ return "BOOL"
611
+
612
+
613
+ class UUIDParameterType(ParamType):
614
+ name = "uuid"
615
+
616
+ def convert(
617
+ self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"]
618
+ ) -> t.Any:
619
+ import uuid
620
+
621
+ if isinstance(value, uuid.UUID):
622
+ return value
623
+
624
+ value = value.strip()
625
+
626
+ try:
627
+ return uuid.UUID(value)
628
+ except ValueError:
629
+ self.fail(
630
+ _("{value!r} is not a valid UUID.").format(value=value), param, ctx
631
+ )
632
+
633
+ def __repr__(self) -> str:
634
+ return "UUID"
635
+
636
+
637
+ class File(ParamType):
638
+ """Declares a parameter to be a file for reading or writing. The file
639
+ is automatically closed once the context tears down (after the command
640
+ finished working).
641
+
642
+ Files can be opened for reading or writing. The special value ``-``
643
+ indicates stdin or stdout depending on the mode.
644
+
645
+ By default, the file is opened for reading text data, but it can also be
646
+ opened in binary mode or for writing. The encoding parameter can be used
647
+ to force a specific encoding.
648
+
649
+ The `lazy` flag controls if the file should be opened immediately or upon
650
+ first IO. The default is to be non-lazy for standard input and output
651
+ streams as well as files opened for reading, `lazy` otherwise. When opening a
652
+ file lazily for reading, it is still opened temporarily for validation, but
653
+ will not be held open until first IO. lazy is mainly useful when opening
654
+ for writing to avoid creating the file until it is needed.
655
+
656
+ Starting with Click 2.0, files can also be opened atomically in which
657
+ case all writes go into a separate file in the same folder and upon
658
+ completion the file will be moved over to the original location. This
659
+ is useful if a file regularly read by other users is modified.
660
+
661
+ See :ref:`file-args` for more information.
662
+ """
663
+
664
+ name = "filename"
665
+ envvar_list_splitter = os.path.pathsep
666
+
667
+ def __init__(
668
+ self,
669
+ mode: str = "r",
670
+ encoding: t.Optional[str] = None,
671
+ errors: t.Optional[str] = "strict",
672
+ lazy: t.Optional[bool] = None,
673
+ atomic: bool = False,
674
+ ) -> None:
675
+ self.mode = mode
676
+ self.encoding = encoding
677
+ self.errors = errors
678
+ self.lazy = lazy
679
+ self.atomic = atomic
680
+
681
+ def to_info_dict(self) -> t.Dict[str, t.Any]:
682
+ info_dict = super().to_info_dict()
683
+ info_dict.update(mode=self.mode, encoding=self.encoding)
684
+ return info_dict
685
+
686
+ def resolve_lazy_flag(self, value: t.Any) -> bool:
687
+ if self.lazy is not None:
688
+ return self.lazy
689
+ if value == "-":
690
+ return False
691
+ elif "w" in self.mode:
692
+ return True
693
+ return False
694
+
695
+ def convert(
696
+ self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"]
697
+ ) -> t.Any:
698
+ try:
699
+ if hasattr(value, "read") or hasattr(value, "write"):
700
+ return value
701
+
702
+ lazy = self.resolve_lazy_flag(value)
703
+
704
+ if lazy:
705
+ f: t.IO = t.cast(
706
+ t.IO,
707
+ LazyFile(
708
+ value, self.mode, self.encoding, self.errors, atomic=self.atomic
709
+ ),
710
+ )
711
+
712
+ if ctx is not None:
713
+ ctx.call_on_close(f.close_intelligently) # type: ignore
714
+
715
+ return f
716
+
717
+ f, should_close = open_stream(
718
+ value, self.mode, self.encoding, self.errors, atomic=self.atomic
719
+ )
720
+
721
+ # If a context is provided, we automatically close the file
722
+ # at the end of the context execution (or flush out). If a
723
+ # context does not exist, it's the caller's responsibility to
724
+ # properly close the file. This for instance happens when the
725
+ # type is used with prompts.
726
+ if ctx is not None:
727
+ if should_close:
728
+ ctx.call_on_close(safecall(f.close))
729
+ else:
730
+ ctx.call_on_close(safecall(f.flush))
731
+
732
+ return f
733
+ except OSError as e: # noqa: B014
734
+ self.fail(f"'{os.fsdecode(value)}': {e.strerror}", param, ctx)
735
+
736
+ def shell_complete(
737
+ self, ctx: "Context", param: "Parameter", incomplete: str
738
+ ) -> t.List["CompletionItem"]:
739
+ """Return a special completion marker that tells the completion
740
+ system to use the shell to provide file path completions.
741
+
742
+ :param ctx: Invocation context for this command.
743
+ :param param: The parameter that is requesting completion.
744
+ :param incomplete: Value being completed. May be empty.
745
+
746
+ .. versionadded:: 8.0
747
+ """
748
+ from click.shell_completion import CompletionItem
749
+
750
+ return [CompletionItem(incomplete, type="file")]
751
+
752
+
753
+ class Path(ParamType):
754
+ """The ``Path`` type is similar to the :class:`File` type, but
755
+ returns the filename instead of an open file. Various checks can be
756
+ enabled to validate the type of file and permissions.
757
+
758
+ :param exists: The file or directory needs to exist for the value to
759
+ be valid. If this is not set to ``True``, and the file does not
760
+ exist, then all further checks are silently skipped.
761
+ :param file_okay: Allow a file as a value.
762
+ :param dir_okay: Allow a directory as a value.
763
+ :param readable: if true, a readable check is performed.
764
+ :param writable: if true, a writable check is performed.
765
+ :param executable: if true, an executable check is performed.
766
+ :param resolve_path: Make the value absolute and resolve any
767
+ symlinks. A ``~`` is not expanded, as this is supposed to be
768
+ done by the shell only.
769
+ :param allow_dash: Allow a single dash as a value, which indicates
770
+ a standard stream (but does not open it). Use
771
+ :func:`~click.open_file` to handle opening this value.
772
+ :param path_type: Convert the incoming path value to this type. If
773
+ ``None``, keep Python's default, which is ``str``. Useful to
774
+ convert to :class:`pathlib.Path`.
775
+
776
+ .. versionchanged:: 8.1
777
+ Added the ``executable`` parameter.
778
+
779
+ .. versionchanged:: 8.0
780
+ Allow passing ``type=pathlib.Path``.
781
+
782
+ .. versionchanged:: 6.0
783
+ Added the ``allow_dash`` parameter.
784
+ """
785
+
786
+ envvar_list_splitter = os.path.pathsep
787
+
788
+ def __init__(
789
+ self,
790
+ exists: bool = False,
791
+ file_okay: bool = True,
792
+ dir_okay: bool = True,
793
+ writable: bool = False,
794
+ readable: bool = True,
795
+ resolve_path: bool = False,
796
+ allow_dash: bool = False,
797
+ path_type: t.Optional[t.Type] = None,
798
+ executable: bool = False,
799
+ ):
800
+ self.exists = exists
801
+ self.file_okay = file_okay
802
+ self.dir_okay = dir_okay
803
+ self.readable = readable
804
+ self.writable = writable
805
+ self.executable = executable
806
+ self.resolve_path = resolve_path
807
+ self.allow_dash = allow_dash
808
+ self.type = path_type
809
+
810
+ if self.file_okay and not self.dir_okay:
811
+ self.name = _("file")
812
+ elif self.dir_okay and not self.file_okay:
813
+ self.name = _("directory")
814
+ else:
815
+ self.name = _("path")
816
+
817
+ def to_info_dict(self) -> t.Dict[str, t.Any]:
818
+ info_dict = super().to_info_dict()
819
+ info_dict.update(
820
+ exists=self.exists,
821
+ file_okay=self.file_okay,
822
+ dir_okay=self.dir_okay,
823
+ writable=self.writable,
824
+ readable=self.readable,
825
+ allow_dash=self.allow_dash,
826
+ )
827
+ return info_dict
828
+
829
+ def coerce_path_result(self, rv: t.Any) -> t.Any:
830
+ if self.type is not None and not isinstance(rv, self.type):
831
+ if self.type is str:
832
+ rv = os.fsdecode(rv)
833
+ elif self.type is bytes:
834
+ rv = os.fsencode(rv)
835
+ else:
836
+ rv = self.type(rv)
837
+
838
+ return rv
839
+
840
+ def convert(
841
+ self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"]
842
+ ) -> t.Any:
843
+ rv = value
844
+
845
+ is_dash = self.file_okay and self.allow_dash and rv in (b"-", "-")
846
+
847
+ if not is_dash:
848
+ if self.resolve_path:
849
+ # os.path.realpath doesn't resolve symlinks on Windows
850
+ # until Python 3.8. Use pathlib for now.
851
+ import pathlib
852
+
853
+ rv = os.fsdecode(pathlib.Path(rv).resolve())
854
+
855
+ try:
856
+ st = os.stat(rv)
857
+ except OSError:
858
+ if not self.exists:
859
+ return self.coerce_path_result(rv)
860
+ self.fail(
861
+ _("{name} {filename!r} does not exist.").format(
862
+ name=self.name.title(), filename=os.fsdecode(value)
863
+ ),
864
+ param,
865
+ ctx,
866
+ )
867
+
868
+ if not self.file_okay and stat.S_ISREG(st.st_mode):
869
+ self.fail(
870
+ _("{name} {filename!r} is a file.").format(
871
+ name=self.name.title(), filename=os.fsdecode(value)
872
+ ),
873
+ param,
874
+ ctx,
875
+ )
876
+ if not self.dir_okay and stat.S_ISDIR(st.st_mode):
877
+ self.fail(
878
+ _("{name} '{filename}' is a directory.").format(
879
+ name=self.name.title(), filename=os.fsdecode(value)
880
+ ),
881
+ param,
882
+ ctx,
883
+ )
884
+
885
+ if self.readable and not os.access(rv, os.R_OK):
886
+ self.fail(
887
+ _("{name} {filename!r} is not readable.").format(
888
+ name=self.name.title(), filename=os.fsdecode(value)
889
+ ),
890
+ param,
891
+ ctx,
892
+ )
893
+
894
+ if self.writable and not os.access(rv, os.W_OK):
895
+ self.fail(
896
+ _("{name} {filename!r} is not writable.").format(
897
+ name=self.name.title(), filename=os.fsdecode(value)
898
+ ),
899
+ param,
900
+ ctx,
901
+ )
902
+
903
+ if self.executable and not os.access(value, os.X_OK):
904
+ self.fail(
905
+ _("{name} {filename!r} is not executable.").format(
906
+ name=self.name.title(), filename=os.fsdecode(value)
907
+ ),
908
+ param,
909
+ ctx,
910
+ )
911
+
912
+ return self.coerce_path_result(rv)
913
+
914
+ def shell_complete(
915
+ self, ctx: "Context", param: "Parameter", incomplete: str
916
+ ) -> t.List["CompletionItem"]:
917
+ """Return a special completion marker that tells the completion
918
+ system to use the shell to provide path completions for only
919
+ directories or any paths.
920
+
921
+ :param ctx: Invocation context for this command.
922
+ :param param: The parameter that is requesting completion.
923
+ :param incomplete: Value being completed. May be empty.
924
+
925
+ .. versionadded:: 8.0
926
+ """
927
+ from click.shell_completion import CompletionItem
928
+
929
+ type = "dir" if self.dir_okay and not self.file_okay else "file"
930
+ return [CompletionItem(incomplete, type=type)]
931
+
932
+
933
+ class Tuple(CompositeParamType):
934
+ """The default behavior of Click is to apply a type on a value directly.
935
+ This works well in most cases, except for when `nargs` is set to a fixed
936
+ count and different types should be used for different items. In this
937
+ case the :class:`Tuple` type can be used. This type can only be used
938
+ if `nargs` is set to a fixed number.
939
+
940
+ For more information see :ref:`tuple-type`.
941
+
942
+ This can be selected by using a Python tuple literal as a type.
943
+
944
+ :param types: a list of types that should be used for the tuple items.
945
+ """
946
+
947
+ def __init__(self, types: t.Sequence[t.Union[t.Type, ParamType]]) -> None:
948
+ self.types = [convert_type(ty) for ty in types]
949
+
950
+ def to_info_dict(self) -> t.Dict[str, t.Any]:
951
+ info_dict = super().to_info_dict()
952
+ info_dict["types"] = [t.to_info_dict() for t in self.types]
953
+ return info_dict
954
+
955
+ @property
956
+ def name(self) -> str: # type: ignore
957
+ return f"<{' '.join(ty.name for ty in self.types)}>"
958
+
959
+ @property
960
+ def arity(self) -> int: # type: ignore
961
+ return len(self.types)
962
+
963
+ def convert(
964
+ self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"]
965
+ ) -> t.Any:
966
+ len_type = len(self.types)
967
+ len_value = len(value)
968
+
969
+ if len_value != len_type:
970
+ self.fail(
971
+ ngettext(
972
+ "{len_type} values are required, but {len_value} was given.",
973
+ "{len_type} values are required, but {len_value} were given.",
974
+ len_value,
975
+ ).format(len_type=len_type, len_value=len_value),
976
+ param=param,
977
+ ctx=ctx,
978
+ )
979
+
980
+ return tuple(ty(x, param, ctx) for ty, x in zip(self.types, value))
981
+
982
+
983
+ def convert_type(ty: t.Optional[t.Any], default: t.Optional[t.Any] = None) -> ParamType:
984
+ """Find the most appropriate :class:`ParamType` for the given Python
985
+ type. If the type isn't provided, it can be inferred from a default
986
+ value.
987
+ """
988
+ guessed_type = False
989
+
990
+ if ty is None and default is not None:
991
+ if isinstance(default, (tuple, list)):
992
+ # If the default is empty, ty will remain None and will
993
+ # return STRING.
994
+ if default:
995
+ item = default[0]
996
+
997
+ # A tuple of tuples needs to detect the inner types.
998
+ # Can't call convert recursively because that would
999
+ # incorrectly unwind the tuple to a single type.
1000
+ if isinstance(item, (tuple, list)):
1001
+ ty = tuple(map(type, item))
1002
+ else:
1003
+ ty = type(item)
1004
+ else:
1005
+ ty = type(default)
1006
+
1007
+ guessed_type = True
1008
+
1009
+ if isinstance(ty, tuple):
1010
+ return Tuple(ty)
1011
+
1012
+ if isinstance(ty, ParamType):
1013
+ return ty
1014
+
1015
+ if ty is str or ty is None:
1016
+ return STRING
1017
+
1018
+ if ty is int:
1019
+ return INT
1020
+
1021
+ if ty is float:
1022
+ return FLOAT
1023
+
1024
+ if ty is bool:
1025
+ return BOOL
1026
+
1027
+ if guessed_type:
1028
+ return STRING
1029
+
1030
+ if __debug__:
1031
+ try:
1032
+ if issubclass(ty, ParamType):
1033
+ raise AssertionError(
1034
+ f"Attempted to use an uninstantiated parameter type ({ty})."
1035
+ )
1036
+ except TypeError:
1037
+ # ty is an instance (correct), so issubclass fails.
1038
+ pass
1039
+
1040
+ return FuncParamType(ty)
1041
+
1042
+
1043
+ #: A dummy parameter type that just does nothing. From a user's
1044
+ #: perspective this appears to just be the same as `STRING` but
1045
+ #: internally no string conversion takes place if the input was bytes.
1046
+ #: This is usually useful when working with file paths as they can
1047
+ #: appear in bytes and unicode.
1048
+ #:
1049
+ #: For path related uses the :class:`Path` type is a better choice but
1050
+ #: there are situations where an unprocessed type is useful which is why
1051
+ #: it is is provided.
1052
+ #:
1053
+ #: .. versionadded:: 4.0
1054
+ UNPROCESSED = UnprocessedParamType()
1055
+
1056
+ #: A unicode string parameter type which is the implicit default. This
1057
+ #: can also be selected by using ``str`` as type.
1058
+ STRING = StringParamType()
1059
+
1060
+ #: An integer parameter. This can also be selected by using ``int`` as
1061
+ #: type.
1062
+ INT = IntParamType()
1063
+
1064
+ #: A floating point value parameter. This can also be selected by using
1065
+ #: ``float`` as type.
1066
+ FLOAT = FloatParamType()
1067
+
1068
+ #: A boolean parameter. This is the default for boolean flags. This can
1069
+ #: also be selected by using ``bool`` as a type.
1070
+ BOOL = BoolParamType()
1071
+
1072
+ #: A UUID parameter.
1073
+ UUID = UUIDParameterType()
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/click/utils.py ADDED
@@ -0,0 +1,580 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import re
3
+ import sys
4
+ import typing as t
5
+ from functools import update_wrapper
6
+ from types import ModuleType
7
+
8
+ from ._compat import _default_text_stderr
9
+ from ._compat import _default_text_stdout
10
+ from ._compat import _find_binary_writer
11
+ from ._compat import auto_wrap_for_ansi
12
+ from ._compat import binary_streams
13
+ from ._compat import get_filesystem_encoding
14
+ from ._compat import open_stream
15
+ from ._compat import should_strip_ansi
16
+ from ._compat import strip_ansi
17
+ from ._compat import text_streams
18
+ from ._compat import WIN
19
+ from .globals import resolve_color_default
20
+
21
+ if t.TYPE_CHECKING:
22
+ import typing_extensions as te
23
+
24
+ F = t.TypeVar("F", bound=t.Callable[..., t.Any])
25
+
26
+
27
+ def _posixify(name: str) -> str:
28
+ return "-".join(name.split()).lower()
29
+
30
+
31
+ def safecall(func: F) -> F:
32
+ """Wraps a function so that it swallows exceptions."""
33
+
34
+ def wrapper(*args, **kwargs): # type: ignore
35
+ try:
36
+ return func(*args, **kwargs)
37
+ except Exception:
38
+ pass
39
+
40
+ return update_wrapper(t.cast(F, wrapper), func)
41
+
42
+
43
+ def make_str(value: t.Any) -> str:
44
+ """Converts a value into a valid string."""
45
+ if isinstance(value, bytes):
46
+ try:
47
+ return value.decode(get_filesystem_encoding())
48
+ except UnicodeError:
49
+ return value.decode("utf-8", "replace")
50
+ return str(value)
51
+
52
+
53
+ def make_default_short_help(help: str, max_length: int = 45) -> str:
54
+ """Returns a condensed version of help string."""
55
+ # Consider only the first paragraph.
56
+ paragraph_end = help.find("\n\n")
57
+
58
+ if paragraph_end != -1:
59
+ help = help[:paragraph_end]
60
+
61
+ # Collapse newlines, tabs, and spaces.
62
+ words = help.split()
63
+
64
+ if not words:
65
+ return ""
66
+
67
+ # The first paragraph started with a "no rewrap" marker, ignore it.
68
+ if words[0] == "\b":
69
+ words = words[1:]
70
+
71
+ total_length = 0
72
+ last_index = len(words) - 1
73
+
74
+ for i, word in enumerate(words):
75
+ total_length += len(word) + (i > 0)
76
+
77
+ if total_length > max_length: # too long, truncate
78
+ break
79
+
80
+ if word[-1] == ".": # sentence end, truncate without "..."
81
+ return " ".join(words[: i + 1])
82
+
83
+ if total_length == max_length and i != last_index:
84
+ break # not at sentence end, truncate with "..."
85
+ else:
86
+ return " ".join(words) # no truncation needed
87
+
88
+ # Account for the length of the suffix.
89
+ total_length += len("...")
90
+
91
+ # remove words until the length is short enough
92
+ while i > 0:
93
+ total_length -= len(words[i]) + (i > 0)
94
+
95
+ if total_length <= max_length:
96
+ break
97
+
98
+ i -= 1
99
+
100
+ return " ".join(words[:i]) + "..."
101
+
102
+
103
+ class LazyFile:
104
+ """A lazy file works like a regular file but it does not fully open
105
+ the file but it does perform some basic checks early to see if the
106
+ filename parameter does make sense. This is useful for safely opening
107
+ files for writing.
108
+ """
109
+
110
+ def __init__(
111
+ self,
112
+ filename: str,
113
+ mode: str = "r",
114
+ encoding: t.Optional[str] = None,
115
+ errors: t.Optional[str] = "strict",
116
+ atomic: bool = False,
117
+ ):
118
+ self.name = filename
119
+ self.mode = mode
120
+ self.encoding = encoding
121
+ self.errors = errors
122
+ self.atomic = atomic
123
+ self._f: t.Optional[t.IO]
124
+
125
+ if filename == "-":
126
+ self._f, self.should_close = open_stream(filename, mode, encoding, errors)
127
+ else:
128
+ if "r" in mode:
129
+ # Open and close the file in case we're opening it for
130
+ # reading so that we can catch at least some errors in
131
+ # some cases early.
132
+ open(filename, mode).close()
133
+ self._f = None
134
+ self.should_close = True
135
+
136
+ def __getattr__(self, name: str) -> t.Any:
137
+ return getattr(self.open(), name)
138
+
139
+ def __repr__(self) -> str:
140
+ if self._f is not None:
141
+ return repr(self._f)
142
+ return f"<unopened file '{self.name}' {self.mode}>"
143
+
144
+ def open(self) -> t.IO:
145
+ """Opens the file if it's not yet open. This call might fail with
146
+ a :exc:`FileError`. Not handling this error will produce an error
147
+ that Click shows.
148
+ """
149
+ if self._f is not None:
150
+ return self._f
151
+ try:
152
+ rv, self.should_close = open_stream(
153
+ self.name, self.mode, self.encoding, self.errors, atomic=self.atomic
154
+ )
155
+ except OSError as e: # noqa: E402
156
+ from .exceptions import FileError
157
+
158
+ raise FileError(self.name, hint=e.strerror) from e
159
+ self._f = rv
160
+ return rv
161
+
162
+ def close(self) -> None:
163
+ """Closes the underlying file, no matter what."""
164
+ if self._f is not None:
165
+ self._f.close()
166
+
167
+ def close_intelligently(self) -> None:
168
+ """This function only closes the file if it was opened by the lazy
169
+ file wrapper. For instance this will never close stdin.
170
+ """
171
+ if self.should_close:
172
+ self.close()
173
+
174
+ def __enter__(self) -> "LazyFile":
175
+ return self
176
+
177
+ def __exit__(self, exc_type, exc_value, tb): # type: ignore
178
+ self.close_intelligently()
179
+
180
+ def __iter__(self) -> t.Iterator[t.AnyStr]:
181
+ self.open()
182
+ return iter(self._f) # type: ignore
183
+
184
+
185
+ class KeepOpenFile:
186
+ def __init__(self, file: t.IO) -> None:
187
+ self._file = file
188
+
189
+ def __getattr__(self, name: str) -> t.Any:
190
+ return getattr(self._file, name)
191
+
192
+ def __enter__(self) -> "KeepOpenFile":
193
+ return self
194
+
195
+ def __exit__(self, exc_type, exc_value, tb): # type: ignore
196
+ pass
197
+
198
+ def __repr__(self) -> str:
199
+ return repr(self._file)
200
+
201
+ def __iter__(self) -> t.Iterator[t.AnyStr]:
202
+ return iter(self._file)
203
+
204
+
205
+ def echo(
206
+ message: t.Optional[t.Any] = None,
207
+ file: t.Optional[t.IO[t.Any]] = None,
208
+ nl: bool = True,
209
+ err: bool = False,
210
+ color: t.Optional[bool] = None,
211
+ ) -> None:
212
+ """Print a message and newline to stdout or a file. This should be
213
+ used instead of :func:`print` because it provides better support
214
+ for different data, files, and environments.
215
+
216
+ Compared to :func:`print`, this does the following:
217
+
218
+ - Ensures that the output encoding is not misconfigured on Linux.
219
+ - Supports Unicode in the Windows console.
220
+ - Supports writing to binary outputs, and supports writing bytes
221
+ to text outputs.
222
+ - Supports colors and styles on Windows.
223
+ - Removes ANSI color and style codes if the output does not look
224
+ like an interactive terminal.
225
+ - Always flushes the output.
226
+
227
+ :param message: The string or bytes to output. Other objects are
228
+ converted to strings.
229
+ :param file: The file to write to. Defaults to ``stdout``.
230
+ :param err: Write to ``stderr`` instead of ``stdout``.
231
+ :param nl: Print a newline after the message. Enabled by default.
232
+ :param color: Force showing or hiding colors and other styles. By
233
+ default Click will remove color if the output does not look like
234
+ an interactive terminal.
235
+
236
+ .. versionchanged:: 6.0
237
+ Support Unicode output on the Windows console. Click does not
238
+ modify ``sys.stdout``, so ``sys.stdout.write()`` and ``print()``
239
+ will still not support Unicode.
240
+
241
+ .. versionchanged:: 4.0
242
+ Added the ``color`` parameter.
243
+
244
+ .. versionadded:: 3.0
245
+ Added the ``err`` parameter.
246
+
247
+ .. versionchanged:: 2.0
248
+ Support colors on Windows if colorama is installed.
249
+ """
250
+ if file is None:
251
+ if err:
252
+ file = _default_text_stderr()
253
+ else:
254
+ file = _default_text_stdout()
255
+
256
+ # Convert non bytes/text into the native string type.
257
+ if message is not None and not isinstance(message, (str, bytes, bytearray)):
258
+ out: t.Optional[t.Union[str, bytes]] = str(message)
259
+ else:
260
+ out = message
261
+
262
+ if nl:
263
+ out = out or ""
264
+ if isinstance(out, str):
265
+ out += "\n"
266
+ else:
267
+ out += b"\n"
268
+
269
+ if not out:
270
+ file.flush()
271
+ return
272
+
273
+ # If there is a message and the value looks like bytes, we manually
274
+ # need to find the binary stream and write the message in there.
275
+ # This is done separately so that most stream types will work as you
276
+ # would expect. Eg: you can write to StringIO for other cases.
277
+ if isinstance(out, (bytes, bytearray)):
278
+ binary_file = _find_binary_writer(file)
279
+
280
+ if binary_file is not None:
281
+ file.flush()
282
+ binary_file.write(out)
283
+ binary_file.flush()
284
+ return
285
+
286
+ # ANSI style code support. For no message or bytes, nothing happens.
287
+ # When outputting to a file instead of a terminal, strip codes.
288
+ else:
289
+ color = resolve_color_default(color)
290
+
291
+ if should_strip_ansi(file, color):
292
+ out = strip_ansi(out)
293
+ elif WIN:
294
+ if auto_wrap_for_ansi is not None:
295
+ file = auto_wrap_for_ansi(file) # type: ignore
296
+ elif not color:
297
+ out = strip_ansi(out)
298
+
299
+ file.write(out) # type: ignore
300
+ file.flush()
301
+
302
+
303
+ def get_binary_stream(name: "te.Literal['stdin', 'stdout', 'stderr']") -> t.BinaryIO:
304
+ """Returns a system stream for byte processing.
305
+
306
+ :param name: the name of the stream to open. Valid names are ``'stdin'``,
307
+ ``'stdout'`` and ``'stderr'``
308
+ """
309
+ opener = binary_streams.get(name)
310
+ if opener is None:
311
+ raise TypeError(f"Unknown standard stream '{name}'")
312
+ return opener()
313
+
314
+
315
+ def get_text_stream(
316
+ name: "te.Literal['stdin', 'stdout', 'stderr']",
317
+ encoding: t.Optional[str] = None,
318
+ errors: t.Optional[str] = "strict",
319
+ ) -> t.TextIO:
320
+ """Returns a system stream for text processing. This usually returns
321
+ a wrapped stream around a binary stream returned from
322
+ :func:`get_binary_stream` but it also can take shortcuts for already
323
+ correctly configured streams.
324
+
325
+ :param name: the name of the stream to open. Valid names are ``'stdin'``,
326
+ ``'stdout'`` and ``'stderr'``
327
+ :param encoding: overrides the detected default encoding.
328
+ :param errors: overrides the default error mode.
329
+ """
330
+ opener = text_streams.get(name)
331
+ if opener is None:
332
+ raise TypeError(f"Unknown standard stream '{name}'")
333
+ return opener(encoding, errors)
334
+
335
+
336
+ def open_file(
337
+ filename: str,
338
+ mode: str = "r",
339
+ encoding: t.Optional[str] = None,
340
+ errors: t.Optional[str] = "strict",
341
+ lazy: bool = False,
342
+ atomic: bool = False,
343
+ ) -> t.IO:
344
+ """Open a file, with extra behavior to handle ``'-'`` to indicate
345
+ a standard stream, lazy open on write, and atomic write. Similar to
346
+ the behavior of the :class:`~click.File` param type.
347
+
348
+ If ``'-'`` is given to open ``stdout`` or ``stdin``, the stream is
349
+ wrapped so that using it in a context manager will not close it.
350
+ This makes it possible to use the function without accidentally
351
+ closing a standard stream:
352
+
353
+ .. code-block:: python
354
+
355
+ with open_file(filename) as f:
356
+ ...
357
+
358
+ :param filename: The name of the file to open, or ``'-'`` for
359
+ ``stdin``/``stdout``.
360
+ :param mode: The mode in which to open the file.
361
+ :param encoding: The encoding to decode or encode a file opened in
362
+ text mode.
363
+ :param errors: The error handling mode.
364
+ :param lazy: Wait to open the file until it is accessed. For read
365
+ mode, the file is temporarily opened to raise access errors
366
+ early, then closed until it is read again.
367
+ :param atomic: Write to a temporary file and replace the given file
368
+ on close.
369
+
370
+ .. versionadded:: 3.0
371
+ """
372
+ if lazy:
373
+ return t.cast(t.IO, LazyFile(filename, mode, encoding, errors, atomic=atomic))
374
+
375
+ f, should_close = open_stream(filename, mode, encoding, errors, atomic=atomic)
376
+
377
+ if not should_close:
378
+ f = t.cast(t.IO, KeepOpenFile(f))
379
+
380
+ return f
381
+
382
+
383
+ def format_filename(
384
+ filename: t.Union[str, bytes, os.PathLike], shorten: bool = False
385
+ ) -> str:
386
+ """Formats a filename for user display. The main purpose of this
387
+ function is to ensure that the filename can be displayed at all. This
388
+ will decode the filename to unicode if necessary in a way that it will
389
+ not fail. Optionally, it can shorten the filename to not include the
390
+ full path to the filename.
391
+
392
+ :param filename: formats a filename for UI display. This will also convert
393
+ the filename into unicode without failing.
394
+ :param shorten: this optionally shortens the filename to strip of the
395
+ path that leads up to it.
396
+ """
397
+ if shorten:
398
+ filename = os.path.basename(filename)
399
+
400
+ return os.fsdecode(filename)
401
+
402
+
403
+ def get_app_dir(app_name: str, roaming: bool = True, force_posix: bool = False) -> str:
404
+ r"""Returns the config folder for the application. The default behavior
405
+ is to return whatever is most appropriate for the operating system.
406
+
407
+ To give you an idea, for an app called ``"Foo Bar"``, something like
408
+ the following folders could be returned:
409
+
410
+ Mac OS X:
411
+ ``~/Library/Application Support/Foo Bar``
412
+ Mac OS X (POSIX):
413
+ ``~/.foo-bar``
414
+ Unix:
415
+ ``~/.config/foo-bar``
416
+ Unix (POSIX):
417
+ ``~/.foo-bar``
418
+ Windows (roaming):
419
+ ``C:\Users\<user>\AppData\Roaming\Foo Bar``
420
+ Windows (not roaming):
421
+ ``C:\Users\<user>\AppData\Local\Foo Bar``
422
+
423
+ .. versionadded:: 2.0
424
+
425
+ :param app_name: the application name. This should be properly capitalized
426
+ and can contain whitespace.
427
+ :param roaming: controls if the folder should be roaming or not on Windows.
428
+ Has no affect otherwise.
429
+ :param force_posix: if this is set to `True` then on any POSIX system the
430
+ folder will be stored in the home folder with a leading
431
+ dot instead of the XDG config home or darwin's
432
+ application support folder.
433
+ """
434
+ if WIN:
435
+ key = "APPDATA" if roaming else "LOCALAPPDATA"
436
+ folder = os.environ.get(key)
437
+ if folder is None:
438
+ folder = os.path.expanduser("~")
439
+ return os.path.join(folder, app_name)
440
+ if force_posix:
441
+ return os.path.join(os.path.expanduser(f"~/.{_posixify(app_name)}"))
442
+ if sys.platform == "darwin":
443
+ return os.path.join(
444
+ os.path.expanduser("~/Library/Application Support"), app_name
445
+ )
446
+ return os.path.join(
447
+ os.environ.get("XDG_CONFIG_HOME", os.path.expanduser("~/.config")),
448
+ _posixify(app_name),
449
+ )
450
+
451
+
452
+ class PacifyFlushWrapper:
453
+ """This wrapper is used to catch and suppress BrokenPipeErrors resulting
454
+ from ``.flush()`` being called on broken pipe during the shutdown/final-GC
455
+ of the Python interpreter. Notably ``.flush()`` is always called on
456
+ ``sys.stdout`` and ``sys.stderr``. So as to have minimal impact on any
457
+ other cleanup code, and the case where the underlying file is not a broken
458
+ pipe, all calls and attributes are proxied.
459
+ """
460
+
461
+ def __init__(self, wrapped: t.IO) -> None:
462
+ self.wrapped = wrapped
463
+
464
+ def flush(self) -> None:
465
+ try:
466
+ self.wrapped.flush()
467
+ except OSError as e:
468
+ import errno
469
+
470
+ if e.errno != errno.EPIPE:
471
+ raise
472
+
473
+ def __getattr__(self, attr: str) -> t.Any:
474
+ return getattr(self.wrapped, attr)
475
+
476
+
477
+ def _detect_program_name(
478
+ path: t.Optional[str] = None, _main: t.Optional[ModuleType] = None
479
+ ) -> str:
480
+ """Determine the command used to run the program, for use in help
481
+ text. If a file or entry point was executed, the file name is
482
+ returned. If ``python -m`` was used to execute a module or package,
483
+ ``python -m name`` is returned.
484
+
485
+ This doesn't try to be too precise, the goal is to give a concise
486
+ name for help text. Files are only shown as their name without the
487
+ path. ``python`` is only shown for modules, and the full path to
488
+ ``sys.executable`` is not shown.
489
+
490
+ :param path: The Python file being executed. Python puts this in
491
+ ``sys.argv[0]``, which is used by default.
492
+ :param _main: The ``__main__`` module. This should only be passed
493
+ during internal testing.
494
+
495
+ .. versionadded:: 8.0
496
+ Based on command args detection in the Werkzeug reloader.
497
+
498
+ :meta private:
499
+ """
500
+ if _main is None:
501
+ _main = sys.modules["__main__"]
502
+
503
+ if not path:
504
+ path = sys.argv[0]
505
+
506
+ # The value of __package__ indicates how Python was called. It may
507
+ # not exist if a setuptools script is installed as an egg. It may be
508
+ # set incorrectly for entry points created with pip on Windows.
509
+ if getattr(_main, "__package__", None) is None or (
510
+ os.name == "nt"
511
+ and _main.__package__ == ""
512
+ and not os.path.exists(path)
513
+ and os.path.exists(f"{path}.exe")
514
+ ):
515
+ # Executed a file, like "python app.py".
516
+ return os.path.basename(path)
517
+
518
+ # Executed a module, like "python -m example".
519
+ # Rewritten by Python from "-m script" to "/path/to/script.py".
520
+ # Need to look at main module to determine how it was executed.
521
+ py_module = t.cast(str, _main.__package__)
522
+ name = os.path.splitext(os.path.basename(path))[0]
523
+
524
+ # A submodule like "example.cli".
525
+ if name != "__main__":
526
+ py_module = f"{py_module}.{name}"
527
+
528
+ return f"python -m {py_module.lstrip('.')}"
529
+
530
+
531
+ def _expand_args(
532
+ args: t.Iterable[str],
533
+ *,
534
+ user: bool = True,
535
+ env: bool = True,
536
+ glob_recursive: bool = True,
537
+ ) -> t.List[str]:
538
+ """Simulate Unix shell expansion with Python functions.
539
+
540
+ See :func:`glob.glob`, :func:`os.path.expanduser`, and
541
+ :func:`os.path.expandvars`.
542
+
543
+ This is intended for use on Windows, where the shell does not do any
544
+ expansion. It may not exactly match what a Unix shell would do.
545
+
546
+ :param args: List of command line arguments to expand.
547
+ :param user: Expand user home directory.
548
+ :param env: Expand environment variables.
549
+ :param glob_recursive: ``**`` matches directories recursively.
550
+
551
+ .. versionchanged:: 8.1
552
+ Invalid glob patterns are treated as empty expansions rather
553
+ than raising an error.
554
+
555
+ .. versionadded:: 8.0
556
+
557
+ :meta private:
558
+ """
559
+ from glob import glob
560
+
561
+ out = []
562
+
563
+ for arg in args:
564
+ if user:
565
+ arg = os.path.expanduser(arg)
566
+
567
+ if env:
568
+ arg = os.path.expandvars(arg)
569
+
570
+ try:
571
+ matches = glob(arg, recursive=glob_recursive)
572
+ except re.error:
573
+ matches = []
574
+
575
+ if not matches:
576
+ out.append(arg)
577
+ else:
578
+ out.extend(matches)
579
+
580
+ return out
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/fontTools/__init__.py ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ import logging
2
+ from fontTools.misc.loggingTools import configLogger
3
+
4
+ log = logging.getLogger(__name__)
5
+
6
+ version = __version__ = "4.34.4"
7
+
8
+ __all__ = ["version", "log", "configLogger"]
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/fontTools/__main__.py ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import sys
2
+
3
+
4
+ def main(args=None):
5
+ if args is None:
6
+ args = sys.argv[1:]
7
+
8
+ # TODO Handle library-wide options. Eg.:
9
+ # --unicodedata
10
+ # --verbose / other logging stuff
11
+
12
+ # TODO Allow a way to run arbitrary modules? Useful for setting
13
+ # library-wide options and calling another library. Eg.:
14
+ #
15
+ # $ fonttools --unicodedata=... fontmake ...
16
+ #
17
+ # This allows for a git-like command where thirdparty commands
18
+ # can be added. Should we just try importing the fonttools
19
+ # module first and try without if it fails?
20
+
21
+ if len(sys.argv) < 2:
22
+ sys.argv.append("help")
23
+ if sys.argv[1] == "-h" or sys.argv[1] == "--help":
24
+ sys.argv[1] = "help"
25
+ mod = 'fontTools.'+sys.argv[1]
26
+ sys.argv[1] = sys.argv[0] + ' ' + sys.argv[1]
27
+ del sys.argv[0]
28
+
29
+ import runpy
30
+ runpy.run_module(mod, run_name='__main__')
31
+
32
+
33
+ if __name__ == '__main__':
34
+ sys.exit(main())
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/fontTools/afmLib.py ADDED
@@ -0,0 +1,430 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Module for reading and writing AFM (Adobe Font Metrics) files.
2
+
3
+ Note that this has been designed to read in AFM files generated by Fontographer
4
+ and has not been tested on many other files. In particular, it does not
5
+ implement the whole Adobe AFM specification [#f1]_ but, it should read most
6
+ "common" AFM files.
7
+
8
+ Here is an example of using `afmLib` to read, modify and write an AFM file:
9
+
10
+ >>> from fontTools.afmLib import AFM
11
+ >>> f = AFM("Tests/afmLib/data/TestAFM.afm")
12
+ >>>
13
+ >>> # Accessing a pair gets you the kern value
14
+ >>> f[("V","A")]
15
+ -60
16
+ >>>
17
+ >>> # Accessing a glyph name gets you metrics
18
+ >>> f["A"]
19
+ (65, 668, (8, -25, 660, 666))
20
+ >>> # (charnum, width, bounding box)
21
+ >>>
22
+ >>> # Accessing an attribute gets you metadata
23
+ >>> f.FontName
24
+ 'TestFont-Regular'
25
+ >>> f.FamilyName
26
+ 'TestFont'
27
+ >>> f.Weight
28
+ 'Regular'
29
+ >>> f.XHeight
30
+ 500
31
+ >>> f.Ascender
32
+ 750
33
+ >>>
34
+ >>> # Attributes and items can also be set
35
+ >>> f[("A","V")] = -150 # Tighten kerning
36
+ >>> f.FontName = "TestFont Squished"
37
+ >>>
38
+ >>> # And the font written out again (remove the # in front)
39
+ >>> #f.write("testfont-squished.afm")
40
+
41
+ .. rubric:: Footnotes
42
+
43
+ .. [#f1] `Adobe Technote 5004 <https://www.adobe.com/content/dam/acom/en/devnet/font/pdfs/5004.AFM_Spec.pdf>`_,
44
+ Adobe Font Metrics File Format Specification.
45
+
46
+ """
47
+
48
+
49
+ import re
50
+
51
+ # every single line starts with a "word"
52
+ identifierRE = re.compile(r"^([A-Za-z]+).*")
53
+
54
+ # regular expression to parse char lines
55
+ charRE = re.compile(
56
+ r"(-?\d+)" # charnum
57
+ r"\s*;\s*WX\s+" # ; WX
58
+ r"(-?\d+)" # width
59
+ r"\s*;\s*N\s+" # ; N
60
+ r"([.A-Za-z0-9_]+)" # charname
61
+ r"\s*;\s*B\s+" # ; B
62
+ r"(-?\d+)" # left
63
+ r"\s+"
64
+ r"(-?\d+)" # bottom
65
+ r"\s+"
66
+ r"(-?\d+)" # right
67
+ r"\s+"
68
+ r"(-?\d+)" # top
69
+ r"\s*;\s*" # ;
70
+ )
71
+
72
+ # regular expression to parse kerning lines
73
+ kernRE = re.compile(
74
+ r"([.A-Za-z0-9_]+)" # leftchar
75
+ r"\s+"
76
+ r"([.A-Za-z0-9_]+)" # rightchar
77
+ r"\s+"
78
+ r"(-?\d+)" # value
79
+ r"\s*"
80
+ )
81
+
82
+ # regular expressions to parse composite info lines of the form:
83
+ # Aacute 2 ; PCC A 0 0 ; PCC acute 182 211 ;
84
+ compositeRE = re.compile(
85
+ r"([.A-Za-z0-9_]+)" # char name
86
+ r"\s+"
87
+ r"(\d+)" # number of parts
88
+ r"\s*;\s*"
89
+ )
90
+ componentRE = re.compile(
91
+ r"PCC\s+" # PPC
92
+ r"([.A-Za-z0-9_]+)" # base char name
93
+ r"\s+"
94
+ r"(-?\d+)" # x offset
95
+ r"\s+"
96
+ r"(-?\d+)" # y offset
97
+ r"\s*;\s*"
98
+ )
99
+
100
+ preferredAttributeOrder = [
101
+ "FontName",
102
+ "FullName",
103
+ "FamilyName",
104
+ "Weight",
105
+ "ItalicAngle",
106
+ "IsFixedPitch",
107
+ "FontBBox",
108
+ "UnderlinePosition",
109
+ "UnderlineThickness",
110
+ "Version",
111
+ "Notice",
112
+ "EncodingScheme",
113
+ "CapHeight",
114
+ "XHeight",
115
+ "Ascender",
116
+ "Descender",
117
+ ]
118
+
119
+
120
+ class error(Exception):
121
+ pass
122
+
123
+
124
+ class AFM(object):
125
+
126
+ _attrs = None
127
+
128
+ _keywords = ['StartFontMetrics',
129
+ 'EndFontMetrics',
130
+ 'StartCharMetrics',
131
+ 'EndCharMetrics',
132
+ 'StartKernData',
133
+ 'StartKernPairs',
134
+ 'EndKernPairs',
135
+ 'EndKernData',
136
+ 'StartComposites',
137
+ 'EndComposites',
138
+ ]
139
+
140
+ def __init__(self, path=None):
141
+ """AFM file reader.
142
+
143
+ Instantiating an object with a path name will cause the file to be opened,
144
+ read, and parsed. Alternatively the path can be left unspecified, and a
145
+ file can be parsed later with the :meth:`read` method."""
146
+ self._attrs = {}
147
+ self._chars = {}
148
+ self._kerning = {}
149
+ self._index = {}
150
+ self._comments = []
151
+ self._composites = {}
152
+ if path is not None:
153
+ self.read(path)
154
+
155
+ def read(self, path):
156
+ """Opens, reads and parses a file."""
157
+ lines = readlines(path)
158
+ for line in lines:
159
+ if not line.strip():
160
+ continue
161
+ m = identifierRE.match(line)
162
+ if m is None:
163
+ raise error("syntax error in AFM file: " + repr(line))
164
+
165
+ pos = m.regs[1][1]
166
+ word = line[:pos]
167
+ rest = line[pos:].strip()
168
+ if word in self._keywords:
169
+ continue
170
+ if word == "C":
171
+ self.parsechar(rest)
172
+ elif word == "KPX":
173
+ self.parsekernpair(rest)
174
+ elif word == "CC":
175
+ self.parsecomposite(rest)
176
+ else:
177
+ self.parseattr(word, rest)
178
+
179
+ def parsechar(self, rest):
180
+ m = charRE.match(rest)
181
+ if m is None:
182
+ raise error("syntax error in AFM file: " + repr(rest))
183
+ things = []
184
+ for fr, to in m.regs[1:]:
185
+ things.append(rest[fr:to])
186
+ charname = things[2]
187
+ del things[2]
188
+ charnum, width, l, b, r, t = (int(thing) for thing in things)
189
+ self._chars[charname] = charnum, width, (l, b, r, t)
190
+
191
+ def parsekernpair(self, rest):
192
+ m = kernRE.match(rest)
193
+ if m is None:
194
+ raise error("syntax error in AFM file: " + repr(rest))
195
+ things = []
196
+ for fr, to in m.regs[1:]:
197
+ things.append(rest[fr:to])
198
+ leftchar, rightchar, value = things
199
+ value = int(value)
200
+ self._kerning[(leftchar, rightchar)] = value
201
+
202
+ def parseattr(self, word, rest):
203
+ if word == "FontBBox":
204
+ l, b, r, t = [int(thing) for thing in rest.split()]
205
+ self._attrs[word] = l, b, r, t
206
+ elif word == "Comment":
207
+ self._comments.append(rest)
208
+ else:
209
+ try:
210
+ value = int(rest)
211
+ except (ValueError, OverflowError):
212
+ self._attrs[word] = rest
213
+ else:
214
+ self._attrs[word] = value
215
+
216
+ def parsecomposite(self, rest):
217
+ m = compositeRE.match(rest)
218
+ if m is None:
219
+ raise error("syntax error in AFM file: " + repr(rest))
220
+ charname = m.group(1)
221
+ ncomponents = int(m.group(2))
222
+ rest = rest[m.regs[0][1]:]
223
+ components = []
224
+ while True:
225
+ m = componentRE.match(rest)
226
+ if m is None:
227
+ raise error("syntax error in AFM file: " + repr(rest))
228
+ basechar = m.group(1)
229
+ xoffset = int(m.group(2))
230
+ yoffset = int(m.group(3))
231
+ components.append((basechar, xoffset, yoffset))
232
+ rest = rest[m.regs[0][1]:]
233
+ if not rest:
234
+ break
235
+ assert len(components) == ncomponents
236
+ self._composites[charname] = components
237
+
238
+ def write(self, path, sep='\r'):
239
+ """Writes out an AFM font to the given path."""
240
+ import time
241
+ lines = [ "StartFontMetrics 2.0",
242
+ "Comment Generated by afmLib; at %s" % (
243
+ time.strftime("%m/%d/%Y %H:%M:%S",
244
+ time.localtime(time.time())))]
245
+
246
+ # write comments, assuming (possibly wrongly!) they should
247
+ # all appear at the top
248
+ for comment in self._comments:
249
+ lines.append("Comment " + comment)
250
+
251
+ # write attributes, first the ones we know about, in
252
+ # a preferred order
253
+ attrs = self._attrs
254
+ for attr in preferredAttributeOrder:
255
+ if attr in attrs:
256
+ value = attrs[attr]
257
+ if attr == "FontBBox":
258
+ value = "%s %s %s %s" % value
259
+ lines.append(attr + " " + str(value))
260
+ # then write the attributes we don't know about,
261
+ # in alphabetical order
262
+ items = sorted(attrs.items())
263
+ for attr, value in items:
264
+ if attr in preferredAttributeOrder:
265
+ continue
266
+ lines.append(attr + " " + str(value))
267
+
268
+ # write char metrics
269
+ lines.append("StartCharMetrics " + repr(len(self._chars)))
270
+ items = [(charnum, (charname, width, box)) for charname, (charnum, width, box) in self._chars.items()]
271
+
272
+ def myKey(a):
273
+ """Custom key function to make sure unencoded chars (-1)
274
+ end up at the end of the list after sorting."""
275
+ if a[0] == -1:
276
+ a = (0xffff,) + a[1:] # 0xffff is an arbitrary large number
277
+ return a
278
+ items.sort(key=myKey)
279
+
280
+ for charnum, (charname, width, (l, b, r, t)) in items:
281
+ lines.append("C %d ; WX %d ; N %s ; B %d %d %d %d ;" %
282
+ (charnum, width, charname, l, b, r, t))
283
+ lines.append("EndCharMetrics")
284
+
285
+ # write kerning info
286
+ lines.append("StartKernData")
287
+ lines.append("StartKernPairs " + repr(len(self._kerning)))
288
+ items = sorted(self._kerning.items())
289
+ for (leftchar, rightchar), value in items:
290
+ lines.append("KPX %s %s %d" % (leftchar, rightchar, value))
291
+ lines.append("EndKernPairs")
292
+ lines.append("EndKernData")
293
+
294
+ if self._composites:
295
+ composites = sorted(self._composites.items())
296
+ lines.append("StartComposites %s" % len(self._composites))
297
+ for charname, components in composites:
298
+ line = "CC %s %s ;" % (charname, len(components))
299
+ for basechar, xoffset, yoffset in components:
300
+ line = line + " PCC %s %s %s ;" % (basechar, xoffset, yoffset)
301
+ lines.append(line)
302
+ lines.append("EndComposites")
303
+
304
+ lines.append("EndFontMetrics")
305
+
306
+ writelines(path, lines, sep)
307
+
308
+ def has_kernpair(self, pair):
309
+ """Returns `True` if the given glyph pair (specified as a tuple) exists
310
+ in the kerning dictionary."""
311
+ return pair in self._kerning
312
+
313
+ def kernpairs(self):
314
+ """Returns a list of all kern pairs in the kerning dictionary."""
315
+ return list(self._kerning.keys())
316
+
317
+ def has_char(self, char):
318
+ """Returns `True` if the given glyph exists in the font."""
319
+ return char in self._chars
320
+
321
+ def chars(self):
322
+ """Returns a list of all glyph names in the font."""
323
+ return list(self._chars.keys())
324
+
325
+ def comments(self):
326
+ """Returns all comments from the file."""
327
+ return self._comments
328
+
329
+ def addComment(self, comment):
330
+ """Adds a new comment to the file."""
331
+ self._comments.append(comment)
332
+
333
+ def addComposite(self, glyphName, components):
334
+ """Specifies that the glyph `glyphName` is made up of the given components.
335
+ The components list should be of the following form::
336
+
337
+ [
338
+ (glyphname, xOffset, yOffset),
339
+ ...
340
+ ]
341
+
342
+ """
343
+ self._composites[glyphName] = components
344
+
345
+ def __getattr__(self, attr):
346
+ if attr in self._attrs:
347
+ return self._attrs[attr]
348
+ else:
349
+ raise AttributeError(attr)
350
+
351
+ def __setattr__(self, attr, value):
352
+ # all attrs *not* starting with "_" are consider to be AFM keywords
353
+ if attr[:1] == "_":
354
+ self.__dict__[attr] = value
355
+ else:
356
+ self._attrs[attr] = value
357
+
358
+ def __delattr__(self, attr):
359
+ # all attrs *not* starting with "_" are consider to be AFM keywords
360
+ if attr[:1] == "_":
361
+ try:
362
+ del self.__dict__[attr]
363
+ except KeyError:
364
+ raise AttributeError(attr)
365
+ else:
366
+ try:
367
+ del self._attrs[attr]
368
+ except KeyError:
369
+ raise AttributeError(attr)
370
+
371
+ def __getitem__(self, key):
372
+ if isinstance(key, tuple):
373
+ # key is a tuple, return the kernpair
374
+ return self._kerning[key]
375
+ else:
376
+ # return the metrics instead
377
+ return self._chars[key]
378
+
379
+ def __setitem__(self, key, value):
380
+ if isinstance(key, tuple):
381
+ # key is a tuple, set kernpair
382
+ self._kerning[key] = value
383
+ else:
384
+ # set char metrics
385
+ self._chars[key] = value
386
+
387
+ def __delitem__(self, key):
388
+ if isinstance(key, tuple):
389
+ # key is a tuple, del kernpair
390
+ del self._kerning[key]
391
+ else:
392
+ # del char metrics
393
+ del self._chars[key]
394
+
395
+ def __repr__(self):
396
+ if hasattr(self, "FullName"):
397
+ return '<AFM object for %s>' % self.FullName
398
+ else:
399
+ return '<AFM object at %x>' % id(self)
400
+
401
+
402
+ def readlines(path):
403
+ with open(path, "r", encoding="ascii") as f:
404
+ data = f.read()
405
+ return data.splitlines()
406
+
407
+ def writelines(path, lines, sep='\r'):
408
+ with open(path, "w", encoding="ascii", newline=sep) as f:
409
+ f.write("\n".join(lines) + "\n")
410
+
411
+
412
+ if __name__ == "__main__":
413
+ import EasyDialogs
414
+ path = EasyDialogs.AskFileForOpen()
415
+ if path:
416
+ afm = AFM(path)
417
+ char = 'A'
418
+ if afm.has_char(char):
419
+ print(afm[char]) # print charnum, width and boundingbox
420
+ pair = ('A', 'V')
421
+ if afm.has_kernpair(pair):
422
+ print(afm[pair]) # print kerning value for pair
423
+ print(afm.Version) # various other afm entries have become attributes
424
+ print(afm.Weight)
425
+ # afm.comments() returns a list of all Comment lines found in the AFM
426
+ print(afm.comments())
427
+ #print afm.chars()
428
+ #print afm.kernpairs()
429
+ print(afm)
430
+ afm.write(path + ".muck")
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/fontTools/agl.py ADDED
The diff for this file is too large to render. See raw diff
 
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/fontTools/fontBuilder.py ADDED
@@ -0,0 +1,958 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ __all__ = ["FontBuilder"]
2
+
3
+ """
4
+ This module is *experimental*, meaning it still may evolve and change.
5
+
6
+ The `FontBuilder` class is a convenient helper to construct working TTF or
7
+ OTF fonts from scratch.
8
+
9
+ Note that the various setup methods cannot be called in arbitrary order,
10
+ due to various interdependencies between OpenType tables. Here is an order
11
+ that works:
12
+
13
+ fb = FontBuilder(...)
14
+ fb.setupGlyphOrder(...)
15
+ fb.setupCharacterMap(...)
16
+ fb.setupGlyf(...) --or-- fb.setupCFF(...)
17
+ fb.setupHorizontalMetrics(...)
18
+ fb.setupHorizontalHeader()
19
+ fb.setupNameTable(...)
20
+ fb.setupOS2()
21
+ fb.addOpenTypeFeatures(...)
22
+ fb.setupPost()
23
+ fb.save(...)
24
+
25
+ Here is how to build a minimal TTF:
26
+
27
+ ```python
28
+ from fontTools.fontBuilder import FontBuilder
29
+ from fontTools.pens.ttGlyphPen import TTGlyphPen
30
+
31
+
32
+ def drawTestGlyph(pen):
33
+ pen.moveTo((100, 100))
34
+ pen.lineTo((100, 1000))
35
+ pen.qCurveTo((200, 900), (400, 900), (500, 1000))
36
+ pen.lineTo((500, 100))
37
+ pen.closePath()
38
+
39
+
40
+ fb = FontBuilder(1024, isTTF=True)
41
+ fb.setupGlyphOrder([".notdef", ".null", "space", "A", "a"])
42
+ fb.setupCharacterMap({32: "space", 65: "A", 97: "a"})
43
+ advanceWidths = {".notdef": 600, "space": 500, "A": 600, "a": 600, ".null": 0}
44
+
45
+ familyName = "HelloTestFont"
46
+ styleName = "TotallyNormal"
47
+ version = "0.1"
48
+
49
+ nameStrings = dict(
50
+ familyName=dict(en=familyName, nl="HalloTestFont"),
51
+ styleName=dict(en=styleName, nl="TotaalNormaal"),
52
+ uniqueFontIdentifier="fontBuilder: " + familyName + "." + styleName,
53
+ fullName=familyName + "-" + styleName,
54
+ psName=familyName + "-" + styleName,
55
+ version="Version " + version,
56
+ )
57
+
58
+ pen = TTGlyphPen(None)
59
+ drawTestGlyph(pen)
60
+ glyph = pen.glyph()
61
+ glyphs = {".notdef": glyph, "space": glyph, "A": glyph, "a": glyph, ".null": glyph}
62
+ fb.setupGlyf(glyphs)
63
+ metrics = {}
64
+ glyphTable = fb.font["glyf"]
65
+ for gn, advanceWidth in advanceWidths.items():
66
+ metrics[gn] = (advanceWidth, glyphTable[gn].xMin)
67
+ fb.setupHorizontalMetrics(metrics)
68
+ fb.setupHorizontalHeader(ascent=824, descent=-200)
69
+ fb.setupNameTable(nameStrings)
70
+ fb.setupOS2(sTypoAscender=824, usWinAscent=824, usWinDescent=200)
71
+ fb.setupPost()
72
+ fb.save("test.ttf")
73
+ ```
74
+
75
+ And here's how to build a minimal OTF:
76
+
77
+ ```python
78
+ from fontTools.fontBuilder import FontBuilder
79
+ from fontTools.pens.t2CharStringPen import T2CharStringPen
80
+
81
+
82
+ def drawTestGlyph(pen):
83
+ pen.moveTo((100, 100))
84
+ pen.lineTo((100, 1000))
85
+ pen.curveTo((200, 900), (400, 900), (500, 1000))
86
+ pen.lineTo((500, 100))
87
+ pen.closePath()
88
+
89
+
90
+ fb = FontBuilder(1024, isTTF=False)
91
+ fb.setupGlyphOrder([".notdef", ".null", "space", "A", "a"])
92
+ fb.setupCharacterMap({32: "space", 65: "A", 97: "a"})
93
+ advanceWidths = {".notdef": 600, "space": 500, "A": 600, "a": 600, ".null": 0}
94
+
95
+ familyName = "HelloTestFont"
96
+ styleName = "TotallyNormal"
97
+ version = "0.1"
98
+
99
+ nameStrings = dict(
100
+ familyName=dict(en=familyName, nl="HalloTestFont"),
101
+ styleName=dict(en=styleName, nl="TotaalNormaal"),
102
+ uniqueFontIdentifier="fontBuilder: " + familyName + "." + styleName,
103
+ fullName=familyName + "-" + styleName,
104
+ psName=familyName + "-" + styleName,
105
+ version="Version " + version,
106
+ )
107
+
108
+ pen = T2CharStringPen(600, None)
109
+ drawTestGlyph(pen)
110
+ charString = pen.getCharString()
111
+ charStrings = {
112
+ ".notdef": charString,
113
+ "space": charString,
114
+ "A": charString,
115
+ "a": charString,
116
+ ".null": charString,
117
+ }
118
+ fb.setupCFF(nameStrings["psName"], {"FullName": nameStrings["psName"]}, charStrings, {})
119
+ lsb = {gn: cs.calcBounds(None)[0] for gn, cs in charStrings.items()}
120
+ metrics = {}
121
+ for gn, advanceWidth in advanceWidths.items():
122
+ metrics[gn] = (advanceWidth, lsb[gn])
123
+ fb.setupHorizontalMetrics(metrics)
124
+ fb.setupHorizontalHeader(ascent=824, descent=200)
125
+ fb.setupNameTable(nameStrings)
126
+ fb.setupOS2(sTypoAscender=824, usWinAscent=824, usWinDescent=200)
127
+ fb.setupPost()
128
+ fb.save("test.otf")
129
+ ```
130
+ """
131
+
132
+ from .ttLib import TTFont, newTable
133
+ from .ttLib.tables._c_m_a_p import cmap_classes
134
+ from .misc.timeTools import timestampNow
135
+ import struct
136
+ from collections import OrderedDict
137
+
138
+
139
+ _headDefaults = dict(
140
+ tableVersion=1.0,
141
+ fontRevision=1.0,
142
+ checkSumAdjustment=0,
143
+ magicNumber=0x5F0F3CF5,
144
+ flags=0x0003,
145
+ unitsPerEm=1000,
146
+ created=0,
147
+ modified=0,
148
+ xMin=0,
149
+ yMin=0,
150
+ xMax=0,
151
+ yMax=0,
152
+ macStyle=0,
153
+ lowestRecPPEM=3,
154
+ fontDirectionHint=2,
155
+ indexToLocFormat=0,
156
+ glyphDataFormat=0,
157
+ )
158
+
159
+ _maxpDefaultsTTF = dict(
160
+ tableVersion=0x00010000,
161
+ numGlyphs=0,
162
+ maxPoints=0,
163
+ maxContours=0,
164
+ maxCompositePoints=0,
165
+ maxCompositeContours=0,
166
+ maxZones=2,
167
+ maxTwilightPoints=0,
168
+ maxStorage=0,
169
+ maxFunctionDefs=0,
170
+ maxInstructionDefs=0,
171
+ maxStackElements=0,
172
+ maxSizeOfInstructions=0,
173
+ maxComponentElements=0,
174
+ maxComponentDepth=0,
175
+ )
176
+ _maxpDefaultsOTF = dict(
177
+ tableVersion=0x00005000,
178
+ numGlyphs=0,
179
+ )
180
+
181
+ _postDefaults = dict(
182
+ formatType=3.0,
183
+ italicAngle=0,
184
+ underlinePosition=0,
185
+ underlineThickness=0,
186
+ isFixedPitch=0,
187
+ minMemType42=0,
188
+ maxMemType42=0,
189
+ minMemType1=0,
190
+ maxMemType1=0,
191
+ )
192
+
193
+ _hheaDefaults = dict(
194
+ tableVersion=0x00010000,
195
+ ascent=0,
196
+ descent=0,
197
+ lineGap=0,
198
+ advanceWidthMax=0,
199
+ minLeftSideBearing=0,
200
+ minRightSideBearing=0,
201
+ xMaxExtent=0,
202
+ caretSlopeRise=1,
203
+ caretSlopeRun=0,
204
+ caretOffset=0,
205
+ reserved0=0,
206
+ reserved1=0,
207
+ reserved2=0,
208
+ reserved3=0,
209
+ metricDataFormat=0,
210
+ numberOfHMetrics=0,
211
+ )
212
+
213
+ _vheaDefaults = dict(
214
+ tableVersion=0x00010000,
215
+ ascent=0,
216
+ descent=0,
217
+ lineGap=0,
218
+ advanceHeightMax=0,
219
+ minTopSideBearing=0,
220
+ minBottomSideBearing=0,
221
+ yMaxExtent=0,
222
+ caretSlopeRise=0,
223
+ caretSlopeRun=0,
224
+ reserved0=0,
225
+ reserved1=0,
226
+ reserved2=0,
227
+ reserved3=0,
228
+ reserved4=0,
229
+ metricDataFormat=0,
230
+ numberOfVMetrics=0,
231
+ )
232
+
233
+ _nameIDs = dict(
234
+ copyright=0,
235
+ familyName=1,
236
+ styleName=2,
237
+ uniqueFontIdentifier=3,
238
+ fullName=4,
239
+ version=5,
240
+ psName=6,
241
+ trademark=7,
242
+ manufacturer=8,
243
+ designer=9,
244
+ description=10,
245
+ vendorURL=11,
246
+ designerURL=12,
247
+ licenseDescription=13,
248
+ licenseInfoURL=14,
249
+ # reserved = 15,
250
+ typographicFamily=16,
251
+ typographicSubfamily=17,
252
+ compatibleFullName=18,
253
+ sampleText=19,
254
+ postScriptCIDFindfontName=20,
255
+ wwsFamilyName=21,
256
+ wwsSubfamilyName=22,
257
+ lightBackgroundPalette=23,
258
+ darkBackgroundPalette=24,
259
+ variationsPostScriptNamePrefix=25,
260
+ )
261
+
262
+ # to insert in setupNameTable doc string:
263
+ # print("\n".join(("%s (nameID %s)" % (k, v)) for k, v in sorted(_nameIDs.items(), key=lambda x: x[1])))
264
+
265
+ _panoseDefaults = dict(
266
+ bFamilyType=0,
267
+ bSerifStyle=0,
268
+ bWeight=0,
269
+ bProportion=0,
270
+ bContrast=0,
271
+ bStrokeVariation=0,
272
+ bArmStyle=0,
273
+ bLetterForm=0,
274
+ bMidline=0,
275
+ bXHeight=0,
276
+ )
277
+
278
+ _OS2Defaults = dict(
279
+ version=3,
280
+ xAvgCharWidth=0,
281
+ usWeightClass=400,
282
+ usWidthClass=5,
283
+ fsType=0x0004, # default: Preview & Print embedding
284
+ ySubscriptXSize=0,
285
+ ySubscriptYSize=0,
286
+ ySubscriptXOffset=0,
287
+ ySubscriptYOffset=0,
288
+ ySuperscriptXSize=0,
289
+ ySuperscriptYSize=0,
290
+ ySuperscriptXOffset=0,
291
+ ySuperscriptYOffset=0,
292
+ yStrikeoutSize=0,
293
+ yStrikeoutPosition=0,
294
+ sFamilyClass=0,
295
+ panose=_panoseDefaults,
296
+ ulUnicodeRange1=0,
297
+ ulUnicodeRange2=0,
298
+ ulUnicodeRange3=0,
299
+ ulUnicodeRange4=0,
300
+ achVendID="????",
301
+ fsSelection=0,
302
+ usFirstCharIndex=0,
303
+ usLastCharIndex=0,
304
+ sTypoAscender=0,
305
+ sTypoDescender=0,
306
+ sTypoLineGap=0,
307
+ usWinAscent=0,
308
+ usWinDescent=0,
309
+ ulCodePageRange1=0,
310
+ ulCodePageRange2=0,
311
+ sxHeight=0,
312
+ sCapHeight=0,
313
+ usDefaultChar=0, # .notdef
314
+ usBreakChar=32, # space
315
+ usMaxContext=0,
316
+ usLowerOpticalPointSize=0,
317
+ usUpperOpticalPointSize=0,
318
+ )
319
+
320
+
321
+ class FontBuilder(object):
322
+ def __init__(self, unitsPerEm=None, font=None, isTTF=True):
323
+ """Initialize a FontBuilder instance.
324
+
325
+ If the `font` argument is not given, a new `TTFont` will be
326
+ constructed, and `unitsPerEm` must be given. If `isTTF` is True,
327
+ the font will be a glyf-based TTF; if `isTTF` is False it will be
328
+ a CFF-based OTF.
329
+
330
+ If `font` is given, it must be a `TTFont` instance and `unitsPerEm`
331
+ must _not_ be given. The `isTTF` argument will be ignored.
332
+ """
333
+ if font is None:
334
+ self.font = TTFont(recalcTimestamp=False)
335
+ self.isTTF = isTTF
336
+ now = timestampNow()
337
+ assert unitsPerEm is not None
338
+ self.setupHead(unitsPerEm=unitsPerEm, created=now, modified=now)
339
+ self.setupMaxp()
340
+ else:
341
+ assert unitsPerEm is None
342
+ self.font = font
343
+ self.isTTF = "glyf" in font
344
+
345
+ def save(self, file):
346
+ """Save the font. The 'file' argument can be either a pathname or a
347
+ writable file object.
348
+ """
349
+ self.font.save(file)
350
+
351
+ def _initTableWithValues(self, tableTag, defaults, values):
352
+ table = self.font[tableTag] = newTable(tableTag)
353
+ for k, v in defaults.items():
354
+ setattr(table, k, v)
355
+ for k, v in values.items():
356
+ setattr(table, k, v)
357
+ return table
358
+
359
+ def _updateTableWithValues(self, tableTag, values):
360
+ table = self.font[tableTag]
361
+ for k, v in values.items():
362
+ setattr(table, k, v)
363
+
364
+ def setupHead(self, **values):
365
+ """Create a new `head` table and initialize it with default values,
366
+ which can be overridden by keyword arguments.
367
+ """
368
+ self._initTableWithValues("head", _headDefaults, values)
369
+
370
+ def updateHead(self, **values):
371
+ """Update the head table with the fields and values passed as
372
+ keyword arguments.
373
+ """
374
+ self._updateTableWithValues("head", values)
375
+
376
+ def setupGlyphOrder(self, glyphOrder):
377
+ """Set the glyph order for the font."""
378
+ self.font.setGlyphOrder(glyphOrder)
379
+
380
+ def setupCharacterMap(self, cmapping, uvs=None, allowFallback=False):
381
+ """Build the `cmap` table for the font. The `cmapping` argument should
382
+ be a dict mapping unicode code points as integers to glyph names.
383
+
384
+ The `uvs` argument, when passed, must be a list of tuples, describing
385
+ Unicode Variation Sequences. These tuples have three elements:
386
+ (unicodeValue, variationSelector, glyphName)
387
+ `unicodeValue` and `variationSelector` are integer code points.
388
+ `glyphName` may be None, to indicate this is the default variation.
389
+ Text processors will then use the cmap to find the glyph name.
390
+ Each Unicode Variation Sequence should be an officially supported
391
+ sequence, but this is not policed.
392
+ """
393
+ subTables = []
394
+ highestUnicode = max(cmapping)
395
+ if highestUnicode > 0xFFFF:
396
+ cmapping_3_1 = dict((k, v) for k, v in cmapping.items() if k < 0x10000)
397
+ subTable_3_10 = buildCmapSubTable(cmapping, 12, 3, 10)
398
+ subTables.append(subTable_3_10)
399
+ else:
400
+ cmapping_3_1 = cmapping
401
+ format = 4
402
+ subTable_3_1 = buildCmapSubTable(cmapping_3_1, format, 3, 1)
403
+ try:
404
+ subTable_3_1.compile(self.font)
405
+ except struct.error:
406
+ # format 4 overflowed, fall back to format 12
407
+ if not allowFallback:
408
+ raise ValueError(
409
+ "cmap format 4 subtable overflowed; sort glyph order by unicode to fix."
410
+ )
411
+ format = 12
412
+ subTable_3_1 = buildCmapSubTable(cmapping_3_1, format, 3, 1)
413
+ subTables.append(subTable_3_1)
414
+ subTable_0_3 = buildCmapSubTable(cmapping_3_1, format, 0, 3)
415
+ subTables.append(subTable_0_3)
416
+
417
+ if uvs is not None:
418
+ uvsDict = {}
419
+ for unicodeValue, variationSelector, glyphName in uvs:
420
+ if cmapping.get(unicodeValue) == glyphName:
421
+ # this is a default variation
422
+ glyphName = None
423
+ if variationSelector not in uvsDict:
424
+ uvsDict[variationSelector] = []
425
+ uvsDict[variationSelector].append((unicodeValue, glyphName))
426
+ uvsSubTable = buildCmapSubTable({}, 14, 0, 5)
427
+ uvsSubTable.uvsDict = uvsDict
428
+ subTables.append(uvsSubTable)
429
+
430
+ self.font["cmap"] = newTable("cmap")
431
+ self.font["cmap"].tableVersion = 0
432
+ self.font["cmap"].tables = subTables
433
+
434
+ def setupNameTable(self, nameStrings, windows=True, mac=True):
435
+ """Create the `name` table for the font. The `nameStrings` argument must
436
+ be a dict, mapping nameIDs or descriptive names for the nameIDs to name
437
+ record values. A value is either a string, or a dict, mapping language codes
438
+ to strings, to allow localized name table entries.
439
+
440
+ By default, both Windows (platformID=3) and Macintosh (platformID=1) name
441
+ records are added, unless any of `windows` or `mac` arguments is False.
442
+
443
+ The following descriptive names are available for nameIDs:
444
+
445
+ copyright (nameID 0)
446
+ familyName (nameID 1)
447
+ styleName (nameID 2)
448
+ uniqueFontIdentifier (nameID 3)
449
+ fullName (nameID 4)
450
+ version (nameID 5)
451
+ psName (nameID 6)
452
+ trademark (nameID 7)
453
+ manufacturer (nameID 8)
454
+ designer (nameID 9)
455
+ description (nameID 10)
456
+ vendorURL (nameID 11)
457
+ designerURL (nameID 12)
458
+ licenseDescription (nameID 13)
459
+ licenseInfoURL (nameID 14)
460
+ typographicFamily (nameID 16)
461
+ typographicSubfamily (nameID 17)
462
+ compatibleFullName (nameID 18)
463
+ sampleText (nameID 19)
464
+ postScriptCIDFindfontName (nameID 20)
465
+ wwsFamilyName (nameID 21)
466
+ wwsSubfamilyName (nameID 22)
467
+ lightBackgroundPalette (nameID 23)
468
+ darkBackgroundPalette (nameID 24)
469
+ variationsPostScriptNamePrefix (nameID 25)
470
+ """
471
+ nameTable = self.font["name"] = newTable("name")
472
+ nameTable.names = []
473
+
474
+ for nameName, nameValue in nameStrings.items():
475
+ if isinstance(nameName, int):
476
+ nameID = nameName
477
+ else:
478
+ nameID = _nameIDs[nameName]
479
+ if isinstance(nameValue, str):
480
+ nameValue = dict(en=nameValue)
481
+ nameTable.addMultilingualName(
482
+ nameValue, ttFont=self.font, nameID=nameID, windows=windows, mac=mac
483
+ )
484
+
485
+ def setupOS2(self, **values):
486
+ """Create a new `OS/2` table and initialize it with default values,
487
+ which can be overridden by keyword arguments.
488
+ """
489
+ self._initTableWithValues("OS/2", _OS2Defaults, values)
490
+ if "xAvgCharWidth" not in values:
491
+ assert (
492
+ "hmtx" in self.font
493
+ ), "the 'hmtx' table must be setup before the 'OS/2' table"
494
+ self.font["OS/2"].recalcAvgCharWidth(self.font)
495
+ if not (
496
+ "ulUnicodeRange1" in values
497
+ or "ulUnicodeRange2" in values
498
+ or "ulUnicodeRange3" in values
499
+ or "ulUnicodeRange3" in values
500
+ ):
501
+ assert (
502
+ "cmap" in self.font
503
+ ), "the 'cmap' table must be setup before the 'OS/2' table"
504
+ self.font["OS/2"].recalcUnicodeRanges(self.font)
505
+
506
+ def setupCFF(self, psName, fontInfo, charStringsDict, privateDict):
507
+ from .cffLib import (
508
+ CFFFontSet,
509
+ TopDictIndex,
510
+ TopDict,
511
+ CharStrings,
512
+ GlobalSubrsIndex,
513
+ PrivateDict,
514
+ )
515
+
516
+ assert not self.isTTF
517
+ self.font.sfntVersion = "OTTO"
518
+ fontSet = CFFFontSet()
519
+ fontSet.major = 1
520
+ fontSet.minor = 0
521
+ fontSet.otFont = self.font
522
+ fontSet.fontNames = [psName]
523
+ fontSet.topDictIndex = TopDictIndex()
524
+
525
+ globalSubrs = GlobalSubrsIndex()
526
+ fontSet.GlobalSubrs = globalSubrs
527
+ private = PrivateDict()
528
+ for key, value in privateDict.items():
529
+ setattr(private, key, value)
530
+ fdSelect = None
531
+ fdArray = None
532
+
533
+ topDict = TopDict()
534
+ topDict.charset = self.font.getGlyphOrder()
535
+ topDict.Private = private
536
+ topDict.GlobalSubrs = fontSet.GlobalSubrs
537
+ for key, value in fontInfo.items():
538
+ setattr(topDict, key, value)
539
+ if "FontMatrix" not in fontInfo:
540
+ scale = 1 / self.font["head"].unitsPerEm
541
+ topDict.FontMatrix = [scale, 0, 0, scale, 0, 0]
542
+
543
+ charStrings = CharStrings(
544
+ None, topDict.charset, globalSubrs, private, fdSelect, fdArray
545
+ )
546
+ for glyphName, charString in charStringsDict.items():
547
+ charString.private = private
548
+ charString.globalSubrs = globalSubrs
549
+ charStrings[glyphName] = charString
550
+ topDict.CharStrings = charStrings
551
+
552
+ fontSet.topDictIndex.append(topDict)
553
+
554
+ self.font["CFF "] = newTable("CFF ")
555
+ self.font["CFF "].cff = fontSet
556
+
557
+ def setupCFF2(self, charStringsDict, fdArrayList=None, regions=None):
558
+ from .cffLib import (
559
+ CFFFontSet,
560
+ TopDictIndex,
561
+ TopDict,
562
+ CharStrings,
563
+ GlobalSubrsIndex,
564
+ PrivateDict,
565
+ FDArrayIndex,
566
+ FontDict,
567
+ )
568
+
569
+ assert not self.isTTF
570
+ self.font.sfntVersion = "OTTO"
571
+ fontSet = CFFFontSet()
572
+ fontSet.major = 2
573
+ fontSet.minor = 0
574
+
575
+ cff2GetGlyphOrder = self.font.getGlyphOrder
576
+ fontSet.topDictIndex = TopDictIndex(None, cff2GetGlyphOrder, None)
577
+
578
+ globalSubrs = GlobalSubrsIndex()
579
+ fontSet.GlobalSubrs = globalSubrs
580
+
581
+ if fdArrayList is None:
582
+ fdArrayList = [{}]
583
+ fdSelect = None
584
+ fdArray = FDArrayIndex()
585
+ fdArray.strings = None
586
+ fdArray.GlobalSubrs = globalSubrs
587
+ for privateDict in fdArrayList:
588
+ fontDict = FontDict()
589
+ fontDict.setCFF2(True)
590
+ private = PrivateDict()
591
+ for key, value in privateDict.items():
592
+ setattr(private, key, value)
593
+ fontDict.Private = private
594
+ fdArray.append(fontDict)
595
+
596
+ topDict = TopDict()
597
+ topDict.cff2GetGlyphOrder = cff2GetGlyphOrder
598
+ topDict.FDArray = fdArray
599
+ scale = 1 / self.font["head"].unitsPerEm
600
+ topDict.FontMatrix = [scale, 0, 0, scale, 0, 0]
601
+
602
+ private = fdArray[0].Private
603
+ charStrings = CharStrings(None, None, globalSubrs, private, fdSelect, fdArray)
604
+ for glyphName, charString in charStringsDict.items():
605
+ charString.private = private
606
+ charString.globalSubrs = globalSubrs
607
+ charStrings[glyphName] = charString
608
+ topDict.CharStrings = charStrings
609
+
610
+ fontSet.topDictIndex.append(topDict)
611
+
612
+ self.font["CFF2"] = newTable("CFF2")
613
+ self.font["CFF2"].cff = fontSet
614
+
615
+ if regions:
616
+ self.setupCFF2Regions(regions)
617
+
618
+ def setupCFF2Regions(self, regions):
619
+ from .varLib.builder import buildVarRegionList, buildVarData, buildVarStore
620
+ from .cffLib import VarStoreData
621
+
622
+ assert "fvar" in self.font, "fvar must to be set up first"
623
+ assert "CFF2" in self.font, "CFF2 must to be set up first"
624
+ axisTags = [a.axisTag for a in self.font["fvar"].axes]
625
+ varRegionList = buildVarRegionList(regions, axisTags)
626
+ varData = buildVarData(list(range(len(regions))), None, optimize=False)
627
+ varStore = buildVarStore(varRegionList, [varData])
628
+ vstore = VarStoreData(otVarStore=varStore)
629
+ topDict = self.font["CFF2"].cff.topDictIndex[0]
630
+ topDict.VarStore = vstore
631
+ for fontDict in topDict.FDArray:
632
+ fontDict.Private.vstore = vstore
633
+
634
+ def setupGlyf(self, glyphs, calcGlyphBounds=True):
635
+ """Create the `glyf` table from a dict, that maps glyph names
636
+ to `fontTools.ttLib.tables._g_l_y_f.Glyph` objects, for example
637
+ as made by `fontTools.pens.ttGlyphPen.TTGlyphPen`.
638
+
639
+ If `calcGlyphBounds` is True, the bounds of all glyphs will be
640
+ calculated. Only pass False if your glyph objects already have
641
+ their bounding box values set.
642
+ """
643
+ assert self.isTTF
644
+ self.font["loca"] = newTable("loca")
645
+ self.font["glyf"] = newTable("glyf")
646
+ self.font["glyf"].glyphs = glyphs
647
+ if hasattr(self.font, "glyphOrder"):
648
+ self.font["glyf"].glyphOrder = self.font.glyphOrder
649
+ if calcGlyphBounds:
650
+ self.calcGlyphBounds()
651
+
652
+ def setupFvar(self, axes, instances):
653
+ """Adds an font variations table to the font.
654
+
655
+ Args:
656
+ axes (list): See below.
657
+ instances (list): See below.
658
+
659
+ ``axes`` should be a list of axes, with each axis either supplied as
660
+ a py:class:`.designspaceLib.AxisDescriptor` object, or a tuple in the
661
+ format ```tupletag, minValue, defaultValue, maxValue, name``.
662
+ The ``name`` is either a string, or a dict, mapping language codes
663
+ to strings, to allow localized name table entries.
664
+
665
+ ```instances`` should be a list of instances, with each instance either
666
+ supplied as a py:class:`.designspaceLib.InstanceDescriptor` object, or a
667
+ dict with keys ``location`` (mapping of axis tags to float values),
668
+ ``stylename`` and (optionally) ``postscriptfontname``.
669
+ The ``stylename`` is either a string, or a dict, mapping language codes
670
+ to strings, to allow localized name table entries.
671
+ """
672
+
673
+ addFvar(self.font, axes, instances)
674
+
675
+ def setupAvar(self, axes):
676
+ """Adds an axis variations table to the font.
677
+
678
+ Args:
679
+ axes (list): A list of py:class:`.designspaceLib.AxisDescriptor` objects.
680
+ """
681
+ from .varLib import _add_avar
682
+
683
+ _add_avar(self.font, OrderedDict(enumerate(axes))) # Only values are used
684
+
685
+ def setupGvar(self, variations):
686
+ gvar = self.font["gvar"] = newTable("gvar")
687
+ gvar.version = 1
688
+ gvar.reserved = 0
689
+ gvar.variations = variations
690
+
691
+ def calcGlyphBounds(self):
692
+ """Calculate the bounding boxes of all glyphs in the `glyf` table.
693
+ This is usually not called explicitly by client code.
694
+ """
695
+ glyphTable = self.font["glyf"]
696
+ for glyph in glyphTable.glyphs.values():
697
+ glyph.recalcBounds(glyphTable)
698
+
699
+ def setupHorizontalMetrics(self, metrics):
700
+ """Create a new `hmtx` table, for horizontal metrics.
701
+
702
+ The `metrics` argument must be a dict, mapping glyph names to
703
+ `(width, leftSidebearing)` tuples.
704
+ """
705
+ self.setupMetrics("hmtx", metrics)
706
+
707
+ def setupVerticalMetrics(self, metrics):
708
+ """Create a new `vmtx` table, for horizontal metrics.
709
+
710
+ The `metrics` argument must be a dict, mapping glyph names to
711
+ `(height, topSidebearing)` tuples.
712
+ """
713
+ self.setupMetrics("vmtx", metrics)
714
+
715
+ def setupMetrics(self, tableTag, metrics):
716
+ """See `setupHorizontalMetrics()` and `setupVerticalMetrics()`."""
717
+ assert tableTag in ("hmtx", "vmtx")
718
+ mtxTable = self.font[tableTag] = newTable(tableTag)
719
+ roundedMetrics = {}
720
+ for gn in metrics:
721
+ w, lsb = metrics[gn]
722
+ roundedMetrics[gn] = int(round(w)), int(round(lsb))
723
+ mtxTable.metrics = roundedMetrics
724
+
725
+ def setupHorizontalHeader(self, **values):
726
+ """Create a new `hhea` table initialize it with default values,
727
+ which can be overridden by keyword arguments.
728
+ """
729
+ self._initTableWithValues("hhea", _hheaDefaults, values)
730
+
731
+ def setupVerticalHeader(self, **values):
732
+ """Create a new `vhea` table initialize it with default values,
733
+ which can be overridden by keyword arguments.
734
+ """
735
+ self._initTableWithValues("vhea", _vheaDefaults, values)
736
+
737
+ def setupVerticalOrigins(self, verticalOrigins, defaultVerticalOrigin=None):
738
+ """Create a new `VORG` table. The `verticalOrigins` argument must be
739
+ a dict, mapping glyph names to vertical origin values.
740
+
741
+ The `defaultVerticalOrigin` argument should be the most common vertical
742
+ origin value. If omitted, this value will be derived from the actual
743
+ values in the `verticalOrigins` argument.
744
+ """
745
+ if defaultVerticalOrigin is None:
746
+ # find the most frequent vorg value
747
+ bag = {}
748
+ for gn in verticalOrigins:
749
+ vorg = verticalOrigins[gn]
750
+ if vorg not in bag:
751
+ bag[vorg] = 1
752
+ else:
753
+ bag[vorg] += 1
754
+ defaultVerticalOrigin = sorted(
755
+ bag, key=lambda vorg: bag[vorg], reverse=True
756
+ )[0]
757
+ self._initTableWithValues(
758
+ "VORG",
759
+ {},
760
+ dict(VOriginRecords={}, defaultVertOriginY=defaultVerticalOrigin),
761
+ )
762
+ vorgTable = self.font["VORG"]
763
+ vorgTable.majorVersion = 1
764
+ vorgTable.minorVersion = 0
765
+ for gn in verticalOrigins:
766
+ vorgTable[gn] = verticalOrigins[gn]
767
+
768
+ def setupPost(self, keepGlyphNames=True, **values):
769
+ """Create a new `post` table and initialize it with default values,
770
+ which can be overridden by keyword arguments.
771
+ """
772
+ isCFF2 = "CFF2" in self.font
773
+ postTable = self._initTableWithValues("post", _postDefaults, values)
774
+ if (self.isTTF or isCFF2) and keepGlyphNames:
775
+ postTable.formatType = 2.0
776
+ postTable.extraNames = []
777
+ postTable.mapping = {}
778
+ else:
779
+ postTable.formatType = 3.0
780
+
781
+ def setupMaxp(self):
782
+ """Create a new `maxp` table. This is called implicitly by FontBuilder
783
+ itself and is usually not called by client code.
784
+ """
785
+ if self.isTTF:
786
+ defaults = _maxpDefaultsTTF
787
+ else:
788
+ defaults = _maxpDefaultsOTF
789
+ self._initTableWithValues("maxp", defaults, {})
790
+
791
+ def setupDummyDSIG(self):
792
+ """This adds an empty DSIG table to the font to make some MS applications
793
+ happy. This does not properly sign the font.
794
+ """
795
+ values = dict(
796
+ ulVersion=1,
797
+ usFlag=0,
798
+ usNumSigs=0,
799
+ signatureRecords=[],
800
+ )
801
+ self._initTableWithValues("DSIG", {}, values)
802
+
803
+ def addOpenTypeFeatures(self, features, filename=None, tables=None):
804
+ """Add OpenType features to the font from a string containing
805
+ Feature File syntax.
806
+
807
+ The `filename` argument is used in error messages and to determine
808
+ where to look for "include" files.
809
+
810
+ The optional `tables` argument can be a list of OTL tables tags to
811
+ build, allowing the caller to only build selected OTL tables. See
812
+ `fontTools.feaLib` for details.
813
+ """
814
+ from .feaLib.builder import addOpenTypeFeaturesFromString
815
+
816
+ addOpenTypeFeaturesFromString(
817
+ self.font, features, filename=filename, tables=tables
818
+ )
819
+
820
+ def addFeatureVariations(self, conditionalSubstitutions, featureTag="rvrn"):
821
+ """Add conditional substitutions to a Variable Font.
822
+
823
+ See `fontTools.varLib.featureVars.addFeatureVariations`.
824
+ """
825
+ from .varLib import featureVars
826
+
827
+ if "fvar" not in self.font:
828
+ raise KeyError("'fvar' table is missing; can't add FeatureVariations.")
829
+
830
+ featureVars.addFeatureVariations(
831
+ self.font, conditionalSubstitutions, featureTag=featureTag
832
+ )
833
+
834
+ def setupCOLR(
835
+ self,
836
+ colorLayers,
837
+ version=None,
838
+ varStore=None,
839
+ varIndexMap=None,
840
+ clipBoxes=None,
841
+ allowLayerReuse=True,
842
+ ):
843
+ """Build new COLR table using color layers dictionary.
844
+
845
+ Cf. `fontTools.colorLib.builder.buildCOLR`.
846
+ """
847
+ from fontTools.colorLib.builder import buildCOLR
848
+
849
+ glyphMap = self.font.getReverseGlyphMap()
850
+ self.font["COLR"] = buildCOLR(
851
+ colorLayers,
852
+ version=version,
853
+ glyphMap=glyphMap,
854
+ varStore=varStore,
855
+ varIndexMap=varIndexMap,
856
+ clipBoxes=clipBoxes,
857
+ allowLayerReuse=allowLayerReuse,
858
+ )
859
+
860
+ def setupCPAL(
861
+ self,
862
+ palettes,
863
+ paletteTypes=None,
864
+ paletteLabels=None,
865
+ paletteEntryLabels=None,
866
+ ):
867
+ """Build new CPAL table using list of palettes.
868
+
869
+ Optionally build CPAL v1 table using paletteTypes, paletteLabels and
870
+ paletteEntryLabels.
871
+
872
+ Cf. `fontTools.colorLib.builder.buildCPAL`.
873
+ """
874
+ from fontTools.colorLib.builder import buildCPAL
875
+
876
+ self.font["CPAL"] = buildCPAL(
877
+ palettes,
878
+ paletteTypes=paletteTypes,
879
+ paletteLabels=paletteLabels,
880
+ paletteEntryLabels=paletteEntryLabels,
881
+ nameTable=self.font.get("name"),
882
+ )
883
+
884
+ def setupStat(self, axes, locations=None, elidedFallbackName=2):
885
+ """Build a new 'STAT' table.
886
+
887
+ See `fontTools.otlLib.builder.buildStatTable` for details about
888
+ the arguments.
889
+ """
890
+ from .otlLib.builder import buildStatTable
891
+
892
+ buildStatTable(self.font, axes, locations, elidedFallbackName)
893
+
894
+
895
+ def buildCmapSubTable(cmapping, format, platformID, platEncID):
896
+ subTable = cmap_classes[format](format)
897
+ subTable.cmap = cmapping
898
+ subTable.platformID = platformID
899
+ subTable.platEncID = platEncID
900
+ subTable.language = 0
901
+ return subTable
902
+
903
+
904
+ def addFvar(font, axes, instances):
905
+ from .ttLib.tables._f_v_a_r import Axis, NamedInstance
906
+
907
+ assert axes
908
+
909
+ fvar = newTable("fvar")
910
+ nameTable = font["name"]
911
+
912
+ for axis_def in axes:
913
+ axis = Axis()
914
+
915
+ if isinstance(axis_def, tuple):
916
+ (
917
+ axis.axisTag,
918
+ axis.minValue,
919
+ axis.defaultValue,
920
+ axis.maxValue,
921
+ name,
922
+ ) = axis_def
923
+ else:
924
+ (axis.axisTag, axis.minValue, axis.defaultValue, axis.maxValue, name) = (
925
+ axis_def.tag,
926
+ axis_def.minimum,
927
+ axis_def.default,
928
+ axis_def.maximum,
929
+ axis_def.name,
930
+ )
931
+
932
+ if isinstance(name, str):
933
+ name = dict(en=name)
934
+
935
+ axis.axisNameID = nameTable.addMultilingualName(name, ttFont=font)
936
+ fvar.axes.append(axis)
937
+
938
+ for instance in instances:
939
+ if isinstance(instance, dict):
940
+ coordinates = instance["location"]
941
+ name = instance["stylename"]
942
+ psname = instance.get("postscriptfontname")
943
+ else:
944
+ coordinates = instance.location
945
+ name = instance.localisedStyleName or instance.styleName
946
+ psname = instance.postScriptFontName
947
+
948
+ if isinstance(name, str):
949
+ name = dict(en=name)
950
+
951
+ inst = NamedInstance()
952
+ inst.subfamilyNameID = nameTable.addMultilingualName(name, ttFont=font)
953
+ if psname is not None:
954
+ inst.postscriptNameID = nameTable.addName(psname)
955
+ inst.coordinates = coordinates
956
+ fvar.instances.append(inst)
957
+
958
+ font["fvar"] = fvar
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/fontTools/help.py ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pkgutil
2
+ import sys
3
+ import fontTools
4
+ import importlib
5
+ import os
6
+ from pathlib import Path
7
+
8
+
9
+ def main():
10
+ """Show this help"""
11
+ path = fontTools.__path__
12
+ descriptions = {}
13
+ for pkg in sorted(
14
+ mod.name
15
+ for mod in pkgutil.walk_packages([fontTools.__path__[0]], prefix="fontTools.")
16
+ ):
17
+ try:
18
+ imports = __import__(pkg, globals(), locals(), ["main"])
19
+ except ImportError as e:
20
+ continue
21
+ try:
22
+ description = imports.main.__doc__
23
+ if description:
24
+ pkg = pkg.replace("fontTools.", "").replace(".__main__", "")
25
+ # show the docstring's first line only
26
+ descriptions[pkg] = description.splitlines()[0]
27
+ except AttributeError as e:
28
+ pass
29
+ for pkg, description in descriptions.items():
30
+ print("fonttools %-12s %s" % (pkg, description), file=sys.stderr)
31
+
32
+
33
+ if __name__ == "__main__":
34
+ print("fonttools v%s\n" % fontTools.__version__, file=sys.stderr)
35
+ main()
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/fontTools/tfmLib.py ADDED
@@ -0,0 +1,460 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Module for reading TFM (TeX Font Metrics) files.
2
+
3
+ The TFM format is described in the TFtoPL WEB source code, whose typeset form
4
+ can be found on `CTAN <http://mirrors.ctan.org/info/knuth-pdf/texware/tftopl.pdf>`_.
5
+
6
+ >>> from fontTools.tfmLib import TFM
7
+ >>> tfm = TFM("Tests/tfmLib/data/cmr10.tfm")
8
+ >>>
9
+ >>> # Accessing an attribute gets you metadata.
10
+ >>> tfm.checksum
11
+ 1274110073
12
+ >>> tfm.designsize
13
+ 10.0
14
+ >>> tfm.codingscheme
15
+ 'TeX text'
16
+ >>> tfm.family
17
+ 'CMR'
18
+ >>> tfm.seven_bit_safe_flag
19
+ False
20
+ >>> tfm.face
21
+ 234
22
+ >>> tfm.extraheader
23
+ {}
24
+ >>> tfm.fontdimens
25
+ {'SLANT': 0.0, 'SPACE': 0.33333396911621094, 'STRETCH': 0.16666698455810547, 'SHRINK': 0.11111164093017578, 'XHEIGHT': 0.4305553436279297, 'QUAD': 1.0000028610229492, 'EXTRASPACE': 0.11111164093017578}
26
+ >>> # Accessing a character gets you its metrics.
27
+ >>> # “width” is always available, other metrics are available only when
28
+ >>> # applicable. All values are relative to “designsize”.
29
+ >>> tfm.chars[ord("g")]
30
+ {'width': 0.5000019073486328, 'height': 0.4305553436279297, 'depth': 0.1944446563720703, 'italic': 0.013888359069824219}
31
+ >>> # Kerning and ligature can be accessed as well.
32
+ >>> tfm.kerning[ord("c")]
33
+ {104: -0.02777862548828125, 107: -0.02777862548828125}
34
+ >>> tfm.ligatures[ord("f")]
35
+ {105: ('LIG', 12), 102: ('LIG', 11), 108: ('LIG', 13)}
36
+ """
37
+
38
+ from types import SimpleNamespace
39
+
40
+ from fontTools.misc.sstruct import calcsize, unpack, unpack2
41
+
42
+ SIZES_FORMAT = """
43
+ >
44
+ lf: h # length of the entire file, in words
45
+ lh: h # length of the header data, in words
46
+ bc: h # smallest character code in the font
47
+ ec: h # largest character code in the font
48
+ nw: h # number of words in the width table
49
+ nh: h # number of words in the height table
50
+ nd: h # number of words in the depth table
51
+ ni: h # number of words in the italic correction table
52
+ nl: h # number of words in the ligature/kern table
53
+ nk: h # number of words in the kern table
54
+ ne: h # number of words in the extensible character table
55
+ np: h # number of font parameter words
56
+ """
57
+
58
+ SIZES_SIZE = calcsize(SIZES_FORMAT)
59
+
60
+ FIXED_FORMAT = "12.20F"
61
+
62
+ HEADER_FORMAT1 = f"""
63
+ >
64
+ checksum: L
65
+ designsize: {FIXED_FORMAT}
66
+ """
67
+
68
+ HEADER_FORMAT2 = f"""
69
+ {HEADER_FORMAT1}
70
+ codingscheme: 40p
71
+ """
72
+
73
+ HEADER_FORMAT3 = f"""
74
+ {HEADER_FORMAT2}
75
+ family: 20p
76
+ """
77
+
78
+ HEADER_FORMAT4 = f"""
79
+ {HEADER_FORMAT3}
80
+ seven_bit_safe_flag: ?
81
+ ignored: x
82
+ ignored: x
83
+ face: B
84
+ """
85
+
86
+ HEADER_SIZE1 = calcsize(HEADER_FORMAT1)
87
+ HEADER_SIZE2 = calcsize(HEADER_FORMAT2)
88
+ HEADER_SIZE3 = calcsize(HEADER_FORMAT3)
89
+ HEADER_SIZE4 = calcsize(HEADER_FORMAT4)
90
+
91
+ LIG_KERN_COMMAND = """
92
+ >
93
+ skip_byte: B
94
+ next_char: B
95
+ op_byte: B
96
+ remainder: B
97
+ """
98
+
99
+ BASE_PARAMS = [
100
+ "SLANT",
101
+ "SPACE",
102
+ "STRETCH",
103
+ "SHRINK",
104
+ "XHEIGHT",
105
+ "QUAD",
106
+ "EXTRASPACE",
107
+ ]
108
+
109
+ MATHSY_PARAMS = [
110
+ "NUM1",
111
+ "NUM2",
112
+ "NUM3",
113
+ "DENOM1",
114
+ "DENOM2",
115
+ "SUP1",
116
+ "SUP2",
117
+ "SUP3",
118
+ "SUB1",
119
+ "SUB2",
120
+ "SUPDROP",
121
+ "SUBDROP",
122
+ "DELIM1",
123
+ "DELIM2",
124
+ "AXISHEIGHT",
125
+ ]
126
+
127
+ MATHEX_PARAMS = [
128
+ "DEFAULTRULETHICKNESS",
129
+ "BIGOPSPACING1",
130
+ "BIGOPSPACING2",
131
+ "BIGOPSPACING3",
132
+ "BIGOPSPACING4",
133
+ "BIGOPSPACING5",
134
+ ]
135
+
136
+ VANILLA = 0
137
+ MATHSY = 1
138
+ MATHEX = 2
139
+
140
+ UNREACHABLE = 0
141
+ PASSTHROUGH = 1
142
+ ACCESSABLE = 2
143
+
144
+ NO_TAG = 0
145
+ LIG_TAG = 1
146
+ LIST_TAG = 2
147
+ EXT_TAG = 3
148
+
149
+ STOP_FLAG = 128
150
+ KERN_FLAG = 128
151
+
152
+
153
+ class TFMException(Exception):
154
+ def __init__(self, message):
155
+ super().__init__(message)
156
+
157
+
158
+ class TFM:
159
+ def __init__(self, file):
160
+ self._read(file)
161
+
162
+ def __repr__(self):
163
+ return (
164
+ f"<TFM"
165
+ f" for {self.family}"
166
+ f" in {self.codingscheme}"
167
+ f" at {self.designsize:g}pt>"
168
+ )
169
+
170
+ def _read(self, file):
171
+ if hasattr(file, "read"):
172
+ data = file.read()
173
+ else:
174
+ with open(file, "rb") as fp:
175
+ data = fp.read()
176
+
177
+ self._data = data
178
+
179
+ if len(data) < SIZES_SIZE:
180
+ raise TFMException("Too short input file")
181
+
182
+ sizes = SimpleNamespace()
183
+ unpack2(SIZES_FORMAT, data, sizes)
184
+
185
+ # Do some file structure sanity checks.
186
+ # TeX and TFtoPL do additional functional checks and might even correct
187
+ # “errors” in the input file, but we instead try to output the file as
188
+ # it is as long as it is parsable, even if the data make no sense.
189
+
190
+ if sizes.lf < 0:
191
+ raise TFMException("The file claims to have negative or zero length!")
192
+
193
+ if len(data) < sizes.lf * 4:
194
+ raise TFMException("The file has fewer bytes than it claims!")
195
+
196
+ for name, length in vars(sizes).items():
197
+ if length < 0:
198
+ raise TFMException("The subfile size: '{name}' is negative!")
199
+
200
+ if sizes.lh < 2:
201
+ raise TFMException(f"The header length is only {sizes.lh}!")
202
+
203
+ if sizes.bc > sizes.ec + 1 or sizes.ec > 255:
204
+ raise TFMException(
205
+ f"The character code range {sizes.bc}..{sizes.ec} is illegal!"
206
+ )
207
+
208
+ if sizes.nw == 0 or sizes.nh == 0 or sizes.nd == 0 or sizes.ni == 0:
209
+ raise TFMException("Incomplete subfiles for character dimensions!")
210
+
211
+ if sizes.ne > 256:
212
+ raise TFMException(f"There are {ne} extensible recipes!")
213
+
214
+ if sizes.lf != (
215
+ 6
216
+ + sizes.lh
217
+ + (sizes.ec - sizes.bc + 1)
218
+ + sizes.nw
219
+ + sizes.nh
220
+ + sizes.nd
221
+ + sizes.ni
222
+ + sizes.nl
223
+ + sizes.nk
224
+ + sizes.ne
225
+ + sizes.np
226
+ ):
227
+ raise TFMException("Subfile sizes don’t add up to the stated total")
228
+
229
+ # Subfile offsets, used in the helper function below. These all are
230
+ # 32-bit word offsets not 8-bit byte offsets.
231
+ char_base = 6 + sizes.lh - sizes.bc
232
+ width_base = char_base + sizes.ec + 1
233
+ height_base = width_base + sizes.nw
234
+ depth_base = height_base + sizes.nh
235
+ italic_base = depth_base + sizes.nd
236
+ lig_kern_base = italic_base + sizes.ni
237
+ kern_base = lig_kern_base + sizes.nl
238
+ exten_base = kern_base + sizes.nk
239
+ param_base = exten_base + sizes.ne
240
+
241
+ # Helper functions for accessing individual data. If this looks
242
+ # nonidiomatic Python, I blame the effect of reading the literate WEB
243
+ # documentation of TFtoPL.
244
+ def char_info(c):
245
+ return 4 * (char_base + c)
246
+
247
+ def width_index(c):
248
+ return data[char_info(c)]
249
+
250
+ def noneexistent(c):
251
+ return c < sizes.bc or c > sizes.ec or width_index(c) == 0
252
+
253
+ def height_index(c):
254
+ return data[char_info(c) + 1] // 16
255
+
256
+ def depth_index(c):
257
+ return data[char_info(c) + 1] % 16
258
+
259
+ def italic_index(c):
260
+ return data[char_info(c) + 2] // 4
261
+
262
+ def tag(c):
263
+ return data[char_info(c) + 2] % 4
264
+
265
+ def remainder(c):
266
+ return data[char_info(c) + 3]
267
+
268
+ def width(c):
269
+ r = 4 * (width_base + width_index(c))
270
+ return read_fixed(r, "v")["v"]
271
+
272
+ def height(c):
273
+ r = 4 * (height_base + height_index(c))
274
+ return read_fixed(r, "v")["v"]
275
+
276
+ def depth(c):
277
+ r = 4 * (depth_base + depth_index(c))
278
+ return read_fixed(r, "v")["v"]
279
+
280
+ def italic(c):
281
+ r = 4 * (italic_base + italic_index(c))
282
+ return read_fixed(r, "v")["v"]
283
+
284
+ def exten(c):
285
+ return 4 * (exten_base + remainder(c))
286
+
287
+ def lig_step(i):
288
+ return 4 * (lig_kern_base + i)
289
+
290
+ def lig_kern_command(i):
291
+ command = SimpleNamespace()
292
+ unpack2(LIG_KERN_COMMAND, data[i:], command)
293
+ return command
294
+
295
+ def kern(i):
296
+ r = 4 * (kern_base + i)
297
+ return read_fixed(r, "v")["v"]
298
+
299
+ def param(i):
300
+ return 4 * (param_base + i)
301
+
302
+ def read_fixed(index, key, obj=None):
303
+ ret = unpack2(f">;{key}:{FIXED_FORMAT}", data[index:], obj)
304
+ return ret[0]
305
+
306
+ # Set all attributes to empty values regardless of the header size.
307
+ unpack(HEADER_FORMAT4, [0] * HEADER_SIZE4, self)
308
+
309
+ offset = 24
310
+ length = sizes.lh * 4
311
+ self.extraheader = {}
312
+ if length >= HEADER_SIZE4:
313
+ rest = unpack2(HEADER_FORMAT4, data[offset:], self)[1]
314
+ if self.face < 18:
315
+ s = self.face % 2
316
+ b = self.face // 2
317
+ self.face = "MBL"[b % 3] + "RI"[s] + "RCE"[b // 3]
318
+ for i in range(sizes.lh - HEADER_SIZE4 // 4):
319
+ rest = unpack2(f">;HEADER{i + 18}:l", rest, self.extraheader)[1]
320
+ elif length >= HEADER_SIZE3:
321
+ unpack2(HEADER_FORMAT3, data[offset:], self)
322
+ elif length >= HEADER_SIZE2:
323
+ unpack2(HEADER_FORMAT2, data[offset:], self)
324
+ elif length >= HEADER_SIZE1:
325
+ unpack2(HEADER_FORMAT1, data[offset:], self)
326
+
327
+ self.fonttype = VANILLA
328
+ scheme = self.codingscheme.upper()
329
+ if scheme.startswith("TEX MATH SY"):
330
+ self.fonttype = MATHSY
331
+ elif scheme.startswith("TEX MATH EX"):
332
+ self.fonttype = MATHEX
333
+
334
+ self.fontdimens = {}
335
+ for i in range(sizes.np):
336
+ name = f"PARAMETER{i+1}"
337
+ if i <= 6:
338
+ name = BASE_PARAMS[i]
339
+ elif self.fonttype == MATHSY and i <= 21:
340
+ name = MATHSY_PARAMS[i - 7]
341
+ elif self.fonttype == MATHEX and i <= 12:
342
+ name = MATHEX_PARAMS[i - 7]
343
+ read_fixed(param(i), name, self.fontdimens)
344
+
345
+ lig_kern_map = {}
346
+ self.right_boundary_char = None
347
+ self.left_boundary_char = None
348
+ if sizes.nl > 0:
349
+ cmd = lig_kern_command(lig_step(0))
350
+ if cmd.skip_byte == 255:
351
+ self.right_boundary_char = cmd.next_char
352
+
353
+ cmd = lig_kern_command(lig_step((sizes.nl - 1)))
354
+ if cmd.skip_byte == 255:
355
+ self.left_boundary_char = 256
356
+ r = 256 * cmd.op_byte + cmd.remainder
357
+ lig_kern_map[self.left_boundary_char] = r
358
+
359
+ self.chars = {}
360
+ for c in range(sizes.bc, sizes.ec + 1):
361
+ if width_index(c) > 0:
362
+ self.chars[c] = info = {}
363
+ info["width"] = width(c)
364
+ if height_index(c) > 0:
365
+ info["height"] = height(c)
366
+ if depth_index(c) > 0:
367
+ info["depth"] = depth(c)
368
+ if italic_index(c) > 0:
369
+ info["italic"] = italic(c)
370
+ char_tag = tag(c)
371
+ if char_tag == NO_TAG:
372
+ pass
373
+ elif char_tag == LIG_TAG:
374
+ lig_kern_map[c] = remainder(c)
375
+ elif char_tag == LIST_TAG:
376
+ info["nextlarger"] = remainder(c)
377
+ elif char_tag == EXT_TAG:
378
+ info["varchar"] = varchar = {}
379
+ for i in range(4):
380
+ part = data[exten(c) + i]
381
+ if i == 3 or part > 0:
382
+ name = "rep"
383
+ if i == 0:
384
+ name = "top"
385
+ elif i == 1:
386
+ name = "mid"
387
+ elif i == 2:
388
+ name = "bot"
389
+ if noneexistent(part):
390
+ varchar[name] = c
391
+ else:
392
+ varchar[name] = part
393
+
394
+ self.ligatures = {}
395
+ self.kerning = {}
396
+ for c, i in sorted(lig_kern_map.items()):
397
+ cmd = lig_kern_command(lig_step(i))
398
+ if cmd.skip_byte > STOP_FLAG:
399
+ i = 256 * cmd.op_byte + cmd.remainder
400
+
401
+ while i < sizes.nl:
402
+ cmd = lig_kern_command(lig_step(i))
403
+ if cmd.skip_byte > STOP_FLAG:
404
+ pass
405
+ else:
406
+ if cmd.op_byte >= KERN_FLAG:
407
+ r = 256 * (cmd.op_byte - KERN_FLAG) + cmd.remainder
408
+ self.kerning.setdefault(c, {})[cmd.next_char] = kern(r)
409
+ else:
410
+ r = cmd.op_byte
411
+ if r == 4 or (r > 7 and r != 11):
412
+ # Ligature step with nonstandard code, we output
413
+ # the code verbatim.
414
+ lig = r
415
+ else:
416
+ lig = ""
417
+ if r % 4 > 1:
418
+ lig += "/"
419
+ lig += "LIG"
420
+ if r % 2 != 0:
421
+ lig += "/"
422
+ while r > 3:
423
+ lig += ">"
424
+ r -= 4
425
+ self.ligatures.setdefault(c, {})[cmd.next_char] = (
426
+ lig,
427
+ cmd.remainder,
428
+ )
429
+
430
+ if cmd.skip_byte >= STOP_FLAG:
431
+ break
432
+ i += cmd.skip_byte + 1
433
+
434
+
435
+ if __name__ == "__main__":
436
+ import sys
437
+
438
+ tfm = TFM(sys.argv[1])
439
+ print(
440
+ "\n".join(
441
+ x
442
+ for x in [
443
+ f"tfm.checksum={tfm.checksum}",
444
+ f"tfm.designsize={tfm.designsize}",
445
+ f"tfm.codingscheme={tfm.codingscheme}",
446
+ f"tfm.fonttype={tfm.fonttype}",
447
+ f"tfm.family={tfm.family}",
448
+ f"tfm.seven_bit_safe_flag={tfm.seven_bit_safe_flag}",
449
+ f"tfm.face={tfm.face}",
450
+ f"tfm.extraheader={tfm.extraheader}",
451
+ f"tfm.fontdimens={tfm.fontdimens}",
452
+ f"tfm.right_boundary_char={tfm.right_boundary_char}",
453
+ f"tfm.left_boundary_char={tfm.left_boundary_char}",
454
+ f"tfm.kerning={tfm.kerning}",
455
+ f"tfm.ligatures={tfm.ligatures}",
456
+ f"tfm.chars={tfm.chars}",
457
+ ]
458
+ )
459
+ )
460
+ print(tfm)
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/fontTools/ttx.py ADDED
@@ -0,0 +1,420 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """\
2
+ usage: ttx [options] inputfile1 [... inputfileN]
3
+
4
+ TTX -- From OpenType To XML And Back
5
+
6
+ If an input file is a TrueType or OpenType font file, it will be
7
+ decompiled to a TTX file (an XML-based text format).
8
+ If an input file is a TTX file, it will be compiled to whatever
9
+ format the data is in, a TrueType or OpenType/CFF font file.
10
+
11
+ Output files are created so they are unique: an existing file is
12
+ never overwritten.
13
+
14
+ General options
15
+ ===============
16
+
17
+ -h Help print this message.
18
+ --version show version and exit.
19
+ -d <outputfolder> Specify a directory where the output files are
20
+ to be created.
21
+ -o <outputfile> Specify a file to write the output to. A special
22
+ value of - would use the standard output.
23
+ -f Overwrite existing output file(s), ie. don't append
24
+ numbers.
25
+ -v Verbose: more messages will be written to stdout
26
+ about what is being done.
27
+ -q Quiet: No messages will be written to stdout about
28
+ what is being done.
29
+ -a allow virtual glyphs ID's on compile or decompile.
30
+
31
+ Dump options
32
+ ============
33
+
34
+ -l List table info: instead of dumping to a TTX file, list
35
+ some minimal info about each table.
36
+ -t <table> Specify a table to dump. Multiple -t options
37
+ are allowed. When no -t option is specified, all tables
38
+ will be dumped.
39
+ -x <table> Specify a table to exclude from the dump. Multiple
40
+ -x options are allowed. -t and -x are mutually exclusive.
41
+ -s Split tables: save the TTX data into separate TTX files per
42
+ table and write one small TTX file that contains references
43
+ to the individual table dumps. This file can be used as
44
+ input to ttx, as long as the table files are in the
45
+ same directory.
46
+ -g Split glyf table: Save the glyf data into separate TTX files
47
+ per glyph and write a small TTX for the glyf table which
48
+ contains references to the individual TTGlyph elements.
49
+ NOTE: specifying -g implies -s (no need for -s together
50
+ with -g)
51
+ -i Do NOT disassemble TT instructions: when this option is
52
+ given, all TrueType programs (glyph programs, the font
53
+ program and the pre-program) will be written to the TTX
54
+ file as hex data instead of assembly. This saves some time
55
+ and makes the TTX file smaller.
56
+ -z <format> Specify a bitmap data export option for EBDT:
57
+ {'raw', 'row', 'bitwise', 'extfile'} or for the CBDT:
58
+ {'raw', 'extfile'} Each option does one of the following:
59
+
60
+ -z raw
61
+ export the bitmap data as a hex dump
62
+ -z row
63
+ export each row as hex data
64
+ -z bitwise
65
+ export each row as binary in an ASCII art style
66
+ -z extfile
67
+ export the data as external files with XML references
68
+
69
+ If no export format is specified 'raw' format is used.
70
+ -e Don't ignore decompilation errors, but show a full traceback
71
+ and abort.
72
+ -y <number> Select font number for TrueType Collection (.ttc/.otc),
73
+ starting from 0.
74
+ --unicodedata <UnicodeData.txt>
75
+ Use custom database file to write character names in the
76
+ comments of the cmap TTX output.
77
+ --newline <value>
78
+ Control how line endings are written in the XML file. It
79
+ can be 'LF', 'CR', or 'CRLF'. If not specified, the
80
+ default platform-specific line endings are used.
81
+
82
+ Compile options
83
+ ===============
84
+
85
+ -m Merge with TrueType-input-file: specify a TrueType or
86
+ OpenType font file to be merged with the TTX file. This
87
+ option is only valid when at most one TTX file is specified.
88
+ -b Don't recalc glyph bounding boxes: use the values in the
89
+ TTX file as-is.
90
+ --recalc-timestamp
91
+ Set font 'modified' timestamp to current time.
92
+ By default, the modification time of the TTX file will be
93
+ used.
94
+ --no-recalc-timestamp
95
+ Keep the original font 'modified' timestamp.
96
+ --flavor <type>
97
+ Specify flavor of output font file. May be 'woff' or 'woff2'.
98
+ Note that WOFF2 requires the Brotli Python extension,
99
+ available at https://github.com/google/brotli
100
+ --with-zopfli
101
+ Use Zopfli instead of Zlib to compress WOFF. The Python
102
+ extension is available at https://pypi.python.org/pypi/zopfli
103
+ """
104
+
105
+
106
+ from fontTools.ttLib import TTFont, TTLibError
107
+ from fontTools.misc.macCreatorType import getMacCreatorAndType
108
+ from fontTools.unicode import setUnicodeData
109
+ from fontTools.misc.textTools import Tag, tostr
110
+ from fontTools.misc.timeTools import timestampSinceEpoch
111
+ from fontTools.misc.loggingTools import Timer
112
+ from fontTools.misc.cliTools import makeOutputFileName
113
+ import os
114
+ import sys
115
+ import getopt
116
+ import re
117
+ import logging
118
+
119
+
120
+ log = logging.getLogger("fontTools.ttx")
121
+
122
+ opentypeheaderRE = re.compile('''sfntVersion=['"]OTTO["']''')
123
+
124
+
125
+ class Options(object):
126
+
127
+ listTables = False
128
+ outputDir = None
129
+ outputFile = None
130
+ overWrite = False
131
+ verbose = False
132
+ quiet = False
133
+ splitTables = False
134
+ splitGlyphs = False
135
+ disassembleInstructions = True
136
+ mergeFile = None
137
+ recalcBBoxes = True
138
+ ignoreDecompileErrors = True
139
+ bitmapGlyphDataFormat = 'raw'
140
+ unicodedata = None
141
+ newlinestr = "\n"
142
+ recalcTimestamp = None
143
+ flavor = None
144
+ useZopfli = False
145
+
146
+ def __init__(self, rawOptions, numFiles):
147
+ self.onlyTables = []
148
+ self.skipTables = []
149
+ self.fontNumber = -1
150
+ for option, value in rawOptions:
151
+ # general options
152
+ if option == "-h":
153
+ print(__doc__)
154
+ sys.exit(0)
155
+ elif option == "--version":
156
+ from fontTools import version
157
+ print(version)
158
+ sys.exit(0)
159
+ elif option == "-d":
160
+ if not os.path.isdir(value):
161
+ raise getopt.GetoptError("The -d option value must be an existing directory")
162
+ self.outputDir = value
163
+ elif option == "-o":
164
+ self.outputFile = value
165
+ elif option == "-f":
166
+ self.overWrite = True
167
+ elif option == "-v":
168
+ self.verbose = True
169
+ elif option == "-q":
170
+ self.quiet = True
171
+ # dump options
172
+ elif option == "-l":
173
+ self.listTables = True
174
+ elif option == "-t":
175
+ # pad with space if table tag length is less than 4
176
+ value = value.ljust(4)
177
+ self.onlyTables.append(value)
178
+ elif option == "-x":
179
+ # pad with space if table tag length is less than 4
180
+ value = value.ljust(4)
181
+ self.skipTables.append(value)
182
+ elif option == "-s":
183
+ self.splitTables = True
184
+ elif option == "-g":
185
+ # -g implies (and forces) splitTables
186
+ self.splitGlyphs = True
187
+ self.splitTables = True
188
+ elif option == "-i":
189
+ self.disassembleInstructions = False
190
+ elif option == "-z":
191
+ validOptions = ('raw', 'row', 'bitwise', 'extfile')
192
+ if value not in validOptions:
193
+ raise getopt.GetoptError(
194
+ "-z does not allow %s as a format. Use %s" % (option, validOptions))
195
+ self.bitmapGlyphDataFormat = value
196
+ elif option == "-y":
197
+ self.fontNumber = int(value)
198
+ # compile options
199
+ elif option == "-m":
200
+ self.mergeFile = value
201
+ elif option == "-b":
202
+ self.recalcBBoxes = False
203
+ elif option == "-e":
204
+ self.ignoreDecompileErrors = False
205
+ elif option == "--unicodedata":
206
+ self.unicodedata = value
207
+ elif option == "--newline":
208
+ validOptions = ('LF', 'CR', 'CRLF')
209
+ if value == "LF":
210
+ self.newlinestr = "\n"
211
+ elif value == "CR":
212
+ self.newlinestr = "\r"
213
+ elif value == "CRLF":
214
+ self.newlinestr = "\r\n"
215
+ else:
216
+ raise getopt.GetoptError(
217
+ "Invalid choice for --newline: %r (choose from %s)"
218
+ % (value, ", ".join(map(repr, validOptions))))
219
+ elif option == "--recalc-timestamp":
220
+ self.recalcTimestamp = True
221
+ elif option == "--no-recalc-timestamp":
222
+ self.recalcTimestamp = False
223
+ elif option == "--flavor":
224
+ self.flavor = value
225
+ elif option == "--with-zopfli":
226
+ self.useZopfli = True
227
+ if self.verbose and self.quiet:
228
+ raise getopt.GetoptError("-q and -v options are mutually exclusive")
229
+ if self.verbose:
230
+ self.logLevel = logging.DEBUG
231
+ elif self.quiet:
232
+ self.logLevel = logging.WARNING
233
+ else:
234
+ self.logLevel = logging.INFO
235
+ if self.mergeFile and self.flavor:
236
+ raise getopt.GetoptError("-m and --flavor options are mutually exclusive")
237
+ if self.onlyTables and self.skipTables:
238
+ raise getopt.GetoptError("-t and -x options are mutually exclusive")
239
+ if self.mergeFile and numFiles > 1:
240
+ raise getopt.GetoptError("Must specify exactly one TTX source file when using -m")
241
+ if self.flavor != 'woff' and self.useZopfli:
242
+ raise getopt.GetoptError("--with-zopfli option requires --flavor 'woff'")
243
+
244
+
245
+ def ttList(input, output, options):
246
+ ttf = TTFont(input, fontNumber=options.fontNumber, lazy=True)
247
+ reader = ttf.reader
248
+ tags = sorted(reader.keys())
249
+ print('Listing table info for "%s":' % input)
250
+ format = " %4s %10s %8s %8s"
251
+ print(format % ("tag ", " checksum", " length", " offset"))
252
+ print(format % ("----", "----------", "--------", "--------"))
253
+ for tag in tags:
254
+ entry = reader.tables[tag]
255
+ if ttf.flavor == "woff2":
256
+ # WOFF2 doesn't store table checksums, so they must be calculated
257
+ from fontTools.ttLib.sfnt import calcChecksum
258
+ data = entry.loadData(reader.transformBuffer)
259
+ checkSum = calcChecksum(data)
260
+ else:
261
+ checkSum = int(entry.checkSum)
262
+ if checkSum < 0:
263
+ checkSum = checkSum + 0x100000000
264
+ checksum = "0x%08X" % checkSum
265
+ print(format % (tag, checksum, entry.length, entry.offset))
266
+ print()
267
+ ttf.close()
268
+
269
+
270
+ @Timer(log, 'Done dumping TTX in %(time).3f seconds')
271
+ def ttDump(input, output, options):
272
+ log.info('Dumping "%s" to "%s"...', input, output)
273
+ if options.unicodedata:
274
+ setUnicodeData(options.unicodedata)
275
+ ttf = TTFont(input, 0,
276
+ ignoreDecompileErrors=options.ignoreDecompileErrors,
277
+ fontNumber=options.fontNumber)
278
+ ttf.saveXML(output,
279
+ tables=options.onlyTables,
280
+ skipTables=options.skipTables,
281
+ splitTables=options.splitTables,
282
+ splitGlyphs=options.splitGlyphs,
283
+ disassembleInstructions=options.disassembleInstructions,
284
+ bitmapGlyphDataFormat=options.bitmapGlyphDataFormat,
285
+ newlinestr=options.newlinestr)
286
+ ttf.close()
287
+
288
+
289
+ @Timer(log, 'Done compiling TTX in %(time).3f seconds')
290
+ def ttCompile(input, output, options):
291
+ log.info('Compiling "%s" to "%s"...' % (input, output))
292
+ if options.useZopfli:
293
+ from fontTools.ttLib import sfnt
294
+ sfnt.USE_ZOPFLI = True
295
+ ttf = TTFont(options.mergeFile, flavor=options.flavor,
296
+ recalcBBoxes=options.recalcBBoxes,
297
+ recalcTimestamp=options.recalcTimestamp)
298
+ ttf.importXML(input)
299
+
300
+ if options.recalcTimestamp is None and 'head' in ttf:
301
+ # use TTX file modification time for head "modified" timestamp
302
+ mtime = os.path.getmtime(input)
303
+ ttf['head'].modified = timestampSinceEpoch(mtime)
304
+
305
+ ttf.save(output)
306
+
307
+
308
+ def guessFileType(fileName):
309
+ base, ext = os.path.splitext(fileName)
310
+ try:
311
+ with open(fileName, "rb") as f:
312
+ header = f.read(256)
313
+ except IOError:
314
+ return None
315
+
316
+ if header.startswith(b'\xef\xbb\xbf<?xml'):
317
+ header = header.lstrip(b'\xef\xbb\xbf')
318
+ cr, tp = getMacCreatorAndType(fileName)
319
+ if tp in ("sfnt", "FFIL"):
320
+ return "TTF"
321
+ if ext == ".dfont":
322
+ return "TTF"
323
+ head = Tag(header[:4])
324
+ if head == "OTTO":
325
+ return "OTF"
326
+ elif head == "ttcf":
327
+ return "TTC"
328
+ elif head in ("\0\1\0\0", "true"):
329
+ return "TTF"
330
+ elif head == "wOFF":
331
+ return "WOFF"
332
+ elif head == "wOF2":
333
+ return "WOFF2"
334
+ elif head == "<?xm":
335
+ # Use 'latin1' because that can't fail.
336
+ header = tostr(header, 'latin1')
337
+ if opentypeheaderRE.search(header):
338
+ return "OTX"
339
+ else:
340
+ return "TTX"
341
+ return None
342
+
343
+
344
+ def parseOptions(args):
345
+ rawOptions, files = getopt.getopt(args, "ld:o:fvqht:x:sgim:z:baey:",
346
+ ['unicodedata=', "recalc-timestamp", "no-recalc-timestamp",
347
+ 'flavor=', 'version', 'with-zopfli', 'newline='])
348
+
349
+ options = Options(rawOptions, len(files))
350
+ jobs = []
351
+
352
+ if not files:
353
+ raise getopt.GetoptError('Must specify at least one input file')
354
+
355
+ for input in files:
356
+ if not os.path.isfile(input):
357
+ raise getopt.GetoptError('File not found: "%s"' % input)
358
+ tp = guessFileType(input)
359
+ if tp in ("OTF", "TTF", "TTC", "WOFF", "WOFF2"):
360
+ extension = ".ttx"
361
+ if options.listTables:
362
+ action = ttList
363
+ else:
364
+ action = ttDump
365
+ elif tp == "TTX":
366
+ extension = "."+options.flavor if options.flavor else ".ttf"
367
+ action = ttCompile
368
+ elif tp == "OTX":
369
+ extension = "."+options.flavor if options.flavor else ".otf"
370
+ action = ttCompile
371
+ else:
372
+ raise getopt.GetoptError('Unknown file type: "%s"' % input)
373
+
374
+ if options.outputFile:
375
+ output = options.outputFile
376
+ else:
377
+ output = makeOutputFileName(input, options.outputDir, extension, options.overWrite)
378
+ # 'touch' output file to avoid race condition in choosing file names
379
+ if action != ttList:
380
+ open(output, 'a').close()
381
+ jobs.append((action, input, output))
382
+ return jobs, options
383
+
384
+
385
+ def process(jobs, options):
386
+ for action, input, output in jobs:
387
+ action(input, output, options)
388
+
389
+
390
+ def main(args=None):
391
+ """Convert OpenType fonts to XML and back"""
392
+ from fontTools import configLogger
393
+
394
+ if args is None:
395
+ args = sys.argv[1:]
396
+ try:
397
+ jobs, options = parseOptions(args)
398
+ except getopt.GetoptError as e:
399
+ print("%s\nERROR: %s" % (__doc__, e), file=sys.stderr)
400
+ sys.exit(2)
401
+
402
+ configLogger(level=options.logLevel)
403
+
404
+ try:
405
+ process(jobs, options)
406
+ except KeyboardInterrupt:
407
+ log.error("(Cancelled.)")
408
+ sys.exit(1)
409
+ except SystemExit:
410
+ raise
411
+ except TTLibError as e:
412
+ log.error(e)
413
+ sys.exit(1)
414
+ except:
415
+ log.exception('Unhandled exception has occurred')
416
+ sys.exit(1)
417
+
418
+
419
+ if __name__ == "__main__":
420
+ sys.exit(main())
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/fontTools/unicode.py ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ def _makeunicodes(f):
2
+ lines = iter(f.readlines())
3
+ unicodes = {}
4
+ for line in lines:
5
+ if not line: continue
6
+ num, name = line.split(';')[:2]
7
+ if name[0] == '<': continue # "<control>", etc.
8
+ num = int(num, 16)
9
+ unicodes[num] = name
10
+ return unicodes
11
+
12
+
13
+ class _UnicodeCustom(object):
14
+
15
+ def __init__(self, f):
16
+ if isinstance(f, str):
17
+ with open(f) as fd:
18
+ codes = _makeunicodes(fd)
19
+ else:
20
+ codes = _makeunicodes(f)
21
+ self.codes = codes
22
+
23
+ def __getitem__(self, charCode):
24
+ try:
25
+ return self.codes[charCode]
26
+ except KeyError:
27
+ return "????"
28
+
29
+ class _UnicodeBuiltin(object):
30
+
31
+ def __getitem__(self, charCode):
32
+ try:
33
+ # use unicodedata backport to python2, if available:
34
+ # https://github.com/mikekap/unicodedata2
35
+ import unicodedata2 as unicodedata
36
+ except ImportError:
37
+ import unicodedata
38
+ try:
39
+ return unicodedata.name(chr(charCode))
40
+ except ValueError:
41
+ return "????"
42
+
43
+ Unicode = _UnicodeBuiltin()
44
+
45
+ def setUnicodeData(f):
46
+ global Unicode
47
+ Unicode = _UnicodeCustom(f)
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/fonttools-4.34.4.dist-info/INSTALLER ADDED
@@ -0,0 +1 @@
 
 
1
+ pip
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/fonttools-4.34.4.dist-info/LICENSE ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ MIT License
2
+
3
+ Copyright (c) 2017 Just van Rossum
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/fonttools-4.34.4.dist-info/RECORD ADDED
@@ -0,0 +1,567 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ../../../bin/fonttools,sha256=ShmZ4DZsdGes7QyEyLH64GYmHgNOv7PMCuC_MwwtFEA,235
2
+ ../../../bin/pyftmerge,sha256=AW4xwMzLdJa5evF6YTHhzrtoIqY3-gU4c_Ldgoe18Mg,232
3
+ ../../../bin/pyftsubset,sha256=VvaYv1kcrQB0EtI6R5HOTjzQFheyP6shiZvXnhCrgyg,233
4
+ ../../../bin/ttx,sha256=YxCkDym_jmrKqG0RL3qiOKULO-S3SgqrSYTt-8fy16k,230
5
+ ../../../share/man/man1/ttx.1,sha256=cLbm_pOOj1C76T2QXvDxzwDj9gk-GTd5RztvTMsouFw,5377
6
+ fontTools/__init__.py,sha256=97ZMPvXRXGmoaoDQH6DrLuPO8zvAUNhpPQnCzNOupMg,183
7
+ fontTools/__main__.py,sha256=aq5EcFtSp-O7lKJVlIMkkJWdXNkqeEGD1GDF-AGm5os,844
8
+ fontTools/__pycache__/__init__.cpython-38.pyc,,
9
+ fontTools/__pycache__/__main__.cpython-38.pyc,,
10
+ fontTools/__pycache__/afmLib.cpython-38.pyc,,
11
+ fontTools/__pycache__/agl.cpython-38.pyc,,
12
+ fontTools/__pycache__/fontBuilder.cpython-38.pyc,,
13
+ fontTools/__pycache__/help.cpython-38.pyc,,
14
+ fontTools/__pycache__/tfmLib.cpython-38.pyc,,
15
+ fontTools/__pycache__/ttx.cpython-38.pyc,,
16
+ fontTools/__pycache__/unicode.cpython-38.pyc,,
17
+ fontTools/afmLib.py,sha256=LT4vyL-fRVbvkQNfVuChor1zsdOBnsiBOKcOGlDBdwo,11113
18
+ fontTools/agl.py,sha256=GZ5u9dcqIguFiu37GnP3e7B8kaVnPXvIbQsKMQjK-hE,112524
19
+ fontTools/cffLib/__init__.py,sha256=8PWUhdrK94znYJ8GxBNwHgQc9-C6ZTRBo39iEID3fUo,93329
20
+ fontTools/cffLib/__pycache__/__init__.cpython-38.pyc,,
21
+ fontTools/cffLib/__pycache__/specializer.cpython-38.pyc,,
22
+ fontTools/cffLib/__pycache__/width.cpython-38.pyc,,
23
+ fontTools/cffLib/specializer.py,sha256=6JTEnUyVhCd2ppjpc_bEXDAuYbAMngDPpRSFDdvV_ac,24894
24
+ fontTools/cffLib/width.py,sha256=9jhlgdANloe5ZGxdl214o8edRqftuwX6EORUxIVLFOs,5221
25
+ fontTools/colorLib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
26
+ fontTools/colorLib/__pycache__/__init__.cpython-38.pyc,,
27
+ fontTools/colorLib/__pycache__/builder.cpython-38.pyc,,
28
+ fontTools/colorLib/__pycache__/errors.cpython-38.pyc,,
29
+ fontTools/colorLib/__pycache__/geometry.cpython-38.pyc,,
30
+ fontTools/colorLib/__pycache__/table_builder.cpython-38.pyc,,
31
+ fontTools/colorLib/__pycache__/unbuilder.cpython-38.pyc,,
32
+ fontTools/colorLib/builder.py,sha256=Vm91SZJExSXkHZvQkiwFJ0SEUzySHml8LHwBQoUeBmk,22927
33
+ fontTools/colorLib/errors.py,sha256=9vNjxG-ow7oHmCIsxrIkLylABDbuqeYNqLBfDDqMCYI,42
34
+ fontTools/colorLib/geometry.py,sha256=3ScySrR2YDJa7d5K5_xM5Yt1-3NCV-ry8ikYA5VwVbI,5518
35
+ fontTools/colorLib/table_builder.py,sha256=9N_Cqe0GNWJYoekGbf4n-OrJq4A2pLYbUSa30GFv9sM,7485
36
+ fontTools/colorLib/unbuilder.py,sha256=iW-E5I39WsV82K3NgCO4Cjzwm1WqzGrtypHt8epwbHM,2142
37
+ fontTools/config/__init__.py,sha256=8rEgB2-CYrNyzjzmc59gShbflLLi-5vorTwvHcna4Bw,2104
38
+ fontTools/config/__pycache__/__init__.cpython-38.pyc,,
39
+ fontTools/cu2qu/__init__.py,sha256=Cuc7Uglb0nSgaraTxXY5J8bReznH5wApW0uakN7MycY,618
40
+ fontTools/cu2qu/__main__.py,sha256=IWCEMB0jcIxofHb_8NvVLmNBVRK9ZU8TQhN6TNAGrfE,83
41
+ fontTools/cu2qu/__pycache__/__init__.cpython-38.pyc,,
42
+ fontTools/cu2qu/__pycache__/__main__.cpython-38.pyc,,
43
+ fontTools/cu2qu/__pycache__/cli.cpython-38.pyc,,
44
+ fontTools/cu2qu/__pycache__/cu2qu.cpython-38.pyc,,
45
+ fontTools/cu2qu/__pycache__/errors.cpython-38.pyc,,
46
+ fontTools/cu2qu/__pycache__/ufo.cpython-38.pyc,,
47
+ fontTools/cu2qu/cli.py,sha256=LYHVxrT_xKCubcLOkTRn6G633ItazYIg8dQSQAShi3s,5826
48
+ fontTools/cu2qu/cu2qu.py,sha256=kjAxjsIjyez5RuMW7-dzshjhjbsBkG7wUXZ2U2qMsCc,16886
49
+ fontTools/cu2qu/errors.py,sha256=Hem7LksGDthtzVFnzFehxqVy4xwQlahs546v8H6ddNQ,2440
50
+ fontTools/cu2qu/ufo.py,sha256=1sHPa1bWCHyzauUebg41KAMWieOcin6RjTHEAw58PI8,11267
51
+ fontTools/designspaceLib/__init__.py,sha256=1UsZNGN4H1C7HZwiM9Ft_C-qDhM-mo_sj0b01ry2UEo,119952
52
+ fontTools/designspaceLib/__pycache__/__init__.cpython-38.pyc,,
53
+ fontTools/designspaceLib/__pycache__/split.cpython-38.pyc,,
54
+ fontTools/designspaceLib/__pycache__/statNames.cpython-38.pyc,,
55
+ fontTools/designspaceLib/__pycache__/types.cpython-38.pyc,,
56
+ fontTools/designspaceLib/split.py,sha256=wokwYtqTviJGu4tvkA6vjlWp1iMsSS7YK0PxhIdS8MA,17679
57
+ fontTools/designspaceLib/statNames.py,sha256=GxSydNHG4wdDtQSr1q6bTx1JCaEEHe-EvFF2TPGO91s,7958
58
+ fontTools/designspaceLib/types.py,sha256=ofK65qXNADqcpl7zI72Pa5s07-cm7G41iEmLVV44-Es,5320
59
+ fontTools/encodings/MacRoman.py,sha256=43gwuGL4EMBCdTB2pKBmRrGz6DkSVZqyllyxBu-aQi0,2621
60
+ fontTools/encodings/StandardEncoding.py,sha256=7jAuUzticDa5XJyXIpJI9SVXyigHzrhdxjVTEUlROdQ,2650
61
+ fontTools/encodings/__init__.py,sha256=DJBWmoX_Haau7qlgmvWyfbhSzrX2qL636Rns7CG01pk,75
62
+ fontTools/encodings/__pycache__/MacRoman.cpython-38.pyc,,
63
+ fontTools/encodings/__pycache__/StandardEncoding.cpython-38.pyc,,
64
+ fontTools/encodings/__pycache__/__init__.cpython-38.pyc,,
65
+ fontTools/encodings/__pycache__/codecs.cpython-38.pyc,,
66
+ fontTools/encodings/codecs.py,sha256=QvXZC4RjqECsLr11u3IIsEOphxXSLu5_p_J8vxyXDEo,3860
67
+ fontTools/feaLib/__init__.py,sha256=jlIru2ghxvb1HhC5Je2BCXjFJmFQlYKpruorPoz3BvQ,213
68
+ fontTools/feaLib/__main__.py,sha256=Df2PA6LXwna98lSXiL7R4as_ZEdWCIk3egSM5w7GpvM,2240
69
+ fontTools/feaLib/__pycache__/__init__.cpython-38.pyc,,
70
+ fontTools/feaLib/__pycache__/__main__.cpython-38.pyc,,
71
+ fontTools/feaLib/__pycache__/ast.cpython-38.pyc,,
72
+ fontTools/feaLib/__pycache__/builder.cpython-38.pyc,,
73
+ fontTools/feaLib/__pycache__/error.cpython-38.pyc,,
74
+ fontTools/feaLib/__pycache__/lexer.cpython-38.pyc,,
75
+ fontTools/feaLib/__pycache__/location.cpython-38.pyc,,
76
+ fontTools/feaLib/__pycache__/lookupDebugInfo.cpython-38.pyc,,
77
+ fontTools/feaLib/__pycache__/parser.cpython-38.pyc,,
78
+ fontTools/feaLib/__pycache__/variableScalar.cpython-38.pyc,,
79
+ fontTools/feaLib/ast.py,sha256=-GZtHYwkHHCcmxcqyDW8gy2BmO5TVMq6M4uHJZAoLRI,73554
80
+ fontTools/feaLib/builder.py,sha256=B67ln7tsWi9fWhGC100elBgpBZOzDVxVUjUTJ3K9vts,67151
81
+ fontTools/feaLib/error.py,sha256=Tq2dZUlCOyLfjTr3qibsT2g9t-S_JEf6bKgyNX55oCE,643
82
+ fontTools/feaLib/lexer.py,sha256=R4OTEyJMqHjwaefYZ4eMTw0dv8mIuN37L2SeO7tWcg0,11139
83
+ fontTools/feaLib/location.py,sha256=JXzHqGV56EHdcq823AwA5oaK05hf_1ySWpScbo3zGC0,234
84
+ fontTools/feaLib/lookupDebugInfo.py,sha256=sWvfEZiL9M9JPVH7_fZF_rSi7MpwoLagoZCSP2WLKSc,304
85
+ fontTools/feaLib/parser.py,sha256=k_dyBwQ3FWjVYzLvEm0QlPf4KgIiFu-PnVxnWtKO4mE,98216
86
+ fontTools/feaLib/variableScalar.py,sha256=TwsAn55FFVTYTL230Sn9tLP5jugUTwiLjI2ONbVxXuA,3281
87
+ fontTools/fontBuilder.py,sha256=t8LkdDpgRVizbHtEzLt74iX0HvlFK_5X4lie4cxAMuA,31177
88
+ fontTools/help.py,sha256=GCPl3WkgB6daag6N4yocVLPNGeyCdiYxdsUgHd0Yfkg,1027
89
+ fontTools/merge/__init__.py,sha256=cHh35sAeqOjgHLHAh2UVhulH1mag4L_Byf0P1D-5vjs,5756
90
+ fontTools/merge/__main__.py,sha256=vD5-bheoeotbQkRnFQg7nawCUeDKTmR1sqx3BcIYUt0,94
91
+ fontTools/merge/__pycache__/__init__.cpython-38.pyc,,
92
+ fontTools/merge/__pycache__/__main__.cpython-38.pyc,,
93
+ fontTools/merge/__pycache__/base.cpython-38.pyc,,
94
+ fontTools/merge/__pycache__/cmap.cpython-38.pyc,,
95
+ fontTools/merge/__pycache__/layout.cpython-38.pyc,,
96
+ fontTools/merge/__pycache__/options.cpython-38.pyc,,
97
+ fontTools/merge/__pycache__/tables.cpython-38.pyc,,
98
+ fontTools/merge/__pycache__/unicode.cpython-38.pyc,,
99
+ fontTools/merge/__pycache__/util.cpython-38.pyc,,
100
+ fontTools/merge/base.py,sha256=DTCsMkxq_u_OEBERaPvnPnwTVXPW8q1Jz68y9qORr9g,2048
101
+ fontTools/merge/cmap.py,sha256=EdXKoBu93roYInM82ws7JDY5fLZ8Qio6Lpc22lgymso,4655
102
+ fontTools/merge/layout.py,sha256=QTGofQUMoOE-0Zb1Z9YfvXXv5J8DEVzwRAPaLy17k5o,13314
103
+ fontTools/merge/options.py,sha256=UacirHGUBgQFGI8naBCFfL_JwsV0VP-UE_wpYIXjkag,1657
104
+ fontTools/merge/tables.py,sha256=0KWuth9LXwi5dljAicXF0pmdMo6Hz5QncmLoThD3_QM,8568
105
+ fontTools/merge/unicode.py,sha256=K1U1uIc33OseFas_KZJVoHHj32322fzRXadPkIfwofY,3915
106
+ fontTools/merge/util.py,sha256=xvP3P-OppYoTq1hdZR1P8ulB1itjjvCuLyn33nET3Es,2964
107
+ fontTools/misc/__init__.py,sha256=DJBWmoX_Haau7qlgmvWyfbhSzrX2qL636Rns7CG01pk,75
108
+ fontTools/misc/__pycache__/__init__.cpython-38.pyc,,
109
+ fontTools/misc/__pycache__/arrayTools.cpython-38.pyc,,
110
+ fontTools/misc/__pycache__/bezierTools.cpython-38.pyc,,
111
+ fontTools/misc/__pycache__/classifyTools.cpython-38.pyc,,
112
+ fontTools/misc/__pycache__/cliTools.cpython-38.pyc,,
113
+ fontTools/misc/__pycache__/configTools.cpython-38.pyc,,
114
+ fontTools/misc/__pycache__/cython.cpython-38.pyc,,
115
+ fontTools/misc/__pycache__/dictTools.cpython-38.pyc,,
116
+ fontTools/misc/__pycache__/eexec.cpython-38.pyc,,
117
+ fontTools/misc/__pycache__/encodingTools.cpython-38.pyc,,
118
+ fontTools/misc/__pycache__/etree.cpython-38.pyc,,
119
+ fontTools/misc/__pycache__/filenames.cpython-38.pyc,,
120
+ fontTools/misc/__pycache__/fixedTools.cpython-38.pyc,,
121
+ fontTools/misc/__pycache__/intTools.cpython-38.pyc,,
122
+ fontTools/misc/__pycache__/loggingTools.cpython-38.pyc,,
123
+ fontTools/misc/__pycache__/macCreatorType.cpython-38.pyc,,
124
+ fontTools/misc/__pycache__/macRes.cpython-38.pyc,,
125
+ fontTools/misc/__pycache__/psCharStrings.cpython-38.pyc,,
126
+ fontTools/misc/__pycache__/psLib.cpython-38.pyc,,
127
+ fontTools/misc/__pycache__/psOperators.cpython-38.pyc,,
128
+ fontTools/misc/__pycache__/py23.cpython-38.pyc,,
129
+ fontTools/misc/__pycache__/roundTools.cpython-38.pyc,,
130
+ fontTools/misc/__pycache__/sstruct.cpython-38.pyc,,
131
+ fontTools/misc/__pycache__/symfont.cpython-38.pyc,,
132
+ fontTools/misc/__pycache__/testTools.cpython-38.pyc,,
133
+ fontTools/misc/__pycache__/textTools.cpython-38.pyc,,
134
+ fontTools/misc/__pycache__/timeTools.cpython-38.pyc,,
135
+ fontTools/misc/__pycache__/transform.cpython-38.pyc,,
136
+ fontTools/misc/__pycache__/treeTools.cpython-38.pyc,,
137
+ fontTools/misc/__pycache__/vector.cpython-38.pyc,,
138
+ fontTools/misc/__pycache__/xmlReader.cpython-38.pyc,,
139
+ fontTools/misc/__pycache__/xmlWriter.cpython-38.pyc,,
140
+ fontTools/misc/arrayTools.py,sha256=RGm3ikjd5AnxWtmPJvkzPJSS59eprJQ5K7eTrT-pWWw,10722
141
+ fontTools/misc/bezierTools.py,sha256=rJFVm8qBBpp2gMbXjNc8sCsnv0BCCCZ-ZldgdnIKJVI,38272
142
+ fontTools/misc/classifyTools.py,sha256=GzXkEaFtVMqDxoiVJ05sUHQKXcFWHpQk9s7RxL1UMkI,4940
143
+ fontTools/misc/cliTools.py,sha256=3KsqYZc966IdCoqx0DjWge7s5BAZGpXV9EAnE8j9PW8,1665
144
+ fontTools/misc/configTools.py,sha256=X51UOl62wCGDqv9HCdcx-T5SixPrIxYj8Iju0etymYU,11187
145
+ fontTools/misc/cython.py,sha256=gO5qHKZPR-fiCp0ZD-BYvrOpxseB7FLs_r5IRD1-zhs,680
146
+ fontTools/misc/dictTools.py,sha256=L69sNH7DVKEmrLOENGzGv-b7qwH2KUUeX14ftlazIKE,2433
147
+ fontTools/misc/eexec.py,sha256=5HM5Y3RjIp48yUisBV1EJzNqfnua8ksupLyhtDF7mxg,2967
148
+ fontTools/misc/encodingTools.py,sha256=oPyIYCh-UbRnXxiHnquwOFSiE10YmKm1ZApK8pvaO3I,1703
149
+ fontTools/misc/etree.py,sha256=diYgYI9umsIumNIayDkIM3or7Gze7PBQZak_pgPDmi0,17087
150
+ fontTools/misc/filenames.py,sha256=k_zEQKP53gGTesleqTznTvbnz2VRV-XOzH5avtTpJXU,7164
151
+ fontTools/misc/fixedTools.py,sha256=EdCrh1UKr9XOvnqvPdv7X-bMLTQhgpcWBxLP7100AhI,6759
152
+ fontTools/misc/intTools.py,sha256=r_oMJOt6I-y6TvCRB58x2NFqji8rbCQTDS5p-ShK-fs,549
153
+ fontTools/misc/loggingTools.py,sha256=z9VNCzVgD57hYIh6Q6wlGNsaf17Agk9mbedamRK6FP4,17232
154
+ fontTools/misc/macCreatorType.py,sha256=47Di88HRVE7tdkDF1XAgnDEuZAly7RgGTIxa9nwbT5A,1374
155
+ fontTools/misc/macRes.py,sha256=2QviAShnX27C-btE-ljLXmdLuWQIg2h81mQMguaVjFI,7413
156
+ fontTools/misc/plistlib/__init__.py,sha256=qYKb0iEIQjf0nb5JuL_GOiBSBe0Lujx8OQofrjl8LZ4,21103
157
+ fontTools/misc/plistlib/__pycache__/__init__.cpython-38.pyc,,
158
+ fontTools/misc/plistlib/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
159
+ fontTools/misc/psCharStrings.py,sha256=nFP_gO739uC3AuMpUd8hxLjuY-s8USvc2LK5VB-PYMw,33952
160
+ fontTools/misc/psLib.py,sha256=MBDR4JgMxMhb28y3uucmuw1_CXt19aQowzfQsmERPoA,9604
161
+ fontTools/misc/psOperators.py,sha256=ozowyXOjddZPmb743upvMcFLP-oeogyv1F3yujOkgoQ,12810
162
+ fontTools/misc/py23.py,sha256=aPVCEUz_deggwLBCeTSsccX6QgJavZqvdVtuhpzrPvA,2238
163
+ fontTools/misc/roundTools.py,sha256=e8p7Tlj03Q63zJ_XBQ238qzN1ck54l-fkSZEUv_6dvo,3035
164
+ fontTools/misc/sstruct.py,sha256=HaQPC2jKvG9bduQ4a87dc4crcoX5N9nErIeXKLr9rHE,6054
165
+ fontTools/misc/symfont.py,sha256=GrsteeKbgYiCZLQAuEy3jbk3h1Nsxq57reM5tzeM6yc,5283
166
+ fontTools/misc/testTools.py,sha256=hf_ls57ndJJfjlQAxEGeaPj3YaXQr5luwPnhlLjRyCA,6922
167
+ fontTools/misc/textTools.py,sha256=m8D1l5-bvw-ymTkOL0EBV5milvb_yBDPPovdVDqZJkY,3093
168
+ fontTools/misc/timeTools.py,sha256=r0Mf4dkmh7FTHQ21zVQfP_JqeNZvYibub5p9GP-GIh4,2041
169
+ fontTools/misc/transform.py,sha256=L9KS64lgYuiKqiC_0RyyFBMhq4kbwP6Bv4_7vVgGSeA,9218
170
+ fontTools/misc/treeTools.py,sha256=tLWkwyDHeZUPVOGNnJeD4Pn7x2bQeZetwJKaEAW2J2M,1269
171
+ fontTools/misc/vector.py,sha256=ds9eoWVhS_W7YQacN0eAY_oWMEuLlA9-cJBMGEJEpbk,3819
172
+ fontTools/misc/xmlReader.py,sha256=RZAtVhzhGqPu1K2HSAgHrPWVtL12qwM17hj6qQGj9rE,4830
173
+ fontTools/misc/xmlWriter.py,sha256=E8CQkA_h_-JGmHZylIwl3bJiyhPc-RCfRL3ExQF86dA,5022
174
+ fontTools/mtiLib/__init__.py,sha256=8Xmkyb4ugMbqtWE1oP5zZUi9y3Ow_gYtvahX0z48Juw,37888
175
+ fontTools/mtiLib/__main__.py,sha256=dKBCSe1_qkBPH6PSVmfXmB_vH-gXh9pIwbFM3iAhmEM,91
176
+ fontTools/mtiLib/__pycache__/__init__.cpython-38.pyc,,
177
+ fontTools/mtiLib/__pycache__/__main__.cpython-38.pyc,,
178
+ fontTools/otlLib/__init__.py,sha256=D2leUW-3gsUTOFcJYGC18edBYjIJ804ut4qitJYWsaQ,45
179
+ fontTools/otlLib/__pycache__/__init__.cpython-38.pyc,,
180
+ fontTools/otlLib/__pycache__/builder.cpython-38.pyc,,
181
+ fontTools/otlLib/__pycache__/error.cpython-38.pyc,,
182
+ fontTools/otlLib/__pycache__/maxContextCalc.cpython-38.pyc,,
183
+ fontTools/otlLib/builder.py,sha256=yGvbz3D483AyxctXPuHDVnbGnFR-nE3h8jaXxtis48Q,109038
184
+ fontTools/otlLib/error.py,sha256=cthuhBuOwZYpkTLi5gFPupUxkXkCHe-L_YgkE7N1wCI,335
185
+ fontTools/otlLib/maxContextCalc.py,sha256=l3PeR9SrhzCTwMRuRzpGxBZJzIWppk1hUqGv6b3--AE,3187
186
+ fontTools/otlLib/optimize/__init__.py,sha256=Yl8wQdvO7SHwvSXsNaR2j4ZQwu2q11rJI1Kf58O6dV0,1531
187
+ fontTools/otlLib/optimize/__main__.py,sha256=GDrfuClFKSoep4tGD-1X_A65JQh2fcbiir14BefprtM,101
188
+ fontTools/otlLib/optimize/__pycache__/__init__.cpython-38.pyc,,
189
+ fontTools/otlLib/optimize/__pycache__/__main__.cpython-38.pyc,,
190
+ fontTools/otlLib/optimize/__pycache__/gpos.cpython-38.pyc,,
191
+ fontTools/otlLib/optimize/gpos.py,sha256=Ccq6-CNrsRXyDM6anrrUtG6F5iDKMe3jML4Q7Euw2g8,18475
192
+ fontTools/pens/__init__.py,sha256=DJBWmoX_Haau7qlgmvWyfbhSzrX2qL636Rns7CG01pk,75
193
+ fontTools/pens/__pycache__/__init__.cpython-38.pyc,,
194
+ fontTools/pens/__pycache__/areaPen.cpython-38.pyc,,
195
+ fontTools/pens/__pycache__/basePen.cpython-38.pyc,,
196
+ fontTools/pens/__pycache__/boundsPen.cpython-38.pyc,,
197
+ fontTools/pens/__pycache__/cocoaPen.cpython-38.pyc,,
198
+ fontTools/pens/__pycache__/cu2quPen.cpython-38.pyc,,
199
+ fontTools/pens/__pycache__/filterPen.cpython-38.pyc,,
200
+ fontTools/pens/__pycache__/freetypePen.cpython-38.pyc,,
201
+ fontTools/pens/__pycache__/hashPointPen.cpython-38.pyc,,
202
+ fontTools/pens/__pycache__/momentsPen.cpython-38.pyc,,
203
+ fontTools/pens/__pycache__/perimeterPen.cpython-38.pyc,,
204
+ fontTools/pens/__pycache__/pointInsidePen.cpython-38.pyc,,
205
+ fontTools/pens/__pycache__/pointPen.cpython-38.pyc,,
206
+ fontTools/pens/__pycache__/qtPen.cpython-38.pyc,,
207
+ fontTools/pens/__pycache__/quartzPen.cpython-38.pyc,,
208
+ fontTools/pens/__pycache__/recordingPen.cpython-38.pyc,,
209
+ fontTools/pens/__pycache__/reportLabPen.cpython-38.pyc,,
210
+ fontTools/pens/__pycache__/reverseContourPen.cpython-38.pyc,,
211
+ fontTools/pens/__pycache__/roundingPen.cpython-38.pyc,,
212
+ fontTools/pens/__pycache__/statisticsPen.cpython-38.pyc,,
213
+ fontTools/pens/__pycache__/svgPathPen.cpython-38.pyc,,
214
+ fontTools/pens/__pycache__/t2CharStringPen.cpython-38.pyc,,
215
+ fontTools/pens/__pycache__/teePen.cpython-38.pyc,,
216
+ fontTools/pens/__pycache__/transformPen.cpython-38.pyc,,
217
+ fontTools/pens/__pycache__/ttGlyphPen.cpython-38.pyc,,
218
+ fontTools/pens/__pycache__/wxPen.cpython-38.pyc,,
219
+ fontTools/pens/areaPen.py,sha256=EiIgKje7tIlA0JmYscMGpeuTj0-6IX1vqWANSOFDCss,1306
220
+ fontTools/pens/basePen.py,sha256=UJOl91xZKSQ5J0DLYDQweLB7WGbZYBGW4DsuMHiKBX0,13225
221
+ fontTools/pens/boundsPen.py,sha256=MpfbOO2NvhcDCqwJ80S020Gy7IyJlOH1owI33c8IQiI,2724
222
+ fontTools/pens/cocoaPen.py,sha256=_CvCJ_Fd-3-6SDcljyCLjSnUo3KKC9IqFPbel9nTmqQ,537
223
+ fontTools/pens/cu2quPen.py,sha256=ofeA-cOvjUyC31ma-ONeYN-_P23gbNJuJofazSQmc9w,10996
224
+ fontTools/pens/filterPen.py,sha256=wycKP3EQTkJirTQSem4mOQFmgD6_AzRfKdwb604IGSw,4732
225
+ fontTools/pens/freetypePen.py,sha256=MsIjlwvd54qQoSe3fqqGm4ZyhrhQi3-9B6X1yv5_KuQ,19813
226
+ fontTools/pens/hashPointPen.py,sha256=meUaKRMNEcw-rrvjSxcg-G4IU1nIsDLiwvpLeB2jISM,2647
227
+ fontTools/pens/momentsPen.py,sha256=xKwzNqDopxUIsVTxqewN0drz3bV_ZCQ-F0b3V1rBjm8,9439
228
+ fontTools/pens/perimeterPen.py,sha256=B9nzzmR-DJBrkMUmsW-VPEDfRXrLEN3lm0BbvS2323A,1892
229
+ fontTools/pens/pointInsidePen.py,sha256=KMxhGgx_w6ieVGcn2P5Y3Juwojmvye__YanO580CuDg,5244
230
+ fontTools/pens/pointPen.py,sha256=C8xNSkRbSLIFjiYLqVkOMLozmbrzHARI4rDVhXqfadM,15245
231
+ fontTools/pens/qtPen.py,sha256=mG64EfzJp0rR6ZkdN2Ks9PZffSiKkHjz1h6Hy2VXIGw,544
232
+ fontTools/pens/quartzPen.py,sha256=UotZzZKyaCAp_Jlnh3Ut11_q5M7-83bxD-A7Xw7Z6Qs,1175
233
+ fontTools/pens/recordingPen.py,sha256=Dql-HGDbhp1XEIONKV3IDFRZ3pLYYnNMGBcSwqEVSkA,4553
234
+ fontTools/pens/reportLabPen.py,sha256=BjjrxQ--mKydz8jwt-XMWHDl_stIBRBA10p3XUBdrx8,1783
235
+ fontTools/pens/reverseContourPen.py,sha256=5PmxS6yrfQsj3Bj4CWRqngyaRARblptNAwBzyyGcGXY,3849
236
+ fontTools/pens/roundingPen.py,sha256=8RRcfds10LRsQGghSMwOr-xJxpmH8Xk423A1VPmiIII,3803
237
+ fontTools/pens/statisticsPen.py,sha256=s6qcFClK4G2tpBQymBjmDZAT2x39jo4hR9dbZix9hAE,3084
238
+ fontTools/pens/svgPathPen.py,sha256=3YIZg77ClWYWd57Bjx3pomazLLDpGg3GM6sARw6gTy0,5401
239
+ fontTools/pens/t2CharStringPen.py,sha256=GUMRvNpXliRaQHJlrmG6gY8YK-qJcj9ZOMp1yVCIfdE,2395
240
+ fontTools/pens/teePen.py,sha256=7mZ32L3NQeqpnccqPJpkm2i4ejhxqhyj8R-84nk3Ewc,1107
241
+ fontTools/pens/transformPen.py,sha256=_Jof5dQDTVPjXKlITlY_GYoaKc3hE5RLIiRSm-argtw,3581
242
+ fontTools/pens/ttGlyphPen.py,sha256=4muXWdKlKMdqBE6sTXEzN-Y9M8ivSOPloExLWeRhvjQ,10133
243
+ fontTools/pens/wxPen.py,sha256=PYcwq9GdxrxoSScmO5hZehPAChFusbzOhtxNZX_IRrM,590
244
+ fontTools/subset/__init__.py,sha256=23RkJgu5m2wW4qOEWmLbIvvCv22eyoNAvG9OyC0tRR0,109805
245
+ fontTools/subset/__main__.py,sha256=OCrmxWb75I39dmEynBjTIveiIOIWLcjv17YAI9XuGWQ,95
246
+ fontTools/subset/__pycache__/__init__.cpython-38.pyc,,
247
+ fontTools/subset/__pycache__/__main__.cpython-38.pyc,,
248
+ fontTools/subset/__pycache__/cff.cpython-38.pyc,,
249
+ fontTools/subset/__pycache__/svg.cpython-38.pyc,,
250
+ fontTools/subset/__pycache__/util.cpython-38.pyc,,
251
+ fontTools/subset/cff.py,sha256=GWfYG1AA16RKCkEK2eiVwnTyEpg6DXTvz7xblOdiqDg,16020
252
+ fontTools/subset/svg.py,sha256=fZWmNk0XxNR7xM1ZBsXC2tsAhFS2hHVayvPTftzcFDw,9226
253
+ fontTools/subset/util.py,sha256=9SXFYb5Ef9Z58uXmYPCQil8B2i3Q7aFB_1fFDFSppdU,754
254
+ fontTools/svgLib/__init__.py,sha256=IGCLwSbU8jLhq6HI2vSdPQgNs6zDUi5774TgX5MCXPY,75
255
+ fontTools/svgLib/__pycache__/__init__.cpython-38.pyc,,
256
+ fontTools/svgLib/path/__init__.py,sha256=PFU73fS7Hk5w22s7cKjSVDVyMeNz3ridC9-w9eYK9Gs,1955
257
+ fontTools/svgLib/path/__pycache__/__init__.cpython-38.pyc,,
258
+ fontTools/svgLib/path/__pycache__/arc.cpython-38.pyc,,
259
+ fontTools/svgLib/path/__pycache__/parser.cpython-38.pyc,,
260
+ fontTools/svgLib/path/__pycache__/shapes.cpython-38.pyc,,
261
+ fontTools/svgLib/path/arc.py,sha256=Kio93A6r7OPbUXaDfdoBqyOIpn5vWpVdYdIjHMQfQSk,5812
262
+ fontTools/svgLib/path/parser.py,sha256=SH-iK3f64u5XUGlqOZQy6EQBU_Hkj6tDWEdsTGe1InM,10702
263
+ fontTools/svgLib/path/shapes.py,sha256=XaOJwy3avxWK4sqDQp4MTZ9x2fla7GLQNP5EFUNc98Q,5331
264
+ fontTools/t1Lib/__init__.py,sha256=pPVn5cTKfQsf9GpWILvoBKFACuQMsdHTWtElZINyvWY,16193
265
+ fontTools/t1Lib/__pycache__/__init__.cpython-38.pyc,,
266
+ fontTools/tfmLib.py,sha256=UMbkM73JXRJVS9t2B-BJc13rSjImaWBuzCoehLwHFhs,14270
267
+ fontTools/ttLib/__init__.py,sha256=Ca_dkbyKS-ygQTLQsWmAtlblPmwCUzRUH1T0zjPvlGE,482
268
+ fontTools/ttLib/__pycache__/__init__.cpython-38.pyc,,
269
+ fontTools/ttLib/__pycache__/macUtils.cpython-38.pyc,,
270
+ fontTools/ttLib/__pycache__/removeOverlaps.cpython-38.pyc,,
271
+ fontTools/ttLib/__pycache__/sfnt.cpython-38.pyc,,
272
+ fontTools/ttLib/__pycache__/standardGlyphOrder.cpython-38.pyc,,
273
+ fontTools/ttLib/__pycache__/ttCollection.cpython-38.pyc,,
274
+ fontTools/ttLib/__pycache__/ttFont.cpython-38.pyc,,
275
+ fontTools/ttLib/__pycache__/woff2.cpython-38.pyc,,
276
+ fontTools/ttLib/macUtils.py,sha256=ozNVoId2eExYEPR4YYrB31snBHHw5NPNvba2pl_nsWU,1540
277
+ fontTools/ttLib/removeOverlaps.py,sha256=jZuClS9U6MynO1E-20gLTvWgocriwqsaLflTyS0Mg_Q,8098
278
+ fontTools/ttLib/sfnt.py,sha256=Rss6d8JEutQFGDWToHH5lLoAQpTF4N77j4Q8zws89Tw,19447
279
+ fontTools/ttLib/standardGlyphOrder.py,sha256=1Dg71QRuhqPtz7yUnknqVngHMLuUmRCkUi9vIZ_VVfA,8302
280
+ fontTools/ttLib/tables/B_A_S_E_.py,sha256=4x2FrRE1TrJ3dzRYtmmy5jLY7PdTKRBJih3u-XBhyYw,85
281
+ fontTools/ttLib/tables/BitmapGlyphMetrics.py,sha256=sTJGi3bhDEVW1aoe0F6EXhcR0baPFp7hOXrd9XPrkfM,1536
282
+ fontTools/ttLib/tables/C_B_D_T_.py,sha256=frhj07AobeNcGMTW-ghx2Vj3b1-85V21ujcT2irSvJY,3033
283
+ fontTools/ttLib/tables/C_B_L_C_.py,sha256=SqMV3Rp5fKI6fI4DH2zOEzy1xh0oY8Bz1R4QuIetjxA,185
284
+ fontTools/ttLib/tables/C_F_F_.py,sha256=sEGy10tZOhHmPKMMWMUQnHFbxjMinw8scYMtVtEgfGs,1259
285
+ fontTools/ttLib/tables/C_F_F__2.py,sha256=sb1Zvn7STQO5JIMRjvt_lMXDQ6Is2AOxy8P8xAY4yO8,426
286
+ fontTools/ttLib/tables/C_O_L_R_.py,sha256=807Nl5UlYmCgzyp5UvmXx7mHDlE2_VG9yQ5_ki3gkKo,4784
287
+ fontTools/ttLib/tables/C_P_A_L_.py,sha256=gpCpjYLaOTnsGZmWUo6lci4rduVxm8IeS8OgZP3dtGI,9473
288
+ fontTools/ttLib/tables/D_S_I_G_.py,sha256=qLs_sF62otfMQn6Pe1v_3s0nERJSHlJt4i_jf0brL10,4572
289
+ fontTools/ttLib/tables/D__e_b_g.py,sha256=2_oy6wxqGWDDmeLkDC3p6yiQAPz8U96oJUnLCup5VDg,433
290
+ fontTools/ttLib/tables/DefaultTable.py,sha256=KRxOrAYMqd0_a-TD4kl3Bd1ehPuSiYzKAr7sqvA8Ma8,1282
291
+ fontTools/ttLib/tables/E_B_D_T_.py,sha256=ZNxyZG9GmrWI3RwCh_vPNjEognneArWt0Y_e3VuCEn0,27177
292
+ fontTools/ttLib/tables/E_B_L_C_.py,sha256=7oMPOw5K_fQXgbSacEYBRV3HD6rsOVp4SNYokX3aqhg,25146
293
+ fontTools/ttLib/tables/F_F_T_M_.py,sha256=Le3rqVHM9cqLExp15L4HVtyBK6aKJJgJ81oUXg9GhZk,1188
294
+ fontTools/ttLib/tables/F__e_a_t.py,sha256=Xk5VBiAnTz3cr7py5pRFoKbLxh_wEk9TxiGxfB9zGd4,4996
295
+ fontTools/ttLib/tables/G_D_E_F_.py,sha256=wJMXPrD9qgtvdm9U0VKwfoSW_rvQX5NBCJ9ullSmYg8,85
296
+ fontTools/ttLib/tables/G_M_A_P_.py,sha256=D4DC-uLIuHVaR0ErYkQB7DVJUdD1xkGRPaZWy40zfFw,3724
297
+ fontTools/ttLib/tables/G_P_K_G_.py,sha256=O4YTuMBB2Lg88KFXt1-XGjtoEY-BB8-1yc6qkfBAAdU,3646
298
+ fontTools/ttLib/tables/G_P_O_S_.py,sha256=G2d4yWSp2NmJQNTMX7lvqCslzkJPowJ46eOb80ZVtKM,85
299
+ fontTools/ttLib/tables/G_S_U_B_.py,sha256=OP6bMn3fdP_p3hErIM2Y4JLdo-fYwWbcs3_MO9G6XCM,85
300
+ fontTools/ttLib/tables/G__l_a_t.py,sha256=Gi2RLP1N4HAiRsZAVGPXrugYx3rpi2WRK6AdSqn1U9g,8400
301
+ fontTools/ttLib/tables/G__l_o_c.py,sha256=DDr_kJlO4J3_ju9TTuPZqZwCeNWbi0Ex0w0PQvtY2xg,2444
302
+ fontTools/ttLib/tables/H_V_A_R_.py,sha256=1SCRvlX1eK1e6-sKnzaa9R0MbAmaCVB8X7pqrCdgdI0,85
303
+ fontTools/ttLib/tables/J_S_T_F_.py,sha256=MQf8KGvJsN_OaGSzZapRvKsCv6kVYt9lLB6P-6vgICc,85
304
+ fontTools/ttLib/tables/L_T_S_H_.py,sha256=kRF-N8ye7OtYRBAiRHbvxV884Q9Ar5W9SGkdUZxWnsY,1613
305
+ fontTools/ttLib/tables/M_A_T_H_.py,sha256=UeJ-Obm9AVVPS00Bfc16gP5P_m8sh3xpQZ0wJF3Bgtk,85
306
+ fontTools/ttLib/tables/M_E_T_A_.py,sha256=5xtxNRi8xk3MOhxm8lQVp78LInmMNo56WrUuuPJa7lI,9362
307
+ fontTools/ttLib/tables/M_V_A_R_.py,sha256=FstEACLz7uacX8yOhT4EFaGuPchjKDijAMzXxrJYCek,85
308
+ fontTools/ttLib/tables/O_S_2f_2.py,sha256=MGVt52dYa291bkUeaSMGLXgmB7dxhRxyyaMzDLilefY,23641
309
+ fontTools/ttLib/tables/S_I_N_G_.py,sha256=E1d6YxtbNjHDS0JEOdbNwzxqlq1oOic4jXXc3qFljsg,2661
310
+ fontTools/ttLib/tables/S_T_A_T_.py,sha256=tPbD_6x4aJACOux8bKe_sFlk0PEat7aiZn8pnXoUGws,88
311
+ fontTools/ttLib/tables/S_V_G_.py,sha256=PplHChKcp9uSVsp5Bg1US0AoHmprxurvwDyU3TcWMIY,6014
312
+ fontTools/ttLib/tables/S__i_l_f.py,sha256=msryU0Hn2mtimgw3B6wYRzCcpRXpMJwAmx3fF9yiT7A,33295
313
+ fontTools/ttLib/tables/S__i_l_l.py,sha256=UF_7a3RuncFH2Lq2MOWp8_7rFaRLxZHSy2xOwU2KYg4,3053
314
+ fontTools/ttLib/tables/T_S_I_B_.py,sha256=4iMSLv0IvU8HijicUZO4hR4NZ4_18d4S6vPGRlkjPsc,82
315
+ fontTools/ttLib/tables/T_S_I_C_.py,sha256=TjDKgGdFEaL4Affo9MTInuVKbYUHMa0pJX18pzgYxT0,88
316
+ fontTools/ttLib/tables/T_S_I_D_.py,sha256=Sl8bSkVK9wmIZjhn8SMirK7jCCLOXhAg5Mk3FijGiXI,82
317
+ fontTools/ttLib/tables/T_S_I_J_.py,sha256=dFnVt_7DvPXe3lri4nuG3NHwXBRMRILK9mO9AaGIvHg,82
318
+ fontTools/ttLib/tables/T_S_I_P_.py,sha256=vDVnjHFAT_1dK9FOocI1vIyrSynSzy2m00iVB6XCMeI,82
319
+ fontTools/ttLib/tables/T_S_I_S_.py,sha256=XXcQeIWaMSWAbSJl6rqJTjreG0A1Bi9YEvewD0YgATI,82
320
+ fontTools/ttLib/tables/T_S_I_V_.py,sha256=oHAWqySjTqSvbY5sRW4mo3v1Y4WhMYs9xdWqz1-yCak,577
321
+ fontTools/ttLib/tables/T_S_I__0.py,sha256=Wan-zOh3hJ1MnDnDogqZfjCuU-tOi34gv6dP2whGrZw,1808
322
+ fontTools/ttLib/tables/T_S_I__1.py,sha256=Zj3HwfsV6GJmeFQ6T8_Cljp4yBR7-5JTiFh733Pm8Q4,5318
323
+ fontTools/ttLib/tables/T_S_I__2.py,sha256=w0PkAzBUKzI9CCnjbffXdD03g14VHgF5ZTLV858NZU4,416
324
+ fontTools/ttLib/tables/T_S_I__3.py,sha256=0vGq0UPNIBItoTSDVMdmvSOXvJgXU7_QaFK9-Qq-PuE,421
325
+ fontTools/ttLib/tables/T_S_I__5.py,sha256=CjLpMBZvGldNuk-0Pykb2m2sz7yhhcUxCOgDxk-jQHg,1288
326
+ fontTools/ttLib/tables/T_T_F_A_.py,sha256=1qUgVPhufFCqVqGc0IZTv7qLFdUwh06SzlegkXSQMdo,77
327
+ fontTools/ttLib/tables/TupleVariation.py,sha256=-r39STlm1E0cLBKMS1qEZtSMCqBZh-ozvDLySxjXooA,24273
328
+ fontTools/ttLib/tables/V_D_M_X_.py,sha256=EPoMRSo9eHRcHyaduO3YMpfznYxf0bf-I20JJ4jRCcw,8187
329
+ fontTools/ttLib/tables/V_O_R_G_.py,sha256=AZdLdd6NFqF4-QcmVv5hUUX_7YAKBesDOKYcu7wvk0w,4730
330
+ fontTools/ttLib/tables/V_V_A_R_.py,sha256=qo17ZU8m2jEpc4fcFOGZ07mRLtkSPXFOWcbFuda-oDA,85
331
+ fontTools/ttLib/tables/__init__.py,sha256=Y2r9RXUSdOd-1OOfLSPvkJ5Ta2JfUUH4wONjPtrvitg,2326
332
+ fontTools/ttLib/tables/__pycache__/B_A_S_E_.cpython-38.pyc,,
333
+ fontTools/ttLib/tables/__pycache__/BitmapGlyphMetrics.cpython-38.pyc,,
334
+ fontTools/ttLib/tables/__pycache__/C_B_D_T_.cpython-38.pyc,,
335
+ fontTools/ttLib/tables/__pycache__/C_B_L_C_.cpython-38.pyc,,
336
+ fontTools/ttLib/tables/__pycache__/C_F_F_.cpython-38.pyc,,
337
+ fontTools/ttLib/tables/__pycache__/C_F_F__2.cpython-38.pyc,,
338
+ fontTools/ttLib/tables/__pycache__/C_O_L_R_.cpython-38.pyc,,
339
+ fontTools/ttLib/tables/__pycache__/C_P_A_L_.cpython-38.pyc,,
340
+ fontTools/ttLib/tables/__pycache__/D_S_I_G_.cpython-38.pyc,,
341
+ fontTools/ttLib/tables/__pycache__/D__e_b_g.cpython-38.pyc,,
342
+ fontTools/ttLib/tables/__pycache__/DefaultTable.cpython-38.pyc,,
343
+ fontTools/ttLib/tables/__pycache__/E_B_D_T_.cpython-38.pyc,,
344
+ fontTools/ttLib/tables/__pycache__/E_B_L_C_.cpython-38.pyc,,
345
+ fontTools/ttLib/tables/__pycache__/F_F_T_M_.cpython-38.pyc,,
346
+ fontTools/ttLib/tables/__pycache__/F__e_a_t.cpython-38.pyc,,
347
+ fontTools/ttLib/tables/__pycache__/G_D_E_F_.cpython-38.pyc,,
348
+ fontTools/ttLib/tables/__pycache__/G_M_A_P_.cpython-38.pyc,,
349
+ fontTools/ttLib/tables/__pycache__/G_P_K_G_.cpython-38.pyc,,
350
+ fontTools/ttLib/tables/__pycache__/G_P_O_S_.cpython-38.pyc,,
351
+ fontTools/ttLib/tables/__pycache__/G_S_U_B_.cpython-38.pyc,,
352
+ fontTools/ttLib/tables/__pycache__/G__l_a_t.cpython-38.pyc,,
353
+ fontTools/ttLib/tables/__pycache__/G__l_o_c.cpython-38.pyc,,
354
+ fontTools/ttLib/tables/__pycache__/H_V_A_R_.cpython-38.pyc,,
355
+ fontTools/ttLib/tables/__pycache__/J_S_T_F_.cpython-38.pyc,,
356
+ fontTools/ttLib/tables/__pycache__/L_T_S_H_.cpython-38.pyc,,
357
+ fontTools/ttLib/tables/__pycache__/M_A_T_H_.cpython-38.pyc,,
358
+ fontTools/ttLib/tables/__pycache__/M_E_T_A_.cpython-38.pyc,,
359
+ fontTools/ttLib/tables/__pycache__/M_V_A_R_.cpython-38.pyc,,
360
+ fontTools/ttLib/tables/__pycache__/O_S_2f_2.cpython-38.pyc,,
361
+ fontTools/ttLib/tables/__pycache__/S_I_N_G_.cpython-38.pyc,,
362
+ fontTools/ttLib/tables/__pycache__/S_T_A_T_.cpython-38.pyc,,
363
+ fontTools/ttLib/tables/__pycache__/S_V_G_.cpython-38.pyc,,
364
+ fontTools/ttLib/tables/__pycache__/S__i_l_f.cpython-38.pyc,,
365
+ fontTools/ttLib/tables/__pycache__/S__i_l_l.cpython-38.pyc,,
366
+ fontTools/ttLib/tables/__pycache__/T_S_I_B_.cpython-38.pyc,,
367
+ fontTools/ttLib/tables/__pycache__/T_S_I_C_.cpython-38.pyc,,
368
+ fontTools/ttLib/tables/__pycache__/T_S_I_D_.cpython-38.pyc,,
369
+ fontTools/ttLib/tables/__pycache__/T_S_I_J_.cpython-38.pyc,,
370
+ fontTools/ttLib/tables/__pycache__/T_S_I_P_.cpython-38.pyc,,
371
+ fontTools/ttLib/tables/__pycache__/T_S_I_S_.cpython-38.pyc,,
372
+ fontTools/ttLib/tables/__pycache__/T_S_I_V_.cpython-38.pyc,,
373
+ fontTools/ttLib/tables/__pycache__/T_S_I__0.cpython-38.pyc,,
374
+ fontTools/ttLib/tables/__pycache__/T_S_I__1.cpython-38.pyc,,
375
+ fontTools/ttLib/tables/__pycache__/T_S_I__2.cpython-38.pyc,,
376
+ fontTools/ttLib/tables/__pycache__/T_S_I__3.cpython-38.pyc,,
377
+ fontTools/ttLib/tables/__pycache__/T_S_I__5.cpython-38.pyc,,
378
+ fontTools/ttLib/tables/__pycache__/T_T_F_A_.cpython-38.pyc,,
379
+ fontTools/ttLib/tables/__pycache__/TupleVariation.cpython-38.pyc,,
380
+ fontTools/ttLib/tables/__pycache__/V_D_M_X_.cpython-38.pyc,,
381
+ fontTools/ttLib/tables/__pycache__/V_O_R_G_.cpython-38.pyc,,
382
+ fontTools/ttLib/tables/__pycache__/V_V_A_R_.cpython-38.pyc,,
383
+ fontTools/ttLib/tables/__pycache__/__init__.cpython-38.pyc,,
384
+ fontTools/ttLib/tables/__pycache__/_a_n_k_r.cpython-38.pyc,,
385
+ fontTools/ttLib/tables/__pycache__/_a_v_a_r.cpython-38.pyc,,
386
+ fontTools/ttLib/tables/__pycache__/_b_s_l_n.cpython-38.pyc,,
387
+ fontTools/ttLib/tables/__pycache__/_c_i_d_g.cpython-38.pyc,,
388
+ fontTools/ttLib/tables/__pycache__/_c_m_a_p.cpython-38.pyc,,
389
+ fontTools/ttLib/tables/__pycache__/_c_v_a_r.cpython-38.pyc,,
390
+ fontTools/ttLib/tables/__pycache__/_c_v_t.cpython-38.pyc,,
391
+ fontTools/ttLib/tables/__pycache__/_f_e_a_t.cpython-38.pyc,,
392
+ fontTools/ttLib/tables/__pycache__/_f_p_g_m.cpython-38.pyc,,
393
+ fontTools/ttLib/tables/__pycache__/_f_v_a_r.cpython-38.pyc,,
394
+ fontTools/ttLib/tables/__pycache__/_g_a_s_p.cpython-38.pyc,,
395
+ fontTools/ttLib/tables/__pycache__/_g_c_i_d.cpython-38.pyc,,
396
+ fontTools/ttLib/tables/__pycache__/_g_l_y_f.cpython-38.pyc,,
397
+ fontTools/ttLib/tables/__pycache__/_g_v_a_r.cpython-38.pyc,,
398
+ fontTools/ttLib/tables/__pycache__/_h_d_m_x.cpython-38.pyc,,
399
+ fontTools/ttLib/tables/__pycache__/_h_e_a_d.cpython-38.pyc,,
400
+ fontTools/ttLib/tables/__pycache__/_h_h_e_a.cpython-38.pyc,,
401
+ fontTools/ttLib/tables/__pycache__/_h_m_t_x.cpython-38.pyc,,
402
+ fontTools/ttLib/tables/__pycache__/_k_e_r_n.cpython-38.pyc,,
403
+ fontTools/ttLib/tables/__pycache__/_l_c_a_r.cpython-38.pyc,,
404
+ fontTools/ttLib/tables/__pycache__/_l_o_c_a.cpython-38.pyc,,
405
+ fontTools/ttLib/tables/__pycache__/_l_t_a_g.cpython-38.pyc,,
406
+ fontTools/ttLib/tables/__pycache__/_m_a_x_p.cpython-38.pyc,,
407
+ fontTools/ttLib/tables/__pycache__/_m_e_t_a.cpython-38.pyc,,
408
+ fontTools/ttLib/tables/__pycache__/_m_o_r_t.cpython-38.pyc,,
409
+ fontTools/ttLib/tables/__pycache__/_m_o_r_x.cpython-38.pyc,,
410
+ fontTools/ttLib/tables/__pycache__/_n_a_m_e.cpython-38.pyc,,
411
+ fontTools/ttLib/tables/__pycache__/_o_p_b_d.cpython-38.pyc,,
412
+ fontTools/ttLib/tables/__pycache__/_p_o_s_t.cpython-38.pyc,,
413
+ fontTools/ttLib/tables/__pycache__/_p_r_e_p.cpython-38.pyc,,
414
+ fontTools/ttLib/tables/__pycache__/_p_r_o_p.cpython-38.pyc,,
415
+ fontTools/ttLib/tables/__pycache__/_s_b_i_x.cpython-38.pyc,,
416
+ fontTools/ttLib/tables/__pycache__/_t_r_a_k.cpython-38.pyc,,
417
+ fontTools/ttLib/tables/__pycache__/_v_h_e_a.cpython-38.pyc,,
418
+ fontTools/ttLib/tables/__pycache__/_v_m_t_x.cpython-38.pyc,,
419
+ fontTools/ttLib/tables/__pycache__/asciiTable.cpython-38.pyc,,
420
+ fontTools/ttLib/tables/__pycache__/grUtils.cpython-38.pyc,,
421
+ fontTools/ttLib/tables/__pycache__/otBase.cpython-38.pyc,,
422
+ fontTools/ttLib/tables/__pycache__/otConverters.cpython-38.pyc,,
423
+ fontTools/ttLib/tables/__pycache__/otData.cpython-38.pyc,,
424
+ fontTools/ttLib/tables/__pycache__/otTables.cpython-38.pyc,,
425
+ fontTools/ttLib/tables/__pycache__/otTraverse.cpython-38.pyc,,
426
+ fontTools/ttLib/tables/__pycache__/sbixGlyph.cpython-38.pyc,,
427
+ fontTools/ttLib/tables/__pycache__/sbixStrike.cpython-38.pyc,,
428
+ fontTools/ttLib/tables/__pycache__/ttProgram.cpython-38.pyc,,
429
+ fontTools/ttLib/tables/_a_n_k_r.py,sha256=ZlT4BJeQODC_zMdFyiokdHS6BvXp2wQgOOAkvtXe6Xw,460
430
+ fontTools/ttLib/tables/_a_v_a_r.py,sha256=LE2gVaA1bcaIKAeBrQoNvjtl3_ubn9M7XGdEyWpgKwA,4534
431
+ fontTools/ttLib/tables/_b_s_l_n.py,sha256=D1tRo8TDAUxeCqVWsTma9u2VxRzxUkCpF84Lv_hy4rU,170
432
+ fontTools/ttLib/tables/_c_i_d_g.py,sha256=OSR64lQMwsmk5X1pHMz7pUdoIdTVeEFfTOZIda90nE4,751
433
+ fontTools/ttLib/tables/_c_m_a_p.py,sha256=opOLsIAToKcJ-PPsud-43uLO-gbRDuW8SwmG5gklf0k,48773
434
+ fontTools/ttLib/tables/_c_v_a_r.py,sha256=tbvcz6Zsdgz_yzbi3ppdLlT5H4pW0A-T2sdKOBuvYXE,3299
435
+ fontTools/ttLib/tables/_c_v_t.py,sha256=hPF8O20-EeQSYEKR-btLvlJYJzZ4iGCYe4MYqdOLFZc,1145
436
+ fontTools/ttLib/tables/_f_e_a_t.py,sha256=onaD-G78aqxUjhR7TEmoi2Ld58cVxA0cwEuduLEZVPA,538
437
+ fontTools/ttLib/tables/_f_p_g_m.py,sha256=4HtL26BMzgeobLd3wLvgwDjmm2eVMzlpUwzDJ8mBM8I,986
438
+ fontTools/ttLib/tables/_f_v_a_r.py,sha256=u5VWsDvK2zHdt6aIOK6GgRR4vRHBqj6bclWVmILKgzk,8258
439
+ fontTools/ttLib/tables/_g_a_s_p.py,sha256=NBhZE7gVVQaJTGm2G7alRclidvxDTUTEXqECemZKhz0,1585
440
+ fontTools/ttLib/tables/_g_c_i_d.py,sha256=4VWq2u6c21ZOQ5_EJ5EwtZXC-zDz6SOPYwDDRZWRczA,170
441
+ fontTools/ttLib/tables/_g_l_y_f.py,sha256=__3y3vXmC1qKO1_9FrsqE9alllLF8RtqRyrabaW8SdY,56607
442
+ fontTools/ttLib/tables/_g_v_a_r.py,sha256=9DTWKB-FuX7PbhAORK1ny9UlAaR14ulyXd-oVmz_H5o,7809
443
+ fontTools/ttLib/tables/_h_d_m_x.py,sha256=ih1-qeztwSksTzq5QQ2LGhL8C96Y7KpUmYvrgsQnGNA,3340
444
+ fontTools/ttLib/tables/_h_e_a_d.py,sha256=loFEWrCQVSu_SPI-pEQLfpZOB7Qrx1NYPqnsF_wmCf4,3965
445
+ fontTools/ttLib/tables/_h_h_e_a.py,sha256=SesDOndy8-Bgte8qE8xMmiAi9ARhqal5Y_ISAiYvWmg,3655
446
+ fontTools/ttLib/tables/_h_m_t_x.py,sha256=5Jf3iZzFGIPf5IppNcsEsJpjarbdiuaax3wKaogBGJo,4618
447
+ fontTools/ttLib/tables/_k_e_r_n.py,sha256=rY2tkN-EEd5tIFCAaJfVLFy0OERPeBqs5_fE4qEIt00,8423
448
+ fontTools/ttLib/tables/_l_c_a_r.py,sha256=SsYzAup_e8Kg6LEC4sXDkwXNBy27-PDV8yOKyaOKj1w,85
449
+ fontTools/ttLib/tables/_l_o_c_a.py,sha256=3t5scKnEhKr6bmNUNdEeyqCZU0ycZg8fNsyl45Mzc9E,1621
450
+ fontTools/ttLib/tables/_l_t_a_g.py,sha256=pTbtCDy8yegXfbgJWXVIzllE0xHMCteDppNkunfdtsI,1921
451
+ fontTools/ttLib/tables/_m_a_x_p.py,sha256=eNwy3vfTQi-UnHgmkTwh6DcUjhHvQWE13-TToTRsLzQ,4191
452
+ fontTools/ttLib/tables/_m_e_t_a.py,sha256=3L-8ahYDxh_XoRuS4WoVR8SeKpq71YUdkVUaT9rO_4I,3618
453
+ fontTools/ttLib/tables/_m_o_r_t.py,sha256=2p7PzPGzdOtFhg-Fxvdh0PO4yRs6_z_WjQegexeZCsw,170
454
+ fontTools/ttLib/tables/_m_o_r_x.py,sha256=UJhBbA3mgVQO1oGmu_2bNXUwQreVSztG85F9k7DpmiQ,170
455
+ fontTools/ttLib/tables/_n_a_m_e.py,sha256=tFetcdXscocYpMXfnNbcr-qTNA1dVuXLyVJUPmICXDI,33507
456
+ fontTools/ttLib/tables/_o_p_b_d.py,sha256=t3eqUkZPyaQbahEmKaqp7brDNbt4MQje2Vq1jBu-fEc,170
457
+ fontTools/ttLib/tables/_p_o_s_t.py,sha256=V0qyOfIIIK5p_qVWrZHq1qOqE33bCEfavujyQRj2OEM,9208
458
+ fontTools/ttLib/tables/_p_r_e_p.py,sha256=oSLIN8AA-o1iQfoyiB8N170gDusGw_NhI9uQP_HW0O8,111
459
+ fontTools/ttLib/tables/_p_r_o_p.py,sha256=3JHFloIJwg9n4dzoe4KLobHc75oJh6DLNe51sakfz8E,170
460
+ fontTools/ttLib/tables/_s_b_i_x.py,sha256=9hOtZT6hek3eNv-lii3j4HuTQz5FkwGnS21kTaQoP2E,3877
461
+ fontTools/ttLib/tables/_t_r_a_k.py,sha256=q7XKRVrnhvnnQpsg7J_Ve5ViHx3aYErKBhMaJ3dUfUM,9321
462
+ fontTools/ttLib/tables/_v_h_e_a.py,sha256=yDEMPJ6oZJD8HCi8OJkdmFV0qUDeyygEY0w1DawRiHw,3384
463
+ fontTools/ttLib/tables/_v_m_t_x.py,sha256=3iOPQroHFa8Z1DPzAeWDTG5yJnpU1IWkULglfVrB8a8,217
464
+ fontTools/ttLib/tables/asciiTable.py,sha256=1QiLVGPVbksDM7A-DR2rbLl8EOyzlbtJcr-GIpFbbUc,560
465
+ fontTools/ttLib/tables/grUtils.py,sha256=SPa8cdnbmSoQ47nVQ9Ohh2g3J-9yOrxtuC2n5sXIgHU,2217
466
+ fontTools/ttLib/tables/otBase.py,sha256=WMmMDwbFhohvzZC-aQBvc6sCG4Zc-LGfuVjnDjdRUqg,42601
467
+ fontTools/ttLib/tables/otConverters.py,sha256=Lp4UXdeN2_1Elynqbo-xI0qduatDKi7zhE3YuaRsquQ,59277
468
+ fontTools/ttLib/tables/otData.py,sha256=ruj26Pli0j04bpKduv890bsMulz3CgLXH4Ma6Sa7fV4,112924
469
+ fontTools/ttLib/tables/otTables.py,sha256=bUJg5P2ECHG5VwyE7five51HnvWZujwCJQnwE_GtoI0,63991
470
+ fontTools/ttLib/tables/otTraverse.py,sha256=OgOaLKMiSRkJGvNaeOn7XT4OAAKs2P5FjgdQb1qEADk,4516
471
+ fontTools/ttLib/tables/sbixGlyph.py,sha256=Y7pP0hJ7n4uVGVP9FniWvfO4erXqkhwBAtN54k-41dc,4426
472
+ fontTools/ttLib/tables/sbixStrike.py,sha256=90-ZDlAQnz5gHkmkLWgy2OBBC2JYyXKdT15gLsrbD3g,5381
473
+ fontTools/ttLib/tables/table_API_readme.txt,sha256=eZlRTLUkLzc_9Ot3pdfhyMb3ahU0_Iipx0vSbzOVGy8,2748
474
+ fontTools/ttLib/tables/ttProgram.py,sha256=_KO3fWAB-qUmdKsHP4YyFkj9VtqtDCm_Y_YIT3I-yQQ,27162
475
+ fontTools/ttLib/ttCollection.py,sha256=VuiiKBbWbs9-ogmRdAJ9iBUEonPzfqXjJxjtx4NJ31o,3423
476
+ fontTools/ttLib/ttFont.py,sha256=izKJ4CQteMABFke6bhx34KmAOX1YclkxGwmC9ihLPak,34475
477
+ fontTools/ttLib/woff2.py,sha256=mz1AC9ftrIYCVZbYeEa1b1B9UrxvkvQYRQGvDS6BxOw,49544
478
+ fontTools/ttx.py,sha256=ux6XHv7XbEL9BuRVNP41ZiGhvC0YvR-riAQwEH9TI3Y,13702
479
+ fontTools/ufoLib/__init__.py,sha256=oDJzK8N0qV7Ktuu-HmpJ3pMKDZ24TqWabFbilm73Za4,79098
480
+ fontTools/ufoLib/__pycache__/__init__.cpython-38.pyc,,
481
+ fontTools/ufoLib/__pycache__/converters.cpython-38.pyc,,
482
+ fontTools/ufoLib/__pycache__/errors.cpython-38.pyc,,
483
+ fontTools/ufoLib/__pycache__/etree.cpython-38.pyc,,
484
+ fontTools/ufoLib/__pycache__/filenames.cpython-38.pyc,,
485
+ fontTools/ufoLib/__pycache__/glifLib.cpython-38.pyc,,
486
+ fontTools/ufoLib/__pycache__/kerning.cpython-38.pyc,,
487
+ fontTools/ufoLib/__pycache__/plistlib.cpython-38.pyc,,
488
+ fontTools/ufoLib/__pycache__/pointPen.cpython-38.pyc,,
489
+ fontTools/ufoLib/__pycache__/utils.cpython-38.pyc,,
490
+ fontTools/ufoLib/__pycache__/validators.cpython-38.pyc,,
491
+ fontTools/ufoLib/converters.py,sha256=bZp27v2VmsyGEq3IzQOB9U3Cv1f5eB1jbZugj5bJWwo,10583
492
+ fontTools/ufoLib/errors.py,sha256=PQFraTNS0BQb0nmpMcDKKpj54xRyi15dbIxoBhxwy70,191
493
+ fontTools/ufoLib/etree.py,sha256=rGcXuMfk4mgn1nBCSMVP6CAuSAN51DrZMw8PYxbgrBA,223
494
+ fontTools/ufoLib/filenames.py,sha256=YPvWyxcH0HnLurK1fOH_WgwAsUi6DeXqSWAUZD080eQ,6888
495
+ fontTools/ufoLib/glifLib.py,sha256=KjwmHmdZ_R9mVKEKzIaghLzLKnUfAcFTQ8ow3jQEkJg,59641
496
+ fontTools/ufoLib/kerning.py,sha256=se4WYX8gTCLyp2VbM8_QT347xyQFdJWHFuzoef-i3CY,2606
497
+ fontTools/ufoLib/plistlib.py,sha256=EYnhCMPmbtnRuutKHLzJTvkYix80mAkpXTEIcdRNUgQ,1498
498
+ fontTools/ufoLib/pointPen.py,sha256=-gZR_E9QabqYbI1IVXCppJjQL5qJwUcBvO4_Bnujbzg,232
499
+ fontTools/ufoLib/utils.py,sha256=E7HahGBiqb2k9bCJP__8eBw9XzjDDwc8Zt_UUwYT5LQ,1892
500
+ fontTools/ufoLib/validators.py,sha256=tqEHhDgtE3IhRpd1uCjBbs8vpBUz0K1D1YYzc2ljAcM,26095
501
+ fontTools/unicode.py,sha256=xI7e7NcvFHK00veR3KTWq-cdNcw61H3zQSxvSIZY2bQ,999
502
+ fontTools/unicodedata/Blocks.py,sha256=UpREe6IH3i9t0nHw6aVsAZvtxTEv9-EPc02lvvjWnTw,43124
503
+ fontTools/unicodedata/OTTags.py,sha256=oUDJC8mDUjvh0ftu5EwmK_hUY52CAEuf1GGRf2d0d8k,1122
504
+ fontTools/unicodedata/ScriptExtensions.py,sha256=4exU01BpiCQ07mFDtQJ4kTUp8wUONKzPbCnmIYUyG_k,26709
505
+ fontTools/unicodedata/Scripts.py,sha256=mJcIGLpVWS2sTxnSJVm2mfkXbEuNBes2wJqZrNyJXbM,124646
506
+ fontTools/unicodedata/__init__.py,sha256=bQHu4Sf5wSdguAOj8S2mAkej1hp7TsiiIx4umP3mS-I,8337
507
+ fontTools/unicodedata/__pycache__/Blocks.cpython-38.pyc,,
508
+ fontTools/unicodedata/__pycache__/OTTags.cpython-38.pyc,,
509
+ fontTools/unicodedata/__pycache__/ScriptExtensions.cpython-38.pyc,,
510
+ fontTools/unicodedata/__pycache__/Scripts.cpython-38.pyc,,
511
+ fontTools/unicodedata/__pycache__/__init__.cpython-38.pyc,,
512
+ fontTools/varLib/__init__.py,sha256=WFidQz7guW4F-tXCxcOPdGybvUTiZ3zP3vMVUN7RShI,37845
513
+ fontTools/varLib/__main__.py,sha256=i2W6IG8FJ3KzOfx5yJ1TC8uQ1dg8fxHE4eywfEQUhgc,92
514
+ fontTools/varLib/__pycache__/__init__.cpython-38.pyc,,
515
+ fontTools/varLib/__pycache__/__main__.cpython-38.pyc,,
516
+ fontTools/varLib/__pycache__/builder.cpython-38.pyc,,
517
+ fontTools/varLib/__pycache__/cff.cpython-38.pyc,,
518
+ fontTools/varLib/__pycache__/errors.cpython-38.pyc,,
519
+ fontTools/varLib/__pycache__/featureVars.cpython-38.pyc,,
520
+ fontTools/varLib/__pycache__/interpolatable.cpython-38.pyc,,
521
+ fontTools/varLib/__pycache__/interpolate_layout.cpython-38.pyc,,
522
+ fontTools/varLib/__pycache__/iup.cpython-38.pyc,,
523
+ fontTools/varLib/__pycache__/merger.cpython-38.pyc,,
524
+ fontTools/varLib/__pycache__/models.cpython-38.pyc,,
525
+ fontTools/varLib/__pycache__/mutator.cpython-38.pyc,,
526
+ fontTools/varLib/__pycache__/mvar.cpython-38.pyc,,
527
+ fontTools/varLib/__pycache__/plot.cpython-38.pyc,,
528
+ fontTools/varLib/__pycache__/stat.cpython-38.pyc,,
529
+ fontTools/varLib/__pycache__/varStore.cpython-38.pyc,,
530
+ fontTools/varLib/builder.py,sha256=ur0GazeGbxmEkNhXkxPoEt-m4IgM6elvWYgKmy10yh8,4307
531
+ fontTools/varLib/cff.py,sha256=5kX6jZzttmQm3hQ-NDgUHj2ATPTjxDBhjzlEeOHQIe0,21433
532
+ fontTools/varLib/errors.py,sha256=z-mk-GeH1GUkOP5y26jWhWagN6Il8PoDdxRzm8-5gW4,6475
533
+ fontTools/varLib/featureVars.py,sha256=AIbMFYr3Qc9DsUkr0CXE53YRV6FM46UzsPEnZBiUkgM,20093
534
+ fontTools/varLib/instancer/__init__.py,sha256=0D8XweLjYicugGYma1QhlyGDqXlsnIaogrzZEw1CsUg,58256
535
+ fontTools/varLib/instancer/__main__.py,sha256=zfULwcP01FhplS1IlcMgNQnLxk5RVfmOuinWjqeid-g,104
536
+ fontTools/varLib/instancer/__pycache__/__init__.cpython-38.pyc,,
537
+ fontTools/varLib/instancer/__pycache__/__main__.cpython-38.pyc,,
538
+ fontTools/varLib/instancer/__pycache__/names.cpython-38.pyc,,
539
+ fontTools/varLib/instancer/names.py,sha256=xV0Bh2ZohY3WEewT2Sgkezhbf3LZ6BpKsk6cuuRrIUY,14413
540
+ fontTools/varLib/interpolatable.py,sha256=Ma5Lj3i25NOdoUD0H_cVSXG-6r2ZRHM10OQCHw5eBUU,15569
541
+ fontTools/varLib/interpolate_layout.py,sha256=6_E0fUu-5471uP6j-X2Ucrf9zmTveay_qg7C4SbnB9w,3311
542
+ fontTools/varLib/iup.py,sha256=33owbarj_pRGYUq3awrwd2_xyJlIXE1qeJ9qrY_8iPg,9181
543
+ fontTools/varLib/merger.py,sha256=tQZSyoFGBmxoUcTQaPCJDBZ4eBJSnm2ulRuXR_PjtG0,49933
544
+ fontTools/varLib/models.py,sha256=2y3Yj-bOllBOy3pb6-aRrShfvIB6kql_Ljz_NMG4Cq4,17329
545
+ fontTools/varLib/mutator.py,sha256=j030AitfHzZg84MWIOwBnJHk_tZ56ho-qruW7RUdBIE,15699
546
+ fontTools/varLib/mvar.py,sha256=_OZpbDH7MiZTeN_RHP2ggjNIP-HxUG2Y5LMk428_q3s,2366
547
+ fontTools/varLib/plot.py,sha256=c8xyDSLjc_0gO_DmS-tlXnqU-Bhedh2GTk4xRavkWTc,4153
548
+ fontTools/varLib/stat.py,sha256=pNtU3Jebm8Gr5umrbF5xGj5yJQciFwSFpfePOcg37xY,4535
549
+ fontTools/varLib/varStore.py,sha256=WIBxcJKuEowfnQXYIBgjZOXj8Mq58W9Yc3Mlq_2_Q-8,17430
550
+ fontTools/voltLib/__init__.py,sha256=ZZ1AsTx1VlDn40Kupce-fM3meOWugy3RZraBW9LG-9M,151
551
+ fontTools/voltLib/__pycache__/__init__.cpython-38.pyc,,
552
+ fontTools/voltLib/__pycache__/ast.cpython-38.pyc,,
553
+ fontTools/voltLib/__pycache__/error.cpython-38.pyc,,
554
+ fontTools/voltLib/__pycache__/lexer.cpython-38.pyc,,
555
+ fontTools/voltLib/__pycache__/parser.cpython-38.pyc,,
556
+ fontTools/voltLib/ast.py,sha256=AYbtVgA4qwraQSDwh7LJgCruxqi0mPw6_1oCDThEn48,13175
557
+ fontTools/voltLib/error.py,sha256=75bGxDBvh4OrpmW4E7pgqkvtgq8ZwetyjRtf7dLT5zQ,397
558
+ fontTools/voltLib/lexer.py,sha256=QjslaIn2YF-u1jNQR4Vi9jn60DbUHkc6c6lmLGvzhkg,3417
559
+ fontTools/voltLib/parser.py,sha256=LXEuSwWzcO1BfJTb6XOJKVwYVV1CQdRRiFZxz2W44zk,25244
560
+ fonttools-4.34.4.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
561
+ fonttools-4.34.4.dist-info/LICENSE,sha256=Z4cgj4P2Wcy8IiOy_elS_6b36KymLxqKK_W8UbsbI4M,1072
562
+ fonttools-4.34.4.dist-info/METADATA,sha256=Is-A-kxp6ihXLT-F8BsfKIJlUQHbWD22xVEFBKJow2I,129218
563
+ fonttools-4.34.4.dist-info/RECORD,,
564
+ fonttools-4.34.4.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
565
+ fonttools-4.34.4.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
566
+ fonttools-4.34.4.dist-info/entry_points.txt,sha256=mwtKkpxzi1TdC9N2bHaMWt9cveTLK1X8tg5kvzjC6A4,148
567
+ fonttools-4.34.4.dist-info/top_level.txt,sha256=rRgRylrXzekqWOsrhygzib12pQ7WILf7UGjqEwkIFDM,10
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/fonttools-4.34.4.dist-info/REQUESTED ADDED
File without changes
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/fonttools-4.34.4.dist-info/WHEEL ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ Wheel-Version: 1.0
2
+ Generator: bdist_wheel (0.37.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/fonttools-4.34.4.dist-info/entry_points.txt ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ [console_scripts]
2
+ fonttools = fontTools.__main__:main
3
+ pyftmerge = fontTools.merge:main
4
+ pyftsubset = fontTools.subset:main
5
+ ttx = fontTools.ttx:main
6
+
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/frozenlist/__init__.py ADDED
@@ -0,0 +1,96 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import sys
3
+ import types
4
+ from collections.abc import MutableSequence
5
+ from functools import total_ordering
6
+ from typing import Tuple, Type
7
+
8
+ __version__ = "1.3.0"
9
+
10
+ __all__ = ("FrozenList", "PyFrozenList") # type: Tuple[str, ...]
11
+
12
+
13
+ NO_EXTENSIONS = bool(os.environ.get("FROZENLIST_NO_EXTENSIONS")) # type: bool
14
+
15
+
16
+ @total_ordering
17
+ class FrozenList(MutableSequence):
18
+
19
+ __slots__ = ("_frozen", "_items")
20
+
21
+ if sys.version_info >= (3, 9):
22
+ __class_getitem__ = classmethod(types.GenericAlias)
23
+ else:
24
+
25
+ @classmethod
26
+ def __class_getitem__(cls: Type["FrozenList"]) -> Type["FrozenList"]:
27
+ return cls
28
+
29
+ def __init__(self, items=None):
30
+ self._frozen = False
31
+ if items is not None:
32
+ items = list(items)
33
+ else:
34
+ items = []
35
+ self._items = items
36
+
37
+ @property
38
+ def frozen(self):
39
+ return self._frozen
40
+
41
+ def freeze(self):
42
+ self._frozen = True
43
+
44
+ def __getitem__(self, index):
45
+ return self._items[index]
46
+
47
+ def __setitem__(self, index, value):
48
+ if self._frozen:
49
+ raise RuntimeError("Cannot modify frozen list.")
50
+ self._items[index] = value
51
+
52
+ def __delitem__(self, index):
53
+ if self._frozen:
54
+ raise RuntimeError("Cannot modify frozen list.")
55
+ del self._items[index]
56
+
57
+ def __len__(self):
58
+ return self._items.__len__()
59
+
60
+ def __iter__(self):
61
+ return self._items.__iter__()
62
+
63
+ def __reversed__(self):
64
+ return self._items.__reversed__()
65
+
66
+ def __eq__(self, other):
67
+ return list(self) == other
68
+
69
+ def __le__(self, other):
70
+ return list(self) <= other
71
+
72
+ def insert(self, pos, item):
73
+ if self._frozen:
74
+ raise RuntimeError("Cannot modify frozen list.")
75
+ self._items.insert(pos, item)
76
+
77
+ def __repr__(self):
78
+ return f"<FrozenList(frozen={self._frozen}, {self._items!r})>"
79
+
80
+ def __hash__(self):
81
+ if self._frozen:
82
+ return hash(tuple(self))
83
+ else:
84
+ raise RuntimeError("Cannot hash unfrozen list.")
85
+
86
+
87
+ PyFrozenList = FrozenList
88
+
89
+
90
+ try:
91
+ from ._frozenlist import FrozenList as CFrozenList # type: ignore
92
+
93
+ if not NO_EXTENSIONS: # pragma: no cover
94
+ FrozenList = CFrozenList # type: ignore
95
+ except ImportError: # pragma: no cover
96
+ pass
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/frozenlist/__init__.pyi ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import (
2
+ Generic,
3
+ Iterable,
4
+ Iterator,
5
+ List,
6
+ MutableSequence,
7
+ Optional,
8
+ TypeVar,
9
+ Union,
10
+ overload,
11
+ )
12
+
13
+ _T = TypeVar("_T")
14
+ _Arg = Union[List[_T], Iterable[_T]]
15
+
16
+ class FrozenList(MutableSequence[_T], Generic[_T]):
17
+ def __init__(self, items: Optional[_Arg[_T]] = None) -> None: ...
18
+ @property
19
+ def frozen(self) -> bool: ...
20
+ def freeze(self) -> None: ...
21
+ @overload
22
+ def __getitem__(self, i: int) -> _T: ...
23
+ @overload
24
+ def __getitem__(self, s: slice) -> FrozenList[_T]: ...
25
+ @overload
26
+ def __setitem__(self, i: int, o: _T) -> None: ...
27
+ @overload
28
+ def __setitem__(self, s: slice, o: Iterable[_T]) -> None: ...
29
+ @overload
30
+ def __delitem__(self, i: int) -> None: ...
31
+ @overload
32
+ def __delitem__(self, i: slice) -> None: ...
33
+ def __len__(self) -> int: ...
34
+ def __iter__(self) -> Iterator[_T]: ...
35
+ def __reversed__(self) -> Iterator[_T]: ...
36
+ def __eq__(self, other: object) -> bool: ...
37
+ def __le__(self, other: FrozenList[_T]) -> bool: ...
38
+ def __ne__(self, other: object) -> bool: ...
39
+ def __lt__(self, other: FrozenList[_T]) -> bool: ...
40
+ def __ge__(self, other: FrozenList[_T]) -> bool: ...
41
+ def __gt__(self, other: FrozenList[_T]) -> bool: ...
42
+ def insert(self, pos: int, item: _T) -> None: ...
43
+ def __repr__(self) -> str: ...
44
+ def __hash__(self) -> int: ...
45
+
46
+ # types for C accelerators are the same
47
+ CFrozenList = PyFrozenList = FrozenList