This is page 64 of 168. Use http://codebase.md/romanshablio/mcp_server?lines=true&page={x} to view the full context.
# Directory Structure
```
├── .DS_Store
├── .venv
│ ├── __pycache__
│ │ └── hello.cpython-312.pyc
│ ├── bin
│ │ ├── activate
│ │ ├── activate.csh
│ │ ├── activate.fish
│ │ ├── Activate.ps1
│ │ ├── flask
│ │ ├── normalizer
│ │ ├── pip
│ │ ├── pip3
│ │ ├── pip3.12
│ │ ├── python
│ │ ├── python3
│ │ └── python3.12
│ ├── hello.py
│ ├── lib
│ │ └── python3.12
│ │ └── site-packages
│ │ ├── beautifulsoup4-4.12.3.dist-info
│ │ │ ├── INSTALLER
│ │ │ ├── licenses
│ │ │ │ ├── AUTHORS
│ │ │ │ └── LICENSE
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ ├── REQUESTED
│ │ │ └── WHEEL
│ │ ├── blinker
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── _utilities.cpython-312.pyc
│ │ │ │ └── base.cpython-312.pyc
│ │ │ ├── _utilities.py
│ │ │ ├── base.py
│ │ │ └── py.typed
│ │ ├── blinker-1.8.2.dist-info
│ │ │ ├── INSTALLER
│ │ │ ├── LICENSE.txt
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ └── WHEEL
│ │ ├── bs4
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── css.cpython-312.pyc
│ │ │ │ ├── dammit.cpython-312.pyc
│ │ │ │ ├── diagnose.cpython-312.pyc
│ │ │ │ ├── element.cpython-312.pyc
│ │ │ │ └── formatter.cpython-312.pyc
│ │ │ ├── builder
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ ├── _html5lib.cpython-312.pyc
│ │ │ │ │ ├── _htmlparser.cpython-312.pyc
│ │ │ │ │ └── _lxml.cpython-312.pyc
│ │ │ │ ├── _html5lib.py
│ │ │ │ ├── _htmlparser.py
│ │ │ │ └── _lxml.py
│ │ │ ├── css.py
│ │ │ ├── dammit.py
│ │ │ ├── diagnose.py
│ │ │ ├── element.py
│ │ │ ├── formatter.py
│ │ │ └── tests
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── test_builder_registry.cpython-312.pyc
│ │ │ │ ├── test_builder.cpython-312.pyc
│ │ │ │ ├── test_css.cpython-312.pyc
│ │ │ │ ├── test_dammit.cpython-312.pyc
│ │ │ │ ├── test_docs.cpython-312.pyc
│ │ │ │ ├── test_element.cpython-312.pyc
│ │ │ │ ├── test_formatter.cpython-312.pyc
│ │ │ │ ├── test_fuzz.cpython-312.pyc
│ │ │ │ ├── test_html5lib.cpython-312.pyc
│ │ │ │ ├── test_htmlparser.cpython-312.pyc
│ │ │ │ ├── test_lxml.cpython-312.pyc
│ │ │ │ ├── test_navigablestring.cpython-312.pyc
│ │ │ │ ├── test_pageelement.cpython-312.pyc
│ │ │ │ ├── test_soup.cpython-312.pyc
│ │ │ │ ├── test_tag.cpython-312.pyc
│ │ │ │ └── test_tree.cpython-312.pyc
│ │ │ ├── fuzz
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-4670634698080256.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-4818336571064320.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-4999465949331456.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-5000587759190016.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-5167584867909632.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-5270998950477824.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-5375146639360000.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-5492400320282624.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-5703933063462912.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-5843991618256896.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-5984173902397440.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-6124268085182464.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-6241471367348224.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-6306874195312640.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-6450958476902400.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-6600557255327744.testcase
│ │ │ │ ├── crash-0d306a50c8ed8bcd0785b67000fcd5dea1d33f08.testcase
│ │ │ │ └── crash-ffbdfa8a2b26f13537b68d3794b0478a4090ee4a.testcase
│ │ │ ├── test_builder_registry.py
│ │ │ ├── test_builder.py
│ │ │ ├── test_css.py
│ │ │ ├── test_dammit.py
│ │ │ ├── test_docs.py
│ │ │ ├── test_element.py
│ │ │ ├── test_formatter.py
│ │ │ ├── test_fuzz.py
│ │ │ ├── test_html5lib.py
│ │ │ ├── test_htmlparser.py
│ │ │ ├── test_lxml.py
│ │ │ ├── test_navigablestring.py
│ │ │ ├── test_pageelement.py
│ │ │ ├── test_soup.py
│ │ │ ├── test_tag.py
│ │ │ └── test_tree.py
│ │ ├── certifi
│ │ │ ├── __init__.py
│ │ │ ├── __main__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── __main__.cpython-312.pyc
│ │ │ │ └── core.cpython-312.pyc
│ │ │ ├── cacert.pem
│ │ │ ├── core.py
│ │ │ └── py.typed
│ │ ├── certifi-2024.8.30.dist-info
│ │ │ ├── INSTALLER
│ │ │ ├── LICENSE
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ ├── top_level.txt
│ │ │ └── WHEEL
│ │ ├── charset_normalizer
│ │ │ ├── __init__.py
│ │ │ ├── __main__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── __main__.cpython-312.pyc
│ │ │ │ ├── api.cpython-312.pyc
│ │ │ │ ├── cd.cpython-312.pyc
│ │ │ │ ├── constant.cpython-312.pyc
│ │ │ │ ├── legacy.cpython-312.pyc
│ │ │ │ ├── md.cpython-312.pyc
│ │ │ │ ├── models.cpython-312.pyc
│ │ │ │ ├── utils.cpython-312.pyc
│ │ │ │ └── version.cpython-312.pyc
│ │ │ ├── api.py
│ │ │ ├── cd.py
│ │ │ ├── cli
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __main__.py
│ │ │ │ └── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ └── __main__.cpython-312.pyc
│ │ │ ├── constant.py
│ │ │ ├── legacy.py
│ │ │ ├── md__mypyc.cpython-312-darwin.so
│ │ │ ├── md.cpython-312-darwin.so
│ │ │ ├── md.py
│ │ │ ├── models.py
│ │ │ ├── py.typed
│ │ │ ├── utils.py
│ │ │ └── version.py
│ │ ├── charset_normalizer-3.4.0.dist-info
│ │ │ ├── entry_points.txt
│ │ │ ├── INSTALLER
│ │ │ ├── LICENSE
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ ├── top_level.txt
│ │ │ └── WHEEL
│ │ ├── click
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── _compat.cpython-312.pyc
│ │ │ │ ├── _termui_impl.cpython-312.pyc
│ │ │ │ ├── _textwrap.cpython-312.pyc
│ │ │ │ ├── _winconsole.cpython-312.pyc
│ │ │ │ ├── core.cpython-312.pyc
│ │ │ │ ├── decorators.cpython-312.pyc
│ │ │ │ ├── exceptions.cpython-312.pyc
│ │ │ │ ├── formatting.cpython-312.pyc
│ │ │ │ ├── globals.cpython-312.pyc
│ │ │ │ ├── parser.cpython-312.pyc
│ │ │ │ ├── shell_completion.cpython-312.pyc
│ │ │ │ ├── termui.cpython-312.pyc
│ │ │ │ ├── testing.cpython-312.pyc
│ │ │ │ ├── types.cpython-312.pyc
│ │ │ │ └── utils.cpython-312.pyc
│ │ │ ├── _compat.py
│ │ │ ├── _termui_impl.py
│ │ │ ├── _textwrap.py
│ │ │ ├── _winconsole.py
│ │ │ ├── core.py
│ │ │ ├── decorators.py
│ │ │ ├── exceptions.py
│ │ │ ├── formatting.py
│ │ │ ├── globals.py
│ │ │ ├── parser.py
│ │ │ ├── py.typed
│ │ │ ├── shell_completion.py
│ │ │ ├── termui.py
│ │ │ ├── testing.py
│ │ │ ├── types.py
│ │ │ └── utils.py
│ │ ├── click-8.1.7.dist-info
│ │ │ ├── INSTALLER
│ │ │ ├── LICENSE.rst
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ ├── top_level.txt
│ │ │ └── WHEEL
│ │ ├── fake_useragent
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── errors.cpython-312.pyc
│ │ │ │ ├── fake.cpython-312.pyc
│ │ │ │ ├── log.cpython-312.pyc
│ │ │ │ ├── settings.cpython-312.pyc
│ │ │ │ └── utils.cpython-312.pyc
│ │ │ ├── data
│ │ │ │ └── browsers.json
│ │ │ ├── errors.py
│ │ │ ├── fake.py
│ │ │ ├── log.py
│ │ │ ├── settings.py
│ │ │ └── utils.py
│ │ ├── fake_useragent-1.5.1.dist-info
│ │ │ ├── AUTHORS
│ │ │ ├── INSTALLER
│ │ │ ├── LICENSE
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ ├── REQUESTED
│ │ │ ├── top_level.txt
│ │ │ └── WHEEL
│ │ ├── flask
│ │ │ ├── __init__.py
│ │ │ ├── __main__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── __main__.cpython-312.pyc
│ │ │ │ ├── app.cpython-312.pyc
│ │ │ │ ├── blueprints.cpython-312.pyc
│ │ │ │ ├── cli.cpython-312.pyc
│ │ │ │ ├── config.cpython-312.pyc
│ │ │ │ ├── ctx.cpython-312.pyc
│ │ │ │ ├── debughelpers.cpython-312.pyc
│ │ │ │ ├── globals.cpython-312.pyc
│ │ │ │ ├── helpers.cpython-312.pyc
│ │ │ │ ├── logging.cpython-312.pyc
│ │ │ │ ├── sessions.cpython-312.pyc
│ │ │ │ ├── signals.cpython-312.pyc
│ │ │ │ ├── templating.cpython-312.pyc
│ │ │ │ ├── testing.cpython-312.pyc
│ │ │ │ ├── typing.cpython-312.pyc
│ │ │ │ ├── views.cpython-312.pyc
│ │ │ │ └── wrappers.cpython-312.pyc
│ │ │ ├── app.py
│ │ │ ├── blueprints.py
│ │ │ ├── cli.py
│ │ │ ├── config.py
│ │ │ ├── ctx.py
│ │ │ ├── debughelpers.py
│ │ │ ├── globals.py
│ │ │ ├── helpers.py
│ │ │ ├── json
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ ├── provider.cpython-312.pyc
│ │ │ │ │ └── tag.cpython-312.pyc
│ │ │ │ ├── provider.py
│ │ │ │ └── tag.py
│ │ │ ├── logging.py
│ │ │ ├── py.typed
│ │ │ ├── sansio
│ │ │ │ ├── __pycache__
│ │ │ │ │ ├── app.cpython-312.pyc
│ │ │ │ │ ├── blueprints.cpython-312.pyc
│ │ │ │ │ └── scaffold.cpython-312.pyc
│ │ │ │ ├── app.py
│ │ │ │ ├── blueprints.py
│ │ │ │ ├── README.md
│ │ │ │ └── scaffold.py
│ │ │ ├── sessions.py
│ │ │ ├── signals.py
│ │ │ ├── templating.py
│ │ │ ├── testing.py
│ │ │ ├── typing.py
│ │ │ ├── views.py
│ │ │ └── wrappers.py
│ │ ├── flask-3.0.3.dist-info
│ │ │ ├── entry_points.txt
│ │ │ ├── INSTALLER
│ │ │ ├── LICENSE.txt
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ ├── REQUESTED
│ │ │ └── WHEEL
│ │ ├── idna
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── codec.cpython-312.pyc
│ │ │ │ ├── compat.cpython-312.pyc
│ │ │ │ ├── core.cpython-312.pyc
│ │ │ │ ├── idnadata.cpython-312.pyc
│ │ │ │ ├── intranges.cpython-312.pyc
│ │ │ │ ├── package_data.cpython-312.pyc
│ │ │ │ └── uts46data.cpython-312.pyc
│ │ │ ├── codec.py
│ │ │ ├── compat.py
│ │ │ ├── core.py
│ │ │ ├── idnadata.py
│ │ │ ├── intranges.py
│ │ │ ├── package_data.py
│ │ │ ├── py.typed
│ │ │ └── uts46data.py
│ │ ├── idna-3.10.dist-info
│ │ │ ├── INSTALLER
│ │ │ ├── LICENSE.md
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ └── WHEEL
│ │ ├── itsdangerous
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── _json.cpython-312.pyc
│ │ │ │ ├── encoding.cpython-312.pyc
│ │ │ │ ├── exc.cpython-312.pyc
│ │ │ │ ├── serializer.cpython-312.pyc
│ │ │ │ ├── signer.cpython-312.pyc
│ │ │ │ ├── timed.cpython-312.pyc
│ │ │ │ └── url_safe.cpython-312.pyc
│ │ │ ├── _json.py
│ │ │ ├── encoding.py
│ │ │ ├── exc.py
│ │ │ ├── py.typed
│ │ │ ├── serializer.py
│ │ │ ├── signer.py
│ │ │ ├── timed.py
│ │ │ └── url_safe.py
│ │ ├── itsdangerous-2.2.0.dist-info
│ │ │ ├── INSTALLER
│ │ │ ├── LICENSE.txt
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ └── WHEEL
│ │ ├── jinja2
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── _identifier.cpython-312.pyc
│ │ │ │ ├── async_utils.cpython-312.pyc
│ │ │ │ ├── bccache.cpython-312.pyc
│ │ │ │ ├── compiler.cpython-312.pyc
│ │ │ │ ├── constants.cpython-312.pyc
│ │ │ │ ├── debug.cpython-312.pyc
│ │ │ │ ├── defaults.cpython-312.pyc
│ │ │ │ ├── environment.cpython-312.pyc
│ │ │ │ ├── exceptions.cpython-312.pyc
│ │ │ │ ├── ext.cpython-312.pyc
│ │ │ │ ├── filters.cpython-312.pyc
│ │ │ │ ├── idtracking.cpython-312.pyc
│ │ │ │ ├── lexer.cpython-312.pyc
│ │ │ │ ├── loaders.cpython-312.pyc
│ │ │ │ ├── meta.cpython-312.pyc
│ │ │ │ ├── nativetypes.cpython-312.pyc
│ │ │ │ ├── nodes.cpython-312.pyc
│ │ │ │ ├── optimizer.cpython-312.pyc
│ │ │ │ ├── parser.cpython-312.pyc
│ │ │ │ ├── runtime.cpython-312.pyc
│ │ │ │ ├── sandbox.cpython-312.pyc
│ │ │ │ ├── tests.cpython-312.pyc
│ │ │ │ ├── utils.cpython-312.pyc
│ │ │ │ └── visitor.cpython-312.pyc
│ │ │ ├── _identifier.py
│ │ │ ├── async_utils.py
│ │ │ ├── bccache.py
│ │ │ ├── compiler.py
│ │ │ ├── constants.py
│ │ │ ├── debug.py
│ │ │ ├── defaults.py
│ │ │ ├── environment.py
│ │ │ ├── exceptions.py
│ │ │ ├── ext.py
│ │ │ ├── filters.py
│ │ │ ├── idtracking.py
│ │ │ ├── lexer.py
│ │ │ ├── loaders.py
│ │ │ ├── meta.py
│ │ │ ├── nativetypes.py
│ │ │ ├── nodes.py
│ │ │ ├── optimizer.py
│ │ │ ├── parser.py
│ │ │ ├── py.typed
│ │ │ ├── runtime.py
│ │ │ ├── sandbox.py
│ │ │ ├── tests.py
│ │ │ ├── utils.py
│ │ │ └── visitor.py
│ │ ├── jinja2-3.1.4.dist-info
│ │ │ ├── entry_points.txt
│ │ │ ├── INSTALLER
│ │ │ ├── LICENSE.txt
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ └── WHEEL
│ │ ├── lxml
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── _elementpath.cpython-312.pyc
│ │ │ │ ├── builder.cpython-312.pyc
│ │ │ │ ├── cssselect.cpython-312.pyc
│ │ │ │ ├── doctestcompare.cpython-312.pyc
│ │ │ │ ├── ElementInclude.cpython-312.pyc
│ │ │ │ ├── pyclasslookup.cpython-312.pyc
│ │ │ │ ├── sax.cpython-312.pyc
│ │ │ │ └── usedoctest.cpython-312.pyc
│ │ │ ├── _elementpath.cpython-312-darwin.so
│ │ │ ├── _elementpath.py
│ │ │ ├── apihelpers.pxi
│ │ │ ├── builder.cpython-312-darwin.so
│ │ │ ├── builder.py
│ │ │ ├── classlookup.pxi
│ │ │ ├── cleanup.pxi
│ │ │ ├── cssselect.py
│ │ │ ├── debug.pxi
│ │ │ ├── docloader.pxi
│ │ │ ├── doctestcompare.py
│ │ │ ├── dtd.pxi
│ │ │ ├── ElementInclude.py
│ │ │ ├── etree_api.h
│ │ │ ├── etree.cpython-312-darwin.so
│ │ │ ├── etree.h
│ │ │ ├── etree.pyx
│ │ │ ├── extensions.pxi
│ │ │ ├── html
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ ├── _diffcommand.cpython-312.pyc
│ │ │ │ │ ├── _html5builder.cpython-312.pyc
│ │ │ │ │ ├── _setmixin.cpython-312.pyc
│ │ │ │ │ ├── builder.cpython-312.pyc
│ │ │ │ │ ├── clean.cpython-312.pyc
│ │ │ │ │ ├── defs.cpython-312.pyc
│ │ │ │ │ ├── diff.cpython-312.pyc
│ │ │ │ │ ├── ElementSoup.cpython-312.pyc
│ │ │ │ │ ├── formfill.cpython-312.pyc
│ │ │ │ │ ├── html5parser.cpython-312.pyc
│ │ │ │ │ ├── soupparser.cpython-312.pyc
│ │ │ │ │ └── usedoctest.cpython-312.pyc
│ │ │ │ ├── _diffcommand.py
│ │ │ │ ├── _html5builder.py
│ │ │ │ ├── _setmixin.py
│ │ │ │ ├── builder.py
│ │ │ │ ├── clean.py
│ │ │ │ ├── defs.py
│ │ │ │ ├── diff.cpython-312-darwin.so
│ │ │ │ ├── diff.py
│ │ │ │ ├── ElementSoup.py
│ │ │ │ ├── formfill.py
│ │ │ │ ├── html5parser.py
│ │ │ │ ├── soupparser.py
│ │ │ │ └── usedoctest.py
│ │ │ ├── includes
│ │ │ │ ├── __init__.pxd
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ └── __init__.cpython-312.pyc
│ │ │ │ ├── c14n.pxd
│ │ │ │ ├── config.pxd
│ │ │ │ ├── dtdvalid.pxd
│ │ │ │ ├── etree_defs.h
│ │ │ │ ├── etreepublic.pxd
│ │ │ │ ├── extlibs
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ └── __init__.cpython-312.pyc
│ │ │ │ │ ├── libcharset.h
│ │ │ │ │ ├── localcharset.h
│ │ │ │ │ ├── zconf.h
│ │ │ │ │ └── zlib.h
│ │ │ │ ├── htmlparser.pxd
│ │ │ │ ├── libexslt
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ └── __init__.cpython-312.pyc
│ │ │ │ │ ├── exslt.h
│ │ │ │ │ ├── exsltconfig.h
│ │ │ │ │ └── exsltexports.h
│ │ │ │ ├── libxml
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ └── __init__.cpython-312.pyc
│ │ │ │ │ ├── c14n.h
│ │ │ │ │ ├── catalog.h
│ │ │ │ │ ├── chvalid.h
│ │ │ │ │ ├── debugXML.h
│ │ │ │ │ ├── dict.h
│ │ │ │ │ ├── encoding.h
│ │ │ │ │ ├── entities.h
│ │ │ │ │ ├── globals.h
│ │ │ │ │ ├── hash.h
│ │ │ │ │ ├── HTMLparser.h
│ │ │ │ │ ├── HTMLtree.h
│ │ │ │ │ ├── list.h
│ │ │ │ │ ├── nanoftp.h
│ │ │ │ │ ├── nanohttp.h
│ │ │ │ │ ├── parser.h
│ │ │ │ │ ├── parserInternals.h
│ │ │ │ │ ├── relaxng.h
│ │ │ │ │ ├── SAX.h
│ │ │ │ │ ├── SAX2.h
│ │ │ │ │ ├── schemasInternals.h
│ │ │ │ │ ├── schematron.h
│ │ │ │ │ ├── threads.h
│ │ │ │ │ ├── tree.h
│ │ │ │ │ ├── uri.h
│ │ │ │ │ ├── valid.h
│ │ │ │ │ ├── xinclude.h
│ │ │ │ │ ├── xlink.h
│ │ │ │ │ ├── xmlautomata.h
│ │ │ │ │ ├── xmlerror.h
│ │ │ │ │ ├── xmlexports.h
│ │ │ │ │ ├── xmlIO.h
│ │ │ │ │ ├── xmlmemory.h
│ │ │ │ │ ├── xmlmodule.h
│ │ │ │ │ ├── xmlreader.h
│ │ │ │ │ ├── xmlregexp.h
│ │ │ │ │ ├── xmlsave.h
│ │ │ │ │ ├── xmlschemas.h
│ │ │ │ │ ├── xmlschemastypes.h
│ │ │ │ │ ├── xmlstring.h
│ │ │ │ │ ├── xmlunicode.h
│ │ │ │ │ ├── xmlversion.h
│ │ │ │ │ ├── xmlwriter.h
│ │ │ │ │ ├── xpath.h
│ │ │ │ │ ├── xpathInternals.h
│ │ │ │ │ └── xpointer.h
│ │ │ │ ├── libxslt
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ └── __init__.cpython-312.pyc
│ │ │ │ │ ├── attributes.h
│ │ │ │ │ ├── documents.h
│ │ │ │ │ ├── extensions.h
│ │ │ │ │ ├── extra.h
│ │ │ │ │ ├── functions.h
│ │ │ │ │ ├── imports.h
│ │ │ │ │ ├── keys.h
│ │ │ │ │ ├── namespaces.h
│ │ │ │ │ ├── numbersInternals.h
│ │ │ │ │ ├── pattern.h
│ │ │ │ │ ├── preproc.h
│ │ │ │ │ ├── security.h
│ │ │ │ │ ├── templates.h
│ │ │ │ │ ├── transform.h
│ │ │ │ │ ├── variables.h
│ │ │ │ │ ├── xslt.h
│ │ │ │ │ ├── xsltconfig.h
│ │ │ │ │ ├── xsltexports.h
│ │ │ │ │ ├── xsltInternals.h
│ │ │ │ │ ├── xsltlocale.h
│ │ │ │ │ └── xsltutils.h
│ │ │ │ ├── lxml-version.h
│ │ │ │ ├── relaxng.pxd
│ │ │ │ ├── schematron.pxd
│ │ │ │ ├── tree.pxd
│ │ │ │ ├── uri.pxd
│ │ │ │ ├── xinclude.pxd
│ │ │ │ ├── xmlerror.pxd
│ │ │ │ ├── xmlparser.pxd
│ │ │ │ ├── xmlschema.pxd
│ │ │ │ ├── xpath.pxd
│ │ │ │ └── xslt.pxd
│ │ │ ├── isoschematron
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ └── __init__.cpython-312.pyc
│ │ │ │ └── resources
│ │ │ │ ├── rng
│ │ │ │ │ └── iso-schematron.rng
│ │ │ │ └── xsl
│ │ │ │ ├── iso-schematron-xslt1
│ │ │ │ │ ├── iso_abstract_expand.xsl
│ │ │ │ │ ├── iso_dsdl_include.xsl
│ │ │ │ │ ├── iso_schematron_message.xsl
│ │ │ │ │ ├── iso_schematron_skeleton_for_xslt1.xsl
│ │ │ │ │ ├── iso_svrl_for_xslt1.xsl
│ │ │ │ │ └── readme.txt
│ │ │ │ ├── RNG2Schtrn.xsl
│ │ │ │ └── XSD2Schtrn.xsl
│ │ │ ├── iterparse.pxi
│ │ │ ├── lxml.etree_api.h
│ │ │ ├── lxml.etree.h
│ │ │ ├── nsclasses.pxi
│ │ │ ├── objectify.cpython-312-darwin.so
│ │ │ ├── objectify.pyx
│ │ │ ├── objectpath.pxi
│ │ │ ├── parser.pxi
│ │ │ ├── parsertarget.pxi
│ │ │ ├── proxy.pxi
│ │ │ ├── public-api.pxi
│ │ │ ├── pyclasslookup.py
│ │ │ ├── readonlytree.pxi
│ │ │ ├── relaxng.pxi
│ │ │ ├── sax.cpython-312-darwin.so
│ │ │ ├── sax.py
│ │ │ ├── saxparser.pxi
│ │ │ ├── schematron.pxi
│ │ │ ├── serializer.pxi
│ │ │ ├── usedoctest.py
│ │ │ ├── xinclude.pxi
│ │ │ ├── xmlerror.pxi
│ │ │ ├── xmlid.pxi
│ │ │ ├── xmlschema.pxi
│ │ │ ├── xpath.pxi
│ │ │ ├── xslt.pxi
│ │ │ └── xsltext.pxi
│ │ ├── lxml-5.3.0.dist-info
│ │ │ ├── INSTALLER
│ │ │ ├── LICENSE.txt
│ │ │ ├── LICENSES.txt
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ ├── REQUESTED
│ │ │ ├── top_level.txt
│ │ │ └── WHEEL
│ │ ├── markupsafe
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ └── _native.cpython-312.pyc
│ │ │ ├── _native.py
│ │ │ ├── _speedups.c
│ │ │ ├── _speedups.cpython-312-darwin.so
│ │ │ ├── _speedups.pyi
│ │ │ └── py.typed
│ │ ├── MarkupSafe-3.0.1.dist-info
│ │ │ ├── INSTALLER
│ │ │ ├── LICENSE.txt
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ ├── top_level.txt
│ │ │ └── WHEEL
│ │ ├── pip
│ │ │ ├── __init__.py
│ │ │ ├── __main__.py
│ │ │ ├── __pip-runner__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── __main__.cpython-312.pyc
│ │ │ │ └── __pip-runner__.cpython-312.pyc
│ │ │ ├── _internal
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ ├── build_env.cpython-312.pyc
│ │ │ │ │ ├── cache.cpython-312.pyc
│ │ │ │ │ ├── configuration.cpython-312.pyc
│ │ │ │ │ ├── exceptions.cpython-312.pyc
│ │ │ │ │ ├── main.cpython-312.pyc
│ │ │ │ │ ├── pyproject.cpython-312.pyc
│ │ │ │ │ ├── self_outdated_check.cpython-312.pyc
│ │ │ │ │ └── wheel_builder.cpython-312.pyc
│ │ │ │ ├── build_env.py
│ │ │ │ ├── cache.py
│ │ │ │ ├── cli
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── autocompletion.cpython-312.pyc
│ │ │ │ │ │ ├── base_command.cpython-312.pyc
│ │ │ │ │ │ ├── cmdoptions.cpython-312.pyc
│ │ │ │ │ │ ├── command_context.cpython-312.pyc
│ │ │ │ │ │ ├── index_command.cpython-312.pyc
│ │ │ │ │ │ ├── main_parser.cpython-312.pyc
│ │ │ │ │ │ ├── main.cpython-312.pyc
│ │ │ │ │ │ ├── parser.cpython-312.pyc
│ │ │ │ │ │ ├── progress_bars.cpython-312.pyc
│ │ │ │ │ │ ├── req_command.cpython-312.pyc
│ │ │ │ │ │ ├── spinners.cpython-312.pyc
│ │ │ │ │ │ └── status_codes.cpython-312.pyc
│ │ │ │ │ ├── autocompletion.py
│ │ │ │ │ ├── base_command.py
│ │ │ │ │ ├── cmdoptions.py
│ │ │ │ │ ├── command_context.py
│ │ │ │ │ ├── index_command.py
│ │ │ │ │ ├── main_parser.py
│ │ │ │ │ ├── main.py
│ │ │ │ │ ├── parser.py
│ │ │ │ │ ├── progress_bars.py
│ │ │ │ │ ├── req_command.py
│ │ │ │ │ ├── spinners.py
│ │ │ │ │ └── status_codes.py
│ │ │ │ ├── commands
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── cache.cpython-312.pyc
│ │ │ │ │ │ ├── check.cpython-312.pyc
│ │ │ │ │ │ ├── completion.cpython-312.pyc
│ │ │ │ │ │ ├── configuration.cpython-312.pyc
│ │ │ │ │ │ ├── debug.cpython-312.pyc
│ │ │ │ │ │ ├── download.cpython-312.pyc
│ │ │ │ │ │ ├── freeze.cpython-312.pyc
│ │ │ │ │ │ ├── hash.cpython-312.pyc
│ │ │ │ │ │ ├── help.cpython-312.pyc
│ │ │ │ │ │ ├── index.cpython-312.pyc
│ │ │ │ │ │ ├── inspect.cpython-312.pyc
│ │ │ │ │ │ ├── install.cpython-312.pyc
│ │ │ │ │ │ ├── list.cpython-312.pyc
│ │ │ │ │ │ ├── search.cpython-312.pyc
│ │ │ │ │ │ ├── show.cpython-312.pyc
│ │ │ │ │ │ ├── uninstall.cpython-312.pyc
│ │ │ │ │ │ └── wheel.cpython-312.pyc
│ │ │ │ │ ├── cache.py
│ │ │ │ │ ├── check.py
│ │ │ │ │ ├── completion.py
│ │ │ │ │ ├── configuration.py
│ │ │ │ │ ├── debug.py
│ │ │ │ │ ├── download.py
│ │ │ │ │ ├── freeze.py
│ │ │ │ │ ├── hash.py
│ │ │ │ │ ├── help.py
│ │ │ │ │ ├── index.py
│ │ │ │ │ ├── inspect.py
│ │ │ │ │ ├── install.py
│ │ │ │ │ ├── list.py
│ │ │ │ │ ├── search.py
│ │ │ │ │ ├── show.py
│ │ │ │ │ ├── uninstall.py
│ │ │ │ │ └── wheel.py
│ │ │ │ ├── configuration.py
│ │ │ │ ├── distributions
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── base.cpython-312.pyc
│ │ │ │ │ │ ├── installed.cpython-312.pyc
│ │ │ │ │ │ ├── sdist.cpython-312.pyc
│ │ │ │ │ │ └── wheel.cpython-312.pyc
│ │ │ │ │ ├── base.py
│ │ │ │ │ ├── installed.py
│ │ │ │ │ ├── sdist.py
│ │ │ │ │ └── wheel.py
│ │ │ │ ├── exceptions.py
│ │ │ │ ├── index
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── collector.cpython-312.pyc
│ │ │ │ │ │ ├── package_finder.cpython-312.pyc
│ │ │ │ │ │ └── sources.cpython-312.pyc
│ │ │ │ │ ├── collector.py
│ │ │ │ │ ├── package_finder.py
│ │ │ │ │ └── sources.py
│ │ │ │ ├── locations
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── _distutils.cpython-312.pyc
│ │ │ │ │ │ ├── _sysconfig.cpython-312.pyc
│ │ │ │ │ │ └── base.cpython-312.pyc
│ │ │ │ │ ├── _distutils.py
│ │ │ │ │ ├── _sysconfig.py
│ │ │ │ │ └── base.py
│ │ │ │ ├── main.py
│ │ │ │ ├── metadata
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── _json.cpython-312.pyc
│ │ │ │ │ │ ├── base.cpython-312.pyc
│ │ │ │ │ │ └── pkg_resources.cpython-312.pyc
│ │ │ │ │ ├── _json.py
│ │ │ │ │ ├── base.py
│ │ │ │ │ ├── importlib
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ │ ├── _compat.cpython-312.pyc
│ │ │ │ │ │ │ ├── _dists.cpython-312.pyc
│ │ │ │ │ │ │ └── _envs.cpython-312.pyc
│ │ │ │ │ │ ├── _compat.py
│ │ │ │ │ │ ├── _dists.py
│ │ │ │ │ │ └── _envs.py
│ │ │ │ │ └── pkg_resources.py
│ │ │ │ ├── models
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── candidate.cpython-312.pyc
│ │ │ │ │ │ ├── direct_url.cpython-312.pyc
│ │ │ │ │ │ ├── format_control.cpython-312.pyc
│ │ │ │ │ │ ├── index.cpython-312.pyc
│ │ │ │ │ │ ├── installation_report.cpython-312.pyc
│ │ │ │ │ │ ├── link.cpython-312.pyc
│ │ │ │ │ │ ├── scheme.cpython-312.pyc
│ │ │ │ │ │ ├── search_scope.cpython-312.pyc
│ │ │ │ │ │ ├── selection_prefs.cpython-312.pyc
│ │ │ │ │ │ ├── target_python.cpython-312.pyc
│ │ │ │ │ │ └── wheel.cpython-312.pyc
│ │ │ │ │ ├── candidate.py
│ │ │ │ │ ├── direct_url.py
│ │ │ │ │ ├── format_control.py
│ │ │ │ │ ├── index.py
│ │ │ │ │ ├── installation_report.py
│ │ │ │ │ ├── link.py
│ │ │ │ │ ├── scheme.py
│ │ │ │ │ ├── search_scope.py
│ │ │ │ │ ├── selection_prefs.py
│ │ │ │ │ ├── target_python.py
│ │ │ │ │ └── wheel.py
│ │ │ │ ├── network
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── auth.cpython-312.pyc
│ │ │ │ │ │ ├── cache.cpython-312.pyc
│ │ │ │ │ │ ├── download.cpython-312.pyc
│ │ │ │ │ │ ├── lazy_wheel.cpython-312.pyc
│ │ │ │ │ │ ├── session.cpython-312.pyc
│ │ │ │ │ │ ├── utils.cpython-312.pyc
│ │ │ │ │ │ └── xmlrpc.cpython-312.pyc
│ │ │ │ │ ├── auth.py
│ │ │ │ │ ├── cache.py
│ │ │ │ │ ├── download.py
│ │ │ │ │ ├── lazy_wheel.py
│ │ │ │ │ ├── session.py
│ │ │ │ │ ├── utils.py
│ │ │ │ │ └── xmlrpc.py
│ │ │ │ ├── operations
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── check.cpython-312.pyc
│ │ │ │ │ │ ├── freeze.cpython-312.pyc
│ │ │ │ │ │ └── prepare.cpython-312.pyc
│ │ │ │ │ ├── build
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ │ ├── build_tracker.cpython-312.pyc
│ │ │ │ │ │ │ ├── metadata_editable.cpython-312.pyc
│ │ │ │ │ │ │ ├── metadata_legacy.cpython-312.pyc
│ │ │ │ │ │ │ ├── metadata.cpython-312.pyc
│ │ │ │ │ │ │ ├── wheel_editable.cpython-312.pyc
│ │ │ │ │ │ │ ├── wheel_legacy.cpython-312.pyc
│ │ │ │ │ │ │ └── wheel.cpython-312.pyc
│ │ │ │ │ │ ├── build_tracker.py
│ │ │ │ │ │ ├── metadata_editable.py
│ │ │ │ │ │ ├── metadata_legacy.py
│ │ │ │ │ │ ├── metadata.py
│ │ │ │ │ │ ├── wheel_editable.py
│ │ │ │ │ │ ├── wheel_legacy.py
│ │ │ │ │ │ └── wheel.py
│ │ │ │ │ ├── check.py
│ │ │ │ │ ├── freeze.py
│ │ │ │ │ ├── install
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ │ ├── editable_legacy.cpython-312.pyc
│ │ │ │ │ │ │ └── wheel.cpython-312.pyc
│ │ │ │ │ │ ├── editable_legacy.py
│ │ │ │ │ │ └── wheel.py
│ │ │ │ │ └── prepare.py
│ │ │ │ ├── pyproject.py
│ │ │ │ ├── req
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── constructors.cpython-312.pyc
│ │ │ │ │ │ ├── req_file.cpython-312.pyc
│ │ │ │ │ │ ├── req_install.cpython-312.pyc
│ │ │ │ │ │ ├── req_set.cpython-312.pyc
│ │ │ │ │ │ └── req_uninstall.cpython-312.pyc
│ │ │ │ │ ├── constructors.py
│ │ │ │ │ ├── req_file.py
│ │ │ │ │ ├── req_install.py
│ │ │ │ │ ├── req_set.py
│ │ │ │ │ └── req_uninstall.py
│ │ │ │ ├── resolution
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ └── base.cpython-312.pyc
│ │ │ │ │ ├── base.py
│ │ │ │ │ ├── legacy
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ │ └── resolver.cpython-312.pyc
│ │ │ │ │ │ └── resolver.py
│ │ │ │ │ └── resolvelib
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── base.cpython-312.pyc
│ │ │ │ │ │ ├── candidates.cpython-312.pyc
│ │ │ │ │ │ ├── factory.cpython-312.pyc
│ │ │ │ │ │ ├── found_candidates.cpython-312.pyc
│ │ │ │ │ │ ├── provider.cpython-312.pyc
│ │ │ │ │ │ ├── reporter.cpython-312.pyc
│ │ │ │ │ │ ├── requirements.cpython-312.pyc
│ │ │ │ │ │ └── resolver.cpython-312.pyc
│ │ │ │ │ ├── base.py
│ │ │ │ │ ├── candidates.py
│ │ │ │ │ ├── factory.py
│ │ │ │ │ ├── found_candidates.py
│ │ │ │ │ ├── provider.py
│ │ │ │ │ ├── reporter.py
│ │ │ │ │ ├── requirements.py
│ │ │ │ │ └── resolver.py
│ │ │ │ ├── self_outdated_check.py
│ │ │ │ ├── utils
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── _jaraco_text.cpython-312.pyc
│ │ │ │ │ │ ├── _log.cpython-312.pyc
│ │ │ │ │ │ ├── appdirs.cpython-312.pyc
│ │ │ │ │ │ ├── compat.cpython-312.pyc
│ │ │ │ │ │ ├── compatibility_tags.cpython-312.pyc
│ │ │ │ │ │ ├── datetime.cpython-312.pyc
│ │ │ │ │ │ ├── deprecation.cpython-312.pyc
│ │ │ │ │ │ ├── direct_url_helpers.cpython-312.pyc
│ │ │ │ │ │ ├── egg_link.cpython-312.pyc
│ │ │ │ │ │ ├── encoding.cpython-312.pyc
│ │ │ │ │ │ ├── entrypoints.cpython-312.pyc
│ │ │ │ │ │ ├── filesystem.cpython-312.pyc
│ │ │ │ │ │ ├── filetypes.cpython-312.pyc
│ │ │ │ │ │ ├── glibc.cpython-312.pyc
│ │ │ │ │ │ ├── hashes.cpython-312.pyc
│ │ │ │ │ │ ├── logging.cpython-312.pyc
│ │ │ │ │ │ ├── misc.cpython-312.pyc
│ │ │ │ │ │ ├── packaging.cpython-312.pyc
│ │ │ │ │ │ ├── retry.cpython-312.pyc
│ │ │ │ │ │ ├── setuptools_build.cpython-312.pyc
│ │ │ │ │ │ ├── subprocess.cpython-312.pyc
│ │ │ │ │ │ ├── temp_dir.cpython-312.pyc
│ │ │ │ │ │ ├── unpacking.cpython-312.pyc
│ │ │ │ │ │ ├── urls.cpython-312.pyc
│ │ │ │ │ │ ├── virtualenv.cpython-312.pyc
│ │ │ │ │ │ └── wheel.cpython-312.pyc
│ │ │ │ │ ├── _jaraco_text.py
│ │ │ │ │ ├── _log.py
│ │ │ │ │ ├── appdirs.py
│ │ │ │ │ ├── compat.py
│ │ │ │ │ ├── compatibility_tags.py
│ │ │ │ │ ├── datetime.py
│ │ │ │ │ ├── deprecation.py
│ │ │ │ │ ├── direct_url_helpers.py
│ │ │ │ │ ├── egg_link.py
│ │ │ │ │ ├── encoding.py
│ │ │ │ │ ├── entrypoints.py
│ │ │ │ │ ├── filesystem.py
│ │ │ │ │ ├── filetypes.py
│ │ │ │ │ ├── glibc.py
│ │ │ │ │ ├── hashes.py
│ │ │ │ │ ├── logging.py
│ │ │ │ │ ├── misc.py
│ │ │ │ │ ├── packaging.py
│ │ │ │ │ ├── retry.py
│ │ │ │ │ ├── setuptools_build.py
│ │ │ │ │ ├── subprocess.py
│ │ │ │ │ ├── temp_dir.py
│ │ │ │ │ ├── unpacking.py
│ │ │ │ │ ├── urls.py
│ │ │ │ │ ├── virtualenv.py
│ │ │ │ │ └── wheel.py
│ │ │ │ ├── vcs
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── bazaar.cpython-312.pyc
│ │ │ │ │ │ ├── git.cpython-312.pyc
│ │ │ │ │ │ ├── mercurial.cpython-312.pyc
│ │ │ │ │ │ ├── subversion.cpython-312.pyc
│ │ │ │ │ │ └── versioncontrol.cpython-312.pyc
│ │ │ │ │ ├── bazaar.py
│ │ │ │ │ ├── git.py
│ │ │ │ │ ├── mercurial.py
│ │ │ │ │ ├── subversion.py
│ │ │ │ │ └── versioncontrol.py
│ │ │ │ └── wheel_builder.py
│ │ │ ├── _vendor
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ └── typing_extensions.cpython-312.pyc
│ │ │ │ ├── cachecontrol
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── _cmd.cpython-312.pyc
│ │ │ │ │ │ ├── adapter.cpython-312.pyc
│ │ │ │ │ │ ├── cache.cpython-312.pyc
│ │ │ │ │ │ ├── controller.cpython-312.pyc
│ │ │ │ │ │ ├── filewrapper.cpython-312.pyc
│ │ │ │ │ │ ├── heuristics.cpython-312.pyc
│ │ │ │ │ │ ├── serialize.cpython-312.pyc
│ │ │ │ │ │ └── wrapper.cpython-312.pyc
│ │ │ │ │ ├── _cmd.py
│ │ │ │ │ ├── adapter.py
│ │ │ │ │ ├── cache.py
│ │ │ │ │ ├── caches
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ │ ├── file_cache.cpython-312.pyc
│ │ │ │ │ │ │ └── redis_cache.cpython-312.pyc
│ │ │ │ │ │ ├── file_cache.py
│ │ │ │ │ │ └── redis_cache.py
│ │ │ │ │ ├── controller.py
│ │ │ │ │ ├── filewrapper.py
│ │ │ │ │ ├── heuristics.py
│ │ │ │ │ ├── py.typed
│ │ │ │ │ ├── serialize.py
│ │ │ │ │ └── wrapper.py
│ │ │ │ ├── certifi
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __main__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── __main__.cpython-312.pyc
│ │ │ │ │ │ └── core.cpython-312.pyc
│ │ │ │ │ ├── cacert.pem
│ │ │ │ │ ├── core.py
│ │ │ │ │ └── py.typed
│ │ │ │ ├── distlib
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── compat.cpython-312.pyc
│ │ │ │ │ │ ├── database.cpython-312.pyc
│ │ │ │ │ │ ├── index.cpython-312.pyc
│ │ │ │ │ │ ├── locators.cpython-312.pyc
│ │ │ │ │ │ ├── manifest.cpython-312.pyc
│ │ │ │ │ │ ├── markers.cpython-312.pyc
│ │ │ │ │ │ ├── metadata.cpython-312.pyc
│ │ │ │ │ │ ├── resources.cpython-312.pyc
│ │ │ │ │ │ ├── scripts.cpython-312.pyc
│ │ │ │ │ │ ├── util.cpython-312.pyc
│ │ │ │ │ │ ├── version.cpython-312.pyc
│ │ │ │ │ │ └── wheel.cpython-312.pyc
│ │ │ │ │ ├── compat.py
│ │ │ │ │ ├── database.py
│ │ │ │ │ ├── index.py
│ │ │ │ │ ├── locators.py
│ │ │ │ │ ├── manifest.py
│ │ │ │ │ ├── markers.py
│ │ │ │ │ ├── metadata.py
│ │ │ │ │ ├── resources.py
│ │ │ │ │ ├── scripts.py
│ │ │ │ │ ├── t32.exe
│ │ │ │ │ ├── t64-arm.exe
│ │ │ │ │ ├── t64.exe
│ │ │ │ │ ├── util.py
│ │ │ │ │ ├── version.py
│ │ │ │ │ ├── w32.exe
│ │ │ │ │ ├── w64-arm.exe
│ │ │ │ │ ├── w64.exe
│ │ │ │ │ └── wheel.py
│ │ │ │ ├── distro
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __main__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── __main__.cpython-312.pyc
│ │ │ │ │ │ └── distro.cpython-312.pyc
│ │ │ │ │ ├── distro.py
│ │ │ │ │ └── py.typed
│ │ │ │ ├── idna
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── codec.cpython-312.pyc
│ │ │ │ │ │ ├── compat.cpython-312.pyc
│ │ │ │ │ │ ├── core.cpython-312.pyc
│ │ │ │ │ │ ├── idnadata.cpython-312.pyc
│ │ │ │ │ │ ├── intranges.cpython-312.pyc
│ │ │ │ │ │ ├── package_data.cpython-312.pyc
│ │ │ │ │ │ └── uts46data.cpython-312.pyc
│ │ │ │ │ ├── codec.py
│ │ │ │ │ ├── compat.py
│ │ │ │ │ ├── core.py
│ │ │ │ │ ├── idnadata.py
│ │ │ │ │ ├── intranges.py
│ │ │ │ │ ├── package_data.py
│ │ │ │ │ ├── py.typed
│ │ │ │ │ └── uts46data.py
│ │ │ │ ├── msgpack
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── exceptions.cpython-312.pyc
│ │ │ │ │ │ ├── ext.cpython-312.pyc
│ │ │ │ │ │ └── fallback.cpython-312.pyc
│ │ │ │ │ ├── exceptions.py
│ │ │ │ │ ├── ext.py
│ │ │ │ │ └── fallback.py
│ │ │ │ ├── packaging
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── _elffile.cpython-312.pyc
│ │ │ │ │ │ ├── _manylinux.cpython-312.pyc
│ │ │ │ │ │ ├── _musllinux.cpython-312.pyc
│ │ │ │ │ │ ├── _parser.cpython-312.pyc
│ │ │ │ │ │ ├── _structures.cpython-312.pyc
│ │ │ │ │ │ ├── _tokenizer.cpython-312.pyc
│ │ │ │ │ │ ├── markers.cpython-312.pyc
│ │ │ │ │ │ ├── metadata.cpython-312.pyc
│ │ │ │ │ │ ├── requirements.cpython-312.pyc
│ │ │ │ │ │ ├── specifiers.cpython-312.pyc
│ │ │ │ │ │ ├── tags.cpython-312.pyc
│ │ │ │ │ │ ├── utils.cpython-312.pyc
│ │ │ │ │ │ └── version.cpython-312.pyc
│ │ │ │ │ ├── _elffile.py
│ │ │ │ │ ├── _manylinux.py
│ │ │ │ │ ├── _musllinux.py
│ │ │ │ │ ├── _parser.py
│ │ │ │ │ ├── _structures.py
│ │ │ │ │ ├── _tokenizer.py
│ │ │ │ │ ├── markers.py
│ │ │ │ │ ├── metadata.py
│ │ │ │ │ ├── py.typed
│ │ │ │ │ ├── requirements.py
│ │ │ │ │ ├── specifiers.py
│ │ │ │ │ ├── tags.py
│ │ │ │ │ ├── utils.py
│ │ │ │ │ └── version.py
│ │ │ │ ├── pkg_resources
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ └── __pycache__
│ │ │ │ │ └── __init__.cpython-312.pyc
│ │ │ │ ├── platformdirs
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __main__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── __main__.cpython-312.pyc
│ │ │ │ │ │ ├── android.cpython-312.pyc
│ │ │ │ │ │ ├── api.cpython-312.pyc
│ │ │ │ │ │ ├── macos.cpython-312.pyc
│ │ │ │ │ │ ├── unix.cpython-312.pyc
│ │ │ │ │ │ ├── version.cpython-312.pyc
│ │ │ │ │ │ └── windows.cpython-312.pyc
│ │ │ │ │ ├── android.py
│ │ │ │ │ ├── api.py
│ │ │ │ │ ├── macos.py
│ │ │ │ │ ├── py.typed
│ │ │ │ │ ├── unix.py
│ │ │ │ │ ├── version.py
│ │ │ │ │ └── windows.py
│ │ │ │ ├── pygments
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __main__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── __main__.cpython-312.pyc
│ │ │ │ │ │ ├── cmdline.cpython-312.pyc
│ │ │ │ │ │ ├── console.cpython-312.pyc
│ │ │ │ │ │ ├── filter.cpython-312.pyc
│ │ │ │ │ │ ├── formatter.cpython-312.pyc
│ │ │ │ │ │ ├── lexer.cpython-312.pyc
│ │ │ │ │ │ ├── modeline.cpython-312.pyc
│ │ │ │ │ │ ├── plugin.cpython-312.pyc
│ │ │ │ │ │ ├── regexopt.cpython-312.pyc
│ │ │ │ │ │ ├── scanner.cpython-312.pyc
│ │ │ │ │ │ ├── sphinxext.cpython-312.pyc
│ │ │ │ │ │ ├── style.cpython-312.pyc
│ │ │ │ │ │ ├── token.cpython-312.pyc
│ │ │ │ │ │ ├── unistring.cpython-312.pyc
│ │ │ │ │ │ └── util.cpython-312.pyc
│ │ │ │ │ ├── cmdline.py
│ │ │ │ │ ├── console.py
│ │ │ │ │ ├── filter.py
│ │ │ │ │ ├── filters
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ └── __pycache__
│ │ │ │ │ │ └── __init__.cpython-312.pyc
│ │ │ │ │ ├── formatter.py
│ │ │ │ │ ├── formatters
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ │ ├── _mapping.cpython-312.pyc
│ │ │ │ │ │ │ ├── bbcode.cpython-312.pyc
│ │ │ │ │ │ │ ├── groff.cpython-312.pyc
│ │ │ │ │ │ │ ├── html.cpython-312.pyc
│ │ │ │ │ │ │ ├── img.cpython-312.pyc
│ │ │ │ │ │ │ ├── irc.cpython-312.pyc
│ │ │ │ │ │ │ ├── latex.cpython-312.pyc
│ │ │ │ │ │ │ ├── other.cpython-312.pyc
│ │ │ │ │ │ │ ├── pangomarkup.cpython-312.pyc
│ │ │ │ │ │ │ ├── rtf.cpython-312.pyc
│ │ │ │ │ │ │ ├── svg.cpython-312.pyc
│ │ │ │ │ │ │ ├── terminal.cpython-312.pyc
│ │ │ │ │ │ │ └── terminal256.cpython-312.pyc
│ │ │ │ │ │ ├── _mapping.py
│ │ │ │ │ │ ├── bbcode.py
│ │ │ │ │ │ ├── groff.py
│ │ │ │ │ │ ├── html.py
│ │ │ │ │ │ ├── img.py
│ │ │ │ │ │ ├── irc.py
│ │ │ │ │ │ ├── latex.py
│ │ │ │ │ │ ├── other.py
│ │ │ │ │ │ ├── pangomarkup.py
│ │ │ │ │ │ ├── rtf.py
│ │ │ │ │ │ ├── svg.py
│ │ │ │ │ │ ├── terminal.py
│ │ │ │ │ │ └── terminal256.py
│ │ │ │ │ ├── lexer.py
│ │ │ │ │ ├── lexers
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ │ ├── _mapping.cpython-312.pyc
│ │ │ │ │ │ │ └── python.cpython-312.pyc
│ │ │ │ │ │ ├── _mapping.py
│ │ │ │ │ │ └── python.py
│ │ │ │ │ ├── modeline.py
│ │ │ │ │ ├── plugin.py
│ │ │ │ │ ├── regexopt.py
│ │ │ │ │ ├── scanner.py
│ │ │ │ │ ├── sphinxext.py
│ │ │ │ │ ├── style.py
│ │ │ │ │ ├── styles
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ │ └── _mapping.cpython-312.pyc
│ │ │ │ │ │ └── _mapping.py
│ │ │ │ │ ├── token.py
│ │ │ │ │ ├── unistring.py
│ │ │ │ │ └── util.py
│ │ │ │ ├── pyproject_hooks
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── _compat.cpython-312.pyc
│ │ │ │ │ │ └── _impl.cpython-312.pyc
│ │ │ │ │ ├── _compat.py
│ │ │ │ │ ├── _impl.py
│ │ │ │ │ └── _in_process
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ └── _in_process.cpython-312.pyc
│ │ │ │ │ └── _in_process.py
│ │ │ │ ├── requests
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── __version__.cpython-312.pyc
│ │ │ │ │ │ ├── _internal_utils.cpython-312.pyc
│ │ │ │ │ │ ├── adapters.cpython-312.pyc
│ │ │ │ │ │ ├── api.cpython-312.pyc
│ │ │ │ │ │ ├── auth.cpython-312.pyc
│ │ │ │ │ │ ├── certs.cpython-312.pyc
│ │ │ │ │ │ ├── compat.cpython-312.pyc
│ │ │ │ │ │ ├── cookies.cpython-312.pyc
│ │ │ │ │ │ ├── exceptions.cpython-312.pyc
│ │ │ │ │ │ ├── help.cpython-312.pyc
│ │ │ │ │ │ ├── hooks.cpython-312.pyc
│ │ │ │ │ │ ├── models.cpython-312.pyc
│ │ │ │ │ │ ├── packages.cpython-312.pyc
│ │ │ │ │ │ ├── sessions.cpython-312.pyc
│ │ │ │ │ │ ├── status_codes.cpython-312.pyc
│ │ │ │ │ │ ├── structures.cpython-312.pyc
│ │ │ │ │ │ └── utils.cpython-312.pyc
│ │ │ │ │ ├── __version__.py
│ │ │ │ │ ├── _internal_utils.py
│ │ │ │ │ ├── adapters.py
│ │ │ │ │ ├── api.py
│ │ │ │ │ ├── auth.py
│ │ │ │ │ ├── certs.py
│ │ │ │ │ ├── compat.py
│ │ │ │ │ ├── cookies.py
│ │ │ │ │ ├── exceptions.py
│ │ │ │ │ ├── help.py
│ │ │ │ │ ├── hooks.py
│ │ │ │ │ ├── models.py
│ │ │ │ │ ├── packages.py
│ │ │ │ │ ├── sessions.py
│ │ │ │ │ ├── status_codes.py
│ │ │ │ │ ├── structures.py
│ │ │ │ │ └── utils.py
│ │ │ │ ├── resolvelib
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── providers.cpython-312.pyc
│ │ │ │ │ │ ├── reporters.cpython-312.pyc
│ │ │ │ │ │ ├── resolvers.cpython-312.pyc
│ │ │ │ │ │ └── structs.cpython-312.pyc
│ │ │ │ │ ├── compat
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ │ └── collections_abc.cpython-312.pyc
│ │ │ │ │ │ └── collections_abc.py
│ │ │ │ │ ├── providers.py
│ │ │ │ │ ├── py.typed
│ │ │ │ │ ├── reporters.py
│ │ │ │ │ ├── resolvers.py
│ │ │ │ │ └── structs.py
│ │ │ │ ├── rich
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __main__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── __main__.cpython-312.pyc
│ │ │ │ │ │ ├── _cell_widths.cpython-312.pyc
│ │ │ │ │ │ ├── _emoji_codes.cpython-312.pyc
│ │ │ │ │ │ ├── _emoji_replace.cpython-312.pyc
│ │ │ │ │ │ ├── _export_format.cpython-312.pyc
│ │ │ │ │ │ ├── _extension.cpython-312.pyc
│ │ │ │ │ │ ├── _fileno.cpython-312.pyc
│ │ │ │ │ │ ├── _inspect.cpython-312.pyc
│ │ │ │ │ │ ├── _log_render.cpython-312.pyc
│ │ │ │ │ │ ├── _loop.cpython-312.pyc
│ │ │ │ │ │ ├── _null_file.cpython-312.pyc
│ │ │ │ │ │ ├── _palettes.cpython-312.pyc
│ │ │ │ │ │ ├── _pick.cpython-312.pyc
│ │ │ │ │ │ ├── _ratio.cpython-312.pyc
│ │ │ │ │ │ ├── _spinners.cpython-312.pyc
│ │ │ │ │ │ ├── _stack.cpython-312.pyc
│ │ │ │ │ │ ├── _timer.cpython-312.pyc
│ │ │ │ │ │ ├── _win32_console.cpython-312.pyc
│ │ │ │ │ │ ├── _windows_renderer.cpython-312.pyc
│ │ │ │ │ │ ├── _windows.cpython-312.pyc
│ │ │ │ │ │ ├── _wrap.cpython-312.pyc
│ │ │ │ │ │ ├── abc.cpython-312.pyc
│ │ │ │ │ │ ├── align.cpython-312.pyc
│ │ │ │ │ │ ├── ansi.cpython-312.pyc
│ │ │ │ │ │ ├── bar.cpython-312.pyc
│ │ │ │ │ │ ├── box.cpython-312.pyc
│ │ │ │ │ │ ├── cells.cpython-312.pyc
│ │ │ │ │ │ ├── color_triplet.cpython-312.pyc
│ │ │ │ │ │ ├── color.cpython-312.pyc
│ │ │ │ │ │ ├── columns.cpython-312.pyc
│ │ │ │ │ │ ├── console.cpython-312.pyc
│ │ │ │ │ │ ├── constrain.cpython-312.pyc
│ │ │ │ │ │ ├── containers.cpython-312.pyc
│ │ │ │ │ │ ├── control.cpython-312.pyc
│ │ │ │ │ │ ├── default_styles.cpython-312.pyc
│ │ │ │ │ │ ├── diagnose.cpython-312.pyc
│ │ │ │ │ │ ├── emoji.cpython-312.pyc
│ │ │ │ │ │ ├── errors.cpython-312.pyc
│ │ │ │ │ │ ├── file_proxy.cpython-312.pyc
│ │ │ │ │ │ ├── filesize.cpython-312.pyc
│ │ │ │ │ │ ├── highlighter.cpython-312.pyc
│ │ │ │ │ │ ├── json.cpython-312.pyc
│ │ │ │ │ │ ├── jupyter.cpython-312.pyc
│ │ │ │ │ │ ├── layout.cpython-312.pyc
│ │ │ │ │ │ ├── live_render.cpython-312.pyc
│ │ │ │ │ │ ├── live.cpython-312.pyc
│ │ │ │ │ │ ├── logging.cpython-312.pyc
│ │ │ │ │ │ ├── markup.cpython-312.pyc
│ │ │ │ │ │ ├── measure.cpython-312.pyc
│ │ │ │ │ │ ├── padding.cpython-312.pyc
│ │ │ │ │ │ ├── pager.cpython-312.pyc
│ │ │ │ │ │ ├── palette.cpython-312.pyc
│ │ │ │ │ │ ├── panel.cpython-312.pyc
│ │ │ │ │ │ ├── pretty.cpython-312.pyc
│ │ │ │ │ │ ├── progress_bar.cpython-312.pyc
│ │ │ │ │ │ ├── progress.cpython-312.pyc
│ │ │ │ │ │ ├── prompt.cpython-312.pyc
│ │ │ │ │ │ ├── protocol.cpython-312.pyc
│ │ │ │ │ │ ├── region.cpython-312.pyc
│ │ │ │ │ │ ├── repr.cpython-312.pyc
│ │ │ │ │ │ ├── rule.cpython-312.pyc
│ │ │ │ │ │ ├── scope.cpython-312.pyc
│ │ │ │ │ │ ├── screen.cpython-312.pyc
│ │ │ │ │ │ ├── segment.cpython-312.pyc
│ │ │ │ │ │ ├── spinner.cpython-312.pyc
│ │ │ │ │ │ ├── status.cpython-312.pyc
│ │ │ │ │ │ ├── style.cpython-312.pyc
│ │ │ │ │ │ ├── styled.cpython-312.pyc
│ │ │ │ │ │ ├── syntax.cpython-312.pyc
│ │ │ │ │ │ ├── table.cpython-312.pyc
│ │ │ │ │ │ ├── terminal_theme.cpython-312.pyc
│ │ │ │ │ │ ├── text.cpython-312.pyc
│ │ │ │ │ │ ├── theme.cpython-312.pyc
│ │ │ │ │ │ ├── themes.cpython-312.pyc
│ │ │ │ │ │ ├── traceback.cpython-312.pyc
│ │ │ │ │ │ └── tree.cpython-312.pyc
│ │ │ │ │ ├── _cell_widths.py
│ │ │ │ │ ├── _emoji_codes.py
│ │ │ │ │ ├── _emoji_replace.py
│ │ │ │ │ ├── _export_format.py
│ │ │ │ │ ├── _extension.py
│ │ │ │ │ ├── _fileno.py
│ │ │ │ │ ├── _inspect.py
│ │ │ │ │ ├── _log_render.py
│ │ │ │ │ ├── _loop.py
│ │ │ │ │ ├── _null_file.py
│ │ │ │ │ ├── _palettes.py
│ │ │ │ │ ├── _pick.py
│ │ │ │ │ ├── _ratio.py
│ │ │ │ │ ├── _spinners.py
│ │ │ │ │ ├── _stack.py
│ │ │ │ │ ├── _timer.py
│ │ │ │ │ ├── _win32_console.py
│ │ │ │ │ ├── _windows_renderer.py
│ │ │ │ │ ├── _windows.py
│ │ │ │ │ ├── _wrap.py
│ │ │ │ │ ├── abc.py
│ │ │ │ │ ├── align.py
│ │ │ │ │ ├── ansi.py
│ │ │ │ │ ├── bar.py
│ │ │ │ │ ├── box.py
│ │ │ │ │ ├── cells.py
│ │ │ │ │ ├── color_triplet.py
│ │ │ │ │ ├── color.py
│ │ │ │ │ ├── columns.py
│ │ │ │ │ ├── console.py
│ │ │ │ │ ├── constrain.py
│ │ │ │ │ ├── containers.py
│ │ │ │ │ ├── control.py
│ │ │ │ │ ├── default_styles.py
│ │ │ │ │ ├── diagnose.py
│ │ │ │ │ ├── emoji.py
│ │ │ │ │ ├── errors.py
│ │ │ │ │ ├── file_proxy.py
│ │ │ │ │ ├── filesize.py
│ │ │ │ │ ├── highlighter.py
│ │ │ │ │ ├── json.py
│ │ │ │ │ ├── jupyter.py
│ │ │ │ │ ├── layout.py
│ │ │ │ │ ├── live_render.py
│ │ │ │ │ ├── live.py
│ │ │ │ │ ├── logging.py
│ │ │ │ │ ├── markup.py
│ │ │ │ │ ├── measure.py
│ │ │ │ │ ├── padding.py
│ │ │ │ │ ├── pager.py
│ │ │ │ │ ├── palette.py
│ │ │ │ │ ├── panel.py
│ │ │ │ │ ├── pretty.py
│ │ │ │ │ ├── progress_bar.py
│ │ │ │ │ ├── progress.py
│ │ │ │ │ ├── prompt.py
│ │ │ │ │ ├── protocol.py
│ │ │ │ │ ├── py.typed
│ │ │ │ │ ├── region.py
│ │ │ │ │ ├── repr.py
│ │ │ │ │ ├── rule.py
│ │ │ │ │ ├── scope.py
│ │ │ │ │ ├── screen.py
│ │ │ │ │ ├── segment.py
│ │ │ │ │ ├── spinner.py
│ │ │ │ │ ├── status.py
│ │ │ │ │ ├── style.py
│ │ │ │ │ ├── styled.py
│ │ │ │ │ ├── syntax.py
│ │ │ │ │ ├── table.py
│ │ │ │ │ ├── terminal_theme.py
│ │ │ │ │ ├── text.py
│ │ │ │ │ ├── theme.py
│ │ │ │ │ ├── themes.py
│ │ │ │ │ ├── traceback.py
│ │ │ │ │ └── tree.py
│ │ │ │ ├── tomli
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── _parser.cpython-312.pyc
│ │ │ │ │ │ ├── _re.cpython-312.pyc
│ │ │ │ │ │ └── _types.cpython-312.pyc
│ │ │ │ │ ├── _parser.py
│ │ │ │ │ ├── _re.py
│ │ │ │ │ ├── _types.py
│ │ │ │ │ └── py.typed
│ │ │ │ ├── truststore
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── _api.cpython-312.pyc
│ │ │ │ │ │ ├── _macos.cpython-312.pyc
│ │ │ │ │ │ ├── _openssl.cpython-312.pyc
│ │ │ │ │ │ ├── _ssl_constants.cpython-312.pyc
│ │ │ │ │ │ └── _windows.cpython-312.pyc
│ │ │ │ │ ├── _api.py
│ │ │ │ │ ├── _macos.py
│ │ │ │ │ ├── _openssl.py
│ │ │ │ │ ├── _ssl_constants.py
│ │ │ │ │ ├── _windows.py
│ │ │ │ │ └── py.typed
│ │ │ │ ├── typing_extensions.py
│ │ │ │ ├── urllib3
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── _collections.cpython-312.pyc
│ │ │ │ │ │ ├── _version.cpython-312.pyc
│ │ │ │ │ │ ├── connection.cpython-312.pyc
│ │ │ │ │ │ ├── connectionpool.cpython-312.pyc
│ │ │ │ │ │ ├── exceptions.cpython-312.pyc
│ │ │ │ │ │ ├── fields.cpython-312.pyc
│ │ │ │ │ │ ├── filepost.cpython-312.pyc
│ │ │ │ │ │ ├── poolmanager.cpython-312.pyc
│ │ │ │ │ │ ├── request.cpython-312.pyc
│ │ │ │ │ │ └── response.cpython-312.pyc
│ │ │ │ │ ├── _collections.py
│ │ │ │ │ ├── _version.py
│ │ │ │ │ ├── connection.py
│ │ │ │ │ ├── connectionpool.py
│ │ │ │ │ ├── contrib
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ │ ├── _appengine_environ.cpython-312.pyc
│ │ │ │ │ │ │ ├── appengine.cpython-312.pyc
│ │ │ │ │ │ │ ├── ntlmpool.cpython-312.pyc
│ │ │ │ │ │ │ ├── pyopenssl.cpython-312.pyc
│ │ │ │ │ │ │ ├── securetransport.cpython-312.pyc
│ │ │ │ │ │ │ └── socks.cpython-312.pyc
│ │ │ │ │ │ ├── _appengine_environ.py
│ │ │ │ │ │ ├── _securetransport
│ │ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ │ │ ├── bindings.cpython-312.pyc
│ │ │ │ │ │ │ │ └── low_level.cpython-312.pyc
│ │ │ │ │ │ │ ├── bindings.py
│ │ │ │ │ │ │ └── low_level.py
│ │ │ │ │ │ ├── appengine.py
│ │ │ │ │ │ ├── ntlmpool.py
│ │ │ │ │ │ ├── pyopenssl.py
│ │ │ │ │ │ ├── securetransport.py
│ │ │ │ │ │ └── socks.py
│ │ │ │ │ ├── exceptions.py
│ │ │ │ │ ├── fields.py
│ │ │ │ │ ├── filepost.py
│ │ │ │ │ ├── packages
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ │ └── six.cpython-312.pyc
│ │ │ │ │ │ ├── backports
│ │ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ │ │ ├── makefile.cpython-312.pyc
│ │ │ │ │ │ │ │ └── weakref_finalize.cpython-312.pyc
│ │ │ │ │ │ │ ├── makefile.py
│ │ │ │ │ │ │ └── weakref_finalize.py
│ │ │ │ │ │ └── six.py
│ │ │ │ │ ├── poolmanager.py
│ │ │ │ │ ├── request.py
│ │ │ │ │ ├── response.py
│ │ │ │ │ └── util
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── connection.cpython-312.pyc
│ │ │ │ │ │ ├── proxy.cpython-312.pyc
│ │ │ │ │ │ ├── queue.cpython-312.pyc
│ │ │ │ │ │ ├── request.cpython-312.pyc
│ │ │ │ │ │ ├── response.cpython-312.pyc
│ │ │ │ │ │ ├── retry.cpython-312.pyc
│ │ │ │ │ │ ├── ssl_.cpython-312.pyc
│ │ │ │ │ │ ├── ssl_match_hostname.cpython-312.pyc
│ │ │ │ │ │ ├── ssltransport.cpython-312.pyc
│ │ │ │ │ │ ├── timeout.cpython-312.pyc
│ │ │ │ │ │ ├── url.cpython-312.pyc
│ │ │ │ │ │ └── wait.cpython-312.pyc
│ │ │ │ │ ├── connection.py
│ │ │ │ │ ├── proxy.py
│ │ │ │ │ ├── queue.py
│ │ │ │ │ ├── request.py
│ │ │ │ │ ├── response.py
│ │ │ │ │ ├── retry.py
│ │ │ │ │ ├── ssl_.py
│ │ │ │ │ ├── ssl_match_hostname.py
│ │ │ │ │ ├── ssltransport.py
│ │ │ │ │ ├── timeout.py
│ │ │ │ │ ├── url.py
│ │ │ │ │ └── wait.py
│ │ │ │ └── vendor.txt
│ │ │ └── py.typed
│ │ ├── pip-24.2.dist-info
│ │ │ ├── AUTHORS.txt
│ │ │ ├── entry_points.txt
│ │ │ ├── INSTALLER
│ │ │ ├── LICENSE.txt
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ ├── REQUESTED
│ │ │ ├── top_level.txt
│ │ │ └── WHEEL
│ │ ├── requests
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── __version__.cpython-312.pyc
│ │ │ │ ├── _internal_utils.cpython-312.pyc
│ │ │ │ ├── adapters.cpython-312.pyc
│ │ │ │ ├── api.cpython-312.pyc
│ │ │ │ ├── auth.cpython-312.pyc
│ │ │ │ ├── certs.cpython-312.pyc
│ │ │ │ ├── compat.cpython-312.pyc
│ │ │ │ ├── cookies.cpython-312.pyc
│ │ │ │ ├── exceptions.cpython-312.pyc
│ │ │ │ ├── help.cpython-312.pyc
│ │ │ │ ├── hooks.cpython-312.pyc
│ │ │ │ ├── models.cpython-312.pyc
│ │ │ │ ├── packages.cpython-312.pyc
│ │ │ │ ├── sessions.cpython-312.pyc
│ │ │ │ ├── status_codes.cpython-312.pyc
│ │ │ │ ├── structures.cpython-312.pyc
│ │ │ │ └── utils.cpython-312.pyc
│ │ │ ├── __version__.py
│ │ │ ├── _internal_utils.py
│ │ │ ├── adapters.py
│ │ │ ├── api.py
│ │ │ ├── auth.py
│ │ │ ├── certs.py
│ │ │ ├── compat.py
│ │ │ ├── cookies.py
│ │ │ ├── exceptions.py
│ │ │ ├── help.py
│ │ │ ├── hooks.py
│ │ │ ├── models.py
│ │ │ ├── packages.py
│ │ │ ├── sessions.py
│ │ │ ├── status_codes.py
│ │ │ ├── structures.py
│ │ │ └── utils.py
│ │ ├── requests-2.32.3.dist-info
│ │ │ ├── INSTALLER
│ │ │ ├── LICENSE
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ ├── REQUESTED
│ │ │ ├── top_level.txt
│ │ │ └── WHEEL
│ │ ├── soupsieve
│ │ │ ├── __init__.py
│ │ │ ├── __meta__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── __meta__.cpython-312.pyc
│ │ │ │ ├── css_match.cpython-312.pyc
│ │ │ │ ├── css_parser.cpython-312.pyc
│ │ │ │ ├── css_types.cpython-312.pyc
│ │ │ │ ├── pretty.cpython-312.pyc
│ │ │ │ └── util.cpython-312.pyc
│ │ │ ├── css_match.py
│ │ │ ├── css_parser.py
│ │ │ ├── css_types.py
│ │ │ ├── pretty.py
│ │ │ ├── py.typed
│ │ │ └── util.py
│ │ ├── soupsieve-2.6.dist-info
│ │ │ ├── INSTALLER
│ │ │ ├── licenses
│ │ │ │ └── LICENSE.md
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ └── WHEEL
│ │ ├── urllib3
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── _base_connection.cpython-312.pyc
│ │ │ │ ├── _collections.cpython-312.pyc
│ │ │ │ ├── _request_methods.cpython-312.pyc
│ │ │ │ ├── _version.cpython-312.pyc
│ │ │ │ ├── connection.cpython-312.pyc
│ │ │ │ ├── connectionpool.cpython-312.pyc
│ │ │ │ ├── exceptions.cpython-312.pyc
│ │ │ │ ├── fields.cpython-312.pyc
│ │ │ │ ├── filepost.cpython-312.pyc
│ │ │ │ ├── poolmanager.cpython-312.pyc
│ │ │ │ └── response.cpython-312.pyc
│ │ │ ├── _base_connection.py
│ │ │ ├── _collections.py
│ │ │ ├── _request_methods.py
│ │ │ ├── _version.py
│ │ │ ├── connection.py
│ │ │ ├── connectionpool.py
│ │ │ ├── contrib
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ ├── pyopenssl.cpython-312.pyc
│ │ │ │ │ └── socks.cpython-312.pyc
│ │ │ │ ├── emscripten
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── connection.cpython-312.pyc
│ │ │ │ │ │ ├── fetch.cpython-312.pyc
│ │ │ │ │ │ ├── request.cpython-312.pyc
│ │ │ │ │ │ └── response.cpython-312.pyc
│ │ │ │ │ ├── connection.py
│ │ │ │ │ ├── emscripten_fetch_worker.js
│ │ │ │ │ ├── fetch.py
│ │ │ │ │ ├── request.py
│ │ │ │ │ └── response.py
│ │ │ │ ├── pyopenssl.py
│ │ │ │ └── socks.py
│ │ │ ├── exceptions.py
│ │ │ ├── fields.py
│ │ │ ├── filepost.py
│ │ │ ├── http2
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ ├── connection.cpython-312.pyc
│ │ │ │ │ └── probe.cpython-312.pyc
│ │ │ │ ├── connection.py
│ │ │ │ └── probe.py
│ │ │ ├── poolmanager.py
│ │ │ ├── py.typed
│ │ │ ├── response.py
│ │ │ └── util
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── connection.cpython-312.pyc
│ │ │ │ ├── proxy.cpython-312.pyc
│ │ │ │ ├── request.cpython-312.pyc
│ │ │ │ ├── response.cpython-312.pyc
│ │ │ │ ├── retry.cpython-312.pyc
│ │ │ │ ├── ssl_.cpython-312.pyc
│ │ │ │ ├── ssl_match_hostname.cpython-312.pyc
│ │ │ │ ├── ssltransport.cpython-312.pyc
│ │ │ │ ├── timeout.cpython-312.pyc
│ │ │ │ ├── url.cpython-312.pyc
│ │ │ │ ├── util.cpython-312.pyc
│ │ │ │ └── wait.cpython-312.pyc
│ │ │ ├── connection.py
│ │ │ ├── proxy.py
│ │ │ ├── request.py
│ │ │ ├── response.py
│ │ │ ├── retry.py
│ │ │ ├── ssl_.py
│ │ │ ├── ssl_match_hostname.py
│ │ │ ├── ssltransport.py
│ │ │ ├── timeout.py
│ │ │ ├── url.py
│ │ │ ├── util.py
│ │ │ └── wait.py
│ │ ├── urllib3-2.2.3.dist-info
│ │ │ ├── INSTALLER
│ │ │ ├── licenses
│ │ │ │ └── LICENSE.txt
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ └── WHEEL
│ │ ├── useragent
│ │ │ ├── __init__.py
│ │ │ ├── __init__.pyc
│ │ │ ├── __pycache__
│ │ │ │ └── __init__.cpython-312.pyc
│ │ │ ├── resources
│ │ │ │ └── user_agent_data.json
│ │ │ └── test
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ └── __init__.cpython-312.pyc
│ │ │ ├── test_additional_os.json
│ │ │ ├── test_browser.json
│ │ │ ├── test_device.json
│ │ │ ├── test_firefox.json
│ │ │ ├── test_os.json
│ │ │ └── test_pgts_browser.json
│ │ ├── useragent-0.1.1.dist-info
│ │ │ ├── INSTALLER
│ │ │ ├── LICENSE.txt
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ ├── REQUESTED
│ │ │ ├── top_level.txt
│ │ │ └── WHEEL
│ │ ├── werkzeug
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── _internal.cpython-312.pyc
│ │ │ │ ├── _reloader.cpython-312.pyc
│ │ │ │ ├── exceptions.cpython-312.pyc
│ │ │ │ ├── formparser.cpython-312.pyc
│ │ │ │ ├── http.cpython-312.pyc
│ │ │ │ ├── local.cpython-312.pyc
│ │ │ │ ├── security.cpython-312.pyc
│ │ │ │ ├── serving.cpython-312.pyc
│ │ │ │ ├── test.cpython-312.pyc
│ │ │ │ ├── testapp.cpython-312.pyc
│ │ │ │ ├── urls.cpython-312.pyc
│ │ │ │ ├── user_agent.cpython-312.pyc
│ │ │ │ ├── utils.cpython-312.pyc
│ │ │ │ └── wsgi.cpython-312.pyc
│ │ │ ├── _internal.py
│ │ │ ├── _reloader.py
│ │ │ ├── datastructures
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ ├── accept.cpython-312.pyc
│ │ │ │ │ ├── auth.cpython-312.pyc
│ │ │ │ │ ├── cache_control.cpython-312.pyc
│ │ │ │ │ ├── csp.cpython-312.pyc
│ │ │ │ │ ├── etag.cpython-312.pyc
│ │ │ │ │ ├── file_storage.cpython-312.pyc
│ │ │ │ │ ├── headers.cpython-312.pyc
│ │ │ │ │ ├── mixins.cpython-312.pyc
│ │ │ │ │ ├── range.cpython-312.pyc
│ │ │ │ │ └── structures.cpython-312.pyc
│ │ │ │ ├── accept.py
│ │ │ │ ├── accept.pyi
│ │ │ │ ├── auth.py
│ │ │ │ ├── cache_control.py
│ │ │ │ ├── cache_control.pyi
│ │ │ │ ├── csp.py
│ │ │ │ ├── csp.pyi
│ │ │ │ ├── etag.py
│ │ │ │ ├── etag.pyi
│ │ │ │ ├── file_storage.py
│ │ │ │ ├── file_storage.pyi
│ │ │ │ ├── headers.py
│ │ │ │ ├── headers.pyi
│ │ │ │ ├── mixins.py
│ │ │ │ ├── mixins.pyi
│ │ │ │ ├── range.py
│ │ │ │ ├── range.pyi
│ │ │ │ ├── structures.py
│ │ │ │ └── structures.pyi
│ │ │ ├── debug
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ ├── console.cpython-312.pyc
│ │ │ │ │ ├── repr.cpython-312.pyc
│ │ │ │ │ └── tbtools.cpython-312.pyc
│ │ │ │ ├── console.py
│ │ │ │ ├── repr.py
│ │ │ │ ├── shared
│ │ │ │ │ ├── console.png
│ │ │ │ │ ├── debugger.js
│ │ │ │ │ ├── ICON_LICENSE.md
│ │ │ │ │ ├── less.png
│ │ │ │ │ ├── more.png
│ │ │ │ │ └── style.css
│ │ │ │ └── tbtools.py
│ │ │ ├── exceptions.py
│ │ │ ├── formparser.py
│ │ │ ├── http.py
│ │ │ ├── local.py
│ │ │ ├── middleware
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ ├── dispatcher.cpython-312.pyc
│ │ │ │ │ ├── http_proxy.cpython-312.pyc
│ │ │ │ │ ├── lint.cpython-312.pyc
│ │ │ │ │ ├── profiler.cpython-312.pyc
│ │ │ │ │ ├── proxy_fix.cpython-312.pyc
│ │ │ │ │ └── shared_data.cpython-312.pyc
│ │ │ │ ├── dispatcher.py
│ │ │ │ ├── http_proxy.py
│ │ │ │ ├── lint.py
│ │ │ │ ├── profiler.py
│ │ │ │ ├── proxy_fix.py
│ │ │ │ └── shared_data.py
│ │ │ ├── py.typed
│ │ │ ├── routing
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ ├── converters.cpython-312.pyc
│ │ │ │ │ ├── exceptions.cpython-312.pyc
│ │ │ │ │ ├── map.cpython-312.pyc
│ │ │ │ │ ├── matcher.cpython-312.pyc
│ │ │ │ │ └── rules.cpython-312.pyc
│ │ │ │ ├── converters.py
│ │ │ │ ├── exceptions.py
│ │ │ │ ├── map.py
│ │ │ │ ├── matcher.py
│ │ │ │ └── rules.py
│ │ │ ├── sansio
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ ├── http.cpython-312.pyc
│ │ │ │ │ ├── multipart.cpython-312.pyc
│ │ │ │ │ ├── request.cpython-312.pyc
│ │ │ │ │ ├── response.cpython-312.pyc
│ │ │ │ │ └── utils.cpython-312.pyc
│ │ │ │ ├── http.py
│ │ │ │ ├── multipart.py
│ │ │ │ ├── request.py
│ │ │ │ ├── response.py
│ │ │ │ └── utils.py
│ │ │ ├── security.py
│ │ │ ├── serving.py
│ │ │ ├── test.py
│ │ │ ├── testapp.py
│ │ │ ├── urls.py
│ │ │ ├── user_agent.py
│ │ │ ├── utils.py
│ │ │ ├── wrappers
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ ├── request.cpython-312.pyc
│ │ │ │ │ └── response.cpython-312.pyc
│ │ │ │ ├── request.py
│ │ │ │ └── response.py
│ │ │ └── wsgi.py
│ │ └── werkzeug-3.0.4.dist-info
│ │ ├── INSTALLER
│ │ ├── LICENSE.txt
│ │ ├── METADATA
│ │ ├── RECORD
│ │ └── WHEEL
│ ├── pyvenv.cfg
│ ├── static
│ │ └── styles.css
│ ├── templates
│ │ └── index.html
│ └── test.py
├── cline_config.json
├── mcp_server.py
├── README.md
├── search_results.json
├── settings.json
└── test_files
├── text1.txt
└── text2.txt
```
# Files
--------------------------------------------------------------------------------
/.venv/lib/python3.12/site-packages/click/decorators.py:
--------------------------------------------------------------------------------
```python
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 | if t.TYPE_CHECKING:
17 | import typing_extensions as te
18 |
19 | P = te.ParamSpec("P")
20 |
21 | R = t.TypeVar("R")
22 | T = t.TypeVar("T")
23 | _AnyCallable = t.Callable[..., t.Any]
24 | FC = t.TypeVar("FC", bound=t.Union[_AnyCallable, Command])
25 |
26 |
27 | def pass_context(f: "t.Callable[te.Concatenate[Context, P], R]") -> "t.Callable[P, R]":
28 | """Marks a callback as wanting to receive the current context
29 | object as first argument.
30 | """
31 |
32 | def new_func(*args: "P.args", **kwargs: "P.kwargs") -> "R":
33 | return f(get_current_context(), *args, **kwargs)
34 |
35 | return update_wrapper(new_func, f)
36 |
37 |
38 | def pass_obj(f: "t.Callable[te.Concatenate[t.Any, P], R]") -> "t.Callable[P, R]":
39 | """Similar to :func:`pass_context`, but only pass the object on the
40 | context onwards (:attr:`Context.obj`). This is useful if that object
41 | represents the state of a nested system.
42 | """
43 |
44 | def new_func(*args: "P.args", **kwargs: "P.kwargs") -> "R":
45 | return f(get_current_context().obj, *args, **kwargs)
46 |
47 | return update_wrapper(new_func, f)
48 |
49 |
50 | def make_pass_decorator(
51 | object_type: t.Type[T], ensure: bool = False
52 | ) -> t.Callable[["t.Callable[te.Concatenate[T, P], R]"], "t.Callable[P, R]"]:
53 | """Given an object type this creates a decorator that will work
54 | similar to :func:`pass_obj` but instead of passing the object of the
55 | current context, it will find the innermost context of type
56 | :func:`object_type`.
57 |
58 | This generates a decorator that works roughly like this::
59 |
60 | from functools import update_wrapper
61 |
62 | def decorator(f):
63 | @pass_context
64 | def new_func(ctx, *args, **kwargs):
65 | obj = ctx.find_object(object_type)
66 | return ctx.invoke(f, obj, *args, **kwargs)
67 | return update_wrapper(new_func, f)
68 | return decorator
69 |
70 | :param object_type: the type of the object to pass.
71 | :param ensure: if set to `True`, a new object will be created and
72 | remembered on the context if it's not there yet.
73 | """
74 |
75 | def decorator(f: "t.Callable[te.Concatenate[T, P], R]") -> "t.Callable[P, R]":
76 | def new_func(*args: "P.args", **kwargs: "P.kwargs") -> "R":
77 | ctx = get_current_context()
78 |
79 | obj: t.Optional[T]
80 | if ensure:
81 | obj = ctx.ensure_object(object_type)
82 | else:
83 | obj = ctx.find_object(object_type)
84 |
85 | if obj is None:
86 | raise RuntimeError(
87 | "Managed to invoke callback without a context"
88 | f" object of type {object_type.__name__!r}"
89 | " existing."
90 | )
91 |
92 | return ctx.invoke(f, obj, *args, **kwargs)
93 |
94 | return update_wrapper(new_func, f)
95 |
96 | return decorator # type: ignore[return-value]
97 |
98 |
99 | def pass_meta_key(
100 | key: str, *, doc_description: t.Optional[str] = None
101 | ) -> "t.Callable[[t.Callable[te.Concatenate[t.Any, P], R]], t.Callable[P, R]]":
102 | """Create a decorator that passes a key from
103 | :attr:`click.Context.meta` as the first argument to the decorated
104 | function.
105 |
106 | :param key: Key in ``Context.meta`` to pass.
107 | :param doc_description: Description of the object being passed,
108 | inserted into the decorator's docstring. Defaults to "the 'key'
109 | key from Context.meta".
110 |
111 | .. versionadded:: 8.0
112 | """
113 |
114 | def decorator(f: "t.Callable[te.Concatenate[t.Any, P], R]") -> "t.Callable[P, R]":
115 | def new_func(*args: "P.args", **kwargs: "P.kwargs") -> R:
116 | ctx = get_current_context()
117 | obj = ctx.meta[key]
118 | return ctx.invoke(f, obj, *args, **kwargs)
119 |
120 | return update_wrapper(new_func, f)
121 |
122 | if doc_description is None:
123 | doc_description = f"the {key!r} key from :attr:`click.Context.meta`"
124 |
125 | decorator.__doc__ = (
126 | f"Decorator that passes {doc_description} as the first argument"
127 | " to the decorated function."
128 | )
129 | return decorator # type: ignore[return-value]
130 |
131 |
132 | CmdType = t.TypeVar("CmdType", bound=Command)
133 |
134 |
135 | # variant: no call, directly as decorator for a function.
136 | @t.overload
137 | def command(name: _AnyCallable) -> Command:
138 | ...
139 |
140 |
141 | # variant: with positional name and with positional or keyword cls argument:
142 | # @command(namearg, CommandCls, ...) or @command(namearg, cls=CommandCls, ...)
143 | @t.overload
144 | def command(
145 | name: t.Optional[str],
146 | cls: t.Type[CmdType],
147 | **attrs: t.Any,
148 | ) -> t.Callable[[_AnyCallable], CmdType]:
149 | ...
150 |
151 |
152 | # variant: name omitted, cls _must_ be a keyword argument, @command(cls=CommandCls, ...)
153 | @t.overload
154 | def command(
155 | name: None = None,
156 | *,
157 | cls: t.Type[CmdType],
158 | **attrs: t.Any,
159 | ) -> t.Callable[[_AnyCallable], CmdType]:
160 | ...
161 |
162 |
163 | # variant: with optional string name, no cls argument provided.
164 | @t.overload
165 | def command(
166 | name: t.Optional[str] = ..., cls: None = None, **attrs: t.Any
167 | ) -> t.Callable[[_AnyCallable], Command]:
168 | ...
169 |
170 |
171 | def command(
172 | name: t.Union[t.Optional[str], _AnyCallable] = None,
173 | cls: t.Optional[t.Type[CmdType]] = None,
174 | **attrs: t.Any,
175 | ) -> t.Union[Command, t.Callable[[_AnyCallable], t.Union[Command, CmdType]]]:
176 | r"""Creates a new :class:`Command` and uses the decorated function as
177 | callback. This will also automatically attach all decorated
178 | :func:`option`\s and :func:`argument`\s as parameters to the command.
179 |
180 | The name of the command defaults to the name of the function with
181 | underscores replaced by dashes. If you want to change that, you can
182 | pass the intended name as the first argument.
183 |
184 | All keyword arguments are forwarded to the underlying command class.
185 | For the ``params`` argument, any decorated params are appended to
186 | the end of the list.
187 |
188 | Once decorated the function turns into a :class:`Command` instance
189 | that can be invoked as a command line utility or be attached to a
190 | command :class:`Group`.
191 |
192 | :param name: the name of the command. This defaults to the function
193 | name with underscores replaced by dashes.
194 | :param cls: the command class to instantiate. This defaults to
195 | :class:`Command`.
196 |
197 | .. versionchanged:: 8.1
198 | This decorator can be applied without parentheses.
199 |
200 | .. versionchanged:: 8.1
201 | The ``params`` argument can be used. Decorated params are
202 | appended to the end of the list.
203 | """
204 |
205 | func: t.Optional[t.Callable[[_AnyCallable], t.Any]] = None
206 |
207 | if callable(name):
208 | func = name
209 | name = None
210 | assert cls is None, "Use 'command(cls=cls)(callable)' to specify a class."
211 | assert not attrs, "Use 'command(**kwargs)(callable)' to provide arguments."
212 |
213 | if cls is None:
214 | cls = t.cast(t.Type[CmdType], Command)
215 |
216 | def decorator(f: _AnyCallable) -> CmdType:
217 | if isinstance(f, Command):
218 | raise TypeError("Attempted to convert a callback into a command twice.")
219 |
220 | attr_params = attrs.pop("params", None)
221 | params = attr_params if attr_params is not None else []
222 |
223 | try:
224 | decorator_params = f.__click_params__ # type: ignore
225 | except AttributeError:
226 | pass
227 | else:
228 | del f.__click_params__ # type: ignore
229 | params.extend(reversed(decorator_params))
230 |
231 | if attrs.get("help") is None:
232 | attrs["help"] = f.__doc__
233 |
234 | if t.TYPE_CHECKING:
235 | assert cls is not None
236 | assert not callable(name)
237 |
238 | cmd = cls(
239 | name=name or f.__name__.lower().replace("_", "-"),
240 | callback=f,
241 | params=params,
242 | **attrs,
243 | )
244 | cmd.__doc__ = f.__doc__
245 | return cmd
246 |
247 | if func is not None:
248 | return decorator(func)
249 |
250 | return decorator
251 |
252 |
253 | GrpType = t.TypeVar("GrpType", bound=Group)
254 |
255 |
256 | # variant: no call, directly as decorator for a function.
257 | @t.overload
258 | def group(name: _AnyCallable) -> Group:
259 | ...
260 |
261 |
262 | # variant: with positional name and with positional or keyword cls argument:
263 | # @group(namearg, GroupCls, ...) or @group(namearg, cls=GroupCls, ...)
264 | @t.overload
265 | def group(
266 | name: t.Optional[str],
267 | cls: t.Type[GrpType],
268 | **attrs: t.Any,
269 | ) -> t.Callable[[_AnyCallable], GrpType]:
270 | ...
271 |
272 |
273 | # variant: name omitted, cls _must_ be a keyword argument, @group(cmd=GroupCls, ...)
274 | @t.overload
275 | def group(
276 | name: None = None,
277 | *,
278 | cls: t.Type[GrpType],
279 | **attrs: t.Any,
280 | ) -> t.Callable[[_AnyCallable], GrpType]:
281 | ...
282 |
283 |
284 | # variant: with optional string name, no cls argument provided.
285 | @t.overload
286 | def group(
287 | name: t.Optional[str] = ..., cls: None = None, **attrs: t.Any
288 | ) -> t.Callable[[_AnyCallable], Group]:
289 | ...
290 |
291 |
292 | def group(
293 | name: t.Union[str, _AnyCallable, None] = None,
294 | cls: t.Optional[t.Type[GrpType]] = None,
295 | **attrs: t.Any,
296 | ) -> t.Union[Group, t.Callable[[_AnyCallable], t.Union[Group, GrpType]]]:
297 | """Creates a new :class:`Group` with a function as callback. This
298 | works otherwise the same as :func:`command` just that the `cls`
299 | parameter is set to :class:`Group`.
300 |
301 | .. versionchanged:: 8.1
302 | This decorator can be applied without parentheses.
303 | """
304 | if cls is None:
305 | cls = t.cast(t.Type[GrpType], Group)
306 |
307 | if callable(name):
308 | return command(cls=cls, **attrs)(name)
309 |
310 | return command(name, cls, **attrs)
311 |
312 |
313 | def _param_memo(f: t.Callable[..., t.Any], param: Parameter) -> None:
314 | if isinstance(f, Command):
315 | f.params.append(param)
316 | else:
317 | if not hasattr(f, "__click_params__"):
318 | f.__click_params__ = [] # type: ignore
319 |
320 | f.__click_params__.append(param) # type: ignore
321 |
322 |
323 | def argument(
324 | *param_decls: str, cls: t.Optional[t.Type[Argument]] = None, **attrs: t.Any
325 | ) -> t.Callable[[FC], FC]:
326 | """Attaches an argument to the command. All positional arguments are
327 | passed as parameter declarations to :class:`Argument`; all keyword
328 | arguments are forwarded unchanged (except ``cls``).
329 | This is equivalent to creating an :class:`Argument` instance manually
330 | and attaching it to the :attr:`Command.params` list.
331 |
332 | For the default argument class, refer to :class:`Argument` and
333 | :class:`Parameter` for descriptions of parameters.
334 |
335 | :param cls: the argument class to instantiate. This defaults to
336 | :class:`Argument`.
337 | :param param_decls: Passed as positional arguments to the constructor of
338 | ``cls``.
339 | :param attrs: Passed as keyword arguments to the constructor of ``cls``.
340 | """
341 | if cls is None:
342 | cls = Argument
343 |
344 | def decorator(f: FC) -> FC:
345 | _param_memo(f, cls(param_decls, **attrs))
346 | return f
347 |
348 | return decorator
349 |
350 |
351 | def option(
352 | *param_decls: str, cls: t.Optional[t.Type[Option]] = None, **attrs: t.Any
353 | ) -> t.Callable[[FC], FC]:
354 | """Attaches an option to the command. All positional arguments are
355 | passed as parameter declarations to :class:`Option`; all keyword
356 | arguments are forwarded unchanged (except ``cls``).
357 | This is equivalent to creating an :class:`Option` instance manually
358 | and attaching it to the :attr:`Command.params` list.
359 |
360 | For the default option class, refer to :class:`Option` and
361 | :class:`Parameter` for descriptions of parameters.
362 |
363 | :param cls: the option class to instantiate. This defaults to
364 | :class:`Option`.
365 | :param param_decls: Passed as positional arguments to the constructor of
366 | ``cls``.
367 | :param attrs: Passed as keyword arguments to the constructor of ``cls``.
368 | """
369 | if cls is None:
370 | cls = Option
371 |
372 | def decorator(f: FC) -> FC:
373 | _param_memo(f, cls(param_decls, **attrs))
374 | return f
375 |
376 | return decorator
377 |
378 |
379 | def confirmation_option(*param_decls: str, **kwargs: t.Any) -> t.Callable[[FC], FC]:
380 | """Add a ``--yes`` option which shows a prompt before continuing if
381 | not passed. If the prompt is declined, the program will exit.
382 |
383 | :param param_decls: One or more option names. Defaults to the single
384 | value ``"--yes"``.
385 | :param kwargs: Extra arguments are passed to :func:`option`.
386 | """
387 |
388 | def callback(ctx: Context, param: Parameter, value: bool) -> None:
389 | if not value:
390 | ctx.abort()
391 |
392 | if not param_decls:
393 | param_decls = ("--yes",)
394 |
395 | kwargs.setdefault("is_flag", True)
396 | kwargs.setdefault("callback", callback)
397 | kwargs.setdefault("expose_value", False)
398 | kwargs.setdefault("prompt", "Do you want to continue?")
399 | kwargs.setdefault("help", "Confirm the action without prompting.")
400 | return option(*param_decls, **kwargs)
401 |
402 |
403 | def password_option(*param_decls: str, **kwargs: t.Any) -> t.Callable[[FC], FC]:
404 | """Add a ``--password`` option which prompts for a password, hiding
405 | input and asking to enter the value again for confirmation.
406 |
407 | :param param_decls: One or more option names. Defaults to the single
408 | value ``"--password"``.
409 | :param kwargs: Extra arguments are passed to :func:`option`.
410 | """
411 | if not param_decls:
412 | param_decls = ("--password",)
413 |
414 | kwargs.setdefault("prompt", True)
415 | kwargs.setdefault("confirmation_prompt", True)
416 | kwargs.setdefault("hide_input", True)
417 | return option(*param_decls, **kwargs)
418 |
419 |
420 | def version_option(
421 | version: t.Optional[str] = None,
422 | *param_decls: str,
423 | package_name: t.Optional[str] = None,
424 | prog_name: t.Optional[str] = None,
425 | message: t.Optional[str] = None,
426 | **kwargs: t.Any,
427 | ) -> t.Callable[[FC], FC]:
428 | """Add a ``--version`` option which immediately prints the version
429 | number and exits the program.
430 |
431 | If ``version`` is not provided, Click will try to detect it using
432 | :func:`importlib.metadata.version` to get the version for the
433 | ``package_name``. On Python < 3.8, the ``importlib_metadata``
434 | backport must be installed.
435 |
436 | If ``package_name`` is not provided, Click will try to detect it by
437 | inspecting the stack frames. This will be used to detect the
438 | version, so it must match the name of the installed package.
439 |
440 | :param version: The version number to show. If not provided, Click
441 | will try to detect it.
442 | :param param_decls: One or more option names. Defaults to the single
443 | value ``"--version"``.
444 | :param package_name: The package name to detect the version from. If
445 | not provided, Click will try to detect it.
446 | :param prog_name: The name of the CLI to show in the message. If not
447 | provided, it will be detected from the command.
448 | :param message: The message to show. The values ``%(prog)s``,
449 | ``%(package)s``, and ``%(version)s`` are available. Defaults to
450 | ``"%(prog)s, version %(version)s"``.
451 | :param kwargs: Extra arguments are passed to :func:`option`.
452 | :raise RuntimeError: ``version`` could not be detected.
453 |
454 | .. versionchanged:: 8.0
455 | Add the ``package_name`` parameter, and the ``%(package)s``
456 | value for messages.
457 |
458 | .. versionchanged:: 8.0
459 | Use :mod:`importlib.metadata` instead of ``pkg_resources``. The
460 | version is detected based on the package name, not the entry
461 | point name. The Python package name must match the installed
462 | package name, or be passed with ``package_name=``.
463 | """
464 | if message is None:
465 | message = _("%(prog)s, version %(version)s")
466 |
467 | if version is None and package_name is None:
468 | frame = inspect.currentframe()
469 | f_back = frame.f_back if frame is not None else None
470 | f_globals = f_back.f_globals if f_back is not None else None
471 | # break reference cycle
472 | # https://docs.python.org/3/library/inspect.html#the-interpreter-stack
473 | del frame
474 |
475 | if f_globals is not None:
476 | package_name = f_globals.get("__name__")
477 |
478 | if package_name == "__main__":
479 | package_name = f_globals.get("__package__")
480 |
481 | if package_name:
482 | package_name = package_name.partition(".")[0]
483 |
484 | def callback(ctx: Context, param: Parameter, value: bool) -> None:
485 | if not value or ctx.resilient_parsing:
486 | return
487 |
488 | nonlocal prog_name
489 | nonlocal version
490 |
491 | if prog_name is None:
492 | prog_name = ctx.find_root().info_name
493 |
494 | if version is None and package_name is not None:
495 | metadata: t.Optional[types.ModuleType]
496 |
497 | try:
498 | from importlib import metadata # type: ignore
499 | except ImportError:
500 | # Python < 3.8
501 | import importlib_metadata as metadata # type: ignore
502 |
503 | try:
504 | version = metadata.version(package_name) # type: ignore
505 | except metadata.PackageNotFoundError: # type: ignore
506 | raise RuntimeError(
507 | f"{package_name!r} is not installed. Try passing"
508 | " 'package_name' instead."
509 | ) from None
510 |
511 | if version is None:
512 | raise RuntimeError(
513 | f"Could not determine the version for {package_name!r} automatically."
514 | )
515 |
516 | echo(
517 | message % {"prog": prog_name, "package": package_name, "version": version},
518 | color=ctx.color,
519 | )
520 | ctx.exit()
521 |
522 | if not param_decls:
523 | param_decls = ("--version",)
524 |
525 | kwargs.setdefault("is_flag", True)
526 | kwargs.setdefault("expose_value", False)
527 | kwargs.setdefault("is_eager", True)
528 | kwargs.setdefault("help", _("Show the version and exit."))
529 | kwargs["callback"] = callback
530 | return option(*param_decls, **kwargs)
531 |
532 |
533 | def help_option(*param_decls: str, **kwargs: t.Any) -> t.Callable[[FC], FC]:
534 | """Add a ``--help`` option which immediately prints the help page
535 | and exits the program.
536 |
537 | This is usually unnecessary, as the ``--help`` option is added to
538 | each command automatically unless ``add_help_option=False`` is
539 | passed.
540 |
541 | :param param_decls: One or more option names. Defaults to the single
542 | value ``"--help"``.
543 | :param kwargs: Extra arguments are passed to :func:`option`.
544 | """
545 |
546 | def callback(ctx: Context, param: Parameter, value: bool) -> None:
547 | if not value or ctx.resilient_parsing:
548 | return
549 |
550 | echo(ctx.get_help(), color=ctx.color)
551 | ctx.exit()
552 |
553 | if not param_decls:
554 | param_decls = ("--help",)
555 |
556 | kwargs.setdefault("is_flag", True)
557 | kwargs.setdefault("expose_value", False)
558 | kwargs.setdefault("is_eager", True)
559 | kwargs.setdefault("help", _("Show this message and exit."))
560 | kwargs["callback"] = callback
561 | return option(*param_decls, **kwargs)
562 |
```
--------------------------------------------------------------------------------
/.venv/lib/python3.12/site-packages/pip/_internal/network/session.py:
--------------------------------------------------------------------------------
```python
1 | """PipSession and supporting code, containing all pip-specific
2 | network request configuration and behavior.
3 | """
4 |
5 | import email.utils
6 | import functools
7 | import io
8 | import ipaddress
9 | import json
10 | import logging
11 | import mimetypes
12 | import os
13 | import platform
14 | import shutil
15 | import subprocess
16 | import sys
17 | import urllib.parse
18 | import warnings
19 | from typing import (
20 | TYPE_CHECKING,
21 | Any,
22 | Dict,
23 | Generator,
24 | List,
25 | Mapping,
26 | Optional,
27 | Sequence,
28 | Tuple,
29 | Union,
30 | )
31 |
32 | from pip._vendor import requests, urllib3
33 | from pip._vendor.cachecontrol import CacheControlAdapter as _BaseCacheControlAdapter
34 | from pip._vendor.requests.adapters import DEFAULT_POOLBLOCK, BaseAdapter
35 | from pip._vendor.requests.adapters import HTTPAdapter as _BaseHTTPAdapter
36 | from pip._vendor.requests.models import PreparedRequest, Response
37 | from pip._vendor.requests.structures import CaseInsensitiveDict
38 | from pip._vendor.urllib3.connectionpool import ConnectionPool
39 | from pip._vendor.urllib3.exceptions import InsecureRequestWarning
40 |
41 | from pip import __version__
42 | from pip._internal.metadata import get_default_environment
43 | from pip._internal.models.link import Link
44 | from pip._internal.network.auth import MultiDomainBasicAuth
45 | from pip._internal.network.cache import SafeFileCache
46 |
47 | # Import ssl from compat so the initial import occurs in only one place.
48 | from pip._internal.utils.compat import has_tls
49 | from pip._internal.utils.glibc import libc_ver
50 | from pip._internal.utils.misc import build_url_from_netloc, parse_netloc
51 | from pip._internal.utils.urls import url_to_path
52 |
53 | if TYPE_CHECKING:
54 | from ssl import SSLContext
55 |
56 | from pip._vendor.urllib3.poolmanager import PoolManager
57 |
58 |
59 | logger = logging.getLogger(__name__)
60 |
61 | SecureOrigin = Tuple[str, str, Optional[Union[int, str]]]
62 |
63 |
64 | # Ignore warning raised when using --trusted-host.
65 | warnings.filterwarnings("ignore", category=InsecureRequestWarning)
66 |
67 |
68 | SECURE_ORIGINS: List[SecureOrigin] = [
69 | # protocol, hostname, port
70 | # Taken from Chrome's list of secure origins (See: http://bit.ly/1qrySKC)
71 | ("https", "*", "*"),
72 | ("*", "localhost", "*"),
73 | ("*", "127.0.0.0/8", "*"),
74 | ("*", "::1/128", "*"),
75 | ("file", "*", None),
76 | # ssh is always secure.
77 | ("ssh", "*", "*"),
78 | ]
79 |
80 |
81 | # These are environment variables present when running under various
82 | # CI systems. For each variable, some CI systems that use the variable
83 | # are indicated. The collection was chosen so that for each of a number
84 | # of popular systems, at least one of the environment variables is used.
85 | # This list is used to provide some indication of and lower bound for
86 | # CI traffic to PyPI. Thus, it is okay if the list is not comprehensive.
87 | # For more background, see: https://github.com/pypa/pip/issues/5499
88 | CI_ENVIRONMENT_VARIABLES = (
89 | # Azure Pipelines
90 | "BUILD_BUILDID",
91 | # Jenkins
92 | "BUILD_ID",
93 | # AppVeyor, CircleCI, Codeship, Gitlab CI, Shippable, Travis CI
94 | "CI",
95 | # Explicit environment variable.
96 | "PIP_IS_CI",
97 | )
98 |
99 |
100 | def looks_like_ci() -> bool:
101 | """
102 | Return whether it looks like pip is running under CI.
103 | """
104 | # We don't use the method of checking for a tty (e.g. using isatty())
105 | # because some CI systems mimic a tty (e.g. Travis CI). Thus that
106 | # method doesn't provide definitive information in either direction.
107 | return any(name in os.environ for name in CI_ENVIRONMENT_VARIABLES)
108 |
109 |
110 | @functools.lru_cache(maxsize=1)
111 | def user_agent() -> str:
112 | """
113 | Return a string representing the user agent.
114 | """
115 | data: Dict[str, Any] = {
116 | "installer": {"name": "pip", "version": __version__},
117 | "python": platform.python_version(),
118 | "implementation": {
119 | "name": platform.python_implementation(),
120 | },
121 | }
122 |
123 | if data["implementation"]["name"] == "CPython":
124 | data["implementation"]["version"] = platform.python_version()
125 | elif data["implementation"]["name"] == "PyPy":
126 | pypy_version_info = sys.pypy_version_info # type: ignore
127 | if pypy_version_info.releaselevel == "final":
128 | pypy_version_info = pypy_version_info[:3]
129 | data["implementation"]["version"] = ".".join(
130 | [str(x) for x in pypy_version_info]
131 | )
132 | elif data["implementation"]["name"] == "Jython":
133 | # Complete Guess
134 | data["implementation"]["version"] = platform.python_version()
135 | elif data["implementation"]["name"] == "IronPython":
136 | # Complete Guess
137 | data["implementation"]["version"] = platform.python_version()
138 |
139 | if sys.platform.startswith("linux"):
140 | from pip._vendor import distro
141 |
142 | linux_distribution = distro.name(), distro.version(), distro.codename()
143 | distro_infos: Dict[str, Any] = dict(
144 | filter(
145 | lambda x: x[1],
146 | zip(["name", "version", "id"], linux_distribution),
147 | )
148 | )
149 | libc = dict(
150 | filter(
151 | lambda x: x[1],
152 | zip(["lib", "version"], libc_ver()),
153 | )
154 | )
155 | if libc:
156 | distro_infos["libc"] = libc
157 | if distro_infos:
158 | data["distro"] = distro_infos
159 |
160 | if sys.platform.startswith("darwin") and platform.mac_ver()[0]:
161 | data["distro"] = {"name": "macOS", "version": platform.mac_ver()[0]}
162 |
163 | if platform.system():
164 | data.setdefault("system", {})["name"] = platform.system()
165 |
166 | if platform.release():
167 | data.setdefault("system", {})["release"] = platform.release()
168 |
169 | if platform.machine():
170 | data["cpu"] = platform.machine()
171 |
172 | if has_tls():
173 | import _ssl as ssl
174 |
175 | data["openssl_version"] = ssl.OPENSSL_VERSION
176 |
177 | setuptools_dist = get_default_environment().get_distribution("setuptools")
178 | if setuptools_dist is not None:
179 | data["setuptools_version"] = str(setuptools_dist.version)
180 |
181 | if shutil.which("rustc") is not None:
182 | # If for any reason `rustc --version` fails, silently ignore it
183 | try:
184 | rustc_output = subprocess.check_output(
185 | ["rustc", "--version"], stderr=subprocess.STDOUT, timeout=0.5
186 | )
187 | except Exception:
188 | pass
189 | else:
190 | if rustc_output.startswith(b"rustc "):
191 | # The format of `rustc --version` is:
192 | # `b'rustc 1.52.1 (9bc8c42bb 2021-05-09)\n'`
193 | # We extract just the middle (1.52.1) part
194 | data["rustc_version"] = rustc_output.split(b" ")[1].decode()
195 |
196 | # Use None rather than False so as not to give the impression that
197 | # pip knows it is not being run under CI. Rather, it is a null or
198 | # inconclusive result. Also, we include some value rather than no
199 | # value to make it easier to know that the check has been run.
200 | data["ci"] = True if looks_like_ci() else None
201 |
202 | user_data = os.environ.get("PIP_USER_AGENT_USER_DATA")
203 | if user_data is not None:
204 | data["user_data"] = user_data
205 |
206 | return "{data[installer][name]}/{data[installer][version]} {json}".format(
207 | data=data,
208 | json=json.dumps(data, separators=(",", ":"), sort_keys=True),
209 | )
210 |
211 |
212 | class LocalFSAdapter(BaseAdapter):
213 | def send(
214 | self,
215 | request: PreparedRequest,
216 | stream: bool = False,
217 | timeout: Optional[Union[float, Tuple[float, float]]] = None,
218 | verify: Union[bool, str] = True,
219 | cert: Optional[Union[str, Tuple[str, str]]] = None,
220 | proxies: Optional[Mapping[str, str]] = None,
221 | ) -> Response:
222 | pathname = url_to_path(request.url)
223 |
224 | resp = Response()
225 | resp.status_code = 200
226 | resp.url = request.url
227 |
228 | try:
229 | stats = os.stat(pathname)
230 | except OSError as exc:
231 | # format the exception raised as a io.BytesIO object,
232 | # to return a better error message:
233 | resp.status_code = 404
234 | resp.reason = type(exc).__name__
235 | resp.raw = io.BytesIO(f"{resp.reason}: {exc}".encode())
236 | else:
237 | modified = email.utils.formatdate(stats.st_mtime, usegmt=True)
238 | content_type = mimetypes.guess_type(pathname)[0] or "text/plain"
239 | resp.headers = CaseInsensitiveDict(
240 | {
241 | "Content-Type": content_type,
242 | "Content-Length": stats.st_size,
243 | "Last-Modified": modified,
244 | }
245 | )
246 |
247 | resp.raw = open(pathname, "rb")
248 | resp.close = resp.raw.close
249 |
250 | return resp
251 |
252 | def close(self) -> None:
253 | pass
254 |
255 |
256 | class _SSLContextAdapterMixin:
257 | """Mixin to add the ``ssl_context`` constructor argument to HTTP adapters.
258 |
259 | The additional argument is forwarded directly to the pool manager. This allows us
260 | to dynamically decide what SSL store to use at runtime, which is used to implement
261 | the optional ``truststore`` backend.
262 | """
263 |
264 | def __init__(
265 | self,
266 | *,
267 | ssl_context: Optional["SSLContext"] = None,
268 | **kwargs: Any,
269 | ) -> None:
270 | self._ssl_context = ssl_context
271 | super().__init__(**kwargs)
272 |
273 | def init_poolmanager(
274 | self,
275 | connections: int,
276 | maxsize: int,
277 | block: bool = DEFAULT_POOLBLOCK,
278 | **pool_kwargs: Any,
279 | ) -> "PoolManager":
280 | if self._ssl_context is not None:
281 | pool_kwargs.setdefault("ssl_context", self._ssl_context)
282 | return super().init_poolmanager( # type: ignore[misc]
283 | connections=connections,
284 | maxsize=maxsize,
285 | block=block,
286 | **pool_kwargs,
287 | )
288 |
289 |
290 | class HTTPAdapter(_SSLContextAdapterMixin, _BaseHTTPAdapter):
291 | pass
292 |
293 |
294 | class CacheControlAdapter(_SSLContextAdapterMixin, _BaseCacheControlAdapter):
295 | pass
296 |
297 |
298 | class InsecureHTTPAdapter(HTTPAdapter):
299 | def cert_verify(
300 | self,
301 | conn: ConnectionPool,
302 | url: str,
303 | verify: Union[bool, str],
304 | cert: Optional[Union[str, Tuple[str, str]]],
305 | ) -> None:
306 | super().cert_verify(conn=conn, url=url, verify=False, cert=cert)
307 |
308 |
309 | class InsecureCacheControlAdapter(CacheControlAdapter):
310 | def cert_verify(
311 | self,
312 | conn: ConnectionPool,
313 | url: str,
314 | verify: Union[bool, str],
315 | cert: Optional[Union[str, Tuple[str, str]]],
316 | ) -> None:
317 | super().cert_verify(conn=conn, url=url, verify=False, cert=cert)
318 |
319 |
320 | class PipSession(requests.Session):
321 | timeout: Optional[int] = None
322 |
323 | def __init__(
324 | self,
325 | *args: Any,
326 | retries: int = 0,
327 | cache: Optional[str] = None,
328 | trusted_hosts: Sequence[str] = (),
329 | index_urls: Optional[List[str]] = None,
330 | ssl_context: Optional["SSLContext"] = None,
331 | **kwargs: Any,
332 | ) -> None:
333 | """
334 | :param trusted_hosts: Domains not to emit warnings for when not using
335 | HTTPS.
336 | """
337 | super().__init__(*args, **kwargs)
338 |
339 | # Namespace the attribute with "pip_" just in case to prevent
340 | # possible conflicts with the base class.
341 | self.pip_trusted_origins: List[Tuple[str, Optional[int]]] = []
342 |
343 | # Attach our User Agent to the request
344 | self.headers["User-Agent"] = user_agent()
345 |
346 | # Attach our Authentication handler to the session
347 | self.auth = MultiDomainBasicAuth(index_urls=index_urls)
348 |
349 | # Create our urllib3.Retry instance which will allow us to customize
350 | # how we handle retries.
351 | retries = urllib3.Retry(
352 | # Set the total number of retries that a particular request can
353 | # have.
354 | total=retries,
355 | # A 503 error from PyPI typically means that the Fastly -> Origin
356 | # connection got interrupted in some way. A 503 error in general
357 | # is typically considered a transient error so we'll go ahead and
358 | # retry it.
359 | # A 500 may indicate transient error in Amazon S3
360 | # A 502 may be a transient error from a CDN like CloudFlare or CloudFront
361 | # A 520 or 527 - may indicate transient error in CloudFlare
362 | status_forcelist=[500, 502, 503, 520, 527],
363 | # Add a small amount of back off between failed requests in
364 | # order to prevent hammering the service.
365 | backoff_factor=0.25,
366 | ) # type: ignore
367 |
368 | # Our Insecure HTTPAdapter disables HTTPS validation. It does not
369 | # support caching so we'll use it for all http:// URLs.
370 | # If caching is disabled, we will also use it for
371 | # https:// hosts that we've marked as ignoring
372 | # TLS errors for (trusted-hosts).
373 | insecure_adapter = InsecureHTTPAdapter(max_retries=retries)
374 |
375 | # We want to _only_ cache responses on securely fetched origins or when
376 | # the host is specified as trusted. We do this because
377 | # we can't validate the response of an insecurely/untrusted fetched
378 | # origin, and we don't want someone to be able to poison the cache and
379 | # require manual eviction from the cache to fix it.
380 | if cache:
381 | secure_adapter = CacheControlAdapter(
382 | cache=SafeFileCache(cache),
383 | max_retries=retries,
384 | ssl_context=ssl_context,
385 | )
386 | self._trusted_host_adapter = InsecureCacheControlAdapter(
387 | cache=SafeFileCache(cache),
388 | max_retries=retries,
389 | )
390 | else:
391 | secure_adapter = HTTPAdapter(max_retries=retries, ssl_context=ssl_context)
392 | self._trusted_host_adapter = insecure_adapter
393 |
394 | self.mount("https://", secure_adapter)
395 | self.mount("http://", insecure_adapter)
396 |
397 | # Enable file:// urls
398 | self.mount("file://", LocalFSAdapter())
399 |
400 | for host in trusted_hosts:
401 | self.add_trusted_host(host, suppress_logging=True)
402 |
403 | def update_index_urls(self, new_index_urls: List[str]) -> None:
404 | """
405 | :param new_index_urls: New index urls to update the authentication
406 | handler with.
407 | """
408 | self.auth.index_urls = new_index_urls
409 |
410 | def add_trusted_host(
411 | self, host: str, source: Optional[str] = None, suppress_logging: bool = False
412 | ) -> None:
413 | """
414 | :param host: It is okay to provide a host that has previously been
415 | added.
416 | :param source: An optional source string, for logging where the host
417 | string came from.
418 | """
419 | if not suppress_logging:
420 | msg = f"adding trusted host: {host!r}"
421 | if source is not None:
422 | msg += f" (from {source})"
423 | logger.info(msg)
424 |
425 | parsed_host, parsed_port = parse_netloc(host)
426 | if parsed_host is None:
427 | raise ValueError(f"Trusted host URL must include a host part: {host!r}")
428 | if (parsed_host, parsed_port) not in self.pip_trusted_origins:
429 | self.pip_trusted_origins.append((parsed_host, parsed_port))
430 |
431 | self.mount(
432 | build_url_from_netloc(host, scheme="http") + "/", self._trusted_host_adapter
433 | )
434 | self.mount(build_url_from_netloc(host) + "/", self._trusted_host_adapter)
435 | if not parsed_port:
436 | self.mount(
437 | build_url_from_netloc(host, scheme="http") + ":",
438 | self._trusted_host_adapter,
439 | )
440 | # Mount wildcard ports for the same host.
441 | self.mount(build_url_from_netloc(host) + ":", self._trusted_host_adapter)
442 |
443 | def iter_secure_origins(self) -> Generator[SecureOrigin, None, None]:
444 | yield from SECURE_ORIGINS
445 | for host, port in self.pip_trusted_origins:
446 | yield ("*", host, "*" if port is None else port)
447 |
448 | def is_secure_origin(self, location: Link) -> bool:
449 | # Determine if this url used a secure transport mechanism
450 | parsed = urllib.parse.urlparse(str(location))
451 | origin_protocol, origin_host, origin_port = (
452 | parsed.scheme,
453 | parsed.hostname,
454 | parsed.port,
455 | )
456 |
457 | # The protocol to use to see if the protocol matches.
458 | # Don't count the repository type as part of the protocol: in
459 | # cases such as "git+ssh", only use "ssh". (I.e., Only verify against
460 | # the last scheme.)
461 | origin_protocol = origin_protocol.rsplit("+", 1)[-1]
462 |
463 | # Determine if our origin is a secure origin by looking through our
464 | # hardcoded list of secure origins, as well as any additional ones
465 | # configured on this PackageFinder instance.
466 | for secure_origin in self.iter_secure_origins():
467 | secure_protocol, secure_host, secure_port = secure_origin
468 | if origin_protocol != secure_protocol and secure_protocol != "*":
469 | continue
470 |
471 | try:
472 | addr = ipaddress.ip_address(origin_host or "")
473 | network = ipaddress.ip_network(secure_host)
474 | except ValueError:
475 | # We don't have both a valid address or a valid network, so
476 | # we'll check this origin against hostnames.
477 | if (
478 | origin_host
479 | and origin_host.lower() != secure_host.lower()
480 | and secure_host != "*"
481 | ):
482 | continue
483 | else:
484 | # We have a valid address and network, so see if the address
485 | # is contained within the network.
486 | if addr not in network:
487 | continue
488 |
489 | # Check to see if the port matches.
490 | if (
491 | origin_port != secure_port
492 | and secure_port != "*"
493 | and secure_port is not None
494 | ):
495 | continue
496 |
497 | # If we've gotten here, then this origin matches the current
498 | # secure origin and we should return True
499 | return True
500 |
501 | # If we've gotten to this point, then the origin isn't secure and we
502 | # will not accept it as a valid location to search. We will however
503 | # log a warning that we are ignoring it.
504 | logger.warning(
505 | "The repository located at %s is not a trusted or secure host and "
506 | "is being ignored. If this repository is available via HTTPS we "
507 | "recommend you use HTTPS instead, otherwise you may silence "
508 | "this warning and allow it anyway with '--trusted-host %s'.",
509 | origin_host,
510 | origin_host,
511 | )
512 |
513 | return False
514 |
515 | def request(self, method: str, url: str, *args: Any, **kwargs: Any) -> Response:
516 | # Allow setting a default timeout on a session
517 | kwargs.setdefault("timeout", self.timeout)
518 | # Allow setting a default proxies on a session
519 | kwargs.setdefault("proxies", self.proxies)
520 |
521 | # Dispatch the actual request
522 | return super().request(method, url, *args, **kwargs)
523 |
```
--------------------------------------------------------------------------------
/.venv/lib/python3.12/site-packages/click/_compat.py:
--------------------------------------------------------------------------------
```python
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 | WIN = sys.platform.startswith("win")
11 | auto_wrap_for_ansi: t.Optional[t.Callable[[t.TextIO], t.TextIO]] = None
12 | _ansi_re = re.compile(r"\033\[[;?0-9]*[a-zA-Z]")
13 |
14 |
15 | def _make_text_stream(
16 | stream: t.BinaryIO,
17 | encoding: t.Optional[str],
18 | errors: t.Optional[str],
19 | force_readable: bool = False,
20 | force_writable: bool = False,
21 | ) -> t.TextIO:
22 | if encoding is None:
23 | encoding = get_best_encoding(stream)
24 | if errors is None:
25 | errors = "replace"
26 | return _NonClosingTextIOWrapper(
27 | stream,
28 | encoding,
29 | errors,
30 | line_buffering=True,
31 | force_readable=force_readable,
32 | force_writable=force_writable,
33 | )
34 |
35 |
36 | def is_ascii_encoding(encoding: str) -> bool:
37 | """Checks if a given encoding is ascii."""
38 | try:
39 | return codecs.lookup(encoding).name == "ascii"
40 | except LookupError:
41 | return False
42 |
43 |
44 | def get_best_encoding(stream: t.IO[t.Any]) -> str:
45 | """Returns the default stream encoding if not found."""
46 | rv = getattr(stream, "encoding", None) or sys.getdefaultencoding()
47 | if is_ascii_encoding(rv):
48 | return "utf-8"
49 | return rv
50 |
51 |
52 | class _NonClosingTextIOWrapper(io.TextIOWrapper):
53 | def __init__(
54 | self,
55 | stream: t.BinaryIO,
56 | encoding: t.Optional[str],
57 | errors: t.Optional[str],
58 | force_readable: bool = False,
59 | force_writable: bool = False,
60 | **extra: t.Any,
61 | ) -> None:
62 | self._stream = stream = t.cast(
63 | t.BinaryIO, _FixupStream(stream, force_readable, force_writable)
64 | )
65 | super().__init__(stream, encoding, errors, **extra)
66 |
67 | def __del__(self) -> None:
68 | try:
69 | self.detach()
70 | except Exception:
71 | pass
72 |
73 | def isatty(self) -> bool:
74 | # https://bitbucket.org/pypy/pypy/issue/1803
75 | return self._stream.isatty()
76 |
77 |
78 | class _FixupStream:
79 | """The new io interface needs more from streams than streams
80 | traditionally implement. As such, this fix-up code is necessary in
81 | some circumstances.
82 |
83 | The forcing of readable and writable flags are there because some tools
84 | put badly patched objects on sys (one such offender are certain version
85 | of jupyter notebook).
86 | """
87 |
88 | def __init__(
89 | self,
90 | stream: t.BinaryIO,
91 | force_readable: bool = False,
92 | force_writable: bool = False,
93 | ):
94 | self._stream = stream
95 | self._force_readable = force_readable
96 | self._force_writable = force_writable
97 |
98 | def __getattr__(self, name: str) -> t.Any:
99 | return getattr(self._stream, name)
100 |
101 | def read1(self, size: int) -> bytes:
102 | f = getattr(self._stream, "read1", None)
103 |
104 | if f is not None:
105 | return t.cast(bytes, f(size))
106 |
107 | return self._stream.read(size)
108 |
109 | def readable(self) -> bool:
110 | if self._force_readable:
111 | return True
112 | x = getattr(self._stream, "readable", None)
113 | if x is not None:
114 | return t.cast(bool, x())
115 | try:
116 | self._stream.read(0)
117 | except Exception:
118 | return False
119 | return True
120 |
121 | def writable(self) -> bool:
122 | if self._force_writable:
123 | return True
124 | x = getattr(self._stream, "writable", None)
125 | if x is not None:
126 | return t.cast(bool, x())
127 | try:
128 | self._stream.write("") # type: ignore
129 | except Exception:
130 | try:
131 | self._stream.write(b"")
132 | except Exception:
133 | return False
134 | return True
135 |
136 | def seekable(self) -> bool:
137 | x = getattr(self._stream, "seekable", None)
138 | if x is not None:
139 | return t.cast(bool, x())
140 | try:
141 | self._stream.seek(self._stream.tell())
142 | except Exception:
143 | return False
144 | return True
145 |
146 |
147 | def _is_binary_reader(stream: t.IO[t.Any], default: bool = False) -> bool:
148 | try:
149 | return isinstance(stream.read(0), bytes)
150 | except Exception:
151 | return default
152 | # This happens in some cases where the stream was already
153 | # closed. In this case, we assume the default.
154 |
155 |
156 | def _is_binary_writer(stream: t.IO[t.Any], default: bool = False) -> bool:
157 | try:
158 | stream.write(b"")
159 | except Exception:
160 | try:
161 | stream.write("")
162 | return False
163 | except Exception:
164 | pass
165 | return default
166 | return True
167 |
168 |
169 | def _find_binary_reader(stream: t.IO[t.Any]) -> t.Optional[t.BinaryIO]:
170 | # We need to figure out if the given stream is already binary.
171 | # This can happen because the official docs recommend detaching
172 | # the streams to get binary streams. Some code might do this, so
173 | # we need to deal with this case explicitly.
174 | if _is_binary_reader(stream, False):
175 | return t.cast(t.BinaryIO, stream)
176 |
177 | buf = getattr(stream, "buffer", None)
178 |
179 | # Same situation here; this time we assume that the buffer is
180 | # actually binary in case it's closed.
181 | if buf is not None and _is_binary_reader(buf, True):
182 | return t.cast(t.BinaryIO, buf)
183 |
184 | return None
185 |
186 |
187 | def _find_binary_writer(stream: t.IO[t.Any]) -> t.Optional[t.BinaryIO]:
188 | # We need to figure out if the given stream is already binary.
189 | # This can happen because the official docs recommend detaching
190 | # the streams to get binary streams. Some code might do this, so
191 | # we need to deal with this case explicitly.
192 | if _is_binary_writer(stream, False):
193 | return t.cast(t.BinaryIO, stream)
194 |
195 | buf = getattr(stream, "buffer", None)
196 |
197 | # Same situation here; this time we assume that the buffer is
198 | # actually binary in case it's closed.
199 | if buf is not None and _is_binary_writer(buf, True):
200 | return t.cast(t.BinaryIO, buf)
201 |
202 | return None
203 |
204 |
205 | def _stream_is_misconfigured(stream: t.TextIO) -> bool:
206 | """A stream is misconfigured if its encoding is ASCII."""
207 | # If the stream does not have an encoding set, we assume it's set
208 | # to ASCII. This appears to happen in certain unittest
209 | # environments. It's not quite clear what the correct behavior is
210 | # but this at least will force Click to recover somehow.
211 | return is_ascii_encoding(getattr(stream, "encoding", None) or "ascii")
212 |
213 |
214 | def _is_compat_stream_attr(stream: t.TextIO, attr: str, value: t.Optional[str]) -> bool:
215 | """A stream attribute is compatible if it is equal to the
216 | desired value or the desired value is unset and the attribute
217 | has a value.
218 | """
219 | stream_value = getattr(stream, attr, None)
220 | return stream_value == value or (value is None and stream_value is not None)
221 |
222 |
223 | def _is_compatible_text_stream(
224 | stream: t.TextIO, encoding: t.Optional[str], errors: t.Optional[str]
225 | ) -> bool:
226 | """Check if a stream's encoding and errors attributes are
227 | compatible with the desired values.
228 | """
229 | return _is_compat_stream_attr(
230 | stream, "encoding", encoding
231 | ) and _is_compat_stream_attr(stream, "errors", errors)
232 |
233 |
234 | def _force_correct_text_stream(
235 | text_stream: t.IO[t.Any],
236 | encoding: t.Optional[str],
237 | errors: t.Optional[str],
238 | is_binary: t.Callable[[t.IO[t.Any], bool], bool],
239 | find_binary: t.Callable[[t.IO[t.Any]], t.Optional[t.BinaryIO]],
240 | force_readable: bool = False,
241 | force_writable: bool = False,
242 | ) -> t.TextIO:
243 | if is_binary(text_stream, False):
244 | binary_reader = t.cast(t.BinaryIO, text_stream)
245 | else:
246 | text_stream = t.cast(t.TextIO, text_stream)
247 | # If the stream looks compatible, and won't default to a
248 | # misconfigured ascii encoding, return it as-is.
249 | if _is_compatible_text_stream(text_stream, encoding, errors) and not (
250 | encoding is None and _stream_is_misconfigured(text_stream)
251 | ):
252 | return text_stream
253 |
254 | # Otherwise, get the underlying binary reader.
255 | possible_binary_reader = find_binary(text_stream)
256 |
257 | # If that's not possible, silently use the original reader
258 | # and get mojibake instead of exceptions.
259 | if possible_binary_reader is None:
260 | return text_stream
261 |
262 | binary_reader = possible_binary_reader
263 |
264 | # Default errors to replace instead of strict in order to get
265 | # something that works.
266 | if errors is None:
267 | errors = "replace"
268 |
269 | # Wrap the binary stream in a text stream with the correct
270 | # encoding parameters.
271 | return _make_text_stream(
272 | binary_reader,
273 | encoding,
274 | errors,
275 | force_readable=force_readable,
276 | force_writable=force_writable,
277 | )
278 |
279 |
280 | def _force_correct_text_reader(
281 | text_reader: t.IO[t.Any],
282 | encoding: t.Optional[str],
283 | errors: t.Optional[str],
284 | force_readable: bool = False,
285 | ) -> t.TextIO:
286 | return _force_correct_text_stream(
287 | text_reader,
288 | encoding,
289 | errors,
290 | _is_binary_reader,
291 | _find_binary_reader,
292 | force_readable=force_readable,
293 | )
294 |
295 |
296 | def _force_correct_text_writer(
297 | text_writer: t.IO[t.Any],
298 | encoding: t.Optional[str],
299 | errors: t.Optional[str],
300 | force_writable: bool = False,
301 | ) -> t.TextIO:
302 | return _force_correct_text_stream(
303 | text_writer,
304 | encoding,
305 | errors,
306 | _is_binary_writer,
307 | _find_binary_writer,
308 | force_writable=force_writable,
309 | )
310 |
311 |
312 | def get_binary_stdin() -> t.BinaryIO:
313 | reader = _find_binary_reader(sys.stdin)
314 | if reader is None:
315 | raise RuntimeError("Was not able to determine binary stream for sys.stdin.")
316 | return reader
317 |
318 |
319 | def get_binary_stdout() -> t.BinaryIO:
320 | writer = _find_binary_writer(sys.stdout)
321 | if writer is None:
322 | raise RuntimeError("Was not able to determine binary stream for sys.stdout.")
323 | return writer
324 |
325 |
326 | def get_binary_stderr() -> t.BinaryIO:
327 | writer = _find_binary_writer(sys.stderr)
328 | if writer is None:
329 | raise RuntimeError("Was not able to determine binary stream for sys.stderr.")
330 | return writer
331 |
332 |
333 | def get_text_stdin(
334 | encoding: t.Optional[str] = None, errors: t.Optional[str] = None
335 | ) -> t.TextIO:
336 | rv = _get_windows_console_stream(sys.stdin, encoding, errors)
337 | if rv is not None:
338 | return rv
339 | return _force_correct_text_reader(sys.stdin, encoding, errors, force_readable=True)
340 |
341 |
342 | def get_text_stdout(
343 | encoding: t.Optional[str] = None, errors: t.Optional[str] = None
344 | ) -> t.TextIO:
345 | rv = _get_windows_console_stream(sys.stdout, encoding, errors)
346 | if rv is not None:
347 | return rv
348 | return _force_correct_text_writer(sys.stdout, encoding, errors, force_writable=True)
349 |
350 |
351 | def get_text_stderr(
352 | encoding: t.Optional[str] = None, errors: t.Optional[str] = None
353 | ) -> t.TextIO:
354 | rv = _get_windows_console_stream(sys.stderr, encoding, errors)
355 | if rv is not None:
356 | return rv
357 | return _force_correct_text_writer(sys.stderr, encoding, errors, force_writable=True)
358 |
359 |
360 | def _wrap_io_open(
361 | file: t.Union[str, "os.PathLike[str]", int],
362 | mode: str,
363 | encoding: t.Optional[str],
364 | errors: t.Optional[str],
365 | ) -> t.IO[t.Any]:
366 | """Handles not passing ``encoding`` and ``errors`` in binary mode."""
367 | if "b" in mode:
368 | return open(file, mode)
369 |
370 | return open(file, mode, encoding=encoding, errors=errors)
371 |
372 |
373 | def open_stream(
374 | filename: "t.Union[str, os.PathLike[str]]",
375 | mode: str = "r",
376 | encoding: t.Optional[str] = None,
377 | errors: t.Optional[str] = "strict",
378 | atomic: bool = False,
379 | ) -> t.Tuple[t.IO[t.Any], bool]:
380 | binary = "b" in mode
381 | filename = os.fspath(filename)
382 |
383 | # Standard streams first. These are simple because they ignore the
384 | # atomic flag. Use fsdecode to handle Path("-").
385 | if os.fsdecode(filename) == "-":
386 | if any(m in mode for m in ["w", "a", "x"]):
387 | if binary:
388 | return get_binary_stdout(), False
389 | return get_text_stdout(encoding=encoding, errors=errors), False
390 | if binary:
391 | return get_binary_stdin(), False
392 | return get_text_stdin(encoding=encoding, errors=errors), False
393 |
394 | # Non-atomic writes directly go out through the regular open functions.
395 | if not atomic:
396 | return _wrap_io_open(filename, mode, encoding, errors), True
397 |
398 | # Some usability stuff for atomic writes
399 | if "a" in mode:
400 | raise ValueError(
401 | "Appending to an existing file is not supported, because that"
402 | " would involve an expensive `copy`-operation to a temporary"
403 | " file. Open the file in normal `w`-mode and copy explicitly"
404 | " if that's what you're after."
405 | )
406 | if "x" in mode:
407 | raise ValueError("Use the `overwrite`-parameter instead.")
408 | if "w" not in mode:
409 | raise ValueError("Atomic writes only make sense with `w`-mode.")
410 |
411 | # Atomic writes are more complicated. They work by opening a file
412 | # as a proxy in the same folder and then using the fdopen
413 | # functionality to wrap it in a Python file. Then we wrap it in an
414 | # atomic file that moves the file over on close.
415 | import errno
416 | import random
417 |
418 | try:
419 | perm: t.Optional[int] = os.stat(filename).st_mode
420 | except OSError:
421 | perm = None
422 |
423 | flags = os.O_RDWR | os.O_CREAT | os.O_EXCL
424 |
425 | if binary:
426 | flags |= getattr(os, "O_BINARY", 0)
427 |
428 | while True:
429 | tmp_filename = os.path.join(
430 | os.path.dirname(filename),
431 | f".__atomic-write{random.randrange(1 << 32):08x}",
432 | )
433 | try:
434 | fd = os.open(tmp_filename, flags, 0o666 if perm is None else perm)
435 | break
436 | except OSError as e:
437 | if e.errno == errno.EEXIST or (
438 | os.name == "nt"
439 | and e.errno == errno.EACCES
440 | and os.path.isdir(e.filename)
441 | and os.access(e.filename, os.W_OK)
442 | ):
443 | continue
444 | raise
445 |
446 | if perm is not None:
447 | os.chmod(tmp_filename, perm) # in case perm includes bits in umask
448 |
449 | f = _wrap_io_open(fd, mode, encoding, errors)
450 | af = _AtomicFile(f, tmp_filename, os.path.realpath(filename))
451 | return t.cast(t.IO[t.Any], af), True
452 |
453 |
454 | class _AtomicFile:
455 | def __init__(self, f: t.IO[t.Any], tmp_filename: str, real_filename: str) -> None:
456 | self._f = f
457 | self._tmp_filename = tmp_filename
458 | self._real_filename = real_filename
459 | self.closed = False
460 |
461 | @property
462 | def name(self) -> str:
463 | return self._real_filename
464 |
465 | def close(self, delete: bool = False) -> None:
466 | if self.closed:
467 | return
468 | self._f.close()
469 | os.replace(self._tmp_filename, self._real_filename)
470 | self.closed = True
471 |
472 | def __getattr__(self, name: str) -> t.Any:
473 | return getattr(self._f, name)
474 |
475 | def __enter__(self) -> "_AtomicFile":
476 | return self
477 |
478 | def __exit__(self, exc_type: t.Optional[t.Type[BaseException]], *_: t.Any) -> None:
479 | self.close(delete=exc_type is not None)
480 |
481 | def __repr__(self) -> str:
482 | return repr(self._f)
483 |
484 |
485 | def strip_ansi(value: str) -> str:
486 | return _ansi_re.sub("", value)
487 |
488 |
489 | def _is_jupyter_kernel_output(stream: t.IO[t.Any]) -> bool:
490 | while isinstance(stream, (_FixupStream, _NonClosingTextIOWrapper)):
491 | stream = stream._stream
492 |
493 | return stream.__class__.__module__.startswith("ipykernel.")
494 |
495 |
496 | def should_strip_ansi(
497 | stream: t.Optional[t.IO[t.Any]] = None, color: t.Optional[bool] = None
498 | ) -> bool:
499 | if color is None:
500 | if stream is None:
501 | stream = sys.stdin
502 | return not isatty(stream) and not _is_jupyter_kernel_output(stream)
503 | return not color
504 |
505 |
506 | # On Windows, wrap the output streams with colorama to support ANSI
507 | # color codes.
508 | # NOTE: double check is needed so mypy does not analyze this on Linux
509 | if sys.platform.startswith("win") and WIN:
510 | from ._winconsole import _get_windows_console_stream
511 |
512 | def _get_argv_encoding() -> str:
513 | import locale
514 |
515 | return locale.getpreferredencoding()
516 |
517 | _ansi_stream_wrappers: t.MutableMapping[t.TextIO, t.TextIO] = WeakKeyDictionary()
518 |
519 | def auto_wrap_for_ansi( # noqa: F811
520 | stream: t.TextIO, color: t.Optional[bool] = None
521 | ) -> t.TextIO:
522 | """Support ANSI color and style codes on Windows by wrapping a
523 | stream with colorama.
524 | """
525 | try:
526 | cached = _ansi_stream_wrappers.get(stream)
527 | except Exception:
528 | cached = None
529 |
530 | if cached is not None:
531 | return cached
532 |
533 | import colorama
534 |
535 | strip = should_strip_ansi(stream, color)
536 | ansi_wrapper = colorama.AnsiToWin32(stream, strip=strip)
537 | rv = t.cast(t.TextIO, ansi_wrapper.stream)
538 | _write = rv.write
539 |
540 | def _safe_write(s):
541 | try:
542 | return _write(s)
543 | except BaseException:
544 | ansi_wrapper.reset_all()
545 | raise
546 |
547 | rv.write = _safe_write
548 |
549 | try:
550 | _ansi_stream_wrappers[stream] = rv
551 | except Exception:
552 | pass
553 |
554 | return rv
555 |
556 | else:
557 |
558 | def _get_argv_encoding() -> str:
559 | return getattr(sys.stdin, "encoding", None) or sys.getfilesystemencoding()
560 |
561 | def _get_windows_console_stream(
562 | f: t.TextIO, encoding: t.Optional[str], errors: t.Optional[str]
563 | ) -> t.Optional[t.TextIO]:
564 | return None
565 |
566 |
567 | def term_len(x: str) -> int:
568 | return len(strip_ansi(x))
569 |
570 |
571 | def isatty(stream: t.IO[t.Any]) -> bool:
572 | try:
573 | return stream.isatty()
574 | except Exception:
575 | return False
576 |
577 |
578 | def _make_cached_stream_func(
579 | src_func: t.Callable[[], t.Optional[t.TextIO]],
580 | wrapper_func: t.Callable[[], t.TextIO],
581 | ) -> t.Callable[[], t.Optional[t.TextIO]]:
582 | cache: t.MutableMapping[t.TextIO, t.TextIO] = WeakKeyDictionary()
583 |
584 | def func() -> t.Optional[t.TextIO]:
585 | stream = src_func()
586 |
587 | if stream is None:
588 | return None
589 |
590 | try:
591 | rv = cache.get(stream)
592 | except Exception:
593 | rv = None
594 | if rv is not None:
595 | return rv
596 | rv = wrapper_func()
597 | try:
598 | cache[stream] = rv
599 | except Exception:
600 | pass
601 | return rv
602 |
603 | return func
604 |
605 |
606 | _default_text_stdin = _make_cached_stream_func(lambda: sys.stdin, get_text_stdin)
607 | _default_text_stdout = _make_cached_stream_func(lambda: sys.stdout, get_text_stdout)
608 | _default_text_stderr = _make_cached_stream_func(lambda: sys.stderr, get_text_stderr)
609 |
610 |
611 | binary_streams: t.Mapping[str, t.Callable[[], t.BinaryIO]] = {
612 | "stdin": get_binary_stdin,
613 | "stdout": get_binary_stdout,
614 | "stderr": get_binary_stderr,
615 | }
616 |
617 | text_streams: t.Mapping[
618 | str, t.Callable[[t.Optional[str], t.Optional[str]], t.TextIO]
619 | ] = {
620 | "stdin": get_text_stdin,
621 | "stdout": get_text_stdout,
622 | "stderr": get_text_stderr,
623 | }
624 |
```